/* This test was ripped out of GNU 'id' from coreutils-5.0 * by Erik Andersen. * * * id is Copyright (C) 1989-2003 Free Software Foundation, Inc. * and licensed under the GPL v2 or later, and was written by * Arnold Robbins, with a major rewrite by David MacKenzie, */ #include #include #include #include #include #include /* The number of errors encountered so far. */ static int problems = 0; /* Print the name or value of group ID GID. */ static void print_group(gid_t gid) { struct group *grp = NULL; grp = getgrgid(gid); if (grp == NULL) { fprintf(stderr, "cannot find name for group ID %u\n", gid); problems++; } if (grp == NULL) printf("%u", (unsigned)gid); else printf("%s", grp->gr_name); } static int xgetgroups(gid_t gid, int *n_groups, gid_t ** groups) { int max_n_groups; int ng; gid_t *g; int fail = 0; max_n_groups = getgroups(0, NULL); /* Add 1 just in case max_n_groups is zero. */ g = (gid_t *) malloc(max_n_groups * sizeof(gid_t) + 1); if (g == NULL) { fprintf(stderr, "out of memory\n"); exit(EXIT_FAILURE); } ng = getgroups(max_n_groups, g); if (ng < 0) { fprintf(stderr, "cannot get supplemental group list\n"); ++fail; free(g); } if (!fail) { *n_groups = ng; *groups = g; } return fail; } /* Print all of the distinct groups the user is in. */ int main(int argc, char *argv[]) { struct passwd *pwd; pwd = getpwuid(getuid()); if (pwd == NULL) problems++; print_group(getgid()); if (getegid() != getgid()) { putchar(' '); print_group(getegid()); } { int n_groups = 0; gid_t *groups; register int i; if (xgetgroups((pwd ? pwd->pw_gid : (gid_t) - 1), &n_groups, &groups)) { return ++problems; } for (i = 0; i < n_groups; i++) if (groups[i] != getgid() && groups[i] != getegid()) { putchar(' '); print_group(groups[i]); } free(groups); } putchar('\n'); return (problems != 0); }