11590Srgrimes/*- 21590Srgrimes * Copyright (c) 1991, 1993 31590Srgrimes * The Regents of the University of California. All rights reserved. 41590Srgrimes * 51590Srgrimes * Redistribution and use in source and binary forms, with or without 61590Srgrimes * modification, are permitted provided that the following conditions 71590Srgrimes * are met: 81590Srgrimes * 1. Redistributions of source code must retain the above copyright 91590Srgrimes * notice, this list of conditions and the following disclaimer. 101590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111590Srgrimes * notice, this list of conditions and the following disclaimer in the 121590Srgrimes * documentation and/or other materials provided with the distribution. 131590Srgrimes * 4. Neither the name of the University nor the names of its contributors 141590Srgrimes * may be used to endorse or promote products derived from this software 151590Srgrimes * without specific prior written permission. 161590Srgrimes * 171590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 181590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 191590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 201590Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 211590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 221590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 231590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 241590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 251590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 261590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 271590Srgrimes * SUCH DAMAGE. 281590Srgrimes */ 291590Srgrimes 301590Srgrimes#ifndef lint 3127418Scharnierstatic const char copyright[] = 321590Srgrimes"@(#) Copyright (c) 1991, 1993\n\ 331590Srgrimes The Regents of the University of California. All rights reserved.\n"; 341590Srgrimes#endif /* not lint */ 351590Srgrimes 361590Srgrimes#ifndef lint 3727418Scharnier#if 0 381590Srgrimesstatic char sccsid[] = "@(#)id.c 8.2 (Berkeley) 2/16/94"; 3927418Scharnier#endif 401590Srgrimes#endif /* not lint */ 4199112Sobrien#include <sys/cdefs.h> 4299112Sobrien__FBSDID("$FreeBSD$"); 431590Srgrimes 441590Srgrimes#include <sys/param.h> 45128900Srwatson#include <sys/mac.h> 461590Srgrimes 47162571Srwatson#ifdef USE_BSM_AUDIT 48162571Srwatson#include <bsm/audit.h> 49162571Srwatson#endif 50162571Srwatson 5127418Scharnier#include <err.h> 52128900Srwatson#include <errno.h> 531590Srgrimes#include <grp.h> 541590Srgrimes#include <pwd.h> 551590Srgrimes#include <stdio.h> 561590Srgrimes#include <stdlib.h> 571590Srgrimes#include <string.h> 581590Srgrimes#include <unistd.h> 591590Srgrimes 60227166Sedstatic void id_print(struct passwd *, int, int, int); 61227166Sedstatic void pline(struct passwd *); 62227166Sedstatic void pretty(struct passwd *); 63227203Sed#ifdef USE_BSM_AUDIT 64227166Sedstatic void auditid(void); 65227203Sed#endif 66227166Sedstatic void group(struct passwd *, int); 67227166Sedstatic void maclabel(void); 68227166Sedstatic void usage(void); 69227166Sedstatic struct passwd *who(char *); 701590Srgrimes 71227166Sedstatic int isgroups, iswhoami; 7283452Sru 731590Srgrimesint 74102944Sdwmalonemain(int argc, char *argv[]) 751590Srgrimes{ 761590Srgrimes struct group *gr; 771590Srgrimes struct passwd *pw; 78128900Srwatson int Gflag, Mflag, Pflag, ch, gflag, id, nflag, pflag, rflag, uflag; 79219304Strasz int Aflag, cflag; 80219304Strasz int error; 8183452Sru const char *myname; 82219304Strasz char loginclass[MAXLOGNAME]; 831590Srgrimes 84128900Srwatson Gflag = Mflag = Pflag = gflag = nflag = pflag = rflag = uflag = 0; 85219304Strasz Aflag = cflag = 0; 8683452Sru 8783452Sru myname = strrchr(argv[0], '/'); 8883452Sru myname = (myname != NULL) ? myname + 1 : argv[0]; 8983452Sru if (strcmp(myname, "groups") == 0) { 9083452Sru isgroups = 1; 9183452Sru Gflag = nflag = 1; 9283452Sru } 9383452Sru else if (strcmp(myname, "whoami") == 0) { 9483452Sru iswhoami = 1; 9583452Sru uflag = nflag = 1; 9683452Sru } 9783452Sru 9883452Sru while ((ch = getopt(argc, argv, 99219304Strasz (isgroups || iswhoami) ? "" : "APGMacgnpru")) != -1) 1001590Srgrimes switch(ch) { 101162578Srwatson#ifdef USE_BSM_AUDIT 102162578Srwatson case 'A': 103162578Srwatson Aflag = 1; 104162578Srwatson break; 105162578Srwatson#endif 1061590Srgrimes case 'G': 1071590Srgrimes Gflag = 1; 1081590Srgrimes break; 109128900Srwatson case 'M': 110128900Srwatson Mflag = 1; 111128900Srwatson break; 11238468Sobrien case 'P': 11338468Sobrien Pflag = 1; 11438468Sobrien break; 115162672Sceri case 'a': 116162672Sceri break; 117219304Strasz case 'c': 118219304Strasz cflag = 1; 119219304Strasz break; 1201590Srgrimes case 'g': 1211590Srgrimes gflag = 1; 1221590Srgrimes break; 1231590Srgrimes case 'n': 1241590Srgrimes nflag = 1; 1251590Srgrimes break; 1261590Srgrimes case 'p': 1271590Srgrimes pflag = 1; 1281590Srgrimes break; 1291590Srgrimes case 'r': 1301590Srgrimes rflag = 1; 1311590Srgrimes break; 1321590Srgrimes case 'u': 1331590Srgrimes uflag = 1; 1341590Srgrimes break; 1351590Srgrimes case '?': 1361590Srgrimes default: 1371590Srgrimes usage(); 1381590Srgrimes } 1391590Srgrimes argc -= optind; 1401590Srgrimes argv += optind; 1411590Srgrimes 14283452Sru if (iswhoami && argc > 0) 14383452Sru usage(); 14483452Sru 145162578Srwatson switch(Aflag + Gflag + Mflag + Pflag + gflag + pflag + uflag) { 1461590Srgrimes case 1: 1471590Srgrimes break; 1481590Srgrimes case 0: 1491590Srgrimes if (!nflag && !rflag) 1501590Srgrimes break; 1511590Srgrimes /* FALLTHROUGH */ 1521590Srgrimes default: 1531590Srgrimes usage(); 1541590Srgrimes } 1551590Srgrimes 1561590Srgrimes pw = *argv ? who(*argv) : NULL; 1571590Srgrimes 158128900Srwatson if (Mflag && pw != NULL) 159128900Srwatson usage(); 160128900Srwatson 161162571Srwatson#ifdef USE_BSM_AUDIT 162162578Srwatson if (Aflag) { 163162571Srwatson auditid(); 164162571Srwatson exit(0); 165162571Srwatson } 166162571Srwatson#endif 167162571Srwatson 168219304Strasz if (cflag) { 169219304Strasz error = getloginclass(loginclass, sizeof(loginclass)); 170219304Strasz if (error != 0) 171219304Strasz err(1, "loginclass"); 172219304Strasz (void)printf("%s\n", loginclass); 173219304Strasz exit(0); 174219304Strasz } 175219304Strasz 1761590Srgrimes if (gflag) { 1771590Srgrimes id = pw ? pw->pw_gid : rflag ? getgid() : getegid(); 1781590Srgrimes if (nflag && (gr = getgrgid(id))) 1791590Srgrimes (void)printf("%s\n", gr->gr_name); 1801590Srgrimes else 1811590Srgrimes (void)printf("%u\n", id); 1821590Srgrimes exit(0); 1831590Srgrimes } 1841590Srgrimes 1851590Srgrimes if (uflag) { 1861590Srgrimes id = pw ? pw->pw_uid : rflag ? getuid() : geteuid(); 1871590Srgrimes if (nflag && (pw = getpwuid(id))) 1881590Srgrimes (void)printf("%s\n", pw->pw_name); 1891590Srgrimes else 1901590Srgrimes (void)printf("%u\n", id); 1911590Srgrimes exit(0); 1921590Srgrimes } 1931590Srgrimes 1941590Srgrimes if (Gflag) { 1951590Srgrimes group(pw, nflag); 1961590Srgrimes exit(0); 1971590Srgrimes } 1981590Srgrimes 199128900Srwatson if (Mflag) { 200128900Srwatson maclabel(); 201128900Srwatson exit(0); 202128900Srwatson } 203128900Srwatson 20438468Sobrien if (Pflag) { 20538468Sobrien pline(pw); 20638468Sobrien exit(0); 20738468Sobrien } 20838468Sobrien 2091590Srgrimes if (pflag) { 2101590Srgrimes pretty(pw); 2111590Srgrimes exit(0); 2121590Srgrimes } 2131590Srgrimes 214145628Srobert if (pw) { 215145672Srobert id_print(pw, 1, 0, 0); 216145628Srobert } 217145628Srobert else { 218145628Srobert id = getuid(); 219165028Smpp pw = getpwuid(id); 220165028Smpp id_print(pw, 0, 1, 1); 221145628Srobert } 2221590Srgrimes exit(0); 2231590Srgrimes} 2241590Srgrimes 225227166Sedstatic void 226102944Sdwmalonepretty(struct passwd *pw) 2271590Srgrimes{ 2281590Srgrimes struct group *gr; 2291590Srgrimes u_int eid, rid; 2301590Srgrimes char *login; 2311590Srgrimes 2321590Srgrimes if (pw) { 2331590Srgrimes (void)printf("uid\t%s\n", pw->pw_name); 2341590Srgrimes (void)printf("groups\t"); 2351590Srgrimes group(pw, 1); 2361590Srgrimes } else { 2371590Srgrimes if ((login = getlogin()) == NULL) 23827418Scharnier err(1, "getlogin"); 2391590Srgrimes 2401590Srgrimes pw = getpwuid(rid = getuid()); 2411590Srgrimes if (pw == NULL || strcmp(login, pw->pw_name)) 2421590Srgrimes (void)printf("login\t%s\n", login); 2431590Srgrimes if (pw) 2441590Srgrimes (void)printf("uid\t%s\n", pw->pw_name); 2451590Srgrimes else 2461590Srgrimes (void)printf("uid\t%u\n", rid); 2478874Srgrimes 24848566Sbillf if ((eid = geteuid()) != rid) { 24927418Scharnier if ((pw = getpwuid(eid))) 25033576Ssteve (void)printf("euid\t%s\n", pw->pw_name); 2511590Srgrimes else 25233576Ssteve (void)printf("euid\t%u\n", eid); 25348566Sbillf } 25448566Sbillf if ((rid = getgid()) != (eid = getegid())) { 25527418Scharnier if ((gr = getgrgid(rid))) 2561590Srgrimes (void)printf("rgid\t%s\n", gr->gr_name); 2571590Srgrimes else 2581590Srgrimes (void)printf("rgid\t%u\n", rid); 25948566Sbillf } 2601590Srgrimes (void)printf("groups\t"); 2611590Srgrimes group(NULL, 1); 2621590Srgrimes } 2631590Srgrimes} 2641590Srgrimes 265227166Sedstatic void 266145672Srobertid_print(struct passwd *pw, int use_ggl, int p_euid, int p_egid) 2671590Srgrimes{ 2681590Srgrimes struct group *gr; 269145628Srobert gid_t gid, egid, lastgid; 270145628Srobert uid_t uid, euid; 271145628Srobert int cnt, ngroups; 272194494Sbrooks long ngroups_max; 273194494Sbrooks gid_t *groups; 27477314Sdd const char *fmt; 2751590Srgrimes 276165028Smpp if (pw != NULL) { 277165028Smpp uid = pw->pw_uid; 278165028Smpp gid = pw->pw_gid; 279165028Smpp } 280165028Smpp else { 281165028Smpp uid = getuid(); 282165028Smpp gid = getgid(); 283165028Smpp } 284145628Srobert 285194494Sbrooks ngroups_max = sysconf(_SC_NGROUPS_MAX) + 1; 286194494Sbrooks if ((groups = malloc(sizeof(gid_t) * ngroups_max)) == NULL) 287194494Sbrooks err(1, "malloc"); 288194494Sbrooks 289165028Smpp if (use_ggl && pw != NULL) { 290194494Sbrooks ngroups = ngroups_max; 291145672Srobert getgrouplist(pw->pw_name, gid, groups, &ngroups); 292145672Srobert } 293145672Srobert else { 294194494Sbrooks ngroups = getgroups(ngroups_max, groups); 295145672Srobert } 296145628Srobert 297165028Smpp if (pw != NULL) 298165028Smpp printf("uid=%u(%s)", uid, pw->pw_name); 299165028Smpp else 300165028Smpp printf("uid=%u", getuid()); 301159008Sstefanf printf(" gid=%u", gid); 302159008Sstefanf if ((gr = getgrgid(gid))) 303159008Sstefanf (void)printf("(%s)", gr->gr_name); 304145628Srobert if (p_euid && (euid = geteuid()) != uid) { 305145628Srobert (void)printf(" euid=%u", euid); 306145628Srobert if ((pw = getpwuid(euid))) 3071590Srgrimes (void)printf("(%s)", pw->pw_name); 3081590Srgrimes } 309145628Srobert if (p_egid && (egid = getegid()) != gid) { 310145628Srobert (void)printf(" egid=%u", egid); 311145628Srobert if ((gr = getgrgid(egid))) 3121590Srgrimes (void)printf("(%s)", gr->gr_name); 3131590Srgrimes } 3141590Srgrimes fmt = " groups=%u"; 31510359Sdg for (lastgid = -1, cnt = 0; cnt < ngroups; ++cnt) { 31610359Sdg if (lastgid == (gid = groups[cnt])) 3171590Srgrimes continue; 318145628Srobert printf(fmt, gid); 319165626Sstefanf fmt = ",%u"; 32027418Scharnier if ((gr = getgrgid(gid))) 321145628Srobert printf("(%s)", gr->gr_name); 32210359Sdg lastgid = gid; 3231590Srgrimes } 324145628Srobert printf("\n"); 325194494Sbrooks free(groups); 3261590Srgrimes} 3271590Srgrimes 328162571Srwatson#ifdef USE_BSM_AUDIT 329227166Sedstatic void 330162571Srwatsonauditid(void) 331162571Srwatson{ 332162571Srwatson auditinfo_t auditinfo; 333172621Scsjp auditinfo_addr_t ainfo_addr; 334172621Scsjp int ret, extended; 335162571Srwatson 336172621Scsjp extended = 0; 337172621Scsjp ret = getaudit(&auditinfo); 338172621Scsjp if (ret < 0 && errno == E2BIG) { 339172621Scsjp if (getaudit_addr(&ainfo_addr, sizeof(ainfo_addr)) < 0) 340172621Scsjp err(1, "getaudit_addr"); 341172621Scsjp extended = 1; 342172621Scsjp } else if (ret < 0) 343162656Sru err(1, "getaudit"); 344172621Scsjp if (extended != 0) { 345172621Scsjp (void) printf("auid=%d\n" 346172621Scsjp "mask.success=0x%08x\n" 347172621Scsjp "mask.failure=0x%08x\n" 348172621Scsjp "asid=%d\n" 349172621Scsjp "termid_addr.port=0x%08x\n" 350172621Scsjp "termid_addr.addr[0]=0x%08x\n" 351172621Scsjp "termid_addr.addr[1]=0x%08x\n" 352172621Scsjp "termid_addr.addr[2]=0x%08x\n" 353172621Scsjp "termid_addr.addr[3]=0x%08x\n", 354172621Scsjp ainfo_addr.ai_auid, ainfo_addr.ai_mask.am_success, 355172621Scsjp ainfo_addr.ai_mask.am_failure, ainfo_addr.ai_asid, 356172621Scsjp ainfo_addr.ai_termid.at_port, 357172621Scsjp ainfo_addr.ai_termid.at_addr[0], 358172621Scsjp ainfo_addr.ai_termid.at_addr[1], 359172621Scsjp ainfo_addr.ai_termid.at_addr[2], 360172621Scsjp ainfo_addr.ai_termid.at_addr[3]); 361172621Scsjp } else { 362172621Scsjp (void) printf("auid=%d\n" 363172621Scsjp "mask.success=0x%08x\n" 364172621Scsjp "mask.failure=0x%08x\n" 365172621Scsjp "asid=%d\n" 366172621Scsjp "termid.port=0x%08x\n" 367172621Scsjp "termid.machine=0x%08x\n", 368172621Scsjp auditinfo.ai_auid, auditinfo.ai_mask.am_success, 369172621Scsjp auditinfo.ai_mask.am_failure, 370172621Scsjp auditinfo.ai_asid, auditinfo.ai_termid.port, 371172621Scsjp auditinfo.ai_termid.machine); 372172621Scsjp } 373162571Srwatson} 374162571Srwatson#endif 375162571Srwatson 376227166Sedstatic void 377102944Sdwmalonegroup(struct passwd *pw, int nflag) 3781590Srgrimes{ 3791590Srgrimes struct group *gr; 3801590Srgrimes int cnt, id, lastid, ngroups; 381194494Sbrooks long ngroups_max; 382194494Sbrooks gid_t *groups; 38377314Sdd const char *fmt; 3841590Srgrimes 385194494Sbrooks ngroups_max = sysconf(_SC_NGROUPS_MAX) + 1; 386194494Sbrooks if ((groups = malloc(sizeof(gid_t) * (ngroups_max))) == NULL) 387194494Sbrooks err(1, "malloc"); 388194494Sbrooks 3891590Srgrimes if (pw) { 390194494Sbrooks ngroups = ngroups_max; 3911590Srgrimes (void) getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups); 3921590Srgrimes } else { 393194494Sbrooks ngroups = getgroups(ngroups_max, groups); 3941590Srgrimes } 3951590Srgrimes fmt = nflag ? "%s" : "%u"; 3961590Srgrimes for (lastid = -1, cnt = 0; cnt < ngroups; ++cnt) { 3971590Srgrimes if (lastid == (id = groups[cnt])) 3981590Srgrimes continue; 3991590Srgrimes if (nflag) { 40027418Scharnier if ((gr = getgrgid(id))) 4011590Srgrimes (void)printf(fmt, gr->gr_name); 4021590Srgrimes else 4031590Srgrimes (void)printf(*fmt == ' ' ? " %u" : "%u", 4041590Srgrimes id); 4051590Srgrimes fmt = " %s"; 4061590Srgrimes } else { 4071590Srgrimes (void)printf(fmt, id); 4081590Srgrimes fmt = " %u"; 4091590Srgrimes } 4101590Srgrimes lastid = id; 4111590Srgrimes } 4121590Srgrimes (void)printf("\n"); 413194494Sbrooks free(groups); 4141590Srgrimes} 4151590Srgrimes 416227166Sedstatic void 417128900Srwatsonmaclabel(void) 418128900Srwatson{ 419128900Srwatson char *string; 420128900Srwatson mac_t label; 421128900Srwatson int error; 422128900Srwatson 423128900Srwatson error = mac_prepare_process_label(&label); 424128900Srwatson if (error == -1) 425128900Srwatson errx(1, "mac_prepare_type: %s", strerror(errno)); 426128900Srwatson 427128900Srwatson error = mac_get_proc(label); 428128900Srwatson if (error == -1) 429128900Srwatson errx(1, "mac_get_proc: %s", strerror(errno)); 430128900Srwatson 431128900Srwatson error = mac_to_text(label, &string); 432128900Srwatson if (error == -1) 433128900Srwatson errx(1, "mac_to_text: %s", strerror(errno)); 434128900Srwatson 435128900Srwatson (void)printf("%s\n", string); 436128900Srwatson mac_free(label); 437128900Srwatson free(string); 438128900Srwatson} 439128900Srwatson 440227166Sedstatic struct passwd * 441102944Sdwmalonewho(char *u) 4421590Srgrimes{ 4431590Srgrimes struct passwd *pw; 4441590Srgrimes long id; 4451590Srgrimes char *ep; 4461590Srgrimes 4471590Srgrimes /* 4481590Srgrimes * Translate user argument into a pw pointer. First, try to 4491590Srgrimes * get it as specified. If that fails, try it as a number. 4501590Srgrimes */ 45127418Scharnier if ((pw = getpwnam(u))) 4521590Srgrimes return(pw); 4531590Srgrimes id = strtol(u, &ep, 10); 4541590Srgrimes if (*u && !*ep && (pw = getpwuid(id))) 4551590Srgrimes return(pw); 45627418Scharnier errx(1, "%s: no such user", u); 4571590Srgrimes /* NOTREACHED */ 4581590Srgrimes} 4591590Srgrimes 460227166Sedstatic void 461102944Sdwmalonepline(struct passwd *pw) 46238468Sobrien{ 46338468Sobrien 46438468Sobrien if (!pw) { 465144840Sstefanf if ((pw = getpwuid(getuid())) == NULL) 46638468Sobrien err(1, "getpwuid"); 46738468Sobrien } 46838468Sobrien 46951032Sbillf (void)printf("%s:%s:%d:%d:%s:%ld:%ld:%s:%s:%s\n", pw->pw_name, 47038468Sobrien pw->pw_passwd, pw->pw_uid, pw->pw_gid, pw->pw_class, 47151032Sbillf (long)pw->pw_change, (long)pw->pw_expire, pw->pw_gecos, 47238468Sobrien pw->pw_dir, pw->pw_shell); 47338468Sobrien} 47438468Sobrien 47538468Sobrien 476227166Sedstatic void 477102944Sdwmaloneusage(void) 4781590Srgrimes{ 47983452Sru 48083452Sru if (isgroups) 48183452Sru (void)fprintf(stderr, "usage: groups [user]\n"); 48283452Sru else if (iswhoami) 48383452Sru (void)fprintf(stderr, "usage: whoami\n"); 48483452Sru else 485219304Strasz (void)fprintf(stderr, "%s\n%s%s\n%s\n%s\n%s\n%s\n%s\n%s\n", 48683452Sru "usage: id [user]", 487162571Srwatson#ifdef USE_BSM_AUDIT 488162578Srwatson " id -A\n", 489162571Srwatson#else 490162571Srwatson "", 491162571Srwatson#endif 492162578Srwatson " id -G [-n] [user]", 493162578Srwatson " id -M", 494162578Srwatson " id -P [user]", 495219304Strasz " id -c", 49683452Sru " id -g [-nr] [user]", 49783452Sru " id -p [user]", 49883452Sru " id -u [-nr] [user]"); 4991590Srgrimes exit(1); 5001590Srgrimes} 501