Factor out common code into vfs_acl_common.c.
authorJeremy Allison <jra@samba.org>
Sat, 25 Jul 2009 00:06:41 +0000 (17:06 -0700)
committerJeremy Allison <jra@samba.org>
Sat, 25 Jul 2009 00:06:41 +0000 (17:06 -0700)
Jeremy.

source3/Makefile.in
source3/include/proto.h
source3/modules/vfs_acl_common.c [new file with mode: 0644]
source3/modules/vfs_acl_tdb.c
source3/modules/vfs_acl_xattr.c

index e6d0cf00ddd0069f6a60e2bba5961c8f3a42c54d..b963511b39a8ac97a6229672b34b4b236c9e7071 100644 (file)
@@ -706,8 +706,8 @@ VFS_FILEID_OBJ = modules/vfs_fileid.o
 VFS_AIO_FORK_OBJ = modules/vfs_aio_fork.o
 VFS_PREOPEN_OBJ = modules/vfs_preopen.o
 VFS_SYNCOPS_OBJ = modules/vfs_syncops.o
-VFS_ACL_XATTR_OBJ = modules/vfs_acl_xattr.o
-VFS_ACL_TDB_OBJ = modules/vfs_acl_tdb.o
+VFS_ACL_XATTR_OBJ = modules/vfs_acl_xattr.o modules/vfs_acl_common.o
+VFS_ACL_TDB_OBJ = modules/vfs_acl_tdb.o modules/vfs_acl_common.o
 VFS_SMB_TRAFFIC_ANALYZER_OBJ = modules/vfs_smb_traffic_analyzer.o
 VFS_ONEFS_OBJ = modules/vfs_onefs.o modules/onefs_acl.o modules/onefs_system.o \
                modules/onefs_open.o modules/onefs_streams.o modules/onefs_dir.o \
index a79c7eb7e80e740180c18b9f522b8b5616abda32..92386f5fae9dfe758791a4f70fb17fc0a0dea6cd 100644 (file)
@@ -7284,4 +7284,31 @@ uint32_t ds_uf2atype(uint32_t uf);
 uint32_t ds_gtype2atype(uint32_t gtype);
 enum lsa_SidType ds_atype_map(uint32_t atype);
 
+/* The following definitions come from modules/vfs_acl_xattr.c */
+NTSTATUS get_acl_blob(TALLOC_CTX *ctx,
+                       vfs_handle_struct *handle,
+                       files_struct *fsp,
+                       const char *name,
+                       DATA_BLOB *pblob);
+NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle,
+                       files_struct *fsp,
+                       DATA_BLOB *pblob);
+NTSTATUS store_acl_blob_pathname(vfs_handle_struct *handle,
+                       const char *fname,
+                       DATA_BLOB *pblob);
+
+/* The following definitions come from modules/vfs_acl_common.c */
+int open_acl_common(vfs_handle_struct *handle,
+                       struct smb_filename *smb_fname,
+                       files_struct *fsp,
+                       int flags,
+                       mode_t mode);
+int mkdir_acl_common(vfs_handle_struct *handle, const char *path, mode_t mode);
+NTSTATUS fget_nt_acl_common(vfs_handle_struct *handle, files_struct *fsp,
+       uint32_t security_info, struct security_descriptor **ppdesc);
+NTSTATUS get_nt_acl_common(vfs_handle_struct *handle,
+       const char *name, uint32_t security_info, struct security_descriptor **ppdesc);
+NTSTATUS fset_nt_acl_common(vfs_handle_struct *handle, files_struct *fsp,
+       uint32_t security_info_sent, const struct security_descriptor *psd);
+
 #endif /*  _PROTO_H_  */
