Fix bug #6133 - Cannot delete non-ACL files on Solaris/ZFS/NFSv4 ACL filesystem.
authorJeremy Allison <jra@samba.org>
Fri, 20 Feb 2009 16:22:57 +0000 (08:22 -0800)
committerJeremy Allison <jra@samba.org>
Fri, 20 Feb 2009 16:22:57 +0000 (08:22 -0800)
As the NFSv4 ACL mapping code doesn't map write directory into the DELETE_CHILD
permission bit (which we require before allowing a delete) no one can delete
files without an explicit DELETE_CHILD bit set on the directory. Add this mapping.
Jeremy.

source/modules/nfs4_acls.c

index 556dad6b5e5c91684a191529e51466eb09f1499f..ba038479af4b3356f2af92aad06e2a74c98bd8bc 100644 (file)
@@ -198,6 +198,7 @@ static int smbacl4_fGetFileOwner(files_struct *fsp, SMB_STRUCT_STAT *psbuf)
 static bool smbacl4_nfs42win(TALLOC_CTX *mem_ctx, SMB4ACL_T *acl, /* in */
        DOM_SID *psid_owner, /* in */
        DOM_SID *psid_group, /* in */
+       bool is_directory, /* in */
        SEC_ACE **ppnt_ace_list, /* out */
        int *pgood_aces /* out */
 )
@@ -256,6 +257,10 @@ static bool smbacl4_nfs42win(TALLOC_CTX *mem_ctx, SMB4ACL_T *acl, /* in */
                DEBUG(10, ("mapped %d to %s\n", ace->who.id,
                           sid_string_dbg(&sid)));
 
+               if (is_directory && (ace->aceMask & SMB_ACE4_ADD_FILE)) {
+                       ace->aceMask |= SMB_ACE4_DELETE_CHILD;
+               }
+
                mask = ace->aceMask;
                init_sec_ace(&nt_ace_list[good_aces++], &sid,
                        ace->aceType, mask,
@@ -287,7 +292,8 @@ static NTSTATUS smb_get_nt_acl_nfs4_common(const SMB_STRUCT_STAT *sbuf,
        uid_to_sid(&sid_owner, sbuf->st_uid);
        gid_to_sid(&sid_group, sbuf->st_gid);
 
-       if (smbacl4_nfs42win(mem_ctx, acl, &sid_owner, &sid_group, &nt_ace_list, &good_aces)==False) {
+       if (smbacl4_nfs42win(mem_ctx, acl, &sid_owner, &sid_group, S_ISDIR(sbuf->st_mode),
+                               &nt_ace_list, &good_aces)==False) {
                DEBUG(8,("smbacl4_nfs42win failed\n"));
                return map_nt_error_from_unix(errno);
        }