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 
9 USE_ID(NEWTOY(id, ">1"USE_ID_Z("Z")"nGgru[!"USE_ID_Z("Z")"Ggu]", TOYFLAG_USR|TOYFLAG_BIN))
10 USE_GROUPS(NEWTOY(groups, NULL, TOYFLAG_USR|TOYFLAG_BIN))
11 USE_LOGNAME(NEWTOY(logname, ">0", TOYFLAG_USR|TOYFLAG_BIN))
12 USE_WHOAMI(OLDTOY(whoami, logname, TOYFLAG_USR|TOYFLAG_BIN))
13 
14 config ID
15   bool "id"
16   default y
17   help
18     usage: id [-nGgru] [USER...]
19 
20     Print user and group ID.
21 
22     -G	Show all group IDs
23     -g	Show only the effective group ID
24     -n	Print names instead of numeric IDs (to be used with -Ggu)
25     -r	Show real ID instead of effective ID
26     -u	Show only the effective user ID
27 
28 config ID_Z
29   bool
30   default y
31   depends on ID && !TOYBOX_LSM_NONE
32   help
33     usage: id [-Z]
34 
35     -Z	Show only security context
36 
37 config GROUPS
38   bool "groups"
39   default y
40   help
41     usage: groups [user]
42 
43     Print the groups a user is in.
44 
45 config LOGNAME
46   bool "logname"
47   default y
48   help
49     usage: logname
50 
51     Print the current user name.
52 
53 config 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 #define FORCE_FLAGS
64 #include "toys.h"
65 
GLOBALS(int is_groups;)66 GLOBALS(
67   int is_groups;
68 )
69 
70 static void showone(char *prefix, char *s, unsigned u, int done)
71 {
72   if (FLAG(n)) printf("%s%s", prefix, s);
73   else printf("%s%u", prefix, u);
74   if (done) {
75     xputc('\n');
76     xexit();
77   }
78 }
79 
showid(char * prefix,unsigned u,char * s)80 static void showid(char *prefix, unsigned u, char *s)
81 {
82   printf("%s%u(%s)", prefix, u, s);
83 }
84 
do_id(char * username)85 static void do_id(char *username)
86 {
87   struct passwd *pw;
88   struct group *grp;
89   uid_t uid = getuid(), euid = geteuid();
90   gid_t gid = getgid(), egid = getegid();
91   gid_t *groups = (gid_t *)toybuf;
92   int i = sizeof(toybuf)/sizeof(gid_t), ngroups;
93 
94   // check if a username is given
95   if (username) {
96     pw = getpwnam(username);
97     if (!pw) {
98       uid = atolx_range(username, 0, INT_MAX);
99       if ((pw = getpwuid(uid))) username = pw->pw_name;
100     }
101     if (!pw) error_exit("no such user '%s'", username);
102     uid = euid = pw->pw_uid;
103     gid = egid = pw->pw_gid;
104     if (TT.is_groups) printf("%s : ", pw->pw_name);
105   }
106 
107   pw = xgetpwuid(FLAG(r) ? uid : euid);
108   if (FLAG(u)) showone("", pw->pw_name, pw->pw_uid, 1);
109 
110   grp = xgetgrgid(FLAG(r) ? gid : egid);
111   if (FLAG(g)) showone("", grp->gr_name, grp->gr_gid, 1);
112 
113   ngroups = username ? getgrouplist(username, gid, groups, &i)
114     : getgroups(i, groups);
115   if (ngroups<0) perror_exit("getgroups");
116 
117   if (FLAG(G)) {
118     showone("", grp->gr_name, grp->gr_gid, 0);
119     for (i = 0; i<ngroups; i++) {
120       if (groups[i] != egid) {
121         if ((grp=getgrgid(groups[i]))) showone(" ",grp->gr_name,grp->gr_gid,0);
122         else printf(" %u", groups[i]);
123       }
124     }
125     xputc('\n');
126     return;
127   }
128 
129   if (!FLAG(Z)) {
130     showid("uid=", pw->pw_uid, pw->pw_name);
131     showid(" gid=", grp->gr_gid, grp->gr_name);
132 
133     if (!FLAG(r)) {
134       if (uid != euid) {
135         pw = xgetpwuid(euid);
136         showid(" euid=", pw->pw_uid, pw->pw_name);
137       }
138       if (gid != egid) {
139         grp = xgetgrgid(egid);
140         showid(" egid=", grp->gr_gid, grp->gr_name);
141       }
142     }
143 
144     showid(" groups=", gid, grp->gr_name);
145     for (i = 0; i<ngroups; i++) {
146       if (groups[i] != egid) {
147         if ((grp=getgrgid(groups[i]))) showid(",", grp->gr_gid, grp->gr_name);
148         else printf(",%u", groups[i]);
149       }
150     }
151   }
152 
153   if (!CFG_TOYBOX_LSM_NONE) {
154     if (lsm_enabled()) {
155       char *context = lsm_context();
156 
157       printf("%s%s", FLAG(Z) ? "" : " context=", context);
158       if (CFG_TOYBOX_FREE) free(context);
159     } else if (FLAG(Z)) error_exit("%s disabled", lsm_name());
160   }
161 
162   xputc('\n');
163 }
164 
id_main(void)165 void id_main(void)
166 {
167   if (toys.optc) while(*toys.optargs) do_id(*toys.optargs++);
168   else do_id(NULL);
169 }
170 
groups_main(void)171 void groups_main(void)
172 {
173   TT.is_groups = 1;
174   toys.optflags = FLAG_G|FLAG_n;
175   id_main();
176 }
177 
logname_main(void)178 void logname_main(void)
179 {
180   toys.optflags = FLAG_u|FLAG_n;
181   id_main();
182 }
183