id: correct getgroups usage

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2011-06-22 16:42:36 +02:00
parent d5ac9c88a7
commit 52f4fe9db6

View File

@ -117,7 +117,7 @@ static int print_user(uid_t id, const char *prefix)
/* On error set *n < 0 and return >= 0 /* On error set *n < 0 and return >= 0
* If *n is too small, update it and return < 0 * If *n is too small, update it and return < 0
* (ok to trash groups[] in both cases) * (ok to trash groups[] in both cases)
* Otherwise fill in groups[] and return >= 0 * Otherwise fill in groups[] and return >= 0
*/ */
static int get_groups(const char *username, gid_t rgid, gid_t *groups, int *n) static int get_groups(const char *username, gid_t rgid, gid_t *groups, int *n)
@ -131,20 +131,19 @@ static int get_groups(const char *username, gid_t rgid, gid_t *groups, int *n)
m = getgrouplist(username, rgid, groups, n); m = getgrouplist(username, rgid, groups, n);
/* I guess *n < 0 might indicate error. Anyway, /* I guess *n < 0 might indicate error. Anyway,
* malloc'ing -1 bytes won't be good, so: */ * malloc'ing -1 bytes won't be good, so: */
//if (*n < 0) if (*n < 0)
// return 0; return 0;
//return m; return m;
//commented out here, happens below anyway
} else {
/* On error -1 is returned, which ends up in *n */
int nn = getgroups(*n, groups);
/* 0: nn <= *n, groups[] was big enough; -1 otherwise */
m = - (nn > *n);
*n = nn;
} }
if (*n < 0)
return 0; /* error, don't return < 0! */ *n = getgroups(*n, groups);
return m; if (*n >= 0)
return *n;
/* Error */
if (errno == EINVAL) /* *n is too small? */
*n = getgroups(0, groups); /* get needed *n */
/* if *n >= 0, return -1 (got new *n), else return 0 (error): */
return -(*n >= 0);
} }
int id_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int id_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
@ -214,11 +213,11 @@ int id_main(int argc UNUSED_PARAM, char **argv)
/* We are supplying largish buffer, trying /* We are supplying largish buffer, trying
* to not run get_groups() twice. That might be slow * to not run get_groups() twice. That might be slow
* ("user database in remote SQL server" case) */ * ("user database in remote SQL server" case) */
groups = xmalloc(64 * sizeof(gid_t)); groups = xmalloc(64 * sizeof(groups[0]));
n = 64; n = 64;
if (get_groups(username, rgid, groups, &n) < 0) { if (get_groups(username, rgid, groups, &n) < 0) {
/* Need bigger buffer after all */ /* Need bigger buffer after all */
groups = xrealloc(groups, n * sizeof(gid_t)); groups = xrealloc(groups, n * sizeof(groups[0]));
get_groups(username, rgid, groups, &n); get_groups(username, rgid, groups, &n);
} }
if (n > 0) { if (n > 0) {