xref: /titanic_54/usr/src/cmd/id/id.c (revision a604d238c5e1858f018e4e7f16c760afb009e655)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*a604d238Scf46844  * Common Development and Distribution License (the "License").
6*a604d238Scf46844  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22*a604d238Scf46844  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
277c478bd9Sstevel@tonic-gate 
287c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
297c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
307c478bd9Sstevel@tonic-gate 
317c478bd9Sstevel@tonic-gate 
327c478bd9Sstevel@tonic-gate #include <locale.h>
337c478bd9Sstevel@tonic-gate #include <stdio.h>
347c478bd9Sstevel@tonic-gate #include <pwd.h>
357c478bd9Sstevel@tonic-gate #include <grp.h>
367c478bd9Sstevel@tonic-gate #include <sys/param.h>
377c478bd9Sstevel@tonic-gate #include <unistd.h>
387c478bd9Sstevel@tonic-gate #include <string.h>
397c478bd9Sstevel@tonic-gate #include <project.h>
407c478bd9Sstevel@tonic-gate #include <stdlib.h>
417c478bd9Sstevel@tonic-gate 
427c478bd9Sstevel@tonic-gate #define	PWNULL  ((struct passwd *)0)
437c478bd9Sstevel@tonic-gate #define	GRNULL  ((struct group *)0)
447c478bd9Sstevel@tonic-gate 
457c478bd9Sstevel@tonic-gate typedef enum TYPE {
467c478bd9Sstevel@tonic-gate 	UID, EUID, GID, EGID, SGID
477c478bd9Sstevel@tonic-gate }	TYPE;
487c478bd9Sstevel@tonic-gate 
497c478bd9Sstevel@tonic-gate typedef enum PRINT {
507c478bd9Sstevel@tonic-gate 	CURR,		/* Print uid/gid only */
517c478bd9Sstevel@tonic-gate 	ALLGROUPS,	/* Print all groups */
527c478bd9Sstevel@tonic-gate 	GROUP,		/* Print only group */
537c478bd9Sstevel@tonic-gate 	USER		/* Print only uid */
547c478bd9Sstevel@tonic-gate }	PRINT;
557c478bd9Sstevel@tonic-gate static PRINT mode = CURR;
567c478bd9Sstevel@tonic-gate 
577c478bd9Sstevel@tonic-gate static int usage(void);
587c478bd9Sstevel@tonic-gate static void puid(uid_t);
597c478bd9Sstevel@tonic-gate static void pgid(gid_t);
607c478bd9Sstevel@tonic-gate static void prid(TYPE, uid_t);
617c478bd9Sstevel@tonic-gate static int getusergroups(int, gid_t *, char *, gid_t);
627c478bd9Sstevel@tonic-gate 
637c478bd9Sstevel@tonic-gate static int nflag = 0;		/* Output names, not numbers */
647c478bd9Sstevel@tonic-gate static int rflag = 0;		/* Output real, not effective IDs */
657c478bd9Sstevel@tonic-gate static char stdbuf[BUFSIZ];
667c478bd9Sstevel@tonic-gate 
677c478bd9Sstevel@tonic-gate int
687c478bd9Sstevel@tonic-gate main(int argc, char *argv[])
697c478bd9Sstevel@tonic-gate {
707c478bd9Sstevel@tonic-gate 	gid_t *idp;
717c478bd9Sstevel@tonic-gate 	uid_t uid, euid;
727c478bd9Sstevel@tonic-gate 	gid_t gid, egid, prgid;
737c478bd9Sstevel@tonic-gate 	int c, aflag = 0, project_flag = 0;
747c478bd9Sstevel@tonic-gate 	struct passwd *pwp;
757c478bd9Sstevel@tonic-gate 	int i, j;
767c478bd9Sstevel@tonic-gate 	gid_t groupids[NGROUPS_UMAX];
777c478bd9Sstevel@tonic-gate 	struct group *gr;
787c478bd9Sstevel@tonic-gate 	char *user = NULL;
797c478bd9Sstevel@tonic-gate 
807c478bd9Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");
817c478bd9Sstevel@tonic-gate 
827c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)	/* Should be defined by cc -D */
837c478bd9Sstevel@tonic-gate #define	TEXT_DOMAIN "SYS_TEST"
847c478bd9Sstevel@tonic-gate #endif
857c478bd9Sstevel@tonic-gate 	(void) textdomain(TEXT_DOMAIN);
86*a604d238Scf46844 	while ((c = getopt(argc, argv, "Ggunarp")) != EOF) {
877c478bd9Sstevel@tonic-gate 		switch (c) {
887c478bd9Sstevel@tonic-gate 			case 'G':
897c478bd9Sstevel@tonic-gate 				if (mode != CURR)
907c478bd9Sstevel@tonic-gate 					return (usage());
917c478bd9Sstevel@tonic-gate 				mode = ALLGROUPS;
927c478bd9Sstevel@tonic-gate 				break;
937c478bd9Sstevel@tonic-gate 
947c478bd9Sstevel@tonic-gate 			case 'g':
957c478bd9Sstevel@tonic-gate 				if (mode != CURR)
967c478bd9Sstevel@tonic-gate 					return (usage());
977c478bd9Sstevel@tonic-gate 				mode = GROUP;
987c478bd9Sstevel@tonic-gate 				break;
997c478bd9Sstevel@tonic-gate 
1007c478bd9Sstevel@tonic-gate 			case 'a':
1017c478bd9Sstevel@tonic-gate 				aflag++;
1027c478bd9Sstevel@tonic-gate 				break;
1037c478bd9Sstevel@tonic-gate 
1047c478bd9Sstevel@tonic-gate 			case 'n':
1057c478bd9Sstevel@tonic-gate 				nflag++;
1067c478bd9Sstevel@tonic-gate 				break;
1077c478bd9Sstevel@tonic-gate 
1087c478bd9Sstevel@tonic-gate 			case 'r':
1097c478bd9Sstevel@tonic-gate 				rflag++;
1107c478bd9Sstevel@tonic-gate 				break;
1117c478bd9Sstevel@tonic-gate 
1127c478bd9Sstevel@tonic-gate 			case 'u':
1137c478bd9Sstevel@tonic-gate 				if (mode != CURR)
1147c478bd9Sstevel@tonic-gate 					return (usage());
1157c478bd9Sstevel@tonic-gate 				mode = USER;
1167c478bd9Sstevel@tonic-gate 				break;
1177c478bd9Sstevel@tonic-gate 
1187c478bd9Sstevel@tonic-gate 			case 'p':
1197c478bd9Sstevel@tonic-gate 				if (mode != CURR)
1207c478bd9Sstevel@tonic-gate 					return (usage());
1217c478bd9Sstevel@tonic-gate 				project_flag++;
1227c478bd9Sstevel@tonic-gate 				break;
1237c478bd9Sstevel@tonic-gate 
1247c478bd9Sstevel@tonic-gate 			case '?':
1257c478bd9Sstevel@tonic-gate 				return (usage());
1267c478bd9Sstevel@tonic-gate 		}
1277c478bd9Sstevel@tonic-gate 	}
1287c478bd9Sstevel@tonic-gate 	setbuf(stdout, stdbuf);
1297c478bd9Sstevel@tonic-gate 	argc -= optind-1;
1307c478bd9Sstevel@tonic-gate 	argv += optind-1;
1317c478bd9Sstevel@tonic-gate 
1327c478bd9Sstevel@tonic-gate 	/* -n and -r must be combined with one of -[Ggu] */
1337c478bd9Sstevel@tonic-gate 	/* -r cannot be combined with -G */
134*a604d238Scf46844 	/* -a and -p cannot be combined with -[Ggu] */
1357c478bd9Sstevel@tonic-gate 
1367c478bd9Sstevel@tonic-gate 	if ((mode == CURR && (nflag || rflag)) ||
1377c478bd9Sstevel@tonic-gate 		(mode == ALLGROUPS && rflag) ||
138*a604d238Scf46844 		(argc != 1 && argc != 2) ||
139*a604d238Scf46844 		(mode != CURR && (project_flag || aflag)))
1407c478bd9Sstevel@tonic-gate 		return (usage());
1417c478bd9Sstevel@tonic-gate 	if (argc == 2) {
1427c478bd9Sstevel@tonic-gate 		if ((pwp = getpwnam(argv[1])) == PWNULL) {
1437c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr,
1447c478bd9Sstevel@tonic-gate 				gettext("id: invalid user name: \"%s\"\n"),
1457c478bd9Sstevel@tonic-gate 					argv[1]);
1467c478bd9Sstevel@tonic-gate 			return (1);
1477c478bd9Sstevel@tonic-gate 		}
1487c478bd9Sstevel@tonic-gate 		user = argv[1];
1497c478bd9Sstevel@tonic-gate 		uid = euid = pwp->pw_uid;
1507c478bd9Sstevel@tonic-gate 		prgid = gid = egid = pwp->pw_gid;
1517c478bd9Sstevel@tonic-gate 	} else {
1527c478bd9Sstevel@tonic-gate 		uid = getuid();
1537c478bd9Sstevel@tonic-gate 		gid = getgid();
1547c478bd9Sstevel@tonic-gate 		euid = geteuid();
1557c478bd9Sstevel@tonic-gate 		egid = getegid();
1567c478bd9Sstevel@tonic-gate 	}
1577c478bd9Sstevel@tonic-gate 
1587c478bd9Sstevel@tonic-gate 	if (mode != CURR) {
1597c478bd9Sstevel@tonic-gate 		if (!rflag) {
1607c478bd9Sstevel@tonic-gate 			uid = euid;
1617c478bd9Sstevel@tonic-gate 			gid = egid;
1627c478bd9Sstevel@tonic-gate 		}
1637c478bd9Sstevel@tonic-gate 		if (mode == USER)
1647c478bd9Sstevel@tonic-gate 			puid(uid);
1657c478bd9Sstevel@tonic-gate 		else if (mode == GROUP)
1667c478bd9Sstevel@tonic-gate 			pgid(gid);
1677c478bd9Sstevel@tonic-gate 		else if (mode == ALLGROUPS) {
1687c478bd9Sstevel@tonic-gate 			pgid(gid);
1697c478bd9Sstevel@tonic-gate 			if (user)
1707c478bd9Sstevel@tonic-gate 				i = getusergroups(NGROUPS_UMAX, groupids, user,
1717c478bd9Sstevel@tonic-gate 				    prgid);
1727c478bd9Sstevel@tonic-gate 			else
1737c478bd9Sstevel@tonic-gate 				i = getgroups(NGROUPS_UMAX, groupids);
1747c478bd9Sstevel@tonic-gate 			if (i == -1)
1757c478bd9Sstevel@tonic-gate 				perror("getgroups");
1767c478bd9Sstevel@tonic-gate 			else if (i > 0) {
1777c478bd9Sstevel@tonic-gate 				for (j = 0; j < i; ++j) {
1787c478bd9Sstevel@tonic-gate 					if ((gid = groupids[j]) == egid)
1797c478bd9Sstevel@tonic-gate 						continue;
1807c478bd9Sstevel@tonic-gate 					(void) putchar(' ');
1817c478bd9Sstevel@tonic-gate 					pgid(gid);
1827c478bd9Sstevel@tonic-gate 				}
1837c478bd9Sstevel@tonic-gate 			}
1847c478bd9Sstevel@tonic-gate 		}
1857c478bd9Sstevel@tonic-gate 		(void) putchar('\n');
1867c478bd9Sstevel@tonic-gate 	} else {
1877c478bd9Sstevel@tonic-gate 		prid(UID, uid);
1887c478bd9Sstevel@tonic-gate 		prid(GID, gid);
1897c478bd9Sstevel@tonic-gate 		if (uid != euid)
1907c478bd9Sstevel@tonic-gate 			prid(EUID, euid);
1917c478bd9Sstevel@tonic-gate 		if (gid != egid)
1927c478bd9Sstevel@tonic-gate 			prid(EGID, egid);
193*a604d238Scf46844 
1947c478bd9Sstevel@tonic-gate 		if (aflag) {
1957c478bd9Sstevel@tonic-gate 			if (user)
1967c478bd9Sstevel@tonic-gate 				i = getusergroups(NGROUPS_UMAX, groupids, user,
1977c478bd9Sstevel@tonic-gate 				    prgid);
1987c478bd9Sstevel@tonic-gate 			else
1997c478bd9Sstevel@tonic-gate 				i = getgroups(NGROUPS_UMAX, groupids);
2007c478bd9Sstevel@tonic-gate 			if (i == -1)
2017c478bd9Sstevel@tonic-gate 				perror("getgroups");
2027c478bd9Sstevel@tonic-gate 			else if (i > 0) {
2037c478bd9Sstevel@tonic-gate 				(void) printf(" groups=");
2047c478bd9Sstevel@tonic-gate 				for (idp = groupids; i--; idp++) {
2057c478bd9Sstevel@tonic-gate 					(void) printf("%d", (int)*idp);
2067c478bd9Sstevel@tonic-gate 					if (gr = getgrgid(*idp))
2077c478bd9Sstevel@tonic-gate 						(void) printf("(%s)",
2087c478bd9Sstevel@tonic-gate 							gr->gr_name);
2097c478bd9Sstevel@tonic-gate 					if (i)
2107c478bd9Sstevel@tonic-gate 						(void) putchar(',');
2117c478bd9Sstevel@tonic-gate 				}
2127c478bd9Sstevel@tonic-gate 			}
2137c478bd9Sstevel@tonic-gate 		}
214*a604d238Scf46844 #ifdef XPG4
215*a604d238Scf46844 		/*
216*a604d238Scf46844 		 * POSIX requires us to show all supplementary groups
217*a604d238Scf46844 		 * groups other than the effective group already listed.
218*a604d238Scf46844 		 *
219*a604d238Scf46844 		 * This differs from -a above, because -a always shows
220*a604d238Scf46844 		 * all groups including the effective group in the group=
221*a604d238Scf46844 		 * line.
222*a604d238Scf46844 		 *
223*a604d238Scf46844 		 * It would be simpler if SunOS could just adopt this
224*a604d238Scf46844 		 * POSIX behavior, as it is so incredibly close to the
225*a604d238Scf46844 		 * the norm already.
226*a604d238Scf46844 		 *
227*a604d238Scf46844 		 * Then the magic -a flag could just indicate whether or
228*a604d238Scf46844 		 * not we are suppressing the effective group id.
229*a604d238Scf46844 		 */
230*a604d238Scf46844 		else {
2317c478bd9Sstevel@tonic-gate 			if (user)
232*a604d238Scf46844 				i = getusergroups(NGROUPS_UMAX, groupids, user,
233*a604d238Scf46844 				    prgid);
2347c478bd9Sstevel@tonic-gate 			else
2357c478bd9Sstevel@tonic-gate 				i = getgroups(NGROUPS_UMAX, groupids);
2367c478bd9Sstevel@tonic-gate 			if (i == -1)
2377c478bd9Sstevel@tonic-gate 				perror("getgroups");
2387c478bd9Sstevel@tonic-gate 			else if (i > 1) {
2397c478bd9Sstevel@tonic-gate 				(void) printf(" groups=");
2407c478bd9Sstevel@tonic-gate 				for (idp = groupids; i--; idp++) {
2417c478bd9Sstevel@tonic-gate 					if (*idp == egid)
2427c478bd9Sstevel@tonic-gate 						continue;
2437c478bd9Sstevel@tonic-gate 					(void) printf("%d", (int)*idp);
2447c478bd9Sstevel@tonic-gate 					if (gr = getgrgid(*idp))
245*a604d238Scf46844 						(void) printf("(%s)",
246*a604d238Scf46844 							gr->gr_name);
2477c478bd9Sstevel@tonic-gate 					if (i)
2487c478bd9Sstevel@tonic-gate 						(void) putchar(',');
2497c478bd9Sstevel@tonic-gate 				}
2507c478bd9Sstevel@tonic-gate 			}
251*a604d238Scf46844 		}
2527c478bd9Sstevel@tonic-gate #endif
2537c478bd9Sstevel@tonic-gate 		if (project_flag) {
2547c478bd9Sstevel@tonic-gate 			struct project proj;
2557c478bd9Sstevel@tonic-gate 			void *projbuf;
2567c478bd9Sstevel@tonic-gate 			projid_t curprojid = getprojid();
2577c478bd9Sstevel@tonic-gate 
2587c478bd9Sstevel@tonic-gate 			if ((projbuf = malloc(PROJECT_BUFSZ)) == NULL) {
2597c478bd9Sstevel@tonic-gate 				(void) fprintf(stderr, "unable to allocate "
2607c478bd9Sstevel@tonic-gate 				    "memory\n");
2617c478bd9Sstevel@tonic-gate 				return (2);
2627c478bd9Sstevel@tonic-gate 			}
2637c478bd9Sstevel@tonic-gate 
2647c478bd9Sstevel@tonic-gate 			if (user) {
2657c478bd9Sstevel@tonic-gate 				if (getdefaultproj(user, &proj, projbuf,
2667c478bd9Sstevel@tonic-gate 				    PROJECT_BUFSZ) != NULL)
2677c478bd9Sstevel@tonic-gate 					(void) printf(" projid=%d(%s)",
2687c478bd9Sstevel@tonic-gate 					    (int)proj.pj_projid, proj.pj_name);
2697c478bd9Sstevel@tonic-gate 				else
2707c478bd9Sstevel@tonic-gate 					/*
2717c478bd9Sstevel@tonic-gate 					 * This can only happen if project
2727c478bd9Sstevel@tonic-gate 					 * "default" has been removed from
2737c478bd9Sstevel@tonic-gate 					 * /etc/project file or the whole
2747c478bd9Sstevel@tonic-gate 					 * project database file was removed.
2757c478bd9Sstevel@tonic-gate 					 */
2767c478bd9Sstevel@tonic-gate 					(void) printf(" projid=(NONE)");
2777c478bd9Sstevel@tonic-gate 			} else {
2787c478bd9Sstevel@tonic-gate 				if (getprojbyid(curprojid, &proj, projbuf,
2797c478bd9Sstevel@tonic-gate 				    PROJECT_BUFSZ) == NULL)
2807c478bd9Sstevel@tonic-gate 					(void) printf(" projid=%d",
2817c478bd9Sstevel@tonic-gate 					    (int)curprojid);
2827c478bd9Sstevel@tonic-gate 				else
2837c478bd9Sstevel@tonic-gate 					(void) printf(" projid=%d(%s)",
2847c478bd9Sstevel@tonic-gate 					    (int)curprojid, proj.pj_name);
2857c478bd9Sstevel@tonic-gate 			}
2867c478bd9Sstevel@tonic-gate 			free(projbuf);
2877c478bd9Sstevel@tonic-gate 		}
2887c478bd9Sstevel@tonic-gate 		(void) putchar('\n');
2897c478bd9Sstevel@tonic-gate 	}
2907c478bd9Sstevel@tonic-gate 	return (0);
2917c478bd9Sstevel@tonic-gate }
2927c478bd9Sstevel@tonic-gate 
2937c478bd9Sstevel@tonic-gate static int
2947c478bd9Sstevel@tonic-gate usage()
2957c478bd9Sstevel@tonic-gate {
2967c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, gettext(
297*a604d238Scf46844 	    "Usage: id [-ap] [user]\n"
2987c478bd9Sstevel@tonic-gate 	    "       id -G [-n] [user]\n"
2997c478bd9Sstevel@tonic-gate 	    "       id -g [-nr] [user]\n"
3007c478bd9Sstevel@tonic-gate 	    "       id -u [-nr] [user]\n"));
3017c478bd9Sstevel@tonic-gate 	return (2);
3027c478bd9Sstevel@tonic-gate }
3037c478bd9Sstevel@tonic-gate 
3047c478bd9Sstevel@tonic-gate static void
3057c478bd9Sstevel@tonic-gate puid(uid_t uid)
3067c478bd9Sstevel@tonic-gate {
3077c478bd9Sstevel@tonic-gate 	struct passwd *pw;
3087c478bd9Sstevel@tonic-gate 
3097c478bd9Sstevel@tonic-gate 	if (nflag && (pw = getpwuid(uid)) != PWNULL)
3107c478bd9Sstevel@tonic-gate 		(void) printf("%s", pw->pw_name);
3117c478bd9Sstevel@tonic-gate 	else
3127c478bd9Sstevel@tonic-gate 		(void) printf("%u", (int)uid);
3137c478bd9Sstevel@tonic-gate }
3147c478bd9Sstevel@tonic-gate 
3157c478bd9Sstevel@tonic-gate static void
3167c478bd9Sstevel@tonic-gate pgid(gid_t gid)
3177c478bd9Sstevel@tonic-gate {
3187c478bd9Sstevel@tonic-gate 	struct group *gr;
3197c478bd9Sstevel@tonic-gate 
3207c478bd9Sstevel@tonic-gate 	if (nflag && (gr = getgrgid(gid)) != GRNULL)
3217c478bd9Sstevel@tonic-gate 		(void) printf("%s", gr->gr_name);
3227c478bd9Sstevel@tonic-gate 	else
3237c478bd9Sstevel@tonic-gate 		(void) printf("%u", (int)gid);
3247c478bd9Sstevel@tonic-gate }
3257c478bd9Sstevel@tonic-gate 
3267c478bd9Sstevel@tonic-gate static void
3277c478bd9Sstevel@tonic-gate prid(TYPE how, uid_t id)
3287c478bd9Sstevel@tonic-gate {
3297c478bd9Sstevel@tonic-gate 	char *s;
3307c478bd9Sstevel@tonic-gate 
3317c478bd9Sstevel@tonic-gate 	switch ((int)how) {
3327c478bd9Sstevel@tonic-gate 		case UID:
3337c478bd9Sstevel@tonic-gate 			s = "uid";
3347c478bd9Sstevel@tonic-gate 			break;
3357c478bd9Sstevel@tonic-gate 
3367c478bd9Sstevel@tonic-gate 		case EUID:
3377c478bd9Sstevel@tonic-gate 			s = " euid";
3387c478bd9Sstevel@tonic-gate 			break;
3397c478bd9Sstevel@tonic-gate 
3407c478bd9Sstevel@tonic-gate 		case GID:
3417c478bd9Sstevel@tonic-gate 			s = " gid";
3427c478bd9Sstevel@tonic-gate 			break;
3437c478bd9Sstevel@tonic-gate 
3447c478bd9Sstevel@tonic-gate 		case EGID:
3457c478bd9Sstevel@tonic-gate 			s = " egid";
3467c478bd9Sstevel@tonic-gate 			break;
3477c478bd9Sstevel@tonic-gate 
3487c478bd9Sstevel@tonic-gate 	}
3497c478bd9Sstevel@tonic-gate 	if (s != NULL)
3507c478bd9Sstevel@tonic-gate 		(void) printf("%s=", s);
3517c478bd9Sstevel@tonic-gate 	(void) printf("%u", (int)id);
3527c478bd9Sstevel@tonic-gate 	switch ((int)how) {
3537c478bd9Sstevel@tonic-gate 	case UID:
3547c478bd9Sstevel@tonic-gate 	case EUID:
3557c478bd9Sstevel@tonic-gate 		{
3567c478bd9Sstevel@tonic-gate 			struct passwd *pwp;
3577c478bd9Sstevel@tonic-gate 
3587c478bd9Sstevel@tonic-gate 			if ((pwp = getpwuid(id)) != PWNULL)
3597c478bd9Sstevel@tonic-gate 				(void) printf("(%s)", pwp->pw_name);
3607c478bd9Sstevel@tonic-gate 
3617c478bd9Sstevel@tonic-gate 		}
3627c478bd9Sstevel@tonic-gate 		break;
3637c478bd9Sstevel@tonic-gate 	case GID:
3647c478bd9Sstevel@tonic-gate 	case EGID:
3657c478bd9Sstevel@tonic-gate 		{
3667c478bd9Sstevel@tonic-gate 			struct group *grp;
3677c478bd9Sstevel@tonic-gate 
3687c478bd9Sstevel@tonic-gate 			if ((grp = getgrgid(id)) != GRNULL)
3697c478bd9Sstevel@tonic-gate 				(void) printf("(%s)", grp->gr_name);
3707c478bd9Sstevel@tonic-gate 		}
3717c478bd9Sstevel@tonic-gate 		break;
3727c478bd9Sstevel@tonic-gate 	}
3737c478bd9Sstevel@tonic-gate }
3747c478bd9Sstevel@tonic-gate 
3757c478bd9Sstevel@tonic-gate /*
3767c478bd9Sstevel@tonic-gate  * Get the supplementary group affiliation for the user
3777c478bd9Sstevel@tonic-gate  */
3787c478bd9Sstevel@tonic-gate static int getusergroups(gidsetsize, grouplist, user, prgid)
3797c478bd9Sstevel@tonic-gate int	gidsetsize;
3807c478bd9Sstevel@tonic-gate gid_t	*grouplist;
3817c478bd9Sstevel@tonic-gate char	*user;
3827c478bd9Sstevel@tonic-gate gid_t	prgid;
3837c478bd9Sstevel@tonic-gate {
3847c478bd9Sstevel@tonic-gate 	struct group *group;
3857c478bd9Sstevel@tonic-gate 	char **gr_mem;
3867c478bd9Sstevel@tonic-gate 	int ngroups = 0;
3877c478bd9Sstevel@tonic-gate 
3887c478bd9Sstevel@tonic-gate 	setgrent();
3897c478bd9Sstevel@tonic-gate 	while ((ngroups < gidsetsize) && ((group = getgrent()) != NULL))
3907c478bd9Sstevel@tonic-gate 		for (gr_mem = group->gr_mem; *gr_mem; gr_mem++)
3917c478bd9Sstevel@tonic-gate 			if (strcmp(user, *gr_mem) == 0) {
3927c478bd9Sstevel@tonic-gate 				if (gidsetsize)
3937c478bd9Sstevel@tonic-gate 					grouplist[ngroups] = group->gr_gid;
3947c478bd9Sstevel@tonic-gate 				ngroups++;
3957c478bd9Sstevel@tonic-gate 			}
3967c478bd9Sstevel@tonic-gate 	endgrent();
3977c478bd9Sstevel@tonic-gate 	if (gidsetsize && !ngroups)
3987c478bd9Sstevel@tonic-gate 		grouplist[ngroups++] = prgid;
3997c478bd9Sstevel@tonic-gate 	return (ngroups);
4007c478bd9Sstevel@tonic-gate }
401