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