diff --git a/source3/modules/vfs_acl_common.c b/source3/modules/vfs_acl_common.c
new file mode 100644 (file)
index 0000000..d8ff8c6
--- /dev/null
@@ -0,0 +1,637 @@
+/*
+ * Store Windows ACLs in data store - common functions.
+ *
+ * Copyright (C) Volker Lendecke, 2008
+ * Copyright (C) Jeremy Allison, 2009
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* NOTE: This is an experimental module, not yet finished. JRA. */
+
+#include "includes.h"
+#include "librpc/gen_ndr/xattr.h"
+#include "librpc/gen_ndr/ndr_xattr.h"
+#include "../lib/crypto/crypto.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_VFS
+
+static NTSTATUS create_acl_blob(const struct security_descriptor *psd,
+                       DATA_BLOB *pblob,
+                       uint16_t hash_type,
+                       uint8_t hash[XATTR_SD_HASH_SIZE]);
+
+#define HASH_SECURITY_INFO (OWNER_SECURITY_INFORMATION | \
+                               GROUP_SECURITY_INFORMATION | \
+                               DACL_SECURITY_INFORMATION | \
+                               SACL_SECURITY_INFORMATION)
+
+/*******************************************************************
+ Hash a security descriptor.
+*******************************************************************/
+
+static NTSTATUS hash_sd_sha256(struct security_descriptor *psd,
+                       uint8_t *hash)
+{
+       DATA_BLOB blob;
+       SHA256_CTX tctx;
+       NTSTATUS status;
+
+       memset(hash, '\0', XATTR_SD_HASH_SIZE);
+       status = create_acl_blob(psd, &blob, XATTR_SD_HASH_TYPE_SHA256, hash);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       SHA256_Init(&tctx);
+       SHA256_Update(&tctx, blob.data, blob.length);
+       SHA256_Final(hash, &tctx);
+
+       return NT_STATUS_OK;
+}
+
+/*******************************************************************
+ Parse out a struct security_descriptor from a DATA_BLOB.
+*******************************************************************/
+
+static NTSTATUS parse_acl_blob(const DATA_BLOB *pblob,
+                               struct security_descriptor **ppdesc,
+                               uint16_t *p_hash_type,
+                               uint8_t hash[XATTR_SD_HASH_SIZE])
+{
+       TALLOC_CTX *ctx = talloc_tos();
+       struct xattr_NTACL xacl;
+       enum ndr_err_code ndr_err;
+       size_t sd_size;
+
+       ndr_err = ndr_pull_struct_blob(pblob, ctx, NULL, &xacl,
+                       (ndr_pull_flags_fn_t)ndr_pull_xattr_NTACL);
+
+       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+               DEBUG(5, ("parse_acl_blob: ndr_pull_xattr_NTACL failed: %s\n",
+                       ndr_errstr(ndr_err)));
+               return ndr_map_error2ntstatus(ndr_err);;
+       }
+
+       switch (xacl.version) {
+               case 2:
+                       *ppdesc = make_sec_desc(ctx, SEC_DESC_REVISION,
+                                       xacl.info.sd_hs2->sd->type | SEC_DESC_SELF_RELATIVE,
+                                       xacl.info.sd_hs2->sd->owner_sid,
+                                       xacl.info.sd_hs2->sd->group_sid,
+                                       xacl.info.sd_hs2->sd->sacl,
+                                       xacl.info.sd_hs2->sd->dacl,
+                                       &sd_size);
+                       /* No hash - null out. */
+                       *p_hash_type = XATTR_SD_HASH_TYPE_NONE;
+                       memset(hash, '\0', XATTR_SD_HASH_SIZE);
+                       break;
+               case 3:
+                       *ppdesc = make_sec_desc(ctx, SEC_DESC_REVISION,
+                                       xacl.info.sd_hs3->sd->type | SEC_DESC_SELF_RELATIVE,
+                                       xacl.info.sd_hs3->sd->owner_sid,
+                                       xacl.info.sd_hs3->sd->group_sid,
+                                       xacl.info.sd_hs3->sd->sacl,
+                                       xacl.info.sd_hs3->sd->dacl,
+                                       &sd_size);
+                       *p_hash_type = xacl.info.sd_hs3->hash_type;
+                       /* Current version 3. */
+                       memcpy(hash, xacl.info.sd_hs3->hash, XATTR_SD_HASH_SIZE);
+                       break;
+               default:
+                       return NT_STATUS_REVISION_MISMATCH;
+       }
+
+       TALLOC_FREE(xacl.info.sd);
+
+       return (*ppdesc != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
+}
+
+/*******************************************************************
+ Create a DATA_BLOB from a security descriptor.
+*******************************************************************/
+
+static NTSTATUS create_acl_blob(const struct security_descriptor *psd,
+                       DATA_BLOB *pblob,
+                       uint16_t hash_type,
+                       uint8_t hash[XATTR_SD_HASH_SIZE])
+{
+       struct xattr_NTACL xacl;
+       struct security_descriptor_hash_v3 sd_hs3;
+       enum ndr_err_code ndr_err;
+       TALLOC_CTX *ctx = talloc_tos();
+
+       ZERO_STRUCT(xacl);
+       ZERO_STRUCT(sd_hs3);
+
+       xacl.version = 3;
+       xacl.info.sd_hs3 = &sd_hs3;
+       xacl.info.sd_hs3->sd = CONST_DISCARD(struct security_descriptor *, psd);
+       xacl.info.sd_hs3->hash_type = hash_type;
+       memcpy(&xacl.info.sd_hs3->hash[0], hash, XATTR_SD_HASH_SIZE);
+
+       ndr_err = ndr_push_struct_blob(
+                       pblob, ctx, NULL, &xacl,
+                       (ndr_push_flags_fn_t)ndr_push_xattr_NTACL);
+
+       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+               DEBUG(5, ("create_acl_blob: ndr_push_xattr_NTACL failed: %s\n",
+                       ndr_errstr(ndr_err)));
+               return ndr_map_error2ntstatus(ndr_err);;
+       }
+
+       return NT_STATUS_OK;
+}
+
+/*******************************************************************
+ Store a DATA_BLOB into an xattr given a pathname.
+*******************************************************************/
+
+static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle,
+                               files_struct *fsp,
+                               const char *name,
+                               uint32_t security_info,
+                               struct security_descriptor **ppdesc)
+{
+       DATA_BLOB blob;
+       NTSTATUS status;
+       uint16_t hash_type;
+       uint8_t hash[XATTR_SD_HASH_SIZE];
+       uint8_t hash_tmp[XATTR_SD_HASH_SIZE];
+       struct security_descriptor *pdesc_next = NULL;
+
+       if (fsp && name == NULL) {
+               name = fsp->fsp_name->base_name;
+       }
+
+       DEBUG(10, ("get_nt_acl_internal: name=%s\n", name));
+
+       status = get_acl_blob(talloc_tos(), handle, fsp, name, &blob);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(10, ("get_acl_blob returned %s\n", nt_errstr(status)));
+               return status;
+       }
+
+       status = parse_acl_blob(&blob, ppdesc,
+                               &hash_type, &hash[0]);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(10, ("parse_acl_blob returned %s\n",
+                               nt_errstr(status)));
+               return status;
+       }
+
+       /* Ensure the hash type is one we know. */
+       switch (hash_type) {
+               case XATTR_SD_HASH_TYPE_NONE:
+                       /* No hash, goto return blob sd. */
+                       goto out;
+               case XATTR_SD_HASH_TYPE_SHA256:
+                       break;
+               default:
+                       return NT_STATUS_REVISION_MISMATCH;
+       }
+
+       /* Get the full underlying sd, then hash. */
+       if (fsp) {
+               status = SMB_VFS_NEXT_FGET_NT_ACL(handle,
+                               fsp,
+                               HASH_SECURITY_INFO,
+                               &pdesc_next);
+       } else {
+               status = SMB_VFS_NEXT_GET_NT_ACL(handle,
+                               name,
+                               HASH_SECURITY_INFO,
+                               &pdesc_next);
+       }
+
+       if (!NT_STATUS_IS_OK(status)) {
+               goto out;
+       }
+
+       status = hash_sd_sha256(pdesc_next, hash_tmp);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto out;
+       }
+
+       if (memcmp(&hash[0], &hash_tmp[0], XATTR_SD_HASH_SIZE) == 0) {
+               TALLOC_FREE(pdesc_next);
+               /* Hash matches, return blob sd. */
+               goto out;
+       }
+
+       /* Hash doesn't match, return underlying sd. */
+
+       if (!(security_info & OWNER_SECURITY_INFORMATION)) {
+               pdesc_next->owner_sid = NULL;
+       }
+       if (!(security_info & GROUP_SECURITY_INFORMATION)) {
+               pdesc_next->group_sid = NULL;
+       }
+       if (!(security_info & DACL_SECURITY_INFORMATION)) {
+               pdesc_next->dacl = NULL;
+       }
+       if (!(security_info & SACL_SECURITY_INFORMATION)) {
+               pdesc_next->sacl = NULL;
+       }
+
+       TALLOC_FREE(*ppdesc);
+       *ppdesc = pdesc_next;
+
+  out:
+
+       if (!(security_info & OWNER_SECURITY_INFORMATION)) {
+               (*ppdesc)->owner_sid = NULL;
+       }
+       if (!(security_info & GROUP_SECURITY_INFORMATION)) {
+               (*ppdesc)->group_sid = NULL;
+       }
+       if (!(security_info & DACL_SECURITY_INFORMATION)) {
+               (*ppdesc)->dacl = NULL;
+       }
+       if (!(security_info & SACL_SECURITY_INFORMATION)) {
+               (*ppdesc)->sacl = NULL;
+       }
+
+       TALLOC_FREE(blob.data);
+       return status;
+}
+
+/*********************************************************************
+ Create a default security descriptor for a file in case no inheritance
+ exists. All permissions to the owner and SYSTEM.
+*********************************************************************/
+
+static struct security_descriptor *default_file_sd(TALLOC_CTX *mem_ctx,
+                                               SMB_STRUCT_STAT *psbuf)
+{
+       struct dom_sid owner_sid, group_sid;
+       size_t sd_size;
+       struct security_ace *pace = NULL;
+       struct security_acl *pacl = NULL;
+
+       uid_to_sid(&owner_sid, psbuf->st_ex_uid);
+       gid_to_sid(&group_sid, psbuf->st_ex_gid);
+
+       pace = TALLOC_ARRAY(mem_ctx, struct security_ace, 2);
+       if (!pace) {
+               return NULL;
+       }
+
+       init_sec_ace(&pace[0], &owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
+                       SEC_RIGHTS_FILE_ALL, 0);
+       init_sec_ace(&pace[1], &global_sid_System, SEC_ACE_TYPE_ACCESS_ALLOWED,
+                       SEC_RIGHTS_FILE_ALL, 0);
+
+       pacl = make_sec_acl(mem_ctx,
+                               NT4_ACL_REVISION,
+                               2,
+                               pace);
+       if (!pacl) {
+               return NULL;
+       }
+       return make_sec_desc(mem_ctx,
+                       SECURITY_DESCRIPTOR_REVISION_1,
+                       SEC_DESC_SELF_RELATIVE|SEC_DESC_DACL_PRESENT,
+                       &owner_sid,
+                       &group_sid,
+                       NULL,
+                        pacl,
+                       &sd_size);
+}
+
+/*********************************************************************
+*********************************************************************/
+
+static NTSTATUS inherit_new_acl(vfs_handle_struct *handle,
+                                       struct smb_filename *smb_fname,
+                                       files_struct *fsp,
+                                       bool container)
+{
+       TALLOC_CTX *ctx = talloc_tos();
+       NTSTATUS status;
+       struct security_descriptor *parent_desc = NULL;
+       struct security_descriptor *psd = NULL;
+       struct security_descriptor *pdesc_next = NULL;
+       DATA_BLOB blob;
+       size_t size;
+       char *parent_name;
+       uint8_t hash[XATTR_SD_HASH_SIZE];
+
+       if (!parent_dirname(ctx, smb_fname->base_name, &parent_name, NULL)) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       DEBUG(10,("inherit_new_acl: check directory %s\n",
+                       parent_name));
+
+       status = get_nt_acl_internal(handle,
+                               NULL,
+                               parent_name,
+                               (OWNER_SECURITY_INFORMATION |
+                                GROUP_SECURITY_INFORMATION |
+                                DACL_SECURITY_INFORMATION),
+                               &parent_desc);
+        if (NT_STATUS_IS_OK(status)) {
+               /* Create an inherited descriptor from the parent. */
+
+               if (DEBUGLEVEL >= 10) {
+                       DEBUG(10,("inherit_new_acl: parent acl is:\n"));
+                       NDR_PRINT_DEBUG(security_descriptor, parent_desc);
+               }
+
+               status = se_create_child_secdesc(ctx,
+                               &psd,
+                               &size,
+                               parent_desc,
+                               &handle->conn->server_info->ptok->user_sids[PRIMARY_USER_SID_INDEX],
+                               &handle->conn->server_info->ptok->user_sids[PRIMARY_GROUP_SID_INDEX],
+                               container);
+               if (!NT_STATUS_IS_OK(status)) {
+                       return status;
+               }
+
+               if (DEBUGLEVEL >= 10) {
+                       DEBUG(10,("inherit_new_acl: child acl is:\n"));
+                       NDR_PRINT_DEBUG(security_descriptor, psd);
+               }
+
+       } else {
+               DEBUG(10,("inherit_new_acl: directory %s failed "
+                       "to get acl %s\n",
+                       parent_name,
+                       nt_errstr(status) ));
+       }
+
+       if (!psd || psd->dacl == NULL) {
+               int ret;
+
+               TALLOC_FREE(psd);
+               if (fsp && !fsp->is_directory && fsp->fh->fd != -1) {
+                       ret = SMB_VFS_FSTAT(fsp, &smb_fname->st);
+               } else {
+                       if (fsp && fsp->posix_open) {
+                               ret = SMB_VFS_LSTAT(handle->conn, smb_fname);
+                       } else {
+                               ret = SMB_VFS_STAT(handle->conn, smb_fname);
+                       }
+               }
+               if (ret == -1) {
+                       return map_nt_error_from_unix(errno);
+               }
+               psd = default_file_sd(ctx, &smb_fname->st);
+               if (!psd) {
+                       return NT_STATUS_NO_MEMORY;
+               }
+
+               if (DEBUGLEVEL >= 10) {
+                       DEBUG(10,("inherit_new_acl: default acl is:\n"));
+                       NDR_PRINT_DEBUG(security_descriptor, psd);
+               }
+       }
+
+       /* Object exists. Read the current SD to get the hash. */
+       if (fsp) {
+               status = SMB_VFS_NEXT_FGET_NT_ACL(handle,
+                               fsp,
+                               HASH_SECURITY_INFO,
+                               &pdesc_next);
+       } else {
+               status = SMB_VFS_NEXT_GET_NT_ACL(handle,
+                               smb_fname->base_name,
+                               HASH_SECURITY_INFO,
+                               &pdesc_next);
+       }
+
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       status = hash_sd_sha256(pdesc_next, hash);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+       status = create_acl_blob(psd, &blob, XATTR_SD_HASH_TYPE_SHA256, hash);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+       if (fsp) {
+               return store_acl_blob_fsp(handle, fsp, &blob);
+       } else {
+               return store_acl_blob_pathname(handle, smb_fname->base_name,
+                                              &blob);
+       }
+}
+
+/*********************************************************************
+ Check ACL on open. For new files inherit from parent directory.
+*********************************************************************/
+
+int open_acl_common(vfs_handle_struct *handle,
+                       struct smb_filename *smb_fname,
+                       files_struct *fsp,
+                       int flags,
+                       mode_t mode)
+{
+       uint32_t access_granted = 0;
+       struct security_descriptor *pdesc = NULL;
+       bool file_existed = true;
+       char *fname = NULL;
+       NTSTATUS status;
+
+       if (fsp->base_fsp) {
+               /* Stream open. Base filename open already did the ACL check. */
+               DEBUG(10,("open_acl_common: stream open on %s\n",
+                       smb_fname_str_dbg(smb_fname) ));
+               return SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
+       }
+
+       status = get_full_smb_filename(talloc_tos(), smb_fname,
+                                      &fname);
+       if (!NT_STATUS_IS_OK(status)) {
+               errno = map_errno_from_nt_status(status);
+               return -1;
+       }
+
+       status = get_nt_acl_internal(handle,
+                               NULL,
+                               fname,
+                               (OWNER_SECURITY_INFORMATION |
+                                GROUP_SECURITY_INFORMATION |
+                                DACL_SECURITY_INFORMATION),
+                               &pdesc);
+        if (NT_STATUS_IS_OK(status)) {
+               /* See if we can access it. */
+               status = smb1_file_se_access_check(pdesc,
+                                       handle->conn->server_info->ptok,
+                                       fsp->access_mask,
+                                       &access_granted);
+               if (!NT_STATUS_IS_OK(status)) {
+                       DEBUG(10,("open_acl_xattr: file %s open "
+                               "refused with error %s\n",
+                               smb_fname_str_dbg(smb_fname),
+                               nt_errstr(status) ));
+                       errno = map_errno_from_nt_status(status);
+                       return -1;
+               }
+        } else if (NT_STATUS_EQUAL(status,NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
+               file_existed = false;
+       }
+
+       DEBUG(10,("open_acl_xattr: get_nt_acl_attr_internal for "
+               "file %s returned %s\n",
+               smb_fname_str_dbg(smb_fname),
+               nt_errstr(status) ));
+
+       fsp->fh->fd = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
+
+       if (!file_existed && fsp->fh->fd != -1) {
+               /* File was created. Inherit from parent directory. */
+               status = fsp_set_smb_fname(fsp, smb_fname);
+               if (!NT_STATUS_IS_OK(status)) {
+                       errno = map_errno_from_nt_status(status);
+                       return -1;
+               }
+               inherit_new_acl(handle, smb_fname, fsp, false);
+       }
+
+       return fsp->fh->fd;
+}
+
+int mkdir_acl_common(vfs_handle_struct *handle, const char *path, mode_t mode)
+{
+       struct smb_filename *smb_fname = NULL;
+       int ret = SMB_VFS_NEXT_MKDIR(handle, path, mode);
+       NTSTATUS status;
+
+       if (ret == -1) {
+               return ret;
+       }
+
+       status = create_synthetic_smb_fname(talloc_tos(), path, NULL, NULL,
+                                           &smb_fname);
+       if (!NT_STATUS_IS_OK(status)) {
+               errno = map_errno_from_nt_status(status);
+               return -1;
+       }
+
+       /* New directory - inherit from parent. */
+       inherit_new_acl(handle, smb_fname, NULL, true);
+       TALLOC_FREE(smb_fname);
+       return ret;
+}
+
+/*********************************************************************
+ Fetch a security descriptor given an fsp.
+*********************************************************************/
+
+NTSTATUS fget_nt_acl_common(vfs_handle_struct *handle, files_struct *fsp,
+        uint32_t security_info, struct security_descriptor **ppdesc)
+{
+       return get_nt_acl_internal(handle, fsp,
+                               NULL, security_info, ppdesc);
+}
+
+/*********************************************************************
+ Fetch a security descriptor given a pathname.
+*********************************************************************/
+
+NTSTATUS get_nt_acl_common(vfs_handle_struct *handle,
+        const char *name, uint32_t security_info, struct security_descriptor **ppdesc)
+{
+       return get_nt_acl_internal(handle, NULL,
+                               name, security_info, ppdesc);
+}
+
+/*********************************************************************
+ Store a security descriptor given an fsp.
+*********************************************************************/
+
+NTSTATUS fset_nt_acl_common(vfs_handle_struct *handle, files_struct *fsp,
+        uint32_t security_info_sent, const struct security_descriptor *psd)
+{
+       NTSTATUS status;
+       DATA_BLOB blob;
+       struct security_descriptor *pdesc_next = NULL;
+       uint8_t hash[XATTR_SD_HASH_SIZE];
+
+       if (DEBUGLEVEL >= 10) {
+               DEBUG(10,("fset_nt_acl_xattr: incoming sd for file %s\n",
+                         fsp_str_dbg(fsp)));
+               NDR_PRINT_DEBUG(security_descriptor,
+                       CONST_DISCARD(struct security_descriptor *,psd));
+       }
+
+       /* Ensure owner and group are set. */
+       if (!psd->owner_sid || !psd->group_sid) {
+               int ret;
+               DOM_SID owner_sid, group_sid;
+               struct security_descriptor *nc_psd = dup_sec_desc(talloc_tos(), psd);
+
+               if (!nc_psd) {
+                       return NT_STATUS_OK;
+               }
+               if (fsp->is_directory || fsp->fh->fd == -1) {
+                       if (fsp->posix_open) {
+                               ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
+                       } else {
+                               ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
+                       }
+               } else {
+                       ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
+               }
+               if (ret == -1) {
+                       /* Lower level acl set succeeded,
+                        * so still return OK. */
+                       return NT_STATUS_OK;
+               }
+               create_file_sids(&fsp->fsp_name->st, &owner_sid, &group_sid);
+               /* This is safe as nc_psd is discarded at fn exit. */
+               nc_psd->owner_sid = &owner_sid;
+               nc_psd->group_sid = &group_sid;
+               security_info_sent |= (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION);
+               psd = nc_psd;
+       }
+
+       status = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent, psd);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       /* Get the full underlying sd, then hash. */
+       status = SMB_VFS_NEXT_FGET_NT_ACL(handle,
+                               fsp,
+                               HASH_SECURITY_INFO,
+                               &pdesc_next);
+
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       status = hash_sd_sha256(pdesc_next, hash);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       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,
+                       CONST_DISCARD(struct security_descriptor *,psd));
+       }
+       create_acl_blob(psd, &blob, XATTR_SD_HASH_TYPE_SHA256, hash);
+       store_acl_blob_fsp(handle, fsp, &blob);
+
+       return NT_STATUS_OK;
+}
index dd7d87490e507fddf0f5c62a67056d8bd7ad31ab..07ad694a30660cc429513ec730bf5070242c1294 100644 (file)
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_VFS
 
