Hi,
this patch adds the bb_getgrouplist_malloc funtion to libb:
llist_t* FAST_FUNC bb_getgrouplist_malloc(uid_t ruid, gid_t rgid, gid_t *egid)
The functon returns a malloced linked list of the user's gids that you will
have to free
yourself, or NULL on failure. If gid_t *egid is not NULL and *egid != rgid
*egid is added
at the second place of the list.
The advantages of this function are:
1) the list is easy to walk (without the need of group number counters)
2) used memory is easy to free (without the need of saved pointers to the
beginning of the allocated memory).
3) the function uses getgrouplist if available or getgrent.
4) it can handle egid != rgid if needed
llist_t* FAST_FUNC bb_getgrouplist_malloc(uid_t ruid, gid_t rgid, gid_t *egid)
Please apply if you like it.
Hints and critics are welcome.
Ciao,
Tito
--- include/libbb_orig.h 2008-09-12 16:34:23.000000000 +0200
+++ include/libbb.h 2008-09-21 13:26:48.000000000 +0200
@@ -857,6 +857,8 @@
* llist_t *llist_add_to(llist_t *old_head, void *data)
* etc does not result in smaller code... */
+/* returns a malloced linked list of the user's gids or NULL on failure */
+llist_t *bb_getgrouplist_malloc(uid_t ruid, gid_t rgid, gid_t *egid) FAST_FUNC;
/* start_stop_daemon and udhcpc are special - they want
* to create pidfiles regardless of FEATURE_PIDFILE */
#if ENABLE_FEATURE_PIDFILE || defined(WANT_PIDFILE)
--- libbb/bb_getgrouplist_malloc_orig.c 1970-01-01 01:00:00.000000000 +0100
+++ libbb/bb_getgrouplist_malloc.c 2008-09-21 13:31:36.000000000 +0200
@@ -0,0 +1,92 @@
+/*
+ * Enhanced getgrouplist implementation for busybox
+ *
+ * Copyright (C) 2008 Tito Ragusa <[EMAIL PROTECTED]>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+/* Returns a malloced linked list of the user's gids that you will have to free
+ * yourself, or NULL on failure. If gid_t *egid is not NULL and *egid != rgid
+ * *egid is added at the second place of the list.
+ */
+
+#include "libbb.h"
+
+#if (defined(__GLIBC__) && !defined(__UCLIBC__))
+#define HAVE_getgrouplist 1
+#elif ENABLE_USE_BB_PWD_GRP
+#define HAVE_getgrouplist 1
+#else
+#define HAVE_getgrouplist 0
+#endif
+
+#ifdef HAVE_getgrouplist
+llist_t* FAST_FUNC bb_getgrouplist_malloc(uid_t ruid, gid_t rgid, gid_t *egid)
+{
+ llist_t *group_list = NULL;
+ const char *username;
+ int n = 0;
+ int i;
+ gid_t *groups = NULL;
+
+ /* Returns NULL on failure */
+ username = bb_getpwuid(NULL, -1, ruid);
+ if (username) {
+ /* Get the number of groups we belong to */
+ getgrouplist(username, rgid, groups, &n);
+ /* malloc the needed emory */
+ groups = xrealloc(groups, sizeof(groups[0]) * n);
+ /* Get the gid list */
+ getgrouplist(username, rgid, groups, &n);
+ /* Create our linked list */
+ for (i = 0; i < n; i++) {
+ if (i == 1 && egid && rgid != *egid) {
+ /* Add egid at the second place if needed */
+ llist_add_to_end(&group_list, memcpy(xmalloc(sizeof(gid_t)), egid, sizeof(gid_t)));
+ }
+ llist_add_to_end(&group_list, memcpy(xmalloc(sizeof(gid_t)), &groups[i], sizeof(gid_t)));
+ }
+ if (ENABLE_FEATURE_CLEAN_UP)
+ free(groups);
+ }
+ return group_list;
+}
+#else
+llist_t* FAST_FUNC bb_getgrouplist_malloc(uid_t ruid, gid_t rgid, gid_t *egid)
+{
+ llist_t *group_list = NULL;
+ const char *username;
+ struct group *grp;
+
+ /* Returns NULL on failure */
+ username = bb_getpwuid(NULL, -1, ruid);
+ if (username) {
+ /* Add gid at the first place of the linked list */
+ llist_add_to_end(&group_list, memcpy(xmalloc(sizeof(gid_t)), &rgid, sizeof(gid_t)));
+ /* Add egid at the second place of the linked list if needed */
+ if (egid && rgid != *egid)
+ llist_add_to_end(&group_list, memcpy(xmalloc(sizeof(gid_t)), egid, sizeof(gid_t)));
+ /* Walk through the groups */
+ while((grp = getgrent())) {
+ /* We added them already so skip them */
+ if (grp->gr_gid == rgid || (egid && grp->gr_gid == *egid))
+ continue;
+ while (*(grp->gr_mem)) {
+ /* Are we a member of this group? */
+ if (!strcmp(username, *(grp->gr_mem))) {
+ /* We are a member of this group, add the gid to the linked list */
+ llist_add_to_end(&group_list, memcpy(xmalloc(sizeof(gid_t)), &(grp->gr_gid), sizeof(gid_t)));
+ /* No need to continue the search, we cannot be list member twice */
+ break;
+ }
+ /* Next group member */
+ (grp->gr_mem)++;
+ }
+ }
+ /* Clean up */
+ endgrent();
+ }
+ return group_list;
+}
+#endif
--- libbb/Kbuild_orig 2008-07-17 21:25:58.000000000 +0200
+++ libbb/Kbuild 2008-09-19 22:07:49.000000000 +0200
@@ -11,6 +11,7 @@
lib-y += bb_askpass.o
lib-y += bb_basename.o
lib-y += bb_do_delay.o
+lib-y += bb_getgrouplist_malloc.o
lib-y += bb_pwd.o
lib-y += bb_qsort.o
lib-y += bb_strtod.o
_______________________________________________
busybox mailing list
[email protected]
http://busybox.net/cgi-bin/mailman/listinfo/busybox