diff options
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | lib/mgetgroups.c | 31 | ||||
-rw-r--r-- | lib/mgetgroups.h | 1 | ||||
-rw-r--r-- | modules/mgetgroups | 1 |
4 files changed, 36 insertions, 4 deletions
@@ -1,5 +1,12 @@ 2009-12-04 Eric Blake <ebb9@byu.net> + mgetgroups: add xgetgroups, and avoid ENOSYS failures + * lib/mgetgroups.h (xgetgroups): New prototype. + * lib/mgetgroups.c (xgetgroups): New wrapper. + (mgetgroups): Handle ENOSYS. + * modules/mgetgroups (Depends-on): Add realloc. + Reported by Scott Harrison <scott.gnu.2009@scottrix.co.uk>. + mgetgroups: avoid argument promotion issues with -1 * lib/mgetgroups.c (mgetgroups): A cast is required when checking for invalid gid_t. diff --git a/lib/mgetgroups.c b/lib/mgetgroups.c index 9a733d5984..7a61db41d9 100644 --- a/lib/mgetgroups.c +++ b/lib/mgetgroups.c @@ -116,13 +116,24 @@ mgetgroups (char const *username, gid_t gid, gid_t **groups) max_n_groups = (username ? getugroups (0, NULL, username, gid) - : getgroups (0, NULL) + (gid != (gid_t) -1)); + : getgroups (0, NULL)); - /* If we failed to count groups with NULL for a buffer, - try again with a non-NULL one, just in case. */ + /* If we failed to count groups because there is no supplemental + group support, then return an array containing just GID. + Otherwise, we fail for the same reason. */ if (max_n_groups < 0) - max_n_groups = 5; + { + if (errno == ENOSYS && (g = realloc_groupbuf (NULL, 1))) + { + *groups = g; + *g = gid; + return gid != (gid_t) -1; + } + return -1; + } + if (!username && gid != (gid_t) -1) + max_n_groups++; g = realloc_groupbuf (NULL, max_n_groups); if (g == NULL) return -1; @@ -133,6 +144,7 @@ mgetgroups (char const *username, gid_t gid, gid_t **groups) if (ng < 0) { + /* Failure is unexpected, but handle it anyway. */ int saved_errno = errno; free (g); errno = saved_errno; @@ -147,3 +159,14 @@ mgetgroups (char const *username, gid_t gid, gid_t **groups) *groups = g; return ng; } + +/* Like mgetgroups, but call xalloc_die on allocation failure. */ + +int +xgetgroups (char const *username, gid_t gid, gid_t **groups) +{ + int result = mgetgroups (username, gid, groups); + if (result == -1 && errno == ENOMEM) + xalloc_die (); + return result; +} diff --git a/lib/mgetgroups.h b/lib/mgetgroups.h index 909d84c645..4868d28815 100644 --- a/lib/mgetgroups.h +++ b/lib/mgetgroups.h @@ -17,3 +17,4 @@ #include <sys/types.h> int mgetgroups (const char *username, gid_t gid, gid_t **groups); +int xgetgroups (const char *username, gid_t gid, gid_t **groups); diff --git a/modules/mgetgroups b/modules/mgetgroups index 58ef74086a..cd249dba31 100644 --- a/modules/mgetgroups +++ b/modules/mgetgroups @@ -9,6 +9,7 @@ m4/mgetgroups.m4 Depends-on: getgroups getugroups +realloc xalloc configure.ac: |