]> granicus.if.org Git - sudo/commitdiff
Cache the user's group IDs and group names separately and only
authorTodd C. Miller <Todd.Miller@courtesan.com>
Sat, 13 Aug 2016 22:27:44 +0000 (16:27 -0600)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Sat, 13 Aug 2016 22:27:44 +0000 (16:27 -0600)
resolve group IDs -> names when needed.  If the sudoers file doesn't
contain groups we will no longer try to resolve all the user's group
IDs to names, which can be expensive on some systems.

plugins/sudoers/ldap.c
plugins/sudoers/policy.c
plugins/sudoers/pwutil.c
plugins/sudoers/pwutil.h
plugins/sudoers/pwutil_impl.c
plugins/sudoers/set_perms.c
plugins/sudoers/sudoers.c
plugins/sudoers/sudoers.h

index d9ad04cc0ea4db6ac07a1cc44626222dd01ee824..764def51b4cc37947c16835c11b3da0fdfb62c98 100644 (file)
@@ -392,7 +392,7 @@ struct sudo_ldap_handle {
     LDAP *ld;
     struct ldap_result *result;
     const char *username;
-    struct group_list *grlist;
+    struct gid_list *gidlist;
 };
 
 struct sudo_nss sudo_nss_ldap = {
@@ -1598,6 +1598,7 @@ sudo_ldap_build_pass1(LDAP *ld, struct passwd *pw)
     char *buf, timebuffer[TIMEFILTER_LENGTH + 1], gidbuf[MAX_UID_T_LEN + 1];
     struct ldap_netgroup_list netgroups;
     struct ldap_netgroup *ng, *nextng;
+    struct gid_list *gidlist;
     struct group_list *grlist;
     struct group *grp;
     size_t sz = 0;
@@ -1628,8 +1629,10 @@ sudo_ldap_build_pass1(LDAP *ld, struct passwd *pw)
                continue;
            sz += 12 + sudo_ldap_value_len(grlist->groups[i]);
        }
-       for (i = 0; i < grlist->ngids; i++) {
-           if (pw->pw_gid == grlist->gids[i])
+    }
+    if ((gidlist = sudo_get_gidlist(pw)) != NULL) {
+       for (i = 0; i < gidlist->ngids; i++) {
+           if (pw->pw_gid == gidlist->gids[i])
                continue;
            sz += 13 + MAX_UID_T_LEN;
        }
@@ -1696,11 +1699,13 @@ sudo_ldap_build_pass1(LDAP *ld, struct passwd *pw)
            CHECK_LDAP_VCAT(buf, grlist->groups[i], sz);
            CHECK_STRLCAT(buf, ")", sz);
        }
-       for (i = 0; i < grlist->ngids; i++) {
-           if (pw->pw_gid == grlist->gids[i])
+    }
+    if (gidlist != NULL) {
+       for (i = 0; i < gidlist->ngids; i++) {
+           if (pw->pw_gid == gidlist->gids[i])
                continue;
            (void) snprintf(gidbuf, sizeof(gidbuf), "%u",
-               (unsigned int)grlist->gids[i]);
+               (unsigned int)gidlist->gids[i]);
            CHECK_STRLCAT(buf, "(sudoUser=%#", sz);
            CHECK_STRLCAT(buf, gidbuf, sz);
            CHECK_STRLCAT(buf, ")", sz);
@@ -1708,6 +1713,8 @@ sudo_ldap_build_pass1(LDAP *ld, struct passwd *pw)
     }
 
     /* Done with groups. */
+    if (gidlist != NULL)
+       sudo_gidlist_delref(gidlist);
     if (grlist != NULL)
        sudo_grlist_delref(grlist);
     if (grp != NULL)
@@ -3101,7 +3108,7 @@ sudo_ldap_open(struct sudo_nss *nss)
     handle->ld = ld;
     /* handle->result = NULL; */
     /* handle->username = NULL; */
-    /* handle->grlist = NULL; */
+    /* handle->gidlist = NULL; */
     nss->handle = handle;
 
 done:
@@ -3372,7 +3379,7 @@ sudo_ldap_result_free_nss(struct sudo_nss *nss)
        DPRINTF1("removing reusable search result");
        sudo_ldap_result_free(handle->result);
        handle->username = NULL;
-       handle->grlist = NULL;
+       handle->gidlist = NULL;
        handle->result = NULL;
     }
     debug_return;
