id.c revision 219304
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: head/usr.bin/id/id.c 219304 2011-03-05 12:40:35Z trasz $"); 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 60145672Srobertvoid id_print(struct passwd *, int, int, int); 6192920Simpvoid pline(struct passwd *); 6292920Simpvoid pretty(struct passwd *); 63162571Srwatsonvoid auditid(void); 6492920Simpvoid group(struct passwd *, int); 65128900Srwatsonvoid maclabel(void); 6692920Simpvoid usage(void); 67145628Srobertstruct passwd *who(char *); 681590Srgrimes 6983452Sruint isgroups, iswhoami; 7083452Sru 711590Srgrimesint 72102944Sdwmalonemain(int argc, char *argv[]) 731590Srgrimes{ 741590Srgrimes struct group *gr; 751590Srgrimes struct passwd *pw; 76128900Srwatson int Gflag, Mflag, Pflag, ch, gflag, id, nflag, pflag, rflag, uflag; 77219304Strasz int Aflag, cflag; 78219304Strasz int error; 7983452Sru const char *myname; 80219304Strasz char loginclass[MAXLOGNAME]; 811590Srgrimes 82128900Srwatson Gflag = Mflag = Pflag = gflag = nflag = pflag = rflag = uflag = 0; 83219304Strasz Aflag = cflag = 0; 8483452Sru 8583452Sru myname = strrchr(argv[0], '/'); 8683452Sru myname = (myname != NULL) ? myname + 1 : argv[0]; 8783452Sru if (strcmp(myname, "groups") == 0) { 8883452Sru isgroups = 1; 8983452Sru Gflag = nflag = 1; 9083452Sru } 9183452Sru else if (strcmp(myname, "whoami") == 0) { 9283452Sru iswhoami = 1; 9383452Sru uflag = nflag = 1; 9483452Sru } 9583452Sru 9683452Sru while ((ch = getopt(argc, argv, 97219304Strasz (isgroups || iswhoami) ? "" : "APGMacgnpru")) != -1) 981590Srgrimes switch(ch) { 99162578Srwatson#ifdef USE_BSM_AUDIT 100162578Srwatson case 'A': 101162578Srwatson Aflag = 1; 102162578Srwatson break; 103162578Srwatson#endif 1041590Srgrimes case 'G': 1051590Srgrimes Gflag = 1; 1061590Srgrimes break; 107128900Srwatson case 'M': 108128900Srwatson Mflag = 1; 109128900Srwatson break; 11038468Sobrien case 'P': 11138468Sobrien Pflag = 1; 11238468Sobrien break; 113162672Sceri case 'a': 114162672Sceri break; 115219304Strasz case 'c': 116219304Strasz cflag = 1; 117219304Strasz break; 1181590Srgrimes case 'g': 1191590Srgrimes gflag = 1; 1201590Srgrimes break; 1211590Srgrimes case 'n': 1221590Srgrimes nflag = 1; 1231590Srgrimes break; 1241590Srgrimes case 'p': 1251590Srgrimes pflag = 1; 1261590Srgrimes break; 1271590Srgrimes case 'r': 1281590Srgrimes rflag = 1; 1291590Srgrimes break; 1301590Srgrimes case 'u': 1311590Srgrimes uflag = 1; 1321590Srgrimes break; 1331590Srgrimes case '?': 1341590Srgrimes default: 1351590Srgrimes usage(); 1361590Srgrimes } 1371590Srgrimes argc -= optind; 1381590Srgrimes argv += optind; 1391590Srgrimes 14083452Sru if (iswhoami && argc > 0) 14183452Sru usage(); 14283452Sru 143162578Srwatson switch(Aflag + Gflag + Mflag + Pflag + gflag + pflag + uflag) { 1441590Srgrimes case 1: 1451590Srgrimes break; 1461590Srgrimes case 0: 1471590Srgrimes if (!nflag && !rflag) 1481590Srgrimes break; 1491590Srgrimes /* FALLTHROUGH */ 1501590Srgrimes default: 1511590Srgrimes usage(); 1521590Srgrimes } 1531590Srgrimes 1541590Srgrimes pw = *argv ? who(*argv) : NULL; 1551590Srgrimes 156128900Srwatson if (Mflag && pw != NULL) 157128900Srwatson usage(); 158128900Srwatson 159162571Srwatson#ifdef USE_BSM_AUDIT 160162578Srwatson if (Aflag) { 161162571Srwatson auditid(); 162162571Srwatson exit(0); 163162571Srwatson } 164162571Srwatson#endif 165162571Srwatson 166219304Strasz if (cflag) { 167219304Strasz error = getloginclass(loginclass, sizeof(loginclass)); 168219304Strasz if (error != 0) 169219304Strasz err(1, "loginclass"); 170219304Strasz (void)printf("%s\n", loginclass); 171219304Strasz exit(0); 172219304Strasz } 173219304Strasz 1741590Srgrimes if (gflag) { 1751590Srgrimes id = pw ? pw->pw_gid : rflag ? getgid() : getegid(); 1761590Srgrimes if (nflag && (gr = getgrgid(id))) 1771590Srgrimes (void)printf("%s\n", gr->gr_name); 1781590Srgrimes else 1791590Srgrimes (void)printf("%u\n", id); 1801590Srgrimes exit(0); 1811590Srgrimes } 1821590Srgrimes 1831590Srgrimes if (uflag) { 1841590Srgrimes id = pw ? pw->pw_uid : rflag ? getuid() : geteuid(); 1851590Srgrimes if (nflag && (pw = getpwuid(id))) 1861590Srgrimes (void)printf("%s\n", pw->pw_name); 1871590Srgrimes else 1881590Srgrimes (void)printf("%u\n", id); 1891590Srgrimes exit(0); 1901590Srgrimes } 1911590Srgrimes 1921590Srgrimes if (Gflag) { 1931590Srgrimes group(pw, nflag); 1941590Srgrimes exit(0); 1951590Srgrimes } 1961590Srgrimes 197128900Srwatson if (Mflag) { 198128900Srwatson maclabel(); 199128900Srwatson exit(0); 200128900Srwatson } 201128900Srwatson 20238468Sobrien if (Pflag) { 20338468Sobrien pline(pw); 20438468Sobrien exit(0); 20538468Sobrien } 20638468Sobrien 2071590Srgrimes if (pflag) { 2081590Srgrimes pretty(pw); 2091590Srgrimes exit(0); 2101590Srgrimes } 2111590Srgrimes 212145628Srobert if (pw) { 213145672Srobert id_print(pw, 1, 0, 0); 214145628Srobert } 215145628Srobert else { 216145628Srobert id = getuid(); 217165028Smpp pw = getpwuid(id); 218165028Smpp id_print(pw, 0, 1, 1); 219145628Srobert } 2201590Srgrimes exit(0); 2211590Srgrimes} 2221590Srgrimes 2231590Srgrimesvoid 224102944Sdwmalonepretty(struct passwd *pw) 2251590Srgrimes{ 2261590Srgrimes struct group *gr; 2271590Srgrimes u_int eid, rid; 2281590Srgrimes char *login; 2291590Srgrimes 2301590Srgrimes if (pw) { 2311590Srgrimes (void)printf("uid\t%s\n", pw->pw_name); 2321590Srgrimes (void)printf("groups\t"); 2331590Srgrimes group(pw, 1); 2341590Srgrimes } else { 2351590Srgrimes if ((login = getlogin()) == NULL) 23627418Scharnier err(1, "getlogin"); 2371590Srgrimes 2381590Srgrimes pw = getpwuid(rid = getuid()); 2391590Srgrimes if (pw == NULL || strcmp(login, pw->pw_name)) 2401590Srgrimes (void)printf("login\t%s\n", login); 2411590Srgrimes if (pw) 2421590Srgrimes (void)printf("uid\t%s\n", pw->pw_name); 2431590Srgrimes else 2441590Srgrimes (void)printf("uid\t%u\n", rid); 2458874Srgrimes 24648566Sbillf if ((eid = geteuid()) != rid) { 24727418Scharnier if ((pw = getpwuid(eid))) 24833576Ssteve (void)printf("euid\t%s\n", pw->pw_name); 2491590Srgrimes else 25033576Ssteve (void)printf("euid\t%u\n", eid); 25148566Sbillf } 25248566Sbillf if ((rid = getgid()) != (eid = getegid())) { 25327418Scharnier if ((gr = getgrgid(rid))) 2541590Srgrimes (void)printf("rgid\t%s\n", gr->gr_name); 2551590Srgrimes else 2561590Srgrimes (void)printf("rgid\t%u\n", rid); 25748566Sbillf } 2581590Srgrimes (void)printf("groups\t"); 2591590Srgrimes group(NULL, 1); 2601590Srgrimes } 2611590Srgrimes} 2621590Srgrimes 2631590Srgrimesvoid 264145672Srobertid_print(struct passwd *pw, int use_ggl, int p_euid, int p_egid) 2651590Srgrimes{ 2661590Srgrimes struct group *gr; 267145628Srobert gid_t gid, egid, lastgid; 268145628Srobert uid_t uid, euid; 269145628Srobert int cnt, ngroups; 270194494Sbrooks long ngroups_max; 271194494Sbrooks gid_t *groups; 27277314Sdd const char *fmt; 2731590Srgrimes 274165028Smpp if (pw != NULL) { 275165028Smpp uid = pw->pw_uid; 276165028Smpp gid = pw->pw_gid; 277165028Smpp } 278165028Smpp else { 279165028Smpp uid = getuid(); 280165028Smpp gid = getgid(); 281165028Smpp } 282145628Srobert 283194494Sbrooks ngroups_max = sysconf(_SC_NGROUPS_MAX) + 1; 284194494Sbrooks if ((groups = malloc(sizeof(gid_t) * ngroups_max)) == NULL) 285194494Sbrooks err(1, "malloc"); 286194494Sbrooks 287165028Smpp if (use_ggl && pw != NULL) { 288194494Sbrooks ngroups = ngroups_max; 289145672Srobert getgrouplist(pw->pw_name, gid, groups, &ngroups); 290145672Srobert } 291145672Srobert else { 292194494Sbrooks ngroups = getgroups(ngroups_max, groups); 293145672Srobert } 294145628Srobert 295165028Smpp if (pw != NULL) 296165028Smpp printf("uid=%u(%s)", uid, pw->pw_name); 297165028Smpp else 298165028Smpp printf("uid=%u", getuid()); 299159008Sstefanf printf(" gid=%u", gid); 300159008Sstefanf if ((gr = getgrgid(gid))) 301159008Sstefanf (void)printf("(%s)", gr->gr_name); 302145628Srobert if (p_euid && (euid = geteuid()) != uid) { 303145628Srobert (void)printf(" euid=%u", euid); 304145628Srobert if ((pw = getpwuid(euid))) 3051590Srgrimes (void)printf("(%s)", pw->pw_name); 3061590Srgrimes } 307145628Srobert if (p_egid && (egid = getegid()) != gid) { 308145628Srobert (void)printf(" egid=%u", egid); 309145628Srobert if ((gr = getgrgid(egid))) 3101590Srgrimes (void)printf("(%s)", gr->gr_name); 3111590Srgrimes } 3121590Srgrimes fmt = " groups=%u"; 31310359Sdg for (lastgid = -1, cnt = 0; cnt < ngroups; ++cnt) { 31410359Sdg if (lastgid == (gid = groups[cnt])) 3151590Srgrimes continue; 316145628Srobert printf(fmt, gid); 317165626Sstefanf fmt = ",%u"; 31827418Scharnier if ((gr = getgrgid(gid))) 319145628Srobert printf("(%s)", gr->gr_name); 32010359Sdg lastgid = gid; 3211590Srgrimes } 322145628Srobert printf("\n"); 323194494Sbrooks free(groups); 3241590Srgrimes} 3251590Srgrimes 326162571Srwatson#ifdef USE_BSM_AUDIT 3271590Srgrimesvoid 328162571Srwatsonauditid(void) 329162571Srwatson{ 330162571Srwatson auditinfo_t auditinfo; 331172621Scsjp auditinfo_addr_t ainfo_addr; 332172621Scsjp int ret, extended; 333162571Srwatson 334172621Scsjp extended = 0; 335172621Scsjp ret = getaudit(&auditinfo); 336172621Scsjp if (ret < 0 && errno == E2BIG) { 337172621Scsjp if (getaudit_addr(&ainfo_addr, sizeof(ainfo_addr)) < 0) 338172621Scsjp err(1, "getaudit_addr"); 339172621Scsjp extended = 1; 340172621Scsjp } else if (ret < 0) 341162656Sru err(1, "getaudit"); 342172621Scsjp if (extended != 0) { 343172621Scsjp (void) printf("auid=%d\n" 344172621Scsjp "mask.success=0x%08x\n" 345172621Scsjp "mask.failure=0x%08x\n" 346172621Scsjp "asid=%d\n" 347172621Scsjp "termid_addr.port=0x%08x\n" 348172621Scsjp "termid_addr.addr[0]=0x%08x\n" 349172621Scsjp "termid_addr.addr[1]=0x%08x\n" 350172621Scsjp "termid_addr.addr[2]=0x%08x\n" 351172621Scsjp "termid_addr.addr[3]=0x%08x\n", 352172621Scsjp ainfo_addr.ai_auid, ainfo_addr.ai_mask.am_success, 353172621Scsjp ainfo_addr.ai_mask.am_failure, ainfo_addr.ai_asid, 354172621Scsjp ainfo_addr.ai_termid.at_port, 355172621Scsjp ainfo_addr.ai_termid.at_addr[0], 356172621Scsjp ainfo_addr.ai_termid.at_addr[1], 357172621Scsjp ainfo_addr.ai_termid.at_addr[2], 358172621Scsjp ainfo_addr.ai_termid.at_addr[3]); 359172621Scsjp } else { 360172621Scsjp (void) printf("auid=%d\n" 361172621Scsjp "mask.success=0x%08x\n" 362172621Scsjp "mask.failure=0x%08x\n" 363172621Scsjp "asid=%d\n" 364172621Scsjp "termid.port=0x%08x\n" 365172621Scsjp "termid.machine=0x%08x\n", 366172621Scsjp auditinfo.ai_auid, auditinfo.ai_mask.am_success, 367172621Scsjp auditinfo.ai_mask.am_failure, 368172621Scsjp auditinfo.ai_asid, auditinfo.ai_termid.port, 369172621Scsjp auditinfo.ai_termid.machine); 370172621Scsjp } 371162571Srwatson} 372162571Srwatson#endif 373162571Srwatson 374162571Srwatsonvoid 375102944Sdwmalonegroup(struct passwd *pw, int nflag) 3761590Srgrimes{ 3771590Srgrimes struct group *gr; 3781590Srgrimes int cnt, id, lastid, ngroups; 379194494Sbrooks long ngroups_max; 380194494Sbrooks gid_t *groups; 38177314Sdd const char *fmt; 3821590Srgrimes 383194494Sbrooks ngroups_max = sysconf(_SC_NGROUPS_MAX) + 1; 384194494Sbrooks if ((groups = malloc(sizeof(gid_t) * (ngroups_max))) == NULL) 385194494Sbrooks err(1, "malloc"); 386194494Sbrooks 3871590Srgrimes if (pw) { 388194494Sbrooks ngroups = ngroups_max; 3891590Srgrimes (void) getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups); 3901590Srgrimes } else { 391194494Sbrooks ngroups = getgroups(ngroups_max, groups); 3921590Srgrimes } 3931590Srgrimes fmt = nflag ? "%s" : "%u"; 3941590Srgrimes for (lastid = -1, cnt = 0; cnt < ngroups; ++cnt) { 3951590Srgrimes if (lastid == (id = groups[cnt])) 3961590Srgrimes continue; 3971590Srgrimes if (nflag) { 39827418Scharnier if ((gr = getgrgid(id))) 3991590Srgrimes (void)printf(fmt, gr->gr_name); 4001590Srgrimes else 4011590Srgrimes (void)printf(*fmt == ' ' ? " %u" : "%u", 4021590Srgrimes id); 4031590Srgrimes fmt = " %s"; 4041590Srgrimes } else { 4051590Srgrimes (void)printf(fmt, id); 4061590Srgrimes fmt = " %u"; 4071590Srgrimes } 4081590Srgrimes lastid = id; 4091590Srgrimes } 4101590Srgrimes (void)printf("\n"); 411194494Sbrooks free(groups); 4121590Srgrimes} 4131590Srgrimes 414128900Srwatsonvoid 415128900Srwatsonmaclabel(void) 416128900Srwatson{ 417128900Srwatson char *string; 418128900Srwatson mac_t label; 419128900Srwatson int error; 420128900Srwatson 421128900Srwatson error = mac_prepare_process_label(&label); 422128900Srwatson if (error == -1) 423128900Srwatson errx(1, "mac_prepare_type: %s", strerror(errno)); 424128900Srwatson 425128900Srwatson error = mac_get_proc(label); 426128900Srwatson if (error == -1) 427128900Srwatson errx(1, "mac_get_proc: %s", strerror(errno)); 428128900Srwatson 429128900Srwatson error = mac_to_text(label, &string); 430128900Srwatson if (error == -1) 431128900Srwatson errx(1, "mac_to_text: %s", strerror(errno)); 432128900Srwatson 433128900Srwatson (void)printf("%s\n", string); 434128900Srwatson mac_free(label); 435128900Srwatson free(string); 436128900Srwatson} 437128900Srwatson 4381590Srgrimesstruct passwd * 439102944Sdwmalonewho(char *u) 4401590Srgrimes{ 4411590Srgrimes struct passwd *pw; 4421590Srgrimes long id; 4431590Srgrimes char *ep; 4441590Srgrimes 4451590Srgrimes /* 4461590Srgrimes * Translate user argument into a pw pointer. First, try to 4471590Srgrimes * get it as specified. If that fails, try it as a number. 4481590Srgrimes */ 44927418Scharnier if ((pw = getpwnam(u))) 4501590Srgrimes return(pw); 4511590Srgrimes id = strtol(u, &ep, 10); 4521590Srgrimes if (*u && !*ep && (pw = getpwuid(id))) 4531590Srgrimes return(pw); 45427418Scharnier errx(1, "%s: no such user", u); 4551590Srgrimes /* NOTREACHED */ 4561590Srgrimes} 4571590Srgrimes 4581590Srgrimesvoid 459102944Sdwmalonepline(struct passwd *pw) 46038468Sobrien{ 46138468Sobrien 46238468Sobrien if (!pw) { 463144840Sstefanf if ((pw = getpwuid(getuid())) == NULL) 46438468Sobrien err(1, "getpwuid"); 46538468Sobrien } 46638468Sobrien 46751032Sbillf (void)printf("%s:%s:%d:%d:%s:%ld:%ld:%s:%s:%s\n", pw->pw_name, 46838468Sobrien pw->pw_passwd, pw->pw_uid, pw->pw_gid, pw->pw_class, 46951032Sbillf (long)pw->pw_change, (long)pw->pw_expire, pw->pw_gecos, 47038468Sobrien pw->pw_dir, pw->pw_shell); 47138468Sobrien} 47238468Sobrien 47338468Sobrien 47438468Sobrienvoid 475102944Sdwmaloneusage(void) 4761590Srgrimes{ 47783452Sru 47883452Sru if (isgroups) 47983452Sru (void)fprintf(stderr, "usage: groups [user]\n"); 48083452Sru else if (iswhoami) 48183452Sru (void)fprintf(stderr, "usage: whoami\n"); 48283452Sru else 483219304Strasz (void)fprintf(stderr, "%s\n%s%s\n%s\n%s\n%s\n%s\n%s\n%s\n", 48483452Sru "usage: id [user]", 485162571Srwatson#ifdef USE_BSM_AUDIT 486162578Srwatson " id -A\n", 487162571Srwatson#else 488162571Srwatson "", 489162571Srwatson#endif 490162578Srwatson " id -G [-n] [user]", 491162578Srwatson " id -M", 492162578Srwatson " id -P [user]", 493219304Strasz " id -c", 49483452Sru " id -g [-nr] [user]", 49583452Sru " id -p [user]", 49683452Sru " id -u [-nr] [user]"); 4971590Srgrimes exit(1); 4981590Srgrimes} 499