xref: /386bsd/usr/src/usr.bin/id/id.c (revision a2142627)
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