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

Reply via email to