1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License").  You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22/*
23 * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27/*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
28/*	  All Rights Reserved  	*/
29
30/*
31 * University Copyright- Copyright (c) 1982, 1986, 1988
32 * The Regents of the University of California
33 * All Rights Reserved
34 *
35 * University Acknowledgment- Portions of this document are derived from
36 * software developed by the University of California, Berkeley, and its
37 * contributors.
38 */
39
40#pragma ident	"%Z%%M%	%I%	%E% SMI"
41
42/*
43 * groups - show group memberships
44 */
45/* LINTLIBRARY PROTOLIB1 */
46
47#include <grp.h>
48#include <pwd.h>
49#include <stdio.h>
50#include <unistd.h>
51#include <stdlib.h>
52
53extern struct group *getgrgid();
54extern struct passwd *getpwnam();
55extern int _getgroupsbymember(const char *, gid_t[], int, int);
56
57static void showgroups();
58
59static int ngroups_max;
60
61int
62main(int argc, char *argv[])
63{
64	int xval = 0;
65	struct passwd *pw;
66
67	ngroups_max = sysconf(_SC_NGROUPS_MAX);
68
69	if (ngroups_max < 0) {
70		(void) fprintf(stderr,
71			"groups: could not get configuration info\n");
72		exit(1);
73	}
74
75	if (ngroups_max == 0)
76		exit(0);
77
78	if (argc == 1) {
79
80		if ((pw = getpwuid(getuid())) == NULL) {
81			(void) fprintf(stderr, "groups: No passwd entry\n");
82			xval = 1;
83		} else
84			showgroups(pw);
85
86	} else while (*++argv) {
87
88		if ((pw = getpwnam(*argv)) == NULL) {
89			(void) fprintf(stderr,
90				"groups: %s : No such user\n", *argv);
91			xval = 1;
92		} else {
93			if (argc > 2)
94				(void) printf("%s : ", *argv);
95			showgroups(pw);
96		}
97	}
98
99	return (xval);
100
101}
102
103static void
104showgroups(struct passwd *pw)
105{
106	struct group *gr;
107	static gid_t *groups = NULL;
108	int ngroups;
109	int i;
110
111	if (groups == NULL) {
112		if ((groups = (gid_t *)calloc((uint_t)ngroups_max,
113						sizeof (gid_t))) == 0) {
114			(void) fprintf(stderr,
115				"allocation of %d bytes failed\n",
116				ngroups_max * sizeof (gid_t));
117			exit(1);
118		}
119	}
120	groups[0] = pw->pw_gid;
121
122	ngroups = _getgroupsbymember(pw->pw_name, groups, ngroups_max, 1);
123
124	if (gr = getgrgid(groups[0]))
125		(void) printf("%s", gr->gr_name);
126	else
127		(void) printf("%d", (int)pw->pw_gid);
128
129	for (i = 1; i < ngroups; i++) {
130		if ((gr = getgrgid(groups[i])))
131			(void) printf(" %s", gr->gr_name);
132		else
133			(void) printf(" %d", (int)groups[i]);
134	}
135
136	(void) printf("\n");
137}
138