vfs_acl_common: avoid setting POSIX ACLs if "ignore system acls" is set
authorUri Simchoni <uri@samba.org>
Mon, 21 Mar 2016 21:04:24 +0000 (23:04 +0200)
committerJeremy Allison <jra@samba.org>
Thu, 24 Mar 2016 02:06:16 +0000 (03:06 +0100)
When "ignore system acls" is set, do not mess at all with POSIX ACLS,
do not even calculate the would-be POSIX-ACL-based security descriptor
(for performance reasons).
Instead, just store a V3 blob with zero hash. This means that if we
later read the ACL without ignoring system ACLs, the NT ACL shall be
reset to the info derivable from the POSIX ACL.

File ownership is still modified as it has bearing on disk quotas.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=11806

Signed-off-by: Uri Simchoni <uri@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
source3/modules/vfs_acl_common.c

index c8c0650ef9369d6b6e243a986b6fed9afab19bfb..d21c16707c849747d39e2ec0b6dc88cf8afb6047 100644 (file)
@@ -744,6 +744,81 @@ static NTSTATUS get_nt_acl_common(vfs_handle_struct *handle,
                                ppdesc);
 }
 
+/*********************************************************************
+ Set the underlying ACL (e.g. POSIX ACLS, POSIX owner, etc)
+*********************************************************************/
+static NTSTATUS set_underlying_acl(vfs_handle_struct *handle, files_struct *fsp,
+                                  struct security_descriptor *psd,
+                                  uint32_t security_info_sent,
+                                  bool chown_needed)
+{
+       NTSTATUS status =
+           SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent, psd);
+       if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
+               return status;
+       }
+
+       /* We got access denied here. If we're already root,
+          or we didn't need to do a chown, or the fsp isn't
+          open with WRITE_OWNER access, just return. */
+       if (get_current_uid(handle->conn) == 0 || chown_needed == false ||
+           !(fsp->access_mask & SEC_STD_WRITE_OWNER)) {
+               return NT_STATUS_ACCESS_DENIED;
+       }
+
+       DEBUG(10, ("fset_nt_acl_common: overriding chown on file %s "
+                  "for sid %s\n",
+                  fsp_str_dbg(fsp), sid_string_tos(psd->owner_sid)));
+
+       /* Ok, we failed to chown and we have
+          SEC_STD_WRITE_OWNER access - override. */
+       become_root();
+       status = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent, psd);
+       unbecome_root();
+
+       return status;
+}
+
+/*********************************************************************
+ Store a v3 security descriptor
+*********************************************************************/
+static NTSTATUS store_v3_blob(vfs_handle_struct *handle, files_struct *fsp,
+                             struct security_descriptor *psd,
+                             struct security_descriptor *pdesc_next,
+                             uint8_t hash[XATTR_SD_HASH_SIZE])
+{
+       NTSTATUS status;
+       DATA_BLOB blob;
+
+       if (DEBUGLEVEL >= 10) {
+               DEBUG(10, ("fset_nt_acl_xattr: storing xattr sd for file %s\n",
+                          fsp_str_dbg(fsp)));
+               NDR_PRINT_DEBUG(
+                   security_descriptor,
+                   discard_const_p(struct security_descriptor, psd));
+
+               if (pdesc_next != NULL) {
+                       DEBUG(10, ("fset_nt_acl_xattr: storing has in xattr sd "
+                                  "based on \n"));
+                       NDR_PRINT_DEBUG(
+                           security_descriptor,
+                           discard_const_p(struct security_descriptor,
+                                           pdesc_next));
+               } else {
+                       DEBUG(10,
+                             ("fset_nt_acl_xattr: ignoring underlying sd\n"));
+               }
+       }
+       status = create_acl_blob(psd, &blob, XATTR_SD_HASH_TYPE_SHA256, hash);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(10, ("fset_nt_acl_xattr: create_acl_blob failed\n"));
+               return status;
+       }
+
+       status = store_acl_blob_fsp(handle, fsp, &blob);
+       return status;
+}
+
 /*********************************************************************
  Store a security descriptor given an fsp.
 *********************************************************************/
