Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 11 Jul 2015 22:35:08 +0000 (UTC)
From:      Baptiste Daroussin <bapt@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r285411 - in head/usr.sbin/pw: . tests
Message-ID:  <201507112235.t6BMZ8xw056772@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: bapt
Date: Sat Jul 11 22:35:07 2015
New Revision: 285411
URL: https://svnweb.freebsd.org/changeset/base/285411

Log:
  Rework groupmod modification:
  
  Use gr_add(3) when possible to avoid code duplication.
  Use a simpler logic to delete members of a group

Modified:
  head/usr.sbin/pw/pw_group.c
  head/usr.sbin/pw/tests/pw_groupmod.sh

Modified: head/usr.sbin/pw/pw_group.c
==============================================================================
--- head/usr.sbin/pw/pw_group.c	Sat Jul 11 21:59:15 2015	(r285410)
+++ head/usr.sbin/pw/pw_group.c	Sat Jul 11 22:35:07 2015	(r285411)
@@ -42,8 +42,7 @@ static const char rcsid[] =
 
 
 static struct passwd *lookup_pwent(const char *user);
-static void	delete_members(char ***members, int *grmembers, int *i,
-    struct carg *arg, struct group *grp);
+static void	delete_members(struct group *grp, char *list);
 static int	print_group(struct group * grp);
 static gid_t    gr_gidpolicy(struct userconf * cnf, long id);
 
