]> granicus.if.org Git - sudo/commitdiff
Use max_groups in front-end and plugin.
authorTodd C. Miller <Todd.Miller@courtesan.com>
Thu, 14 Feb 2013 20:52:27 +0000 (15:52 -0500)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Thu, 14 Feb 2013 20:52:27 +0000 (15:52 -0500)
plugins/sudoers/policy.c
plugins/sudoers/pwutil_impl.c
plugins/sudoers/sudoers.h
src/sudo.c

index 1fa112a8cb99ef466e5e1c0a01360df7c0b73909..b454d9327510450b354bfe367d89d7d409e7c087 100644 (file)
@@ -113,6 +113,7 @@ sudoers_policy_deserialize_info(void *v, char **runas_user, char **runas_group)
 
     /* Parse command line settings. */
     user_closefrom = -1;
+    sudo_user.max_groups = -1;
     for (cur = info->settings; *cur != NULL; cur++) {
        if (MATCHES(*cur, "closefrom=")) {
            user_closefrom = atoi(*cur + sizeof("closefrom=") - 1);
@@ -226,6 +227,10 @@ sudoers_policy_deserialize_info(void *v, char **runas_user, char **runas_group)
            set_interfaces(interfaces_string);
            continue;
        }
+       if (MATCHES(*cur, "max_groups=")) {
+           sudo_user.max_groups = atoi(*cur + sizeof("max_groups=") - 1);
+           continue;
+       }
     }
 
     for (cur = info->user_info; *cur != NULL; cur++) {
index c929bdc77980972e06ed4b567218028cf8604105..70c6899ca70b198c227998499d07cb0042dc9c34 100644 (file)
@@ -250,23 +250,29 @@ sudo_make_grlist_item(struct passwd *pw)
        user_gids = NULL;
        user_ngids = 0;
     } else {
+       if (sudo_user.max_groups != -1) {
+           ngids = sudo_user.max_groups;
+           gids = emalloc2(ngids, sizeof(GETGROUPS_T));
+           (void)getgrouplist(pw->pw_name, pw->pw_gid, gids, &ngids);
+       } else {
 #if defined(HAVE_SYSCONF) && defined(_SC_NGROUPS_MAX)
-        ngids = (int)sysconf(_SC_NGROUPS_MAX) * 2;
-        if (ngids < 0)
+           ngids = (int)sysconf(_SC_NGROUPS_MAX) * 2;
+           if (ngids < 0)
 #endif
-            ngids = NGROUPS_MAX * 2;
-       gids = emalloc2(ngids, sizeof(GETGROUPS_T));
-       if (getgrouplist(pw->pw_name, pw->pw_gid, gids, &ngids) == -1) {
-           efree(gids);
+               ngids = NGROUPS_MAX * 2;
            gids = emalloc2(ngids, sizeof(GETGROUPS_T));
            if (getgrouplist(pw->pw_name, pw->pw_gid, gids, &ngids) == -1) {
                efree(gids);
-               debug_return_ptr(NULL);
+               gids = emalloc2(ngids, sizeof(GETGROUPS_T));
+               if (getgrouplist(pw->pw_name, pw->pw_gid, gids, &ngids) == -1)
+                   ngids = -1;
            }
        }
     }
-    if (ngids <= 0)
+    if (ngids <= 0) {
+       efree(gids);
        debug_return_ptr(NULL);
+    }
 
 #ifdef HAVE_SETAUTHDB
     aix_setauthdb((char *) pw->pw_name);
@@ -328,6 +334,7 @@ again:
        }
     }
     grlist->ngroups = ngroups;
+    efree(gids);
 
 #ifdef HAVE_SETAUTHDB
     aix_restoreauthdb();
index 30fed52719b421fa31601d0cf66a846a3bf95738..98bf3456e439a6ef91e14cfb6b9c3d07403d0354 100644 (file)
@@ -93,6 +93,7 @@ struct sudo_user {
     int   lines;
     int   cols;
     int   flags;
+    int   max_groups;
     uid_t uid;
     uid_t gid;
     pid_t sid;
index 9823e2cea23b9e50c6b1b790e3371a490d1fdb54..ddeb28ff602a505e5abd053a9547ed9401efdd55 100644 (file)
@@ -343,23 +343,35 @@ fix_fds(void)
  * for when we cannot (or don't want to) use getgroups().
  */
 static int
-fill_group_list(struct user_details *ud, int maxgroups)
+fill_group_list(struct user_details *ud, int system_maxgroups)
 {
     int tries, rval = -1;
     debug_decl(fill_group_list, SUDO_DEBUG_UTIL)
 
     /*
-     * It is possible to belong to more groups in the group database
-     * than NGROUPS_MAX.  We start off with NGROUPS_MAX * 4 entries
-     * and double this as needed.
+     * If user specified a max number of groups, use it, otherwise keep
+     * trying getgrouplist() until we have enough room in the array.
      */
-    ud->groups = NULL;
-    ud->ngroups = maxgroups << 1;
-    for (tries = 0; tries < 10 && rval == -1; tries++) {
-       ud->ngroups <<= 1;
-       efree(ud->groups);
+    ud->ngroups = sudo_conf_max_groups();
+    if (ud->ngroups != -1) {
        ud->groups = emalloc2(ud->ngroups, sizeof(GETGROUPS_T));
-       rval = getgrouplist(ud->username, ud->gid, ud->groups, &ud->ngroups);
+       /* No error on insufficient space if user specified max_groups. */
+       (void)getgrouplist(ud->username, ud->gid, ud->groups, &ud->ngroups);
+       rval = 0;
+    } else {
+       /*
+        * It is possible to belong to more groups in the group database
+        * than NGROUPS_MAX.  We start off with NGROUPS_MAX * 4 entries
+        * and double this as needed.
+        */
+       ud->groups = NULL;
+       ud->ngroups = system_maxgroups << 1;
+       for (tries = 0; tries < 10 && rval == -1; tries++) {
+           ud->ngroups <<= 1;
+           efree(ud->groups);
+           ud->groups = emalloc2(ud->ngroups, sizeof(GETGROUPS_T));
+           rval = getgrouplist(ud->username, ud->gid, ud->groups, &ud->ngroups);
+       }
     }
     debug_return_int(rval);
 }