2 * Copyright (c) 1991 - 1994, Julianne Frances Haugh
3 * Copyright (c) 1996 - 2000, Marek Michałkiewicz
4 * Copyright (c) 2001 - 2006, Tomasz Kłoczko
5 * Copyright (c) 2007 - 2008, Nicolas François
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. The name of the copyright holders or contributors may not be used to
17 * endorse or promote products derived from this software without
18 * specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 * id - print current process user identification information
36 * Print the current process identifiers. This includes the
37 * UID, GID, effective-UID and effective-GID. Optionally print
38 * the concurrent group set if the current system supports it.
48 #include <sys/types.h>
50 /* local function prototypes */
51 static void usage (void);
53 static void usage (void)
56 (void) fputs (_("Usage: id [-a]\n"), stderr);
58 (void) fputs (_("Usage: id\n"), stderr);
63 /*ARGSUSED*/ int main (int argc, char **argv)
70 * This block of declarations is particularly strained because of several
71 * different ways of doing concurrent groups. Old BSD systems used int for
72 * gid's, but short for the type passed to getgroups(). Newer systems use
73 * gid_t for everything. Some systems have a small and fixed NGROUPS,
74 * usually about 16 or 32. Others use bigger values.
84 (void) setlocale (LC_ALL, "");
85 (void) bindtextdomain (PACKAGE, LOCALEDIR);
86 (void) textdomain (PACKAGE);
89 * Dynamically get the maximum number of groups from system, instead
90 * of using the symbolic constant NGROUPS_MAX. This ensures that the
91 * group limit is not hard coded into the binary, so it will still
92 * work if the system library is recompiled.
94 sys_ngroups = sysconf (_SC_NGROUPS_MAX);
96 groups = (GETGROUPS_T *) malloc (sizeof (GETGROUPS_T) * sys_ngroups);
98 * See if the -a flag has been given to print out the concurrent
103 if ((argc > 2) || (strcmp (argv[1], "-a") != 0)) {
121 * Print out the real user ID and group ID. If the user or group
122 * does not exist, just give the numerical value.
125 pw = getpwuid (ruid); /* local, no need for xgetpwuid */
127 (void) printf ("UID=%lu(%s)",
128 (unsigned long) ruid, pw->pw_name);
130 (void) printf ("UID=%lu", (unsigned long) ruid);
133 gr = getgrgid (rgid);; /* local, no need for xgetgrgid */
135 (void) printf (" GID=%lu(%s)",
136 (unsigned long) rgid, gr->gr_name);
138 (void) printf (" GID=%lu", (unsigned long) rgid);
142 * Print out the effective user ID and group ID if they are
143 * different from the real values.
147 pw = getpwuid (euid); /* local, no need for xgetpwuid */
149 (void) printf (" EUID=%lu(%s)",
150 (unsigned long) euid, pw->pw_name);
152 (void) printf (" EUID=%lu", (unsigned long) euid);
156 gr = getgrgid (egid); /* local, no need for xgetgrgid */
158 (void) printf (" EGID=%lu(%s)",
159 (unsigned long) egid, gr->gr_name);
161 (void) printf (" EGID=%lu", (unsigned long) egid);
164 #ifdef HAVE_GETGROUPS
166 * Print out the concurrent group set if the user has requested it.
167 * The group numbers will be printed followed by their names.
169 if (aflg && (ngroups = getgroups (sys_ngroups, groups)) != -1) {
173 * Start off the group message. It will be of the format
175 * groups=###(aaa),###(aaa),###(aaa)
177 * where "###" is a numerical value and "aaa" is the
178 * corresponding name for each respective numerical value.
180 (void) puts (_(" groups="));
181 for (i = 0; i < ngroups; i++) {
183 (void) putchar (',');
185 /* local, no need for xgetgrgid */
186 gr = getgrgid (groups[i]);
188 (void) printf ("%lu(%s)",
189 (unsigned long) groups[i],
192 (void) printf ("%lu",
193 (unsigned long) groups[i]);
201 * Finish off the line.
203 (void) putchar ('\n');