From 9983999d294887046abf386adc31190700d89b61 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 13 Oct 2014 10:57:30 +0200 Subject: [PATCH] Fix backward compatiblity of the new pkgAcquireMethod::DropPrivsOrDie() Do not drop privileges in the methods when using a older version of libapt that does not support the chown magic in partial/ yet. To do this DropPrivileges() now will ignore a empty Apt::Sandbox::User. Cleanup all hardcoded _apt along the way. --- apt-pkg/acquire-item.cc | 12 +++++++++--- apt-pkg/acquire.cc | 5 +++-- apt-pkg/contrib/fileutl.cc | 7 ++++++- apt-pkg/init.cc | 3 +++ methods/ftp.cc | 7 ++++--- methods/gpgv.cc | 14 +++++++++++--- methods/gzip.cc | 12 ++++++++++-- methods/http.cc | 2 ++ methods/http_main.cc | 1 - methods/https.cc | 12 ++++++++++-- methods/https.h | 2 ++ 11 files changed, 60 insertions(+), 17 deletions(-) diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index 97ff1bd18..44d45cedb 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -215,7 +215,11 @@ bool pkgAcquire::Item::Rename(string From,string To) void pkgAcquire::Item::QueueURI(ItemDesc &Item) { if (RealFileExists(DestFile)) - ChangeOwnerAndPermissionOfFile("GetPartialFileName", DestFile.c_str(), "_apt", "root", 0600); + { + std::string SandboxUser = _config->Find("APT::Sandbox::User"); + ChangeOwnerAndPermissionOfFile("GetPartialFileName", DestFile.c_str(), + SandboxUser.c_str(), "root", 0600); + } Owner->Enqueue(Item); } void pkgAcquire::Item::Dequeue() @@ -2486,7 +2490,8 @@ bool pkgAcqArchive::QueueNext() else { PartialSize = Buf.st_size; - ChangeOwnerAndPermissionOfFile("pkgAcqArchive::QueueNext", DestFile.c_str(), "_apt", "root", 0600); + std::string SandboxUser = _config->Find("APT::Sandbox::User"); + ChangeOwnerAndPermissionOfFile("pkgAcqArchive::QueueNext",DestFile.c_str(), SandboxUser.c_str(), "root", 0600); } } @@ -2654,7 +2659,8 @@ pkgAcqFile::pkgAcqFile(pkgAcquire *Owner,string URI, HashStringList const &Hashe else { PartialSize = Buf.st_size; - ChangeOwnerAndPermissionOfFile("pkgAcqFile", DestFile.c_str(), "_apt", "root", 0600); + std::string SandboxUser = _config->Find("APT::Sandbox::User"); + ChangeOwnerAndPermissionOfFile("pkgAcqFile", DestFile.c_str(), SandboxUser.c_str(), "root", 0600); } } diff --git a/apt-pkg/acquire.cc b/apt-pkg/acquire.cc index 34c7f06de..3ef912600 100644 --- a/apt-pkg/acquire.cc +++ b/apt-pkg/acquire.cc @@ -83,10 +83,11 @@ static bool SetupAPTPartialDirectory(std::string const &grand, std::string const if (getuid() == 0) // if we aren't root, we can't chown, so don't try it { - struct passwd *pw = getpwnam("_apt"); + std::string SandboxUser = _config->Find("APT::Sandbox::User"); + struct passwd *pw = getpwnam(SandboxUser.c_str()); struct group *gr = getgrnam("root"); if (pw != NULL && gr != NULL && chown(partial.c_str(), pw->pw_uid, gr->gr_gid) != 0) - _error->WarningE("SetupAPTPartialDirectory", "chown to _apt:root of directory %s failed", partial.c_str()); + _error->WarningE("SetupAPTPartialDirectory", "chown to %s:root of directory %s failed", SandboxUser.c_str(), partial.c_str()); } if (chmod(partial.c_str(), 0700) != 0) _error->WarningE("SetupAPTPartialDirectory", "chmod 0700 of directory %s failed", partial.c_str()); diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index 3e592d94f..f6351b7b5 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -2168,6 +2168,12 @@ bool DropPrivileges() /*{{{*/ if(_config->FindB("Debug::NoDropPrivs", false) == true) return true; + // empty setting disables DropPrivilidges - this also ensures + // backward compatibility, see bug #764506 + const std::string toUser = _config->Find("APT::Sandbox::User"); + if (toUser.empty()) + return true; + #if __gnu_linux__ #if defined(PR_SET_NO_NEW_PRIVS) && ( PR_SET_NO_NEW_PRIVS != 38 ) #error "PR_SET_NO_NEW_PRIVS is defined, but with a different value than expected!" @@ -2186,7 +2192,6 @@ bool DropPrivileges() /*{{{*/ if (old_uid != 0) return true; - const std::string toUser = _config->Find("APT::Sandbox::User", "_apt"); struct passwd *pw = getpwnam(toUser.c_str()); if (pw == NULL) return _error->Error("No user %s, can not drop rights", toUser.c_str()); diff --git a/apt-pkg/init.cc b/apt-pkg/init.cc index 82dff4ee8..8d206e428 100644 --- a/apt-pkg/init.cc +++ b/apt-pkg/init.cc @@ -95,6 +95,9 @@ bool pkgInitConfig(Configuration &Cnf) // Default cdrom mount point Cnf.CndSet("Acquire::cdrom::mount", "/media/cdrom/"); + // The default user we drop to in the methods + Cnf.CndSet("APT::Sandbox::User", "_apt"); + bool Res = true; // Read an alternate config file diff --git a/methods/ftp.cc b/methods/ftp.cc index 5b739ea06..0504e5872 100644 --- a/methods/ftp.cc +++ b/methods/ftp.cc @@ -988,6 +988,10 @@ bool FtpMethod::Configuration(string Message) return false; TimeOut = _config->FindI("Acquire::Ftp::Timeout",TimeOut); + + // no more active ftp, sorry + DropPrivsOrDie(); + return true; } /*}}}*/ @@ -1141,8 +1145,5 @@ int main(int, const char *argv[]) FtpMethod Mth; - // no more active ftp, sorry - Mth.DropPrivsOrDie(); - return Mth.Run(); } diff --git a/methods/gpgv.cc b/methods/gpgv.cc index 7e8500c51..488c16826 100644 --- a/methods/gpgv.cc +++ b/methods/gpgv.cc @@ -44,12 +44,22 @@ class GPGVMethod : public pkgAcqMethod protected: virtual bool Fetch(FetchItem *Itm); - + virtual bool Configuration(string Message); public: GPGVMethod() : pkgAcqMethod("1.0",SingleInstance | SendConfig) {}; }; +bool GPGVMethod::Configuration(string Message) +{ + if (pkgAcqMethod::Configuration(Message) == false) + return false; + + DropPrivsOrDie(); + + return true; +} + string GPGVMethod::VerifyGetSigners(const char *file, const char *outfile, vector &GoodSigners, vector &BadSigners, @@ -265,7 +275,5 @@ int main() GPGVMethod Mth; - Mth.DropPrivsOrDie(); - return Mth.Run(); } diff --git a/methods/gzip.cc b/methods/gzip.cc index 7ffcda60f..387c05f2e 100644 --- a/methods/gzip.cc +++ b/methods/gzip.cc @@ -33,12 +33,22 @@ const char *Prog; class GzipMethod : public pkgAcqMethod { virtual bool Fetch(FetchItem *Itm); + virtual bool Configuration(std::string Message); public: GzipMethod() : pkgAcqMethod("1.1",SingleInstance | SendConfig) {}; }; +bool GzipMethod::Configuration(std::string Message) +{ + if (pkgAcqMethod::Configuration(Message) == false) + return false; + + DropPrivsOrDie(); + + return true; +} // GzipMethod::Fetch - Decompress the passed URI /*{{{*/ // --------------------------------------------------------------------- @@ -140,7 +150,5 @@ int main(int, char *argv[]) GzipMethod Mth; - Mth.DropPrivsOrDie(); - return Mth.Run(); } diff --git a/methods/http.cc b/methods/http.cc index c00b439b7..a5de13511 100644 --- a/methods/http.cc +++ b/methods/http.cc @@ -770,6 +770,8 @@ bool HttpMethod::Configuration(string Message) if (ServerMethod::Configuration(Message) == false) return false; + DropPrivsOrDie(); + AllowRedirect = _config->FindB("Acquire::http::AllowRedirect",true); PipelineDepth = _config->FindI("Acquire::http::Pipeline-Depth", PipelineDepth); diff --git a/methods/http_main.cc b/methods/http_main.cc index f21a5709c..cd52c42e8 100644 --- a/methods/http_main.cc +++ b/methods/http_main.cc @@ -15,6 +15,5 @@ int main() HttpMethod Mth; - Mth.DropPrivsOrDie(); return Mth.Loop(); } diff --git a/methods/https.cc b/methods/https.cc index 16d564b34..366148e19 100644 --- a/methods/https.cc +++ b/methods/https.cc @@ -37,6 +37,16 @@ /*}}}*/ using namespace std; +bool HttpsMethod::Configuration(std::string Message) +{ + if (pkgAcqMethod::Configuration(Message) == false) + return false; + + DropPrivsOrDie(); + + return true; +} + size_t HttpsMethod::parse_header(void *buffer, size_t size, size_t nmemb, void *userp) { @@ -452,8 +462,6 @@ int main() HttpsMethod Mth; curl_global_init(CURL_GLOBAL_SSL) ; - Mth.DropPrivsOrDie(); - return Mth.Run(); } diff --git a/methods/https.h b/methods/https.h index 0387cb9b5..9df18e83a 100644 --- a/methods/https.h +++ b/methods/https.h @@ -58,6 +58,8 @@ class HttpsMethod : public pkgAcqMethod static const int DL_MIN_SPEED = 10; virtual bool Fetch(FetchItem *); + virtual bool Configuration(std::string Message); + static size_t parse_header(void *buffer, size_t size, size_t nmemb, void *userp); static size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp); static int progress_callback(void *clientp, double dltotal, double dlnow, -- 2.45.2