id.c revision 1.4 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[] = "from: @(#)id.c 5.1 (Berkeley) 6/29/91";*/
42 static char rcsid[] = "$Id: id.c,v 1.4 1994/04/01 01:19:18 jtc Exp $";
43 #endif /* not lint */
44
45 #include <sys/param.h>
46 #include <pwd.h>
47 #include <grp.h>
48 #include <errno.h>
49 #include <unistd.h>
50 #include <stdlib.h>
51 #include <stdio.h>
52 #include <string.h>
53
54 typedef struct passwd PW;
55 typedef struct group GR;
56
57 void current __P((void));
58 void err __P((const char *, ...));
59 int gcmp __P((const void *, const void *));
60 void sgroup __P((PW *));
61 void ugroup __P((PW *));
62 void usage __P((void));
63 void user __P((PW *));
64 PW *who __P((char *));
65
66 int Gflag, gflag, nflag, rflag, uflag;
67
68 main(argc, argv)
69 int argc;
70 char *argv[];
71 {
72 GR *gr;
73 PW *pw;
74 int ch, id;
75
76 while ((ch = getopt(argc, argv, "Ggnru")) != EOF)
77 switch(ch) {
78 case 'G':
79 Gflag = 1;
80 break;
81 case 'g':
82 gflag = 1;
83 break;
84 case 'n':
85 nflag = 1;
86 break;
87 case 'r':
88 rflag = 1;
89 break;
90 case 'u':
91 uflag = 1;
92 break;
93 case '?':
94 default:
95 usage();
96 }
97 argc -= optind;
98 argv += optind;
99
100 pw = *argv ? who(*argv) : NULL;
101
102 if (Gflag + gflag + uflag > 1)
103 usage();
104
105 if (Gflag) {
106 if (nflag)
107 sgroup(pw);
108 else
109 ugroup(pw);
110 exit(0);
111 }
112
113 if (gflag) {
114 id = pw ? pw->pw_gid : rflag ? getgid() : getegid();
115 if (nflag && (gr = getgrgid(id))) {
116 (void)printf("%s\n", gr->gr_name);
117 exit(0);
118 }
119 (void)printf("%u\n", id);
120 exit(0);
121 }
122
123 if (uflag) {
124 id = pw ? pw->pw_uid : rflag ? getuid() : geteuid();
125 if (nflag && (pw = getpwuid(id))) {
126 (void)printf("%s\n", pw->pw_name);
127 exit(0);
128 }
129 (void)printf("%u\n", id);
130 exit(0);
131 }
132
133 if (pw)
134 user(pw);
135 else
136 current();
137 exit(0);
138 }
139
140 void
141 sgroup(pw)
142 PW *pw;
143 {
144 register int id, lastid;
145 char *fmt;
146
147 if (pw) {
148 register GR *gr;
149 register char *name, **p;
150
151 name = pw->pw_name;
152 for (fmt = "%s", lastid = -1; gr = getgrent(); lastid = id) {
153 for (p = gr->gr_mem; p && *p; p++)
154 if (!strcmp(*p, name)) {
155 (void)printf(fmt, gr->gr_name);
156 fmt = " %s";
157 break;
158 }
159 }
160 } else {
161 GR *gr;
162 register int ngroups;
163 gid_t groups[NGROUPS + 1];
164
165 groups[0] = getgid();
166 ngroups = getgroups(NGROUPS, groups + 1) + 1;
167 heapsort(groups, ngroups, sizeof(groups[0]), gcmp);
168 for (fmt = "%s", lastid = -1; --ngroups >= 0;) {
169 if (lastid == (id = groups[ngroups]))
170 continue;
171 if (gr = getgrgid(id))
172 (void)printf(fmt, gr->gr_name);
173 else
174 (void)printf(*fmt == ' ' ? " %u" : "%u", id);
175 fmt = " %s";
176 lastid = id;
177 }
178 }
179 (void)printf("\n");
180 }
181
182 void
183 ugroup(pw)
184 PW *pw;
185 {
186 register int id, lastid;
187 register char *fmt;
188
189 if (pw) {
190 register GR *gr;
191 register char *name, **p;
192
193 name = pw->pw_name;
194 for (fmt = "%u", lastid = -1; gr = getgrent(); lastid = id) {
195 for (p = gr->gr_mem; p && *p; p++)
196 if (!strcmp(*p, name)) {
197 (void)printf(fmt, gr->gr_gid);
198 fmt = " %u";
199 break;
200 }
201 }
202 } else {
203 register int ngroups;
204 gid_t groups[NGROUPS + 1];
205
206 groups[0] = getgid();
207 ngroups = getgroups(NGROUPS, groups + 1) + 1;
208 heapsort(groups, ngroups, sizeof(groups[0]), gcmp);
209 for (fmt = "%u", lastid = -1; --ngroups >= 0;) {
210 if (lastid == (id = groups[ngroups]))
211 continue;
212 (void)printf(fmt, id);
213 fmt = " %u";
214 lastid = id;
215 }
216 }
217 (void)printf("\n");
218 }
219
220 void
221 current()
222 {
223 GR *gr;
224 PW *pw;
225 int id, eid, lastid, ngroups;
226 gid_t groups[NGROUPS];
227 char *fmt;
228
229 id = getuid();
230 (void)printf("uid=%u", id);
231 if (pw = getpwuid(id))
232 (void)printf("(%s)", pw->pw_name);
233 if ((eid = geteuid()) != id) {
234 (void)printf(" euid=%u", eid);
235 if (pw = getpwuid(eid))
236 (void)printf("(%s)", pw->pw_name);
237 }
238 id = getgid();
239 (void)printf(" gid=%u", id);
240 if (gr = getgrgid(id))
241 (void)printf("(%s)", gr->gr_name);
242 if ((eid = getegid()) != id) {
243 (void)printf(" egid=%u", eid);
244 if (gr = getgrgid(eid))
245 (void)printf("(%s)", gr->gr_name);
246 }
247 if (ngroups = getgroups(NGROUPS, groups)) {
248 heapsort(groups, ngroups, sizeof(groups[0]), gcmp);
249 for (fmt = " groups=%u", lastid = -1; --ngroups >= 0;
250 fmt = ", %u", lastid = id) {
251 id = groups[ngroups];
252 if (lastid == id)
253 continue;
254 (void)printf(fmt, id);
255 if (gr = getgrgid(id))
256 (void)printf("(%s)", gr->gr_name);
257 }
258 }
259 (void)printf("\n");
260 }
261
262 void
263 user(pw)
264 register PW *pw;
265 {
266 register GR *gr;
267 register int id, lastid;
268 register char *fmt, **p;
269
270 id = pw->pw_uid;
271 (void)printf("uid=%u(%s)", id, pw->pw_name);
272 (void)printf(" gid=%u", pw->pw_gid);
273 if (gr = getgrgid(pw->pw_gid))
274 (void)printf("(%s)", gr->gr_name);
275 for (fmt = " groups=%u(%s)", lastid = -1; gr = getgrent();
276 lastid = id) {
277 if (pw->pw_gid == gr->gr_gid)
278 continue;
279 for (p = gr->gr_mem; p && *p; p++)
280 if (!strcmp(*p, pw->pw_name)) {
281 (void)printf(fmt, gr->gr_gid, gr->gr_name);
282 fmt = ", %u(%s)";
283 break;
284 }
285 }
286 (void)printf("\n");
287 }
288
289 PW *
290 who(u)
291 char *u;
292 {
293 PW *pw;
294 long id;
295 char *ep;
296
297 /*
298 * Translate user argument into a pw pointer. First, try to
299 * get it as specified. If that fails, try it as a number.
300 */
301 if (pw = getpwnam(u))
302 return(pw);
303 id = strtol(u, &ep, 10);
304 if (*u && !*ep && (pw = getpwuid(id)))
305 return(pw);
306 err("%s: No such user", u);
307 /* NOTREACHED */
308 }
309
310 gcmp(a, b)
311 const void *a, *b;
312 {
313 return(*(int *)b - *(int *)a);
314 }
315
316 #if __STDC__
317 #include <stdarg.h>
318 #else
319 #include <varargs.h>
320 #endif
321
322 void
323 #if __STDC__
324 err(const char *fmt, ...)
325 #else
326 err(fmt, va_alist)
327 char *fmt;
328 va_dcl
329 #endif
330 {
331 va_list ap;
332 #if __STDC__
333 va_start(ap, fmt);
334 #else
335 va_start(ap);
336 #endif
337 (void)fprintf(stderr, "id: ");
338 (void)vfprintf(stderr, fmt, ap);
339 va_end(ap);
340 (void)fprintf(stderr, "\n");
341 exit(1);
342 /* NOTREACHED */
343 }
344
345 void
346 usage()
347 {
348 (void)fprintf(stderr, "usage: id [user]\n");
349 (void)fprintf(stderr, " id -G [-n] [user]\n");
350 (void)fprintf(stderr, " id -g [-nr] [user]\n");
351 (void)fprintf(stderr, " id -u [-nr] [user]\n");
352 exit(1);
353 }
354