Annotation of src/usr.bin/id/id.c, Revision 1.28
1.28 ! tedu 1: /* $OpenBSD: id.c,v 1.27 2017/05/30 15:07:01 tedu 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: case '?':
111: default:
112: usage();
113: }
114: argc -= optind;
115: argv += optind;
116:
1.27 tedu 117: switch (cflag + Gflag + gflag + pflag + Rflag + uflag) {
1.1 deraadt 118: case 1:
119: break;
120: case 0:
121: if (!nflag && !rflag)
122: break;
123: /* FALLTHROUGH */
124: default:
125: usage();
126: }
127:
1.20 okan 128: if (strcmp(opts, "") != 0 && argc > 1)
129: usage();
1.27 tedu 130:
131: if (Rflag) {
132: printf("%d\n", getrtable());
133: exit(0);
134: }
1.20 okan 135:
1.1 deraadt 136: pw = *argv ? who(*argv) : NULL;
137:
1.23 millert 138: if (cflag) {
139: if (pw == NULL)
140: pw = getpwuid(getuid());
141: if (pw != NULL && pw->pw_class != NULL && *pw->pw_class != '\0')
142: (void)printf("%s\n", pw->pw_class);
143: else
144: (void)printf("%s\n", LOGIN_DEFCLASS);
145: exit(0);
146: }
147:
1.1 deraadt 148: if (gflag) {
1.14 tdeval 149: gid = pw ? pw->pw_gid : rflag ? getgid() : getegid();
150: if (nflag && (gr = getgrgid(gid)))
1.1 deraadt 151: (void)printf("%s\n", gr->gr_name);
152: else
1.14 tdeval 153: (void)printf("%u\n", gid);
1.1 deraadt 154: exit(0);
155: }
156:
157: if (uflag) {
1.14 tdeval 158: uid = pw ? pw->pw_uid : rflag ? getuid() : geteuid();
159: if (nflag && (pw = getpwuid(uid)))
1.1 deraadt 160: (void)printf("%s\n", pw->pw_name);
161: else
1.14 tdeval 162: (void)printf("%u\n", uid);
1.1 deraadt 163: exit(0);
164: }
165:
166: if (Gflag) {
167: group(pw, nflag);
168: exit(0);
169: }
170:
171: if (pflag) {
172: pretty(pw);
173: exit(0);
174: }
175:
176: if (pw)
177: user(pw);
178: else
179: current();
180: exit(0);
181: }
182:
183: void
1.13 deraadt 184: pretty(struct passwd *pw)
1.1 deraadt 185: {
186: struct group *gr;
1.4 deraadt 187: uid_t eid, rid;
1.1 deraadt 188: char *login;
189:
190: if (pw) {
191: (void)printf("uid\t%s\n", pw->pw_name);
192: (void)printf("groups\t");
193: group(pw, 1);
194: } else {
195: if ((login = getlogin()) == NULL)
1.6 mickey 196: err(1, "getlogin");
1.1 deraadt 197:
198: pw = getpwuid(rid = getuid());
199: if (pw == NULL || strcmp(login, pw->pw_name))
200: (void)printf("login\t%s\n", login);
201: if (pw)
202: (void)printf("uid\t%s\n", pw->pw_name);
203: else
204: (void)printf("uid\t%u\n", rid);
1.20 okan 205:
1.9 deraadt 206: if ((eid = geteuid()) != rid) {
1.4 deraadt 207: if ((pw = getpwuid(eid)))
1.7 aaron 208: (void)printf("euid\t%s\n", pw->pw_name);
1.1 deraadt 209: else
1.7 aaron 210: (void)printf("euid\t%u\n", eid);
1.9 deraadt 211: }
212: if ((rid = getgid()) != (eid = getegid())) {
1.4 deraadt 213: if ((gr = getgrgid(rid)))
1.1 deraadt 214: (void)printf("rgid\t%s\n", gr->gr_name);
215: else
216: (void)printf("rgid\t%u\n", rid);
1.9 deraadt 217: }
1.1 deraadt 218: (void)printf("groups\t");
219: group(NULL, 1);
220: }
1.23 millert 221: if (pw != NULL && pw->pw_class != NULL && *pw->pw_class != '\0')
222: (void)printf("class\t%s\n", pw->pw_class);
1.1 deraadt 223: }
224:
225: void
1.13 deraadt 226: current(void)
1.1 deraadt 227: {
228: struct group *gr;
229: struct passwd *pw;
1.4 deraadt 230: int cnt, ngroups;
1.14 tdeval 231: uid_t uid, euid;
1.22 deraadt 232: gid_t groups[NGROUPS_MAX], gid, egid, lastgid;
1.21 guenther 233: char *prefix;
1.1 deraadt 234:
1.14 tdeval 235: uid = getuid();
236: (void)printf("uid=%u", uid);
237: if ((pw = getpwuid(uid)))
1.1 deraadt 238: (void)printf("(%s)", pw->pw_name);
1.14 tdeval 239: if ((euid = geteuid()) != uid) {
240: (void)printf(" euid=%u", euid);
241: if ((pw = getpwuid(euid)))
1.1 deraadt 242: (void)printf("(%s)", pw->pw_name);
243: }
1.14 tdeval 244: gid = getgid();
245: (void)printf(" gid=%u", gid);
246: if ((gr = getgrgid(gid)))
1.1 deraadt 247: (void)printf("(%s)", gr->gr_name);
1.14 tdeval 248: if ((egid = getegid()) != gid) {
249: (void)printf(" egid=%u", egid);
250: if ((gr = getgrgid(egid)))
1.1 deraadt 251: (void)printf("(%s)", gr->gr_name);
252: }
1.22 deraadt 253: if ((ngroups = getgroups(NGROUPS_MAX, groups))) {
1.21 guenther 254: for (prefix = " groups=", lastgid = (gid_t)-1, cnt = 0;
255: cnt < ngroups; prefix = ", ", lastgid = gid) {
1.4 deraadt 256: gid = groups[cnt++];
257: if (lastgid == gid)
1.1 deraadt 258: continue;
1.21 guenther 259: (void)printf("%s%u", prefix, gid);
1.4 deraadt 260: if ((gr = getgrgid(gid)))
1.1 deraadt 261: (void)printf("(%s)", gr->gr_name);
262: }
263: }
264: (void)printf("\n");
265: }
266:
267: void
1.13 deraadt 268: user(struct passwd *pw)
1.1 deraadt 269: {
1.22 deraadt 270: gid_t gid, groups[NGROUPS_MAX + 1];
1.14 tdeval 271: int cnt, ngroups;
272: uid_t uid;
1.10 mpech 273: struct group *gr;
1.21 guenther 274: char *prefix;
1.1 deraadt 275:
1.14 tdeval 276: uid = pw->pw_uid;
277: (void)printf("uid=%u(%s)", uid, pw->pw_name);
1.1 deraadt 278: (void)printf(" gid=%u", pw->pw_gid);
1.4 deraadt 279: if ((gr = getgrgid(pw->pw_gid)))
1.1 deraadt 280: (void)printf("(%s)", gr->gr_name);
1.22 deraadt 281: ngroups = NGROUPS_MAX + 1;
1.1 deraadt 282: (void) getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups);
1.21 guenther 283: prefix = " groups=";
1.14 tdeval 284: for (cnt = 0; cnt < ngroups;) {
285: gid = groups[cnt];
1.21 guenther 286: (void)printf("%s%u", prefix, gid);
287: prefix = ", ";
1.14 tdeval 288: if ((gr = getgrgid(gid)))
1.1 deraadt 289: (void)printf("(%s)", gr->gr_name);
1.14 tdeval 290: /* Skip same gid entries. */
1.24 deraadt 291: while (++cnt < ngroups && gid == groups[cnt])
292: ;
1.1 deraadt 293: }
294: (void)printf("\n");
295: }
296:
297: void
1.13 deraadt 298: group(struct passwd *pw, int nflag)
1.1 deraadt 299: {
1.14 tdeval 300: int cnt, ngroups;
1.22 deraadt 301: gid_t gid, groups[NGROUPS_MAX + 1];
1.1 deraadt 302: struct group *gr;
1.21 guenther 303: char *prefix;
1.1 deraadt 304:
305: if (pw) {
1.22 deraadt 306: ngroups = NGROUPS_MAX + 1;
1.1 deraadt 307: (void) getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups);
308: } else {
309: groups[0] = getgid();
1.22 deraadt 310: ngroups = getgroups(NGROUPS_MAX, groups + 1) + 1;
1.1 deraadt 311: }
1.21 guenther 312: prefix = "";
1.14 tdeval 313: for (cnt = 0; cnt < ngroups;) {
314: gid = groups[cnt];
1.1 deraadt 315: if (nflag) {
1.14 tdeval 316: if ((gr = getgrgid(gid)))
1.21 guenther 317: (void)printf("%s%s", prefix, gr->gr_name);
1.1 deraadt 318: else
1.21 guenther 319: (void)printf("%s%u", prefix, gid);
1.1 deraadt 320: } else {
1.21 guenther 321: (void)printf("%s%u", prefix, gid);
1.1 deraadt 322: }
1.21 guenther 323: prefix = " ";
1.14 tdeval 324: /* Skip same gid entries. */
1.24 deraadt 325: while (++cnt < ngroups && gid == groups[cnt])
326: ;
1.1 deraadt 327: }
328: (void)printf("\n");
329: }
330:
331: struct passwd *
1.13 deraadt 332: who(char *u)
1.1 deraadt 333: {
334: struct passwd *pw;
1.14 tdeval 335: uid_t uid;
1.16 pvalchev 336: const char *errstr;
1.1 deraadt 337:
338: /*
339: * Translate user argument into a pw pointer. First, try to
340: * get it as specified. If that fails, try it as a number.
341: */
1.4 deraadt 342: if ((pw = getpwnam(u)))
1.1 deraadt 343: return(pw);
1.16 pvalchev 344: uid = strtonum(u, 0, UID_MAX, &errstr);
345: if (!errstr && (pw = getpwuid(uid)))
1.1 deraadt 346: return(pw);
1.6 mickey 347: errx(1, "%s: No such user", u);
1.1 deraadt 348: /* NOTREACHED */
349: }
350:
351: void
1.13 deraadt 352: usage(void)
1.1 deraadt 353: {
1.20 okan 354: if (strcmp(getprogname(), "groups") == 0) {
355: (void)fprintf(stderr, "usage: groups [user]\n");
356: } else if (strcmp(getprogname(), "whoami") == 0) {
357: (void)fprintf(stderr, "usage: whoami\n");
358: } else {
359: (void)fprintf(stderr, "usage: id [user]\n");
1.23 millert 360: (void)fprintf(stderr, " id -c [user]\n");
1.20 okan 361: (void)fprintf(stderr, " id -G [-n] [user]\n");
362: (void)fprintf(stderr, " id -g [-nr] [user]\n");
363: (void)fprintf(stderr, " id -p [user]\n");
1.28 ! tedu 364: (void)fprintf(stderr, " id -R\n");
1.20 okan 365: (void)fprintf(stderr, " id -u [-nr] [user]\n");
366: }
1.1 deraadt 367: exit(1);
368: }