Fix checks in can_delete_file_in_directory()
authorVolker Lendecke <vl@samba.org>
Thu, 19 Jun 2008 12:53:46 +0000 (14:53 +0200)
committerVolker Lendecke <vl@samba.org>
Thu, 19 Jun 2008 13:27:41 +0000 (15:27 +0200)
With at least NFSv4 ACLs around the write permission for the owner is a bogus
check if we can delete a file in a directory. Like in Windows, there are two
ways which can grant us such: First, the DELETE permission on the file itself,
or if that does not help, the DELETE_CHILD permission on the directory. It
might be a bit more code that runs, but essentially we should end up with the
same set of syscalls in the non-acl case.

source/smbd/file_access.c

index 0552a16b508a3357fb0539989af2de27e5a57f5e..e61a8c3a5a282de15bcb9038a9e8dac1657aea74 100644 (file)
@@ -87,11 +87,6 @@ bool can_delete_file_in_directory(connection_struct *conn, const char *fname)
                return True;
        }
 
-       /* Check primary owner write access. */
-       if (conn->server_info->uid == sbuf.st_uid) {
-               return (sbuf.st_mode & S_IWUSR) ? True : False;
-       }
-
 #ifdef S_ISVTX
        /* sticky bit means delete only by owner or root. */
        if (sbuf.st_mode & S_ISVTX) {
@@ -117,7 +112,21 @@ bool can_delete_file_in_directory(connection_struct *conn, const char *fname)
 
        /* now for ACL checks */
 
-       return can_access_file_acl(conn, dname, FILE_WRITE_DATA);
+       /*
+        * There's two ways to get the permission to delete a file: First by
+        * having the DELETE bit on the file itself and second if that does
+        * not help, by the DELETE_CHILD bit on the containing directory.
+        *
+        * Here we check the other way round because with just posix
+        * permissions looking at the file itself will never grant DELETE, so
+        * by looking at the directory first we save one get_acl call.
+        */
+
+       if (can_access_file_acl(conn, dname, FILE_DELETE_CHILD)) {
+               return true;
+       }
+
+       return can_access_file_acl(conn, fname, DELETE_ACCESS);
 }
 
 /****************************************************************************