On Wednesday 22 June 2011 15:51:25 Tito wrote:
> 
> 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);
>  }
> 

Hi,
Just for future reference the same patch created with --ignore-all-space
switch to show the real code changes. 

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,9 +175,11 @@
                opt = getopt32(argv, "rnugG" IF_SELINUX("Z"));
        }
 
-       username = argv[optind];
-       if (username) {
-               struct passwd *p = xgetpwnam(username);
+       //argc -= optind;
+       argv += optind;
+       do {
+               if (*argv) {
+                       struct passwd *p = xgetpwnam(*argv);
                euid = ruid = p->pw_uid;
                egid = rgid = p->pw_gid;
        } else {
@@ -206,6 +204,8 @@
                        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)
@@ -216,10 +216,10 @@
                 * ("user database in remote SQL server" case) */
                groups = xmalloc(64 * sizeof(gid_t));
                n = 64;
-               if (get_groups(username, rgid, groups, &n) < 0) {
+                       if (get_groups(*argv, rgid, groups, &n) < 0) {
                        /* Need bigger buffer after all */
                        groups = xrealloc(groups, n * sizeof(gid_t));
-                       get_groups(username, rgid, groups, &n);
+                               get_groups(*argv, rgid, groups, &n);
                }
                if (n > 0) {
                        /* Print the list */
@@ -235,7 +235,7 @@
                                bb_error_msg_and_die("can't get groups");
                        return EXIT_FAILURE;
                }
-               if (ENABLE_FEATURE_CLEAN_UP)
+                       if (ENABLE_FEATURE_CLEAN_UP || do_groups)
                        free(groups);
 #if ENABLE_SELINUX
                if (is_selinux_enabled()) {
@@ -266,5 +266,6 @@
                freecon(scontext);
 #endif
        bb_putchar('\n');
+       } while (do_groups-- > 1 && *argv++);
        fflush_stdout_and_exit(status);
 }
--- 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,9 +175,11 @@
 		opt = getopt32(argv, "rnugG" IF_SELINUX("Z"));
 	}
 
-	username = argv[optind];
-	if (username) {
-		struct passwd *p = xgetpwnam(username);
+	//argc -= optind;
+	argv += optind;
+	do {
+		if (*argv) {
+			struct passwd *p = xgetpwnam(*argv);
 		euid = ruid = p->pw_uid;
 		egid = rgid = p->pw_gid;
 	} else {
@@ -206,6 +204,8 @@
 			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)
@@ -216,10 +216,10 @@
 		 * ("user database in remote SQL server" case) */
 		groups = xmalloc(64 * sizeof(gid_t));
 		n = 64;
-		if (get_groups(username, rgid, groups, &n) < 0) {
+			if (get_groups(*argv, rgid, groups, &n) < 0) {
 			/* Need bigger buffer after all */
 			groups = xrealloc(groups, n * sizeof(gid_t));
-			get_groups(username, rgid, groups, &n);
+				get_groups(*argv, rgid, groups, &n);
 		}
 		if (n > 0) {
 			/* Print the list */
@@ -235,7 +235,7 @@
 				bb_error_msg_and_die("can't get groups");
 			return EXIT_FAILURE;
 		}
-		if (ENABLE_FEATURE_CLEAN_UP)
+			if (ENABLE_FEATURE_CLEAN_UP || do_groups)
 			free(groups);
 #if ENABLE_SELINUX
 		if (is_selinux_enabled()) {
@@ -266,5 +266,6 @@
 		freecon(scontext);
 #endif
 	bb_putchar('\n');
+	} while (do_groups-- > 1 && *argv++);
 	fflush_stdout_and_exit(status);
 }
_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to