Skip to content

Commit 2552e63

Browse files
create_directories: preserve sticky and setgid permissions (#1855)
* Fix sticky permissions * Use the helpers only privately
1 parent 17eb5e5 commit 2552e63

1 file changed

Lines changed: 45 additions & 4 deletions

File tree

src/auxiliary/Filesystem.cpp

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,46 @@ list_directory_nothrow(std::string const &path)
112112
return ret;
113113
}
114114

115+
#ifndef _WIN32
116+
// Need to manually preserve sticky bit and setgid on Unix systems
117+
namespace
118+
{
119+
std::string get_parent(std::string const &path)
120+
{
121+
std::string parent = path;
122+
size_t pos = parent.find_last_of(directory_separator);
123+
if (pos != std::string::npos)
124+
{
125+
parent = parent.substr(0, pos);
126+
if (parent.empty())
127+
parent = "/";
128+
}
129+
else
130+
{
131+
parent.clear();
132+
}
133+
return parent;
134+
}
135+
136+
mode_t get_permissions(std::string const &path)
137+
{
138+
std::string parent = get_parent(path);
139+
if (parent.empty() || !directory_exists(parent))
140+
{
141+
return 0;
142+
}
143+
144+
struct stat s;
145+
if (stat(parent.c_str(), &s) != 0)
146+
{
147+
return 0;
148+
}
149+
150+
return s.st_mode & 07777;
151+
}
152+
} // namespace
153+
#endif
154+
115155
bool create_directories(std::string const &path)
116156
{
117157
if (directory_exists(path))
@@ -122,10 +162,11 @@ bool create_directories(std::string const &path)
122162
return CreateDirectory(p.c_str(), nullptr);
123163
};
124164
#else
125-
mode_t mask = umask(0);
126-
umask(mask);
127-
auto mk = [mask](std::string const &p) -> bool {
128-
return (0 == mkdir(p.c_str(), 0777 & ~mask));
165+
auto mk = [](std::string const &p) -> bool {
166+
// preserve sticky and setgid from parent
167+
mode_t parentPerms =
168+
get_permissions(get_parent(p)) & (S_ISVTX | S_ISGID);
169+
return (0 == mkdir(p.c_str(), 0777 | parentPerms));
129170
};
130171
#endif
131172
std::istringstream ss(path);

0 commit comments

Comments
 (0)