Check unlink on directory for all users, not just root.
authorCraig A. Berry <craigberry@mac.com>
Sun, 1 Dec 2013 23:16:47 +0000 (17:16 -0600)
committerCraig A. Berry <craigberry@mac.com>
Tue, 3 Dec 2013 04:45:36 +0000 (22:45 -0600)
For cross-platform consistency, it makes more sense to reject
unlink attempts on directories in the same way for all users
rather than only for root.  geteuid() always returns zero on
Windows, never returns zero on VMS, and is a poor indicator
of privilege on modern unixen, so the code really hasn't been
working as intended on all platforms anyway.

doio.c
t/io/fs.t

diff --git a/doio.c b/doio.c
index 56d33b2..b80460a 100644 (file)
--- a/doio.c
+++ b/doio.c
@@ -1816,7 +1816,7 @@ nothing in the core.
            if (!IS_SAFE_PATHNAME(s, len, "unlink")) {
                 tot--;
             }
-           else if (PerlProc_geteuid() || PL_unsafe) {
+           else if (PL_unsafe) {
                if (UNLINK(s))
                    tot--;
            }
index 857b091..aaa6a7b 100644 (file)
--- a/t/io/fs.t
+++ b/t/io/fs.t
@@ -457,11 +457,9 @@ ok(-d $tmpdir1, "rename on directories working");
     ok(1, "extend sp in pp_chown");
 }
 
-# Calling unlink on a directory as root without -U will always fail, but
+# Calling unlink on a directory without -U and privileges will always fail, but
 # it should set errno to EISDIR even though unlink(2) is never called.
-SKIP: {
-    skip "only test unlink(dir) when running as root", 3 if $> != 0;
-
+{
     require Errno;
 
     my $tmpdir = tempfile();
@@ -477,15 +475,15 @@ SKIP: {
 
     # errno should be set even though unlink(2) is not called
     local $!;
-    is(unlink($tmpdir), 0, "can't unlink directory as root without -U");
-    is(0+$!, Errno::EISDIR(), "unlink directory as root without -U sets errno");
+    is(unlink($tmpdir), 0, "can't unlink directory without -U and privileges");
+    is(0+$!, Errno::EISDIR(), "unlink directory without -U sets errno");
 
     rmdir $tmpdir;
 
     # errno should be set by failed lstat(2) call
     $! = 0;
     unlink($tmpdir);
-    is(0+$!, Errno::ENOENT(), "unlink non-existent directory as root without -U sets ENOENT");
+    is(0+$!, Errno::ENOENT(), "unlink non-existent directory without -U sets ENOENT");
 }
 
 # need to remove $tmpdir if rename() in test 28 failed!