summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBaptiste Daroussin <bapt@FreeBSD.org>2020-03-23 08:23:22 +0000
committerBaptiste Daroussin <bapt@FreeBSD.org>2020-03-23 08:23:22 +0000
commita4ba6edfe75c4ed6cc70fdff9a7c22b2e49a8129 (patch)
treeb8e5bbc1bd9eeac47b69b7aa148fe3760f31daa4
parent3722ad4a19622e3b757b0735dc355e48b5ef34dc (diff)
downloadpw-darwin-a4ba6edfe75c4ed6cc70fdff9a7c22b2e49a8129.tar.gz
pw-darwin-a4ba6edfe75c4ed6cc70fdff9a7c22b2e49a8129.tar.zst
pw-darwin-a4ba6edfe75c4ed6cc70fdff9a7c22b2e49a8129.zip
pw: do not removed home directories if not owned
When deleting a user, if its home directory does not belong to it, it should not be removed. This is the promise that the manpage makes, the tool should ensure that it respects that promise. Add a regression test about it PR: 244967 Submitted by: Eric Hanneken <eric@erichanneken.com> MFC after: 3 days
-rw-r--r--pw/rm_r.c5
-rwxr-xr-xpw/tests/pw_userdel_test.sh20
2 files changed, 24 insertions, 1 deletions
diff --git a/pw/rm_r.c b/pw/rm_r.c
index 940266d..66298a2 100644
--- a/pw/rm_r.c
+++ b/pw/rm_r.c
@@ -71,5 +71,8 @@ rm_r(int rootfd, const char *path, uid_t uid)
closedir(d);
if (fstatat(rootfd, path, &st, AT_SYMLINK_NOFOLLOW) != 0)
return;
- unlinkat(rootfd, path, S_ISDIR(st.st_mode) ? AT_REMOVEDIR : 0);
+ if (S_ISLNK(st.st_mode))
+ unlinkat(rootfd, path, 0);
+ else if (st.st_uid == uid)
+ unlinkat(rootfd, path, AT_REMOVEDIR);
}
diff --git a/pw/tests/pw_userdel_test.sh b/pw/tests/pw_userdel_test.sh
index d03501a..694d7bb 100755
--- a/pw/tests/pw_userdel_test.sh
+++ b/pw/tests/pw_userdel_test.sh
@@ -67,10 +67,30 @@ home_not_a_dir_body() {
atf_check ${RPW} userdel foo -r
}
+atf_test_case home_shared
+home_shared_body() {
+ populate_root_etc_skel
+ mkdir ${HOME}/shared
+ atf_check ${RPW} useradd -n testuser1 -d /shared
+ atf_check ${RPW} useradd -n testuser2 -d /shared
+ atf_check ${RPW} userdel -n testuser1 -r
+ test -d ${HOME}/shared || atf_fail "Shared home has been removed"
+}
+
+atf_test_case home_regular_dir
+home_regular_dir_body() {
+ populate_root_etc_skel
+ atf_check ${RPW} useradd -n foo -d /foo
+ atf_check ${RPW} userdel -n foo -r
+ [ ! -d ${HOME}/foo ] || atf_fail "Home has not been removed"
+}
+
atf_init_test_cases() {
atf_add_test_case rmuser_seperate_group
atf_add_test_case user_do_not_try_to_delete_root_if_user_unknown
atf_add_test_case delete_files
atf_add_test_case delete_numeric_name
atf_add_test_case home_not_a_dir
+ atf_add_test_case home_shared
+ atf_add_test_case home_regular_dir
}