Use new sudo_getgrouplist2() function instead of getgrouplist().

This commit is contained in:
Todd C. Miller
2018-06-15 14:05:14 -06:00
parent 0ae9662833
commit c57ca74405
3 changed files with 19 additions and 66 deletions

View File

@@ -289,7 +289,7 @@ static struct cache_item_gidlist *gidlist_item;
/* /*
* Dynamically allocate space for a struct item plus the key and data * Dynamically allocate space for a struct item plus the key and data
* elements. Fills in datum from user_gids or from getgrouplist(3). * elements. Fills in datum from user_gids or from sudo_getgrouplist2(3).
*/ */
struct cache_item * struct cache_item *
cvtsudoers_make_gidlist_item(const struct passwd *pw, char * const *unused1, cvtsudoers_make_gidlist_item(const struct passwd *pw, char * const *unused1,

View File

@@ -227,7 +227,7 @@ sudo_make_gritem(gid_t gid, const char *name)
/* /*
* Dynamically allocate space for a struct item plus the key and data * Dynamically allocate space for a struct item plus the key and data
* elements. Fills in datum from user_gids or from getgrouplist(3). * elements. Fills in datum from user_gids or from sudo_getgrouplist2(3).
*/ */
struct cache_item * struct cache_item *
sudo_make_gidlist_item(const struct passwd *pw, char * const *unused1, sudo_make_gidlist_item(const struct passwd *pw, char * const *unused1,
@@ -258,37 +258,14 @@ sudo_make_gidlist_item(const struct passwd *pw, char * const *unused1,
"unable to allocate memory"); "unable to allocate memory");
debug_return_ptr(NULL); debug_return_ptr(NULL);
} }
(void)getgrouplist(pw->pw_name, pw->pw_gid, gids, &ngids); (void)sudo_getgrouplist2(pw->pw_name, pw->pw_gid, &gids, &ngids);
} else { } else {
#ifdef HAVE_GETGROUPLIST_2 gids = NULL;
ngids = getgrouplist_2(pw->pw_name, pw->pw_gid, &gids); if (sudo_getgrouplist2(pw->pw_name, pw->pw_gid, &gids, &ngids) == -1) {
if (ngids == -1) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
"unable to allocate memory"); "unable to allocate memory");
debug_return_ptr(NULL); debug_return_ptr(NULL);
} }
#else
ngids = (int)sysconf(_SC_NGROUPS_MAX) * 2;
if (ngids < 0)
ngids = NGROUPS_MAX * 2;
gids = reallocarray(NULL, ngids, sizeof(GETGROUPS_T));
if (gids == NULL) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
"unable to allocate memory");
debug_return_ptr(NULL);
}
if (getgrouplist(pw->pw_name, pw->pw_gid, gids, &ngids) == -1) {
free(gids);
gids = reallocarray(NULL, ngids, sizeof(GETGROUPS_T));
if (gids == NULL) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
"unable to allocate memory");
debug_return_ptr(NULL);
}
if (getgrouplist(pw->pw_name, pw->pw_gid, gids, &ngids) == -1)
ngids = -1;
}
#endif /* HAVE_GETGROUPLIST_2 */
} }
} }
if (ngids <= 0) { if (ngids <= 0) {

View File

@@ -366,7 +366,7 @@ fix_fds(void)
} }
/* /*
* Allocate space for groups and fill in using getgrouplist() * Allocate space for groups and fill in using sudo_getgrouplist2()
* for when we cannot (or don't want to) use getgroups(). * for when we cannot (or don't want to) use getgroups().
* Returns 0 on success and -1 on failure. * Returns 0 on success and -1 on failure.
*/ */
@@ -377,55 +377,31 @@ fill_group_list(struct user_details *ud, int system_maxgroups)
debug_decl(fill_group_list, SUDO_DEBUG_UTIL) debug_decl(fill_group_list, SUDO_DEBUG_UTIL)
/* /*
* If user specified a max number of groups, use it, otherwise keep * If user specified a max number of groups, use it, otherwise let
* trying getgrouplist() until we have enough room in the array. * sudo_getgrouplist2() allocate the group vector.
*/ */
ud->ngroups = sudo_conf_max_groups(); ud->ngroups = sudo_conf_max_groups();
if (ud->ngroups > 0) { if (ud->ngroups > 0) {
ud->groups = reallocarray(NULL, ud->ngroups, sizeof(GETGROUPS_T)); ud->groups = reallocarray(NULL, ud->ngroups, sizeof(GETGROUPS_T));
if (ud->groups == NULL) { if (ud->groups != NULL) {
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
goto done;
}
/* No error on insufficient space if user specified max_groups. */ /* No error on insufficient space if user specified max_groups. */
(void)getgrouplist(ud->username, ud->gid, ud->groups, &ud->ngroups); (void)sudo_getgrouplist2(ud->username, ud->gid, &ud->groups,
&ud->ngroups);
ret = 0; ret = 0;
}
} else { } else {
#ifdef HAVE_GETGROUPLIST_2
ud->groups = NULL; ud->groups = NULL;
ud->ngroups = getgrouplist_2(ud->username, ud->gid, &ud->groups); ret = sudo_getgrouplist2(ud->username, ud->gid, &ud->groups,
if (ud->ngroups != -1) &ud->ngroups);
ret = 0;
#else
int tries;
/*
* 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 && ret == -1; tries++) {
ud->ngroups <<= 1;
free(ud->groups);
ud->groups = reallocarray(NULL, ud->ngroups, sizeof(GETGROUPS_T));
if (ud->groups == NULL) {
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
goto done;
} }
ret = getgrouplist(ud->username, ud->gid, ud->groups, &ud->ngroups);
}
#endif /* HAVE_GETGROUPLIST_2 */
}
done:
if (ret == -1) { if (ret == -1) {
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO, sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
"%s: %s: unable to get groups via getgrouplist()", "%s: %s: unable to get groups via sudo_getgrouplist2()",
__func__, ud->username); __func__, ud->username);
} else { } else {
sudo_debug_printf(SUDO_DEBUG_INFO, sudo_debug_printf(SUDO_DEBUG_INFO,
"%s: %s: got %d groups via getgrouplist()", "%s: %s: got %d groups via sudo_getgrouplist2()",
__func__, ud->username, ud->ngroups); __func__, ud->username, ud->ngroups);
} }
debug_return_int(ret); debug_return_int(ret);