Annotation of src/usr.bin/id/id.c, Revision 1.23
1.23 ! millert 1: /* $OpenBSD: id.c,v 1.22 2015/01/16 06:40:08 deraadt 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:
1.20 okan 32: #include <err.h>
1.1 deraadt 33: #include <errno.h>
34: #include <grp.h>
35: #include <pwd.h>
36: #include <stdio.h>
37: #include <stdlib.h>
38: #include <string.h>
39: #include <unistd.h>
1.22 deraadt 40: #include <limits.h>
1.23 ! millert 41: #include <login_cap.h>
1.1 deraadt 42:
1.11 millert 43: void current(void);
44: void pretty(struct passwd *);
45: void group(struct passwd *, int);
46: void usage(void);
47: void user(struct passwd *);
1.1 deraadt 48: struct passwd *
1.11 millert 49: who(char *);
1.1 deraadt 50:
51: int
1.13 deraadt 52: main(int argc, char *argv[])
1.1 deraadt 53: {
54: struct group *gr;
55: struct passwd *pw;
1.23 ! millert 56: int ch, cflag, Gflag, gflag, nflag, pflag, rflag, uflag;
1.14 tdeval 57: uid_t uid;
58: gid_t gid;
1.20 okan 59: const char *opts;
1.1 deraadt 60:
1.23 ! millert 61: cflag = Gflag = gflag = nflag = pflag = rflag = uflag = 0;
1.20 okan 62:
63: if (strcmp(getprogname(), "groups") == 0) {
64: Gflag = 1;
65: nflag = 1;
66: opts = "";
67: if (argc > 2)
68: usage();
69: } else if (strcmp(getprogname(), "whoami") == 0) {
70: uflag = 1;
71: nflag = 1;
72: opts = "";
73: if (argc > 1)
74: usage();
75: } else
1.23 ! millert 76: opts = "cGgnpru";
1.20 okan 77:
78: while ((ch = getopt(argc, argv, opts)) != -1)
1.1 deraadt 79: switch(ch) {
1.23 ! millert 80: case 'c':
! 81: cflag = 1;
! 82: break;
1.1 deraadt 83: case 'G':
84: Gflag = 1;
85: break;
86: case 'g':
87: gflag = 1;
88: break;
89: case 'n':
90: nflag = 1;
91: break;
92: case 'p':
93: pflag = 1;
94: break;
95: case 'r':
96: rflag = 1;
97: break;
98: case 'u':
99: uflag = 1;
100: break;
101: case '?':
102: default:
103: usage();
104: }
105: argc -= optind;
106: argv += optind;
107:
1.23 ! millert 108: switch (cflag + Gflag + gflag + pflag + uflag) {
1.1 deraadt 109: case 1:
110: break;
111: case 0:
112: if (!nflag && !rflag)
113: break;
114: /* FALLTHROUGH */
115: default:
116: usage();
117: }
118:
1.20 okan 119: if (strcmp(opts, "") != 0 && argc > 1)
120: usage();
121:
1.1 deraadt 122: pw = *argv ? who(*argv) : NULL;
123:
1.23 ! millert 124: if (cflag) {
! 125: if (pw == NULL)
! 126: pw = getpwuid(getuid());
! 127: if (pw != NULL && pw->pw_class != NULL && *pw->pw_class != '\0')
! 128: (void)printf("%s\n", pw->pw_class);
! 129: else
! 130: (void)printf("%s\n", LOGIN_DEFCLASS);
! 131: exit(0);
! 132: }
! 133:
1.1 deraadt 134: if (gflag) {
1.14 tdeval 135: gid = pw ? pw->pw_gid : rflag ? getgid() : getegid();
136: if (nflag && (gr = getgrgid(gid)))
1.1 deraadt 137: (void)printf("%s\n", gr->gr_name);
138: else
1.14 tdeval 139: (void)printf("%u\n", gid);
1.1 deraadt 140: exit(0);
141: }
142:
143: if (uflag) {
1.14 tdeval 144: uid = pw ? pw->pw_uid : rflag ? getuid() : geteuid();
145: if (nflag && (pw = getpwuid(uid)))
1.1 deraadt 146: (void)printf("%s\n", pw->pw_name);
147: else
1.14 tdeval 148: (void)printf("%u\n", uid);
1.1 deraadt 149: exit(0);
150: }
151:
152: if (Gflag) {
153: group(pw, nflag);
154: exit(0);
155: }
156:
157: if (pflag) {
158: pretty(pw);
159: exit(0);
160: }
161:
162: if (pw)
163: user(pw);
164: else
165: current();
166: exit(0);
167: }
168:
169: void
1.13 deraadt 170: pretty(struct passwd *pw)
1.1 deraadt 171: {
172: struct group *gr;
1.4 deraadt 173: uid_t eid, rid;
1.1 deraadt 174: char *login;
175:
176: if (pw) {
177: (void)printf("uid\t%s\n", pw->pw_name);
178: (void)printf("groups\t");
179: group(pw, 1);
180: } else {
181: if ((login = getlogin()) == NULL)
1.6 mickey 182: err(1, "getlogin");
1.1 deraadt 183:
184: pw = getpwuid(rid = getuid());
185: if (pw == NULL || strcmp(login, pw->pw_name))
186: (void)printf("login\t%s\n", login);
187: if (pw)
188: (void)printf("uid\t%s\n", pw->pw_name);
189: else
190: (void)printf("uid\t%u\n", rid);
1.20 okan 191:
1.9 deraadt 192: if ((eid = geteuid()) != rid) {
1.4 deraadt 193: if ((pw = getpwuid(eid)))
1.7 aaron 194: (void)printf("euid\t%s\n", pw->pw_name);
1.1 deraadt 195: else
1.7 aaron 196: (void)printf("euid\t%u\n", eid);
1.9 deraadt 197: }
198: if ((rid = getgid()) != (eid = getegid())) {
1.4 deraadt 199: if ((gr = getgrgid(rid)))
1.1 deraadt 200: (void)printf("rgid\t%s\n", gr->gr_name);
201: else
202: (void)printf("rgid\t%u\n", rid);
1.9 deraadt 203: }
1.1 deraadt 204: (void)printf("groups\t");
205: group(NULL, 1);
206: }
1.23 ! millert 207: if (pw != NULL && pw->pw_class != NULL && *pw->pw_class != '\0')
! 208: (void)printf("class\t%s\n", pw->pw_class);
1.1 deraadt 209: }
210:
211: void
1.13 deraadt 212: current(void)
1.1 deraadt 213: {
214: struct group *gr;
215: struct passwd *pw;
1.4 deraadt 216: int cnt, ngroups;
1.14 tdeval 217: uid_t uid, euid;
1.22 deraadt 218: gid_t groups[NGROUPS_MAX], gid, egid, lastgid;
1.21 guenther 219: char *prefix;
1.1 deraadt 220:
1.14 tdeval 221: uid = getuid();
222: (void)printf("uid=%u", uid);
223: if ((pw = getpwuid(uid)))
1.1 deraadt 224: (void)printf("(%s)", pw->pw_name);
1.14 tdeval 225: if ((euid = geteuid()) != uid) {
226: (void)printf(" euid=%u", euid);
227: if ((pw = getpwuid(euid)))
1.1 deraadt 228: (void)printf("(%s)", pw->pw_name);
229: }
1.14 tdeval 230: gid = getgid();
231: (void)printf(" gid=%u", gid);
232: if ((gr = getgrgid(gid)))
1.1 deraadt 233: (void)printf("(%s)", gr->gr_name);
1.14 tdeval 234: if ((egid = getegid()) != gid) {
235: (void)printf(" egid=%u", egid);
236: if ((gr = getgrgid(egid)))
1.1 deraadt 237: (void)printf("(%s)", gr->gr_name);
238: }
1.22 deraadt 239: if ((ngroups = getgroups(NGROUPS_MAX, groups))) {
1.21 guenther 240: for (prefix = " groups=", lastgid = (gid_t)-1, cnt = 0;
241: cnt < ngroups; prefix = ", ", lastgid = gid) {
1.4 deraadt 242: gid = groups[cnt++];
243: if (lastgid == gid)
1.1 deraadt 244: continue;
1.21 guenther 245: (void)printf("%s%u", prefix, gid);
1.4 deraadt 246: if ((gr = getgrgid(gid)))
1.1 deraadt 247: (void)printf("(%s)", gr->gr_name);
248: }
249: }
250: (void)printf("\n");
251: }
252:
253: void
1.13 deraadt 254: user(struct passwd *pw)
1.1 deraadt 255: {
1.22 deraadt 256: gid_t gid, groups[NGROUPS_MAX + 1];
1.14 tdeval 257: int cnt, ngroups;
258: uid_t uid;
1.10 mpech 259: struct group *gr;
1.21 guenther 260: char *prefix;
1.1 deraadt 261:
1.14 tdeval 262: uid = pw->pw_uid;
263: (void)printf("uid=%u(%s)", uid, pw->pw_name);
1.1 deraadt 264: (void)printf(" gid=%u", pw->pw_gid);
1.4 deraadt 265: if ((gr = getgrgid(pw->pw_gid)))
1.1 deraadt 266: (void)printf("(%s)", gr->gr_name);
1.22 deraadt 267: ngroups = NGROUPS_MAX + 1;
1.1 deraadt 268: (void) getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups);
1.21 guenther 269: prefix = " groups=";
1.14 tdeval 270: for (cnt = 0; cnt < ngroups;) {
271: gid = groups[cnt];
1.21 guenther 272: (void)printf("%s%u", prefix, gid);
273: prefix = ", ";
1.14 tdeval 274: if ((gr = getgrgid(gid)))
1.1 deraadt 275: (void)printf("(%s)", gr->gr_name);
1.14 tdeval 276: /* Skip same gid entries. */
277: while (++cnt < ngroups && gid == groups[cnt]);
1.1 deraadt 278: }
279: (void)printf("\n");
280: }
281:
282: void
1.13 deraadt 283: group(struct passwd *pw, int nflag)
1.1 deraadt 284: {
1.14 tdeval 285: int cnt, ngroups;
1.22 deraadt 286: gid_t gid, groups[NGROUPS_MAX + 1];
1.1 deraadt 287: struct group *gr;
1.21 guenther 288: char *prefix;
1.1 deraadt 289:
290: if (pw) {
1.22 deraadt 291: ngroups = NGROUPS_MAX + 1;
1.1 deraadt 292: (void) getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups);
293: } else {
294: groups[0] = getgid();
1.22 deraadt 295: ngroups = getgroups(NGROUPS_MAX, groups + 1) + 1;
1.1 deraadt 296: }
1.21 guenther 297: prefix = "";
1.14 tdeval 298: for (cnt = 0; cnt < ngroups;) {
299: gid = groups[cnt];
1.1 deraadt 300: if (nflag) {
1.14 tdeval 301: if ((gr = getgrgid(gid)))
1.21 guenther 302: (void)printf("%s%s", prefix, gr->gr_name);
1.1 deraadt 303: else
1.21 guenther 304: (void)printf("%s%u", prefix, gid);
1.1 deraadt 305: } else {
1.21 guenther 306: (void)printf("%s%u", prefix, gid);
1.1 deraadt 307: }
1.21 guenther 308: prefix = " ";
1.14 tdeval 309: /* Skip same gid entries. */
310: while (++cnt < ngroups && gid == groups[cnt]);
1.1 deraadt 311: }
312: (void)printf("\n");
313: }
314:
315: struct passwd *
1.13 deraadt 316: who(char *u)
1.1 deraadt 317: {
318: struct passwd *pw;
1.14 tdeval 319: uid_t uid;
1.16 pvalchev 320: const char *errstr;
1.1 deraadt 321:
322: /*
323: * Translate user argument into a pw pointer. First, try to
324: * get it as specified. If that fails, try it as a number.
325: */
1.4 deraadt 326: if ((pw = getpwnam(u)))
1.1 deraadt 327: return(pw);
1.16 pvalchev 328: uid = strtonum(u, 0, UID_MAX, &errstr);
329: if (!errstr && (pw = getpwuid(uid)))
1.1 deraadt 330: return(pw);
1.6 mickey 331: errx(1, "%s: No such user", u);
1.1 deraadt 332: /* NOTREACHED */
333: }
334:
335: void
1.13 deraadt 336: usage(void)
1.1 deraadt 337: {
1.20 okan 338: if (strcmp(getprogname(), "groups") == 0) {
339: (void)fprintf(stderr, "usage: groups [user]\n");
340: } else if (strcmp(getprogname(), "whoami") == 0) {
341: (void)fprintf(stderr, "usage: whoami\n");
342: } else {
343: (void)fprintf(stderr, "usage: id [user]\n");
1.23 ! millert 344: (void)fprintf(stderr, " id -c [user]\n");
1.20 okan 345: (void)fprintf(stderr, " id -G [-n] [user]\n");
346: (void)fprintf(stderr, " id -g [-nr] [user]\n");
347: (void)fprintf(stderr, " id -p [user]\n");
348: (void)fprintf(stderr, " id -u [-nr] [user]\n");
349: }
1.1 deraadt 350: exit(1);
351: }