xref: /netbsd-src/usr.bin/id/id.c (revision 5f7096188587a2c7c95fa3c69b78e1ec9c7923d0)
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.2 1993/08/01 18:14:41 mycroft 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 		int 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 		int 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, groups[NGROUPS];
226 	char *fmt;
227 
228 	id = getuid();
229 	(void)printf("uid=%u", id);
230 	if (pw = getpwuid(id))
231 		(void)printf("(%s)", pw->pw_name);
232 	if ((eid = geteuid()) != id) {
233 		(void)printf(" euid=%u", eid);
234 		if (pw = getpwuid(eid))
235 			(void)printf("(%s)", pw->pw_name);
236 	}
237 	id = getgid();
238 	(void)printf(" gid=%u", id);
239 	if (gr = getgrgid(id))
240 		(void)printf("(%s)", gr->gr_name);
241 	if ((eid = getegid()) != id) {
242 		(void)printf(" egid=%u", eid);
243 		if (gr = getgrgid(eid))
244 			(void)printf("(%s)", gr->gr_name);
245 	}
246 	if (ngroups = getgroups(NGROUPS, groups)) {
247 		heapsort(groups, ngroups, sizeof(groups[0]), gcmp);
248 		for (fmt = " groups=%u", lastid = -1; --ngroups >= 0;
249 		    fmt = ", %u", lastid = id) {
250 			id = groups[ngroups];
251 			if (lastid == id)
252 				continue;
253 			(void)printf(fmt, id);
254 			if (gr = getgrgid(id))
255 				(void)printf("(%s)", gr->gr_name);
256 		}
257 	}
258 	(void)printf("\n");
259 }
260 
261 void
262 user(pw)
263 	register PW *pw;
264 {
265 	register GR *gr;
266 	register int id, lastid;
267 	register char *fmt, **p;
268 
269 	id = pw->pw_uid;
270 	(void)printf("uid=%u(%s)", id, pw->pw_name);
271 	(void)printf(" gid=%u", pw->pw_gid);
272 	if (gr = getgrgid(id))
273 		(void)printf("(%s)", gr->gr_name);
274 	for (fmt = " groups=%u(%s)", lastid = -1; gr = getgrent();
275 	    lastid = id) {
276 		if (pw->pw_gid == gr->gr_gid)
277 			continue;
278 		for (p = gr->gr_mem; p && *p; p++)
279 			if (!strcmp(*p, pw->pw_name)) {
280 				(void)printf(fmt, gr->gr_gid, gr->gr_name);
281 				fmt = ", %u(%s)";
282 				break;
283 			}
284 	}
285 	(void)printf("\n");
286 }
287 
288 PW *
289 who(u)
290 	char *u;
291 {
292 	PW *pw;
293 	long id;
294 	char *ep;
295 
296 	/*
297 	 * Translate user argument into a pw pointer.  First, try to
298 	 * get it as specified.  If that fails, try it as a number.
299 	 */
300 	if (pw = getpwnam(u))
301 		return(pw);
302 	id = strtol(u, &ep, 10);
303 	if (*u && !*ep && (pw = getpwuid(id)))
304 		return(pw);
305 	err("%s: No such user", u);
306 	/* NOTREACHED */
307 }
308 
309 gcmp(a, b)
310 	const void *a, *b;
311 {
312 	return(*(int *)b - *(int *)a);
313 }
314 
315 #if __STDC__
316 #include <stdarg.h>
317 #else
318 #include <varargs.h>
319 #endif
320 
321 void
322 #if __STDC__
323 err(const char *fmt, ...)
324 #else
325 err(fmt, va_alist)
326 	char *fmt;
327         va_dcl
328 #endif
329 {
330 	va_list ap;
331 #if __STDC__
332 	va_start(ap, fmt);
333 #else
334 	va_start(ap);
335 #endif
336 	(void)fprintf(stderr, "id: ");
337 	(void)vfprintf(stderr, fmt, ap);
338 	va_end(ap);
339 	(void)fprintf(stderr, "\n");
340 	exit(1);
341 	/* NOTREACHED */
342 }
343 
344 void
345 usage()
346 {
347 	(void)fprintf(stderr, "usage: id [user]\n");
348 	(void)fprintf(stderr, "       id -G [-n] [user]\n");
349 	(void)fprintf(stderr, "       id -g [-nr] [user]\n");
350 	(void)fprintf(stderr, "       id -u [-nr] [user]\n");
351 	exit(1);
352 }
353