@@ -761,6 +836,8 @@ static NTSTATUS fset_nt_acl_common(vfs_handle_struct *handle, files_struct *fsp,
        bool chown_needed = false;
        char *sys_acl_description;
        TALLOC_CTX *frame = talloc_stackframe();
+       bool ignore_file_system_acl = lp_parm_bool(
+           SNUM(handle->conn), ACL_MODULE_NAME, "ignore system acls", false);
 
        if (DEBUGLEVEL >= 10) {
                DEBUG(10,("fset_nt_acl_xattr: incoming sd for file %s\n",
@@ -816,38 +893,29 @@ static NTSTATUS fset_nt_acl_common(vfs_handle_struct *handle, files_struct *fsp,
                psd->type |= SEC_DESC_SACL_PRESENT;
        }
 
-       status = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent, psd);
-       if (!NT_STATUS_IS_OK(status)) {
-               if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
-                       TALLOC_FREE(frame);
-                       return status;
-               }
-               /* We got access denied here. If we're already root,
-                  or we didn't need to do a chown, or the fsp isn't
-                  open with WRITE_OWNER access, just return. */
-               if (get_current_uid(handle->conn) == 0 ||
-                               chown_needed == false ||
-                               !(fsp->access_mask & SEC_STD_WRITE_OWNER)) {
-                       TALLOC_FREE(frame);
-                       return NT_STATUS_ACCESS_DENIED;
+       if (ignore_file_system_acl) {
+               if (chown_needed) {
+                       /* send only ownership stuff to lower layer */
+                       security_info_sent &= (SECINFO_OWNER | SECINFO_GROUP);
+                       status = set_underlying_acl(handle, fsp, psd,
+                                                   security_info_sent, true);
+                       if (!NT_STATUS_IS_OK(status)) {
+                               TALLOC_FREE(frame);
+                               return status;
+                       }
                }
+               ZERO_ARRAY(hash);
+               status = store_v3_blob(handle, fsp, psd, NULL, hash);
 
-               DEBUG(10,("fset_nt_acl_common: overriding chown on file %s "
-                       "for sid %s\n",
-                       fsp_str_dbg(fsp),
-                       sid_string_tos(psd->owner_sid)
-                       ));
-
-               /* Ok, we failed to chown and we have
-                  SEC_STD_WRITE_OWNER access - override. */
-               become_root();
-               status = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp,
-                               security_info_sent, psd);
-               unbecome_root();
-               if (!NT_STATUS_IS_OK(status)) {
-                       TALLOC_FREE(frame);
-                       return status;
-               }
+               TALLOC_FREE(frame);
+               return status;
+       }
+
+       status = set_underlying_acl(handle, fsp, psd, security_info_sent,
+                                   chown_needed);
+       if (!NT_STATUS_IS_OK(status)) {
+               TALLOC_FREE(frame);
+               return status;
        }
 
        /* Get the full underlying sd, then hash. */
@@ -878,24 +946,7 @@ static NTSTATUS fset_nt_acl_common(vfs_handle_struct *handle, files_struct *fsp,
        /* If we fail to get the ACL blob (for some reason) then this
         * is not fatal, we just work based on the NT ACL only */
        if (ret != 0) {
-               if (DEBUGLEVEL >= 10) {
-                       DEBUG(10,("fset_nt_acl_xattr: storing xattr sd for file %s\n",
-                                 fsp_str_dbg(fsp)));
-                       NDR_PRINT_DEBUG(security_descriptor,
-                                       discard_const_p(struct security_descriptor, psd));
-
-                       DEBUG(10,("fset_nt_acl_xattr: storing has in xattr sd based on \n"));
-                       NDR_PRINT_DEBUG(security_descriptor,
-                                       discard_const_p(struct security_descriptor, pdesc_next));
-               }
-               status = create_acl_blob(psd, &blob, XATTR_SD_HASH_TYPE_SHA256, hash);
-               if (!NT_STATUS_IS_OK(status)) {
-                       DEBUG(10, ("fset_nt_acl_xattr: create_acl_blob failed\n"));
-                       TALLOC_FREE(frame);
-                       return status;
-               }
-
-               status = store_acl_blob_fsp(handle, fsp, &blob);
+               status = store_v3_blob(handle, fsp, psd, pdesc_next, hash);
 
                TALLOC_FREE(frame);
                return status;