id.c revision 259065
150276Speter/*- 2184989Srafan * Copyright (c) 1991, 1993 350276Speter * The Regents of the University of California. All rights reserved. 450276Speter * 550276Speter * Redistribution and use in source and binary forms, with or without 650276Speter * modification, are permitted provided that the following conditions 750276Speter * are met: 850276Speter * 1. Redistributions of source code must retain the above copyright 950276Speter * notice, this list of conditions and the following disclaimer. 1050276Speter * 2. Redistributions in binary form must reproduce the above copyright 1150276Speter * notice, this list of conditions and the following disclaimer in the 1250276Speter * documentation and/or other materials provided with the distribution. 1350276Speter * 4. Neither the name of the University nor the names of its contributors 1450276Speter * may be used to endorse or promote products derived from this software 1550276Speter * without specific prior written permission. 1650276Speter * 1750276Speter * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 1850276Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1950276Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2050276Speter * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2150276Speter * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2250276Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2350276Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2450276Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2550276Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2650276Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2750276Speter * SUCH DAMAGE. 2850276Speter */ 2950276Speter 30166124Srafan#ifndef lint 3150276Speterstatic const char copyright[] = 3250276Speter"@(#) Copyright (c) 1991, 1993\n\ 3350276Speter The Regents of the University of California. All rights reserved.\n"; 3450276Speter#endif /* not lint */ 35184989Srafan 3650276Speter#ifndef lint 3750276Speter#if 0 38166124Srafanstatic char sccsid[] = "@(#)id.c 8.2 (Berkeley) 2/16/94"; 39166124Srafan#endif 40166124Srafan#endif /* not lint */ 41166124Srafan#include <sys/cdefs.h> 42166124Srafan__FBSDID("$FreeBSD: releng/10.0/usr.bin/id/id.c 227203 2011-11-06 09:09:45Z ed $"); 43166124Srafan 44166124Srafan#include <sys/param.h> 45166124Srafan#include <sys/mac.h> 46166124Srafan 47166124Srafan#ifdef USE_BSM_AUDIT 48166124Srafan#include <bsm/audit.h> 49166124Srafan#endif 50166124Srafan 51166124Srafan#include <err.h> 52166124Srafan#include <errno.h> 53166124Srafan#include <grp.h> 54166124Srafan#include <pwd.h> 55166124Srafan#include <stdio.h> 56166124Srafan#include <stdlib.h> 57166124Srafan#include <string.h> 58166124Srafan#include <unistd.h> 59166124Srafan 60166124Srafanstatic void id_print(struct passwd *, int, int, int); 61166124Srafanstatic void pline(struct passwd *); 6250276Speterstatic void pretty(struct passwd *); 6350276Speter#ifdef USE_BSM_AUDIT 6476726Speterstatic void auditid(void); 6550276Speter#endif 6650276Speterstatic void group(struct passwd *, int); 6750276Speterstatic void maclabel(void); 6850276Speterstatic void usage(void); 6950276Speterstatic struct passwd *who(char *); 7050276Speter 7150276Speterstatic int isgroups, iswhoami; 7250276Speter 7350276Speterint 7450276Spetermain(int argc, char *argv[]) 7550276Speter{ 7650276Speter struct group *gr; 7750276Speter struct passwd *pw; 78166124Srafan int Gflag, Mflag, Pflag, ch, gflag, id, nflag, pflag, rflag, uflag; 79166124Srafan int Aflag, cflag; 8050276Speter int error; 8150276Speter const char *myname; 82166124Srafan char loginclass[MAXLOGNAME]; 8350276Speter 8450276Speter Gflag = Mflag = Pflag = gflag = nflag = pflag = rflag = uflag = 0; 8550276Speter Aflag = cflag = 0; 86166124Srafan 8750276Speter myname = strrchr(argv[0], '/'); 8850276Speter myname = (myname != NULL) ? myname + 1 : argv[0]; 8950276Speter if (strcmp(myname, "groups") == 0) { 9050276Speter isgroups = 1; 9150276Speter Gflag = nflag = 1; 92166124Srafan } 93166124Srafan else if (strcmp(myname, "whoami") == 0) { 94166124Srafan iswhoami = 1; 9550276Speter uflag = nflag = 1; 9650276Speter } 97166124Srafan 98166124Srafan while ((ch = getopt(argc, argv, 9950276Speter (isgroups || iswhoami) ? "" : "APGMacgnpru")) != -1) 10050276Speter switch(ch) { 10150276Speter#ifdef USE_BSM_AUDIT 10250276Speter case 'A': 103166124Srafan Aflag = 1; 104166124Srafan break; 105166124Srafan#endif 10650276Speter case 'G': 10750276Speter Gflag = 1; 108166124Srafan break; 10950276Speter case 'M': 11050276Speter Mflag = 1; 111166124Srafan break; 11250276Speter case 'P': 11350276Speter Pflag = 1; 11450276Speter break; 11550276Speter case 'a': 11650276Speter break; 11750276Speter case 'c': 11850276Speter cflag = 1; 11950276Speter break; 12050276Speter case 'g': 12150276Speter gflag = 1; 122166124Srafan break; 123166124Srafan case 'n': 12450276Speter nflag = 1; 12550276Speter break; 12650276Speter case 'p': 12750276Speter pflag = 1; 12850276Speter break; 129166124Srafan case 'r': 13050276Speter rflag = 1; 131166124Srafan break; 13250276Speter case 'u': 13350276Speter uflag = 1; 134166124Srafan break; 13550276Speter case '?': 13650276Speter default: 13750276Speter usage(); 138166124Srafan } 13950276Speter argc -= optind; 140166124Srafan argv += optind; 141166124Srafan 14250276Speter if (iswhoami && argc > 0) 14350276Speter usage(); 14450276Speter 14550276Speter switch(Aflag + Gflag + Mflag + Pflag + gflag + pflag + uflag) { 14650276Speter case 1: 14750276Speter break; 14850276Speter case 0: 14950276Speter if (!nflag && !rflag) 15050276Speter break; 15150276Speter /* FALLTHROUGH */ 15250276Speter default: 15350276Speter usage(); 15450276Speter } 155166124Srafan 156166124Srafan pw = *argv ? who(*argv) : NULL; 15750276Speter 15850276Speter if (Mflag && pw != NULL) 15950276Speter usage(); 16050276Speter 16150276Speter#ifdef USE_BSM_AUDIT 162166124Srafan if (Aflag) { 163166124Srafan auditid(); 164166124Srafan exit(0); 16550276Speter } 16650276Speter#endif 167166124Srafan 16850276Speter if (cflag) { 169166124Srafan error = getloginclass(loginclass, sizeof(loginclass)); 17050276Speter if (error != 0) 17150276Speter err(1, "loginclass"); 17250276Speter (void)printf("%s\n", loginclass); 173166124Srafan exit(0); 17450276Speter } 17550276Speter 176166124Srafan if (gflag) { 17750276Speter id = pw ? pw->pw_gid : rflag ? getgid() : getegid(); 178166124Srafan if (nflag && (gr = getgrgid(id))) 17950276Speter (void)printf("%s\n", gr->gr_name); 180166124Srafan else 181166124Srafan (void)printf("%u\n", id); 18250276Speter exit(0); 18350276Speter } 184166124Srafan 185166124Srafan if (uflag) { 18650276Speter id = pw ? pw->pw_uid : rflag ? getuid() : geteuid(); 187166124Srafan if (nflag && (pw = getpwuid(id))) 18850276Speter (void)printf("%s\n", pw->pw_name); 189174993Srafan else 19050276Speter (void)printf("%u\n", id); 191174993Srafan exit(0); 19250276Speter } 19350276Speter 19450276Speter if (Gflag) { 19550276Speter group(pw, nflag); 196166124Srafan exit(0); 19750276Speter } 19850276Speter 199166124Srafan if (Mflag) { 20050276Speter maclabel(); 201166124Srafan exit(0); 20250276Speter } 20350276Speter 20450276Speter if (Pflag) { 20550276Speter pline(pw); 20650276Speter exit(0); 207166124Srafan } 20850276Speter 20950276Speter if (pflag) { 21050276Speter pretty(pw); 21150276Speter exit(0); 212166124Srafan } 21350276Speter 21450276Speter if (pw) { 215166124Srafan id_print(pw, 1, 0, 0); 216166124Srafan } 21750276Speter else { 218166124Srafan id = getuid(); 21950276Speter pw = getpwuid(id); 22050276Speter id_print(pw, 0, 1, 1); 221166124Srafan } 222166124Srafan exit(0); 22350276Speter} 224166124Srafan 225166124Srafanstatic void 22650276Speterpretty(struct passwd *pw) 227166124Srafan{ 22850276Speter struct group *gr; 22950276Speter u_int eid, rid; 230166124Srafan char *login; 231166124Srafan 23250276Speter if (pw) { 23350276Speter (void)printf("uid\t%s\n", pw->pw_name); 234166124Srafan (void)printf("groups\t"); 235166124Srafan group(pw, 1); 23650276Speter } else { 237184989Srafan if ((login = getlogin()) == NULL) 238184989Srafan err(1, "getlogin"); 239184989Srafan 240184989Srafan pw = getpwuid(rid = getuid()); 241184989Srafan if (pw == NULL || strcmp(login, pw->pw_name)) 242184989Srafan (void)printf("login\t%s\n", login); 243184989Srafan if (pw) 244184989Srafan (void)printf("uid\t%s\n", pw->pw_name); 245184989Srafan else 246184989Srafan (void)printf("uid\t%u\n", rid); 24750276Speter 24850276Speter if ((eid = geteuid()) != rid) { 24950276Speter if ((pw = getpwuid(eid))) 25050276Speter (void)printf("euid\t%s\n", pw->pw_name); 25150276Speter else 25250276Speter (void)printf("euid\t%u\n", eid); 25350276Speter } 25450276Speter if ((rid = getgid()) != (eid = getegid())) { 25550276Speter if ((gr = getgrgid(rid))) 25650276Speter (void)printf("rgid\t%s\n", gr->gr_name); 25750276Speter else 25850276Speter (void)printf("rgid\t%u\n", rid); 259166124Srafan } 260166124Srafan (void)printf("groups\t"); 261166124Srafan group(NULL, 1); 26250276Speter } 263166124Srafan} 264166124Srafan 26550276Speterstatic void 266166124Srafanid_print(struct passwd *pw, int use_ggl, int p_euid, int p_egid) 267166124Srafan{ 26850276Speter struct group *gr; 26950276Speter gid_t gid, egid, lastgid; 270166124Srafan uid_t uid, euid; 27150276Speter int cnt, ngroups; 27250276Speter long ngroups_max; 273166124Srafan gid_t *groups; 27450276Speter const char *fmt; 27550276Speter 27650276Speter if (pw != NULL) { 27750276Speter uid = pw->pw_uid; 27850276Speter gid = pw->pw_gid; 279166124Srafan } 28050276Speter else { 281166124Srafan uid = getuid(); 28250276Speter gid = getgid(); 283166124Srafan } 28450276Speter 28550276Speter ngroups_max = sysconf(_SC_NGROUPS_MAX) + 1; 28650276Speter if ((groups = malloc(sizeof(gid_t) * ngroups_max)) == NULL) 28750276Speter err(1, "malloc"); 28850276Speter 28950276Speter if (use_ggl && pw != NULL) { 290166124Srafan ngroups = ngroups_max; 291166124Srafan getgrouplist(pw->pw_name, gid, groups, &ngroups); 292166124Srafan } 293166124Srafan else { 294166124Srafan ngroups = getgroups(ngroups_max, groups); 295166124Srafan } 29650276Speter 29776726Speter if (pw != NULL) 298166124Srafan printf("uid=%u(%s)", uid, pw->pw_name); 299166124Srafan else 30050276Speter printf("uid=%u", getuid()); 30150276Speter printf(" gid=%u", gid); 302174993Srafan if ((gr = getgrgid(gid))) 303166124Srafan (void)printf("(%s)", gr->gr_name); 304166124Srafan if (p_euid && (euid = geteuid()) != uid) { 30550276Speter (void)printf(" euid=%u", euid); 30650276Speter if ((pw = getpwuid(euid))) 307174993Srafan (void)printf("(%s)", pw->pw_name); 30850276Speter } 309166124Srafan if (p_egid && (egid = getegid()) != gid) { 31050276Speter (void)printf(" egid=%u", egid); 31150276Speter if ((gr = getgrgid(egid))) 31250276Speter (void)printf("(%s)", gr->gr_name); 31350276Speter } 31450276Speter fmt = " groups=%u"; 31550276Speter for (lastgid = -1, cnt = 0; cnt < ngroups; ++cnt) { 31650276Speter if (lastgid == (gid = groups[cnt])) 31750276Speter continue; 318166124Srafan printf(fmt, gid); 319166124Srafan fmt = ",%u"; 32050276Speter if ((gr = getgrgid(gid))) 32150276Speter printf("(%s)", gr->gr_name); 32250276Speter lastgid = gid; 32350276Speter } 32450276Speter printf("\n"); 32550276Speter free(groups); 32650276Speter} 32750276Speter 32850276Speter#ifdef USE_BSM_AUDIT 32950276Speterstatic void 33050276Speterauditid(void) 33150276Speter{ 33276726Speter auditinfo_t auditinfo; 333166124Srafan auditinfo_addr_t ainfo_addr; 33450276Speter int ret, extended; 335166124Srafan 336166124Srafan extended = 0; 337166124Srafan ret = getaudit(&auditinfo); 33850276Speter if (ret < 0 && errno == E2BIG) { 33950276Speter if (getaudit_addr(&ainfo_addr, sizeof(ainfo_addr)) < 0) 340166124Srafan err(1, "getaudit_addr"); 34150276Speter extended = 1; 342166124Srafan } else if (ret < 0) 343166124Srafan err(1, "getaudit"); 344166124Srafan if (extended != 0) { 34550276Speter (void) printf("auid=%d\n" 34650276Speter "mask.success=0x%08x\n" 347166124Srafan "mask.failure=0x%08x\n" 34850276Speter "asid=%d\n" 34950276Speter "termid_addr.port=0x%08x\n" 35050276Speter "termid_addr.addr[0]=0x%08x\n" 35150276Speter "termid_addr.addr[1]=0x%08x\n" 35250276Speter "termid_addr.addr[2]=0x%08x\n" 35350276Speter "termid_addr.addr[3]=0x%08x\n", 35450276Speter ainfo_addr.ai_auid, ainfo_addr.ai_mask.am_success, 35550276Speter ainfo_addr.ai_mask.am_failure, ainfo_addr.ai_asid, 35650276Speter ainfo_addr.ai_termid.at_port, 357166124Srafan ainfo_addr.ai_termid.at_addr[0], 358166124Srafan ainfo_addr.ai_termid.at_addr[1], 359166124Srafan ainfo_addr.ai_termid.at_addr[2], 360166124Srafan ainfo_addr.ai_termid.at_addr[3]); 361166124Srafan } else { 36250276Speter (void) printf("auid=%d\n" 36376726Speter "mask.success=0x%08x\n" 364166124Srafan "mask.failure=0x%08x\n" 36550276Speter "asid=%d\n" 36650276Speter "termid.port=0x%08x\n" 36750276Speter "termid.machine=0x%08x\n", 368166124Srafan auditinfo.ai_auid, auditinfo.ai_mask.am_success, 369166124Srafan auditinfo.ai_mask.am_failure, 370166124Srafan auditinfo.ai_asid, auditinfo.ai_termid.port, 371166124Srafan auditinfo.ai_termid.machine); 37250276Speter } 37350276Speter} 374166124Srafan#endif 37550276Speter 376166124Srafanstatic void 37750276Spetergroup(struct passwd *pw, int nflag) 378166124Srafan{ 379166124Srafan struct group *gr; 380166124Srafan int cnt, id, lastid, ngroups; 381166124Srafan long ngroups_max; 382166124Srafan gid_t *groups; 38350276Speter const char *fmt; 38450276Speter 385166124Srafan ngroups_max = sysconf(_SC_NGROUPS_MAX) + 1; 38650276Speter if ((groups = malloc(sizeof(gid_t) * (ngroups_max))) == NULL) 38750276Speter err(1, "malloc"); 38850276Speter 38950276Speter if (pw) { 39050276Speter ngroups = ngroups_max; 39150276Speter (void) getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups); 39250276Speter } else { 39350276Speter ngroups = getgroups(ngroups_max, groups); 39476726Speter } 395166124Srafan fmt = nflag ? "%s" : "%u"; 39650276Speter for (lastid = -1, cnt = 0; cnt < ngroups; ++cnt) { 397166124Srafan if (lastid == (id = groups[cnt])) 398166124Srafan continue; 39950276Speter if (nflag) { 40050276Speter if ((gr = getgrgid(id))) 40150276Speter (void)printf(fmt, gr->gr_name); 40250276Speter else 40350276Speter (void)printf(*fmt == ' ' ? " %u" : "%u", 40450276Speter id); 40550276Speter fmt = " %s"; 40650276Speter } else { 40750276Speter (void)printf(fmt, id); 40850276Speter fmt = " %u"; 40976726Speter } 410166124Srafan lastid = id; 41150276Speter } 412166124Srafan (void)printf("\n"); 413166124Srafan free(groups); 414166124Srafan} 41550276Speter 41650276Speterstatic void 41750276Spetermaclabel(void) 418{ 419 char *string; 420 mac_t label; 421 int error; 422 423 error = mac_prepare_process_label(&label); 424 if (error == -1) 425 errx(1, "mac_prepare_type: %s", strerror(errno)); 426 427 error = mac_get_proc(label); 428 if (error == -1) 429 errx(1, "mac_get_proc: %s", strerror(errno)); 430 431 error = mac_to_text(label, &string); 432 if (error == -1) 433 errx(1, "mac_to_text: %s", strerror(errno)); 434 435 (void)printf("%s\n", string); 436 mac_free(label); 437 free(string); 438} 439 440static struct passwd * 441who(char *u) 442{ 443 struct passwd *pw; 444 long id; 445 char *ep; 446 447 /* 448 * Translate user argument into a pw pointer. First, try to 449 * get it as specified. If that fails, try it as a number. 450 */ 451 if ((pw = getpwnam(u))) 452 return(pw); 453 id = strtol(u, &ep, 10); 454 if (*u && !*ep && (pw = getpwuid(id))) 455 return(pw); 456 errx(1, "%s: no such user", u); 457 /* NOTREACHED */ 458} 459 460static void 461pline(struct passwd *pw) 462{ 463 464 if (!pw) { 465 if ((pw = getpwuid(getuid())) == NULL) 466 err(1, "getpwuid"); 467 } 468 469 (void)printf("%s:%s:%d:%d:%s:%ld:%ld:%s:%s:%s\n", pw->pw_name, 470 pw->pw_passwd, pw->pw_uid, pw->pw_gid, pw->pw_class, 471 (long)pw->pw_change, (long)pw->pw_expire, pw->pw_gecos, 472 pw->pw_dir, pw->pw_shell); 473} 474 475 476static void 477usage(void) 478{ 479 480 if (isgroups) 481 (void)fprintf(stderr, "usage: groups [user]\n"); 482 else if (iswhoami) 483 (void)fprintf(stderr, "usage: whoami\n"); 484 else 485 (void)fprintf(stderr, "%s\n%s%s\n%s\n%s\n%s\n%s\n%s\n%s\n", 486 "usage: id [user]", 487#ifdef USE_BSM_AUDIT 488 " id -A\n", 489#else 490 "", 491#endif 492 " id -G [-n] [user]", 493 " id -M", 494 " id -P [user]", 495 " id -c", 496 " id -g [-nr] [user]", 497 " id -p [user]", 498 " id -u [-nr] [user]"); 499 exit(1); 500} 501