diff options
author | Cameron Katri <me@cameronkatri.com> | 2021-05-09 14:20:58 -0400 |
---|---|---|
committer | Cameron Katri <me@cameronkatri.com> | 2021-05-09 14:20:58 -0400 |
commit | 5fd83771641d15c418f747bd343ba6738d3875f7 (patch) | |
tree | 5abf0f78f680d9837dbd93d4d4c3933bb7509599 /shell_cmds/id | |
download | apple_cmds-5fd83771641d15c418f747bd343ba6738d3875f7.tar.gz apple_cmds-5fd83771641d15c418f747bd343ba6738d3875f7.tar.zst apple_cmds-5fd83771641d15c418f747bd343ba6738d3875f7.zip |
Import macOS userland
adv_cmds-176
basic_cmds-55
bootstrap_cmds-116.100.1
developer_cmds-66
diskdev_cmds-667.40.1
doc_cmds-53.60.1
file_cmds-321.40.3
mail_cmds-35
misc_cmds-34
network_cmds-606.40.1
patch_cmds-17
remote_cmds-63
shell_cmds-216.60.1
system_cmds-880.60.2
text_cmds-106
Diffstat (limited to 'shell_cmds/id')
-rw-r--r-- | shell_cmds/id/groups.1 | 63 | ||||
-rw-r--r-- | shell_cmds/id/id.1 | 167 | ||||
-rw-r--r-- | shell_cmds/id/id.c | 529 | ||||
-rw-r--r-- | shell_cmds/id/open_directory.c | 229 | ||||
-rw-r--r-- | shell_cmds/id/open_directory.h | 18 | ||||
-rw-r--r-- | shell_cmds/id/whoami.1 | 60 |
6 files changed, 1066 insertions, 0 deletions
diff --git a/shell_cmds/id/groups.1 b/shell_cmds/id/groups.1 new file mode 100644 index 0000000..00c030b --- /dev/null +++ b/shell_cmds/id/groups.1 @@ -0,0 +1,63 @@ +.\" Copyright (c) 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)groups.1 8.1 (Berkeley) 6/6/93 +.\" $FreeBSD: src/usr.bin/id/groups.1,v 1.10 2006/12/23 17:14:01 ru Exp $ +.\" +.Dd June 6, 1993 +.Dt GROUPS 1 +.Os +.Sh NAME +.Nm groups +.Nd show group memberships +.Sh SYNOPSIS +.Nm +.Op Ar user +.Sh DESCRIPTION +The +.Nm +utility has been obsoleted by the +.Xr id 1 +utility, and is equivalent to +.Dq Nm id Fl Gn Op Ar user . +The command +.Dq Nm id Fl p +is suggested for normal interactive use. +.Pp +The +.Nm +utility displays the groups to which you (or the optionally specified +.Ar user ) +belong. +.Sh EXIT STATUS +.Ex -std +.Sh SEE ALSO +.Xr id 1 diff --git a/shell_cmds/id/id.1 b/shell_cmds/id/id.1 new file mode 100644 index 0000000..1090c9a --- /dev/null +++ b/shell_cmds/id/id.1 @@ -0,0 +1,167 @@ +.\" Copyright (c) 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" the Institute of Electrical and Electronics Engineers, Inc. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)id.1 8.1 (Berkeley) 6/6/93 +.\" $FreeBSD: src/usr.bin/id/id.1,v 1.18 2006/09/26 22:28:12 ceri Exp $ +.\" +.Dd September 26, 2006 +.Dt ID 1 +.Os +.Sh NAME +.Nm id +.Nd return user identity +.Sh SYNOPSIS +.Nm +.Op Ar user +.Nm +.Fl A +.Nm +.Fl F +.Op Ar user +.Nm +.Fl G Op Fl n +.Op Ar user +.Nm +.Fl M +.Nm +.Fl P +.Op Ar user +.Nm +.Fl g Op Fl nr +.Op Ar user +.Nm +.Fl p +.Op Ar user +.Nm +.Fl u Op Fl nr +.Op Ar user +.Sh DESCRIPTION +The +.Nm +utility displays the user and group names and numeric IDs, of the +calling process, to the standard output. +If the real and effective IDs are different, both are displayed, +otherwise only the real ID is displayed. +.Pp +If a +.Ar user +(login name or user ID) +is specified, the user and group IDs of that user are displayed. +In this case, the real and effective IDs are assumed to be the same. +.Pp +The options are as follows: +.Bl -tag -width indent +.It Fl A +Display the process audit user ID and other process audit properties, which +requires privilege. +.It Fl F +Display the full name of the user. +.It Fl G +Display the different group IDs (effective, real and supplementary) +as white-space separated numbers, in no particular order. +.It Fl M +Display the MAC label of the current process. +.It Fl P +Display the id as a password file entry. +.It Fl a +Ignored for compatibility with other +.Nm +implementations. +.It Fl g +Display the effective group ID as a number. +.It Fl n +Display the name of the user or group ID for the +.Fl G , +.Fl g +and +.Fl u +options instead of the number. +If any of the ID numbers cannot be mapped into names, the number will be +displayed as usual. +.It Fl p +Make the output human-readable. +If the user name returned by +.Xr getlogin 2 +is different from the login name referenced by the user ID, the name +returned by +.Xr getlogin 2 +is displayed, preceded by the keyword +.Dq login . +The user ID as a name is displayed, preceded by the keyword +.Dq uid . +If the effective user ID is different from the real user ID, the real user +ID is displayed as a name, preceded by the keyword +.Dq euid . +If the effective group ID is different from the real group ID, the real group +ID is displayed as a name, preceded by the keyword +.Dq rgid . +The list of groups to which the user belongs is then displayed as names, +preceded by the keyword +.Dq groups . +Each display is on a separate line. +.It Fl r +Display the real ID for the +.Fl g +and +.Fl u +options instead of the effective ID. +.It Fl u +Display the effective user ID as a number. +.El +.Sh EXIT STATUS +.Ex -std +.Sh SEE ALSO +.Xr who 1 +.Sh STANDARDS +The +.Nm +function is expected to conform to +.St -p1003.2 . +.Sh HISTORY +The +historic +.Xr groups 1 +command is equivalent to +.Dq Nm id Fl Gn Op Ar user . +.Pp +The +historic +.Xr whoami 1 +command is equivalent to +.Dq Nm id Fl un . +.Pp +The +.Nm +command appeared in +.Bx 4.4 . diff --git a/shell_cmds/id/id.c b/shell_cmds/id/id.c new file mode 100644 index 0000000..2567770 --- /dev/null +++ b/shell_cmds/id/id.c @@ -0,0 +1,529 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static const char copyright[] = +"@(#) Copyright (c) 1991, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +#if 0 +static char sccsid[] = "@(#)id.c 8.2 (Berkeley) 2/16/94"; +#endif +#endif /* not lint */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD: src/usr.bin/id/id.c,v 1.33 2006/12/29 12:28:34 stefanf Exp $"); + +#include <sys/param.h> +#ifndef __APPLE__ +#include <sys/mac.h> +#endif /* !__APPLE__ */ + +#ifdef USE_BSM_AUDIT +#include <bsm/audit.h> +#endif + +#include <err.h> +#include <errno.h> +#include <grp.h> +#include <pwd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +void id_print(struct passwd *, int, int, int); +void pline(struct passwd *); +void pretty(struct passwd *); +void auditid(void); +void fullname(struct passwd *); +void group(struct passwd *, int); +void maclabel(void); +void usage(void); +struct passwd *who(char *); + +int isgroups, iswhoami; + +#ifdef __APPLE__ +// SPI for 5235093 +int32_t getgrouplist_2(const char *, gid_t, gid_t **); +#endif + +int +main(int argc, char *argv[]) +{ + struct group *gr; + struct passwd *pw; + int Gflag, Mflag, Pflag, ch, gflag, id, nflag, pflag, rflag, uflag; + int Aflag; + int Fflag; + const char *myname; + + Gflag = Mflag = Pflag = gflag = nflag = pflag = rflag = uflag = 0; + Aflag = 0; + Fflag = 0; + + myname = strrchr(argv[0], '/'); + myname = (myname != NULL) ? myname + 1 : argv[0]; + if (strcmp(myname, "groups") == 0) { + isgroups = 1; + Gflag = nflag = 1; + } + else if (strcmp(myname, "whoami") == 0) { + iswhoami = 1; + uflag = nflag = 1; + } + + while ((ch = getopt(argc, argv, + (isgroups || iswhoami) ? "" : "AFPGMagnpru")) != -1) + switch(ch) { +#ifdef USE_BSM_AUDIT + case 'A': + Aflag = 1; + break; +#endif + case 'F': + Fflag = 1; + break; + case 'G': + Gflag = 1; + break; + case 'M': + Mflag = 1; + break; + case 'P': + Pflag = 1; + break; + case 'a': + break; + case 'g': + gflag = 1; + break; + case 'n': + nflag = 1; + break; + case 'p': + pflag = 1; + break; + case 'r': + rflag = 1; + break; + case 'u': + uflag = 1; + break; + case '?': + default: + usage(); + } + argc -= optind; + argv += optind; + + if (iswhoami && argc > 0) + usage(); + + switch(Aflag + Fflag + Gflag + Mflag + Pflag + gflag + pflag + uflag) { + case 1: + break; + case 0: + if (!nflag && !rflag) + break; + /* FALLTHROUGH */ + default: + usage(); + } + + pw = *argv ? who(*argv) : NULL; + + if (Mflag && pw != NULL) + usage(); + +#ifdef USE_BSM_AUDIT + if (Aflag) { + auditid(); + exit(0); + } +#endif + + if (Fflag) { + fullname(pw); + exit(0); + } + + if (gflag) { + id = pw ? pw->pw_gid : rflag ? getgid() : getegid(); + if (nflag && (gr = getgrgid(id))) + (void)printf("%s\n", gr->gr_name); + else + (void)printf("%u\n", id); + exit(0); + } + + if (uflag) { + id = pw ? pw->pw_uid : rflag ? getuid() : geteuid(); + if (nflag && (pw = getpwuid(id))) + (void)printf("%s\n", pw->pw_name); + else + (void)printf("%u\n", id); + exit(0); + } + + if (Gflag) { + group(pw, nflag); + exit(0); + } + + if (Mflag) { + maclabel(); + exit(0); + } + + if (Pflag) { + pline(pw); + exit(0); + } + + if (pflag) { + pretty(pw); + exit(0); + } + + if (pw) { + id_print(pw, 1, 0, 0); + } + else { + id = getuid(); + pw = getpwuid(id); + id_print(pw, 0, 1, 1); + } + exit(0); +} + +void +pretty(struct passwd *pw) +{ + struct group *gr; + u_int eid, rid; + char *login; + + if (pw) { + (void)printf("uid\t%s\n", pw->pw_name); + (void)printf("groups\t"); + group(pw, 1); + } else { + if ((login = getlogin()) == NULL) + err(1, "getlogin"); + + pw = getpwuid(rid = getuid()); + if (pw == NULL || strcmp(login, pw->pw_name)) + (void)printf("login\t%s\n", login); + if (pw) + (void)printf("uid\t%s\n", pw->pw_name); + else + (void)printf("uid\t%u\n", rid); + + if ((eid = geteuid()) != rid) { + if ((pw = getpwuid(eid))) + (void)printf("euid\t%s\n", pw->pw_name); + else + (void)printf("euid\t%u\n", eid); + } + if ((rid = getgid()) != (eid = getegid())) { + if ((gr = getgrgid(rid))) + (void)printf("rgid\t%s\n", gr->gr_name); + else + (void)printf("rgid\t%u\n", rid); + } + (void)printf("groups\t"); + group(NULL, 1); + } +} + +void +id_print(struct passwd *pw, int use_ggl, int p_euid, int p_egid) +{ + struct group *gr; + gid_t gid, egid, lastgid; + uid_t uid, euid; + int cnt, ngroups; +#ifdef __APPLE__ + gid_t *groups = NULL; +#else + gid_t groups[NGROUPS + 1]; +#endif + const char *fmt; + +#ifdef __APPLE__ + if (pw == NULL) { + pw = getpwuid(getuid()); + } + + use_ggl = 1; +#endif + + if (pw != NULL) { + uid = pw->pw_uid; + gid = pw->pw_gid; + } + else { + uid = getuid(); + gid = getgid(); + } + + if (use_ggl && pw != NULL) { +#ifdef __APPLE__ + // 5235093 + ngroups = getgrouplist_2(pw->pw_name, gid, &groups); +#else + ngroups = NGROUPS + 1; + getgrouplist(pw->pw_name, gid, groups, &ngroups); +#endif + } + else { +#ifdef __APPLE__ + groups = malloc((NGROUPS + 1) * sizeof(gid_t)); +#endif + ngroups = getgroups(NGROUPS + 1, groups); + } + +#ifdef __APPLE__ + if (ngroups < 0) + warn("failed to retrieve group list"); +#endif + + if (pw != NULL) + printf("uid=%u(%s)", uid, pw->pw_name); + else + printf("uid=%u", getuid()); + printf(" gid=%u", gid); + if ((gr = getgrgid(gid))) + (void)printf("(%s)", gr->gr_name); + if (p_euid && (euid = geteuid()) != uid) { + (void)printf(" euid=%u", euid); + if ((pw = getpwuid(euid))) + (void)printf("(%s)", pw->pw_name); + } + if (p_egid && (egid = getegid()) != gid) { + (void)printf(" egid=%u", egid); + if ((gr = getgrgid(egid))) + (void)printf("(%s)", gr->gr_name); + } + fmt = " groups=%u"; + for (lastgid = -1, cnt = 0; cnt < ngroups; ++cnt) { + if (lastgid == (gid = groups[cnt])) + continue; + printf(fmt, gid); + fmt = ",%u"; + if ((gr = getgrgid(gid))) + printf("(%s)", gr->gr_name); + lastgid = gid; + } + printf("\n"); +#ifdef __APPLE__ + free(groups); +#endif +} + +#ifdef USE_BSM_AUDIT +void +auditid(void) +{ + auditinfo_addr_t auditinfo; + + if (getaudit_addr(&auditinfo, sizeof(auditinfo)) < 0) + err(1, "getaudit"); + printf("auid=%d\n", auditinfo.ai_auid); + printf("mask.success=0x%08x\n", auditinfo.ai_mask.am_success); + printf("mask.failure=0x%08x\n", auditinfo.ai_mask.am_failure); + printf("termid.port=0x%08x\n", auditinfo.ai_termid.at_port); + printf("asid=%d\n", auditinfo.ai_asid); +} +#endif + +void +fullname(struct passwd *pw) +{ + + if (!pw) { + if ((pw = getpwuid(getuid())) == NULL) + err(1, "getpwuid"); + } + + (void)printf("%s\n", pw->pw_gecos); +} + +void +group(struct passwd *pw, int nflag) +{ + struct group *gr; + int cnt, id, lastid, ngroups; +#ifdef __APPLE__ + gid_t *groups = NULL; +#else + gid_t groups[NGROUPS + 1]; +#endif + const char *fmt; + +#ifdef __APPLE__ + if (pw == NULL) { + pw = getpwuid(getuid()); + } +#endif + + if (pw) { +#ifdef __APPLE__ + // 5235093 + ngroups = getgrouplist_2(pw->pw_name, pw->pw_gid, &groups); +#else + ngroups = NGROUPS + 1; + (void) getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups); +#endif + } else { +#ifdef __APPLE__ + groups = malloc((NGROUPS + 1) * sizeof(gid_t)); +#endif + groups[0] = getgid(); + ngroups = getgroups(NGROUPS, groups + 1) + 1; + } + fmt = nflag ? "%s" : "%u"; + for (lastid = -1, cnt = 0; cnt < ngroups; ++cnt) { + if (lastid == (id = groups[cnt])) + continue; + if (nflag) { + if ((gr = getgrgid(id))) + (void)printf(fmt, gr->gr_name); + else + (void)printf(*fmt == ' ' ? " %u" : "%u", + id); + fmt = " %s"; + } else { + (void)printf(fmt, id); + fmt = " %u"; + } + lastid = id; + } + (void)printf("\n"); +#ifdef __APPLE__ + free(groups); +#endif +} + +void +maclabel(void) +{ +#ifdef __APPLE__ + errx(1, "-M unsupported"); +#else /* !__APPLE__ */ + char *string; + mac_t label; + int error; + + error = mac_prepare_process_label(&label); + if (error == -1) + errx(1, "mac_prepare_type: %s", strerror(errno)); + + error = mac_get_proc(label); + if (error == -1) + errx(1, "mac_get_proc: %s", strerror(errno)); + + error = mac_to_text(label, &string); + if (error == -1) + errx(1, "mac_to_text: %s", strerror(errno)); + + (void)printf("%s\n", string); + mac_free(label); + free(string); +#endif /* __APPLE__ */ +} + +struct passwd * +who(char *u) +{ + struct passwd *pw; + long id; + char *ep; + + /* + * Translate user argument into a pw pointer. First, try to + * get it as specified. If that fails, try it as a number. + */ + if ((pw = getpwnam(u))) + return(pw); + id = strtol(u, &ep, 10); + if (*u && !*ep && (pw = getpwuid(id))) + return(pw); + errx(1, "%s: no such user", u); + /* NOTREACHED */ +} + +void +pline(struct passwd *pw) +{ + + if (!pw) { + if ((pw = getpwuid(getuid())) == NULL) + err(1, "getpwuid"); + } + + (void)printf("%s:%s:%d:%d:%s:%ld:%ld:%s:%s:%s\n", pw->pw_name, + pw->pw_passwd, pw->pw_uid, pw->pw_gid, pw->pw_class, + (long)pw->pw_change, (long)pw->pw_expire, pw->pw_gecos, + pw->pw_dir, pw->pw_shell); +} + + +void +usage(void) +{ + + if (isgroups) + (void)fprintf(stderr, "usage: groups [user]\n"); + else if (iswhoami) + (void)fprintf(stderr, "usage: whoami\n"); + else + (void)fprintf(stderr, "%s\n%s%s\n%s\n%s\n%s\n%s\n%s\n%s\n", + "usage: id [user]", +#ifdef USE_BSM_AUDIT + " id -A\n", +#else + "", +#endif + " id -F [user]", + " id -G [-n] [user]", + " id -M", + " id -P [user]", + " id -g [-nr] [user]", + " id -p [user]", + " id -u [-nr] [user]"); + exit(1); +} diff --git a/shell_cmds/id/open_directory.c b/shell_cmds/id/open_directory.c new file mode 100644 index 0000000..fb34de9 --- /dev/null +++ b/shell_cmds/id/open_directory.c @@ -0,0 +1,229 @@ +#include <membership.h> + +#include "open_directory.h" + +ODNodeRef +CreateNode(void) +{ + CFErrorRef error = NULL; + ODNodeRef node = NULL; + + node = ODNodeCreateWithNodeType(NULL, kODSessionDefault, kODTypeAuthenticationSearchNode, &error); + + if (node == NULL) { + CFShow(error); + exit(1); + } + + return node; +} + +static ODRecordRef +CopyRecordWithUUID(ODNodeRef node, CFStringRef type, uuid_t uuid) +{ + CFErrorRef error = NULL; + char uuidstr[37]; + CFStringRef uuidref; + ODQueryRef query = NULL; + CFTypeRef vals[] = { CFSTR(kDSAttributesStandardAll) }; + CFArrayRef attributes = CFArrayCreate(NULL, vals, 1, &kCFTypeArrayCallBacks); + CFArrayRef results = NULL; + ODRecordRef record = NULL; + + uuid_unparse(uuid, uuidstr); + uuidref = CFStringCreateWithCString(NULL, uuidstr, kCFStringEncodingUTF8); + + if (uuidref) { + query = ODQueryCreateWithNode(NULL, node, type, CFSTR(kDS1AttrGeneratedUID), kODMatchEqualTo, uuidref, attributes, 100, &error); + + if (query) { + results = ODQueryCopyResults(query, false, &error); + + if (results) { + if (CFArrayGetCount(results) == 1) { + record = (ODRecordRef)CFArrayGetValueAtIndex(results, 0); + CFRetain(record); + } + + CFRelease(results); + } + + CFRelease(query); + } + + CFRelease(uuidref); + } + + return record; +} + +ODRecordRef +CopyGroupRecordWithGID(ODNodeRef node, gid_t gid) +{ + uuid_t uuid; + + mbr_gid_to_uuid(gid, uuid); + + return CopyRecordWithUUID(node, CFSTR(kDSStdRecordTypeGroups), uuid); +} + +ODRecordRef +CopyUserRecordWithUID(ODNodeRef node, uid_t uid) +{ + uuid_t uuid; + + mbr_uid_to_uuid(uid, uuid); + + return CopyRecordWithUUID(node, CFSTR(kDSStdRecordTypeUsers), uuid); +} + +ODRecordRef +CopyUserRecordWithUsername(ODNodeRef node, char *name) +{ + CFStringRef nameref; + CFTypeRef vals[] = { CFSTR(kDSAttributesStandardAll) }; + CFArrayRef attributes = CFArrayCreate(NULL, vals, 1, &kCFTypeArrayCallBacks); + CFErrorRef error; + + nameref = CFStringCreateWithCString(NULL, name, kCFStringEncodingUTF8); + + if (nameref == NULL) + return NULL; + + return ODNodeCopyRecord(node, CFSTR(kDSStdRecordTypeUsers), nameref, attributes, &error); +} + +CFStringRef +CopyAttrFromRecord(ODRecordRef record, CFStringRef attribute) +{ + CFErrorRef error = NULL; + CFArrayRef values = ODRecordCopyValues(record, attribute, &error); + CFStringRef result = NULL; + + if (values) { + if (CFArrayGetCount(values) == 1) { + result = CFArrayGetValueAtIndex(values, 0); + CFRetain(result); + } + CFRelease(values); + } + + return result; +} + +int +GetIntAttrFromRecord(ODRecordRef record, CFStringRef attribute, int *output) +{ + int status = 1; + CFStringRef str = CopyAttrFromRecord(record, attribute); + + if (str) { + *output = CFStringGetIntValue(str); + status = 0; + CFRelease(str); + } + + return status; +} + +uid_t +GetUIDFromRecord(ODRecordRef record) +{ + int uid = -1; + + GetIntAttrFromRecord(record, CFSTR(kDS1AttrUniqueID), &uid); + + return uid; +} + +gid_t +GetGIDFromRecord(ODRecordRef record) +{ + int gid = -1; + + GetIntAttrFromRecord(record, CFSTR(kDS1AttrPrimaryGroupID), &gid); + + return gid; +} + +CFArrayRef +CopyGroupRecordsForUser(ODNodeRef node, ODRecordRef user, CFIndex limit) +{ + CFMutableArrayRef groups; + gid_t primary_gid; + ODRecordRef primary_group; + CFErrorRef error = NULL; + ODQueryRef query; + CFArrayRef results; + int i; + ODRecordRef gr; + + query = ODQueryCreateWithNode(NULL, node, CFSTR(kDSStdRecordTypeGroups), + CFSTR(kDSNAttrMember), kODMatchContains, ODRecordGetRecordName(user), NULL, limit, &error); + results = ODQueryCopyResults(query, false, &error); + CFRelease(query); + + groups = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); + + primary_gid = GetGIDFromRecord(user); + primary_group = CopyGroupRecordWithGID(node, primary_gid); + CFArrayAppendValue(groups, primary_group); + CFRelease(primary_group); + + for (i = 0; i < CFArrayGetCount(results); i++) { + gr = (ODRecordRef)CFArrayGetValueAtIndex(results, i); + if (GetGIDFromRecord(gr) != primary_gid) { + CFArrayAppendValue(groups, gr); + } + } + + CFRelease(results); + + return groups; +} + +static int +cvfprintf(FILE *file, const char *format, va_list args) +{ + char* cstr; + int result = 0; + CFStringRef formatStr = CFStringCreateWithCStringNoCopy(NULL, format, kCFStringEncodingUTF8, kCFAllocatorNull); + if (formatStr) { + CFStringRef str = CFStringCreateWithFormatAndArguments(NULL, NULL, formatStr, args); + if (str) { + size_t size = CFStringGetMaximumSizeForEncoding(CFStringGetLength(str), kCFStringEncodingUTF8) + 1; + cstr = malloc(size); + if (cstr && CFStringGetCString(str, cstr, size, kCFStringEncodingUTF8)) { + result = fprintf(file, "%s", cstr); + free(cstr); + } + CFRelease(str); + } + CFRelease(formatStr); + } + return result; +} + +int +cfprintf(FILE *file, const char *format, ...) +{ + int result; + va_list args; + + va_start(args, format); + result = cvfprintf(file, format, args); + va_end(args); + return result; +} + +int +cprintf(const char *format, ...) +{ + int result; + va_list args; + + va_start(args, format); + result = cvfprintf(stdout, format, args); + va_end(args); + return result; +} diff --git a/shell_cmds/id/open_directory.h b/shell_cmds/id/open_directory.h new file mode 100644 index 0000000..2c79775 --- /dev/null +++ b/shell_cmds/id/open_directory.h @@ -0,0 +1,18 @@ +#include <OpenDirectory/OpenDirectory.h> + +ODNodeRef CreateNode(void); + +ODRecordRef CopyGroupRecordWithGID(ODNodeRef, gid_t); + +ODRecordRef CopyUserRecordWithUID(ODNodeRef, uid_t); +ODRecordRef CopyUserRecordWithUsername(ODNodeRef, char *); + +CFArrayRef CopyGroupRecordsForUser(ODNodeRef, ODRecordRef, CFIndex); + +CFStringRef CopyAttrFromRecord(ODRecordRef record, CFStringRef attribute); +int GetIntAttrFromRecord(ODRecordRef record, CFStringRef attribute, int *output); +uid_t GetUIDFromRecord(ODRecordRef); +gid_t GetGIDFromRecord(ODRecordRef); + +int cfprintf(FILE *file, const char *format, ...); +int cprintf(const char *format, ...); diff --git a/shell_cmds/id/whoami.1 b/shell_cmds/id/whoami.1 new file mode 100644 index 0000000..568fbaf --- /dev/null +++ b/shell_cmds/id/whoami.1 @@ -0,0 +1,60 @@ +.\" Copyright (c) 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)whoami.1 8.1 (Berkeley) 6/6/93 +.\" $FreeBSD: src/usr.bin/id/whoami.1,v 1.9 2005/01/17 07:44:19 ru Exp $ +.\" +.Dd June 6, 1993 +.Dt WHOAMI 1 +.Os +.Sh NAME +.Nm whoami +.Nd display effective user id +.Sh SYNOPSIS +.Nm +.Sh DESCRIPTION +The +.Nm +utility has been obsoleted by the +.Xr id 1 +utility, and is equivalent to +.Dq Nm id Fl un . +The command +.Dq Nm id Fl p +is suggested for normal interactive use. +.Pp +The +.Nm +utility displays your effective user ID as a name. +.Sh EXIT STATUS +.Ex -std +.Sh SEE ALSO +.Xr id 1 |