On Wednesday 22 June 2011 08:06:28 Tito wrote:
> 
> On Wednesday 22 June 2011 04:18:32 Denys Vlasenko wrote:
> > On Wednesday 22 June 2011 01:03, Tito wrote:
> > > > Applied, thanks!
> > > 
> > > Hi Denys,
> > > i suspect that:
> > > 
> > > opt_complementary = "?1:u--g:g--u:G--u:u--G:g--G:G--g:r?ugG:n?ugG"
> > > 
> > > should be before
> > > 
> > > if (ENABLE_GROUPS && (!ENABLE_ID || applet_name[0] == 'g')) {
> > >  option_mask32 = opt = getopt32(argv, "") | JUST_ALL_GROUPS | 
> > > NAME_NOT_NUMBER;
> > > } else {
> > > 
> > > as else the max args (= 1) statement is not enforced for groups.
> > > At least something like this is needed:
> > 
> > coreutils groups can take more than one arg.
> > 
> Hi,
> Yes, but id doesn't and our groups doesn't.  Even bb's groups' help text says 
> [USER].
> 
> Ciao,
> Tito

Hi,
attached a patch that allows group to use multiple usernames.
Little tested, seems to work, looks a little ugly.... ;-).

Ciao,
Tito

--- coreutils/id.c.original     2011-06-22 14:29:58.000000000 +0200
+++ coreutils/id.c      2011-06-22 15:41:38.000000000 +0200
@@ -51,7 +51,7 @@
 //usage:       "uid=1000(andersen) gid=1000(andersen)\n"
 
 //usage:#define groups_trivial_usage
-//usage:       "[USER]"
+//usage:       "[USERS]"
 //usage:#define groups_full_usage "\n\n"
 //usage:       "Print the group memberships of USER or for the current process"
 //usage:
@@ -158,19 +158,15 @@
        int i;
        int status = EXIT_SUCCESS;
        const char *prefix;
-       const char *username;
+       /* Are we groups or id? */
+       int do_groups = (ENABLE_GROUPS && (!ENABLE_ID || applet_name[0] == 
'g'));
 #if ENABLE_SELINUX
        security_context_t scontext = NULL;
 #endif
 
