On Monday 15 September 2008 23:23:19 Tito wrote:
> Hi to all,
> i'm thinking about a getgrouplist implementation for busybox.
> To use for example in id, but maybe also other applets could
> use it. So far I have two different versions based on the same
> algoritm but I'm unable to decide which is the right way to go
> or if I'm on a dead end.
> Hints, critics comments are welcome..........
Now with correct rgid and egid handling.
Usage as before.
> Ciao,
> Tito
>
> gid_t *bb_getgrouplist_malloc(uid_t uid, int *ngrp)
>
> Usage example:
>
> int ngrp = 0;
> gid_t grplist * = bb_getgrouplist_malloc(uid, &ngrp);
> for (int i = 0; i < ngrp; i++) {
> printf("%d ", grplist[i]);
> }
> free(grp_list);
>
> llist_t *bb_getgrouplist_malloc(uid_t uid)
>
> Usage example:
>
> list_t * grplist = bb_getgrouplist_malloc(uid);
> while (grplist) {
> gid_t *gid = llist_pop(&grplist);
> printf("%d ", *gid);
> free(gid);
> }
> free(grplist);
>
>
>
static gid_t *bb_getgrouplist_malloc(uid_t uid, int *ngrp)
{
FILE *group_file;
struct passwd *pwd;
struct group *grp;
gid_t *group_list = NULL;
gid_t euid;
/* Counter for mallocing memory */
int n = 1;
char *line;
/* Default for error conditions */
*ngrp = 0;
pwd = getpwuid(uid);
group_file = fopen_or_warn(bb_path_group_file, "r");
if (group_file && pwd) {
/* Add the already known gid to the list */
group_list = (gid_t *) xmalloc(sizeof(gid_t));
memcpy(&group_list[0], &(pwd->pw_gid), sizeof(gid_t));
*ngrp = 1;
euid = geteuid();
if (pwd->pw_gid != euid) {
group_list = xrealloc(group_list, ++n * sizeof(gid_t));
memcpy(&group_list[1], &euid, sizeof(gid_t));
}
/* Walk through /etc/group */
while ((line = xmalloc_fgetline(group_file)) != NULL) {
/* Get the group name token and obtain a struct group */
/* rather than try to parse the whole line */
/* This should not fail unless group is removed after */
/* we read the line. We can ignore it */
grp = getgrnam(strtok(line, ":"));
/* Check if we have this one already */
if (grp && grp->gr_gid != pwd->pw_gid) {
/* Walk through the group members */
while (*(grp->gr_mem)) {
/* Are we a member of this group? */
if (!strcmp(pwd->pw_name,
*(grp->gr_mem))) {
/* Found, realloc the needed
space */
group_list =
xrealloc(group_list, ++n * sizeof(gid_t));
/* Copy the gid to the list */
memcpy(&group_list[n - 1],
&(grp->gr_gid), sizeof(gid_t));
/* No need to continue the
search */
break;
}
(grp->gr_mem)++;
}
}
free(line);
}
*ngrp = n;
/* Clean up */
fclose(group_file);
}
return group_list;
}
static llist_t *bb_getgrouplist_malloc(uid_t uid)
{
FILE *group_file;
struct passwd *pwd;
struct group *grp;
gid_t euid;
llist_t *group_list = NULL;
char *line;
pwd = getpwuid(uid);
group_file = fopen_or_warn(bb_path_group_file, "r");
if (group_file && pwd) {
/* Add the already known gid to the list */
llist_add_to_end(&group_list, memcpy(xmalloc(sizeof(gid_t)),
&(pwd->pw_gid), sizeof(gid_t)));
euid = geteuid();
if (pwd->pw_gid != euid) {
llist_add_to_end(&group_list,
memcpy(xmalloc(sizeof(gid_t)), &euid, sizeof(gid_t)));
}
/* Walk through /etc/group */
while ((line = xmalloc_fgetline(group_file)) != NULL) {
/* Get the group name token and obtain a struct group */
/* rather than try to parse the whole line */
/* This should not fail unless group is removed after */
/* we read the line. We can ignore it */
grp = getgrnam(strtok(line, ":"));
/* Check if we have this one already */
if (grp && grp->gr_gid != pwd->pw_gid) {
/* Walk through the group members */
while (*(grp->gr_mem)) {
/* Are we a member of this group? */
if (!strcmp(pwd->pw_name,
*(grp->gr_mem))) {
/* Found, add the gid to the
list */
llist_add_to_end(&group_list,
memcpy(xmalloc(sizeof(gid_t)), &(grp->gr_gid), sizeof(gid_t)));
/* No need to continue the
search, cannot be list member twice */
break;
}
/* Next group member */
(grp->gr_mem)++;
}
}
/* Clean up */
free(line);
}
/* Clean up */
fclose(group_file);
}
/* return list or NULL on error */
return group_list;
}
_______________________________________________
busybox mailing list
[email protected]
http://busybox.net/cgi-bin/mailman/listinfo/busybox