]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3: VFS: Split out fget_nt_acl_common() from get_nt_acl_common().
authorJeremy Allison <jra@samba.org>
Mon, 13 Apr 2020 19:09:47 +0000 (12:09 -0700)
committerJeremy Allison <jra@samba.org>
Thu, 7 May 2020 19:27:34 +0000 (19:27 +0000)
No change in logic and not yet used, just means it'll be
cleaner when we start adding the xxxAT() versions of SMB_VFS_GET_NT_ACL().

Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
source3/modules/vfs_acl_common.c
source3/modules/vfs_acl_common.h

index 43167be77a3a005110f528969750223c25386f93..5a2fc81bc43ad0e9292d3cc048c384f1e51b368d 100644 (file)
@@ -635,6 +635,154 @@ static NTSTATUS stat_fsp_or_smb_fname(vfs_handle_struct *handle,
        return NT_STATUS_OK;
 }
 
+/*******************************************************************
+ Pull a DATA_BLOB from an xattr given an fsp.
+ If the hash doesn't match, or doesn't exist - return the underlying
+ filesystem sd.
+*******************************************************************/
+
+NTSTATUS fget_nt_acl_common(
+       NTSTATUS (*fget_acl_blob_fn)(TALLOC_CTX *ctx,
+                                   vfs_handle_struct *handle,
+                                   files_struct *fsp,
+                                   DATA_BLOB *pblob),
+       vfs_handle_struct *handle,
+       files_struct *fsp,
+       uint32_t security_info,
+       TALLOC_CTX *mem_ctx,
+       struct security_descriptor **ppdesc)
+{
+       DATA_BLOB blob = data_blob_null;
+       NTSTATUS status;
+       struct security_descriptor *psd = NULL;
+       const struct smb_filename *smb_fname = fsp->fsp_name;
+       bool psd_is_from_fs = false;
+       struct acl_common_config *config = NULL;
+
+       SMB_VFS_HANDLE_GET_DATA(handle, config,
+                               struct acl_common_config,
+                               return NT_STATUS_UNSUCCESSFUL);
+
+       DBG_DEBUG("name=%s\n", smb_fname->base_name);
+
+       status = fget_acl_blob_fn(mem_ctx, handle, fsp, &blob);
+       if (NT_STATUS_IS_OK(status)) {
+               status = validate_nt_acl_blob(mem_ctx,
+                                             handle,
+                                             fsp,
+                                             smb_fname,
+                                             &blob,
+                                             &psd,
+                                             &psd_is_from_fs);
+               TALLOC_FREE(blob.data);
+               if (!NT_STATUS_IS_OK(status)) {
+                       DBG_DEBUG("ACL validation for [%s] failed\n",
+                                 smb_fname->base_name);
+                       goto fail;
+               }
+       }
+
+       if (psd == NULL) {
+               /* Get the full underlying sd, as we failed to get the
+                * blob for the hash, or the revision/hash type wasn't
+                * known */
+
+               if (config->ignore_system_acls) {
+                       status = vfs_stat_fsp(fsp);
+                       if (!NT_STATUS_IS_OK(status)) {
+                               goto fail;
+                       }
+
+                       status = make_default_filesystem_acl(
+                               mem_ctx,
+                               config->default_acl_style,
+                               smb_fname->base_name,
+                               &fsp->fsp_name->st,
+                               &psd);
+                       if (!NT_STATUS_IS_OK(status)) {
+                               goto fail;
+                       }
+               } else {
+                       status = SMB_VFS_NEXT_FGET_NT_ACL(handle,
+                                                         fsp,
+                                                         security_info,
+                                                         mem_ctx,
+                                                         &psd);
+
+                       if (!NT_STATUS_IS_OK(status)) {
+                               DBG_DEBUG("get_next_acl for file %s "
+                                         "returned %s\n",
+                                         smb_fname->base_name,
+                                         nt_errstr(status));
+                               goto fail;
+                       }
+
+                       psd_is_from_fs = true;
+               }
+       }
+
+       if (psd_is_from_fs) {
+               status = vfs_stat_fsp(fsp);
+               if (!NT_STATUS_IS_OK(status)) {
+                       goto fail;
+               }
+
+               /*
+                * We're returning the underlying ACL from the
+                * filesystem. If it's a directory, and has no
+                * inheritable ACE entries we have to fake them.
+                */
+
+               if (fsp->fsp_flags.is_directory &&
+                               !sd_has_inheritable_components(psd, true)) {
+                       status = add_directory_inheritable_components(
+                               handle,
+                               smb_fname->base_name,
+                               &fsp->fsp_name->st,
+                               psd);
+                       if (!NT_STATUS_IS_OK(status)) {
+                               goto fail;
+                       }
+               }
+
+               /*
+                * The underlying POSIX module always sets the
+                * ~SEC_DESC_DACL_PROTECTED bit, as ACLs can't be inherited in
+                * this way under POSIX. Remove it for Windows-style ACLs.
+                */
+               psd->type &= ~SEC_DESC_DACL_PROTECTED;
+       }
+
+       if (!(security_info & SECINFO_OWNER)) {
+               psd->owner_sid = NULL;
+       }
+       if (!(security_info & SECINFO_GROUP)) {
+               psd->group_sid = NULL;
+       }
+       if (!(security_info & SECINFO_DACL)) {
+               psd->type &= ~SEC_DESC_DACL_PRESENT;
+               psd->dacl = NULL;
+       }
+       if (!(security_info & SECINFO_SACL)) {
+               psd->type &= ~SEC_DESC_SACL_PRESENT;
+               psd->sacl = NULL;
+       }
+
+       if (DEBUGLEVEL >= 10) {
+               DBG_DEBUG("returning acl for %s is:\n",
+                         smb_fname->base_name);
+               NDR_PRINT_DEBUG(security_descriptor, psd);
+       }
+
+       *ppdesc = psd;
+
+       return NT_STATUS_OK;
+
+fail:
+       TALLOC_FREE(psd);
+       return status;
+}
+
 /*******************************************************************
  Pull a DATA_BLOB from an xattr given a pathname.
  If the hash doesn't match, or doesn't exist - return the underlying
index bc2177349d3619cef8110e3503ad062bd59a0a00..3fc5c2bf1048bf4f9a4bbce89318c1535381792a 100644 (file)
@@ -60,6 +60,17 @@ NTSTATUS get_nt_acl_common(
        TALLOC_CTX *mem_ctx,
        struct security_descriptor **ppdesc);
 
+NTSTATUS fget_nt_acl_common(
+       NTSTATUS (*fget_acl_blob_fn)(TALLOC_CTX *ctx,
+                                   vfs_handle_struct *handle,
+                                   files_struct *fsp,
+                                   DATA_BLOB *pblob),
+       vfs_handle_struct *handle,
+       files_struct *fsp,
+       uint32_t security_info,
+       TALLOC_CTX *mem_ctx,
+       struct security_descriptor **ppdesc);
+
 NTSTATUS fset_nt_acl_common(
        NTSTATUS (*get_acl_blob_fn)(TALLOC_CTX *ctx,
                                    vfs_handle_struct *handle,