]> git.saurik.com Git - apt.git/blobdiff - apt-pkg/deb/dpkgpm.cc
edsp: drop privileges before executing solvers
[apt.git] / apt-pkg / deb / dpkgpm.cc
index e94a8cfdc3be40e3dcd5aab63887dc3f32715af5..4a77942f169c711040e50c1fbf59ec0bc894798b 100644 (file)
@@ -49,6 +49,7 @@
 #include <utility>
 #include <vector>
 #include <sstream>
+#include <numeric>
 
 #include <apti18n.h>
                                                                        /*}}}*/
 using namespace std;
 
 APT_PURE static string
-AptHistoryUser()
+AptHistoryRequestingUser()
 {
-   stringstream out;
-   const char* env[]{"SUDO_USER", "PKEXEC_UID", nullptr};
-   for (int i=0; env[i] != nullptr; i++)
+   const char* EnvKeys[]{"SUDO_UID", "PKEXEC_UID", "PACKAGEKIT_CALLER_UID"};
+
+   for (const auto &Key: EnvKeys)
    {
-      if (getenv(env[i]) != nullptr)
+      if (getenv(Key) != nullptr)
       {
-         out << env[i] << "=" << getenv(env[i]) << " ";
+         int uid = atoi(getenv(Key));
+         if (uid > 0) {
+            struct passwd pwd;
+            struct passwd *result;
+            char buf[255];
+            if (getpwuid_r(uid, &pwd, buf, sizeof(buf), &result) == 0 && result != NULL) {
+               std::string res;
+               strprintf(res, "%s (%d)", pwd.pw_name, uid);
+               return res;
+            }
+         }
       }
    }
-   return out.str();
+   return "";
 }
 
 APT_PURE static unsigned int
@@ -466,7 +477,7 @@ bool pkgDPkgPM::RunScriptsWithPkgs(const char *Cnf)
       close(Pipes[0]);
       FILE *F = fdopen(Pipes[1],"w");
       if (F == 0) {
-         result = _error->Errno("fdopen","Faild to open new FD");
+         result = _error->Errno("fdopen","Failed to open new FD");
          break;
       }
       
@@ -892,8 +903,9 @@ bool pkgDPkgPM::OpenLog()
       }
       if (_config->Exists("Commandline::AsString") == true)
         WriteHistoryTag("Commandline", _config->Find("Commandline::AsString"));
-      if (AptHistoryUser() != "")
-         WriteHistoryTag("Requested-By", AptHistoryUser());
+      std::string RequestingUser = AptHistoryRequestingUser();
+      if (RequestingUser != "")
+         WriteHistoryTag("Requested-By", RequestingUser);
       WriteHistoryTag("Install", install);
       WriteHistoryTag("Reinstall", reinstall);
       WriteHistoryTag("Upgrade", upgrade);
@@ -1489,6 +1501,13 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress)
               _exit(100);
         }
 
+        // if color support isn't enabled/disabled explicitly tell
+        // dpkg to use the same state apt is using for its color support
+        if (_config->FindB("APT::Color", false) == true)
+           setenv("DPKG_COLORS", "always", 0);
+        else
+           setenv("DPKG_COLORS", "never", 0);
+
         execvp(Args[0], (char**) &Args[0]);
         cerr << "Could not exec dpkg!" << endl;
         _exit(100);
@@ -1518,20 +1537,14 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress)
       // the result of the waitpid call
       int res;
       int select_ret;
+      bool waitpid_failure = false;
       while ((res=waitpid(Child,&Status, WNOHANG)) != Child) {
         if(res < 0) {
-           // FIXME: move this to a function or something, looks ugly here
            // error handling, waitpid returned -1
            if (errno == EINTR)
               continue;
-           RunScripts("DPkg::Post-Invoke");
-
-           // Restore sig int/quit
-           signal(SIGQUIT,old_SIGQUIT);
-           signal(SIGINT,old_SIGINT);
-
-           signal(SIGHUP,old_SIGHUP);
-           return _error->Errno("waitpid","Couldn't wait for subprocess");
+           waitpid_failure = true;
+           break;
         }
 
         // wait for input or output here
@@ -1571,12 +1584,19 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress)
       // Restore sig int/quit
       signal(SIGQUIT,old_SIGQUIT);
       signal(SIGINT,old_SIGINT);
-      
       signal(SIGHUP,old_SIGHUP);
+
+      if (waitpid_failure == true)
+      {
+        strprintf(d->dpkg_error, "Sub-process %s couldn't be waited for.",Args[0]);
+        _error->Error("%s", d->dpkg_error.c_str());
+        break;
+      }
+
       // Check for an error code.
       if (WIFEXITED(Status) == 0 || WEXITSTATUS(Status) != 0)
       {
-        // if it was set to "keep-dpkg-runing" then we won't return
+        // if it was set to "keep-dpkg-running" then we won't return
         // here but keep the loop going and just report it as a error
         // for later
         bool const stopOnError = _config->FindB("Dpkg::StopOnError",true);
@@ -1594,16 +1614,12 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress)
       }
    }
    // dpkg is done at this point
-   d->progress->Stop();
    StopPtyMagic();
    CloseLog();
 
    if (pkgPackageManager::SigINTStop)
        _error->Warning(_("Operation was interrupted before it could finish"));
 
-   if (RunScripts("DPkg::Post-Invoke") == false)
-      return false;
-
    if (_config->FindB("Debug::pkgDPkgPM",false) == false)
    {
       std::string const oldpkgcache = _config->FindFile("Dir::cache::pkgcache");
@@ -1622,6 +1638,12 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress)
    }
 
    Cache.writeStateFile(NULL);
+
+   d->progress->Stop();
+
+   if (RunScripts("DPkg::Post-Invoke") == false)
+      return false;
+
    return d->dpkg_error.empty();
 }