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