summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apt-pkg/acquire-item.cc4
-rw-r--r--apt-pkg/contrib/fileutl.cc31
-rw-r--r--apt-pkg/contrib/fileutl.h1
3 files changed, 31 insertions, 5 deletions
diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc
index f505531c1..b6b6d8e48 100644
--- a/apt-pkg/acquire-item.cc
+++ b/apt-pkg/acquire-item.cc
@@ -2999,7 +2999,8 @@ void pkgAcqChangelog::Init(std::string const &DestDir, std::string const &DestFi
if (DestDir.empty())
{
- std::string const systemTemp = GetTempDir();
+ std::string const SandboxUser = _config->Find("APT::Sandbox::User");
+ std::string const systemTemp = GetTempDir(SandboxUser);
char tmpname[100];
snprintf(tmpname, sizeof(tmpname), "%s/apt-changelog-XXXXXX", systemTemp.c_str());
if (NULL == mkdtemp(tmpname))
@@ -3010,7 +3011,6 @@ void pkgAcqChangelog::Init(std::string const &DestDir, std::string const &DestFi
}
DestFile = TemporaryDirectory = tmpname;
- std::string SandboxUser = _config->Find("APT::Sandbox::User");
ChangeOwnerAndPermissionOfFile("Item::QueueURI", DestFile.c_str(),
SandboxUser.c_str(), "root", 0700);
}
diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc
index d7c9424cf..1d20c9c35 100644
--- a/apt-pkg/contrib/fileutl.cc
+++ b/apt-pkg/contrib/fileutl.cc
@@ -2123,13 +2123,38 @@ std::string GetTempDir() /*{{{*/
struct stat st;
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";
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) /*{{{*/
{
diff --git a/apt-pkg/contrib/fileutl.h b/apt-pkg/contrib/fileutl.h
index acfd560ab..cddfe2b45 100644
--- a/apt-pkg/contrib/fileutl.h
+++ b/apt-pkg/contrib/fileutl.h
@@ -159,6 +159,7 @@ time_t GetModificationTime(std::string const &Path);
bool Rename(std::string From, std::string To);
std::string GetTempDir();
+std::string GetTempDir(std::string const &User);
FileFd* GetTempFile(std::string const &Prefix = "",
bool ImmediateUnlink = true,
FileFd * const TmpFd = NULL);