summaryrefslogtreecommitdiffstats
path: root/pw
diff options
context:
space:
mode:
Diffstat (limited to 'pw')
-rw-r--r--pw/pw_group.c90
-rwxr-xr-xpw/tests/pw_groupmod.sh27
2 files changed, 56 insertions, 61 deletions
diff --git a/pw/pw_group.c b/pw/pw_group.c
index a3fa595..156ab3d 100644
--- a/pw/pw_group.c
+++ b/pw/pw_group.c
@@ -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, struct cargs * args)
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, struct cargs * args)
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, struct cargs * args)
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;
}
diff --git a/pw/tests/pw_groupmod.sh b/pw/tests/pw_groupmod.sh
index 9ea8a6d..5806925 100755
--- a/pw/tests/pw_groupmod.sh
+++ b/pw/tests/pw_groupmod.sh
@@ -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
}