diff options
author | Darren Tucker <dtucker@dtucker.net> | 2018-09-07 14:41:53 +1000 |
---|---|---|
committer | Darren Tucker <dtucker@dtucker.net> | 2018-09-07 14:41:53 +1000 |
commit | 2678833013e97f8b18f09779b7f70bcbf5eb2ab2 (patch) | |
tree | 522fb0d2437ac3665d6ecddb30cfe0020289be96 /groupaccess.c | |
parent | 039bf2a81797b8f3af6058d34005a4896a363221 (diff) |
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 | |||
50 | ga_init(const char *user, gid_t base) | 50 | ga_init(const char *user, gid_t base) |
51 | { | 51 | { |
52 | gid_t *groups_bygid; | 52 | gid_t *groups_bygid; |
53 | int i, j; | 53 | int i, j, retry = 0; |
54 | struct group *gr; | 54 | struct group *gr; |
55 | 55 | ||
56 | if (ngroups > 0) | 56 | if (ngroups > 0) |
@@ -62,10 +62,14 @@ ga_init(const char *user, gid_t base) | |||
62 | #endif | 62 | #endif |
63 | 63 | ||
64 | groups_bygid = xcalloc(ngroups, sizeof(*groups_bygid)); | 64 | groups_bygid = xcalloc(ngroups, sizeof(*groups_bygid)); |
65 | while (getgrouplist(user, base, groups_bygid, &ngroups) == -1) { | ||
66 | if (retry++ > 0) | ||
67 | fatal("getgrouplist: groups list too small"); | ||
68 | groups_bygid = xreallocarray(groups_bygid, ngroups, | ||
69 | sizeof(*groups_bygid)); | ||
70 | } | ||
65 | groups_byname = xcalloc(ngroups, sizeof(*groups_byname)); | 71 | groups_byname = xcalloc(ngroups, sizeof(*groups_byname)); |
66 | 72 | ||
67 | if (getgrouplist(user, base, groups_bygid, &ngroups) == -1) | ||
68 | logit("getgrouplist: groups list too small"); | ||
69 | for (i = 0, j = 0; i < ngroups; i++) | 73 | for (i = 0, j = 0; i < ngroups; i++) |
70 | if ((gr = getgrgid(groups_bygid[i])) != NULL) | 74 | if ((gr = getgrgid(groups_bygid[i])) != NULL) |
71 | groups_byname[j++] = xstrdup(gr->gr_name); | 75 | groups_byname[j++] = xstrdup(gr->gr_name); |
@@ -124,5 +128,6 @@ ga_free(void) | |||
124 | free(groups_byname[i]); | 128 | free(groups_byname[i]); |
125 | ngroups = 0; | 129 | ngroups = 0; |
126 | free(groups_byname); | 130 | free(groups_byname); |
131 | groups_byname = NULL; | ||
127 | } | 132 | } |
128 | } | 133 | } |