1 /* id -- print real and effective UIDs and GIDs
2 Copyright (C) 1989, 1991 Free Software Foundation.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
18 /* Written by Arnold Robbins, arnold@audiofax.com.
19 Major rewrite by David MacKenzie, djm@gnu.ai.mit.edu. */
23 #include <sys/types.h>
30 #if !defined(NGROUPS_MAX) || NGROUPS_MAX < 1
31 #define NGROUPS_MAX sysconf (_SC_NGROUPS_MAX)
32 #endif /* !NGROUPS_MAX */
34 /* Even though SunOS 4, Ultrix 4, and 386BSD are mostly POSIX.1 compliant,
35 their getgroups system call (except in the `System V' environment, which
36 is troublesome in other ways) fills in an array of int, not gid_t
37 (which is `short' on those systems). Kludge, kludge. */
39 #if !defined(sun) && !defined(ultrix) && !defined(__386BSD__)
40 #define GETGROUPS_T gid_t
41 #else /* sun or ultrix or 386BSD */
42 #define GETGROUPS_T int
43 #endif /* sun or ultrix or 386BSD */
44 #else /* not _POSIX_VERSION */
45 struct passwd *getpwuid ();
46 struct group *getgrgid ();
51 #include <sys/param.h>
52 #if !defined(NGROUPS_MAX) && defined(NGROUPS)
53 #define NGROUPS_MAX NGROUPS
54 #endif /* not NGROUPS_MAX and NGROUPS */
55 #define GETGROUPS_T int
56 #endif /* not _POSIX_VERSION */
63 void print_group_list ();
64 void print_full_info ();
67 /* The name this program was run with. */
70 /* If nonzero, output only the group ID(s). -g */
73 /* If nonzero, output user/group name instead of ID number. -n */
76 /* If nonzero, output real UID/GID instead of default effective UID/GID. -r */
79 /* If nonzero, output only the user ID(s). -u */
82 /* If nonzero, output only the supplementary groups. -G */
83 int just_group_list = 0;
85 /* The real and effective IDs of the user to print. */
89 /* The number of errors encountered so far. */
92 struct option longopts[] =
94 {"group", 0, NULL, 'g'},
95 {"name", 0, NULL, 'n'},
96 {"real", 0, NULL, 'r'},
97 {"user", 0, NULL, 'u'},
98 {"groups", 0, NULL, 'G'},
109 program_name = argv[0];
111 while ((optc = getopt_long (argc, argv, "gnruG", longopts, (int *) 0))
136 if (just_user + just_group + just_group_list > 1)
137 error (1, 0, "cannot print only user and only group");
139 if (just_user + just_group + just_group_list == 0 && (use_real || use_name))
140 error (1, 0, "cannot print only names or real IDs in default format");
142 if (argc - optind > 1)
145 if (argc - optind == 1)
147 struct passwd *pwd = getpwnam (argv[optind]);
149 error (1, 0, "%s: No such user", argv[optind]);
150 ruid = euid = pwd->pw_uid;
151 rgid = egid = pwd->pw_gid;
162 print_user (use_real ? ruid : euid);
164 print_group (use_real ? rgid : egid);
165 else if (just_group_list)
166 print_group_list (argv[optind]);
168 print_full_info (argv[optind]);
171 exit (problems != 0);
174 /* Print the name or value of user ID UID. */
180 struct passwd *pwd = NULL;
184 pwd = getpwuid (uid);
190 printf ("%u", (unsigned) uid);
192 printf ("%s", pwd->pw_name);
195 /* Print the name or value of group ID GID. */
201 struct group *grp = NULL;
205 grp = getgrgid (gid);
211 printf ("%u", (unsigned) gid);
213 printf ("%s", grp->gr_name);
216 /* Print all of the distinct groups the user is in . */
219 print_group_list (username)
235 groups = (GETGROUPS_T *) xmalloc (NGROUPS_MAX * sizeof (GETGROUPS_T));
237 ngroups = getgroups (NGROUPS_MAX, groups);
239 ngroups = getugroups (NGROUPS_MAX, groups, username);
242 error (0, errno, "cannot get supplemental group list");
248 for (i = 0; i < ngroups; i++)
249 if (groups[i] != rgid && groups[i] != egid)
252 print_group (groups[i]);
259 /* Print all of the info about the user's user and group IDs. */
262 print_full_info (username)
268 printf ("uid=%u", (unsigned) ruid);
269 pwd = getpwuid (ruid);
273 printf ("(%s)", pwd->pw_name);
275 printf (" gid=%u", (unsigned) rgid);
276 grp = getgrgid (rgid);
280 printf ("(%s)", grp->gr_name);
284 printf (" euid=%u", (unsigned) euid);
285 pwd = getpwuid (euid);
289 printf ("(%s)", pwd->pw_name);
294 printf (" egid=%u", (unsigned) egid);
295 grp = getgrgid (egid);
299 printf ("(%s)", grp->gr_name);
308 groups = (GETGROUPS_T *) xmalloc (NGROUPS_MAX * sizeof (GETGROUPS_T));
310 ngroups = getgroups (NGROUPS_MAX, groups);
312 ngroups = getugroups (NGROUPS_MAX, groups, username);
315 error (0, errno, "cannot get supplemental group list");
322 fputs (" groups=", stdout);
323 for (i = 0; i < ngroups; i++)
327 printf ("%u", (unsigned) groups[i]);
328 grp = getgrgid (groups[i]);
332 printf ("(%s)", grp->gr_name);
343 Usage: %s [-gnruG] [--group] [--name] [--real] [--user] [--groups] [username]\n",