id.c revision 33576
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
3527418Scharnierstatic const 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
4127418Scharnier#if 0
421590Srgrimesstatic char sccsid[] = "@(#)id.c	8.2 (Berkeley) 2/16/94";
4327418Scharnier#endif
4427418Scharnierstatic const char rcsid[] =
4533576Ssteve	"$Id: id.c,v 1.5 1997/07/15 09:48:49 charnier Exp $";
461590Srgrimes#endif /* not lint */
471590Srgrimes
481590Srgrimes#include <sys/param.h>
491590Srgrimes
5027418Scharnier#include <err.h>
511590Srgrimes#include <grp.h>
521590Srgrimes#include <pwd.h>
531590Srgrimes#include <stdio.h>
541590Srgrimes#include <stdlib.h>
551590Srgrimes#include <string.h>
561590Srgrimes#include <unistd.h>
571590Srgrimes
581590Srgrimesvoid	current __P((void));
591590Srgrimesvoid	pretty __P((struct passwd *));
601590Srgrimesvoid	group __P((struct passwd *, int));
611590Srgrimesvoid	usage __P((void));
621590Srgrimesvoid	user __P((struct passwd *));
631590Srgrimesstruct passwd *
641590Srgrimes	who __P((char *));
651590Srgrimes
661590Srgrimesint
671590Srgrimesmain(argc, argv)
681590Srgrimes	int argc;
691590Srgrimes	char *argv[];
701590Srgrimes{
711590Srgrimes	struct group *gr;
721590Srgrimes	struct passwd *pw;
731590Srgrimes	int Gflag, ch, gflag, id, nflag, pflag, rflag, uflag;
741590Srgrimes
751590Srgrimes	Gflag = gflag = nflag = pflag = rflag = uflag = 0;
7624360Simp	while ((ch = getopt(argc, argv, "Ggnpru")) != -1)
771590Srgrimes		switch(ch) {
781590Srgrimes		case 'G':
791590Srgrimes			Gflag = 1;
801590Srgrimes			break;
811590Srgrimes		case 'g':
821590Srgrimes			gflag = 1;
831590Srgrimes			break;
841590Srgrimes		case 'n':
851590Srgrimes			nflag = 1;
861590Srgrimes			break;
871590Srgrimes		case 'p':
881590Srgrimes			pflag = 1;
891590Srgrimes			break;
901590Srgrimes		case 'r':
911590Srgrimes			rflag = 1;
921590Srgrimes			break;
931590Srgrimes		case 'u':
941590Srgrimes			uflag = 1;
951590Srgrimes			break;
961590Srgrimes		case '?':
971590Srgrimes		default:
981590Srgrimes			usage();
991590Srgrimes		}
1001590Srgrimes	argc -= optind;
1011590Srgrimes	argv += optind;
1021590Srgrimes
1031590Srgrimes	switch(Gflag + gflag + pflag + uflag) {
1041590Srgrimes	case 1:
1051590Srgrimes		break;
1061590Srgrimes	case 0:
1071590Srgrimes		if (!nflag && !rflag)
1081590Srgrimes			break;
1091590Srgrimes		/* FALLTHROUGH */
1101590Srgrimes	default:
1111590Srgrimes		usage();
1121590Srgrimes	}
1131590Srgrimes
1141590Srgrimes	pw = *argv ? who(*argv) : NULL;
1151590Srgrimes
1161590Srgrimes	if (gflag) {
1171590Srgrimes		id = pw ? pw->pw_gid : rflag ? getgid() : getegid();
1181590Srgrimes		if (nflag && (gr = getgrgid(id)))
1191590Srgrimes			(void)printf("%s\n", gr->gr_name);
1201590Srgrimes		else
1211590Srgrimes			(void)printf("%u\n", id);
1221590Srgrimes		exit(0);
1231590Srgrimes	}
1241590Srgrimes
1251590Srgrimes	if (uflag) {
1261590Srgrimes		id = pw ? pw->pw_uid : rflag ? getuid() : geteuid();
1271590Srgrimes		if (nflag && (pw = getpwuid(id)))
1281590Srgrimes			(void)printf("%s\n", pw->pw_name);
1291590Srgrimes		else
1301590Srgrimes			(void)printf("%u\n", id);
1311590Srgrimes		exit(0);
1321590Srgrimes	}
1331590Srgrimes
1341590Srgrimes	if (Gflag) {
1351590Srgrimes		group(pw, nflag);
1361590Srgrimes		exit(0);
1371590Srgrimes	}
1381590Srgrimes
1391590Srgrimes	if (pflag) {
1401590Srgrimes		pretty(pw);
1411590Srgrimes		exit(0);
1421590Srgrimes	}
1431590Srgrimes
1441590Srgrimes	if (pw)
1451590Srgrimes		user(pw);
1461590Srgrimes	else
1471590Srgrimes		current();
1481590Srgrimes	exit(0);
1491590Srgrimes}
1501590Srgrimes
1511590Srgrimesvoid
1521590Srgrimespretty(pw)
1531590Srgrimes	struct passwd *pw;
1541590Srgrimes{
1551590Srgrimes	struct group *gr;
1561590Srgrimes	u_int eid, rid;
1571590Srgrimes	char *login;
1581590Srgrimes
1591590Srgrimes	if (pw) {
1601590Srgrimes		(void)printf("uid\t%s\n", pw->pw_name);
1611590Srgrimes		(void)printf("groups\t");
1621590Srgrimes		group(pw, 1);
1631590Srgrimes	} else {
1641590Srgrimes		if ((login = getlogin()) == NULL)
16527418Scharnier			err(1, "getlogin");
1661590Srgrimes
1671590Srgrimes		pw = getpwuid(rid = getuid());
1681590Srgrimes		if (pw == NULL || strcmp(login, pw->pw_name))
1691590Srgrimes			(void)printf("login\t%s\n", login);
1701590Srgrimes		if (pw)
1711590Srgrimes			(void)printf("uid\t%s\n", pw->pw_name);
1721590Srgrimes		else
1731590Srgrimes			(void)printf("uid\t%u\n", rid);
1748874Srgrimes
1751590Srgrimes		if ((eid = geteuid()) != rid)
17627418Scharnier			if ((pw = getpwuid(eid)))
17733576Ssteve				(void)printf("euid\t%s\n", pw->pw_name);
1781590Srgrimes			else
17933576Ssteve				(void)printf("euid\t%u\n", eid);
1801590Srgrimes		if ((rid = getgid()) != (eid = getegid()))
18127418Scharnier			if ((gr = getgrgid(rid)))
1821590Srgrimes				(void)printf("rgid\t%s\n", gr->gr_name);
1831590Srgrimes			else
1841590Srgrimes				(void)printf("rgid\t%u\n", rid);
1851590Srgrimes		(void)printf("groups\t");
1861590Srgrimes		group(NULL, 1);
1871590Srgrimes	}
1881590Srgrimes}
1891590Srgrimes
1901590Srgrimesvoid
1911590Srgrimescurrent()
1921590Srgrimes{
1931590Srgrimes	struct group *gr;
1941590Srgrimes	struct passwd *pw;
1951590Srgrimes	int cnt, id, eid, lastid, ngroups;
1961590Srgrimes	gid_t groups[NGROUPS];
1971590Srgrimes	char *fmt;
1981590Srgrimes
1991590Srgrimes	id = getuid();
2001590Srgrimes	(void)printf("uid=%u", id);
20127418Scharnier	if ((pw = getpwuid(id)))
2021590Srgrimes		(void)printf("(%s)", pw->pw_name);
2031590Srgrimes	if ((eid = geteuid()) != id) {
2041590Srgrimes		(void)printf(" euid=%u", eid);
20527418Scharnier		if ((pw = getpwuid(eid)))
2061590Srgrimes			(void)printf("(%s)", pw->pw_name);
2071590Srgrimes	}
2081590Srgrimes	id = getgid();
2091590Srgrimes	(void)printf(" gid=%u", id);
21027418Scharnier	if ((gr = getgrgid(id)))
2111590Srgrimes		(void)printf("(%s)", gr->gr_name);
2121590Srgrimes	if ((eid = getegid()) != id) {
2131590Srgrimes		(void)printf(" egid=%u", eid);
21427418Scharnier		if ((gr = getgrgid(eid)))
2151590Srgrimes			(void)printf("(%s)", gr->gr_name);
2161590Srgrimes	}
21727418Scharnier	if ((ngroups = getgroups(NGROUPS, groups))) {
2181590Srgrimes		for (fmt = " groups=%u", lastid = -1, cnt = 0; cnt < ngroups;
2191590Srgrimes		    fmt = ", %u", lastid = id) {
2201590Srgrimes			id = groups[cnt++];
2211590Srgrimes			if (lastid == id)
2221590Srgrimes				continue;
2231590Srgrimes			(void)printf(fmt, id);
22427418Scharnier			if ((gr = getgrgid(id)))
2251590Srgrimes				(void)printf("(%s)", gr->gr_name);
2261590Srgrimes		}
2271590Srgrimes	}
2281590Srgrimes	(void)printf("\n");
2291590Srgrimes}
2301590Srgrimes
2311590Srgrimesvoid
2321590Srgrimesuser(pw)
2331590Srgrimes	register struct passwd *pw;
2341590Srgrimes{
2351590Srgrimes	register struct group *gr;
23627418Scharnier	register char *fmt;
23710359Sdg	int cnt, gid, lastgid, ngroups, groups[NGROUPS + 1];
2381590Srgrimes
23910359Sdg	(void)printf("uid=%u(%s)", pw->pw_uid, pw->pw_name);
24010359Sdg	gid = pw->pw_gid;
24110359Sdg	(void)printf(" gid=%u", gid);
24227418Scharnier	if ((gr = getgrgid(gid)))
2431590Srgrimes		(void)printf("(%s)", gr->gr_name);
2441590Srgrimes	ngroups = NGROUPS + 1;
24510359Sdg	(void) getgrouplist(pw->pw_name, gid, groups, &ngroups);
2461590Srgrimes	fmt = " groups=%u";
24710359Sdg	for (lastgid = -1, cnt = 0; cnt < ngroups; ++cnt) {
24810359Sdg		if (lastgid == (gid = groups[cnt]))
2491590Srgrimes			continue;
25010359Sdg		(void)printf(fmt, gid);
2511590Srgrimes		fmt = " %u";
25227418Scharnier		if ((gr = getgrgid(gid)))
2531590Srgrimes			(void)printf("(%s)", gr->gr_name);
25410359Sdg		lastgid = gid;
2551590Srgrimes	}
2561590Srgrimes	(void)printf("\n");
2571590Srgrimes}
2581590Srgrimes
2591590Srgrimesvoid
2601590Srgrimesgroup(pw, nflag)
2611590Srgrimes	struct passwd *pw;
2621590Srgrimes	int nflag;
2631590Srgrimes{
2641590Srgrimes	struct group *gr;
2651590Srgrimes	int cnt, id, lastid, ngroups;
2661590Srgrimes	gid_t groups[NGROUPS + 1];
2671590Srgrimes	char *fmt;
2681590Srgrimes
2691590Srgrimes	if (pw) {
2701590Srgrimes		ngroups = NGROUPS + 1;
2711590Srgrimes		(void) getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups);
2721590Srgrimes	} else {
2731590Srgrimes		groups[0] = getgid();
2741590Srgrimes		ngroups = getgroups(NGROUPS, groups + 1) + 1;
2751590Srgrimes	}
2761590Srgrimes	fmt = nflag ? "%s" : "%u";
2771590Srgrimes	for (lastid = -1, cnt = 0; cnt < ngroups; ++cnt) {
2781590Srgrimes		if (lastid == (id = groups[cnt]))
2791590Srgrimes			continue;
2801590Srgrimes		if (nflag) {
28127418Scharnier			if ((gr = getgrgid(id)))
2821590Srgrimes				(void)printf(fmt, gr->gr_name);
2831590Srgrimes			else
2841590Srgrimes				(void)printf(*fmt == ' ' ? " %u" : "%u",
2851590Srgrimes				    id);
2861590Srgrimes			fmt = " %s";
2871590Srgrimes		} else {
2881590Srgrimes			(void)printf(fmt, id);
2891590Srgrimes			fmt = " %u";
2901590Srgrimes		}
2911590Srgrimes		lastid = id;
2921590Srgrimes	}
2931590Srgrimes	(void)printf("\n");
2941590Srgrimes}
2951590Srgrimes
2961590Srgrimesstruct passwd *
2971590Srgrimeswho(u)
2981590Srgrimes	char *u;
2991590Srgrimes{
3001590Srgrimes	struct passwd *pw;
3011590Srgrimes	long id;
3021590Srgrimes	char *ep;
3031590Srgrimes
3041590Srgrimes	/*
3051590Srgrimes	 * Translate user argument into a pw pointer.  First, try to
3061590Srgrimes	 * get it as specified.  If that fails, try it as a number.
3071590Srgrimes	 */
30827418Scharnier	if ((pw = getpwnam(u)))
3091590Srgrimes		return(pw);
3101590Srgrimes	id = strtol(u, &ep, 10);
3111590Srgrimes	if (*u && !*ep && (pw = getpwuid(id)))
3121590Srgrimes		return(pw);
31327418Scharnier	errx(1, "%s: no such user", u);
3141590Srgrimes	/* NOTREACHED */
3151590Srgrimes}
3161590Srgrimes
3171590Srgrimesvoid
3181590Srgrimesusage()
3191590Srgrimes{
32027418Scharnier	(void)fprintf(stderr, "%s\n%s\n%s\n%s\n",
32127418Scharnier		"usage: id [user]",
32227418Scharnier		"       id -G [-n] [user]",
32327418Scharnier		"       id -g [-nr] [user]",
32427418Scharnier		"       id -u [-nr] [user]");
3251590Srgrimes	exit(1);
3261590Srgrimes}
327