1/* id.c - print real and effective user and group IDs 2 * 3 * Copyright 2012 Sony Network Entertainment, Inc. 4 * 5 * by Tim Bird <tim.bird@am.sony.com> 6 * 7 * See http://opengroup.org/onlinepubs/9699919799/utilities/id.html 8 9USE_ID(NEWTOY(id, ">1"USE_ID_SELINUX("Z")"nGgru[!"USE_ID_SELINUX("Z")"Ggu]", TOYFLAG_USR|TOYFLAG_BIN)) 10USE_GROUPS(NEWTOY(groups, NULL, TOYFLAG_USR|TOYFLAG_BIN)) 11USE_LOGNAME(NEWTOY(logname, ">0", TOYFLAG_USR|TOYFLAG_BIN)) 12USE_WHOAMI(OLDTOY(whoami, logname, TOYFLAG_USR|TOYFLAG_BIN)) 13 14config ID 15 bool "id" 16 default y 17 help 18 usage: id [-nGgru] 19 20 Print user and group ID. 21 22 -n print names instead of numeric IDs (to be used with -Ggu) 23 -G Show only the group IDs 24 -g Show only the effective group ID 25 -r Show real ID instead of effective ID 26 -u Show only the effective user ID 27 28config ID_SELINUX 29 bool 30 default y 31 depends on ID && TOYBOX_SELINUX 32 help 33 usage: id [-Z] 34 35 -Z Show only SELinux context 36 37config GROUPS 38 bool "groups" 39 default y 40 help 41 usage: groups [user] 42 43 Print the groups a user is in. 44 45config LOGNAME 46 bool "logname" 47 default y 48 help 49 usage: logname 50 51 Print the current user name. 52 53config WHOAMI 54 bool "whoami" 55 default y 56 help 57 usage: whoami 58 59 Print the current user name. 60*/ 61 62#define FOR_id 63#include "toys.h" 64 65GLOBALS( 66 int do_u, do_n, do_G, do_Z, is_groups; 67) 68 69static void s_or_u(char *s, unsigned u, int done) 70{ 71 if (TT.do_n) printf("%s", s); 72 else printf("%u", u); 73 if (done) { 74 xputc('\n'); 75 exit(0); 76 } 77} 78 79static void showid(char *header, unsigned u, char *s) 80{ 81 printf("%s%u(%s)", header, u, s); 82} 83 84void do_id(char *username) 85{ 86 int flags, i, ngroups; 87 struct passwd *pw; 88 struct group *grp; 89 uid_t uid = getuid(), euid = geteuid(); 90 gid_t gid = getgid(), egid = getegid(), *groups; 91 92 flags = toys.optflags; 93 94 // check if a username is given 95 if (username) { 96 pw = xgetpwnam(username); 97 uid = euid = pw->pw_uid; 98 gid = egid = pw->pw_gid; 99 if (TT.is_groups) printf("%s : ", pw->pw_name); 100 } 101 102 i = flags & FLAG_r; 103 pw = xgetpwuid(i ? uid : euid); 104 if (TT.do_u) s_or_u(pw->pw_name, pw->pw_uid, 1); 105 106 grp = xgetgrgid(i ? gid : egid); 107 if (flags & FLAG_g) s_or_u(grp->gr_name, grp->gr_gid, 1); 108 109 if (!TT.do_G && !TT.do_Z) { 110 showid("uid=", pw->pw_uid, pw->pw_name); 111 showid(" gid=", grp->gr_gid, grp->gr_name); 112 113 if (!i) { 114 if (uid != euid) { 115 pw = xgetpwuid(euid); 116 showid(" euid=", pw->pw_uid, pw->pw_name); 117 } 118 if (gid != egid) { 119 grp = xgetgrgid(egid); 120 showid(" egid=", grp->gr_gid, grp->gr_name); 121 } 122 } 123 124 showid(" groups=", grp->gr_gid, grp->gr_name); 125 } 126 127 if (!TT.do_Z) { 128 groups = (gid_t *)toybuf; 129 i = sizeof(toybuf)/sizeof(gid_t); 130 ngroups = username ? getgrouplist(username, gid, groups, &i) 131 : getgroups(i, groups); 132 if (ngroups<0) perror_exit(0); 133 134 int show_separator = !TT.do_G; 135 for (i = 0; i<ngroups; i++) { 136 if (show_separator) xputc(TT.do_G ? ' ' : ','); 137 show_separator = 1; 138 if (!(grp = getgrgid(groups[i]))) perror_msg(0); 139 else if (TT.do_G) s_or_u(grp->gr_name, grp->gr_gid, 0); 140 else if (grp->gr_gid != egid) showid("", grp->gr_gid, grp->gr_name); 141 else show_separator = 0; // Because we didn't show anything this time. 142 } 143 if (TT.do_G) { 144 xputc('\n'); 145 exit(0); 146 } 147 } 148 149 if (CFG_TOYBOX_SELINUX) { 150 char *context = NULL; 151 152 if (is_selinux_enabled() < 1) { 153 if (TT.do_Z) 154 error_exit("SELinux disabled"); 155 } else if (getcon(&context) == 0) { 156 if (!TT.do_Z) xputc(' '); 157 printf("context=%s", context); 158 } 159 if (CFG_TOYBOX_FREE) free(context); 160 } 161 162 xputc('\n'); 163} 164 165void id_main(void) 166{ 167 // FLAG macros can be 0 if "id" command not enabled, so snapshot them here. 168 if (FLAG_u) TT.do_u |= toys.optflags & FLAG_u; 169 if (FLAG_n) TT.do_n |= toys.optflags & FLAG_n; 170 if (FLAG_G) TT.do_G |= toys.optflags & FLAG_G; 171 if (FLAG_Z) TT.do_Z |= toys.optflags & FLAG_Z; 172 173 if (toys.optc) while(*toys.optargs) do_id(*toys.optargs++); 174 else do_id(NULL); 175} 176 177void groups_main(void) 178{ 179 TT.is_groups = 1; 180 TT.do_G = TT.do_n = 1; 181 id_main(); 182} 183 184void logname_main(void) 185{ 186 TT.do_u = TT.do_n = 1; 187 id_main(); 188} 189