@@ -3400,7 +3407,7 @@ sudo_ldap_result_get(struct sudo_nss *nss, struct passwd *pw)
      * have to contact the LDAP server again.
      */
     if (handle->result) {
-       if (handle->grlist == user_group_list &&
+       if (handle->gidlist == user_gid_list &&
            strcmp(pw->pw_name, handle->username) == 0) {
            DPRINTF1("reusing previous result (user %s) with %d entries",
                handle->username, handle->result->nentries);
@@ -3501,9 +3508,10 @@ sudo_ldap_result_get(struct sudo_nss *nss, struct passwd *pw)
 
     /* Store everything in the sudo_nss handle. */
     /* XXX - store pw and take a reference to it. */
+    /* XXX - take refs for gidlist and grlist */
     handle->result = lres;
     handle->username = pw->pw_name;
-    handle->grlist = user_group_list;
+    handle->gidlist = user_gid_list;
 
     debug_return_ptr(lres);
 }
index c393b49fed857fafc08db4c71dc3423b67ba39cd..2b551e6b2cd8693ec2af0d1df692970dca39c645 100644 (file)
@@ -492,11 +492,11 @@ sudoers_policy_exec_setup(char *argv[], char *envp[], mode_t cmnd_umask,
        gid_t egid;
        size_t glsize;
        char *cp, *gid_list;
-       struct group_list *grlist = sudo_get_grlist(runas_pw);
+       struct gid_list *gidlist = sudo_get_gidlist(runas_pw);
 
        /* We reserve an extra spot in the list for the effective gid. */
        glsize = sizeof("runas_groups=") - 1 +
-           ((grlist->ngids + 1) * (MAX_UID_T_LEN + 1));
+           ((gidlist->ngids + 1) * (MAX_UID_T_LEN + 1));
        gid_list = malloc(glsize);
        if (gid_list == NULL)
            goto oom;
@@ -513,10 +513,10 @@ sudoers_policy_exec_setup(char *argv[], char *envp[], mode_t cmnd_umask,
            goto bad;
        }
        cp += len;
-       for (i = 0; i < grlist->ngids; i++) {
-           if (grlist->gids[i] != egid) {
+       for (i = 0; i < gidlist->ngids; i++) {
+           if (gidlist->gids[i] != egid) {
                len = snprintf(cp, glsize - (cp - gid_list), ",%u",
-                    (unsigned int) grlist->gids[i]);
+                    (unsigned int) gidlist->gids[i]);
                if (len < 0 || (size_t)len >= glsize - (cp - gid_list)) {
                    sudo_warnx(U_("internal error, %s overflow"), __func__);
                    free(gid_list);
@@ -526,7 +526,7 @@ sudoers_policy_exec_setup(char *argv[], char *envp[], mode_t cmnd_umask,
            }
        }
        command_info[info_len++] = gid_list;
-       sudo_grlist_delref(grlist);
+       sudo_gidlist_delref(gidlist);
     }
     if (def_closefrom >= 0) {
        if (asprintf(&command_info[info_len++], "closefrom=%d", def_closefrom) == -1)
@@ -678,9 +678,9 @@ sudoers_policy_close(int exit_status, int error_code)
        sudo_gr_delref(runas_gr);
        runas_gr = NULL;
     }
-    if (user_group_list != NULL) {
-       sudo_grlist_delref(user_group_list);
-       user_group_list = NULL;
+    if (user_gid_list != NULL) {
+       sudo_gidlist_delref(user_gid_list);
+       user_gid_list = NULL;
     }
     free(user_gids);
     user_gids = NULL;
index 354866a207383de7f35c1b13a716d9ce09448317..2ffd7ec76b177f05a07a8994bc683da656d2473f 100644 (file)
@@ -48,7 +48,7 @@
  */
 static struct rbtree *pwcache_byuid, *pwcache_byname;
 static struct rbtree *grcache_bygid, *grcache_byname;
-static struct rbtree *grlist_cache;
+static struct rbtree *gidlist_cache, *grlist_cache;
 
 static int  cmp_pwuid(const void *, const void *);
 static int  cmp_pwnam(const void *, const void *);
@@ -652,10 +652,38 @@ sudo_fakegrnam(const char *group)
     debug_return_ptr(item->d.gr);
 }
 
+void
+sudo_gidlist_addref(struct gid_list *gidlist)
+{
+    debug_decl(sudo_gidlist_addref, SUDOERS_DEBUG_NSS)
+    ptr_to_item(gidlist)->refcnt++;
+    debug_return;
+}
+
+static void
+sudo_gidlist_delref_item(void *v)
+{
+    struct cache_item *item = v;
+    debug_decl(sudo_gidlist_delref_item, SUDOERS_DEBUG_NSS)
+
+    if (--item->refcnt == 0)
+       free(item);
+
+    debug_return;
+}
+
+void
+sudo_gidlist_delref(struct gid_list *gidlist)
+{
+    debug_decl(sudo_gidlist_delref, SUDOERS_DEBUG_NSS)
+    sudo_gidlist_delref_item(ptr_to_item(gidlist));
+    debug_return;
+}
+
 void
 sudo_grlist_addref(struct group_list *grlist)
 {
-    debug_decl(sudo_gr_addref, SUDOERS_DEBUG_NSS)
+    debug_decl(sudo_grlist_addref, SUDOERS_DEBUG_NSS)
     ptr_to_item(grlist)->refcnt++;
     debug_return;
 }
@@ -664,7 +692,7 @@ static void
 sudo_grlist_delref_item(void *v)
 {
     struct cache_item *item = v;
-    debug_decl(sudo_gr_delref_item, SUDOERS_DEBUG_NSS)
+    debug_decl(sudo_grlist_delref_item, SUDOERS_DEBUG_NSS)
 
     if (--item->refcnt == 0)
        free(item);
@@ -675,7 +703,7 @@ sudo_grlist_delref_item(void *v)
 void
 sudo_grlist_delref(struct group_list *grlist)
 {
-    debug_decl(sudo_gr_delref, SUDOERS_DEBUG_NSS)
+    debug_decl(sudo_grlist_delref, SUDOERS_DEBUG_NSS)
     sudo_grlist_delref_item(ptr_to_item(grlist));
     debug_return;
 }
@@ -697,6 +725,10 @@ sudo_freegrcache(void)
        rbdestroy(grlist_cache, sudo_grlist_delref_item);
        grlist_cache = NULL;
     }
+    if (gidlist_cache != NULL) {
+       rbdestroy(gidlist_cache, sudo_gidlist_delref_item);
+       gidlist_cache = NULL;
+    }
 
     debug_return;
 }
@@ -708,8 +740,11 @@ sudo_get_grlist(const struct passwd *pw)
     struct rbnode *node;
     debug_decl(sudo_get_grlist, SUDOERS_DEBUG_NSS)
 
+    sudo_debug_printf(SUDO_DEBUG_DEBUG, "%s: looking up group names for %s",
+       __func__, pw->pw_name);
+
     if (grlist_cache == NULL) {
-       grlist_cache = rbcreate(cmp_grnam);
+       grlist_cache = rbcreate(cmp_pwnam);
        if (grlist_cache == NULL) {
            sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
            debug_return_ptr(NULL);
@@ -725,7 +760,7 @@ sudo_get_grlist(const struct passwd *pw)
     /*
      * Cache group db entry if it exists or a negative response if not.
      */
-    item = sudo_make_grlist_item(pw, NULL, NULL);
+    item = sudo_make_grlist_item(pw, NULL);
     if (item == NULL) {
        /* Out of memory? */
        debug_return_ptr(NULL);
@@ -759,14 +794,14 @@ done:
 }
 
 int
-sudo_set_grlist(struct passwd *pw, char * const *groups, char * const *gids)
+sudo_set_grlist(struct passwd *pw, char * const *groups)
 {
     struct cache_item key, *item;
     struct rbnode *node;
     debug_decl(sudo_set_grlist, SUDOERS_DEBUG_NSS)
 
     if (grlist_cache == NULL) {
-       grlist_cache = rbcreate(cmp_grnam);
+       grlist_cache = rbcreate(cmp_pwnam);
        if (grlist_cache == NULL) {
            sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
            debug_return_int(-1);
@@ -779,7 +814,7 @@ sudo_set_grlist(struct passwd *pw, char * const *groups, char * const *gids)
     key.k.name = pw->pw_name;
     getauthregistry(NULL, key.registry);
     if ((node = rbfind(grlist_cache, &key)) == NULL) {
-       if ((item = sudo_make_grlist_item(pw, groups, gids)) == NULL) {
+       if ((item = sudo_make_grlist_item(pw, groups)) == NULL) {
            sudo_warnx(U_("unable to parse groups for %s"), pw->pw_name);
            debug_return_int(-1);
        }
@@ -800,17 +835,120 @@ sudo_set_grlist(struct passwd *pw, char * const *groups, char * const *gids)
     debug_return_int(0);
 }
 
+struct gid_list *
+sudo_get_gidlist(const struct passwd *pw)
+{
+    struct cache_item key, *item;
+    struct rbnode *node;
+    debug_decl(sudo_get_gidlist, SUDOERS_DEBUG_NSS)
+
+    sudo_debug_printf(SUDO_DEBUG_DEBUG, "%s: looking up group IDs for %s",
+       __func__, pw->pw_name);
+
+    if (gidlist_cache == NULL) {
+       gidlist_cache = rbcreate(cmp_pwnam);
+       if (gidlist_cache == NULL) {
+           sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+           debug_return_ptr(NULL);
+       }
+    }
+
+    key.k.name = pw->pw_name;
+    getauthregistry(pw->pw_name, key.registry);
+    if ((node = rbfind(gidlist_cache, &key)) != NULL) {
+       item = node->data;
+       goto done;
+    }
+    /*
+     * Cache group db entry if it exists or a negative response if not.
+     */
+    item = sudo_make_gidlist_item(pw, NULL);
+    if (item == NULL) {
+       /* Out of memory? */
+       debug_return_ptr(NULL);
+    }
+    strlcpy(item->registry, key.registry, sizeof(item->registry));
+    switch (rbinsert(gidlist_cache, item, NULL)) {
+    case 1:
+       /* should not happen */
+       sudo_warnx(U_("unable to cache group list for %s, already exists"),
+           pw->pw_name);
+       item->refcnt = 0;
+       break;
+    case -1:
+       /* can't cache item, just return it */
+       sudo_warnx(U_("unable to cache group list for %s, out of memory"),
+           pw->pw_name);
+       item->refcnt = 0;
+       break;
+    }
+    if (item->d.gidlist != NULL) {
+       int i;
+       for (i = 0; i < item->d.gidlist->ngids; i++) {
+           sudo_debug_printf(SUDO_DEBUG_DEBUG,
+               "%s: user %s has supplementary gid %u", __func__,
+               pw->pw_name, (unsigned int)item->d.gidlist->gids[i]);
+       }
+    }
+done:
+    item->refcnt++;
+    debug_return_ptr(item->d.gidlist);
+}
+
+int
+sudo_set_gidlist(struct passwd *pw, char * const *gids)
+{
+    struct cache_item key, *item;
+    struct rbnode *node;
+    debug_decl(sudo_set_gidlist, SUDOERS_DEBUG_NSS)
+
+    if (gidlist_cache == NULL) {
+       gidlist_cache = rbcreate(cmp_pwnam);
+       if (gidlist_cache == NULL) {
+           sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+           debug_return_int(-1);
+       }
+    }
+
+    /*
+     * Cache group db entry if it doesn't already exist
+     */
+    key.k.name = pw->pw_name;
+    getauthregistry(NULL, key.registry);
+    if ((node = rbfind(gidlist_cache, &key)) == NULL) {
+       if ((item = sudo_make_gidlist_item(pw, gids)) == NULL) {
+           sudo_warnx(U_("unable to parse gids for %s"), pw->pw_name);
+           debug_return_int(-1);
+       }
+       strlcpy(item->registry, key.registry, sizeof(item->registry));
+       switch (rbinsert(gidlist_cache, item, NULL)) {
+       case 1:
+           sudo_warnx(U_("unable to cache group list for %s, already exists"),
+               pw->pw_name);
+           sudo_gidlist_delref_item(item);
+           break;
+       case -1:
+           sudo_warnx(U_("unable to cache group list for %s, out of memory"),
+               pw->pw_name);
+           sudo_gidlist_delref_item(item);
+           debug_return_int(-1);
+       }
+    }
+    debug_return_int(0);
+}
+
 bool
 user_in_group(const struct passwd *pw, const char *group)
 {
-    struct group_list *grlist;
+    struct group_list *grlist = NULL;
+    struct gid_list *gidlist = NULL;
     struct group *grp = NULL;
     const char *errstr;
     int i;
     bool matched = false;
     debug_decl(user_in_group, SUDOERS_DEBUG_NSS)
 
-    if ((grlist = sudo_get_grlist(pw)) != NULL) {
+    if ((gidlist = sudo_get_gidlist(pw)) != NULL) {
        /*
         * If it could be a sudo-style group ID check gids first.
         */
@@ -824,8 +962,8 @@ user_in_group(const struct passwd *pw, const char *group)
                    matched = true;
                    goto done;
                }
-               for (i = 0; i < grlist->ngids; i++) {
-                   if (gid == grlist->gids[i]) {
+               for (i = 0; i < gidlist->ngids; i++) {
+                   if (gid == gidlist->gids[i]) {
                        matched = true;
                        goto done;
                    }
@@ -837,10 +975,12 @@ user_in_group(const struct passwd *pw, const char *group)
         * Next check the supplementary group vector.
         * It usually includes the password db group too.
         */
-       for (i = 0; i < grlist->ngroups; i++) {
-           if (strcasecmp(group, grlist->groups[i]) == 0) {
-               matched = true;
-               goto done;
+       if ((grlist = sudo_get_grlist(pw)) != NULL) {
+           for (i = 0; i < grlist->ngroups; i++) {
+               if (strcasecmp(group, grlist->groups[i]) == 0) {
+                   matched = true;
+                   goto done;
+               }
            }
        }
 
@@ -854,7 +994,9 @@ user_in_group(const struct passwd *pw, const char *group)
 done:
        if (grp != NULL)
            sudo_gr_delref(grp);
-       sudo_grlist_delref(grlist);
+       if (grlist != NULL)
+           sudo_grlist_delref(grlist);
+       sudo_gidlist_delref(gidlist);
     }
     sudo_debug_printf(SUDO_DEBUG_DEBUG, "%s: user %s %sin group %s",
        __func__, pw->pw_name, matched ? "" : "NOT ", group);
index 433e15687a8a265ef05c55f53a160f2cbdc3d1ee..f1ade0056d116606e48fb8fd033c8fbb8327b3e6 100644 (file)
@@ -36,12 +36,13 @@ struct cache_item {
        struct passwd *pw;
        struct group *gr;
        struct group_list *grlist;
+       struct gid_list *gidlist;
     } d;
 };
 
 /*
  * Container structs to simpify size and offset calculations and guarantee
- * proper aligment of struct passwd, group and group_list.
+ * proper aligment of struct passwd, group, gid_list and group_list.
  */
 struct cache_item_pw {
     struct cache_item cache;
@@ -59,8 +60,15 @@ struct cache_item_grlist {
     /* actually bigger */
 };
 
+struct cache_item_gidlist {
+    struct cache_item cache;
+    struct gid_list gidlist;
+    /* actually bigger */
+};
+
 struct cache_item *sudo_make_gritem(gid_t gid, const char *group);
-struct cache_item *sudo_make_grlist_item(const struct passwd *pw, char * const *groups, char * const *gids);
+struct cache_item *sudo_make_grlist_item(const struct passwd *pw, char * const *groups);
+struct cache_item *sudo_make_gidlist_item(const struct passwd *pw, char * const *gids);
 struct cache_item *sudo_make_pwitem(uid_t uid, const char *user);
 
 #endif /* SUDOERS_PWUTIL_H */
index 1a1b4392ff8f6a701a5d1ad6ba43651e79932857..8c469f583d33b8ef3a52b2c73f81fe9fbcf777fa 100644 (file)
@@ -230,17 +230,15 @@ sudo_make_gritem(gid_t gid, const char *name)
  * elements.  Fills in datum from user_gids or from getgrouplist(3).
  */
 struct cache_item *
-sudo_make_grlist_item(const struct passwd *pw, char * const *unused1,
-    char * const *unused2)
+sudo_make_gidlist_item(const struct passwd *pw, char * const *unused1)
 {
     char *cp;
-    size_t nsize, ngroups, total, len;
-    struct cache_item_grlist *grlitem;
-    struct group_list *grlist;
+    size_t nsize, total;
+    struct cache_item_gidlist *glitem;
+    struct gid_list *gidlist;
     GETGROUPS_T *gids;
-    struct group *grp = NULL;
-    int i, ngids, groupname_len;
-    debug_decl(sudo_make_grlist_item, SUDOERS_DEBUG_NSS)
+    int i, ngids;
+    debug_decl(sudo_make_gidlist_item, SUDOERS_DEBUG_NSS)
 
     if (pw == sudo_user.pw && sudo_user.gids != NULL) {
        gids = user_gids;
@@ -286,6 +284,69 @@ sudo_make_grlist_item(const struct passwd *pw, char * const *unused1,
        debug_return_ptr(NULL);
     }
 
+    /* Allocate in one big chunk for easy freeing. */
+    nsize = strlen(pw->pw_name) + 1;
+    total = sizeof(*glitem) + nsize;
+    total += sizeof(gid_t *) * ngids;
+
+    if ((glitem = calloc(1, total)) == NULL) {
+       sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+           "unable to allocate memory");
+       free(gids);
+       debug_return_ptr(NULL);
+    }
+
+    /*
+     * Copy in group list and make pointers relative to space
+     * at the end of the buffer.  Note that the groups array must come
+     * immediately after struct group to guarantee proper alignment.
+     */
+    gidlist = &glitem->gidlist;
+    cp = (char *)(glitem + 1);
+    gidlist->gids = (gid_t *)cp;
+    cp += sizeof(gid_t) * ngids;
+
+    /* Set key and datum. */
+    memcpy(cp, pw->pw_name, nsize);
+    glitem->cache.k.name = cp;
+    glitem->cache.d.gidlist = gidlist;
+    glitem->cache.refcnt = 1;
+
+    /*
+     * Store group IDs.
+     */
+    for (i = 0; i < ngids; i++)
+       gidlist->gids[i] = gids[i];
+    gidlist->ngids = ngids;
+    free(gids);
+
+    debug_return_ptr(&glitem->cache);
+}
+
+/*
+ * Dynamically allocate space for a struct item plus the key and data
+ * elements.  Fills in group names from a call to sudo_get_gidlist().
+ */
+struct cache_item *
+sudo_make_grlist_item(const struct passwd *pw, char * const *unused1)
+{
+    char *cp;
+    size_t nsize, ngroups, total, len;
+    struct cache_item_grlist *grlitem;
+    struct group_list *grlist;
+    struct gid_list *gidlist;
+    struct group *grp = NULL;
+    int i, groupname_len;
+    debug_decl(sudo_make_grlist_item, SUDOERS_DEBUG_NSS)
+
+    gidlist = sudo_get_gidlist(pw);
+    if (gidlist == NULL) {
+       sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+           "no gid list for use %s", pw->pw_name);
+       errno = ENOENT;
+       debug_return_ptr(NULL);
+    }
+
 #ifdef _SC_LOGIN_NAME_MAX
     groupname_len = MAX((int)sysconf(_SC_LOGIN_NAME_MAX), 32);
 #else
@@ -295,15 +356,13 @@ sudo_make_grlist_item(const struct passwd *pw, char * const *unused1,
     /* Allocate in one big chunk for easy freeing. */
     nsize = strlen(pw->pw_name) + 1;
     total = sizeof(*grlitem) + nsize;
-    total += sizeof(char *) * ngids;
-    total += sizeof(gid_t *) * ngids;
-    total += groupname_len * ngids;
+    total += groupname_len * gidlist->ngids;
 
 again:
     if ((grlitem = calloc(1, total)) == NULL) {
        sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
            "unable to allocate memory");
-       free(gids);
+       sudo_gidlist_delref(gidlist);
        debug_return_ptr(NULL);
     }
 
@@ -315,9 +374,7 @@ again:
     grlist = &grlitem->grlist;
     cp = (char *)(grlitem + 1);
     grlist->groups = (char **)cp;
-    cp += sizeof(char *) * ngids;
-    grlist->gids = (gid_t *)cp;
-    cp += sizeof(gid_t) * ngids;
+    cp += sizeof(char *) * gidlist->ngids;
 
     /* Set key and datum. */
     memcpy(cp, pw->pw_name, nsize);
@@ -326,13 +383,6 @@ again:
     grlitem->cache.refcnt = 1;
     cp += nsize;
 
-    /*
-     * Store group IDs.
-     */
-    for (i = 0; i < ngids; i++)
-       grlist->gids[i] = gids[i];
-    grlist->ngids = ngids;
-
     /*
      * Resolve and store group names by ID.
      */
@@ -341,8 +391,8 @@ again:
        aix_setauthdb((char *) pw->pw_name, NULL);
 #endif
     ngroups = 0;
-    for (i = 0; i < ngids; i++) {
-       if ((grp = sudo_getgrgid(gids[i])) != NULL) {
+    for (i = 0; i < gidlist->ngids; i++) {
+       if ((grp = sudo_getgrgid(gidlist->gids[i])) != NULL) {
            len = strlen(grp->gr_name) + 1;
            if (cp - (char *)grlitem + len > total) {
                total += len + groupname_len;
@@ -357,7 +407,7 @@ again:
        }
     }
     grlist->ngroups = ngroups;
-    free(gids);
+    sudo_gidlist_delref(gidlist);
 
 #ifdef HAVE_SETAUTHDB
     aix_restoreauthdb();
index e38d98de241f90f6e7cbd7d4d885d64c8356565b..58c7cc63683d2fdf7e37f3adc2bfedee12033ebc 100644 (file)
@@ -44,7 +44,7 @@
  * Prototypes
  */
 #if defined(HAVE_SETRESUID) || defined(HAVE_SETREUID) || defined(HAVE_SETEUID)
-static struct group_list *runas_setgroups(void);
+static struct gid_list *runas_setgroups(void);
 #endif
 
 /*
@@ -62,7 +62,7 @@ struct perm_state {
 #if defined(HAVE_SETRESUID) || defined(ID_SAVED)
     gid_t sgid;
 #endif
-    struct group_list *grlist;
+    struct gid_list *gidlist;
 };
 
 #define PERM_STACK_MAX 16
@@ -84,7 +84,7 @@ rewind_perms(void)
            if (!restore_perms())
                debug_return_bool(false);
        }
-       sudo_grlist_delref(perm_stack[0].grlist);
+       sudo_gidlist_delref(perm_stack[0].gidlist);
     }
 
     debug_return_bool(true);
@@ -147,8 +147,8 @@ set_perms(int perm)
        state->egid = getegid();
        state->sgid = state->egid; /* in case we are setgid */
 #endif
-       state->grlist = user_group_list;
-       sudo_grlist_addref(state->grlist);
+       state->gidlist = user_gid_list;
+       sudo_gidlist_addref(state->gidlist);
        sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_INITIAL: "
            "ruid: %d, euid: %d, suid: %d, rgid: %d, egid: %d, sgid: %d",
            __func__, (int)state->ruid, (int)state->euid, (int)state->suid,
@@ -180,8 +180,8 @@ set_perms(int perm)
            errstr = N_("unable to change to root gid");
            goto bad;
        }
-       state->grlist = ostate->grlist;
-       sudo_grlist_addref(state->grlist);
+       state->gidlist = ostate->gidlist;
+       sudo_gidlist_addref(state->gidlist);
        break;
 
     case PERM_USER:
@@ -197,10 +197,10 @@ set_perms(int perm)
                ID(rgid), ID(egid), ID(sgid));
            goto bad;
        }
-       state->grlist = user_group_list;
-       sudo_grlist_addref(state->grlist);
-       if (state->grlist != ostate->grlist) {
-           if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
+       state->gidlist = user_gid_list;
+       sudo_gidlist_addref(state->gidlist);
+       if (state->gidlist != ostate->gidlist) {
+           if (sudo_setgroups(state->gidlist->ngids, state->gidlist->gids)) {
                errstr = "PERM_USER: setgroups";
                goto bad;
            }
@@ -234,10 +234,10 @@ set_perms(int perm)
                ID(rgid), ID(egid), ID(sgid));
            goto bad;
        }
-       state->grlist = user_group_list;
-       sudo_grlist_addref(state->grlist);
-       if (state->grlist != ostate->grlist) {
-           if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
+       state->gidlist = user_gid_list;
+       sudo_gidlist_addref(state->gidlist);
+       if (state->gidlist != ostate->gidlist) {
+           if (sudo_setgroups(state->gidlist->ngids, state->gidlist->gids)) {
                errstr = "PERM_FULL_USER: setgroups";
                goto bad;
            }
@@ -269,8 +269,8 @@ set_perms(int perm)
            errstr = N_("unable to change to runas gid");
            goto bad;
        }
-       state->grlist = runas_setgroups();
-       if (state->grlist == NULL) {
+       state->gidlist = runas_setgroups();
+       if (state->gidlist == NULL) {
            errstr = N_("unable to set runas group vector");
            goto bad;
        }
@@ -288,8 +288,8 @@ set_perms(int perm)
        break;
 
     case PERM_SUDOERS:
-       state->grlist = ostate->grlist;
-       sudo_grlist_addref(state->grlist);
+       state->gidlist = ostate->gidlist;
+       sudo_gidlist_addref(state->gidlist);
 
        /* assumes euid == ROOT_UID, ruid == user */
        state->rgid = ostate->rgid;
@@ -328,8 +328,8 @@ set_perms(int perm)
        break;
 
     case PERM_TIMESTAMP:
-       state->grlist = ostate->grlist;
-       sudo_grlist_addref(state->grlist);
+       state->gidlist = ostate->gidlist;
+       sudo_gidlist_addref(state->gidlist);
        state->rgid = ostate->rgid;
        state->egid = ostate->egid;
        state->sgid = ostate->sgid;
@@ -402,13 +402,13 @@ restore_perms(void)
            (int)OID(rgid), (int)OID(egid), (int)OID(sgid));
        goto bad;
     }
-    if (state->grlist != ostate->grlist) {
-       if (sudo_setgroups(ostate->grlist->ngids, ostate->grlist->gids)) {
+    if (state->gidlist != ostate->gidlist) {
+       if (sudo_setgroups(ostate->gidlist->ngids, ostate->gidlist->gids)) {
            sudo_warn("setgroups()");
            goto bad;
        }
     }
-    sudo_grlist_delref(state->grlist);
+    sudo_gidlist_delref(state->gidlist);
     debug_return_bool(true);
 
 bad:
@@ -459,8 +459,8 @@ set_perms(int perm)
        state->rgid = getgidx(ID_REAL);
        state->egid = getgidx(ID_EFFECTIVE);
        state->sgid = getgidx(ID_SAVED);
-       state->grlist = user_group_list;
-       sudo_grlist_addref(state->grlist);
+       state->gidlist = user_gid_list;
+       sudo_gidlist_addref(state->gidlist);
        sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_INITIAL: "
            "ruid: %d, euid: %d, suid: %d, rgid: %d, egid: %d, sgid: %d",
            __func__, (unsigned int)state->ruid, (unsigned int)state->euid,
@@ -493,8 +493,8 @@ set_perms(int perm)
            errstr = N_("unable to change to root gid");
            goto bad;
        }
-       state->grlist = ostate->grlist;
-       sudo_grlist_addref(state->grlist);
+       state->gidlist = ostate->gidlist;
+       sudo_gidlist_addref(state->gidlist);
        break;
 
     case PERM_USER:
@@ -510,10 +510,10 @@ set_perms(int perm)
                "PERM_USER: setgidx(ID_EFFECTIVE, %d)", user_gid);
            goto bad;
        }
-       state->grlist = user_group_list;
-       sudo_grlist_addref(state->grlist);
-       if (state->grlist != ostate->grlist) {
-           if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
+       state->gidlist = user_gid_list;
+       sudo_gidlist_addref(state->gidlist);
+       if (state->gidlist != ostate->gidlist) {
+           if (sudo_setgroups(state->gidlist->ngids, state->gidlist->gids)) {
                errstr = "PERM_USER: setgroups";
                goto bad;
            }
@@ -555,10 +555,10 @@ set_perms(int perm)
                user_gid);
            goto bad;
        }
-       state->grlist = user_group_list;
-       sudo_grlist_addref(state->grlist);
-       if (state->grlist != ostate->grlist) {
-           if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
+       state->gidlist = user_gid_list;
+       sudo_gidlist_addref(state->gidlist);
+       if (state->gidlist != ostate->gidlist) {
+           if (sudo_setgroups(state->gidlist->ngids, state->gidlist->gids)) {
                errstr = "PERM_FULL_USER: setgroups";
                goto bad;
            }
@@ -590,8 +590,8 @@ set_perms(int perm)
            errstr = N_("unable to change to runas gid");
            goto bad;
        }
-       state->grlist = runas_setgroups();
-       if (state->grlist == NULL) {
+       state->gidlist = runas_setgroups();
+       if (state->gidlist == NULL) {
            errstr = N_("unable to set runas group vector");
            goto bad;
        }
@@ -609,8 +609,8 @@ set_perms(int perm)
        break;
 
     case PERM_SUDOERS:
-       state->grlist = ostate->grlist;
-       sudo_grlist_addref(state->grlist);
+       state->gidlist = ostate->gidlist;
+       sudo_gidlist_addref(state->gidlist);
 
        /* assume euid == ROOT_UID, ruid == user */
        state->rgid = ostate->rgid;
@@ -658,8 +658,8 @@ set_perms(int perm)
        break;
 
     case PERM_TIMESTAMP:
-       state->grlist = ostate->grlist;
-       sudo_grlist_addref(state->grlist);
+       state->gidlist = ostate->gidlist;
+       sudo_gidlist_addref(state->gidlist);
        state->rgid = ostate->rgid;
        state->egid = ostate->egid;
        state->sgid = ostate->sgid;
@@ -805,13 +805,13 @@ restore_perms(void)
            }
        }
     }
-    if (state->grlist != ostate->grlist) {
-       if (sudo_setgroups(ostate->grlist->ngids, ostate->grlist->gids)) {
+    if (state->gidlist != ostate->gidlist) {
+       if (sudo_setgroups(ostate->gidlist->ngids, ostate->gidlist->gids)) {
            sudo_warn("setgroups()");
            goto bad;
        }
     }
-    sudo_grlist_delref(state->grlist);
+    sudo_gidlist_delref(state->gidlist);
     debug_return_bool(true);
 
 bad:
@@ -860,8 +860,8 @@ set_perms(int perm)
        state->euid = geteuid();
        state->rgid = getgid();
        state->egid = getegid();
-       state->grlist = user_group_list;
-       sudo_grlist_addref(state->grlist);
+       state->gidlist = user_gid_list;
+       sudo_gidlist_addref(state->gidlist);
        sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_INITIAL: "
            "ruid: %d, euid: %d, rgid: %d, egid: %d", __func__,
            (int)state->ruid, (int)state->euid,
@@ -901,8 +901,8 @@ set_perms(int perm)
                "PERM_ROOT: setregid(%d, %d)", ID(rgid), ID(egid));
            goto bad;
        }
-       state->grlist = ostate->grlist;
-       sudo_grlist_addref(state->grlist);
+       state->gidlist = ostate->gidlist;
+       sudo_gidlist_addref(state->gidlist);
        break;
 
     case PERM_USER:
@@ -916,10 +916,10 @@ set_perms(int perm)
                "PERM_USER: setregid(%d, %d)", ID(rgid), ID(egid));
            goto bad;
        }
-       state->grlist = user_group_list;
-       sudo_grlist_addref(state->grlist);
-       if (state->grlist != ostate->grlist) {
-           if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
+       state->gidlist = user_gid_list;
+       sudo_gidlist_addref(state->gidlist);
+       if (state->gidlist != ostate->gidlist) {
+           if (sudo_setgroups(state->gidlist->ngids, state->gidlist->gids)) {
                errstr = "PERM_USER: setgroups";
                goto bad;
            }
@@ -948,10 +948,10 @@ set_perms(int perm)
                "PERM_FULL_USER: setregid(%d, %d)", ID(rgid), ID(egid));
            goto bad;
        }
-       state->grlist = user_group_list;
-       sudo_grlist_addref(state->grlist);
-       if (state->grlist != ostate->grlist) {
-           if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
+       state->gidlist = user_gid_list;
+       sudo_gidlist_addref(state->gidlist);
+       if (state->gidlist != ostate->gidlist) {
+           if (sudo_setgroups(state->gidlist->ngids, state->gidlist->gids)) {
                errstr = "PERM_FULL_USER: setgroups";
                goto bad;
            }
@@ -978,8 +978,8 @@ set_perms(int perm)
            errstr = N_("unable to change to runas gid");
            goto bad;
        }
-       state->grlist = runas_setgroups();
-       if (state->grlist == NULL) {
+       state->gidlist = runas_setgroups();
+       if (state->gidlist == NULL) {
            errstr = N_("unable to set runas group vector");
            goto bad;
        }
@@ -995,8 +995,8 @@ set_perms(int perm)
        break;
 
     case PERM_SUDOERS:
-       state->grlist = ostate->grlist;
-       sudo_grlist_addref(state->grlist);
+       state->gidlist = ostate->gidlist;
+       sudo_gidlist_addref(state->gidlist);
 
        /* assume euid == ROOT_UID, ruid == user */
        state->rgid = ostate->rgid;
@@ -1030,8 +1030,8 @@ set_perms(int perm)
        break;
 
     case PERM_TIMESTAMP:
-       state->grlist = ostate->grlist;
-       sudo_grlist_addref(state->grlist);
+       state->gidlist = ostate->gidlist;
+       sudo_gidlist_addref(state->gidlist);
        state->rgid = ostate->rgid;
        state->egid = ostate->egid;
        state->ruid = ROOT_UID;
@@ -1103,13 +1103,13 @@ restore_perms(void)
            (int)state->egid, (int)OID(rgid), (int)OID(egid));
        goto bad;
     }
-    if (state->grlist != ostate->grlist) {
-       if (sudo_setgroups(ostate->grlist->ngids, ostate->grlist->gids)) {
+    if (state->gidlist != ostate->gidlist) {
+       if (sudo_setgroups(ostate->gidlist->ngids, ostate->gidlist->gids)) {
            sudo_warn("setgroups()");
            goto bad;
        }
     }
-    sudo_grlist_delref(state->grlist);
+    sudo_gidlist_delref(state->gidlist);
     debug_return_bool(true);
 
 bad:
@@ -1173,8 +1173,8 @@ set_perms(int perm)
        state->euid = geteuid();
        state->rgid = getgid();
        state->egid = getegid();
-       state->grlist = user_group_list;
-       sudo_grlist_addref(state->grlist);
+       state->gidlist = user_gid_list;
+       sudo_gidlist_addref(state->gidlist);
        sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_INITIAL: "
            "ruid: %d, euid: %d, rgid: %d, egid: %d", __func__,
            (int)state->ruid, (int)state->euid,
@@ -1197,8 +1197,8 @@ set_perms(int perm)
            errstr = N_("unable to change to root gid");
            goto bad;
        }
-       state->grlist = ostate->grlist;
-       sudo_grlist_addref(state->grlist);
+       state->gidlist = ostate->gidlist;
+       sudo_gidlist_addref(state->gidlist);
        break;
 
     case PERM_USER:
@@ -1212,10 +1212,10 @@ set_perms(int perm)
                "PERM_USER: setegid(%d)", user_gid);
            goto bad;
        }
-       state->grlist = user_group_list;
-       sudo_grlist_addref(state->grlist);
-       if (state->grlist != ostate->grlist) {
-           if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
+       state->gidlist = user_gid_list;
+       sudo_gidlist_addref(state->gidlist);
+       if (state->gidlist != ostate->gidlist) {
+           if (sudo_setgroups(state->gidlist->ngids, state->gidlist->gids)) {
                errstr = "PERM_USER: setgroups";
                goto bad;
            }
@@ -1244,10 +1244,10 @@ set_perms(int perm)
                "PERM_FULL_USER: setgid(%d)", user_gid);
            goto bad;
        }
-       state->grlist = user_group_list;
-       sudo_grlist_addref(state->grlist);
-       if (state->grlist != ostate->grlist) {
-           if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
+       state->gidlist = user_gid_list;
+       sudo_gidlist_addref(state->gidlist);
+       if (state->gidlist != ostate->gidlist) {
+           if (sudo_setgroups(state->gidlist->ngids, state->gidlist->gids)) {
                errstr = "PERM_FULL_USER: setgroups";
                goto bad;
            }
@@ -1274,8 +1274,8 @@ set_perms(int perm)
            errstr = N_("unable to change to runas gid");
            goto bad;
        }
-       state->grlist = runas_setgroups();
-       if (state->grlist == NULL) {
+       state->gidlist = runas_setgroups();
+       if (state->gidlist == NULL) {
            errstr = N_("unable to set runas group vector");
            goto bad;
        }
@@ -1291,8 +1291,8 @@ set_perms(int perm)
        break;
 
     case PERM_SUDOERS:
-       state->grlist = ostate->grlist;
-       sudo_grlist_addref(state->grlist);
+       state->gidlist = ostate->gidlist;
+       sudo_gidlist_addref(state->gidlist);
 
        /* assume euid == ROOT_UID, ruid == user */
        state->rgid = ostate->rgid;
@@ -1326,8 +1326,8 @@ set_perms(int perm)
        break;
 
     case PERM_TIMESTAMP:
-       state->grlist = ostate->grlist;
-       sudo_grlist_addref(state->grlist);
+       state->gidlist = ostate->gidlist;
+       sudo_gidlist_addref(state->gidlist);
        state->rgid = ostate->rgid;
        state->egid = ostate->egid;
        state->ruid = ROOT_UID;
@@ -1394,8 +1394,8 @@ restore_perms(void)
        sudo_warn("setegid(%d)", (int)ostate->egid);
        goto bad;
     }
-    if (state->grlist != ostate->grlist) {
-       if (sudo_setgroups(ostate->grlist->ngids, ostate->grlist->gids)) {
+    if (state->gidlist != ostate->gidlist) {
+       if (sudo_setgroups(ostate->gidlist->ngids, ostate->gidlist->gids)) {
            sudo_warn("setgroups()");
            goto bad;
        }
@@ -1404,7 +1404,7 @@ restore_perms(void)
        sudo_warn("seteuid(%d)", ostate->euid);
        goto bad;
     }
-    sudo_grlist_delref(state->grlist);
+    sudo_gidlist_delref(state->gidlist);
     debug_return_bool(true);
 
 bad:
@@ -1447,8 +1447,8 @@ set_perms(int perm)
        /* Stash initial state */
        state->ruid = geteuid() == ROOT_UID ? ROOT_UID : getuid();
        state->rgid = getgid();
-       state->grlist = user_group_list;
-       sudo_grlist_addref(state->grlist);
+       state->gidlist = user_gid_list;
+       sudo_gidlist_addref(state->gidlist);
        sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_INITIAL: "
            "ruid: %d, rgid: %d", __func__, (int)state->ruid, (int)state->rgid);
        break;
@@ -1456,8 +1456,8 @@ set_perms(int perm)
     case PERM_ROOT:
        state->ruid = ROOT_UID;
        state->rgid = ROOT_GID;
-       state->grlist = ostate->grlist;
-       sudo_grlist_addref(state->grlist);
+       state->gidlist = ostate->gidlist;
+       sudo_gidlist_addref(state->gidlist);
        sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_ROOT: uid: "
            "[%d] -> [%d]", __func__, (int)ostate->ruid, (int)state->ruid);
        if (setuid(ROOT_UID)) {
@@ -1477,10 +1477,10 @@ set_perms(int perm)
        sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_FULL_USER: gid: "
            "[%d] -> [%d]", __func__, (int)ostate->rgid, (int)state->rgid);
        (void) setgid(user_gid);
-       state->grlist = user_group_list;
-       sudo_grlist_addref(state->grlist);
-       if (state->grlist != ostate->grlist) {
-           if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
+       state->gidlist = user_gid_list;
+       sudo_gidlist_addref(state->gidlist);
+       if (state->gidlist != ostate->gidlist) {
+           if (sudo_setgroups(state->gidlist->ngids, state->gidlist->gids)) {
                errstr = "PERM_FULL_USER: setgroups";
                goto bad;
            }
@@ -1502,8 +1502,8 @@ set_perms(int perm)
        /* Unsupported since we can't set euid. */
        state->ruid = ostate->ruid;
        state->rgid = ostate->rgid;
-       state->grlist = ostate->grlist;
-       sudo_grlist_addref(state->grlist);
+       state->gidlist = ostate->gidlist;
+       sudo_gidlist_addref(state->gidlist);
        break;
     }
 
@@ -1541,13 +1541,13 @@ restore_perms(void)
        sudo_warn("setgid(%d)", (int)ostate->rgid);
        goto bad;
     }
-    if (state->grlist != ostate->grlist) {
-       if (sudo_setgroups(ostate->grlist->ngids, ostate->grlist->gids)) {
+    if (state->gidlist != ostate->gidlist) {
+       if (sudo_setgroups(ostate->gidlist->ngids, ostate->gidlist->gids)) {
            sudo_warn("setgroups()");
            goto bad;
        }
     }
-    sudo_grlist_delref(state->grlist);
+    sudo_gidlist_delref(state->gidlist);
     if (OID(ruid) != (uid_t)-1 && setuid(ostate->ruid)) {
        sudo_warn("setuid(%d)", (int)ostate->ruid);
        goto bad;
@@ -1560,26 +1560,26 @@ bad:
 #endif /* HAVE_SETRESUID || HAVE_SETREUID || HAVE_SETEUID */
 
 #if defined(HAVE_SETRESUID) || defined(HAVE_SETREUID) || defined(HAVE_SETEUID)
-static struct group_list *
+static struct gid_list *
 runas_setgroups(void)
 {
     struct passwd *pw;
-    struct group_list *grlist;
+    struct gid_list *gidlist;
     debug_decl(runas_setgroups, SUDOERS_DEBUG_PERMS)
 
     if (def_preserve_groups) {
-       sudo_grlist_addref(user_group_list);
-       debug_return_ptr(user_group_list);
+       sudo_gidlist_addref(user_gid_list);
+       debug_return_ptr(user_gid_list);
     }
 
     pw = runas_pw ? runas_pw : sudo_user.pw;
-    grlist = sudo_get_grlist(pw);
-    if (grlist != NULL) {
-       if (sudo_setgroups(grlist->ngids, grlist->gids) < 0) {
-           sudo_grlist_delref(grlist);
-           grlist = NULL;
+    gidlist = sudo_get_gidlist(pw);
+    if (gidlist != NULL) {
+       if (sudo_setgroups(gidlist->ngids, gidlist->gids) < 0) {
+           sudo_gidlist_delref(gidlist);
+           gidlist = NULL;
        }
     }
-    debug_return_ptr(grlist);
+    debug_return_ptr(gidlist);
 }
 #endif /* HAVE_SETRESUID || HAVE_SETREUID || HAVE_SETEUID */
index 67dd6b275e86d5e02e72c1dcd0569f558a264d48..74b02dcee4af6f3ebcc7fb3dd7f6b1227f57c3d6 100644 (file)
@@ -695,8 +695,8 @@ init_vars(char * const envp[])
            unknown_user = true;
        }
     }
-    if (user_group_list == NULL)
-       user_group_list = sudo_get_grlist(sudo_user.pw);
+    if (user_gid_list == NULL)
+       user_gid_list = sudo_get_gidlist(sudo_user.pw);
 
     /* Store initialize permissions so we can restore them later. */
     if (!set_perms(PERM_INITIAL))
index bf2ce13dd700dcb18261285a2302c910bd1cecb6..5ff7346a0ea3b66e79f184c76940f191f1ff270f 100644 (file)
 #include "sudoers_debug.h"
 
 /*
- * Password db and supplementary group IDs with associated group names.
+ * Supplementary group IDs for a user.
  */
-struct group_list {
-    char **groups;
+struct gid_list {
+    int ngids;
     GETGROUPS_T *gids;
+};
+
+/*
+ * Supplementary group names for a user.
+ */
+struct group_list {
     int ngroups;
-    int ngids;
+    char **groups;
 };
 
 /*
@@ -77,7 +83,7 @@ struct sudo_user {
     char *cmnd_safe;
     char *class_name;
     char *krb5_ccname;
-    struct group_list *group_list;
+    struct gid_list *gid_list;
     char * const * env_vars;
 #ifdef HAVE_SELINUX
     char *role;
@@ -183,7 +189,7 @@ struct sudo_user {
 #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_gid_list          (sudo_user.gid_list)
 #define user_tty               (sudo_user.tty)
 #define user_ttypath           (sudo_user.ttypath)
 #define user_cwd               (sudo_user.cwd)
@@ -294,6 +300,7 @@ __dso_public void sudo_gr_addref(struct group *);
 __dso_public void sudo_gr_delref(struct group *);
 bool user_in_group(const struct passwd *, const char *);
 struct group *sudo_fakegrnam(const char *);
+struct gid_list *sudo_get_gidlist(const struct passwd *pw);
 struct group_list *sudo_get_grlist(const struct passwd *pw);
 struct passwd *sudo_fakepwnam(const char *, gid_t);
 struct passwd *sudo_mkpwent(const char *user, uid_t uid, gid_t gid, const char *home, const char *shell);
@@ -302,11 +309,14 @@ struct passwd *sudo_getpwuid(uid_t);
 void sudo_endspent(void);
 void sudo_freegrcache(void);
 void sudo_freepwcache(void);
+void sudo_gidlist_addref(struct gid_list *);
+void sudo_gidlist_delref(struct gid_list *);
 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 *);
-int  sudo_set_grlist(struct passwd *pw, char * const *groups, char * const *gids);
+int  sudo_set_gidlist(struct passwd *pw, char * const *gids);
+int  sudo_set_grlist(struct passwd *pw, char * const *groups);
 void sudo_setspent(void);
 
 /* timestr.c */