summaryrefslogtreecommitdiff
path: root/groupaccess.c
diff options
context:
space:
mode:
authorDarren Tucker <dtucker@dtucker.net>2018-09-07 14:41:53 +1000
committerDarren Tucker <dtucker@dtucker.net>2018-09-07 14:41:53 +1000
commit2678833013e97f8b18f09779b7f70bcbf5eb2ab2 (patch)
tree522fb0d2437ac3665d6ecddb30cfe0020289be96 /groupaccess.c
parent039bf2a81797b8f3af6058d34005a4896a363221 (diff)
downloadopenssh-git-2678833013e97f8b18f09779b7f70bcbf5eb2ab2.tar.gz
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.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/groupaccess.c b/groupaccess.c
index 2518c848..9e4d2552 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;
}
}