From c57ca7440560b6374b250fda52e68033992784ab Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Fri, 15 Jun 2018 14:05:14 -0600 Subject: [PATCH] Use new sudo_getgrouplist2() function instead of getgrouplist(). --- plugins/sudoers/cvtsudoers_pwutil.c | 2 +- plugins/sudoers/pwutil_impl.c | 31 +++--------------- src/sudo.c | 50 ++++++++--------------------- 3 files changed, 18 insertions(+), 65 deletions(-) diff --git a/plugins/sudoers/cvtsudoers_pwutil.c b/plugins/sudoers/cvtsudoers_pwutil.c index 9314b22c4..1ec54138c 100644 --- a/plugins/sudoers/cvtsudoers_pwutil.c +++ b/plugins/sudoers/cvtsudoers_pwutil.c @@ -289,7 +289,7 @@ static struct cache_item_gidlist *gidlist_item; /* * 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 * cvtsudoers_make_gidlist_item(const struct passwd *pw, char * const *unused1, diff --git a/plugins/sudoers/pwutil_impl.c b/plugins/sudoers/pwutil_impl.c index c4afe70db..11c1b75ba 100644 --- a/plugins/sudoers/pwutil_impl.c +++ b/plugins/sudoers/pwutil_impl.c @@ -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 - * 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 * 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"); 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 { -#ifdef HAVE_GETGROUPLIST_2 - ngids = getgrouplist_2(pw->pw_name, pw->pw_gid, &gids); - if (ngids == -1) { + gids = NULL; + if (sudo_getgrouplist2(pw->pw_name, pw->pw_gid, &gids, &ngids) == -1) { sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, "unable to allocate memory"); 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) { diff --git a/src/sudo.c b/src/sudo.c index a287ef899..d8d80c324 100644 --- a/src/sudo.c +++ b/src/sudo.c @@ -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(). * 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) /* - * If user specified a max number of groups, use it, otherwise keep - * trying getgrouplist() until we have enough room in the array. + * If user specified a max number of groups, use it, otherwise let + * sudo_getgrouplist2() allocate the group vector. */ ud->ngroups = sudo_conf_max_groups(); if (ud->ngroups > 0) { 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; + if (ud->groups != NULL) { + /* No error on insufficient space if user specified max_groups. */ + (void)sudo_getgrouplist2(ud->username, ud->gid, &ud->groups, + &ud->ngroups); + ret = 0; } - /* No error on insufficient space if user specified max_groups. */ - (void)getgrouplist(ud->username, ud->gid, ud->groups, &ud->ngroups); - ret = 0; } else { -#ifdef HAVE_GETGROUPLIST_2 ud->groups = NULL; - ud->ngroups = getgrouplist_2(ud->username, ud->gid, &ud->groups); - if (ud->ngroups != -1) - 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 */ + ret = sudo_getgrouplist2(ud->username, ud->gid, &ud->groups, + &ud->ngroups); } -done: if (ret == -1) { + sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); 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); } else { 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); } debug_return_int(ret); -- 2.40.0