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> 55275855Sgleb#include <stdint.h> 561590Srgrimes#include <stdio.h> 571590Srgrimes#include <stdlib.h> 581590Srgrimes#include <string.h> 591590Srgrimes#include <unistd.h> 601590Srgrimes 61227166Sedstatic void id_print(struct passwd *, int, int, int); 62227166Sedstatic void pline(struct passwd *); 63227166Sedstatic void pretty(struct passwd *); 64227203Sed#ifdef USE_BSM_AUDIT 65227166Sedstatic void auditid(void); 66227203Sed#endif 67227166Sedstatic void group(struct passwd *, int); 68227166Sedstatic void maclabel(void); 69227166Sedstatic void usage(void); 70227166Sedstatic struct passwd *who(char *); 711590Srgrimes 72227166Sedstatic int isgroups, iswhoami; 7383452Sru 741590Srgrimesint 75102944Sdwmalonemain(int argc, char *argv[]) 761590Srgrimes{ 771590Srgrimes struct group *gr; 781590Srgrimes struct passwd *pw; 79128900Srwatson int Gflag, Mflag, Pflag, ch, gflag, id, nflag, pflag, rflag, uflag; 80219304Strasz int Aflag, cflag; 81219304Strasz int error; 8283452Sru const char *myname; 83219304Strasz char loginclass[MAXLOGNAME]; 841590Srgrimes 85128900Srwatson Gflag = Mflag = Pflag = gflag = nflag = pflag = rflag = uflag = 0; 86219304Strasz Aflag = cflag = 0; 8783452Sru 8883452Sru myname = strrchr(argv[0], '/'); 8983452Sru myname = (myname != NULL) ? myname + 1 : argv[0]; 9083452Sru if (strcmp(myname, "groups") == 0) { 9183452Sru isgroups = 1; 9283452Sru Gflag = nflag = 1; 9383452Sru } 9483452Sru else if (strcmp(myname, "whoami") == 0) { 9583452Sru iswhoami = 1; 9683452Sru uflag = nflag = 1; 9783452Sru } 9883452Sru 9983452Sru while ((ch = getopt(argc, argv, 100219304Strasz (isgroups || iswhoami) ? "" : "APGMacgnpru")) != -1) 1011590Srgrimes switch(ch) { 102162578Srwatson#ifdef USE_BSM_AUDIT 103162578Srwatson case 'A': 104162578Srwatson Aflag = 1; 105162578Srwatson break; 106162578Srwatson#endif 1071590Srgrimes case 'G': 1081590Srgrimes Gflag = 1; 1091590Srgrimes break; 110128900Srwatson case 'M': 111128900Srwatson Mflag = 1; 112128900Srwatson break; 11338468Sobrien case 'P': 11438468Sobrien Pflag = 1; 11538468Sobrien break; 116162672Sceri case 'a': 117162672Sceri break; 118219304Strasz case 'c': 119219304Strasz cflag = 1; 120219304Strasz break; 1211590Srgrimes case 'g': 1221590Srgrimes gflag = 1; 1231590Srgrimes break; 1241590Srgrimes case 'n': 1251590Srgrimes nflag = 1; 1261590Srgrimes break; 1271590Srgrimes case 'p': 1281590Srgrimes pflag = 1; 1291590Srgrimes break; 1301590Srgrimes case 'r': 1311590Srgrimes rflag = 1; 1321590Srgrimes break; 1331590Srgrimes case 'u': 1341590Srgrimes uflag = 1; 1351590Srgrimes break; 1361590Srgrimes case '?': 1371590Srgrimes default: 1381590Srgrimes usage(); 1391590Srgrimes } 1401590Srgrimes argc -= optind; 1411590Srgrimes argv += optind; 1421590Srgrimes 14383452Sru if (iswhoami && argc > 0) 14483452Sru usage(); 14583452Sru 146162578Srwatson switch(Aflag + Gflag + Mflag + Pflag + gflag + pflag + uflag) { 1471590Srgrimes case 1: 1481590Srgrimes break; 1491590Srgrimes case 0: 1501590Srgrimes if (!nflag && !rflag) 1511590Srgrimes break; 1521590Srgrimes /* FALLTHROUGH */ 1531590Srgrimes default: 1541590Srgrimes usage(); 1551590Srgrimes } 1561590Srgrimes 1571590Srgrimes pw = *argv ? who(*argv) : NULL; 1581590Srgrimes 159128900Srwatson if (Mflag && pw != NULL) 160128900Srwatson usage(); 161128900Srwatson 162162571Srwatson#ifdef USE_BSM_AUDIT 163162578Srwatson if (Aflag) { 164162571Srwatson auditid(); 165162571Srwatson exit(0); 166162571Srwatson } 167162571Srwatson#endif 168162571Srwatson 169219304Strasz if (cflag) { 170219304Strasz error = getloginclass(loginclass, sizeof(loginclass)); 171219304Strasz if (error != 0) 172219304Strasz err(1, "loginclass"); 173219304Strasz (void)printf("%s\n", loginclass); 174219304Strasz exit(0); 175219304Strasz } 176219304Strasz 1771590Srgrimes if (gflag) { 1781590Srgrimes id = pw ? pw->pw_gid : rflag ? getgid() : getegid(); 1791590Srgrimes if (nflag && (gr = getgrgid(id))) 1801590Srgrimes (void)printf("%s\n", gr->gr_name); 1811590Srgrimes else 1821590Srgrimes (void)printf("%u\n", id); 1831590Srgrimes exit(0); 1841590Srgrimes } 1851590Srgrimes 1861590Srgrimes if (uflag) { 1871590Srgrimes id = pw ? pw->pw_uid : rflag ? getuid() : geteuid(); 1881590Srgrimes if (nflag && (pw = getpwuid(id))) 1891590Srgrimes (void)printf("%s\n", pw->pw_name); 1901590Srgrimes else 1911590Srgrimes (void)printf("%u\n", id); 1921590Srgrimes exit(0); 1931590Srgrimes } 1941590Srgrimes 1951590Srgrimes if (Gflag) { 1961590Srgrimes group(pw, nflag); 1971590Srgrimes exit(0); 1981590Srgrimes } 1991590Srgrimes 200128900Srwatson if (Mflag) { 201128900Srwatson maclabel(); 202128900Srwatson exit(0); 203128900Srwatson } 204128900Srwatson 20538468Sobrien if (Pflag) { 20638468Sobrien pline(pw); 20738468Sobrien exit(0); 20838468Sobrien } 20938468Sobrien 2101590Srgrimes if (pflag) { 2111590Srgrimes pretty(pw); 2121590Srgrimes exit(0); 2131590Srgrimes } 2141590Srgrimes 215145628Srobert if (pw) { 216145672Srobert id_print(pw, 1, 0, 0); 217145628Srobert } 218145628Srobert else { 219145628Srobert id = getuid(); 220165028Smpp pw = getpwuid(id); 221165028Smpp id_print(pw, 0, 1, 1); 222145628Srobert } 2231590Srgrimes exit(0); 2241590Srgrimes} 2251590Srgrimes 226227166Sedstatic void 227102944Sdwmalonepretty(struct passwd *pw) 2281590Srgrimes{ 2291590Srgrimes struct group *gr; 2301590Srgrimes u_int eid, rid; 2311590Srgrimes char *login; 2321590Srgrimes 2331590Srgrimes if (pw) { 2341590Srgrimes (void)printf("uid\t%s\n", pw->pw_name); 2351590Srgrimes (void)printf("groups\t"); 2361590Srgrimes group(pw, 1); 2371590Srgrimes } else { 2381590Srgrimes if ((login = getlogin()) == NULL) 23927418Scharnier err(1, "getlogin"); 2401590Srgrimes 2411590Srgrimes pw = getpwuid(rid = getuid()); 2421590Srgrimes if (pw == NULL || strcmp(login, pw->pw_name)) 2431590Srgrimes (void)printf("login\t%s\n", login); 2441590Srgrimes if (pw) 2451590Srgrimes (void)printf("uid\t%s\n", pw->pw_name); 2461590Srgrimes else 2471590Srgrimes (void)printf("uid\t%u\n", rid); 2488874Srgrimes 24948566Sbillf if ((eid = geteuid()) != rid) { 25027418Scharnier if ((pw = getpwuid(eid))) 25133576Ssteve (void)printf("euid\t%s\n", pw->pw_name); 2521590Srgrimes else 25333576Ssteve (void)printf("euid\t%u\n", eid); 25448566Sbillf } 25548566Sbillf if ((rid = getgid()) != (eid = getegid())) { 25627418Scharnier if ((gr = getgrgid(rid))) 2571590Srgrimes (void)printf("rgid\t%s\n", gr->gr_name); 2581590Srgrimes else 2591590Srgrimes (void)printf("rgid\t%u\n", rid); 26048566Sbillf } 2611590Srgrimes (void)printf("groups\t"); 2621590Srgrimes group(NULL, 1); 2631590Srgrimes } 2641590Srgrimes} 2651590Srgrimes 266227166Sedstatic void 267145672Srobertid_print(struct passwd *pw, int use_ggl, int p_euid, int p_egid) 2681590Srgrimes{ 2691590Srgrimes struct group *gr; 270145628Srobert gid_t gid, egid, lastgid; 271145628Srobert uid_t uid, euid; 272145628Srobert int cnt, ngroups; 273194494Sbrooks long ngroups_max; 274194494Sbrooks gid_t *groups; 27577314Sdd const char *fmt; 2761590Srgrimes 277165028Smpp if (pw != NULL) { 278165028Smpp uid = pw->pw_uid; 279165028Smpp gid = pw->pw_gid; 280165028Smpp } 281165028Smpp else { 282165028Smpp uid = getuid(); 283165028Smpp gid = getgid(); 284165028Smpp } 285145628Srobert 286194494Sbrooks ngroups_max = sysconf(_SC_NGROUPS_MAX) + 1; 287194494Sbrooks if ((groups = malloc(sizeof(gid_t) * ngroups_max)) == NULL) 288194494Sbrooks err(1, "malloc"); 289194494Sbrooks 290165028Smpp if (use_ggl && pw != NULL) { 291194494Sbrooks ngroups = ngroups_max; 292145672Srobert getgrouplist(pw->pw_name, gid, groups, &ngroups); 293145672Srobert } 294145672Srobert else { 295194494Sbrooks ngroups = getgroups(ngroups_max, groups); 296145672Srobert } 297145628Srobert 298165028Smpp if (pw != NULL) 299165028Smpp printf("uid=%u(%s)", uid, pw->pw_name); 300165028Smpp else 301165028Smpp printf("uid=%u", getuid()); 302159008Sstefanf printf(" gid=%u", gid); 303159008Sstefanf if ((gr = getgrgid(gid))) 304159008Sstefanf (void)printf("(%s)", gr->gr_name); 305145628Srobert if (p_euid && (euid = geteuid()) != uid) { 306145628Srobert (void)printf(" euid=%u", euid); 307145628Srobert if ((pw = getpwuid(euid))) 3081590Srgrimes (void)printf("(%s)", pw->pw_name); 3091590Srgrimes } 310145628Srobert if (p_egid && (egid = getegid()) != gid) { 311145628Srobert (void)printf(" egid=%u", egid); 312145628Srobert if ((gr = getgrgid(egid))) 3131590Srgrimes (void)printf("(%s)", gr->gr_name); 3141590Srgrimes } 3151590Srgrimes fmt = " groups=%u"; 31610359Sdg for (lastgid = -1, cnt = 0; cnt < ngroups; ++cnt) { 31710359Sdg if (lastgid == (gid = groups[cnt])) 3181590Srgrimes continue; 319145628Srobert printf(fmt, gid); 320165626Sstefanf fmt = ",%u"; 32127418Scharnier if ((gr = getgrgid(gid))) 322145628Srobert printf("(%s)", gr->gr_name); 32310359Sdg lastgid = gid; 3241590Srgrimes } 325145628Srobert printf("\n"); 326194494Sbrooks free(groups); 3271590Srgrimes} 3281590Srgrimes 329162571Srwatson#ifdef USE_BSM_AUDIT 330227166Sedstatic void 331162571Srwatsonauditid(void) 332162571Srwatson{ 333162571Srwatson auditinfo_t auditinfo; 334172621Scsjp auditinfo_addr_t ainfo_addr; 335172621Scsjp int ret, extended; 336162571Srwatson 337172621Scsjp extended = 0; 338172621Scsjp ret = getaudit(&auditinfo); 339172621Scsjp if (ret < 0 && errno == E2BIG) { 340172621Scsjp if (getaudit_addr(&ainfo_addr, sizeof(ainfo_addr)) < 0) 341172621Scsjp err(1, "getaudit_addr"); 342172621Scsjp extended = 1; 343172621Scsjp } else if (ret < 0) 344162656Sru err(1, "getaudit"); 345172621Scsjp if (extended != 0) { 346172621Scsjp (void) printf("auid=%d\n" 347172621Scsjp "mask.success=0x%08x\n" 348172621Scsjp "mask.failure=0x%08x\n" 349172621Scsjp "asid=%d\n" 350275855Sgleb "termid_addr.port=0x%08jx\n" 351172621Scsjp "termid_addr.addr[0]=0x%08x\n" 352172621Scsjp "termid_addr.addr[1]=0x%08x\n" 353172621Scsjp "termid_addr.addr[2]=0x%08x\n" 354172621Scsjp "termid_addr.addr[3]=0x%08x\n", 355172621Scsjp ainfo_addr.ai_auid, ainfo_addr.ai_mask.am_success, 356172621Scsjp ainfo_addr.ai_mask.am_failure, ainfo_addr.ai_asid, 357275855Sgleb (uintmax_t)ainfo_addr.ai_termid.at_port, 358172621Scsjp ainfo_addr.ai_termid.at_addr[0], 359172621Scsjp ainfo_addr.ai_termid.at_addr[1], 360172621Scsjp ainfo_addr.ai_termid.at_addr[2], 361172621Scsjp ainfo_addr.ai_termid.at_addr[3]); 362172621Scsjp } else { 363172621Scsjp (void) printf("auid=%d\n" 364172621Scsjp "mask.success=0x%08x\n" 365172621Scsjp "mask.failure=0x%08x\n" 366172621Scsjp "asid=%d\n" 367275855Sgleb "termid.port=0x%08jx\n" 368172621Scsjp "termid.machine=0x%08x\n", 369172621Scsjp auditinfo.ai_auid, auditinfo.ai_mask.am_success, 370172621Scsjp auditinfo.ai_mask.am_failure, 371275855Sgleb auditinfo.ai_asid, (uintmax_t)auditinfo.ai_termid.port, 372172621Scsjp auditinfo.ai_termid.machine); 373172621Scsjp } 374162571Srwatson} 375162571Srwatson#endif 376162571Srwatson 377227166Sedstatic void 378102944Sdwmalonegroup(struct passwd *pw, int nflag) 3791590Srgrimes{ 3801590Srgrimes struct group *gr; 3811590Srgrimes int cnt, id, lastid, ngroups; 382194494Sbrooks long ngroups_max; 383194494Sbrooks gid_t *groups; 38477314Sdd const char *fmt; 3851590Srgrimes 386194494Sbrooks ngroups_max = sysconf(_SC_NGROUPS_MAX) + 1; 387194494Sbrooks if ((groups = malloc(sizeof(gid_t) * (ngroups_max))) == NULL) 388194494Sbrooks err(1, "malloc"); 389194494Sbrooks 3901590Srgrimes if (pw) { 391194494Sbrooks ngroups = ngroups_max; 3921590Srgrimes (void) getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups); 3931590Srgrimes } else { 394194494Sbrooks ngroups = getgroups(ngroups_max, groups); 3951590Srgrimes } 3961590Srgrimes fmt = nflag ? "%s" : "%u"; 3971590Srgrimes for (lastid = -1, cnt = 0; cnt < ngroups; ++cnt) { 3981590Srgrimes if (lastid == (id = groups[cnt])) 3991590Srgrimes continue; 4001590Srgrimes if (nflag) { 40127418Scharnier if ((gr = getgrgid(id))) 4021590Srgrimes (void)printf(fmt, gr->gr_name); 4031590Srgrimes else 4041590Srgrimes (void)printf(*fmt == ' ' ? " %u" : "%u", 4051590Srgrimes id); 4061590Srgrimes fmt = " %s"; 4071590Srgrimes } else { 4081590Srgrimes (void)printf(fmt, id); 4091590Srgrimes fmt = " %u"; 4101590Srgrimes } 4111590Srgrimes lastid = id; 4121590Srgrimes } 4131590Srgrimes (void)printf("\n"); 414194494Sbrooks free(groups); 4151590Srgrimes} 4161590Srgrimes 417227166Sedstatic void 418128900Srwatsonmaclabel(void) 419128900Srwatson{ 420128900Srwatson char *string; 421128900Srwatson mac_t label; 422128900Srwatson int error; 423128900Srwatson 424128900Srwatson error = mac_prepare_process_label(&label); 425128900Srwatson if (error == -1) 426128900Srwatson errx(1, "mac_prepare_type: %s", strerror(errno)); 427128900Srwatson 428128900Srwatson error = mac_get_proc(label); 429128900Srwatson if (error == -1) 430128900Srwatson errx(1, "mac_get_proc: %s", strerror(errno)); 431128900Srwatson 432128900Srwatson error = mac_to_text(label, &string); 433128900Srwatson if (error == -1) 434128900Srwatson errx(1, "mac_to_text: %s", strerror(errno)); 435128900Srwatson 436128900Srwatson (void)printf("%s\n", string); 437128900Srwatson mac_free(label); 438128900Srwatson free(string); 439128900Srwatson} 440128900Srwatson 441227166Sedstatic struct passwd * 442102944Sdwmalonewho(char *u) 4431590Srgrimes{ 4441590Srgrimes struct passwd *pw; 4451590Srgrimes long id; 4461590Srgrimes char *ep; 4471590Srgrimes 4481590Srgrimes /* 4491590Srgrimes * Translate user argument into a pw pointer. First, try to 4501590Srgrimes * get it as specified. If that fails, try it as a number. 4511590Srgrimes */ 45227418Scharnier if ((pw = getpwnam(u))) 4531590Srgrimes return(pw); 4541590Srgrimes id = strtol(u, &ep, 10); 4551590Srgrimes if (*u && !*ep && (pw = getpwuid(id))) 4561590Srgrimes return(pw); 45727418Scharnier errx(1, "%s: no such user", u); 4581590Srgrimes /* NOTREACHED */ 4591590Srgrimes} 4601590Srgrimes 461227166Sedstatic void 462102944Sdwmalonepline(struct passwd *pw) 46338468Sobrien{ 46438468Sobrien 46538468Sobrien if (!pw) { 466144840Sstefanf if ((pw = getpwuid(getuid())) == NULL) 46738468Sobrien err(1, "getpwuid"); 46838468Sobrien } 46938468Sobrien 47051032Sbillf (void)printf("%s:%s:%d:%d:%s:%ld:%ld:%s:%s:%s\n", pw->pw_name, 47138468Sobrien pw->pw_passwd, pw->pw_uid, pw->pw_gid, pw->pw_class, 47251032Sbillf (long)pw->pw_change, (long)pw->pw_expire, pw->pw_gecos, 47338468Sobrien pw->pw_dir, pw->pw_shell); 47438468Sobrien} 47538468Sobrien 47638468Sobrien 477227166Sedstatic void 478102944Sdwmaloneusage(void) 4791590Srgrimes{ 48083452Sru 48183452Sru if (isgroups) 48283452Sru (void)fprintf(stderr, "usage: groups [user]\n"); 48383452Sru else if (iswhoami) 48483452Sru (void)fprintf(stderr, "usage: whoami\n"); 48583452Sru else 486219304Strasz (void)fprintf(stderr, "%s\n%s%s\n%s\n%s\n%s\n%s\n%s\n%s\n", 48783452Sru "usage: id [user]", 488162571Srwatson#ifdef USE_BSM_AUDIT 489162578Srwatson " id -A\n", 490162571Srwatson#else 491162571Srwatson "", 492162571Srwatson#endif 493162578Srwatson " id -G [-n] [user]", 494162578Srwatson " id -M", 495162578Srwatson " id -P [user]", 496219304Strasz " id -c", 49783452Sru " id -g [-nr] [user]", 49883452Sru " id -p [user]", 49983452Sru " id -u [-nr] [user]"); 5001590Srgrimes exit(1); 5011590Srgrimes} 502