don't bother resolving onbld python module deps
[unleashed.git] / bin / id / id.c
blobf23de74c74f28d413c55205e809b929a95ebb15c
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #pragma ident "%Z%%M% %I% %E% SMI"
28 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
29 /* All Rights Reserved */
32 #include <locale.h>
33 #include <stdio.h>
34 #include <pwd.h>
35 #include <grp.h>
36 #include <sys/param.h>
37 #include <unistd.h>
38 #include <string.h>
39 #include <project.h>
40 #include <stdlib.h>
41 #include <alloca.h>
43 #define PWNULL ((struct passwd *)0)
44 #define GRNULL ((struct group *)0)
46 typedef enum TYPE {
47 UID, EUID, GID, EGID, SGID
48 } TYPE;
50 typedef enum PRINT {
51 CURR, /* Print uid/gid only */
52 ALLGROUPS, /* Print all groups */
53 GROUP, /* Print only group */
54 USER /* Print only uid */
55 } PRINT;
56 static PRINT mode = CURR;
58 static int usage(void);
59 static void puid(uid_t);
60 static void pgid(gid_t);
61 static void prid(TYPE, uid_t);
62 static int getusergroups(int, gid_t *, char *, gid_t);
64 static int nflag = 0; /* Output names, not numbers */
65 static int rflag = 0; /* Output real, not effective IDs */
66 static char stdbuf[BUFSIZ];
68 int
69 main(int argc, char *argv[])
71 gid_t *idp;
72 uid_t uid, euid;
73 gid_t gid, egid, prgid;
74 int c, project_flag = 0;
75 struct passwd *pwp;
76 int i, j;
77 int groupmax = sysconf(_SC_NGROUPS_MAX);
78 gid_t *groupids = alloca(groupmax * sizeof (gid_t));
79 struct group *gr;
80 char *user = NULL;
82 (void) setlocale(LC_ALL, "");
84 #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
85 #define TEXT_DOMAIN "SYS_TEST"
86 #endif
87 (void) textdomain(TEXT_DOMAIN);
88 while ((c = getopt(argc, argv, "Ggunrp")) != EOF) {
89 switch (c) {
90 case 'G':
91 if (mode != CURR)
92 return (usage());
93 mode = ALLGROUPS;
94 break;
96 case 'g':
97 if (mode != CURR)
98 return (usage());
99 mode = GROUP;
100 break;
102 case 'n':
103 nflag++;
104 break;
106 case 'r':
107 rflag++;
108 break;
110 case 'u':
111 if (mode != CURR)
112 return (usage());
113 mode = USER;
114 break;
116 case 'p':
117 if (mode != CURR)
118 return (usage());
119 project_flag++;
120 break;
122 case '?':
123 return (usage());
126 setbuf(stdout, stdbuf);
127 argc -= optind-1;
128 argv += optind-1;
130 /* -n and -r must be combined with one of -[Ggu] */
131 /* -r cannot be combined with -G */
132 /* -p cannot be combined with -[Ggu] */
134 if ((mode == CURR && (nflag || rflag)) ||
135 (mode == ALLGROUPS && rflag) ||
136 (argc != 1 && argc != 2) ||
137 (mode != CURR && project_flag))
138 return (usage());
139 if (argc == 2) {
140 if ((pwp = getpwnam(argv[1])) == PWNULL) {
141 (void) fprintf(stderr,
142 gettext("id: invalid user name: \"%s\"\n"),
143 argv[1]);
144 return (1);
146 user = argv[1];
147 uid = euid = pwp->pw_uid;
148 prgid = gid = egid = pwp->pw_gid;
149 } else {
150 uid = getuid();
151 gid = getgid();
152 euid = geteuid();
153 egid = getegid();
156 if (mode != CURR) {
157 if (!rflag) {
158 uid = euid;
159 gid = egid;
161 if (mode == USER)
162 puid(uid);
163 else if (mode == GROUP)
164 pgid(gid);
165 else if (mode == ALLGROUPS) {
166 pgid(gid);
167 if (user)
168 i = getusergroups(groupmax, groupids, user,
169 prgid);
170 else
171 i = getgroups(groupmax, groupids);
172 if (i == -1)
173 perror("getgroups");
174 else if (i > 0) {
175 for (j = 0; j < i; ++j) {
176 if ((gid = groupids[j]) == egid)
177 continue;
178 (void) putchar(' ');
179 pgid(gid);
183 (void) putchar('\n');
184 } else {
185 prid(UID, uid);
186 prid(GID, gid);
187 if (uid != euid)
188 prid(EUID, euid);
189 if (gid != egid)
190 prid(EGID, egid);
192 if (user)
193 i = getusergroups(groupmax, groupids, user,
194 prgid);
195 else
196 i = getgroups(groupmax, groupids);
197 if (i == -1)
198 perror("getgroups");
199 else if (i > 1) {
200 (void) printf(" groups=");
201 for (idp = groupids; i--; idp++) {
202 if (*idp == egid)
203 continue;
204 (void) printf("%u", *idp);
205 if (gr = getgrgid(*idp))
206 (void) printf("(%s)",
207 gr->gr_name);
208 if (i)
209 (void) putchar(',');
213 if (project_flag) {
214 struct project proj;
215 void *projbuf;
216 projid_t curprojid = getprojid();
218 if ((projbuf = malloc(PROJECT_BUFSZ)) == NULL) {
219 (void) fprintf(stderr, "unable to allocate "
220 "memory\n");
221 return (2);
224 if (user) {
225 if (getdefaultproj(user, &proj, projbuf,
226 PROJECT_BUFSZ) != NULL)
227 (void) printf(" projid=%d(%s)",
228 (int)proj.pj_projid, proj.pj_name);
229 else
231 * This can only happen if project
232 * "default" has been removed from
233 * /etc/project file or the whole
234 * project database file was removed.
236 (void) printf(" projid=(NONE)");
237 } else {
238 if (getprojbyid(curprojid, &proj, projbuf,
239 PROJECT_BUFSZ) == NULL)
240 (void) printf(" projid=%d",
241 (int)curprojid);
242 else
243 (void) printf(" projid=%d(%s)",
244 (int)curprojid, proj.pj_name);
246 free(projbuf);
248 (void) putchar('\n');
250 return (0);
253 static int
254 usage()
256 (void) fprintf(stderr, gettext(
257 "Usage: id [user]\n"
258 " id -G [-n] [user]\n"
259 " id -g [-nr] [user]\n"
260 " id -p [user]\n"
261 " id -u [-nr] [user]\n"));
262 return (2);
265 static void
266 puid(uid_t uid)
268 struct passwd *pw;
270 if (nflag && (pw = getpwuid(uid)) != PWNULL)
271 (void) printf("%s", pw->pw_name);
272 else
273 (void) printf("%u", uid);
276 static void
277 pgid(gid_t gid)
279 struct group *gr;
281 if (nflag && (gr = getgrgid(gid)) != GRNULL)
282 (void) printf("%s", gr->gr_name);
283 else
284 (void) printf("%u", gid);
287 static void
288 prid(TYPE how, uid_t id)
290 char *s;
292 switch ((int)how) {
293 case UID:
294 s = "uid";
295 break;
297 case EUID:
298 s = " euid";
299 break;
301 case GID:
302 s = " gid";
303 break;
305 case EGID:
306 s = " egid";
307 break;
310 if (s != NULL)
311 (void) printf("%s=", s);
312 (void) printf("%u", id);
313 switch ((int)how) {
314 case UID:
315 case EUID:
317 struct passwd *pwp;
319 if ((pwp = getpwuid(id)) != PWNULL)
320 (void) printf("(%s)", pwp->pw_name);
323 break;
324 case GID:
325 case EGID:
327 struct group *grp;
329 if ((grp = getgrgid(id)) != GRNULL)
330 (void) printf("(%s)", grp->gr_name);
332 break;
337 * Get the supplementary group affiliation for the user
339 static int getusergroups(gidsetsize, grouplist, user, prgid)
340 int gidsetsize;
341 gid_t *grouplist;
342 char *user;
343 gid_t prgid;
345 struct group *group;
346 char **gr_mem;
347 int ngroups = 0;
349 setgrent();
350 while ((ngroups < gidsetsize) && ((group = getgrent()) != NULL))
351 for (gr_mem = group->gr_mem; *gr_mem; gr_mem++)
352 if (strcmp(user, *gr_mem) == 0) {
353 if (gidsetsize)
354 grouplist[ngroups] = group->gr_gid;
355 ngroups++;
357 endgrent();
358 if (gidsetsize && !ngroups)
359 grouplist[ngroups++] = prgid;
360 return (ngroups);