blob: 5769b180b167bb89d44efd76f42e1f15a7d464ab [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001/* This test was ripped out of GNU 'id' from coreutils-5.0
2 * by Erik Andersen.
3 *
4 *
5 * id is Copyright (C) 1989-2003 Free Software Foundation, Inc.
6 * and licensed under the GPL v2 or later, and was written by
7 * Arnold Robbins, with a major rewrite by David MacKenzie,
8 */
9
10#include <stdio.h>
11#include <stdlib.h>
12#include <unistd.h>
13#include <sys/types.h>
14#include <pwd.h>
15#include <grp.h>
16#include <err.h>
17
18/* The number of errors encountered so far. */
19static int problems = 0;
20
21/* Print the name or value of group ID GID. */
22static void print_group(gid_t gid)
23{
24 struct group *grp = NULL;
25
26 grp = getgrgid(gid);
27 if (grp == NULL) {
28 warn("cannot find name for group ID %u", gid);
29 problems++;
30 }
31
32 if (grp == NULL)
33 printf("%u", (unsigned)gid);
34 else
35 printf("%s", grp->gr_name);
36}
37
38static int xgetgroups(gid_t gid, int *n_groups, gid_t ** groups)
39{
40 int max_n_groups;
41 int ng;
42 gid_t *g;
43 int fail = 0;
44
45 max_n_groups = getgroups(0, NULL);
46
47 /* Add 1 just in case max_n_groups is zero. */
48 g = (gid_t *) malloc(max_n_groups * sizeof(gid_t) + 1);
49 if (g == NULL)
50 err(EXIT_FAILURE, "out of memory");
51 ng = getgroups(max_n_groups, g);
52
53 if (ng < 0) {
54 warn("cannot get supplemental group list");
55 ++fail;
56 free(g);
57 }
58 if (!fail) {
59 *n_groups = ng;
60 *groups = g;
61 }
62 return fail;
63}
64
65/* Print all of the distinct groups the user is in. */
66int main(int argc, char *argv[])
67{
68 struct passwd *pwd;
69
70 pwd = getpwuid(getuid());
71 if (pwd == NULL)
72 problems++;
73
74 print_group(getgid());
75 if (getegid() != getgid()) {
76 putchar(' ');
77 print_group(getegid());
78 }
79
80 {
81 int n_groups = 0;
82 gid_t *groups;
83 register int i;
84
85 if (xgetgroups((pwd ? pwd->pw_gid : (gid_t) - 1),
86 &n_groups, &groups)) {
87 return ++problems;
88 }
89
90 for (i = 0; i < n_groups; i++)
91 if (groups[i] != getgid() && groups[i] != getegid()) {
92 putchar(' ');
93 print_group(groups[i]);
94 }
95 free(groups);
96 }
97 putchar('\n');
98 return (problems != 0);
99}