From 1cd50d0bce19e0ae86f60a4e4995655ac001861e Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Wed, 27 Jun 2012 16:50:56 -0400 Subject: [PATCH] Defer group ID to name resolution until we actually need it. --- plugins/sudoers/pwutil.c | 43 ++++++++++++++------------------------- plugins/sudoers/sudoers.c | 4 ++-- plugins/sudoers/sudoers.h | 5 ++++- 3 files changed, 21 insertions(+), 31 deletions(-) diff --git a/plugins/sudoers/pwutil.c b/plugins/sudoers/pwutil.c index b887199bc..3e876d889 100644 --- a/plugins/sudoers/pwutil.c +++ b/plugins/sudoers/pwutil.c @@ -857,19 +857,27 @@ sudo_get_grlist(struct passwd *pw) } /* * Cache group db entry if it exists or a negative response if not. + * Use gids list from front-end if possible, otherwise getgrouplist(). */ + if (pw == sudo_user.pw && sudo_user.gids != NULL) { + gids = user_gids; + ngids = user_ngids; + user_gids = NULL; + user_ngids = 0; + } 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) { + efree(gids); + debug_return_ptr(NULL); + } } } if (ngids > 0) { @@ -896,27 +904,6 @@ done: debug_return_ptr(item->d.grlist); } -void -sudo_set_grlist(const char *user, GETGROUPS_T *gids, int ngids) -{ - struct cache_item key, *item; - struct rbnode *node; - debug_decl(sudo_set_grlist, SUDO_DEBUG_NSS) - - /* - * Cache group db entry if it doesn't already exist - */ - key.k.name = (char *) user; - if ((node = rbfind(grlist_cache, &key)) == NULL) { - if ((item = make_grlist_item(user, gids, ngids)) == NULL) - errorx(1, "unable to parse group list for %s", user); - if (rbinsert(grlist_cache, item) != NULL) - errorx(1, "unable to cache group list for %s, already exists", - user); - } - debug_return; -} - bool user_in_group(struct passwd *pw, const char *group) { diff --git a/plugins/sudoers/sudoers.c b/plugins/sudoers/sudoers.c index 02aaf97c0..1ffe4c07f 100644 --- a/plugins/sudoers/sudoers.c +++ b/plugins/sudoers/sudoers.c @@ -1430,8 +1430,8 @@ deserialize_info(char * const args[], char * const settings[], char * const user break; cp++; /* skip over comma */ } - sudo_set_grlist(user_name, gids, ngids); - efree(gids); + user_gids = gids; + user_ngids = ngids; } /* Setup debugging if indicated. */ diff --git a/plugins/sudoers/sudoers.h b/plugins/sudoers/sudoers.h index b0152b851..bf07650d3 100644 --- a/plugins/sudoers/sudoers.h +++ b/plugins/sudoers/sudoers.h @@ -83,6 +83,8 @@ struct sudo_user { #endif char *cwd; char *iolog_file; + GETGROUPS_T *gids; + int ngids; int closefrom; int lines; int cols; @@ -158,6 +160,8 @@ struct sudo_user { #define user_passwd (sudo_user.pw->pw_passwd) #define user_uuid (sudo_user.uuid) #define user_dir (sudo_user.pw->pw_dir) +#define user_gids (sudo_user.gids) +#define user_ngids (sudo_user.ngids) #define user_group_list (sudo_user.group_list) #define user_tty (sudo_user.tty) #define user_ttypath (sudo_user.ttypath) @@ -281,7 +285,6 @@ void sudo_grlist_addref(struct group_list *); void sudo_grlist_delref(struct group_list *); void sudo_pw_addref(struct passwd *); void sudo_pw_delref(struct passwd *); -void sudo_set_grlist(const char *, GETGROUPS_T *gids, int ngids); void sudo_setgrent(void); void sudo_setpwent(void); void sudo_setspent(void);