1 /*-
2 * Copyright (c) 1991 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34 #ifndef lint
35 char copyright[] =
36 "@(#) Copyright (c) 1991 The Regents of the University of California.\n\
37 All rights reserved.\n";
38 #endif /* not lint */
39
40 #ifndef lint
41 static char sccsid[] = "@(#)id.c 5.1 (Berkeley) 6/29/91";
42 #endif /* not lint */
43
44 #include <sys/param.h>
45 #include <pwd.h>
46 #include <grp.h>
47 #include <errno.h>
48 #include <unistd.h>
49 #include <stdlib.h>
50 #include <stdio.h>
51 #include <string.h>
52
53 typedef struct passwd PW;
54 typedef struct group GR;
55
56 void current __P((void));
57 void err __P((const char *, ...));
58 int gcmp __P((const void *, const void *));
59 void sgroup __P((PW *));
60 void ugroup __P((PW *));
61 void usage __P((void));
62 void user __P((PW *));
63 PW *who __P((char *));
64
65 int Gflag, gflag, nflag, rflag, uflag;
66
main(argc,argv)67 main(argc, argv)
68 int argc;
69 char *argv[];
70 {
71 GR *gr;
72 PW *pw;
73 int ch, id;
74
75 while ((ch = getopt(argc, argv, "Ggnru")) != EOF)
76 switch(ch) {
77 case 'G':
78 Gflag = 1;
79 break;
80 case 'g':
81 gflag = 1;
82 break;
83 case 'n':
84 nflag = 1;
85 break;
86 case 'r':
87 rflag = 1;
88 break;
89 case 'u':
90 uflag = 1;
91 break;
92 case '?':
93 default:
94 usage();
95 }
96 argc -= optind;
97 argv += optind;
98
99 pw = *argv ? who(*argv) : NULL;
100
101 if (Gflag + gflag + uflag > 1)
102 usage();
103
104 if (Gflag) {
105 if (nflag)
106 sgroup(pw);
107 else
108 ugroup(pw);
109 exit(0);
110 }
111
112 if (gflag) {
113 id = pw ? pw->pw_gid : rflag ? getgid() : getegid();
114 if (nflag && (gr = getgrgid(id))) {
115 (void)printf("%s\n", gr->gr_name);
116 exit(0);
117 }
118 (void)printf("%u\n", id);
119 exit(0);
120 }
121
122 if (uflag) {
123 id = pw ? pw->pw_uid : rflag ? getuid() : geteuid();
124 if (nflag && (pw = getpwuid(id))) {
125 (void)printf("%s\n", pw->pw_name);
126 exit(0);
127 }
128 (void)printf("%u\n", id);
129 exit(0);
130 }
131
132 if (pw)
133 user(pw);
134 else
135 current();
136 exit(0);
137 }
138
139 void
sgroup(pw)140 sgroup(pw)
141 PW *pw;
142 {
143 register int id, lastid;
144 char *fmt;
145
146 if (pw) {
147 register GR *gr;
148 register char *name, **p;
149
150 name = pw->pw_name;
151 for (fmt = "%s", lastid = -1; gr = getgrent(); lastid = id) {
152 for (p = gr->gr_mem; p && *p; p++)
153 if (!strcmp(*p, name)) {
154 (void)printf(fmt, gr->gr_name);
155 fmt = " %s";
156 break;
157 }
158 }
159 } else {
160 GR *gr;
161 register int ngroups;
162 int *groups;
163
164 ngroups = getgroups(0, 0);
165 groups = (int *)malloc((ngroups+1) * sizeof(int));
166 groups[0] = getgid();
167 ngroups = getgroups(ngroups, groups + 1) + 1;
168 heapsort(groups, ngroups, sizeof(groups[0]), gcmp);
169 for (fmt = "%s", lastid = -1; --ngroups >= 0;) {
170 if (lastid == (id = groups[ngroups]))
171 continue;
172 if (gr = getgrgid(id))
173 (void)printf(fmt, gr->gr_name);
174 else
175 (void)printf(*fmt == ' ' ? " %u" : "%u", id);
176 fmt = " %s";
177 lastid = id;
178 }
179 free((void *) groups);
180 }
181 (void)printf("\n");
182 }
183
184 void
ugroup(pw)185 ugroup(pw)
186 PW *pw;
187 {
188 register int id, lastid;
189 register char *fmt;
190
191 if (pw) {
192 register GR *gr;
193 register char *name, **p;
194
195 name = pw->pw_name;
196 for (fmt = "%u", lastid = -1; gr = getgrent(); lastid = id) {
197 for (p = gr->gr_mem; p && *p; p++)
198 if (!strcmp(*p, name)) {
199 (void)printf(fmt, gr->gr_gid);
200 fmt = " %u";
201 break;
202 }
203 }
204 } else {
205 register int ngroups;
206 int *groups;
207
208 ngroups = getgroups(0, 0);
209 groups = (int *)malloc((ngroups+1) * sizeof(int));
210 groups[0] = getgid();
211 ngroups = getgroups(ngroups, groups + 1) + 1;
212 heapsort(groups, ngroups, sizeof(groups[0]), gcmp);
213 for (fmt = "%u", lastid = -1; --ngroups >= 0;) {
214 if (lastid == (id = groups[ngroups]))
215 continue;
216 (void)printf(fmt, id);
217 fmt = " %u";
218 lastid = id;
219 }
220 free((void *) groups);
221 }
222 (void)printf("\n");
223 }
224
225 void
current()226 current()
227 {
228 GR *gr;
229 PW *pw;
230 int id, eid, lastid, ngroups, *groups;
231 char *fmt;
232
233 id = getuid();
234 (void)printf("uid=%u", id);
235 if (pw = getpwuid(id))
236 (void)printf("(%s)", pw->pw_name);
237 if ((eid = geteuid()) != id) {
238 (void)printf(" euid=%u", eid);
239 if (pw = getpwuid(eid))
240 (void)printf("(%s)", pw->pw_name);
241 }
242 id = getgid();
243 (void)printf(" gid=%u", id);
244 if (gr = getgrgid(id))
245 (void)printf("(%s)", gr->gr_name);
246 if ((eid = getegid()) != id) {
247 (void)printf(" egid=%u", eid);
248 if (gr = getgrgid(eid))
249 (void)printf("(%s)", gr->gr_name);
250 }
251
252 ngroups = getgroups(0, 0);
253 groups = (int *)malloc(ngroups * sizeof(int));
254 if (ngroups = getgroups(ngroups, groups)) {
255 heapsort(groups, ngroups, sizeof(groups[0]), gcmp);
256 for (fmt = " groups=%u", lastid = -1; --ngroups >= 0;
257 fmt = ", %u", lastid = id) {
258 id = groups[ngroups];
259 if (lastid == id)
260 continue;
261 (void)printf(fmt, id);
262 if (gr = getgrgid(id))
263 (void)printf("(%s)", gr->gr_name);
264 }
265 }
266 free((void *) groups);
267 (void)printf("\n");
268 }
269
270 void
user(pw)271 user(pw)
272 register PW *pw;
273 {
274 register GR *gr;
275 register int id, lastid;
276 register char *fmt, **p;
277
278 id = pw->pw_uid;
279 (void)printf("uid=%u(%s)", id, pw->pw_name);
280 (void)printf(" gid=%u", pw->pw_gid);
281 if (gr = getgrgid(id))
282 (void)printf("(%s)", gr->gr_name);
283 for (fmt = " groups=%u(%s)", lastid = -1; gr = getgrent();
284 lastid = id) {
285 if (pw->pw_gid == gr->gr_gid)
286 continue;
287 for (p = gr->gr_mem; p && *p; p++)
288 if (!strcmp(*p, pw->pw_name)) {
289 (void)printf(fmt, gr->gr_gid, gr->gr_name);
290 fmt = ", %u(%s)";
291 break;
292 }
293 }
294 (void)printf("\n");
295 }
296
297 PW *
who(u)298 who(u)
299 char *u;
300 {
301 PW *pw;
302 long id;
303 char *ep;
304
305 /*
306 * Translate user argument into a pw pointer. First, try to
307 * get it as specified. If that fails, try it as a number.
308 */
309 if (pw = getpwnam(u))
310 return(pw);
311 id = strtol(u, &ep, 10);
312 if (*u && !*ep && (pw = getpwuid(id)))
313 return(pw);
314 err("%s: No such user", u);
315 /* NOTREACHED */
316 }
317
gcmp(a,b)318 gcmp(a, b)
319 const void *a, *b;
320 {
321 return(*(int *)b - *(int *)a);
322 }
323
324 #if __STDC__
325 #include <stdarg.h>
326 #else
327 #include <varargs.h>
328 #endif
329
330 void
331 #if __STDC__
err(const char * fmt,...)332 err(const char *fmt, ...)
333 #else
334 err(fmt, va_alist)
335 char *fmt;
336 va_dcl
337 #endif
338 {
339 va_list ap;
340 #if __STDC__
341 va_start(ap, fmt);
342 #else
343 va_start(ap);
344 #endif
345 (void)fprintf(stderr, "id: ");
346 (void)vfprintf(stderr, fmt, ap);
347 va_end(ap);
348 (void)fprintf(stderr, "\n");
349 exit(1);
350 /* NOTREACHED */
351 }
352
353 void
usage()354 usage()
355 {
356 (void)fprintf(stderr, "usage: id [user]\n");
357 (void)fprintf(stderr, " id -G [-n] [user]\n");
358 (void)fprintf(stderr, " id -g [-nr] [user]\n");
359 (void)fprintf(stderr, " id -u [-nr] [user]\n");
360 exit(1);
361 }
362