diff options
author | Darren Tucker <dtucker@dtucker.net> | 2018-09-07 06:41:53 +0200 |
---|---|---|
committer | Darren Tucker <dtucker@dtucker.net> | 2018-09-07 06:41:53 +0200 |
commit | 2678833013e97f8b18f09779b7f70bcbf5eb2ab2 (patch) | |
tree | 522fb0d2437ac3665d6ecddb30cfe0020289be96 /groupaccess.c | |
parent | Initial len for the fmt=NULL case. (diff) | |
download | openssh-2678833013e97f8b18f09779b7f70bcbf5eb2ab2.tar.xz openssh-2678833013e97f8b18f09779b7f70bcbf5eb2ab2.zip |
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@
Diffstat (limited to 'groupaccess.c')
-rw-r--r-- | groupaccess.c | 11 |
1 files changed, 8 insertions, 3 deletions
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; } } |