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