@@ -163,7 +162,6 @@ pw_group(int mode, char *name, long id, 
 	int		rc;
 	struct carg    *arg;
 	struct group   *grp = NULL;
-	int	        grmembers = 0;
 	char           **members = NULL;
 	struct userconf	*cnf = conf.userconf;
 
@@ -216,13 +214,11 @@ pw_group(int mode, char *name, long id, 
 		else if (grp != NULL)	/* Exists */
 			errx(EX_DATAERR, "group name `%s' already exists", name);
 
-		extendarray(&members, &grmembers, 200);
-		members[0] = NULL;
 		grp = &fakegroup;
 		grp->gr_name = pw_checkname(name, 0);
 		grp->gr_passwd = "*";
 		grp->gr_gid = gr_gidpolicy(cnf, id);
-		grp->gr_mem = members;
+		grp->gr_mem = NULL;
 	}
 
 	/*
@@ -238,42 +234,31 @@ pw_group(int mode, char *name, long id, 
 	if (((arg = getarg(args, 'M')) != NULL ||
 	    (arg = getarg(args, 'd')) != NULL ||
 	    (arg = getarg(args, 'm')) != NULL) && arg->val) {
-		int	i = 0;
 		char   *p;
 		struct passwd	*pwd;
 
 		/* Make sure this is not stay NULL with -M "" */
-		extendarray(&members, &grmembers, 200);
 		if (arg->ch == 'd')
-			delete_members(&members, &grmembers, &i, arg, grp);
-		else if (arg->ch == 'm') {
-			int	k = 0;
-
-			if (grp->gr_mem != NULL) {
-				while (grp->gr_mem[k] != NULL) {
-					if (extendarray(&members, &grmembers, i + 2) != -1)
-						members[i++] = grp->gr_mem[k];
-					k++;
-				}
+			delete_members(grp, arg->val);
+		else if (arg->ch == 'M')
+			grp->gr_mem = NULL;
+
+		for (p = strtok(arg->val, ", \t"); arg->ch != 'd' &&  p != NULL;
+		    p = strtok(NULL, ", \t")) {
+			int	j;
+
+			/*
+			 * Check for duplicates
+			 */
+			pwd = lookup_pwent(p);
+			for (j = 0; grp->gr_mem != NULL && grp->gr_mem[j] != NULL; j++) {
+				if (strcmp(grp->gr_mem[j], pwd->pw_name) == 0)
+					break;
 			}
+			if (grp->gr_mem != NULL && grp->gr_mem[j] != NULL)
+				continue;
+			grp = gr_add(grp, pwd->pw_name);
 		}
-
-		if (arg->ch != 'd')
-			for (p = strtok(arg->val, ", \t"); p != NULL; p = strtok(NULL, ", \t")) {
-				int	j;
-
-				/*
-				 * Check for duplicates
-				 */
-				pwd = lookup_pwent(p);
-				for (j = 0; j < i && strcmp(members[j], pwd->pw_name) != 0; j++)
-					;
-				if (j == i && extendarray(&members, &grmembers, i + 2) != -1)
-					members[i++] = newstr(pwd->pw_name);
-			}
-		while (i < grmembers)
-			members[i++] = NULL;
-		grp->gr_mem = members;
 	}
 
 	if (conf.dryrun)
@@ -328,42 +313,25 @@ lookup_pwent(const char *user)
  * Delete requested members from a group.
  */
 static void
-delete_members(char ***members, int *grmembers, int *i, struct carg *arg,
-    struct group *grp)
+delete_members(struct group *grp, char *list)
 {
-	bool matchFound;
-	char *user;
-	char *valueCopy;
-	char *valuePtr;
+	char *p;
 	int k;
-	struct passwd *pwd;
 
 	if (grp->gr_mem == NULL)
 		return;
 
-	k = 0;
-	while (grp->gr_mem[k] != NULL) {
-		matchFound = false;
-		if ((valueCopy = strdup(arg->val)) == NULL)
-			errx(EX_UNAVAILABLE, "out of memory");
-		valuePtr = valueCopy;
-		while ((user = strsep(&valuePtr, ", \t")) != NULL) {
-			pwd = lookup_pwent(user);
-			if (strcmp(grp->gr_mem[k], pwd->pw_name) == 0) {
-				matchFound = true;
+	for (p = strtok(list, ", \t"); p != NULL; p = strtok(NULL, ", \t")) {
+		for (k = 0; grp->gr_mem[k] != NULL; k++) {
+			if (strcmp(grp->gr_mem[k], p) == 0)
 				break;
-			}
 		}
-		free(valueCopy);
-
-		if (!matchFound &&
-		    extendarray(members, grmembers, *i + 2) != -1)
-			(*members)[(*i)++] = grp->gr_mem[k];
+		if (grp->gr_mem[k] == NULL) /* No match */
+			continue;
 
-		k++;
+		for (; grp->gr_mem[k] != NULL; k++)
+			grp->gr_mem[k] = grp->gr_mem[k+1];
 	}
-
-	return;
 }
 
 

Modified: head/usr.sbin/pw/tests/pw_groupmod.sh
==============================================================================
--- head/usr.sbin/pw/tests/pw_groupmod.sh	Sat Jul 11 21:59:15 2015	(r285410)
+++ head/usr.sbin/pw/tests/pw_groupmod.sh	Sat Jul 11 22:35:07 2015	(r285411)
@@ -81,6 +81,32 @@ groupmod_rename_body() {
 		grep "^bar:.*" ${HOME}/group
 }
 
+atf_test_case groupmod_members
+groupmod_members_body() {
+	populate_etc_skel
+
+	for i in user1 user2 user3 user4; do
+		atf_check -s exit:0 ${PW} useradd $i
+	done
+
+	atf_check -s exit:0 ${PW} groupadd foo -M "user1, user2"
+	atf_check -o inline:"foo:*:1005:user1,user2\n" -s exit:0 \
+		${PW} groupshow foo
+	atf_check -s exit:0 ${PW} groupmod foo -m "user3, user4"
+	atf_check -o inline:"foo:*:1005:user1,user2,user3,user4\n" -s exit:0 \
+		${PW} groupshow foo
+	atf_check -s exit:0 ${PW} groupmod foo -M "user1, user4"
+	atf_check -o inline:"foo:*:1005:user1,user4\n" -s exit:0 \
+		${PW} groupshow foo
+	# what about duplicates
+	atf_check -s exit:0 ${PW} groupmod foo -m "user1, user2, user3, user4"
+	atf_check -o inline:"foo:*:1005:user1,user4,user2,user3\n" -s exit:0 \
+		${PW} groupshow foo
+	atf_check -s exit:0 ${PW} groupmod foo -d "user1, user3"
+	atf_check -o inline:"foo:*:1005:user4,user2\n" -s exit:0 \
+		${PW} groupshow foo
+}
+
 atf_init_test_cases() {
 	atf_add_test_case groupmod_user
 	atf_add_test_case groupmod_invalid_user
@@ -88,4 +114,5 @@ atf_init_test_cases() {
 	atf_add_test_case usermod_bug_185666
 	atf_add_test_case do_not_duplicate_group_on_gid_change
 	atf_add_test_case groupmod_rename
+	atf_add_test_case groupmod_members
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201507112235.t6BMZ8xw056772>