From: Darren Tucker Date: Fri, 7 Sep 2018 04:41:53 +0000 (+1000) Subject: Handle ngroups>_SC_NGROUPS_MAX. X-Git-Tag: V_7_9_P1~77 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2678833013e97f8b18f09779b7f70bcbf5eb2ab2;p=thirdparty%2Fopenssh-portable.git Handle ngroups>_SC_NGROUPS_MAX. 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@ --- diff --git a/groupaccess.c b/groupaccess.c index 2518c8487..9e4d25521 100644 --- a/groupaccess.c +++ b/groupaccess.c @@ -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; } }