id.c revision 194494
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 * 3. All advertising materials mentioning features or use of this software 141590Srgrimes * must display the following acknowledgement: 151590Srgrimes * This product includes software developed by the University of 161590Srgrimes * California, Berkeley and its contributors. 171590Srgrimes * 4. Neither the name of the University nor the names of its contributors 181590Srgrimes * may be used to endorse or promote products derived from this software 191590Srgrimes * without specific prior written permission. 201590Srgrimes * 211590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241590Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311590Srgrimes * SUCH DAMAGE. 321590Srgrimes */ 331590Srgrimes 341590Srgrimes#ifndef lint 3527418Scharnierstatic const char copyright[] = 361590Srgrimes"@(#) Copyright (c) 1991, 1993\n\ 371590Srgrimes The Regents of the University of California. All rights reserved.\n"; 381590Srgrimes#endif /* not lint */ 391590Srgrimes 401590Srgrimes#ifndef lint 4127418Scharnier#if 0 421590Srgrimesstatic char sccsid[] = "@(#)id.c 8.2 (Berkeley) 2/16/94"; 4327418Scharnier#endif 441590Srgrimes#endif /* not lint */ 4599112Sobrien#include <sys/cdefs.h> 4699112Sobrien__FBSDID("$FreeBSD: head/usr.bin/id/id.c 194494 2009-06-19 15:58:24Z brooks $"); 471590Srgrimes 481590Srgrimes#include <sys/param.h> 49128900Srwatson#include <sys/mac.h> 501590Srgrimes 51162571Srwatson#ifdef USE_BSM_AUDIT 52162571Srwatson#include <bsm/audit.h> 53162571Srwatson#endif 54162571Srwatson 5527418Scharnier#include <err.h> 56128900Srwatson#include <errno.h> 571590Srgrimes#include <grp.h> 581590Srgrimes#include <pwd.h> 591590Srgrimes#include <stdio.h> 601590Srgrimes#include <stdlib.h> 611590Srgrimes#include <string.h> 621590Srgrimes#include <unistd.h> 631590Srgrimes 64145672Srobertvoid id_print(struct passwd *, int, int, int); 6592920Simpvoid pline(struct passwd *); 6692920Simpvoid pretty(struct passwd *); 67162571Srwatsonvoid auditid(void); 6892920Simpvoid group(struct passwd *, int); 69128900Srwatsonvoid maclabel(void); 7092920Simpvoid usage(void); 71145628Srobertstruct passwd *who(char *); 721590Srgrimes 7383452Sruint isgroups, iswhoami; 7483452Sru 751590Srgrimesint 76102944Sdwmalonemain(int argc, char *argv[]) 771590Srgrimes{ 781590Srgrimes struct group *gr; 791590Srgrimes struct passwd *pw; 80128900Srwatson int Gflag, Mflag, Pflag, ch, gflag, id, nflag, pflag, rflag, uflag; 81162578Srwatson int Aflag; 8283452Sru const char *myname; 831590Srgrimes 84128900Srwatson Gflag = Mflag = Pflag = gflag = nflag = pflag = rflag = uflag = 0; 85162578Srwatson Aflag = 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, 99162672Sceri (isgroups || iswhoami) ? "" : "APGMagnpru")) != -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; 1171590Srgrimes case 'g': 1181590Srgrimes gflag = 1; 1191590Srgrimes break; 1201590Srgrimes case 'n': 1211590Srgrimes nflag = 1; 1221590Srgrimes break; 1231590Srgrimes case 'p': 1241590Srgrimes pflag = 1; 1251590Srgrimes break; 1261590Srgrimes case 'r': 1271590Srgrimes rflag = 1; 1281590Srgrimes break; 1291590Srgrimes case 'u': 1301590Srgrimes uflag = 1; 1311590Srgrimes break; 1321590Srgrimes case '?': 1331590Srgrimes default: 1341590Srgrimes usage(); 1351590Srgrimes } 1361590Srgrimes argc -= optind; 1371590Srgrimes argv += optind; 1381590Srgrimes 13983452Sru if (iswhoami && argc > 0) 14083452Sru usage(); 14183452Sru 142162578Srwatson switch(Aflag + Gflag + Mflag + Pflag + gflag + pflag + uflag) { 1431590Srgrimes case 1: 1441590Srgrimes break; 1451590Srgrimes case 0: 1461590Srgrimes if (!nflag && !rflag) 1471590Srgrimes break; 1481590Srgrimes /* FALLTHROUGH */ 1491590Srgrimes default: 1501590Srgrimes usage(); 1511590Srgrimes } 1521590Srgrimes 1531590Srgrimes pw = *argv ? who(*argv) : NULL; 1541590Srgrimes 155128900Srwatson if (Mflag && pw != NULL) 156128900Srwatson usage(); 157128900Srwatson 158162571Srwatson#ifdef USE_BSM_AUDIT 159162578Srwatson if (Aflag) { 160162571Srwatson auditid(); 161162571Srwatson exit(0); 162162571Srwatson } 163162571Srwatson#endif 164162571Srwatson 1651590Srgrimes if (gflag) { 1661590Srgrimes id = pw ? pw->pw_gid : rflag ? getgid() : getegid(); 1671590Srgrimes if (nflag && (gr = getgrgid(id))) 1681590Srgrimes (void)printf("%s\n", gr->gr_name); 1691590Srgrimes else 1701590Srgrimes (void)printf("%u\n", id); 1711590Srgrimes exit(0); 1721590Srgrimes } 1731590Srgrimes 1741590Srgrimes if (uflag) { 1751590Srgrimes id = pw ? pw->pw_uid : rflag ? getuid() : geteuid(); 1761590Srgrimes if (nflag && (pw = getpwuid(id))) 1771590Srgrimes (void)printf("%s\n", pw->pw_name); 1781590Srgrimes else 1791590Srgrimes (void)printf("%u\n", id); 1801590Srgrimes exit(0); 1811590Srgrimes } 1821590Srgrimes 1831590Srgrimes if (Gflag) { 1841590Srgrimes group(pw, nflag); 1851590Srgrimes exit(0); 1861590Srgrimes } 1871590Srgrimes 188128900Srwatson if (Mflag) { 189128900Srwatson maclabel(); 190128900Srwatson exit(0); 191128900Srwatson } 192128900Srwatson 19338468Sobrien if (Pflag) { 19438468Sobrien pline(pw); 19538468Sobrien exit(0); 19638468Sobrien } 19738468Sobrien 1981590Srgrimes if (pflag) { 1991590Srgrimes pretty(pw); 2001590Srgrimes exit(0); 2011590Srgrimes } 2021590Srgrimes 203145628Srobert if (pw) { 204145672Srobert id_print(pw, 1, 0, 0); 205145628Srobert } 206145628Srobert else { 207145628Srobert id = getuid(); 208165028Smpp pw = getpwuid(id); 209165028Smpp id_print(pw, 0, 1, 1); 210145628Srobert } 2111590Srgrimes exit(0); 2121590Srgrimes} 2131590Srgrimes 2141590Srgrimesvoid 215102944Sdwmalonepretty(struct passwd *pw) 2161590Srgrimes{ 2171590Srgrimes struct group *gr; 2181590Srgrimes u_int eid, rid; 2191590Srgrimes char *login; 2201590Srgrimes 2211590Srgrimes if (pw) { 2221590Srgrimes (void)printf("uid\t%s\n", pw->pw_name); 2231590Srgrimes (void)printf("groups\t"); 2241590Srgrimes group(pw, 1); 2251590Srgrimes } else { 2261590Srgrimes if ((login = getlogin()) == NULL) 22727418Scharnier err(1, "getlogin"); 2281590Srgrimes 2291590Srgrimes pw = getpwuid(rid = getuid()); 2301590Srgrimes if (pw == NULL || strcmp(login, pw->pw_name)) 2311590Srgrimes (void)printf("login\t%s\n", login); 2321590Srgrimes if (pw) 2331590Srgrimes (void)printf("uid\t%s\n", pw->pw_name); 2341590Srgrimes else 2351590Srgrimes (void)printf("uid\t%u\n", rid); 2368874Srgrimes 23748566Sbillf if ((eid = geteuid()) != rid) { 23827418Scharnier if ((pw = getpwuid(eid))) 23933576Ssteve (void)printf("euid\t%s\n", pw->pw_name); 2401590Srgrimes else 24133576Ssteve (void)printf("euid\t%u\n", eid); 24248566Sbillf } 24348566Sbillf if ((rid = getgid()) != (eid = getegid())) { 24427418Scharnier if ((gr = getgrgid(rid))) 2451590Srgrimes (void)printf("rgid\t%s\n", gr->gr_name); 2461590Srgrimes else 2471590Srgrimes (void)printf("rgid\t%u\n", rid); 24848566Sbillf } 2491590Srgrimes (void)printf("groups\t"); 2501590Srgrimes group(NULL, 1); 2511590Srgrimes } 2521590Srgrimes} 2531590Srgrimes 2541590Srgrimesvoid 255145672Srobertid_print(struct passwd *pw, int use_ggl, int p_euid, int p_egid) 2561590Srgrimes{ 2571590Srgrimes struct group *gr; 258145628Srobert gid_t gid, egid, lastgid; 259145628Srobert uid_t uid, euid; 260145628Srobert int cnt, ngroups; 261194494Sbrooks long ngroups_max; 262194494Sbrooks gid_t *groups; 26377314Sdd const char *fmt; 2641590Srgrimes 265165028Smpp if (pw != NULL) { 266165028Smpp uid = pw->pw_uid; 267165028Smpp gid = pw->pw_gid; 268165028Smpp } 269165028Smpp else { 270165028Smpp uid = getuid(); 271165028Smpp gid = getgid(); 272165028Smpp } 273145628Srobert 274194494Sbrooks ngroups_max = sysconf(_SC_NGROUPS_MAX) + 1; 275194494Sbrooks if ((groups = malloc(sizeof(gid_t) * ngroups_max)) == NULL) 276194494Sbrooks err(1, "malloc"); 277194494Sbrooks 278165028Smpp if (use_ggl && pw != NULL) { 279194494Sbrooks ngroups = ngroups_max; 280145672Srobert getgrouplist(pw->pw_name, gid, groups, &ngroups); 281145672Srobert } 282145672Srobert else { 283194494Sbrooks ngroups = getgroups(ngroups_max, groups); 284145672Srobert } 285145628Srobert 286165028Smpp if (pw != NULL) 287165028Smpp printf("uid=%u(%s)", uid, pw->pw_name); 288165028Smpp else 289165028Smpp printf("uid=%u", getuid()); 290159008Sstefanf printf(" gid=%u", gid); 291159008Sstefanf if ((gr = getgrgid(gid))) 292159008Sstefanf (void)printf("(%s)", gr->gr_name); 293145628Srobert if (p_euid && (euid = geteuid()) != uid) { 294145628Srobert (void)printf(" euid=%u", euid); 295145628Srobert if ((pw = getpwuid(euid))) 2961590Srgrimes (void)printf("(%s)", pw->pw_name); 2971590Srgrimes } 298145628Srobert if (p_egid && (egid = getegid()) != gid) { 299145628Srobert (void)printf(" egid=%u", egid); 300145628Srobert if ((gr = getgrgid(egid))) 3011590Srgrimes (void)printf("(%s)", gr->gr_name); 3021590Srgrimes } 3031590Srgrimes fmt = " groups=%u"; 30410359Sdg for (lastgid = -1, cnt = 0; cnt < ngroups; ++cnt) { 30510359Sdg if (lastgid == (gid = groups[cnt])) 3061590Srgrimes continue; 307145628Srobert printf(fmt, gid); 308165626Sstefanf fmt = ",%u"; 30927418Scharnier if ((gr = getgrgid(gid))) 310145628Srobert printf("(%s)", gr->gr_name); 31110359Sdg lastgid = gid; 3121590Srgrimes } 313145628Srobert printf("\n"); 314194494Sbrooks free(groups); 3151590Srgrimes} 3161590Srgrimes 317162571Srwatson#ifdef USE_BSM_AUDIT 3181590Srgrimesvoid 319162571Srwatsonauditid(void) 320162571Srwatson{ 321162571Srwatson auditinfo_t auditinfo; 322172621Scsjp auditinfo_addr_t ainfo_addr; 323172621Scsjp int ret, extended; 324162571Srwatson 325172621Scsjp extended = 0; 326172621Scsjp ret = getaudit(&auditinfo); 327172621Scsjp if (ret < 0 && errno == E2BIG) { 328172621Scsjp if (getaudit_addr(&ainfo_addr, sizeof(ainfo_addr)) < 0) 329172621Scsjp err(1, "getaudit_addr"); 330172621Scsjp extended = 1; 331172621Scsjp } else if (ret < 0) 332162656Sru err(1, "getaudit"); 333172621Scsjp if (extended != 0) { 334172621Scsjp (void) printf("auid=%d\n" 335172621Scsjp "mask.success=0x%08x\n" 336172621Scsjp "mask.failure=0x%08x\n" 337172621Scsjp "asid=%d\n" 338172621Scsjp "termid_addr.port=0x%08x\n" 339172621Scsjp "termid_addr.addr[0]=0x%08x\n" 340172621Scsjp "termid_addr.addr[1]=0x%08x\n" 341172621Scsjp "termid_addr.addr[2]=0x%08x\n" 342172621Scsjp "termid_addr.addr[3]=0x%08x\n", 343172621Scsjp ainfo_addr.ai_auid, ainfo_addr.ai_mask.am_success, 344172621Scsjp ainfo_addr.ai_mask.am_failure, ainfo_addr.ai_asid, 345172621Scsjp ainfo_addr.ai_termid.at_port, 346172621Scsjp ainfo_addr.ai_termid.at_addr[0], 347172621Scsjp ainfo_addr.ai_termid.at_addr[1], 348172621Scsjp ainfo_addr.ai_termid.at_addr[2], 349172621Scsjp ainfo_addr.ai_termid.at_addr[3]); 350172621Scsjp } else { 351172621Scsjp (void) printf("auid=%d\n" 352172621Scsjp "mask.success=0x%08x\n" 353172621Scsjp "mask.failure=0x%08x\n" 354172621Scsjp "asid=%d\n" 355172621Scsjp "termid.port=0x%08x\n" 356172621Scsjp "termid.machine=0x%08x\n", 357172621Scsjp auditinfo.ai_auid, auditinfo.ai_mask.am_success, 358172621Scsjp auditinfo.ai_mask.am_failure, 359172621Scsjp auditinfo.ai_asid, auditinfo.ai_termid.port, 360172621Scsjp auditinfo.ai_termid.machine); 361172621Scsjp } 362162571Srwatson} 363162571Srwatson#endif 364162571Srwatson 365162571Srwatsonvoid 366102944Sdwmalonegroup(struct passwd *pw, int nflag) 3671590Srgrimes{ 3681590Srgrimes struct group *gr; 3691590Srgrimes int cnt, id, lastid, ngroups; 370194494Sbrooks long ngroups_max; 371194494Sbrooks gid_t *groups; 37277314Sdd const char *fmt; 3731590Srgrimes 374194494Sbrooks ngroups_max = sysconf(_SC_NGROUPS_MAX) + 1; 375194494Sbrooks if ((groups = malloc(sizeof(gid_t) * (ngroups_max))) == NULL) 376194494Sbrooks err(1, "malloc"); 377194494Sbrooks 3781590Srgrimes if (pw) { 379194494Sbrooks ngroups = ngroups_max; 3801590Srgrimes (void) getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups); 3811590Srgrimes } else { 382194494Sbrooks ngroups = getgroups(ngroups_max, groups); 3831590Srgrimes } 3841590Srgrimes fmt = nflag ? "%s" : "%u"; 3851590Srgrimes for (lastid = -1, cnt = 0; cnt < ngroups; ++cnt) { 3861590Srgrimes if (lastid == (id = groups[cnt])) 3871590Srgrimes continue; 3881590Srgrimes if (nflag) { 38927418Scharnier if ((gr = getgrgid(id))) 3901590Srgrimes (void)printf(fmt, gr->gr_name); 3911590Srgrimes else 3921590Srgrimes (void)printf(*fmt == ' ' ? " %u" : "%u", 3931590Srgrimes id); 3941590Srgrimes fmt = " %s"; 3951590Srgrimes } else { 3961590Srgrimes (void)printf(fmt, id); 3971590Srgrimes fmt = " %u"; 3981590Srgrimes } 3991590Srgrimes lastid = id; 4001590Srgrimes } 4011590Srgrimes (void)printf("\n"); 402194494Sbrooks free(groups); 4031590Srgrimes} 4041590Srgrimes 405128900Srwatsonvoid 406128900Srwatsonmaclabel(void) 407128900Srwatson{ 408128900Srwatson char *string; 409128900Srwatson mac_t label; 410128900Srwatson int error; 411128900Srwatson 412128900Srwatson error = mac_prepare_process_label(&label); 413128900Srwatson if (error == -1) 414128900Srwatson errx(1, "mac_prepare_type: %s", strerror(errno)); 415128900Srwatson 416128900Srwatson error = mac_get_proc(label); 417128900Srwatson if (error == -1) 418128900Srwatson errx(1, "mac_get_proc: %s", strerror(errno)); 419128900Srwatson 420128900Srwatson error = mac_to_text(label, &string); 421128900Srwatson if (error == -1) 422128900Srwatson errx(1, "mac_to_text: %s", strerror(errno)); 423128900Srwatson 424128900Srwatson (void)printf("%s\n", string); 425128900Srwatson mac_free(label); 426128900Srwatson free(string); 427128900Srwatson} 428128900Srwatson 4291590Srgrimesstruct passwd * 430102944Sdwmalonewho(char *u) 4311590Srgrimes{ 4321590Srgrimes struct passwd *pw; 4331590Srgrimes long id; 4341590Srgrimes char *ep; 4351590Srgrimes 4361590Srgrimes /* 4371590Srgrimes * Translate user argument into a pw pointer. First, try to 4381590Srgrimes * get it as specified. If that fails, try it as a number. 4391590Srgrimes */ 44027418Scharnier if ((pw = getpwnam(u))) 4411590Srgrimes return(pw); 4421590Srgrimes id = strtol(u, &ep, 10); 4431590Srgrimes if (*u && !*ep && (pw = getpwuid(id))) 4441590Srgrimes return(pw); 44527418Scharnier errx(1, "%s: no such user", u); 4461590Srgrimes /* NOTREACHED */ 4471590Srgrimes} 4481590Srgrimes 4491590Srgrimesvoid 450102944Sdwmalonepline(struct passwd *pw) 45138468Sobrien{ 45238468Sobrien 45338468Sobrien if (!pw) { 454144840Sstefanf if ((pw = getpwuid(getuid())) == NULL) 45538468Sobrien err(1, "getpwuid"); 45638468Sobrien } 45738468Sobrien 45851032Sbillf (void)printf("%s:%s:%d:%d:%s:%ld:%ld:%s:%s:%s\n", pw->pw_name, 45938468Sobrien pw->pw_passwd, pw->pw_uid, pw->pw_gid, pw->pw_class, 46051032Sbillf (long)pw->pw_change, (long)pw->pw_expire, pw->pw_gecos, 46138468Sobrien pw->pw_dir, pw->pw_shell); 46238468Sobrien} 46338468Sobrien 46438468Sobrien 46538468Sobrienvoid 466102944Sdwmaloneusage(void) 4671590Srgrimes{ 46883452Sru 46983452Sru if (isgroups) 47083452Sru (void)fprintf(stderr, "usage: groups [user]\n"); 47183452Sru else if (iswhoami) 47283452Sru (void)fprintf(stderr, "usage: whoami\n"); 47383452Sru else 474162578Srwatson (void)fprintf(stderr, "%s\n%s%s\n%s\n%s\n%s\n%s\n%s\n", 47583452Sru "usage: id [user]", 476162571Srwatson#ifdef USE_BSM_AUDIT 477162578Srwatson " id -A\n", 478162571Srwatson#else 479162571Srwatson "", 480162571Srwatson#endif 481162578Srwatson " id -G [-n] [user]", 482162578Srwatson " id -M", 483162578Srwatson " id -P [user]", 48483452Sru " id -g [-nr] [user]", 48583452Sru " id -p [user]", 48683452Sru " id -u [-nr] [user]"); 4871590Srgrimes exit(1); 4881590Srgrimes} 489