-static NTSTATUS create_acl_blob(const struct security_descriptor *psd,
-                       DATA_BLOB *pblob,
-                       uint16_t hash_type,
-                       uint8_t hash[XATTR_SD_HASH_SIZE]);
-
-#define HASH_SECURITY_INFO (OWNER_SECURITY_INFORMATION | \
-                               GROUP_SECURITY_INFORMATION | \
-                               DACL_SECURITY_INFORMATION | \
-                               SACL_SECURITY_INFORMATION)
-
 static unsigned int ref_count;
 static struct db_context *acl_db;
 
@@ -141,92 +131,11 @@ static NTSTATUS acl_tdb_delete(vfs_handle_struct *handle,
        return status;
 }
 
-/*******************************************************************
- Hash a security descriptor.
-*******************************************************************/
-
-static NTSTATUS hash_sd_sha256(struct security_descriptor *psd,
-                       uint8_t hash[XATTR_SD_HASH_SIZE])
-{
-       DATA_BLOB blob;
-       SHA256_CTX tctx;
-       NTSTATUS status;
-
-       memset(hash, '\0', XATTR_SD_HASH_SIZE);
-       status = create_acl_blob(psd, &blob, XATTR_SD_HASH_TYPE_SHA256, hash);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-
-       SHA256_Init(&tctx);
-       SHA256_Update(&tctx, blob.data, blob.length);
-       SHA256_Final(hash, &tctx);
-
-       return NT_STATUS_OK;
-}
-
-/*******************************************************************
- Parse out a struct security_descriptor from a DATA_BLOB.
-*******************************************************************/
-
-static NTSTATUS parse_acl_blob(const DATA_BLOB *pblob,
-                               struct security_descriptor **ppdesc,
-                               uint16_t *p_hash_type,
-                               uint8_t hash[XATTR_SD_HASH_SIZE])
-{
-       TALLOC_CTX *ctx = talloc_tos();
-       struct xattr_NTACL xacl;
-       enum ndr_err_code ndr_err;
-       size_t sd_size;
-
-       ndr_err = ndr_pull_struct_blob(pblob, ctx, NULL, &xacl,
-                       (ndr_pull_flags_fn_t)ndr_pull_xattr_NTACL);
-
-       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-               DEBUG(5, ("parse_acl_blob: ndr_pull_xattr_NTACL failed: %s\n",
-                       ndr_errstr(ndr_err)));
-               return ndr_map_error2ntstatus(ndr_err);;
-       }
-
-       switch (xacl.version) {
-               case 2:
-                       *ppdesc = make_sec_desc(ctx, SEC_DESC_REVISION,
-                                       xacl.info.sd_hs2->sd->type | SEC_DESC_SELF_RELATIVE,
-                                       xacl.info.sd_hs2->sd->owner_sid,
-                                       xacl.info.sd_hs2->sd->group_sid,
-                                       xacl.info.sd_hs2->sd->sacl,
-                                       xacl.info.sd_hs2->sd->dacl,
-                                       &sd_size);
-                       /* No hash - null out. */
-                       *p_hash_type = XATTR_SD_HASH_TYPE_NONE;
-                       memset(hash, '\0', XATTR_SD_HASH_SIZE);
-                       break;
-                case 3:
-                       *ppdesc = make_sec_desc(ctx, SEC_DESC_REVISION,
-                                       xacl.info.sd_hs3->sd->type | SEC_DESC_SELF_RELATIVE,
-                                       xacl.info.sd_hs3->sd->owner_sid,
-                                       xacl.info.sd_hs3->sd->group_sid,
-                                       xacl.info.sd_hs3->sd->sacl,
-                                       xacl.info.sd_hs3->sd->dacl,
-                                       &sd_size);
-                       *p_hash_type = xacl.info.sd_hs3->hash_type;
-                       /* Current version 3. */
-                       memcpy(hash, xacl.info.sd_hs3->hash, XATTR_SD_HASH_SIZE);
-                       break;
-               default:
-                       return NT_STATUS_REVISION_MISMATCH;
-       }
-
-       TALLOC_FREE(xacl.info.sd);
-
-       return (*ppdesc != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
-}
-
 /*******************************************************************
  Pull a security descriptor into a DATA_BLOB from a tdb store.
 *******************************************************************/
 
