]> granicus.if.org Git - sudo/commitdiff
Set user groups in exec_setup() if they were not already set by
authorTodd C. Miller <Todd.Miller@courtesan.com>
Wed, 22 Jun 2016 16:21:29 +0000 (10:21 -0600)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Wed, 22 Jun 2016 16:21:29 +0000 (10:21 -0600)
policy_init_session().  Bug #749

src/sudo.c
src/sudo.h

index 005596d6d848a71670b7862f78d2c2b910551e8a..58085e9e73e5b0a44765b271ef52a8dcc9185d4e 100644 (file)
@@ -616,7 +616,7 @@ command_info_to_details(char * const info[], struct command_details *details)
     memset(details, 0, sizeof(*details));
     details->closefrom = -1;
     details->execfd = -1;
-    details->flags = CD_SUDOEDIT_CHECKDIR;
+    details->flags = CD_SUDOEDIT_CHECKDIR | CD_SET_GROUPS;
     TAILQ_INIT(&details->preserved_fds);
 
 #define SET_STRING(s, n) \
@@ -938,6 +938,39 @@ restore_nproc(void)
 #endif /* __linux__ */
 }
 
+static bool
+set_user_groups(struct command_details *details)
+{
+    bool rval = false;
+    debug_decl(set_user_groups, SUDO_DEBUG_EXEC)
+
+    if (!ISSET(details->flags, CD_PRESERVE_GROUPS)) {
+       if (details->ngroups >= 0) {
+           if (sudo_setgroups(details->ngroups, details->groups) < 0) {
+               sudo_warn(U_("unable to set supplementary group IDs"));
+               goto done;
+           }
+       }
+    }
+#ifdef HAVE_SETEUID
+    if (ISSET(details->flags, CD_SET_EGID) && setegid(details->egid)) {
+       sudo_warn(U_("unable to set effective gid to runas gid %u"),
+           (unsigned int)details->egid);
+       goto done;
+    }
+#endif
+    if (ISSET(details->flags, CD_SET_GID) && setgid(details->gid)) {
+       sudo_warn(U_("unable to set gid to runas gid %u"),
+           (unsigned int)details->gid);
+       goto done;
+    }
+    rval = true;
+
+done:
+    CLR(details->flags, CD_SET_GROUPS);
+    debug_return_bool(rval);
+}
+
 /*
  * Setup the execution environment immediately prior to the call to execve().
  * Group setup is performed by policy_init_session(), called earlier.
@@ -1019,6 +1052,12 @@ exec_setup(struct command_details *details, const char *ptyname, int ptyfd)
 #endif /* HAVE_LOGIN_CAP_H */
     }
 
+    if (ISSET(details->flags, CD_SET_GROUPS)) {
+       /* set_user_groups() prints error message on failure. */
+       if (!set_user_groups(details))
+           goto done;
+    }
+
     if (ISSET(details->flags, CD_SET_PRIORITY)) {
        if (setpriority(PRIO_PROCESS, 0, details->priority) != 0) {
            sudo_warn(U_("unable to set process priority"));
@@ -1347,28 +1386,10 @@ policy_init_session(struct command_details *details)
      * as part of the session setup.  This allows for dynamic
      * groups to be set via pam_group(8) in pam_setcred(3).
      */
-    if (!ISSET(details->flags, CD_PRESERVE_GROUPS)) {
-       if (details->ngroups >= 0) {
-           if (sudo_setgroups(details->ngroups, details->groups) < 0) {
-               sudo_warn(U_("unable to set supplementary group IDs"));
-               rval = -1;
-               goto done;
-           }
-       }
-    }
-#ifdef HAVE_SETEUID
-    if (ISSET(details->flags, CD_SET_EGID) && setegid(details->egid)) {
-       sudo_warn(U_("unable to set effective gid to runas gid %u"),
-           (unsigned int)details->egid);
-       rval = -1;
-       goto done;
-    }
-#endif
-    if (ISSET(details->flags, CD_SET_GID) && setgid(details->gid)) {
-       sudo_warn(U_("unable to set gid to runas gid %u"),
-           (unsigned int)details->gid);
-       rval = -1;
-       goto done;
+    if (ISSET(details->flags, CD_SET_GROUPS)) {
+       /* set_user_groups() prints error message on failure. */
+       if (!set_user_groups(details))
+           goto done;
     }
 
     if (policy_plugin.u.policy->init_session) {
index 32987f30c1e74c02e5cbe4d71bf6019fddcdf01d..e871acde4e019a2e41bf14072e47c3f8cc6fb703 100644 (file)
@@ -129,6 +129,7 @@ struct user_details {
 #define CD_SUDOEDIT_COPY       0x08000
 #define CD_SUDOEDIT_FOLLOW     0x10000
 #define CD_SUDOEDIT_CHECKDIR   0x20000
+#define CD_SET_GROUPS          0x40000
 
 struct preserved_fd {
     TAILQ_ENTRY(preserved_fd) entries;