aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libutil/util.cc14
1 files changed, 13 insertions, 1 deletions
diff --git a/src/libutil/util.cc b/src/libutil/util.cc
index 4e9346486..556c3c3a2 100644
--- a/src/libutil/util.cc
+++ b/src/libutil/util.cc
@@ -300,7 +300,19 @@ Path createTempDir()
while (1) {
checkInterrupt();
Path tmpDir = tempName();
- if (mkdir(tmpDir.c_str(), 0777) == 0) return tmpDir;
+ if (mkdir(tmpDir.c_str(), 0777) == 0) {
+ /* Explicitly set the group of the directory. This is to
+ work around around problems caused by BSD's group
+ ownership semantics (directories inherit the group of
+ the parent). For instance, the group of /tmp on
+ FreeBSD is "wheel", so all directories created in /tmp
+ will be owned by "wheel"; but if the user is not in
+ "wheel", then "tar" will fail to unpack archives that
+ have the setgid bit set on directories. */
+ if (chown(tmpDir.c_str(), (uid_t) -1, getegid()) != 0)
+ throw SysError(format("setting group of directory `%1%'") % tmpDir);
+ return tmpDir;
+ }
if (errno != EEXIST)
throw SysError(format("creating directory `%1%'") % tmpDir);
}