about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2006-09-04T22·55+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2006-09-04T22·55+0000
commitbafc1690fc4a2a2c3ff81ff1c1a677f208d3b1b7 (patch)
tree822877e73d7e4ffe4dd3ef3b1a1ff02dafaed186
parente5a6c09b12a9a68ba604d4e95adf28482ae8fc8d (diff)
* Move setuid stuff to libutil.
* Install libexpr header files.

-rw-r--r--src/libexpr/Makefile.am13
-rw-r--r--src/libmain/shared.cc133
-rw-r--r--src/libutil/util.cc136
-rw-r--r--src/libutil/util.hh6
4 files changed, 146 insertions, 142 deletions
diff --git a/src/libexpr/Makefile.am b/src/libexpr/Makefile.am
index 01a2a2f12dbc..3d255d6bbd32 100644
--- a/src/libexpr/Makefile.am
+++ b/src/libexpr/Makefile.am
@@ -1,11 +1,12 @@
 pkglib_LTLIBRARIES = libexpr.la
 
-libexpr_la_SOURCES = nixexpr.cc nixexpr.hh \
- eval.cc eval.hh primops.cc \
- lexer-tab.cc lexer-tab.hh parser-tab.cc parser-tab.hh \
- get-drvs.cc get-drvs.hh \
- attr-path.cc attr-path.hh \
- expr-to-xml.cc expr-to-xml.hh
+libexpr_la_SOURCES = \
+ nixexpr.cc eval.cc primops.cc lexer-tab.cc parser-tab.cc \
+ get-drvs.cc attr-path.cc expr-to-xml.cc
+
+pkginclude_HEADERS = \
+ nixexpr.hh eval.hh parser.hh lexer-tab.hh parser-tab.hh \
+ get-drvs.hh attr-path.hh expr-to-xml.hh
 
 libexpr_la_LIBADD = ../libutil/libutil.la ../libstore/libstore.la \
  ../boost/format/libformat.la
diff --git a/src/libmain/shared.cc b/src/libmain/shared.cc
index c153a6fafcad..3064299c8518 100644
--- a/src/libmain/shared.cc
+++ b/src/libmain/shared.cc
@@ -207,139 +207,6 @@ static void initAndRun(int argc, char * * argv)
 }
 
 
-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
-
-
-SwitchToOriginalUser::SwitchToOriginalUser()
-{
-#if SETUID_HACK && HAVE_SETRESUID
-    /* Temporarily switch the effective uid/gid back to the saved
-       uid/gid (which is the uid/gid of the user that executed the Nix
-       program; it's *not* the real uid/gid, since we changed that to
-       the Nix user in switchToNixUser()). */
-    if (haveSwitched) {
-        if (setuid(savedUid) == -1)
-            throw SysError(format("temporarily restoring uid to `%1%'") % savedUid); 
-        if (setgid(savedGid) == -1)
-            throw SysError(format("temporarily restoring gid to `%1%'") % savedGid); 
-    }
-#endif
-}
-
-
-SwitchToOriginalUser::~SwitchToOriginalUser()
-{
-#if SETUID_HACK && HAVE_SETRESUID
-    /* Switch the effective uid/gid back to the Nix user. */
-    if (haveSwitched) {
-        if (setuid(nixUid) == -1)
-            throw SysError(format("restoring uid to `%1%'") % nixUid); 
-        if (setgid(nixGid) == -1)
-            throw SysError(format("restoring gid to `%1%'") % nixGid); 
-    }
-#endif
-}
-
-
-void switchToNixUser()
-{
-#if SETUID_HACK
-
-    /* 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.  Otherwise we just drop all privileges. */
-    
-    /* Lookup the Nix gid. */
-    struct group * gr = getgrnam(NIX_GROUP);
-    if (!gr) {
-        cerr << format("missing group `%1%'\n") % NIX_GROUP;
-        exit(1);
-    }
-
-    /* Get the supplementary group IDs for the current user. */
-    int maxGids = 512, nrGids;
-    gid_t gids[maxGids];
-    if ((nrGids = getgroups(maxGids, gids)) == -1) {
-        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] == gr->gr_gid) {
-            found = true;
-            break;
-        }
-
-    if (!found) {
-        /* Not in the Nix group - drop all root/Nix privileges. */
-        _setgid(getgid());
-        _setuid(getuid());
-        return;
-    }
-
-    savedUid = getuid();
-    savedGid = getgid();
-
-    /* Set the real, effective and saved gids to gr->gr_gid.  Also
-       make very sure that this succeeded.  We switch the gid first
-       because we cannot do it after we have dropped root uid. */
-    nixGid = gr->gr_gid;
-    if (_setgid(nixGid) != 0 || getgid() != nixGid || getegid() != nixGid) {
-        cerr << format("unable to set gid to `%1%'\n") % NIX_GROUP;
-        exit(1);
-    }
-
-    /* Lookup the Nix uid. */
-    struct passwd * pw = getpwnam(NIX_USER);
-    if (!pw) {
-        cerr << format("missing user `%1%'\n") % NIX_USER;
-        exit(1);
-    }
-
-    /* This will drop all root privileges, setting the real, effective
-       and saved uids to pw->pw_uid.  Also make very sure that this
-       succeeded.*/
-    nixUid = pw->pw_uid;
-    if (_setuid(nixUid) != 0 || getuid() != nixUid || geteuid() != nixUid) {
-        cerr << format("unable to set uid to `%1%'\n") % NIX_USER;
-        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
-}
-
-
 }
 
 
