[prev in list] [next in list] [prev in thread] [next in thread] 

List:       busybox
Subject:    Re: [PATCH] allows group to use multiple usernames
From:       Tito <farmatito () tiscali ! it>
Date:       2011-06-22 13:51:25
Message-ID: 201106221551.25995.farmatito () tiscali ! it
[Download RAW message or body]

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);
 }

["id2.patch.gz" (application/x-gzip)]

_______________________________________________
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic