id.c revision 38468
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[] =
4538468Sobrien	"$Id: id.c,v 1.6 1998/02/18 17:35:16 steve 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));
5938468Sobrienvoid	pline __P((struct passwd *));
601590Srgrimesvoid	pretty __P((struct passwd *));
611590Srgrimesvoid	group __P((struct passwd *, int));
621590Srgrimesvoid	usage __P((void));
631590Srgrimesvoid	user __P((struct passwd *));
641590Srgrimesstruct passwd *
651590Srgrimes	who __P((char *));
661590Srgrimes
671590Srgrimesint
681590Srgrimesmain(argc, argv)
691590Srgrimes	int argc;
701590Srgrimes	char *argv[];
711590Srgrimes{
721590Srgrimes	struct group *gr;
731590Srgrimes	struct passwd *pw;
7438468Sobrien	int Gflag, Pflag, ch, gflag, id, nflag, pflag, rflag, uflag;
751590Srgrimes
7638468Sobrien	Gflag = Pflag = gflag = nflag = pflag = rflag = uflag = 0;
7738468Sobrien	while ((ch = getopt(argc, argv, "PGgnpru")) != -1)
781590Srgrimes		switch(ch) {
791590Srgrimes		case 'G':
801590Srgrimes			Gflag = 1;
811590Srgrimes			break;
8238468Sobrien		case 'P':
8338468Sobrien			Pflag = 1;
8438468Sobrien			break;
851590Srgrimes		case 'g':
861590Srgrimes			gflag = 1;
871590Srgrimes			break;
881590Srgrimes		case 'n':
891590Srgrimes			nflag = 1;
901590Srgrimes			break;
911590Srgrimes		case 'p':
921590Srgrimes			pflag = 1;
931590Srgrimes			break;
941590Srgrimes		case 'r':
951590Srgrimes			rflag = 1;
961590Srgrimes			break;
971590Srgrimes		case 'u':
981590Srgrimes			uflag = 1;
991590Srgrimes			break;
1001590Srgrimes		case '?':
1011590Srgrimes		default:
1021590Srgrimes			usage();
1031590Srgrimes		}
1041590Srgrimes	argc -= optind;
1051590Srgrimes	argv += optind;
1061590Srgrimes
10738468Sobrien	switch(Gflag + Pflag + gflag + pflag + uflag) {
1081590Srgrimes	case 1:
1091590Srgrimes		break;
1101590Srgrimes	case 0:
1111590Srgrimes		if (!nflag && !rflag)
1121590Srgrimes			break;
1131590Srgrimes		/* FALLTHROUGH */
1141590Srgrimes	default:
1151590Srgrimes		usage();
1161590Srgrimes	}
1171590Srgrimes
1181590Srgrimes	pw = *argv ? who(*argv) : NULL;
1191590Srgrimes
1201590Srgrimes	if (gflag) {
1211590Srgrimes		id = pw ? pw->pw_gid : rflag ? getgid() : getegid();
1221590Srgrimes		if (nflag && (gr = getgrgid(id)))
1231590Srgrimes			(void)printf("%s\n", gr->gr_name);
1241590Srgrimes		else
1251590Srgrimes			(void)printf("%u\n", id);
1261590Srgrimes		exit(0);
1271590Srgrimes	}
1281590Srgrimes
1291590Srgrimes	if (uflag) {
1301590Srgrimes		id = pw ? pw->pw_uid : rflag ? getuid() : geteuid();
1311590Srgrimes		if (nflag && (pw = getpwuid(id)))
1321590Srgrimes			(void)printf("%s\n", pw->pw_name);
1331590Srgrimes		else
1341590Srgrimes			(void)printf("%u\n", id);
1351590Srgrimes		exit(0);
1361590Srgrimes	}
1371590Srgrimes
1381590Srgrimes	if (Gflag) {
1391590Srgrimes		group(pw, nflag);
1401590Srgrimes		exit(0);
1411590Srgrimes	}
1421590Srgrimes
14338468Sobrien	if (Pflag) {
14438468Sobrien		pline(pw);
14538468Sobrien		exit(0);
14638468Sobrien	}
14738468Sobrien
1481590Srgrimes	if (pflag) {
1491590Srgrimes		pretty(pw);
1501590Srgrimes		exit(0);
1511590Srgrimes	}
1521590Srgrimes
1531590Srgrimes	if (pw)
1541590Srgrimes		user(pw);
1551590Srgrimes	else
1561590Srgrimes		current();
1571590Srgrimes	exit(0);
1581590Srgrimes}
1591590Srgrimes
1601590Srgrimesvoid
1611590Srgrimespretty(pw)
1621590Srgrimes	struct passwd *pw;
1631590Srgrimes{
1641590Srgrimes	struct group *gr;
1651590Srgrimes	u_int eid, rid;
1661590Srgrimes	char *login;
1671590Srgrimes
1681590Srgrimes	if (pw) {
1691590Srgrimes		(void)printf("uid\t%s\n", pw->pw_name);
1701590Srgrimes		(void)printf("groups\t");
1711590Srgrimes		group(pw, 1);
1721590Srgrimes	} else {
1731590Srgrimes		if ((login = getlogin()) == NULL)
17427418Scharnier			err(1, "getlogin");
1751590Srgrimes
1761590Srgrimes		pw = getpwuid(rid = getuid());
1771590Srgrimes		if (pw == NULL || strcmp(login, pw->pw_name))
1781590Srgrimes			(void)printf("login\t%s\n", login);
1791590Srgrimes		if (pw)
1801590Srgrimes			(void)printf("uid\t%s\n", pw->pw_name);
1811590Srgrimes		else
1821590Srgrimes			(void)printf("uid\t%u\n", rid);
1838874Srgrimes
1841590Srgrimes		if ((eid = geteuid()) != rid)
18527418Scharnier			if ((pw = getpwuid(eid)))
18633576Ssteve				(void)printf("euid\t%s\n", pw->pw_name);
1871590Srgrimes			else
18833576Ssteve				(void)printf("euid\t%u\n", eid);
1891590Srgrimes		if ((rid = getgid()) != (eid = getegid()))
19027418Scharnier			if ((gr = getgrgid(rid)))
1911590Srgrimes				(void)printf("rgid\t%s\n", gr->gr_name);
1921590Srgrimes			else
1931590Srgrimes				(void)printf("rgid\t%u\n", rid);
1941590Srgrimes		(void)printf("groups\t");
1951590Srgrimes		group(NULL, 1);
1961590Srgrimes	}
1971590Srgrimes}
1981590Srgrimes
1991590Srgrimesvoid
2001590Srgrimescurrent()
2011590Srgrimes{
2021590Srgrimes	struct group *gr;
2031590Srgrimes	struct passwd *pw;
2041590Srgrimes	int cnt, id, eid, lastid, ngroups;
2051590Srgrimes	gid_t groups[NGROUPS];
2061590Srgrimes	char *fmt;
2071590Srgrimes
2081590Srgrimes	id = getuid();
2091590Srgrimes	(void)printf("uid=%u", id);
21027418Scharnier	if ((pw = getpwuid(id)))
2111590Srgrimes		(void)printf("(%s)", pw->pw_name);
2121590Srgrimes	if ((eid = geteuid()) != id) {
2131590Srgrimes		(void)printf(" euid=%u", eid);
21427418Scharnier		if ((pw = getpwuid(eid)))
2151590Srgrimes			(void)printf("(%s)", pw->pw_name);
2161590Srgrimes	}
2171590Srgrimes	id = getgid();
2181590Srgrimes	(void)printf(" gid=%u", id);
21927418Scharnier	if ((gr = getgrgid(id)))
2201590Srgrimes		(void)printf("(%s)", gr->gr_name);
2211590Srgrimes	if ((eid = getegid()) != id) {
2221590Srgrimes		(void)printf(" egid=%u", eid);
22327418Scharnier		if ((gr = getgrgid(eid)))
2241590Srgrimes			(void)printf("(%s)", gr->gr_name);
2251590Srgrimes	}
22627418Scharnier	if ((ngroups = getgroups(NGROUPS, groups))) {
2271590Srgrimes		for (fmt = " groups=%u", lastid = -1, cnt = 0; cnt < ngroups;
2281590Srgrimes		    fmt = ", %u", lastid = id) {
2291590Srgrimes			id = groups[cnt++];
2301590Srgrimes			if (lastid == id)
2311590Srgrimes				continue;
2321590Srgrimes			(void)printf(fmt, id);
23327418Scharnier			if ((gr = getgrgid(id)))
2341590Srgrimes				(void)printf("(%s)", gr->gr_name);
2351590Srgrimes		}
2361590Srgrimes	}
2371590Srgrimes	(void)printf("\n");
2381590Srgrimes}
2391590Srgrimes
2401590Srgrimesvoid
2411590Srgrimesuser(pw)
2421590Srgrimes	register struct passwd *pw;
2431590Srgrimes{
2441590Srgrimes	register struct group *gr;
24527418Scharnier	register char *fmt;
24610359Sdg	int cnt, gid, lastgid, ngroups, groups[NGROUPS + 1];
2471590Srgrimes
24810359Sdg	(void)printf("uid=%u(%s)", pw->pw_uid, pw->pw_name);
24910359Sdg	gid = pw->pw_gid;
25010359Sdg	(void)printf(" gid=%u", gid);
25127418Scharnier	if ((gr = getgrgid(gid)))
2521590Srgrimes		(void)printf("(%s)", gr->gr_name);
2531590Srgrimes	ngroups = NGROUPS + 1;
25410359Sdg	(void) getgrouplist(pw->pw_name, gid, groups, &ngroups);
2551590Srgrimes	fmt = " groups=%u";
25610359Sdg	for (lastgid = -1, cnt = 0; cnt < ngroups; ++cnt) {
25710359Sdg		if (lastgid == (gid = groups[cnt]))
2581590Srgrimes			continue;
25910359Sdg		(void)printf(fmt, gid);
2601590Srgrimes		fmt = " %u";
26127418Scharnier		if ((gr = getgrgid(gid)))
2621590Srgrimes			(void)printf("(%s)", gr->gr_name);
26310359Sdg		lastgid = gid;
2641590Srgrimes	}
2651590Srgrimes	(void)printf("\n");
2661590Srgrimes}
2671590Srgrimes
2681590Srgrimesvoid
2691590Srgrimesgroup(pw, nflag)
2701590Srgrimes	struct passwd *pw;
2711590Srgrimes	int nflag;
2721590Srgrimes{
2731590Srgrimes	struct group *gr;
2741590Srgrimes	int cnt, id, lastid, ngroups;
2751590Srgrimes	gid_t groups[NGROUPS + 1];
2761590Srgrimes	char *fmt;
2771590Srgrimes
2781590Srgrimes	if (pw) {
2791590Srgrimes		ngroups = NGROUPS + 1;
2801590Srgrimes		(void) getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups);
2811590Srgrimes	} else {
2821590Srgrimes		groups[0] = getgid();
2831590Srgrimes		ngroups = getgroups(NGROUPS, groups + 1) + 1;
2841590Srgrimes	}
2851590Srgrimes	fmt = nflag ? "%s" : "%u";
2861590Srgrimes	for (lastid = -1, cnt = 0; cnt < ngroups; ++cnt) {
2871590Srgrimes		if (lastid == (id = groups[cnt]))
2881590Srgrimes			continue;
2891590Srgrimes		if (nflag) {
29027418Scharnier			if ((gr = getgrgid(id)))
2911590Srgrimes				(void)printf(fmt, gr->gr_name);
2921590Srgrimes			else
2931590Srgrimes				(void)printf(*fmt == ' ' ? " %u" : "%u",
2941590Srgrimes				    id);
2951590Srgrimes			fmt = " %s";
2961590Srgrimes		} else {
2971590Srgrimes			(void)printf(fmt, id);
2981590Srgrimes			fmt = " %u";
2991590Srgrimes		}
3001590Srgrimes		lastid = id;
3011590Srgrimes	}
3021590Srgrimes	(void)printf("\n");
3031590Srgrimes}
3041590Srgrimes
3051590Srgrimesstruct passwd *
3061590Srgrimeswho(u)
3071590Srgrimes	char *u;
3081590Srgrimes{
3091590Srgrimes	struct passwd *pw;
3101590Srgrimes	long id;
3111590Srgrimes	char *ep;
3121590Srgrimes
3131590Srgrimes	/*
3141590Srgrimes	 * Translate user argument into a pw pointer.  First, try to
3151590Srgrimes	 * get it as specified.  If that fails, try it as a number.
3161590Srgrimes	 */
31727418Scharnier	if ((pw = getpwnam(u)))
3181590Srgrimes		return(pw);
3191590Srgrimes	id = strtol(u, &ep, 10);
3201590Srgrimes	if (*u && !*ep && (pw = getpwuid(id)))
3211590Srgrimes		return(pw);
32227418Scharnier	errx(1, "%s: no such user", u);
3231590Srgrimes	/* NOTREACHED */
3241590Srgrimes}
3251590Srgrimes
3261590Srgrimesvoid
32738468Sobrienpline(pw)
32838468Sobrien	struct passwd *pw;
32938468Sobrien{
33038468Sobrien	struct group *gr;
33138468Sobrien	u_int eid, rid;
33238468Sobrien	char *login;
33338468Sobrien
33438468Sobrien	if (!pw) {
33538468Sobrien		if ((pw = getpwuid(rid = getuid())) == NULL)
33638468Sobrien			err(1, "getpwuid");
33738468Sobrien	}
33838468Sobrien
33938468Sobrien	(void)printf("%s:%s:%d:%d:%s:%d:%d:%s:%s:%s\n", pw->pw_name,
34038468Sobrien			pw->pw_passwd, pw->pw_uid, pw->pw_gid, pw->pw_class,
34138468Sobrien			pw->pw_change, pw->pw_expire, pw->pw_gecos,
34238468Sobrien			pw->pw_dir, pw->pw_shell);
34338468Sobrien}
34438468Sobrien
34538468Sobrien
34638468Sobrienvoid
3471590Srgrimesusage()
3481590Srgrimes{
34927418Scharnier	(void)fprintf(stderr, "%s\n%s\n%s\n%s\n",
35027418Scharnier		"usage: id [user]",
35127418Scharnier		"       id -G [-n] [user]",
35227418Scharnier		"       id -g [-nr] [user]",
35327418Scharnier		"       id -u [-nr] [user]");
3541590Srgrimes	exit(1);
3551590Srgrimes}
356