diff options
-rw-r--r-- | pw/pw_group.c | 90 | ||||
-rwxr-xr-x | pw/tests/pw_groupmod.sh | 27 |
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 } |