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