|
@@ -2123,12 +2123,37 @@ std::string GetTempDir() /*{{{*/
|
|
|
|
|
|
|
|
struct stat st;
|
|
struct stat st;
|
|
|
if (!tmpdir || strlen(tmpdir) == 0 || // tmpdir is set
|
|
if (!tmpdir || strlen(tmpdir) == 0 || // tmpdir is set
|
|
|
- stat(tmpdir, &st) != 0 || (st.st_mode & S_IFDIR) == 0 || // exists and is directory
|
|
|
|
|
- access(tmpdir, R_OK | W_OK | X_OK) != 0 // current user has rwx access to directory
|
|
|
|
|
- )
|
|
|
|
|
|
|
+ stat(tmpdir, &st) != 0 || (st.st_mode & S_IFDIR) == 0) // exists and is directory
|
|
|
|
|
+ tmpdir = "/tmp";
|
|
|
|
|
+ else if (geteuid() != 0 && // root can do everything anyway
|
|
|
|
|
+ faccessat(-1, tmpdir, R_OK | W_OK | X_OK, AT_EACCESS | AT_SYMLINK_NOFOLLOW) != 0) // current user has rwx access to directory
|
|
|
tmpdir = "/tmp";
|
|
tmpdir = "/tmp";
|
|
|
|
|
|
|
|
return string(tmpdir);
|
|
return string(tmpdir);
|
|
|
|
|
+}
|
|
|
|
|
+std::string GetTempDir(std::string const &User)
|
|
|
|
|
+{
|
|
|
|
|
+ // no need/possibility to drop privs
|
|
|
|
|
+ if(getuid() != 0 || User.empty() || User == "root")
|
|
|
|
|
+ return GetTempDir();
|
|
|
|
|
+
|
|
|
|
|
+ struct passwd const * const pw = getpwnam(User.c_str());
|
|
|
|
|
+ if (pw == NULL)
|
|
|
|
|
+ return GetTempDir();
|
|
|
|
|
+
|
|
|
|
|
+ if (setegid(pw->pw_gid) != 0)
|
|
|
|
|
+ _error->Errno("setegid", "setegid %u failed", pw->pw_gid);
|
|
|
|
|
+ if (seteuid(pw->pw_uid) != 0)
|
|
|
|
|
+ _error->Errno("seteuid", "seteuid %u failed", pw->pw_uid);
|
|
|
|
|
+
|
|
|
|
|
+ std::string const tmp = GetTempDir();
|
|
|
|
|
+
|
|
|
|
|
+ if (seteuid(0) != 0)
|
|
|
|
|
+ _error->Errno("seteuid", "seteuid %u failed", 0);
|
|
|
|
|
+ if (setegid(0) != 0)
|
|
|
|
|
+ _error->Errno("setegid", "setegid %u failed", 0);
|
|
|
|
|
+
|
|
|
|
|
+ return tmp;
|
|
|
}
|
|
}
|
|
|
/*}}}*/
|
|
/*}}}*/
|
|
|
FileFd* GetTempFile(std::string const &Prefix, bool ImmediateUnlink, FileFd * const TmpFd) /*{{{*/
|
|
FileFd* GetTempFile(std::string const &Prefix, bool ImmediateUnlink, FileFd * const TmpFd) /*{{{*/
|