diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2011-06-22 16:42:36 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2011-06-22 16:42:36 +0200 |
commit | 52f4fe9db6cedfba332ee0923182f5b2e9d9673b (patch) | |
tree | a150597a766f5761fef33b7af35a2d4e4b8a4978 | |
parent | d5ac9c88a7f620f6b775e404b145017827a10480 (diff) | |
download | busybox-w32-52f4fe9db6cedfba332ee0923182f5b2e9d9673b.tar.gz busybox-w32-52f4fe9db6cedfba332ee0923182f5b2e9d9673b.tar.bz2 busybox-w32-52f4fe9db6cedfba332ee0923182f5b2e9d9673b.zip |
id: correct getgroups usage
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | coreutils/id.c | 31 |
1 files changed, 15 insertions, 16 deletions
diff --git a/coreutils/id.c b/coreutils/id.c index bb950f9ec..399d25e34 100644 --- a/coreutils/id.c +++ b/coreutils/id.c | |||
@@ -117,7 +117,7 @@ static int print_user(uid_t id, const char *prefix) | |||
117 | 117 | ||
118 | /* On error set *n < 0 and return >= 0 | 118 | /* On error set *n < 0 and return >= 0 |
119 | * If *n is too small, update it and return < 0 | 119 | * If *n is too small, update it and return < 0 |
120 | * (ok to trash groups[] in both cases) | 120 | * (ok to trash groups[] in both cases) |
121 | * Otherwise fill in groups[] and return >= 0 | 121 | * Otherwise fill in groups[] and return >= 0 |
122 | */ | 122 | */ |
123 | static int get_groups(const char *username, gid_t rgid, gid_t *groups, int *n) | 123 | 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) | |||
131 | m = getgrouplist(username, rgid, groups, n); | 131 | m = getgrouplist(username, rgid, groups, n); |
132 | /* I guess *n < 0 might indicate error. Anyway, | 132 | /* I guess *n < 0 might indicate error. Anyway, |
133 | * malloc'ing -1 bytes won't be good, so: */ | 133 | * malloc'ing -1 bytes won't be good, so: */ |
134 | //if (*n < 0) | 134 | if (*n < 0) |
135 | // return 0; | 135 | return 0; |
136 | //return m; | 136 | return m; |
137 | //commented out here, happens below anyway | ||
138 | } else { | ||
139 | /* On error -1 is returned, which ends up in *n */ | ||
140 | int nn = getgroups(*n, groups); | ||
141 | /* 0: nn <= *n, groups[] was big enough; -1 otherwise */ | ||
142 | m = - (nn > *n); | ||
143 | *n = nn; | ||
144 | } | 137 | } |
145 | if (*n < 0) | 138 | |
146 | return 0; /* error, don't return < 0! */ | 139 | *n = getgroups(*n, groups); |
147 | return m; | 140 | if (*n >= 0) |
141 | return *n; | ||
142 | /* Error */ | ||
143 | if (errno == EINVAL) /* *n is too small? */ | ||
144 | *n = getgroups(0, groups); /* get needed *n */ | ||
145 | /* if *n >= 0, return -1 (got new *n), else return 0 (error): */ | ||
146 | return -(*n >= 0); | ||
148 | } | 147 | } |
149 | 148 | ||
150 | int id_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 149 | int id_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
@@ -214,11 +213,11 @@ int id_main(int argc UNUSED_PARAM, char **argv) | |||
214 | /* We are supplying largish buffer, trying | 213 | /* We are supplying largish buffer, trying |
215 | * to not run get_groups() twice. That might be slow | 214 | * to not run get_groups() twice. That might be slow |
216 | * ("user database in remote SQL server" case) */ | 215 | * ("user database in remote SQL server" case) */ |
217 | groups = xmalloc(64 * sizeof(gid_t)); | 216 | groups = xmalloc(64 * sizeof(groups[0])); |
218 | n = 64; | 217 | n = 64; |
219 | if (get_groups(username, rgid, groups, &n) < 0) { | 218 | if (get_groups(username, rgid, groups, &n) < 0) { |
220 | /* Need bigger buffer after all */ | 219 | /* Need bigger buffer after all */ |
221 | groups = xrealloc(groups, n * sizeof(gid_t)); | 220 | groups = xrealloc(groups, n * sizeof(groups[0])); |
222 | get_groups(username, rgid, groups, &n); | 221 | get_groups(username, rgid, groups, &n); |
223 | } | 222 | } |
224 | if (n > 0) { | 223 | if (n > 0) { |