id.c revision 24360
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
35static 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
41static 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
54void	current __P((void));
55void	err __P((const char *, ...));
56void	pretty __P((struct passwd *));
57void	group __P((struct passwd *, int));
58void	usage __P((void));
59void	user __P((struct passwd *));
60struct passwd *
61	who __P((char *));
62
63int
64main(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")) != -1)
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
148void
149pretty(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
187void
188current()
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
228void
229user(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
256void
257group(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
293struct passwd *
294who(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
320void
321#if __STDC__
322err(const char *fmt, ...)
323#else
324err(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
343void
344usage()
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