id.c revision 8874
11590Srgrimes/*-
21590Srgrimes * Copyright (c) 1991, 1993
31590Srgrimes *	The Regents of the University of California.  All rights reserved.
41590Srgrimes *
51590Srgrimes * Redistribution and use in source and binary forms, with or without
61590Srgrimes * modification, are permitted provided that the following conditions
71590Srgrimes * are met:
81590Srgrimes * 1. Redistributions of source code must retain the above copyright
91590Srgrimes *    notice, this list of conditions and the following disclaimer.
101590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
111590Srgrimes *    notice, this list of conditions and the following disclaimer in the
121590Srgrimes *    documentation and/or other materials provided with the distribution.
131590Srgrimes * 3. All advertising materials mentioning features or use of this software
141590Srgrimes *    must display the following acknowledgement:
151590Srgrimes *	This product includes software developed by the University of
161590Srgrimes *	California, Berkeley and its contributors.
171590Srgrimes * 4. Neither the name of the University nor the names of its contributors
181590Srgrimes *    may be used to endorse or promote products derived from this software
191590Srgrimes *    without specific prior written permission.
201590Srgrimes *
211590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
221590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
231590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
241590Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
251590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
261590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
271590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
281590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
291590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
301590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
311590Srgrimes * SUCH DAMAGE.
321590Srgrimes */
331590Srgrimes
341590Srgrimes#ifndef lint
351590Srgrimesstatic char copyright[] =
361590Srgrimes"@(#) Copyright (c) 1991, 1993\n\
371590Srgrimes	The Regents of the University of California.  All rights reserved.\n";
381590Srgrimes#endif /* not lint */
391590Srgrimes
401590Srgrimes#ifndef lint
411590Srgrimesstatic char sccsid[] = "@(#)id.c	8.2 (Berkeley) 2/16/94";
421590Srgrimes#endif /* not lint */
431590Srgrimes
441590Srgrimes#include <sys/param.h>
451590Srgrimes
461590Srgrimes#include <errno.h>
471590Srgrimes#include <grp.h>
481590Srgrimes#include <pwd.h>
491590Srgrimes#include <stdio.h>
501590Srgrimes#include <stdlib.h>
511590Srgrimes#include <string.h>
521590Srgrimes#include <unistd.h>
531590Srgrimes
541590Srgrimesvoid	current __P((void));
551590Srgrimesvoid	err __P((const char *, ...));
561590Srgrimesvoid	pretty __P((struct passwd *));
571590Srgrimesvoid	group __P((struct passwd *, int));
581590Srgrimesvoid	usage __P((void));
591590Srgrimesvoid	user __P((struct passwd *));
601590Srgrimesstruct passwd *
611590Srgrimes	who __P((char *));
621590Srgrimes
631590Srgrimesint
641590Srgrimesmain(argc, argv)
651590Srgrimes	int argc;
661590Srgrimes	char *argv[];
671590Srgrimes{
681590Srgrimes	struct group *gr;
691590Srgrimes	struct passwd *pw;
701590Srgrimes	int Gflag, ch, gflag, id, nflag, pflag, rflag, uflag;
711590Srgrimes
721590Srgrimes	Gflag = gflag = nflag = pflag = rflag = uflag = 0;
731590Srgrimes	while ((ch = getopt(argc, argv, "Ggnpru")) != EOF)
741590Srgrimes		switch(ch) {
751590Srgrimes		case 'G':
761590Srgrimes			Gflag = 1;
771590Srgrimes			break;
781590Srgrimes		case 'g':
791590Srgrimes			gflag = 1;
801590Srgrimes			break;
811590Srgrimes		case 'n':
821590Srgrimes			nflag = 1;
831590Srgrimes			break;
841590Srgrimes		case 'p':
851590Srgrimes			pflag = 1;
861590Srgrimes			break;
871590Srgrimes		case 'r':
881590Srgrimes			rflag = 1;
891590Srgrimes			break;
901590Srgrimes		case 'u':
911590Srgrimes			uflag = 1;
921590Srgrimes			break;
931590Srgrimes		case '?':
941590Srgrimes		default:
951590Srgrimes			usage();
961590Srgrimes		}
971590Srgrimes	argc -= optind;
981590Srgrimes	argv += optind;
991590Srgrimes
1001590Srgrimes	switch(Gflag + gflag + pflag + uflag) {
1011590Srgrimes	case 1:
1021590Srgrimes		break;
1031590Srgrimes	case 0:
1041590Srgrimes		if (!nflag && !rflag)
1051590Srgrimes			break;
1061590Srgrimes		/* FALLTHROUGH */
1071590Srgrimes	default:
1081590Srgrimes		usage();
1091590Srgrimes	}
1101590Srgrimes
1111590Srgrimes	pw = *argv ? who(*argv) : NULL;
1121590Srgrimes
1131590Srgrimes	if (gflag) {
1141590Srgrimes		id = pw ? pw->pw_gid : rflag ? getgid() : getegid();
1151590Srgrimes		if (nflag && (gr = getgrgid(id)))
1161590Srgrimes			(void)printf("%s\n", gr->gr_name);
1171590Srgrimes		else
1181590Srgrimes			(void)printf("%u\n", id);
1191590Srgrimes		exit(0);
1201590Srgrimes	}
1211590Srgrimes
1221590Srgrimes	if (uflag) {
1231590Srgrimes		id = pw ? pw->pw_uid : rflag ? getuid() : geteuid();
1241590Srgrimes		if (nflag && (pw = getpwuid(id)))
1251590Srgrimes			(void)printf("%s\n", pw->pw_name);
1261590Srgrimes		else
1271590Srgrimes			(void)printf("%u\n", id);
1281590Srgrimes		exit(0);
1291590Srgrimes	}
1301590Srgrimes
1311590Srgrimes	if (Gflag) {
1321590Srgrimes		group(pw, nflag);
1331590Srgrimes		exit(0);
1341590Srgrimes	}
1351590Srgrimes
1361590Srgrimes	if (pflag) {
1371590Srgrimes		pretty(pw);
1381590Srgrimes		exit(0);
1391590Srgrimes	}
1401590Srgrimes
1411590Srgrimes	if (pw)
1421590Srgrimes		user(pw);
1431590Srgrimes	else
1441590Srgrimes		current();
1451590Srgrimes	exit(0);
1461590Srgrimes}
1471590Srgrimes
1481590Srgrimesvoid
1491590Srgrimespretty(pw)
1501590Srgrimes	struct passwd *pw;
1511590Srgrimes{
1521590Srgrimes	struct group *gr;
1531590Srgrimes	u_int eid, rid;
1541590Srgrimes	char *login;
1551590Srgrimes
1561590Srgrimes	if (pw) {
1571590Srgrimes		(void)printf("uid\t%s\n", pw->pw_name);
1581590Srgrimes		(void)printf("groups\t");
1591590Srgrimes		group(pw, 1);
1601590Srgrimes	} else {
1611590Srgrimes		if ((login = getlogin()) == NULL)
1621590Srgrimes			err("getlogin: %s", strerror(errno));
1631590Srgrimes
1641590Srgrimes		pw = getpwuid(rid = getuid());
1651590Srgrimes		if (pw == NULL || strcmp(login, pw->pw_name))
1661590Srgrimes			(void)printf("login\t%s\n", login);
1671590Srgrimes		if (pw)
1681590Srgrimes			(void)printf("uid\t%s\n", pw->pw_name);
1691590Srgrimes		else
1701590Srgrimes			(void)printf("uid\t%u\n", rid);
1718874Srgrimes
1721590Srgrimes		if ((eid = geteuid()) != rid)
1731590Srgrimes			if (pw = getpwuid(eid))
1741590Srgrimes				(void)printf("euid\t%s", pw->pw_name);
1751590Srgrimes			else
1761590Srgrimes				(void)printf("euid\t%u", eid);
1771590Srgrimes		if ((rid = getgid()) != (eid = getegid()))
1781590Srgrimes			if (gr = getgrgid(rid))
1791590Srgrimes				(void)printf("rgid\t%s\n", gr->gr_name);
1801590Srgrimes			else
1811590Srgrimes				(void)printf("rgid\t%u\n", rid);
1821590Srgrimes		(void)printf("groups\t");
1831590Srgrimes		group(NULL, 1);
1841590Srgrimes	}
1851590Srgrimes}
1861590Srgrimes
1871590Srgrimesvoid
1881590Srgrimescurrent()
1891590Srgrimes{
1901590Srgrimes	struct group *gr;
1911590Srgrimes	struct passwd *pw;
1921590Srgrimes	int cnt, id, eid, lastid, ngroups;
1931590Srgrimes	gid_t groups[NGROUPS];
1941590Srgrimes	char *fmt;
1951590Srgrimes
1961590Srgrimes	id = getuid();
1971590Srgrimes	(void)printf("uid=%u", id);
1981590Srgrimes	if (pw = getpwuid(id))
1991590Srgrimes		(void)printf("(%s)", pw->pw_name);
2001590Srgrimes	if ((eid = geteuid()) != id) {
2011590Srgrimes		(void)printf(" euid=%u", eid);
2021590Srgrimes		if (pw = getpwuid(eid))
2031590Srgrimes			(void)printf("(%s)", pw->pw_name);
2041590Srgrimes	}
2051590Srgrimes	id = getgid();
2061590Srgrimes	(void)printf(" gid=%u", id);
2071590Srgrimes	if (gr = getgrgid(id))
2081590Srgrimes		(void)printf("(%s)", gr->gr_name);
2091590Srgrimes	if ((eid = getegid()) != id) {
2101590Srgrimes		(void)printf(" egid=%u", eid);
2111590Srgrimes		if (gr = getgrgid(eid))
2121590Srgrimes			(void)printf("(%s)", gr->gr_name);
2131590Srgrimes	}
2141590Srgrimes	if (ngroups = getgroups(NGROUPS, groups)) {
2151590Srgrimes		for (fmt = " groups=%u", lastid = -1, cnt = 0; cnt < ngroups;
2161590Srgrimes		    fmt = ", %u", lastid = id) {
2171590Srgrimes			id = groups[cnt++];
2181590Srgrimes			if (lastid == id)
2191590Srgrimes				continue;
2201590Srgrimes			(void)printf(fmt, id);
2211590Srgrimes			if (gr = getgrgid(id))
2221590Srgrimes				(void)printf("(%s)", gr->gr_name);
2231590Srgrimes		}
2241590Srgrimes	}
2251590Srgrimes	(void)printf("\n");
2261590Srgrimes}
2271590Srgrimes
2281590Srgrimesvoid
2291590Srgrimesuser(pw)
2301590Srgrimes	register struct passwd *pw;
2311590Srgrimes{
2321590Srgrimes	register struct group *gr;
2331590Srgrimes	register char *fmt, **p;
2341590Srgrimes	int cnt, id, lastid, ngroups, groups[NGROUPS + 1];
2351590Srgrimes
2361590Srgrimes	id = pw->pw_uid;
2371590Srgrimes	(void)printf("uid=%u(%s)", id, pw->pw_name);
2381590Srgrimes	(void)printf(" gid=%u", pw->pw_gid);
2391590Srgrimes	if (gr = getgrgid(id))
2401590Srgrimes		(void)printf("(%s)", gr->gr_name);
2411590Srgrimes	ngroups = NGROUPS + 1;
2421590Srgrimes	(void) getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups);
2431590Srgrimes	fmt = " groups=%u";
2441590Srgrimes	for (lastid = -1, cnt = 0; cnt < ngroups; ++cnt) {
2451590Srgrimes		if (lastid == (id = groups[cnt]))
2461590Srgrimes			continue;
2471590Srgrimes		(void)printf(fmt, id);
2481590Srgrimes		fmt = " %u";
2491590Srgrimes		if (gr = getgrgid(id))
2501590Srgrimes			(void)printf("(%s)", gr->gr_name);
2511590Srgrimes		lastid = id;
2521590Srgrimes	}
2531590Srgrimes	(void)printf("\n");
2541590Srgrimes}
2551590Srgrimes
2561590Srgrimesvoid
2571590Srgrimesgroup(pw, nflag)
2581590Srgrimes	struct passwd *pw;
2591590Srgrimes	int nflag;
2601590Srgrimes{
2611590Srgrimes	struct group *gr;
2621590Srgrimes	int cnt, id, lastid, ngroups;
2631590Srgrimes	gid_t groups[NGROUPS + 1];
2641590Srgrimes	char *fmt;
2651590Srgrimes
2661590Srgrimes	if (pw) {
2671590Srgrimes		ngroups = NGROUPS + 1;
2681590Srgrimes		(void) getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups);
2691590Srgrimes	} else {
2701590Srgrimes		groups[0] = getgid();
2711590Srgrimes		ngroups = getgroups(NGROUPS, groups + 1) + 1;
2721590Srgrimes	}
2731590Srgrimes	fmt = nflag ? "%s" : "%u";
2741590Srgrimes	for (lastid = -1, cnt = 0; cnt < ngroups; ++cnt) {
2751590Srgrimes		if (lastid == (id = groups[cnt]))
2761590Srgrimes			continue;
2771590Srgrimes		if (nflag) {
2781590Srgrimes			if (gr = getgrgid(id))
2791590Srgrimes				(void)printf(fmt, gr->gr_name);
2801590Srgrimes			else
2811590Srgrimes				(void)printf(*fmt == ' ' ? " %u" : "%u",
2821590Srgrimes				    id);
2831590Srgrimes			fmt = " %s";
2841590Srgrimes		} else {
2851590Srgrimes			(void)printf(fmt, id);
2861590Srgrimes			fmt = " %u";
2871590Srgrimes		}
2881590Srgrimes		lastid = id;
2891590Srgrimes	}
2901590Srgrimes	(void)printf("\n");
2911590Srgrimes}
2921590Srgrimes
2931590Srgrimesstruct passwd *
2941590Srgrimeswho(u)
2951590Srgrimes	char *u;
2961590Srgrimes{
2971590Srgrimes	struct passwd *pw;
2981590Srgrimes	long id;
2991590Srgrimes	char *ep;
3001590Srgrimes
3011590Srgrimes	/*
3021590Srgrimes	 * Translate user argument into a pw pointer.  First, try to
3031590Srgrimes	 * get it as specified.  If that fails, try it as a number.
3041590Srgrimes	 */
3051590Srgrimes	if (pw = getpwnam(u))
3061590Srgrimes		return(pw);
3071590Srgrimes	id = strtol(u, &ep, 10);
3081590Srgrimes	if (*u && !*ep && (pw = getpwuid(id)))
3091590Srgrimes		return(pw);
3101590Srgrimes	err("%s: No such user", u);
3111590Srgrimes	/* NOTREACHED */
3121590Srgrimes}
3131590Srgrimes
3141590Srgrimes#if __STDC__
3151590Srgrimes#include <stdarg.h>
3161590Srgrimes#else
3171590Srgrimes#include <varargs.h>
3181590Srgrimes#endif
3191590Srgrimes
3201590Srgrimesvoid
3211590Srgrimes#if __STDC__
3221590Srgrimeserr(const char *fmt, ...)
3231590Srgrimes#else
3241590Srgrimeserr(fmt, va_alist)
3251590Srgrimes	char *fmt;
3261590Srgrimes        va_dcl
3271590Srgrimes#endif
3281590Srgrimes{
3291590Srgrimes	va_list ap;
3301590Srgrimes#if __STDC__
3311590Srgrimes	va_start(ap, fmt);
3321590Srgrimes#else
3331590Srgrimes	va_start(ap);
3341590Srgrimes#endif
3351590Srgrimes	(void)fprintf(stderr, "id: ");
3361590Srgrimes	(void)vfprintf(stderr, fmt, ap);
3371590Srgrimes	va_end(ap);
3381590Srgrimes	(void)fprintf(stderr, "\n");
3391590Srgrimes	exit(1);
3401590Srgrimes	/* NOTREACHED */
3411590Srgrimes}
3421590Srgrimes
3431590Srgrimesvoid
3441590Srgrimesusage()
3451590Srgrimes{
3461590Srgrimes	(void)fprintf(stderr, "usage: id [user]\n");
3471590Srgrimes	(void)fprintf(stderr, "       id -G [-n] [user]\n");
3481590Srgrimes	(void)fprintf(stderr, "       id -g [-nr] [user]\n");
3491590Srgrimes	(void)fprintf(stderr, "       id -u [-nr] [user]\n");
3501590Srgrimes	exit(1);
3511590Srgrimes}
352