]> git.ipfire.org Git - thirdparty/openssh-portable.git/commitdiff
Handle ngroups>_SC_NGROUPS_MAX.
authorDarren Tucker <dtucker@dtucker.net>
Fri, 7 Sep 2018 04:41:53 +0000 (14:41 +1000)
committerDarren Tucker <dtucker@dtucker.net>
Fri, 7 Sep 2018 04:41:53 +0000 (14:41 +1000)
Based on github pull request #99 from Darren Maffat at Oracle: Solaris'
getgrouplist considers _SC_NGROUPS_MAX more of a guideline and can return
a larger number of groups.  In this case, retry getgrouplist with a
larger array and defer allocating groups_byname.  ok djm@

groupaccess.c

index 2518c84874c5a71f96fd27fc65b9f7e0dfd9f911..9e4d25521647dab0020bddfc4a3dea59091e8770 100644 (file)
@@ -50,7 +50,7 @@ int
 ga_init(const char *user, gid_t base)
 {
        gid_t *groups_bygid;
-       int i, j;
+       int i, j, retry = 0;
        struct group *gr;
 
        if (ngroups > 0)
@@ -62,10 +62,14 @@ ga_init(const char *user, gid_t base)
 #endif
 
        groups_bygid = xcalloc(ngroups, sizeof(*groups_bygid));
+       while (getgrouplist(user, base, groups_bygid, &ngroups) == -1) {
+               if (retry++ > 0)
+                       fatal("getgrouplist: groups list too small");
+               groups_bygid = xreallocarray(groups_bygid, ngroups,
+                   sizeof(*groups_bygid));
+       }
        groups_byname = xcalloc(ngroups, sizeof(*groups_byname));
 
-       if (getgrouplist(user, base, groups_bygid, &ngroups) == -1)
-               logit("getgrouplist: groups list too small");
        for (i = 0, j = 0; i < ngroups; i++)
                if ((gr = getgrgid(groups_bygid[i])) != NULL)
                        groups_byname[j++] = xstrdup(gr->gr_name);
@@ -124,5 +128,6 @@ ga_free(void)
                        free(groups_byname[i]);
                ngroups = 0;
                free(groups_byname);
+               groups_byname = NULL;
        }
 }