diff options
Diffstat (limited to 'src/libutil/util.cc')
-rw-r--r-- | src/libutil/util.cc | 131 |
1 files changed, 1 insertions, 130 deletions
diff --git a/src/libutil/util.cc b/src/libutil/util.cc index 375e0e1df892..5623b013125e 100644 --- a/src/libutil/util.cc +++ b/src/libutil/util.cc @@ -11,11 +11,8 @@ #include <sys/stat.h> #include <sys/wait.h> -#include <fcntl.h> - #include <sys/types.h> -#include <pwd.h> -#include <grp.h> +#include <fcntl.h> #include "util.hh" @@ -891,130 +888,4 @@ bool string2Int(const string & s, int & n) } -////////////////////////////////////////////////////////////////////// - - -static bool haveSwitched; -static uid_t savedUid, nixUid; -static gid_t savedGid, nixGid; - - -#if HAVE_SETRESUID -#define _setuid(uid) setresuid(uid, uid, savedUid) -#define _setgid(gid) setresgid(gid, gid, savedGid) -#else -/* Only works properly when run by root. */ -#define _setuid(uid) setuid(uid) -#define _setgid(gid) setgid(gid) -#endif - - -void switchToNixUser() -{ -#if 0 - fprintf(stderr, "real = %d/%d, effective = %d/%d\n", - getuid(), getgid(), geteuid(), getegid()); -#endif - - /* Note: we require setresuid for now since I don't want to think - to deeply about whether this works on systems that don't have - setresuid. It's already hard enough. */ - -#if HAVE_SETRESUID - - /* Setuid Nix operation works as follows: - - - The Nix binaries are owned by a Nix user and group, e.g., - nix.nix, and must setuid and setgid, e.g., - - rwsrwsr-x nix.nix - - - Users (say alice.users) are only allowed to run (most) Nix - operations if they are in the Nix group. If they aren't, - some read-only operations (like nix-env -qa) may still work. - - - We run mostly under the Nix user/group, but we switch back to - the calling user/group for some work, like reading Nix - expressions. - - */ - - - /* Don't do anything if this is not a setuid binary. */ - if (getuid() == geteuid() && getgid() == getegid()) return; - - /* Here we set the uid and gid to the Nix user and group, - respectively, IF the current (real) user is a member of the Nix - group. (The Nix group is the group of the current executable, - i.e., the current effective gid.) Otherwise we just drop all - privileges. */ - - nixGid = geteuid(); - - /* Get the supplementary group IDs for the current user. */ - int maxGids = 512, nrGids; - gid_t gids[maxGids]; - if ((nrGids = getgroups(maxGids, gids)) == -1) { - std::cerr << format("unable to query gids\n"); - exit(1); - } - - /* !!! Apparently it is unspecified whether getgroups() includes - the effective gid. In that case the following test is always - true *if* the program is installed setgid (which we do when we - have setresuid()). On Linux this doesn't appear to be the - case, but we should switch to the real gid before doing this - test, and then switch back to the saved gid. */ - - /* Check that the current user is a member of the Nix group. */ - bool found = false; - for (int i = 0; i < nrGids; ++i) - if (gids[i] == nixGid) { - found = true; - break; - } - - if (!found) { - /* Not in the Nix group - drop all root/Nix privileges. */ - _setgid(getgid()); - _setuid(getuid()); - return; - } - - /* Save the uid/gid of the caller so the we can switch back to - that uid/gid for temporary work, like accessing files, in - SwitchToOriginaluser. */ - savedUid = getuid(); - savedGid = getgid(); - - /* Set the real and effective gids to nixGid. Also make very sure - that this succeeded. We switch the gid first because we cannot - do it after we have dropped root uid. */ - if (_setgid(nixGid) != 0 || getgid() != nixGid || getegid() != nixGid) { - std::cerr << format("unable to set gid to `%1%'\n") % nixGid; - exit(1); - } - - /* The Nix uid is the effective uid of the owner of the current - executable, i.e., the current effective uid. */ - nixUid = geteuid(); - - /* This will drop all root privileges, setting the real, effective - and saved uids to pw->pw_uid. Also make very sure that this - succeeded.*/ - if (_setuid(nixUid) != 0 || getuid() != nixUid || geteuid() != nixUid) { - std::cerr << format("unable to set uid to `%1%'\n") % nixUid; - exit(1); - } - - /* !!! for setuid operation, we should: 1) wipe the environment; - 2) verify file descriptors 0, 1, 2; 3) etc. - See: http://www.daemon-systems.org/man/setuid.7.html - */ - - haveSwitched = true; -#endif -} - - } |