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