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