diff options
-rw-r--r-- | coreutils/id.c | 47 | ||||
-rw-r--r-- | include/usage.h | 1 |
2 files changed, 38 insertions, 10 deletions
diff --git a/coreutils/id.c b/coreutils/id.c index 0fadd98d3..b2f3b20e1 100644 --- a/coreutils/id.c +++ b/coreutils/id.c | |||
@@ -7,10 +7,11 @@ | |||
7 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. | 7 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. |
8 | */ | 8 | */ |
9 | 9 | ||
10 | /* BB_AUDIT SUSv3 _NOT_ compliant -- option -G is not currently supported. */ | 10 | /* BB_AUDIT SUSv3 compliant. */ |
11 | /* Hacked by Tito Ragusa (C) 2004 to handle usernames of whatever length and to | 11 | /* Hacked by Tito Ragusa (C) 2004 to handle usernames of whatever length and to |
12 | * be more similar to GNU id. | 12 | * be more similar to GNU id. |
13 | * -Z option support: by Yuichi Nakamura <ynakam@hitachisoft.jp> | 13 | * -Z option support: by Yuichi Nakamura <ynakam@hitachisoft.jp> |
14 | * Added -G option Tito Ragusa (C) 2008 for SUSv3. | ||
14 | */ | 15 | */ |
15 | 16 | ||
16 | #include "libbb.h" | 17 | #include "libbb.h" |
@@ -19,17 +20,18 @@ | |||
19 | #define NAME_NOT_NUMBER 2 | 20 | #define NAME_NOT_NUMBER 2 |
20 | #define JUST_USER 4 | 21 | #define JUST_USER 4 |
21 | #define JUST_GROUP 8 | 22 | #define JUST_GROUP 8 |
23 | #define JUST_ALL_GROUPS 16 | ||
22 | #if ENABLE_SELINUX | 24 | #if ENABLE_SELINUX |
23 | #define JUST_CONTEXT 16 | 25 | #define JUST_CONTEXT 32 |
24 | #endif | 26 | #endif |
25 | 27 | ||
26 | static int printf_full(unsigned int id, const char *arg, const char prefix) | 28 | static int printf_full(unsigned int id, const char *arg, const char *prefix) |
27 | { | 29 | { |
28 | const char *fmt = "%cid=%u"; | 30 | const char *fmt = "%s%u"; |
29 | int status = EXIT_FAILURE; | 31 | int status = EXIT_FAILURE; |
30 | 32 | ||
31 | if (arg) { | 33 | if (arg) { |
32 | fmt = "%cid=%u(%s)"; | 34 | fmt = "%s%u(%s)"; |
33 | status = EXIT_SUCCESS; | 35 | status = EXIT_SUCCESS; |
34 | } | 36 | } |
35 | printf(fmt, prefix, id, arg); | 37 | printf(fmt, prefix, id, arg); |
@@ -42,6 +44,8 @@ int id_main(int argc UNUSED_PARAM, char **argv) | |||
42 | struct passwd *p; | 44 | struct passwd *p; |
43 | uid_t uid; | 45 | uid_t uid; |
44 | gid_t gid; | 46 | gid_t gid; |
47 | gid_t *groups; | ||
48 | int grp; | ||
45 | unsigned long flags; | 49 | unsigned long flags; |
46 | short status; | 50 | short status; |
47 | #if ENABLE_SELINUX | 51 | #if ENABLE_SELINUX |
@@ -49,8 +53,8 @@ int id_main(int argc UNUSED_PARAM, char **argv) | |||
49 | #endif | 53 | #endif |
50 | /* Don't allow -n -r -nr -ug -rug -nug -rnug */ | 54 | /* Don't allow -n -r -nr -ug -rug -nug -rnug */ |
51 | /* Don't allow more than one username */ | 55 | /* Don't allow more than one username */ |
52 | opt_complementary = "?1:u--g:g--u:r?ug:n?ug" USE_SELINUX(":u--Z:Z--u:g--Z:Z--g"); | 56 | opt_complementary = "?1:u--g:g--u:G--u:u--G:g--G:G--g:r?ugG:n?ugG" USE_SELINUX(":u--Z:Z--u:g--Z:Z--g"); |
53 | flags = getopt32(argv, "rnug" USE_SELINUX("Z")); | 57 | flags = getopt32(argv, "rnugG" USE_SELINUX("Z")); |
54 | 58 | ||
55 | /* This values could be overwritten later */ | 59 | /* This values could be overwritten later */ |
56 | uid = geteuid(); | 60 | uid = geteuid(); |
@@ -68,6 +72,22 @@ int id_main(int argc UNUSED_PARAM, char **argv) | |||
68 | /* in this case PRINT_REAL is the same */ | 72 | /* in this case PRINT_REAL is the same */ |
69 | } | 73 | } |
70 | 74 | ||
75 | grp = getgroups(0, 0); | ||
76 | groups = (gid_t *)xmalloc(sizeof(gid_t) * grp); | ||
77 | getgroups(grp, (gid_t *)groups); | ||
78 | |||
79 | if (flags & (JUST_ALL_GROUPS)) { | ||
80 | while (grp--) { | ||
81 | if (flags & NAME_NOT_NUMBER) | ||
82 | printf("%s", bb_getgrgid(NULL, 0, *groups++)); | ||
83 | else | ||
84 | printf("%d", *groups++); | ||
85 | bb_putchar((grp > 0) ? ' ' : '\n'); | ||
86 | } | ||
87 | /* exit */ | ||
88 | fflush_stdout_and_exit(EXIT_SUCCESS); | ||
89 | } | ||
90 | |||
71 | if (flags & (JUST_GROUP | JUST_USER USE_SELINUX(| JUST_CONTEXT))) { | 91 | if (flags & (JUST_GROUP | JUST_USER USE_SELINUX(| JUST_CONTEXT))) { |
72 | /* JUST_GROUP and JUST_USER are mutually exclusive */ | 92 | /* JUST_GROUP and JUST_USER are mutually exclusive */ |
73 | if (flags & NAME_NOT_NUMBER) { | 93 | if (flags & NAME_NOT_NUMBER) { |
@@ -101,10 +121,17 @@ int id_main(int argc UNUSED_PARAM, char **argv) | |||
101 | 121 | ||
102 | /* Print full info like GNU id */ | 122 | /* Print full info like GNU id */ |
103 | /* bb_getpwuid(0) doesn't exit on failure (returns NULL) */ | 123 | /* bb_getpwuid(0) doesn't exit on failure (returns NULL) */ |
104 | status = printf_full(uid, bb_getpwuid(NULL, 0, uid), 'u'); | 124 | status = printf_full(uid, bb_getpwuid(NULL, 0, uid), "uid="); |
105 | bb_putchar(' '); | 125 | bb_putchar(' '); |
106 | status |= printf_full(gid, bb_getgrgid(NULL, 0, gid), 'g'); | 126 | status |= printf_full(gid, bb_getgrgid(NULL, 0, gid), "gid="); |
107 | 127 | printf(" groups="); | |
128 | while (grp--) { | ||
129 | status |= printf_full(*groups, bb_getgrgid(NULL, 0, *groups), ""); | ||
130 | if (grp > 0) | ||
131 | bb_putchar(','); | ||
132 | groups++; | ||
133 | } | ||
134 | /* Don't free groups */ | ||
108 | #if ENABLE_SELINUX | 135 | #if ENABLE_SELINUX |
109 | if (is_selinux_enabled()) { | 136 | if (is_selinux_enabled()) { |
110 | security_context_t mysid; | 137 | security_context_t mysid; |
diff --git a/include/usage.h b/include/usage.h index fdad63a4f..951be53de 100644 --- a/include/usage.h +++ b/include/usage.h | |||
@@ -1602,6 +1602,7 @@ | |||
1602 | USE_SELINUX( \ | 1602 | USE_SELINUX( \ |
1603 | "\n -Z Print the security context" \ | 1603 | "\n -Z Print the security context" \ |
1604 | ) \ | 1604 | ) \ |
1605 | "\n -G Print all group IDs" \ | ||
1605 | "\n -g Print group ID" \ | 1606 | "\n -g Print group ID" \ |
1606 | "\n -u Print user ID" \ | 1607 | "\n -u Print user ID" \ |
1607 | "\n -n Print name instead of a number" \ | 1608 | "\n -n Print name instead of a number" \ |