Defer group ID to name resolution until we actually need it.

This commit is contained in:
Todd C. Miller
2012-06-27 16:50:56 -04:00
parent faf89fc792
commit 1cd50d0bce
3 changed files with 21 additions and 31 deletions

View File

@@ -857,19 +857,27 @@ sudo_get_grlist(struct passwd *pw)
} }
/* /*
* Cache group db entry if it exists or a negative response if not. * 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) #if defined(HAVE_SYSCONF) && defined(_SC_NGROUPS_MAX)
ngids = (int)sysconf(_SC_NGROUPS_MAX) * 2; ngids = (int)sysconf(_SC_NGROUPS_MAX) * 2;
if (ngids < 0) if (ngids < 0)
#endif #endif
ngids = NGROUPS_MAX * 2; ngids = NGROUPS_MAX * 2;
gids = emalloc2(ngids, sizeof(GETGROUPS_T));
if (getgrouplist(pw->pw_name, pw->pw_gid, gids, &ngids) == -1) {
efree(gids);
gids = emalloc2(ngids, sizeof(GETGROUPS_T)); gids = emalloc2(ngids, sizeof(GETGROUPS_T));
if (getgrouplist(pw->pw_name, pw->pw_gid, gids, &ngids) == -1) { if (getgrouplist(pw->pw_name, pw->pw_gid, gids, &ngids) == -1) {
efree(gids); 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) { if (ngids > 0) {
@@ -896,27 +904,6 @@ done:
debug_return_ptr(item->d.grlist); 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 bool
user_in_group(struct passwd *pw, const char *group) user_in_group(struct passwd *pw, const char *group)
{ {

View File

@@ -1430,8 +1430,8 @@ deserialize_info(char * const args[], char * const settings[], char * const user
break; break;
cp++; /* skip over comma */ cp++; /* skip over comma */
} }
sudo_set_grlist(user_name, gids, ngids); user_gids = gids;
efree(gids); user_ngids = ngids;
} }
/* Setup debugging if indicated. */ /* Setup debugging if indicated. */

View File

@@ -83,6 +83,8 @@ struct sudo_user {
#endif #endif
char *cwd; char *cwd;
char *iolog_file; char *iolog_file;
GETGROUPS_T *gids;
int ngids;
int closefrom; int closefrom;
int lines; int lines;
int cols; int cols;
@@ -158,6 +160,8 @@ struct sudo_user {
#define user_passwd (sudo_user.pw->pw_passwd) #define user_passwd (sudo_user.pw->pw_passwd)
#define user_uuid (sudo_user.uuid) #define user_uuid (sudo_user.uuid)
#define user_dir (sudo_user.pw->pw_dir) #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_group_list (sudo_user.group_list)
#define user_tty (sudo_user.tty) #define user_tty (sudo_user.tty)
#define user_ttypath (sudo_user.ttypath) #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_grlist_delref(struct group_list *);
void sudo_pw_addref(struct passwd *); void sudo_pw_addref(struct passwd *);
void sudo_pw_delref(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_setgrent(void);
void sudo_setpwent(void); void sudo_setpwent(void);
void sudo_setspent(void); void sudo_setspent(void);