aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-09-18 00:56:24 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-09-18 00:56:24 +0000
commit2228426512eabc05767b5abac69770e3ae9cd9bb (patch)
tree913718f56916075be130a9ea2290ff36664d4803
parent28f5619e842d4a4e03abe6f96d7f9fd5a70e223f (diff)
downloadbusybox-w32-2228426512eabc05767b5abac69770e3ae9cd9bb.tar.gz
busybox-w32-2228426512eabc05767b5abac69770e3ae9cd9bb.tar.bz2
busybox-w32-2228426512eabc05767b5abac69770e3ae9cd9bb.zip
id: fix "id <user>" case. Requires getgrouplist().
function old new delta getgrouplist_internal - 200 +200 id_main 462 539 +77 bb_internal_getgrouplist - 67 +67 bb__parsespent 119 117 -2 bb_internal_initgroups 213 58 -155 ------------------------------------------------------------------------------ (add/remove: 2/0 grow/shrink: 1/2 up/down: 344/-157) Total: 187 bytes
-rw-r--r--coreutils/id.c50
-rw-r--r--libpwdgrp/pwd_grp.c70
2 files changed, 87 insertions, 33 deletions
diff --git a/coreutils/id.c b/coreutils/id.c
index 5225f357c..aa27ed394 100644
--- a/coreutils/id.c
+++ b/coreutils/id.c
@@ -38,14 +38,25 @@ static int printf_full(unsigned id, const char *arg, const char *prefix)
38 return status; 38 return status;
39} 39}
40 40
41#if (defined(__GLIBC__) && !defined(__UCLIBC__))
42#define HAVE_getgrouplist 1
43#elif ENABLE_USE_BB_PWD_GRP
44#define HAVE_getgrouplist 1
45#else
46#define HAVE_getgrouplist 0
47#endif
48
41int id_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 49int id_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
42int id_main(int argc UNUSED_PARAM, char **argv) 50int id_main(int argc UNUSED_PARAM, char **argv)
43{ 51{
52 const char *username;
44 struct passwd *p; 53 struct passwd *p;
45 uid_t uid; 54 uid_t uid;
46 gid_t gid; 55 gid_t gid;
56#if HAVE_getgrouplist
47 gid_t *groups; 57 gid_t *groups;
48 int n; 58 int n;
59#endif
49 unsigned flags; 60 unsigned flags;
50 short status; 61 short status;
51#if ENABLE_SELINUX 62#if ENABLE_SELINUX
@@ -55,6 +66,7 @@ int id_main(int argc UNUSED_PARAM, char **argv)
55 /* Don't allow more than one username */ 66 /* Don't allow more than one username */
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"); 67 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");
57 flags = getopt32(argv, "rnugG" USE_SELINUX("Z")); 68 flags = getopt32(argv, "rnugG" USE_SELINUX("Z"));
69 username = argv[optind];
58 70
59 /* This values could be overwritten later */ 71 /* This values could be overwritten later */
60 uid = geteuid(); 72 uid = geteuid();
@@ -64,19 +76,34 @@ int id_main(int argc UNUSED_PARAM, char **argv)
64 gid = getgid(); 76 gid = getgid();
65 } 77 }
66 78
67 if (argv[optind]) { 79 if (username) {
68 p = getpwnam(argv[optind]); 80#if HAVE_getgrouplist
81 int m;
82#endif
83 p = getpwnam(username);
69 /* xuname2uid is needed because it exits on failure */ 84 /* xuname2uid is needed because it exits on failure */
70 uid = xuname2uid(argv[optind]); 85 uid = xuname2uid(username);
71 gid = p->pw_gid; 86 gid = p->pw_gid; /* in this case PRINT_REAL is the same */
72 /* in this case PRINT_REAL is the same */ 87
88#if HAVE_getgrouplist
89 n = 16;
90 groups = NULL;
91 do {
92 m = n;
93 groups = xrealloc(groups, sizeof(groups[0]) * m);
94 getgrouplist(username, gid, groups, &n); /* GNUism? */
95 } while (n > m);
96#endif
97 } else {
98#if HAVE_getgrouplist
99 n = getgroups(0, NULL);
100 groups = xmalloc(sizeof(groups[0]) * n);
101 getgroups(n, groups);
102#endif
73 } 103 }
74 104
75 n = getgroups(0, NULL);
76 groups = xmalloc(sizeof(groups[0]) * n);
77 getgroups(n, groups);
78
79 if (flags & JUST_ALL_GROUPS) { 105 if (flags & JUST_ALL_GROUPS) {
106#if HAVE_getgrouplist
80 while (n--) { 107 while (n--) {
81 if (flags & NAME_NOT_NUMBER) 108 if (flags & NAME_NOT_NUMBER)
82 printf("%s", bb_getgrgid(NULL, 0, *groups++)); 109 printf("%s", bb_getgrgid(NULL, 0, *groups++));
@@ -84,6 +111,7 @@ int id_main(int argc UNUSED_PARAM, char **argv)
84 printf("%u", (unsigned) *groups++); 111 printf("%u", (unsigned) *groups++);
85 bb_putchar((n > 0) ? ' ' : '\n'); 112 bb_putchar((n > 0) ? ' ' : '\n');
86 } 113 }
114#endif
87 /* exit */ 115 /* exit */
88 fflush_stdout_and_exit(EXIT_SUCCESS); 116 fflush_stdout_and_exit(EXIT_SUCCESS);
89 } 117 }
@@ -105,7 +133,7 @@ int id_main(int argc UNUSED_PARAM, char **argv)
105#if ENABLE_SELINUX 133#if ENABLE_SELINUX
106 if (flags & JUST_CONTEXT) { 134 if (flags & JUST_CONTEXT) {
107 selinux_or_die(); 135 selinux_or_die();
108 if (argv[optind]) { 136 if (username) {
109 bb_error_msg_and_die("user name can't be passed with -Z"); 137 bb_error_msg_and_die("user name can't be passed with -Z");
110 } 138 }
111 139
@@ -123,6 +151,7 @@ int id_main(int argc UNUSED_PARAM, char **argv)
123 /* bb_getpwuid(0) doesn't exit on failure (returns NULL) */ 151 /* bb_getpwuid(0) doesn't exit on failure (returns NULL) */
124 status = printf_full(uid, bb_getpwuid(NULL, 0, uid), "uid="); 152 status = printf_full(uid, bb_getpwuid(NULL, 0, uid), "uid=");
125 status |= printf_full(gid, bb_getgrgid(NULL, 0, gid), " gid="); 153 status |= printf_full(gid, bb_getgrgid(NULL, 0, gid), " gid=");
154#if HAVE_getgrouplist
126 { 155 {
127 const char *msg = " groups="; 156 const char *msg = " groups=";
128 while (n--) { 157 while (n--) {
@@ -132,6 +161,7 @@ int id_main(int argc UNUSED_PARAM, char **argv)
132 } 161 }
133 } 162 }
134 /* we leak groups vector... */ 163 /* we leak groups vector... */
164#endif
135 165
136#if ENABLE_SELINUX 166#if ENABLE_SELINUX
137 if (is_selinux_enabled()) { 167 if (is_selinux_enabled()) {
diff --git a/libpwdgrp/pwd_grp.c b/libpwdgrp/pwd_grp.c
index 206519084..98b8367ca 100644
--- a/libpwdgrp/pwd_grp.c
+++ b/libpwdgrp/pwd_grp.c
@@ -620,43 +620,67 @@ struct spwd *sgetspent(const char *string)
620} 620}
621#endif 621#endif
622 622
623int initgroups(const char *user, gid_t gid) 623static gid_t *getgrouplist_internal(int *ngroups_ptr, const char *user, gid_t gid)
624{ 624{
625 FILE *grfile; 625 FILE *grfile;
626 gid_t *group_list; 626 gid_t *group_list;
627 int num_groups, rv; 627 int ngroups;
628 char **m;
629 struct group group; 628 struct group group;
630 char buff[PWD_BUFFER_SIZE]; 629 char buff[PWD_BUFFER_SIZE];
631 630
632 rv = -1; 631 /* We alloc space for 8 gids at a time. */
633 grfile = fopen_for_read(_PATH_GROUP); 632 group_list = xmalloc(8 * sizeof(group_list[0]));
634 if (grfile != NULL) { 633 group_list[0] = gid;
635 634 ngroups = 1;
636 /* We alloc space for 8 gids at a time. */
637 group_list = xmalloc(8 * sizeof(gid_t *));
638 *group_list = gid;
639 num_groups = 1;
640 635
636 grfile = fopen_for_read(_PATH_GROUP);
637 if (grfile) {
641 while (!bb__pgsreader(bb__parsegrent, &group, buff, sizeof(buff), grfile)) { 638 while (!bb__pgsreader(bb__parsegrent, &group, buff, sizeof(buff), grfile)) {
639 char **m;
642 assert(group.gr_mem); /* Must have at least a NULL terminator. */ 640 assert(group.gr_mem); /* Must have at least a NULL terminator. */
643 if (group.gr_gid != gid) { 641 if (group.gr_gid == gid)
644 for (m = group.gr_mem; *m; m++) { 642 continue;
645 if (!strcmp(*m, user)) { 643 for (m = group.gr_mem; *m; m++) {
646 group_list = xrealloc_vector(group_list, 3, num_groups); 644 if (strcmp(*m, user) != 0)
647 group_list[num_groups++] = group.gr_gid; 645 continue;
648 break; 646 group_list = xrealloc_vector(group_list, 3, ngroups);
649 } 647 group_list[ngroups++] = group.gr_gid;
650 } 648 break;
651 } 649 }
652 } 650 }
653
654 rv = setgroups(num_groups, group_list);
655 free(group_list);
656 fclose(grfile); 651 fclose(grfile);
657 } 652 }
653 *ngroups_ptr = ngroups;
654 return group_list;
655}
658 656
659 return rv; 657int initgroups(const char *user, gid_t gid)
658{
659 int ngroups;
660 gid_t *group_list = getgrouplist_internal(&ngroups, user, gid);
661
662 if (!group_list)
663 return -1;
664
665 ngroups = setgroups(ngroups, group_list);
666 free(group_list);
667 return ngroups;
668}
669
670/* TODO: uclibc needs this ported to it! */
671int getgrouplist(const char *user, gid_t gid, gid_t *groups, int *ngroups)
672{
673 int ngroups_old = *ngroups;
674 gid_t *group_list = getgrouplist_internal(ngroups, user, gid);
675
676 if (*ngroups <= ngroups_old) {
677 ngroups_old = *ngroups;
678 memcpy(groups, group_list, ngroups_old * sizeof(groups[0]));
679 } else {
680 ngroups_old = -1;
681 }
682 free(group_list);
683 return ngroups_old;
660} 684}
661 685
662int putpwent(const struct passwd *__restrict p, FILE *__restrict f) 686int putpwent(const struct passwd *__restrict p, FILE *__restrict f)