-static NTSTATUS get_acl_blob(TALLOC_CTX *ctx,
+NTSTATUS get_acl_blob(TALLOC_CTX *ctx,
                        vfs_handle_struct *handle,
                        files_struct *fsp,
                        const char *name,
@@ -280,47 +189,11 @@ static NTSTATUS get_acl_blob(TALLOC_CTX *ctx,
        return NT_STATUS_OK;
 }
 
-/*******************************************************************
- Create a DATA_BLOB from a security descriptor.
-*******************************************************************/
-
-static NTSTATUS create_acl_blob(const struct security_descriptor *psd,
-                       DATA_BLOB *pblob,
-                       uint16_t hash_type,
-                       uint8_t hash[XATTR_SD_HASH_SIZE])
-{
-       struct xattr_NTACL xacl;
-       struct security_descriptor_hash_v3 sd_hs3;
-       enum ndr_err_code ndr_err;
-       TALLOC_CTX *ctx = talloc_tos();
-
-       ZERO_STRUCT(xacl);
-       ZERO_STRUCT(sd_hs3);
-
-       xacl.version = 3;
-       xacl.info.sd_hs3 = &sd_hs3;
-       xacl.info.sd_hs3->sd = CONST_DISCARD(struct security_descriptor *, psd);
-       xacl.info.sd_hs3->hash_type = hash_type;
-       memcpy(&xacl.info.sd_hs3->hash[0], hash, XATTR_SD_HASH_SIZE);
-
-       ndr_err = ndr_push_struct_blob(
-                       pblob, ctx, NULL, &xacl,
-                       (ndr_push_flags_fn_t)ndr_push_xattr_NTACL);
-
-       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-               DEBUG(5, ("create_acl_blob: ndr_push_xattr_NTACL failed: %s\n",
-                       ndr_errstr(ndr_err)));
-               return ndr_map_error2ntstatus(ndr_err);;
-       }
-
-       return NT_STATUS_OK;
-}
-
 /*******************************************************************
  Store a DATA_BLOB into a tdb record given an fsp pointer.
 *******************************************************************/
 
-static NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle,
+NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle,
                                files_struct *fsp,
                                DATA_BLOB *pblob)
 {
@@ -371,7 +244,7 @@ static NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle,
  Store a DATA_BLOB into a tdb record given a pathname.
 *******************************************************************/
 
-static NTSTATUS store_acl_blob_pathname(vfs_handle_struct *handle,
+NTSTATUS store_acl_blob_pathname(vfs_handle_struct *handle,
                                        const char *fname,
                                        DATA_BLOB *pblob)
 {
@@ -417,360 +290,6 @@ static NTSTATUS store_acl_blob_pathname(vfs_handle_struct *handle,
        return rec->store(rec, data, 0);
 }
 
-/*******************************************************************
- Store a DATA_BLOB into an tdb given a pathname.
-*******************************************************************/
-
-static NTSTATUS get_nt_acl_tdb_internal(vfs_handle_struct *handle,
-                                       files_struct *fsp,
-                                       const char *name,
-                                       uint32_t security_info,
-                                       struct security_descriptor **ppdesc)
-{
-       DATA_BLOB blob;
-       NTSTATUS status;
-       uint16_t hash_type;
-       uint8_t hash[XATTR_SD_HASH_SIZE];
-       uint8_t hash_tmp[XATTR_SD_HASH_SIZE];
-       struct security_descriptor *pdesc_next = NULL;
-
-       if (fsp && name == NULL) {
-               name = fsp->fsp_name->base_name;
-       }
-
-       DEBUG(10, ("get_nt_acl_tdb_internal: name=%s\n", name));
-
-       status = get_acl_blob(talloc_tos(), handle, fsp, name, &blob);
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(10, ("get_acl_blob returned %s\n", nt_errstr(status)));
-               return status;
-       }
-
-       status = parse_acl_blob(&blob, ppdesc,
-                               &hash_type, &hash[0]);
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(10, ("parse_acl_blob returned %s\n",
-                       nt_errstr(status)));
-               return status;
-       }
-
-       /* Ensure the hash type is one we know. */
-       switch (hash_type) {
-               case XATTR_SD_HASH_TYPE_NONE:
-                       /* No hash, goto return blob sd. */
-                       goto out;
-               case XATTR_SD_HASH_TYPE_SHA256:
-                       break;
-               default:
-                       return NT_STATUS_REVISION_MISMATCH;
-       }
-
-       /* Get the full underlying sd, then hash. */
-       if (fsp) {
-               status = SMB_VFS_NEXT_FGET_NT_ACL(handle,
-                               fsp,
-                               HASH_SECURITY_INFO,
-                               &pdesc_next);
-       } else {
-               status = SMB_VFS_NEXT_GET_NT_ACL(handle,
-                               name,
-                               HASH_SECURITY_INFO,
-                               &pdesc_next);
-       }
-
-       if (!NT_STATUS_IS_OK(status)) {
-               goto out;
-       }
-
-       status = hash_sd_sha256(pdesc_next, hash_tmp);
-       if (!NT_STATUS_IS_OK(status)) {
-               goto out;
-       }
-
-       if (memcmp(&hash[0], &hash_tmp[0], XATTR_SD_HASH_SIZE) == 0) {
-               TALLOC_FREE(pdesc_next);
-               /* Hash matches, return blob sd. */
-               goto out;
-       }
-
-       /* Hash doesn't match, return underlying sd. */
-
-       if (!(security_info & OWNER_SECURITY_INFORMATION)) {
-               pdesc_next->owner_sid = NULL;
-       }
-       if (!(security_info & GROUP_SECURITY_INFORMATION)) {
-               pdesc_next->group_sid = NULL;
-       }
-       if (!(security_info & DACL_SECURITY_INFORMATION)) {
-               pdesc_next->dacl = NULL;
-       }
-       if (!(security_info & SACL_SECURITY_INFORMATION)) {
-               pdesc_next->sacl = NULL;
-       }
-
-       TALLOC_FREE(*ppdesc);
-       *ppdesc = pdesc_next;
-
-  out:
-
-       if (!(security_info & OWNER_SECURITY_INFORMATION)) {
-               (*ppdesc)->owner_sid = NULL;
-       }
-       if (!(security_info & GROUP_SECURITY_INFORMATION)) {
-               (*ppdesc)->group_sid = NULL;
-       }
-       if (!(security_info & DACL_SECURITY_INFORMATION)) {
-               (*ppdesc)->dacl = NULL;
-       }
-       if (!(security_info & SACL_SECURITY_INFORMATION)) {
-               (*ppdesc)->sacl = NULL;
-       }
-
-       TALLOC_FREE(blob.data);
-       return status;
-}
-
-/*********************************************************************
- Create a default security descriptor for a file in case no inheritance
- exists. All permissions to the owner and SYSTEM.
-*********************************************************************/
-
-static struct security_descriptor *default_file_sd(TALLOC_CTX *mem_ctx,
-                                               SMB_STRUCT_STAT *psbuf)
-{
-       struct dom_sid owner_sid, group_sid;
-       size_t sd_size;
-       struct security_ace *pace = NULL;
-       struct security_acl *pacl = NULL;
-
-       uid_to_sid(&owner_sid, psbuf->st_ex_uid);
-       gid_to_sid(&group_sid, psbuf->st_ex_gid);
-
-       pace = TALLOC_ARRAY(mem_ctx, struct security_ace, 2);
-       if (!pace) {
-               return NULL;
-       }
-
-       init_sec_ace(&pace[0], &owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
-                       SEC_RIGHTS_FILE_ALL, 0);
-       init_sec_ace(&pace[1], &global_sid_System, SEC_ACE_TYPE_ACCESS_ALLOWED,
-                       SEC_RIGHTS_FILE_ALL, 0);
-
-       pacl = make_sec_acl(mem_ctx,
-                               NT4_ACL_REVISION,
-                               2,
-                               pace);
-       if (!pacl) {
-               return NULL;
-       }
-       return make_sec_desc(mem_ctx,
-                       SECURITY_DESCRIPTOR_REVISION_1,
-                       SEC_DESC_SELF_RELATIVE|SEC_DESC_DACL_PRESENT,
-                       &owner_sid,
-                       &group_sid,
-                       NULL,
-                        pacl,
-                       &sd_size);
-}
-
-/*********************************************************************
-*********************************************************************/
-
-static NTSTATUS inherit_new_acl(vfs_handle_struct *handle,
-                                       struct smb_filename *smb_fname,
-                                       files_struct *fsp,
-                                       bool container)
-{
-       TALLOC_CTX *ctx = talloc_tos();
-       NTSTATUS status;
-       struct security_descriptor *parent_desc = NULL;
-       struct security_descriptor *psd = NULL;
-       struct security_descriptor *pdesc_next = NULL;
-       DATA_BLOB blob;
-       size_t size;
-       char *parent_name;
-       uint8_t hash[XATTR_SD_HASH_SIZE];
-
-       if (!parent_dirname(ctx, smb_fname->base_name, &parent_name, NULL)) {
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       DEBUG(10,("inherit_new_acl: check directory %s\n",
-                       parent_name));
-
-       status = get_nt_acl_tdb_internal(handle,
-                                       NULL,
-                                       parent_name,
-                                       (OWNER_SECURITY_INFORMATION |
-                                        GROUP_SECURITY_INFORMATION |
-                                        DACL_SECURITY_INFORMATION),
-                                       &parent_desc);
-        if (NT_STATUS_IS_OK(status)) {
-               /* Create an inherited descriptor from the parent. */
-
-               if (DEBUGLEVEL >= 10) {
-                       DEBUG(10,("inherit_new_acl: parent acl is:\n"));
-                       NDR_PRINT_DEBUG(security_descriptor, parent_desc);
-               }
-
-               status = se_create_child_secdesc(ctx,
-                               &psd,
-                               &size,
-                               parent_desc,
-                               &handle->conn->server_info->ptok->user_sids[PRIMARY_USER_SID_INDEX],
-                               &handle->conn->server_info->ptok->user_sids[PRIMARY_GROUP_SID_INDEX],
-                               container);
-               if (!NT_STATUS_IS_OK(status)) {
-                       return status;
-               }
-
-               if (DEBUGLEVEL >= 10) {
-                       DEBUG(10,("inherit_new_acl: child acl is:\n"));
-                       NDR_PRINT_DEBUG(security_descriptor, psd);
-               }
-
-       } else {
-               DEBUG(10,("inherit_new_acl: directory %s failed "
-                       "to get acl %s\n",
-                       parent_name,
-                       nt_errstr(status) ));
-       }
-
-       if (!psd || psd->dacl == NULL) {
-               int ret;
-
-               TALLOC_FREE(psd);
-               if (fsp && !fsp->is_directory && fsp->fh->fd != -1) {
-                       ret = SMB_VFS_FSTAT(fsp, &smb_fname->st);
-               } else {
-                       if (fsp && fsp->posix_open) {
-                               ret = SMB_VFS_LSTAT(handle->conn, smb_fname);
-                       } else {
-                               ret = SMB_VFS_STAT(handle->conn, smb_fname);
-                       }
-               }
-               if (ret == -1) {
-                       return map_nt_error_from_unix(errno);
-               }
-               psd = default_file_sd(ctx, &smb_fname->st);
-               if (!psd) {
-                       return NT_STATUS_NO_MEMORY;
-               }
-
-               if (DEBUGLEVEL >= 10) {
-                       DEBUG(10,("inherit_new_acl: default acl is:\n"));
-                       NDR_PRINT_DEBUG(security_descriptor, psd);
-               }
-       }
-
-       /* Object exists. Read the current SD to get the hash. */
-       if (fsp) {
-               status = SMB_VFS_NEXT_FGET_NT_ACL(handle,
-                               fsp,
-                               HASH_SECURITY_INFO,
-                               &pdesc_next);
-       } else {
-               status = SMB_VFS_NEXT_GET_NT_ACL(handle,
-                               smb_fname->base_name,
-                               HASH_SECURITY_INFO,
-                               &pdesc_next);
-       }
-
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-
-       status = hash_sd_sha256(pdesc_next, hash);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-       status = create_acl_blob(psd, &blob, XATTR_SD_HASH_TYPE_SHA256, hash);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-       if (fsp) {
-               return store_acl_blob_fsp(handle, fsp, &blob);
-       } else {
-               return store_acl_blob_pathname(handle, smb_fname->base_name,
-                                              &blob);
-       }
-}
-
-/*********************************************************************
- Check ACL on open. For new files inherit from parent directory.
-*********************************************************************/
-
-static int open_acl_tdb(vfs_handle_struct *handle,
-                                       struct smb_filename *smb_fname,
-                                       files_struct *fsp,
-                                       int flags,
-                                       mode_t mode)
-{
-       uint32_t access_granted = 0;
-       struct security_descriptor *pdesc = NULL;
-       bool file_existed = true;
-       char *fname = NULL;
-       NTSTATUS status;
-
-       if (fsp->base_fsp) {
-               /* Stream open. Base filename open already did the ACL check. */
-               DEBUG(10,("open_acl_tdb: stream open on %s\n",
-                       smb_fname_str_dbg(smb_fname) ));
-               return SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
-       }
-
-       status = get_full_smb_filename(talloc_tos(), smb_fname,
-                                      &fname);
-       if (!NT_STATUS_IS_OK(status)) {
-               errno = map_errno_from_nt_status(status);
-               return -1;
-       }
-
-       status = get_nt_acl_tdb_internal(handle,
-                                       NULL,
-                                       fname,
-                                       (OWNER_SECURITY_INFORMATION |
-                                        GROUP_SECURITY_INFORMATION |
-                                        DACL_SECURITY_INFORMATION),
-                                       &pdesc);
-        if (NT_STATUS_IS_OK(status)) {
-               /* See if we can access it. */
-               status = smb1_file_se_access_check(pdesc,
-                                       handle->conn->server_info->ptok,
-                                       fsp->access_mask,
-                                       &access_granted);
-               if (!NT_STATUS_IS_OK(status)) {
-                       DEBUG(10,("open_acl_tdb: file %s open "
-                               "refused with error %s\n",
-                               smb_fname_str_dbg(smb_fname),
-                               nt_errstr(status) ));
-                       errno = map_errno_from_nt_status(status);
-                       return -1;
-               }
-        } else if (NT_STATUS_EQUAL(status,NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
-               file_existed = false;
-       }
-
-       DEBUG(10,("open_acl_tdb: get_nt_acl_attr_internal for "
-               "file %s returned %s\n",
-               smb_fname_str_dbg(smb_fname),
-               nt_errstr(status) ));
-
-       fsp->fh->fd = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
-
-       if (!file_existed && fsp->fh->fd != -1) {
-               /* File was created. Inherit from parent directory. */
-               status = fsp_set_smb_fname(fsp, smb_fname);
-               if (!NT_STATUS_IS_OK(status)) {
-                       errno = map_errno_from_nt_status(status);
-                       return -1;
-               }
-               inherit_new_acl(handle, smb_fname, fsp, false);
-       }
-
-       return fsp->fh->fd;
-}
-
 /*********************************************************************
  On unlink we need to delete the tdb record (if using tdb).
 *********************************************************************/
@@ -812,33 +331,6 @@ static int unlink_acl_tdb(vfs_handle_struct *handle,
        return ret;
 }
 
-/*********************************************************************
- Store an inherited SD on mkdir.
-*********************************************************************/
-
-static int mkdir_acl_tdb(vfs_handle_struct *handle, const char *path, mode_t mode)
-{
-       struct smb_filename *smb_fname = NULL;
-       int ret = SMB_VFS_NEXT_MKDIR(handle, path, mode);
-       NTSTATUS status;
-
-       if (ret == -1) {
-               return ret;
-       }
-
-       status = create_synthetic_smb_fname(talloc_tos(), path, NULL, NULL,
-                                           &smb_fname);
-       if (!NT_STATUS_IS_OK(status)) {
-               errno = map_errno_from_nt_status(status);
-               return -1;
-       }
-
-       /* New directory - inherit from parent. */
-       inherit_new_acl(handle, smb_fname, NULL, true);
-       TALLOC_FREE(smb_fname);
-       return ret;
-}
-
 /*********************************************************************
  On rmdir we need to delete the tdb record (if using tdb).
 *********************************************************************/
@@ -871,128 +363,6 @@ static int rmdir_acl_tdb(vfs_handle_struct *handle, const char *path)
        return 0;
 }
 
-/*********************************************************************
- Fetch a security descriptor given an fsp.
-*********************************************************************/
-
-static NTSTATUS fget_nt_acl_tdb(vfs_handle_struct *handle, files_struct *fsp,
-        uint32 security_info, struct security_descriptor **ppdesc)
-{
-       return get_nt_acl_tdb_internal(handle, fsp,
-                               NULL, security_info, ppdesc);
-}
-
-/*********************************************************************
- Fetch a security descriptor given a pathname.
-*********************************************************************/
-
-static NTSTATUS get_nt_acl_tdb(vfs_handle_struct *handle,
-        const char *name, uint32 security_info, struct security_descriptor **ppdesc)
-{
-       return get_nt_acl_tdb_internal(handle, NULL,
-                               name, security_info, ppdesc);
-}
-
-/*********************************************************************
- Store a security descriptor given an fsp.
-*********************************************************************/
-
-static NTSTATUS fset_nt_acl_tdb(vfs_handle_struct *handle, files_struct *fsp,
-        uint32_t security_info_sent, const struct security_descriptor *psd)
-{
-       NTSTATUS status;
-       DATA_BLOB blob;
-       struct security_descriptor *pdesc_next = NULL;
-       uint8_t hash[XATTR_SD_HASH_SIZE];
-
-       if (DEBUGLEVEL >= 10) {
-               DEBUG(10,("fset_nt_acl_tdb: incoming sd for file %s\n",
-                         fsp_str_dbg(fsp)));
-               NDR_PRINT_DEBUG(security_descriptor,
-                       CONST_DISCARD(struct security_descriptor *,psd));
-       }
-
-       /* Ensure owner and group are set. */
-       if (!psd->owner_sid || !psd->group_sid) {
-               int ret;
-               DOM_SID owner_sid, group_sid;
-               struct security_descriptor *nc_psd = dup_sec_desc(talloc_tos(), psd);
-
-               if (!nc_psd) {
-                       return NT_STATUS_OK;
-               }
-               if (fsp->is_directory || fsp->fh->fd == -1) {
-                       if (fsp->posix_open) {
-                               ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
-                       } else {
-                               ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
-                       }
-               } else {
-                       ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
-               }
-               if (ret == -1) {
-                       /* Lower level acl set succeeded,
-                        * so still return OK. */
-                       return NT_STATUS_OK;
-               }
-               create_file_sids(&fsp->fsp_name->st, &owner_sid, &group_sid);
-               /* This is safe as nc_psd is discarded at fn exit. */
-               nc_psd->owner_sid = &owner_sid;
-               nc_psd->group_sid = &group_sid;
-               security_info_sent |= (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION);
-               psd = nc_psd;
-       }
-
-       status = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent, psd);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-
-       /* Get the full underlying sd, then hash. */
-       status = SMB_VFS_NEXT_FGET_NT_ACL(handle,
-                               fsp,
-                               HASH_SECURITY_INFO,
-                               &pdesc_next);
-
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-
-       status = hash_sd_sha256(pdesc_next, hash);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-
-#if 0
-       if ((security_info_sent & DACL_SECURITY_INFORMATION) &&
-                       psd->dacl != NULL &&
-                       (psd->type & (SE_DESC_DACL_AUTO_INHERITED|
-                               SE_DESC_DACL_AUTO_INHERIT_REQ))==
-                               (SE_DESC_DACL_AUTO_INHERITED|
-                               SE_DESC_DACL_AUTO_INHERIT_REQ) ) {
-               struct security_descriptor *new_psd = NULL;
-               status = append_parent_acl(fsp, psd, &new_psd);
-               if (!NT_STATUS_IS_OK(status)) {
-                       /* Lower level acl set succeeded,
-                        * so still return OK. */
-                       return NT_STATUS_OK;
-               }
-               psd = new_psd;
-       }
-#endif
-
-       if (DEBUGLEVEL >= 10) {
-               DEBUG(10,("fset_nt_acl_tdb: storing xattr sd for file %s\n",
-                         fsp_str_dbg(fsp)));
-               NDR_PRINT_DEBUG(security_descriptor,
-                       CONST_DISCARD(struct security_descriptor *,psd));
-       }
-       create_acl_blob(psd, &blob, XATTR_SD_HASH_TYPE_SHA256, hash);
-       store_acl_blob_fsp(handle, fsp, &blob);
-
-       return NT_STATUS_OK;
-}
-
 /*******************************************************************
  Handle opening the storage tdb if so configured.
 *******************************************************************/
@@ -1096,13 +466,13 @@ static int sys_acl_set_fd_tdb(vfs_handle_struct *handle,
 
 static struct vfs_fn_pointers vfs_acl_tdb_fns = {
        .connect_fn = connect_acl_tdb,
-       .mkdir = mkdir_acl_tdb,
-       .open = open_acl_tdb,
+       .mkdir = mkdir_acl_common,
+       .open = open_acl_common,
        .unlink = unlink_acl_tdb,
        .rmdir = rmdir_acl_tdb,
-       .fget_nt_acl = fget_nt_acl_tdb,
-       .get_nt_acl = get_nt_acl_tdb,
-       .fset_nt_acl = fset_nt_acl_tdb,
+       .fget_nt_acl = fget_nt_acl_common,
+       .get_nt_acl = get_nt_acl_common,
+       .fset_nt_acl = fset_nt_acl_common,
        .sys_acl_set_file = sys_acl_set_file_tdb,
        .sys_acl_set_fd = sys_acl_set_fd_tdb
 };
index 381c374decbc0d4362987cdb1a6eac3a2c9d110e..d7711760ed4eaad8de19058431ceb6484144392c 100644 (file)
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_VFS
 
-static NTSTATUS create_acl_blob(const struct security_descriptor *psd,
-                       DATA_BLOB *pblob,
-                       uint16_t hash_type,
-                       uint8_t hash[XATTR_SD_HASH_SIZE]);
-
-#define HASH_SECURITY_INFO (OWNER_SECURITY_INFORMATION | \
-                               GROUP_SECURITY_INFORMATION | \
-                               DACL_SECURITY_INFORMATION | \
-                               SACL_SECURITY_INFORMATION)
-
-/*******************************************************************
- Hash a security descriptor.
-*******************************************************************/
-
-static NTSTATUS hash_sd_sha256(struct security_descriptor *psd,
-                       uint8_t hash[XATTR_SD_HASH_SIZE])
-{
-       DATA_BLOB blob;
-       SHA256_CTX tctx;
-       NTSTATUS status;
-
-       memset(hash, '\0', XATTR_SD_HASH_SIZE);
-       status = create_acl_blob(psd, &blob, XATTR_SD_HASH_TYPE_SHA256, hash);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-
-       SHA256_Init(&tctx);
-       SHA256_Update(&tctx, blob.data, blob.length);
-       SHA256_Final(hash, &tctx);
-
-       return NT_STATUS_OK;
-}
-
-/*******************************************************************
- Parse out a struct security_descriptor from a DATA_BLOB.
-*******************************************************************/
-
-static NTSTATUS parse_acl_blob(const DATA_BLOB *pblob,
-                               struct security_descriptor **ppdesc,
-                               uint16_t *p_hash_type,
-                               uint8_t hash[XATTR_SD_HASH_SIZE])
-{
-       TALLOC_CTX *ctx = talloc_tos();
-       struct xattr_NTACL xacl;
-       enum ndr_err_code ndr_err;
-       size_t sd_size;
-
-       ndr_err = ndr_pull_struct_blob(pblob, ctx, NULL, &xacl,
-                       (ndr_pull_flags_fn_t)ndr_pull_xattr_NTACL);
-
-       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-               DEBUG(5, ("parse_acl_blob: ndr_pull_xattr_NTACL failed: %s\n",
-                       ndr_errstr(ndr_err)));
-               return ndr_map_error2ntstatus(ndr_err);;
-       }
-
-       switch (xacl.version) {
-               case 2:
-                       *ppdesc = make_sec_desc(ctx, SEC_DESC_REVISION,
-                                       xacl.info.sd_hs2->sd->type | SEC_DESC_SELF_RELATIVE,
-                                       xacl.info.sd_hs2->sd->owner_sid,
-                                       xacl.info.sd_hs2->sd->group_sid,
-                                       xacl.info.sd_hs2->sd->sacl,
-                                       xacl.info.sd_hs2->sd->dacl,
-                                       &sd_size);
-                       /* No hash - null out. */
-                       *p_hash_type = XATTR_SD_HASH_TYPE_NONE;
-                       memset(hash, '\0', XATTR_SD_HASH_SIZE);
-                       break;
-               case 3:
-                       *ppdesc = make_sec_desc(ctx, SEC_DESC_REVISION,
-                                       xacl.info.sd_hs3->sd->type | SEC_DESC_SELF_RELATIVE,
-                                       xacl.info.sd_hs3->sd->owner_sid,
-                                       xacl.info.sd_hs3->sd->group_sid,
-                                       xacl.info.sd_hs3->sd->sacl,
-                                       xacl.info.sd_hs3->sd->dacl,
-                                       &sd_size);
-                       *p_hash_type = xacl.info.sd_hs3->hash_type;
-                       /* Current version 3. */
-                       memcpy(hash, xacl.info.sd_hs3->hash, XATTR_SD_HASH_SIZE);
-                       break;
-               default:
-                       return NT_STATUS_REVISION_MISMATCH;
-       }
-
-       TALLOC_FREE(xacl.info.sd);
-
-       return (*ppdesc != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
-}
-
 /*******************************************************************
  Pull a security descriptor into a DATA_BLOB from a xattr.
 *******************************************************************/
 
-static NTSTATUS get_acl_blob(TALLOC_CTX *ctx,
+NTSTATUS get_acl_blob(TALLOC_CTX *ctx,
                        vfs_handle_struct *handle,
                        files_struct *fsp,
                        const char *name,
@@ -177,47 +86,11 @@ static NTSTATUS get_acl_blob(TALLOC_CTX *ctx,
        return NT_STATUS_OK;
 }
 
-/*******************************************************************
- Create a DATA_BLOB from a security descriptor.
-*******************************************************************/
-
-static NTSTATUS create_acl_blob(const struct security_descriptor *psd,
-                       DATA_BLOB *pblob,
-                       uint16_t hash_type,
-                       uint8_t hash[XATTR_SD_HASH_SIZE])
-{
-       struct xattr_NTACL xacl;
-       struct security_descriptor_hash_v3 sd_hs3;
-       enum ndr_err_code ndr_err;
-       TALLOC_CTX *ctx = talloc_tos();
-
-       ZERO_STRUCT(xacl);
-       ZERO_STRUCT(sd_hs3);
-
-       xacl.version = 3;
-       xacl.info.sd_hs3 = &sd_hs3;
-       xacl.info.sd_hs3->sd = CONST_DISCARD(struct security_descriptor *, psd);
-       xacl.info.sd_hs3->hash_type = hash_type;
-       memcpy(&xacl.info.sd_hs3->hash[0], hash, XATTR_SD_HASH_SIZE);
-
-       ndr_err = ndr_push_struct_blob(
-                       pblob, ctx, NULL, &xacl,
-                       (ndr_push_flags_fn_t)ndr_push_xattr_NTACL);
-
-       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-               DEBUG(5, ("create_acl_blob: ndr_push_xattr_NTACL failed: %s\n",
-                       ndr_errstr(ndr_err)));
-               return ndr_map_error2ntstatus(ndr_err);;
-       }
-
-       return NT_STATUS_OK;
-}
-
 /*******************************************************************
  Store a DATA_BLOB into an xattr given an fsp pointer.
 *******************************************************************/
 
-static NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle,
+NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle,
                                files_struct *fsp,
                                DATA_BLOB *pblob)
 {
@@ -255,7 +128,7 @@ static NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle,
  Store a DATA_BLOB into an xattr given a pathname.
 *******************************************************************/
 
-static NTSTATUS store_acl_blob_pathname(vfs_handle_struct *handle,
+NTSTATUS store_acl_blob_pathname(vfs_handle_struct *handle,
                                        const char *fname,
                                        DATA_BLOB *pblob)
 {
@@ -286,505 +159,6 @@ static NTSTATUS store_acl_blob_pathname(vfs_handle_struct *handle,
        return NT_STATUS_OK;
 }
 
-/*******************************************************************
- Store a DATA_BLOB into an xattr given a pathname.
-*******************************************************************/
-
-static NTSTATUS get_nt_acl_xattr_internal(vfs_handle_struct *handle,
-                                       files_struct *fsp,
-                                       const char *name,
-                                       uint32_t security_info,
-                                       struct security_descriptor **ppdesc)
-{
-       DATA_BLOB blob;
-       NTSTATUS status;
-       uint16_t hash_type;
-       uint8_t hash[XATTR_SD_HASH_SIZE];
-       uint8_t hash_tmp[XATTR_SD_HASH_SIZE];
-       struct security_descriptor *pdesc_next = NULL;
-
-       if (fsp && name == NULL) {
-               name = fsp->fsp_name->base_name;
-       }
-
-       DEBUG(10, ("get_nt_acl_xattr_internal: name=%s\n", name));
-
-       status = get_acl_blob(talloc_tos(), handle, fsp, name, &blob);
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(10, ("get_acl_blob returned %s\n", nt_errstr(status)));
-               return status;
-       }
-
-       status = parse_acl_blob(&blob, ppdesc,
-                               &hash_type, &hash[0]);
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(10, ("parse_acl_blob returned %s\n",
-                               nt_errstr(status)));
-               return status;
-       }
-
-       /* Ensure the hash type is one we know. */
-       switch (hash_type) {
-               case XATTR_SD_HASH_TYPE_NONE:
-                       /* No hash, goto return blob sd. */
-                       goto out;
-               case XATTR_SD_HASH_TYPE_SHA256:
-                       break;
-               default:
-                       return NT_STATUS_REVISION_MISMATCH;
-       }
-
-       /* Get the full underlying sd, then hash. */
-       if (fsp) {
-               status = SMB_VFS_NEXT_FGET_NT_ACL(handle,
-                               fsp,
-                               HASH_SECURITY_INFO,
-                               &pdesc_next);
-       } else {
-               status = SMB_VFS_NEXT_GET_NT_ACL(handle,
-                               name,
-                               HASH_SECURITY_INFO,
-                               &pdesc_next);
-       }
-
-       if (!NT_STATUS_IS_OK(status)) {
-               goto out;
-       }
-
-       status = hash_sd_sha256(pdesc_next, hash_tmp);
-       if (!NT_STATUS_IS_OK(status)) {
-               goto out;
-       }
-
-       if (memcmp(&hash[0], &hash_tmp[0], XATTR_SD_HASH_SIZE) == 0) {
-               TALLOC_FREE(pdesc_next);
-               /* Hash matches, return blob sd. */
-               goto out;
-       }
-
-       /* Hash doesn't match, return underlying sd. */
-
-       if (!(security_info & OWNER_SECURITY_INFORMATION)) {
-               pdesc_next->owner_sid = NULL;
-       }
-       if (!(security_info & GROUP_SECURITY_INFORMATION)) {
-               pdesc_next->group_sid = NULL;
-       }
-       if (!(security_info & DACL_SECURITY_INFORMATION)) {
-               pdesc_next->dacl = NULL;
-       }
-       if (!(security_info & SACL_SECURITY_INFORMATION)) {
-               pdesc_next->sacl = NULL;
-       }
-
-       TALLOC_FREE(*ppdesc);
-       *ppdesc = pdesc_next;
-
-  out:
-
-       if (!(security_info & OWNER_SECURITY_INFORMATION)) {
-               (*ppdesc)->owner_sid = NULL;
-       }
-       if (!(security_info & GROUP_SECURITY_INFORMATION)) {
-               (*ppdesc)->group_sid = NULL;
-       }
-       if (!(security_info & DACL_SECURITY_INFORMATION)) {
-               (*ppdesc)->dacl = NULL;
-       }
-       if (!(security_info & SACL_SECURITY_INFORMATION)) {
-               (*ppdesc)->sacl = NULL;
-       }
-
-       TALLOC_FREE(blob.data);
-       return status;
-}
-
-/*********************************************************************
- Create a default security descriptor for a file in case no inheritance
- exists. All permissions to the owner and SYSTEM.
-*********************************************************************/
-
-static struct security_descriptor *default_file_sd(TALLOC_CTX *mem_ctx,
-                                               SMB_STRUCT_STAT *psbuf)
-{
-       struct dom_sid owner_sid, group_sid;
-       size_t sd_size;
-       struct security_ace *pace = NULL;
-       struct security_acl *pacl = NULL;
-
-       uid_to_sid(&owner_sid, psbuf->st_ex_uid);
-       gid_to_sid(&group_sid, psbuf->st_ex_gid);
-
-       pace = TALLOC_ARRAY(mem_ctx, struct security_ace, 2);
-       if (!pace) {
-               return NULL;
-       }
-
-       init_sec_ace(&pace[0], &owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
-                       SEC_RIGHTS_FILE_ALL, 0);
-       init_sec_ace(&pace[1], &global_sid_System, SEC_ACE_TYPE_ACCESS_ALLOWED,
-                       SEC_RIGHTS_FILE_ALL, 0);
-
-       pacl = make_sec_acl(mem_ctx,
-                               NT4_ACL_REVISION,
-                               2,
-                               pace);
-       if (!pacl) {
-               return NULL;
-       }
-       return make_sec_desc(mem_ctx,
-                       SECURITY_DESCRIPTOR_REVISION_1,
-                       SEC_DESC_SELF_RELATIVE|SEC_DESC_DACL_PRESENT,
-                       &owner_sid,
-                       &group_sid,
-                       NULL,
-                        pacl,
-                       &sd_size);
-}
-
-/*********************************************************************
-*********************************************************************/
-
-static NTSTATUS inherit_new_acl(vfs_handle_struct *handle,
-                                       struct smb_filename *smb_fname,
-                                       files_struct *fsp,
-                                       bool container)
-{
-       TALLOC_CTX *ctx = talloc_tos();
-       NTSTATUS status;
-       struct security_descriptor *parent_desc = NULL;
-       struct security_descriptor *psd = NULL;
-       struct security_descriptor *pdesc_next = NULL;
-       DATA_BLOB blob;
-       size_t size;
-       char *parent_name;
-       uint8_t hash[XATTR_SD_HASH_SIZE];
-
-       if (!parent_dirname(ctx, smb_fname->base_name, &parent_name, NULL)) {
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       DEBUG(10,("inherit_new_acl: check directory %s\n",
-                       parent_name));
-
-       status = get_nt_acl_xattr_internal(handle,
-                                       NULL,
-                                       parent_name,
-                                       (OWNER_SECURITY_INFORMATION |
-                                        GROUP_SECURITY_INFORMATION |
-                                        DACL_SECURITY_INFORMATION),
-                                       &parent_desc);
-        if (NT_STATUS_IS_OK(status)) {
-               /* Create an inherited descriptor from the parent. */
-
-               if (DEBUGLEVEL >= 10) {
-                       DEBUG(10,("inherit_new_acl: parent acl is:\n"));
-                       NDR_PRINT_DEBUG(security_descriptor, parent_desc);
-               }
-
-               status = se_create_child_secdesc(ctx,
-                               &psd,
-                               &size,
-                               parent_desc,
-                               &handle->conn->server_info->ptok->user_sids[PRIMARY_USER_SID_INDEX],
-                               &handle->conn->server_info->ptok->user_sids[PRIMARY_GROUP_SID_INDEX],
-                               container);
-               if (!NT_STATUS_IS_OK(status)) {
-                       return status;
-               }
-
-               if (DEBUGLEVEL >= 10) {
-                       DEBUG(10,("inherit_new_acl: child acl is:\n"));
-                       NDR_PRINT_DEBUG(security_descriptor, psd);
-               }
-
-       } else {
-               DEBUG(10,("inherit_new_acl: directory %s failed "
-                       "to get acl %s\n",
-                       parent_name,
-                       nt_errstr(status) ));
-       }
-
-       if (!psd || psd->dacl == NULL) {
-               int ret;
-
-               TALLOC_FREE(psd);
-               if (fsp && !fsp->is_directory && fsp->fh->fd != -1) {
-                       ret = SMB_VFS_FSTAT(fsp, &smb_fname->st);
-               } else {
-                       if (fsp && fsp->posix_open) {
-                               ret = SMB_VFS_LSTAT(handle->conn, smb_fname);
-                       } else {
-                               ret = SMB_VFS_STAT(handle->conn, smb_fname);
-                       }
-               }
-               if (ret == -1) {
-                       return map_nt_error_from_unix(errno);
-               }
-               psd = default_file_sd(ctx, &smb_fname->st);
-               if (!psd) {
-                       return NT_STATUS_NO_MEMORY;
-               }
-
-               if (DEBUGLEVEL >= 10) {
-                       DEBUG(10,("inherit_new_acl: default acl is:\n"));
-                       NDR_PRINT_DEBUG(security_descriptor, psd);
-               }
-       }
-
-       /* Object exists. Read the current SD to get the hash. */
-       if (fsp) {
-               status = SMB_VFS_NEXT_FGET_NT_ACL(handle,
-                               fsp,
-                               HASH_SECURITY_INFO,
-                               &pdesc_next);
-       } else {
-               status = SMB_VFS_NEXT_GET_NT_ACL(handle,
-                               smb_fname->base_name,
-                               HASH_SECURITY_INFO,
-                               &pdesc_next);
-       }
-
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-
-       status = hash_sd_sha256(pdesc_next, hash);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-       status = create_acl_blob(psd, &blob, XATTR_SD_HASH_TYPE_SHA256, hash);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-       if (fsp) {
-               return store_acl_blob_fsp(handle, fsp, &blob);
-       } else {
-               return store_acl_blob_pathname(handle, smb_fname->base_name,
-                                              &blob);
-       }
-}
-
-/*********************************************************************
- Check ACL on open. For new files inherit from parent directory.
-*********************************************************************/
-
-static int open_acl_xattr(vfs_handle_struct *handle,
-                                       struct smb_filename *smb_fname,
-                                       files_struct *fsp,
-                                       int flags,
-                                       mode_t mode)
-{
-       uint32_t access_granted = 0;
-       struct security_descriptor *pdesc = NULL;
-       bool file_existed = true;
-       char *fname = NULL;
-       NTSTATUS status;
-
-       if (fsp->base_fsp) {
-               /* Stream open. Base filename open already did the ACL check. */
-               DEBUG(10,("open_acl_xattr: stream open on %s\n",
-                       smb_fname_str_dbg(smb_fname) ));
-               return SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
-       }
-
-       status = get_full_smb_filename(talloc_tos(), smb_fname,
-                                      &fname);
-       if (!NT_STATUS_IS_OK(status)) {
-               errno = map_errno_from_nt_status(status);
-               return -1;
-       }
-
-       status = get_nt_acl_xattr_internal(handle,
-                                       NULL,
-                                       fname,
-                                       (OWNER_SECURITY_INFORMATION |
-                                        GROUP_SECURITY_INFORMATION |
-                                        DACL_SECURITY_INFORMATION),
-                                       &pdesc);
-        if (NT_STATUS_IS_OK(status)) {
-               /* See if we can access it. */
-               status = smb1_file_se_access_check(pdesc,
-                                       handle->conn->server_info->ptok,
-                                       fsp->access_mask,
-                                       &access_granted);
-               if (!NT_STATUS_IS_OK(status)) {
-                       DEBUG(10,("open_acl_xattr: file %s open "
-                               "refused with error %s\n",
-                               smb_fname_str_dbg(smb_fname),
-                               nt_errstr(status) ));
-                       errno = map_errno_from_nt_status(status);
-                       return -1;
-               }
-        } else if (NT_STATUS_EQUAL(status,NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
-               file_existed = false;
-       }
-
-       DEBUG(10,("open_acl_xattr: get_nt_acl_attr_internal for "
-               "file %s returned %s\n",
-               smb_fname_str_dbg(smb_fname),
-               nt_errstr(status) ));
-
-       fsp->fh->fd = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
-
-       if (!file_existed && fsp->fh->fd != -1) {
-               /* File was created. Inherit from parent directory. */
-               status = fsp_set_smb_fname(fsp, smb_fname);
-               if (!NT_STATUS_IS_OK(status)) {
-                       errno = map_errno_from_nt_status(status);
-                       return -1;
-               }
-               inherit_new_acl(handle, smb_fname, fsp, false);
-       }
-
-       return fsp->fh->fd;
-}
-
-static int mkdir_acl_xattr(vfs_handle_struct *handle, const char *path, mode_t mode)
-{
-       struct smb_filename *smb_fname = NULL;
-       int ret = SMB_VFS_NEXT_MKDIR(handle, path, mode);
-       NTSTATUS status;
-
-       if (ret == -1) {
-               return ret;
-       }
-
-       status = create_synthetic_smb_fname(talloc_tos(), path, NULL, NULL,
-                                           &smb_fname);
-       if (!NT_STATUS_IS_OK(status)) {
-               errno = map_errno_from_nt_status(status);
-               return -1;
-       }
-
-       /* New directory - inherit from parent. */
-       inherit_new_acl(handle, smb_fname, NULL, true);
-       TALLOC_FREE(smb_fname);
-       return ret;
-}
-
-/*********************************************************************
- Fetch a security descriptor given an fsp.
-*********************************************************************/
-
-static NTSTATUS fget_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp,
-        uint32_t security_info, struct security_descriptor **ppdesc)
-{
-       return get_nt_acl_xattr_internal(handle, fsp,
-                               NULL, security_info, ppdesc);
-}
-
-/*********************************************************************
- Fetch a security descriptor given a pathname.
-*********************************************************************/
-
-static NTSTATUS get_nt_acl_xattr(vfs_handle_struct *handle,
-        const char *name, uint32_t security_info, struct security_descriptor **ppdesc)
-{
-       return get_nt_acl_xattr_internal(handle, NULL,
-                               name, security_info, ppdesc);
-}
-
-/*********************************************************************
- Store a security descriptor given an fsp.
-*********************************************************************/
-
-static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp,
-        uint32_t security_info_sent, const struct security_descriptor *psd)
-{
-       NTSTATUS status;
-       DATA_BLOB blob;
-       struct security_descriptor *pdesc_next = NULL;
-       uint8_t hash[XATTR_SD_HASH_SIZE];
-
-       if (DEBUGLEVEL >= 10) {
-               DEBUG(10,("fset_nt_acl_xattr: incoming sd for file %s\n",
-                         fsp_str_dbg(fsp)));
-               NDR_PRINT_DEBUG(security_descriptor,
-                       CONST_DISCARD(struct security_descriptor *,psd));
-       }
-
-       /* Ensure owner and group are set. */
-       if (!psd->owner_sid || !psd->group_sid) {
-               int ret;
-               DOM_SID owner_sid, group_sid;
-               struct security_descriptor *nc_psd = dup_sec_desc(talloc_tos(), psd);
-
-               if (!nc_psd) {
-                       return NT_STATUS_OK;
-               }
-               if (fsp->is_directory || fsp->fh->fd == -1) {
-                       if (fsp->posix_open) {
-                               ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
-                       } else {
-                               ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
-                       }
-               } else {
-                       ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
-               }
-               if (ret == -1) {
-                       /* Lower level acl set succeeded,
-                        * so still return OK. */
-                       return NT_STATUS_OK;
-               }
-               create_file_sids(&fsp->fsp_name->st, &owner_sid, &group_sid);
-               /* This is safe as nc_psd is discarded at fn exit. */
-               nc_psd->owner_sid = &owner_sid;
-               nc_psd->group_sid = &group_sid;
-               security_info_sent |= (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION);
-               psd = nc_psd;
-       }
-
-       status = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent, psd);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-
-       /* Get the full underlying sd, then hash. */
-       status = SMB_VFS_NEXT_FGET_NT_ACL(handle,
-                               fsp,
-                               HASH_SECURITY_INFO,
-                               &pdesc_next);
-
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-
-       status = hash_sd_sha256(pdesc_next, hash);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-
-#if 0
-       if ((security_info_sent & DACL_SECURITY_INFORMATION) &&
-                       psd->dacl != NULL &&
-                       (psd->type & (SE_DESC_DACL_AUTO_INHERITED|
-                               SE_DESC_DACL_AUTO_INHERIT_REQ))==
-                               (SE_DESC_DACL_AUTO_INHERITED|
-                               SE_DESC_DACL_AUTO_INHERIT_REQ) ) {
-               struct security_descriptor *new_psd = NULL;
-               status = append_parent_acl(fsp, psd, &new_psd);
-               if (!NT_STATUS_IS_OK(status)) {
-                       /* Lower level acl set succeeded,
-                        * so still return OK. */
-                       return NT_STATUS_OK;
-               }
-               psd = new_psd;
-       }
-#endif
-
-       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,
-                       CONST_DISCARD(struct security_descriptor *,psd));
-       }
-       create_acl_blob(psd, &blob, XATTR_SD_HASH_TYPE_SHA256, hash);
-       store_acl_blob_fsp(handle, fsp, &blob);
-
-       return NT_STATUS_OK;
-}
-
 /*********************************************************************
  Remove a Windows ACL - we're setting the underlying POSIX ACL.
 *********************************************************************/
@@ -833,11 +207,11 @@ static int sys_acl_set_fd_xattr(vfs_handle_struct *handle,
 
 
 static struct vfs_fn_pointers vfs_acl_xattr_fns = {
-       .mkdir = mkdir_acl_xattr,
-       .open = open_acl_xattr,
-       .fget_nt_acl = fget_nt_acl_xattr,
-       .get_nt_acl = get_nt_acl_xattr,
-       .fset_nt_acl = fset_nt_acl_xattr,
+       .mkdir = mkdir_acl_common,
+       .open = open_acl_common,
+       .fget_nt_acl = fget_nt_acl_common,
+       .get_nt_acl = get_nt_acl_common,
+       .fset_nt_acl = fset_nt_acl_common,
        .sys_acl_set_file = sys_acl_set_file_xattr,
        .sys_acl_set_fd = sys_acl_set_fd_xattr
 };