Annotation of src/usr.bin/id/id.c, Revision 1.18
1.18 ! sobrado 1: /* $OpenBSD: id.c,v 1.17 2004/11/16 13:51:35 jmc Exp $ */
1.2 deraadt 2:
1.1 deraadt 3: /*-
4: * Copyright (c) 1991, 1993
5: * The Regents of the University of California. All rights reserved.
6: *
7: * Redistribution and use in source and binary forms, with or without
8: * modification, are permitted provided that the following conditions
9: * are met:
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: * 2. Redistributions in binary form must reproduce the above copyright
13: * notice, this list of conditions and the following disclaimer in the
14: * documentation and/or other materials provided with the distribution.
1.12 millert 15: * 3. Neither the name of the University nor the names of its contributors
1.1 deraadt 16: * may be used to endorse or promote products derived from this software
17: * without specific prior written permission.
18: *
19: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29: * SUCH DAMAGE.
30: */
31:
32: #ifndef lint
33: static char copyright[] =
34: "@(#) Copyright (c) 1991, 1993\n\
35: The Regents of the University of California. All rights reserved.\n";
36: #endif /* not lint */
37:
38: #ifndef lint
39: /*static char sccsid[] = "@(#)id.c 8.3 (Berkeley) 4/28/95";*/
1.18 ! sobrado 40: static char rcsid[] = "$OpenBSD: id.c,v 1.17 2004/11/16 13:51:35 jmc Exp $";
1.1 deraadt 41: #endif /* not lint */
42:
43: #include <sys/param.h>
44:
45: #include <errno.h>
46: #include <grp.h>
47: #include <pwd.h>
48: #include <stdio.h>
49: #include <stdlib.h>
50: #include <string.h>
51: #include <unistd.h>
1.6 mickey 52: #include <err.h>
1.1 deraadt 53:
1.11 millert 54: void current(void);
55: void pretty(struct passwd *);
56: void group(struct passwd *, int);
57: void usage(void);
58: void user(struct passwd *);
1.1 deraadt 59: struct passwd *
1.11 millert 60: who(char *);
1.1 deraadt 61:
62: int
1.13 deraadt 63: main(int argc, char *argv[])
1.1 deraadt 64: {
65: struct group *gr;
66: struct passwd *pw;
1.14 tdeval 67: int Gflag, ch, gflag, nflag, pflag, rflag, uflag;
68: uid_t uid;
69: gid_t gid;
1.1 deraadt 70:
71: Gflag = gflag = nflag = pflag = rflag = uflag = 0;
1.3 millert 72: while ((ch = getopt(argc, argv, "Ggnpru")) != -1)
1.1 deraadt 73: switch(ch) {
74: case 'G':
75: Gflag = 1;
76: break;
77: case 'g':
78: gflag = 1;
79: break;
80: case 'n':
81: nflag = 1;
82: break;
83: case 'p':
84: pflag = 1;
85: break;
86: case 'r':
87: rflag = 1;
88: break;
89: case 'u':
90: uflag = 1;
91: break;
92: case '?':
93: default:
94: usage();
95: }
96: argc -= optind;
97: argv += optind;
98:
99: switch(Gflag + gflag + pflag + uflag) {
100: case 1:
101: break;
102: case 0:
103: if (!nflag && !rflag)
104: break;
105: /* FALLTHROUGH */
106: default:
107: usage();
108: }
109:
110: pw = *argv ? who(*argv) : NULL;
111:
112: if (gflag) {
1.14 tdeval 113: gid = pw ? pw->pw_gid : rflag ? getgid() : getegid();
114: if (nflag && (gr = getgrgid(gid)))
1.1 deraadt 115: (void)printf("%s\n", gr->gr_name);
116: else
1.14 tdeval 117: (void)printf("%u\n", gid);
1.1 deraadt 118: exit(0);
119: }
120:
121: if (uflag) {
1.14 tdeval 122: uid = pw ? pw->pw_uid : rflag ? getuid() : geteuid();
123: if (nflag && (pw = getpwuid(uid)))
1.1 deraadt 124: (void)printf("%s\n", pw->pw_name);
125: else
1.14 tdeval 126: (void)printf("%u\n", uid);
1.1 deraadt 127: exit(0);
128: }
129:
130: if (Gflag) {
131: group(pw, nflag);
132: exit(0);
133: }
134:
135: if (pflag) {
136: pretty(pw);
137: exit(0);
138: }
139:
140: if (pw)
141: user(pw);
142: else
143: current();
144: exit(0);
145: }
146:
147: void
1.13 deraadt 148: pretty(struct passwd *pw)
1.1 deraadt 149: {
150: struct group *gr;
1.4 deraadt 151: uid_t eid, rid;
1.1 deraadt 152: char *login;
153:
154: if (pw) {
155: (void)printf("uid\t%s\n", pw->pw_name);
156: (void)printf("groups\t");
157: group(pw, 1);
158: } else {
159: if ((login = getlogin()) == NULL)
1.6 mickey 160: err(1, "getlogin");
1.1 deraadt 161:
162: pw = getpwuid(rid = getuid());
163: if (pw == NULL || strcmp(login, pw->pw_name))
164: (void)printf("login\t%s\n", login);
165: if (pw)
166: (void)printf("uid\t%s\n", pw->pw_name);
167: else
168: (void)printf("uid\t%u\n", rid);
169:
1.9 deraadt 170: if ((eid = geteuid()) != rid) {
1.4 deraadt 171: if ((pw = getpwuid(eid)))
1.7 aaron 172: (void)printf("euid\t%s\n", pw->pw_name);
1.1 deraadt 173: else
1.7 aaron 174: (void)printf("euid\t%u\n", eid);
1.9 deraadt 175: }
176: if ((rid = getgid()) != (eid = getegid())) {
1.4 deraadt 177: if ((gr = getgrgid(rid)))
1.1 deraadt 178: (void)printf("rgid\t%s\n", gr->gr_name);
179: else
180: (void)printf("rgid\t%u\n", rid);
1.9 deraadt 181: }
1.1 deraadt 182: (void)printf("groups\t");
183: group(NULL, 1);
184: }
185: }
186:
187: void
1.13 deraadt 188: current(void)
1.1 deraadt 189: {
190: struct group *gr;
191: struct passwd *pw;
1.4 deraadt 192: int cnt, ngroups;
1.14 tdeval 193: uid_t uid, euid;
194: gid_t groups[NGROUPS], gid, egid, lastgid;
1.1 deraadt 195: char *fmt;
196:
1.14 tdeval 197: uid = getuid();
198: (void)printf("uid=%u", uid);
199: if ((pw = getpwuid(uid)))
1.1 deraadt 200: (void)printf("(%s)", pw->pw_name);
1.14 tdeval 201: if ((euid = geteuid()) != uid) {
202: (void)printf(" euid=%u", euid);
203: if ((pw = getpwuid(euid)))
1.1 deraadt 204: (void)printf("(%s)", pw->pw_name);
205: }
1.14 tdeval 206: gid = getgid();
207: (void)printf(" gid=%u", gid);
208: if ((gr = getgrgid(gid)))
1.1 deraadt 209: (void)printf("(%s)", gr->gr_name);
1.14 tdeval 210: if ((egid = getegid()) != gid) {
211: (void)printf(" egid=%u", egid);
212: if ((gr = getgrgid(egid)))
1.1 deraadt 213: (void)printf("(%s)", gr->gr_name);
214: }
1.4 deraadt 215: if ((ngroups = getgroups(NGROUPS, groups))) {
1.18 ! sobrado 216: for (fmt = " groups=%u", lastgid = (gid_t)-1, cnt = 0;
! 217: cnt < ngroups; fmt = ", %u", lastgid = gid) {
1.4 deraadt 218: gid = groups[cnt++];
219: if (lastgid == gid)
1.1 deraadt 220: continue;
1.4 deraadt 221: (void)printf(fmt, gid);
222: if ((gr = getgrgid(gid)))
1.1 deraadt 223: (void)printf("(%s)", gr->gr_name);
224: }
225: }
226: (void)printf("\n");
227: }
228:
229: void
1.13 deraadt 230: user(struct passwd *pw)
1.1 deraadt 231: {
1.14 tdeval 232: gid_t gid, groups[NGROUPS + 1];
233: int cnt, ngroups;
234: uid_t uid;
1.10 mpech 235: struct group *gr;
236: char *fmt;
1.1 deraadt 237:
1.14 tdeval 238: uid = pw->pw_uid;
239: (void)printf("uid=%u(%s)", uid, pw->pw_name);
1.1 deraadt 240: (void)printf(" gid=%u", pw->pw_gid);
1.4 deraadt 241: if ((gr = getgrgid(pw->pw_gid)))
1.1 deraadt 242: (void)printf("(%s)", gr->gr_name);
243: ngroups = NGROUPS + 1;
244: (void) getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups);
245: fmt = " groups=%u";
1.14 tdeval 246: for (cnt = 0; cnt < ngroups;) {
247: gid = groups[cnt];
248: (void)printf(fmt, gid);
1.8 aaron 249: fmt = ", %u";
1.14 tdeval 250: if ((gr = getgrgid(gid)))
1.1 deraadt 251: (void)printf("(%s)", gr->gr_name);
1.14 tdeval 252: /* Skip same gid entries. */
253: while (++cnt < ngroups && gid == groups[cnt]);
1.1 deraadt 254: }
255: (void)printf("\n");
256: }
257:
258: void
1.13 deraadt 259: group(struct passwd *pw, int nflag)
1.1 deraadt 260: {
1.14 tdeval 261: int cnt, ngroups;
262: gid_t gid, groups[NGROUPS + 1];
1.1 deraadt 263: struct group *gr;
264: char *fmt;
265:
266: if (pw) {
267: ngroups = NGROUPS + 1;
268: (void) getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups);
269: } else {
270: groups[0] = getgid();
271: ngroups = getgroups(NGROUPS, groups + 1) + 1;
272: }
273: fmt = nflag ? "%s" : "%u";
1.14 tdeval 274: for (cnt = 0; cnt < ngroups;) {
275: gid = groups[cnt];
1.1 deraadt 276: if (nflag) {
1.14 tdeval 277: if ((gr = getgrgid(gid)))
1.1 deraadt 278: (void)printf(fmt, gr->gr_name);
279: else
280: (void)printf(*fmt == ' ' ? " %u" : "%u",
1.14 tdeval 281: gid);
1.1 deraadt 282: fmt = " %s";
283: } else {
1.14 tdeval 284: (void)printf(fmt, gid);
1.1 deraadt 285: fmt = " %u";
286: }
1.14 tdeval 287: /* Skip same gid entries. */
288: while (++cnt < ngroups && gid == groups[cnt]);
1.1 deraadt 289: }
290: (void)printf("\n");
291: }
292:
293: struct passwd *
1.13 deraadt 294: who(char *u)
1.1 deraadt 295: {
296: struct passwd *pw;
1.14 tdeval 297: uid_t uid;
1.16 pvalchev 298: const char *errstr;
1.1 deraadt 299:
300: /*
301: * Translate user argument into a pw pointer. First, try to
302: * get it as specified. If that fails, try it as a number.
303: */
1.4 deraadt 304: if ((pw = getpwnam(u)))
1.1 deraadt 305: return(pw);
1.16 pvalchev 306: uid = strtonum(u, 0, UID_MAX, &errstr);
307: if (!errstr && (pw = getpwuid(uid)))
1.1 deraadt 308: return(pw);
1.6 mickey 309: errx(1, "%s: No such user", u);
1.1 deraadt 310: /* NOTREACHED */
311: }
312:
313: void
1.13 deraadt 314: usage(void)
1.1 deraadt 315: {
1.6 mickey 316: (void)fprintf(stderr, "usage: id [user]\n"
317: " id -G [-n] [user]\n"
318: " id -g [-nr] [user]\n"
1.17 jmc 319: " id -p [user]\n"
1.6 mickey 320: " id -u [-nr] [user]\n");
1.1 deraadt 321: exit(1);
322: }