summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/misc/getgrouplist.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/src/misc/getgrouplist.c b/src/misc/getgrouplist.c
index 88f273d7..63557afe 100644
--- a/src/misc/getgrouplist.c
+++ b/src/misc/getgrouplist.c
@@ -1,11 +1,23 @@
#include <grp.h>
-
-/* FIXME */
+#include <string.h>
+#include <limits.h>
int getgrouplist(const char *user, gid_t gid, gid_t *groups, int *ngroups)
{
+ size_t n, i;
+ struct group *gr;
if (*ngroups<1) return -1;
- *groups = gid;
+ n = *ngroups;
+ *groups++ = gid;
*ngroups = 1;
- return 0;
+
+ setgrent();
+ while ((gr = getgrent()) && *ngroups < INT_MAX) {
+ for (i=0; gr->gr_mem[i] && strcmp(user, gr->gr_mem[i]); i++);
+ if (!gr->gr_mem[i]) continue;
+ if (++*ngroups <= n) *groups++ = gr->gr_gid;
+ }
+ endgrent();
+
+ return *ngroups > n ? -1 : *ngroups;
}