diff --git a/src/libutil/util.cc b/src/libutil/util.cc
index 44b39f8c623a..eac124edbd89 100644
--- a/src/libutil/util.cc
+++ b/src/libutil/util.cc
@@ -850,4 +850,140 @@ 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
+
+
+SwitchToOriginalUser::SwitchToOriginalUser()
+{
+#if SETUID_HACK && HAVE_SETRESUID
+    /* Temporarily switch the effective uid/gid back to the saved
+       uid/gid (which is the uid/gid of the user that executed the Nix
+       program; it's *not* the real uid/gid, since we changed that to
+       the Nix user in switchToNixUser()). */
+    if (haveSwitched) {
+        if (setuid(savedUid) == -1)
+            throw SysError(format("temporarily restoring uid to `%1%'") % savedUid); 
+        if (setgid(savedGid) == -1)
+            throw SysError(format("temporarily restoring gid to `%1%'") % savedGid); 
+    }
+#endif
+}
+
+
+SwitchToOriginalUser::~SwitchToOriginalUser()
+{
+#if SETUID_HACK && HAVE_SETRESUID
+    /* Switch the effective uid/gid back to the Nix user. */
+    if (haveSwitched) {
+        if (setuid(nixUid) == -1)
+            throw SysError(format("restoring uid to `%1%'") % nixUid); 
+        if (setgid(nixGid) == -1)
+            throw SysError(format("restoring gid to `%1%'") % nixGid); 
+    }
+#endif
+}
+
+
+void switchToNixUser()
+{
+#if SETUID_HACK
+
+    /* 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.  Otherwise we just drop all privileges. */
+    
+    /* Lookup the Nix gid. */
+    struct group * gr = getgrnam(NIX_GROUP);
+    if (!gr) {
+        cerr << format("missing group `%1%'\n") % NIX_GROUP;
+        exit(1);
+    }
+
+    /* Get the supplementary group IDs for the current user. */
+    int maxGids = 512, nrGids;
+    gid_t gids[maxGids];
+    if ((nrGids = getgroups(maxGids, gids)) == -1) {
+        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] == gr->gr_gid) {
+            found = true;
+            break;
+        }
+
+    if (!found) {
+        /* Not in the Nix group - drop all root/Nix privileges. */
+        _setgid(getgid());
+        _setuid(getuid());
+        return;
+    }
+
+    savedUid = getuid();
+    savedGid = getgid();
+
+    /* Set the real, effective and saved gids to gr->gr_gid.  Also
+       make very sure that this succeeded.  We switch the gid first
+       because we cannot do it after we have dropped root uid. */
+    nixGid = gr->gr_gid;
+    if (_setgid(nixGid) != 0 || getgid() != nixGid || getegid() != nixGid) {
+        cerr << format("unable to set gid to `%1%'\n") % NIX_GROUP;
+        exit(1);
+    }
+
+    /* Lookup the Nix uid. */
+    struct passwd * pw = getpwnam(NIX_USER);
+    if (!pw) {
+        cerr << format("missing user `%1%'\n") % NIX_USER;
+        exit(1);
+    }
+
+    /* This will drop all root privileges, setting the real, effective
+       and saved uids to pw->pw_uid.  Also make very sure that this
+       succeeded.*/
+    nixUid = pw->pw_uid;
+    if (_setuid(nixUid) != 0 || getuid() != nixUid || geteuid() != nixUid) {
+        cerr << format("unable to set uid to `%1%'\n") % NIX_USER;
+        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
+}
+
+
 }
diff --git a/src/libutil/util.hh b/src/libutil/util.hh
index b4a61ae04a0d..52ef2c6eb20e 100644
--- a/src/libutil/util.hh
+++ b/src/libutil/util.hh
@@ -246,15 +246,15 @@ string int2String(int n);
 bool string2Int(const string & s, int & n);
 
 
-/* !!! HACK HACK HACK - this should be in shared.hh, but it's to
-   facilitate a quick hack - will remove this eventually (famous last
-   words). */
+/* Setuid support. */
 struct SwitchToOriginalUser
 {
     SwitchToOriginalUser();
     ~SwitchToOriginalUser();
 };
 
+void switchToNixUser();
+
  
 }