/* 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);
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++) {
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);
}
}
grlist->ngroups = ngroups;
+ efree(gids);
#ifdef HAVE_SETAUTHDB
aix_restoreauthdb();
* 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);
}