id: fix "id <user>" case. Requires getgrouplist().

function                                             old     new   delta
getgrouplist_internal                                  -     200    +200
id_main                                              462     539     +77
bb_internal_getgrouplist                               -      67     +67
bb__parsespent                                       119     117      -2
bb_internal_initgroups                               213      58    -155
------------------------------------------------------------------------------
(add/remove: 2/0 grow/shrink: 1/2 up/down: 344/-157)          Total: 187 bytes
This commit is contained in:
Denis Vlasenko
2008-09-18 00:56:24 +00:00
parent 28f5619e84
commit 2228426512
2 changed files with 87 additions and 33 deletions

View File

@@ -620,43 +620,67 @@ struct spwd *sgetspent(const char *string)
}
#endif
int initgroups(const char *user, gid_t gid)
static gid_t *getgrouplist_internal(int *ngroups_ptr, const char *user, gid_t gid)
{
FILE *grfile;
gid_t *group_list;
int num_groups, rv;
char **m;
int ngroups;
struct group group;
char buff[PWD_BUFFER_SIZE];
rv = -1;
/* We alloc space for 8 gids at a time. */
group_list = xmalloc(8 * sizeof(group_list[0]));
group_list[0] = gid;
ngroups = 1;
grfile = fopen_for_read(_PATH_GROUP);
if (grfile != NULL) {
/* We alloc space for 8 gids at a time. */
group_list = xmalloc(8 * sizeof(gid_t *));
*group_list = gid;
num_groups = 1;
if (grfile) {
while (!bb__pgsreader(bb__parsegrent, &group, buff, sizeof(buff), grfile)) {
char **m;
assert(group.gr_mem); /* Must have at least a NULL terminator. */
if (group.gr_gid != gid) {
for (m = group.gr_mem; *m; m++) {
if (!strcmp(*m, user)) {
group_list = xrealloc_vector(group_list, 3, num_groups);
group_list[num_groups++] = group.gr_gid;
break;
}
}
if (group.gr_gid == gid)
continue;
for (m = group.gr_mem; *m; m++) {
if (strcmp(*m, user) != 0)
continue;
group_list = xrealloc_vector(group_list, 3, ngroups);
group_list[ngroups++] = group.gr_gid;
break;
}
}
rv = setgroups(num_groups, group_list);
free(group_list);
fclose(grfile);
}
*ngroups_ptr = ngroups;
return group_list;
}
return rv;
int initgroups(const char *user, gid_t gid)
{
int ngroups;
gid_t *group_list = getgrouplist_internal(&ngroups, user, gid);
if (!group_list)
return -1;
ngroups = setgroups(ngroups, group_list);
free(group_list);
return ngroups;
}
/* TODO: uclibc needs this ported to it! */
int getgrouplist(const char *user, gid_t gid, gid_t *groups, int *ngroups)
{
int ngroups_old = *ngroups;
gid_t *group_list = getgrouplist_internal(ngroups, user, gid);
if (*ngroups <= ngroups_old) {
ngroups_old = *ngroups;
memcpy(groups, group_list, ngroups_old * sizeof(groups[0]));
} else {
ngroups_old = -1;
}
free(group_list);
return ngroups_old;
}
int putpwent(const struct passwd *__restrict p, FILE *__restrict f)