diff options
Diffstat (limited to 'coreutils/id.c')
-rw-r--r-- | coreutils/id.c | 78 |
1 files changed, 57 insertions, 21 deletions
diff --git a/coreutils/id.c b/coreutils/id.c index 42ed4c749..399d25e34 100644 --- a/coreutils/id.c +++ b/coreutils/id.c | |||
@@ -15,11 +15,28 @@ | |||
15 | * Added -G option Tito Ragusa (C) 2008 for SUSv3. | 15 | * Added -G option Tito Ragusa (C) 2008 for SUSv3. |
16 | */ | 16 | */ |
17 | 17 | ||
18 | //config:config ID | ||
19 | //config: bool "id" | ||
20 | //config: default y | ||
21 | //config: help | ||
22 | //config: id displays the current user and group ID names. | ||
23 | |||
24 | //config:config GROUPS | ||
25 | //config: bool "groups" | ||
26 | //config: default y | ||
27 | //config: help | ||
28 | //config: Print the group names associated with current user id. | ||
29 | |||
30 | //kbuild:lib-$(CONFIG_GROUPS) += id.o | ||
31 | //kbuild:lib-$(CONFIG_ID) += id.o | ||
32 | |||
33 | //applet:IF_GROUPS(APPLET_NOEXEC(groups, id, BB_DIR_USR_BIN, BB_SUID_DROP, groups)) | ||
34 | //applet:IF_ID( APPLET_NOEXEC(id, id, BB_DIR_USR_BIN, BB_SUID_DROP, id )) | ||
35 | |||
18 | //usage:#define id_trivial_usage | 36 | //usage:#define id_trivial_usage |
19 | //usage: "[OPTIONS] [USER]" | 37 | //usage: "[OPTIONS] [USER]" |
20 | //usage:#define id_full_usage "\n\n" | 38 | //usage:#define id_full_usage "\n\n" |
21 | //usage: "Print information about USER or the current user\n" | 39 | //usage: "Print information about USER or the current user\n" |
22 | //usage: "\nOptions:" | ||
23 | //usage: IF_SELINUX( | 40 | //usage: IF_SELINUX( |
24 | //usage: "\n -Z Security context" | 41 | //usage: "\n -Z Security context" |
25 | //usage: ) | 42 | //usage: ) |
@@ -33,6 +50,15 @@ | |||
33 | //usage: "$ id\n" | 50 | //usage: "$ id\n" |
34 | //usage: "uid=1000(andersen) gid=1000(andersen)\n" | 51 | //usage: "uid=1000(andersen) gid=1000(andersen)\n" |
35 | 52 | ||
53 | //usage:#define groups_trivial_usage | ||
54 | //usage: "[USER]" | ||
55 | //usage:#define groups_full_usage "\n\n" | ||
56 | //usage: "Print the group memberships of USER or for the current process" | ||
57 | //usage: | ||
58 | //usage:#define groups_example_usage | ||
59 | //usage: "$ groups\n" | ||
60 | //usage: "andersen lp dialout cdrom floppy\n" | ||
61 | |||
36 | #include "libbb.h" | 62 | #include "libbb.h" |
37 | 63 | ||
38 | /* This is a NOEXEC applet. Be very careful! */ | 64 | /* This is a NOEXEC applet. Be very careful! */ |
@@ -91,7 +117,7 @@ static int print_user(uid_t id, const char *prefix) | |||
91 | 117 | ||
92 | /* On error set *n < 0 and return >= 0 | 118 | /* On error set *n < 0 and return >= 0 |
93 | * If *n is too small, update it and return < 0 | 119 | * If *n is too small, update it and return < 0 |
94 | * (ok to trash groups[] in both cases) | 120 | * (ok to trash groups[] in both cases) |
95 | * Otherwise fill in groups[] and return >= 0 | 121 | * Otherwise fill in groups[] and return >= 0 |
96 | */ | 122 | */ |
97 | static int get_groups(const char *username, gid_t rgid, gid_t *groups, int *n) | 123 | static int get_groups(const char *username, gid_t rgid, gid_t *groups, int *n) |
@@ -105,20 +131,19 @@ static int get_groups(const char *username, gid_t rgid, gid_t *groups, int *n) | |||
105 | m = getgrouplist(username, rgid, groups, n); | 131 | m = getgrouplist(username, rgid, groups, n); |
106 | /* I guess *n < 0 might indicate error. Anyway, | 132 | /* I guess *n < 0 might indicate error. Anyway, |
107 | * malloc'ing -1 bytes won't be good, so: */ | 133 | * malloc'ing -1 bytes won't be good, so: */ |
108 | //if (*n < 0) | 134 | if (*n < 0) |
109 | // return 0; | 135 | return 0; |
110 | //return m; | 136 | return m; |
111 | //commented out here, happens below anyway | ||
112 | } else { | ||
113 | /* On error -1 is returned, which ends up in *n */ | ||
114 | int nn = getgroups(*n, groups); | ||
115 | /* 0: nn <= *n, groups[] was big enough; -1 otherwise */ | ||
116 | m = - (nn > *n); | ||
117 | *n = nn; | ||
118 | } | 137 | } |
119 | if (*n < 0) | 138 | |
120 | return 0; /* error, don't return < 0! */ | 139 | *n = getgroups(*n, groups); |
121 | return m; | 140 | if (*n >= 0) |
141 | return *n; | ||
142 | /* Error */ | ||
143 | if (errno == EINVAL) /* *n is too small? */ | ||
144 | *n = getgroups(0, groups); /* get needed *n */ | ||
145 | /* if *n >= 0, return -1 (got new *n), else return 0 (error): */ | ||
146 | return -(*n >= 0); | ||
122 | } | 147 | } |
123 | 148 | ||
124 | int id_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 149 | int id_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
@@ -136,11 +161,22 @@ int id_main(int argc UNUSED_PARAM, char **argv) | |||
136 | #if ENABLE_SELINUX | 161 | #if ENABLE_SELINUX |
137 | security_context_t scontext = NULL; | 162 | security_context_t scontext = NULL; |
138 | #endif | 163 | #endif |
139 | /* Don't allow -n -r -nr -ug -rug -nug -rnug -uZ -gZ -GZ*/ | 164 | |
140 | /* Don't allow more than one username */ | 165 | if (ENABLE_GROUPS && (!ENABLE_ID || applet_name[0] == 'g')) { |
141 | opt_complementary = "?1:u--g:g--u:G--u:u--G:g--G:G--g:r?ugG:n?ugG" | 166 | /* TODO: coreutils groups prepend "USER : " prefix, |
167 | * and accept many usernames. Example: | ||
168 | * # groups root root | ||
169 | * root : root | ||
170 | * root : root | ||
171 | */ | ||
172 | opt = option_mask32 = getopt32(argv, "") | JUST_ALL_GROUPS | NAME_NOT_NUMBER; | ||
173 | } else { | ||
174 | /* Don't allow -n -r -nr -ug -rug -nug -rnug -uZ -gZ -GZ*/ | ||
175 | /* Don't allow more than one username */ | ||
176 | opt_complementary = "?1:u--g:g--u:G--u:u--G:g--G:G--g:r?ugG:n?ugG" | ||
142 | IF_SELINUX(":u--Z:Z--u:g--Z:Z--g:G--Z:Z--G"); | 177 | IF_SELINUX(":u--Z:Z--u:g--Z:Z--g:G--Z:Z--G"); |
143 | opt = getopt32(argv, "rnugG" IF_SELINUX("Z")); | 178 | opt = getopt32(argv, "rnugG" IF_SELINUX("Z")); |
179 | } | ||
144 | 180 | ||
145 | username = argv[optind]; | 181 | username = argv[optind]; |
146 | if (username) { | 182 | if (username) { |
@@ -177,11 +213,11 @@ int id_main(int argc UNUSED_PARAM, char **argv) | |||
177 | /* We are supplying largish buffer, trying | 213 | /* We are supplying largish buffer, trying |
178 | * to not run get_groups() twice. That might be slow | 214 | * to not run get_groups() twice. That might be slow |
179 | * ("user database in remote SQL server" case) */ | 215 | * ("user database in remote SQL server" case) */ |
180 | groups = xmalloc(64 * sizeof(gid_t)); | 216 | groups = xmalloc(64 * sizeof(groups[0])); |
181 | n = 64; | 217 | n = 64; |
182 | if (get_groups(username, rgid, groups, &n) < 0) { | 218 | if (get_groups(username, rgid, groups, &n) < 0) { |
183 | /* Need bigger buffer after all */ | 219 | /* Need bigger buffer after all */ |
184 | groups = xrealloc(groups, n * sizeof(gid_t)); | 220 | groups = xrealloc(groups, n * sizeof(groups[0])); |
185 | get_groups(username, rgid, groups, &n); | 221 | get_groups(username, rgid, groups, &n); |
186 | } | 222 | } |
187 | if (n > 0) { | 223 | if (n > 0) { |