From 2678833013e97f8b18f09779b7f70bcbf5eb2ab2 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 7 Sep 2018 14:41:53 +1000 Subject: 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@ --- groupaccess.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'groupaccess.c') 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; } } -- cgit v1.2.3