diff --git a/usr.sbin/pw/pw.h b/usr.sbin/pw/pw.h --- a/usr.sbin/pw/pw.h +++ b/usr.sbin/pw/pw.h @@ -114,3 +114,5 @@ uintmax_t strtounum(const char * __restrict, uintmax_t, uintmax_t, const char ** __restrict); + +bool grp_has_member(struct group *grp, const char *name); diff --git a/usr.sbin/pw/pw_group.c b/usr.sbin/pw/pw_group.c --- a/usr.sbin/pw/pw_group.c +++ b/usr.sbin/pw/pw_group.c @@ -418,7 +418,7 @@ return (EXIT_SUCCESS); } -static bool +bool grp_has_member(struct group *grp, const char *name) { int j; diff --git a/usr.sbin/pw/pw_user.c b/usr.sbin/pw/pw_user.c --- a/usr.sbin/pw/pw_user.c +++ b/usr.sbin/pw/pw_user.c @@ -378,8 +378,7 @@ grp = GETGRGID(gid); } gid = grp->gr_gid; - } else if ((grp = GETGRNAM(nam)) != NULL && - (grp->gr_mem == NULL || grp->gr_mem[0] == NULL)) { + } else if ((grp = GETGRNAM(nam)) != NULL) { gid = grp->gr_gid; /* Already created? Use it anyway... */ } else { intmax_t grid = -1; @@ -1408,6 +1407,9 @@ if (cmdcnf->groups != NULL) { for (i = 0; i < cmdcnf->groups->sl_cur; i++) { grp = GETGRNAM(cmdcnf->groups->sl_str[i]); + /* gr_add doesn't check if new member is already in group */ + if (grp_has_member(grp, pwd->pw_name)) + continue; grp = gr_add(grp, pwd->pw_name); /* * grp can only be NULL in 2 cases: diff --git a/usr.sbin/pw/tests/pw_useradd_test.sh b/usr.sbin/pw/tests/pw_useradd_test.sh --- a/usr.sbin/pw/tests/pw_useradd_test.sh +++ b/usr.sbin/pw/tests/pw_useradd_test.sh @@ -463,6 +463,29 @@ grep defaultpasswd ${HOME}/pw.conf } +atf_test_case user_add_existing_login_group +user_add_existing_login_group_body() +{ + populate_etc_skel + + atf_check -s exit:0 ${PW} groupadd testuser + atf_check -s exit:0 ${PW} useradd user1 -G testuser + atf_check -s exit:0 ${PW} useradd testuser + atf_check -o match:"1" \ + sh -c "grep testuser ${HOME}/group | wc -l" +} + +atf_test_case user_add_already_in_group +user_add_already_in_group_body() +{ + populate_etc_skel + + echo "testgroup:*:4242:testuser" >> ${HOME}/group + atf_check -s exit:0 ${PW} useradd testuser -G testgroup + atf_check -o not-match:"testuser,testuser" \ + grep testuser ${HOME}/group +} + atf_init_test_cases() { atf_add_test_case user_add atf_add_test_case user_add_noupdate @@ -503,4 +526,6 @@ atf_add_test_case user_add_defaultgroup atf_add_test_case user_add_conf_defaultpasswd + atf_add_test_case user_add_existing_login_group + atf_add_test_case user_add_already_in_group }