[RFC] bb_getgrouplist implementation

Tito farmatito at tiscali.it
Mon Sep 15 21:23:19 UTC 2008


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..........

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);



----------------------------------------------------------------------------------------------------------

gid_t *bb_getgrouplist_malloc(uid_t uid, int *ngrp)
{
	FILE *group_file;
	struct passwd *pwd;
	struct group *grp;
	gid_t *group_list = NULL;
	/* 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;
		/* 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;
}


llist_t *bb_getgrouplist_malloc(uid_t uid)
{
	FILE *group_file;
	struct passwd *pwd;
	struct group *grp;
	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)));
		/* 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;
}



More information about the busybox mailing list