-       if (ENABLE_GROUPS && (!ENABLE_ID || applet_name[0] == 'g')) {
-               /* TODO: coreutils groups prepend "USER : " prefix,
-                * and accept many usernames. Example:
-                * # groups root root
-                * root : root
-                * root : root
-                */
+       if (do_groups) {
                opt = option_mask32 = getopt32(argv, "") | JUST_ALL_GROUPS | 
NAME_NOT_NUMBER;
+               do_groups = argc - optind;
        } else {
                /* Don't allow -n -r -nr -ug -rug -nug -rnug -uZ -gZ -GZ*/
                /* Don't allow more than one username */
@@ -179,92 +175,97 @@
                opt = getopt32(argv, "rnugG" IF_SELINUX("Z"));
        }
 
-       username = argv[optind];
-       if (username) {
-               struct passwd *p = xgetpwnam(username);
-               euid = ruid = p->pw_uid;
-               egid = rgid = p->pw_gid;
-       } else {
-               egid = getegid();
-               rgid = getgid();
-               euid = geteuid();
-               ruid = getuid();
-       }
-       /* JUST_ALL_GROUPS ignores -r PRINT_REAL flag even if man page for */
-       /* id says: print the real ID instead of the effective ID, with -ugG */
-       /* in fact in this case egid is always printed if egid != rgid */
-       if (!opt || (opt & JUST_ALL_GROUPS)) {
-               gid_t *groups;
-               int n;
-
-               if (!opt) {
-                       /* Default Mode */
-                       status |= print_user(ruid, "uid=");
-                       status |= print_group(rgid, " gid=");
-                       if (euid != ruid)
-                               status |= print_user(euid, " euid=");
-                       if (egid != rgid)
-                               status |= print_group(egid, " egid=");
+       //argc -= optind;
+       argv += optind;
+       do {
+               if (*argv) {
+                       struct passwd *p = xgetpwnam(*argv);
+                       euid = ruid = p->pw_uid;
+                       egid = rgid = p->pw_gid;
                } else {
-                       /* JUST_ALL_GROUPS */
-                       status |= print_group(rgid, NULL);
-                       if (egid != rgid)
-                               status |= print_group(egid, " ");
-               }
-               /* We are supplying largish buffer, trying
-                * to not run get_groups() twice. That might be slow
-                * ("user database in remote SQL server" case) */
-               groups = xmalloc(64 * sizeof(gid_t));
-               n = 64;
-               if (get_groups(username, rgid, groups, &n) < 0) {
-                       /* Need bigger buffer after all */
-                       groups = xrealloc(groups, n * sizeof(gid_t));
-                       get_groups(username, rgid, groups, &n);
-               }
-               if (n > 0) {
-                       /* Print the list */
-                       prefix = " groups=";
-                       for (i = 0; i < n; i++) {
-                               if (opt && (groups[i] == rgid || groups[i] == 
egid))
-                                       continue;
-                               status |= print_group(groups[i], opt ? " " : 
prefix);
-                               prefix = ",";
-                       }
-               } else if (n < 0) { /* error in get_groups() */
-                       if (ENABLE_DESKTOP)
-                               bb_error_msg_and_die("can't get groups");
-                       return EXIT_FAILURE;
+                       egid = getegid();
+                       rgid = getgid();
+                       euid = geteuid();
+                       ruid = getuid();
+               }
+               /* JUST_ALL_GROUPS ignores -r PRINT_REAL flag even if man page 
for */
+               /* id says: print the real ID instead of the effective ID, with 
-ugG */
+               /* in fact in this case egid is always printed if egid != rgid 
*/
+               if (!opt || (opt & JUST_ALL_GROUPS)) {
+                       gid_t *groups;
+                       int n;
+       
+                       if (!opt) {
+                               /* Default Mode */
+                               status |= print_user(ruid, "uid=");
+                               status |= print_group(rgid, " gid=");
+                               if (euid != ruid)
+                                       status |= print_user(euid, " euid=");
+                               if (egid != rgid)
+                                       status |= print_group(egid, " egid=");
+                       } else {
+                               if (do_groups)
+                                       printf("%s : ", *argv ? *argv : 
xuid2uname(euid));
+                               /* JUST_ALL_GROUPS */
+                               status |= print_group(rgid, NULL);
+                               if (egid != rgid)
+                                       status |= print_group(egid, " ");
+                       }
+                       /* We are supplying largish buffer, trying
+                       * to not run get_groups() twice. That might be slow
+                       * ("user database in remote SQL server" case) */
+                       groups = xmalloc(64 * sizeof(gid_t));
+                       n = 64;
+                       if (get_groups(*argv, rgid, groups, &n) < 0) {
+                               /* Need bigger buffer after all */
+                               groups = xrealloc(groups, n * sizeof(gid_t));
+                               get_groups(*argv, rgid, groups, &n);
+                       }
+                       if (n > 0) {
+                               /* Print the list */
+                               prefix = " groups=";
+                               for (i = 0; i < n; i++) {
+                                       if (opt && (groups[i] == rgid || 
groups[i] == egid))
+                                               continue;
+                                       status |= print_group(groups[i], opt ? 
" " : prefix);
+                                       prefix = ",";
+                               }
+                       } else if (n < 0) { /* error in get_groups() */
+                               if (ENABLE_DESKTOP)
+                                       bb_error_msg_and_die("can't get 
groups");
+                               return EXIT_FAILURE;
+                       }
+                       if (ENABLE_FEATURE_CLEAN_UP || do_groups)
+                               free(groups);
+       #if ENABLE_SELINUX
+                       if (is_selinux_enabled()) {
+                               if (getcon(&scontext) == 0)
+                                       printf(" context=%s", scontext);
+                       }
+       #endif
+               } else if (opt & PRINT_REAL) {
+                       euid = ruid;
+                       egid = rgid;
+               }
+       
+               if (opt & JUST_USER)
+                       status |= print_user(euid, NULL);
+               else if (opt & JUST_GROUP)
+                       status |= print_group(egid, NULL);
+       #if ENABLE_SELINUX
+               else if (opt & JUST_CONTEXT) {
+                       selinux_or_die();
+                       if (username || getcon(&scontext)) {
+                               bb_error_msg_and_die("can't get process 
context%s",
+                                       username ? " for a different user" : 
"");
+                       }
+                       fputs(scontext, stdout);
                }
+               /* freecon(NULL) seems to be harmless */
                if (ENABLE_FEATURE_CLEAN_UP)
-                       free(groups);
-#if ENABLE_SELINUX
-               if (is_selinux_enabled()) {
-                       if (getcon(&scontext) == 0)
-                               printf(" context=%s", scontext);
-               }
-#endif
-       } else if (opt & PRINT_REAL) {
-               euid = ruid;
-               egid = rgid;
-       }
-
-       if (opt & JUST_USER)
-               status |= print_user(euid, NULL);
-       else if (opt & JUST_GROUP)
-               status |= print_group(egid, NULL);
-#if ENABLE_SELINUX
-       else if (opt & JUST_CONTEXT) {
-               selinux_or_die();
-               if (username || getcon(&scontext)) {
-                       bb_error_msg_and_die("can't get process context%s",
-                               username ? " for a different user" : "");
-               }
-               fputs(scontext, stdout);
-       }
-       /* freecon(NULL) seems to be harmless */
-       if (ENABLE_FEATURE_CLEAN_UP)
-               freecon(scontext);
-#endif
-       bb_putchar('\n');
+                       freecon(scontext);
+       #endif
+               bb_putchar('\n');
+       } while (do_groups-- > 1 && *argv++);
        fflush_stdout_and_exit(status);
 }

Attachment: id2.patch.gz
Description: GNU Zip compressed data

_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to