summaryrefslogtreecommitdiff
path: root/source3/smbd/file_access.c
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2008-06-19 14:53:46 +0200
committerVolker Lendecke <vl@samba.org>2008-06-19 15:27:41 +0200
commit066f6c856fccc791009f85492289276267e24bcf (patch)
tree2ae1efdae4d8d5c85ed75c9eab054630178a0eb7 /source3/smbd/file_access.c
parent7df309c339602d2d67e146441958818f626a0f6b (diff)
downloadsamba-066f6c856fccc791009f85492289276267e24bcf.tar.gz
samba-066f6c856fccc791009f85492289276267e24bcf.tar.bz2
samba-066f6c856fccc791009f85492289276267e24bcf.zip
Fix checks in can_delete_file_in_directory()
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. (This used to be commit daa9b056645a45edfb3a70e3536011ebe5678970)
Diffstat (limited to 'source3/smbd/file_access.c')
-rw-r--r--source3/smbd/file_access.c21
1 files changed, 15 insertions, 6 deletions
diff --git a/source3/smbd/file_access.c b/source3/smbd/file_access.c
index 0552a16b50..e61a8c3a5a 100644
--- a/source3/smbd/file_access.c
+++ b/source3/smbd/file_access.c
@@ -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);
}
/****************************************************************************