From ddcaac99f0262909be57eceac4535bd3684096b3 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 10 Oct 2012 16:49:59 +1100 Subject: [PATCH] vfs: Implement a sys_acl_blob_get_{fd,file} for POSIX ACL backends This simply linearlises the SMB_ACL_T (default and access acl for directories) and the file owner, group and mode into a blob. It will be useful for an improved vfs_acl_common.c that uses this sets that, rather than the hash of the NT ACL, in the xattr This will in turn insulate the stored hash from changes in the ACL mapping. Andrew Bartlett --- source3/Makefile.in | 2 +- source3/smbd/posix_acls.c | 115 ++++++++++++++++++++++++++++++++++++++++++++++ source3/smbd/proto.h | 10 ++++ 3 files changed, 126 insertions(+), 1 deletion(-) diff --git a/source3/Makefile.in b/source3/Makefile.in index a29aae2e0ab..b202df37450 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -947,7 +947,7 @@ SMBD_OBJ_SRV = smbd/server_reload.o \ smbd/dosmode.o smbd/filename.o smbd/open.o smbd/close.o \ smbd/blocking.o smbd/sec_ctx.o smbd/srvstr.o \ smbd/vfs.o smbd/perfcount.o smbd/statcache.o smbd/seal.o \ - smbd/posix_acls.o lib/sysacls.o \ + smbd/posix_acls.o lib/sysacls.o autoconf/librpc/gen_ndr/ndr_smb_acl.o\ smbd/process.o smbd/service.o param/service.o smbd/error.o \ rpc_server/epmd.o \ rpc_server/lsasd.o \ diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index 05cd2a740d0..fadd22922e2 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -27,6 +27,7 @@ #include "passdb/lookup_sid.h" #include "auth.h" #include "../librpc/gen_ndr/idmap.h" +#include "../librpc/gen_ndr/ndr_smb_acl.h" #include "lib/param/loadparm.h" extern const struct generic_mapping file_generic_mapping; @@ -5141,3 +5142,117 @@ NTSTATUS make_default_filesystem_acl(TALLOC_CTX *ctx, } return NT_STATUS_OK; } + +int posix_sys_acl_blob_get_file(vfs_handle_struct *handle, + const char *path_p, + TALLOC_CTX *mem_ctx, + char **blob_description, + DATA_BLOB *blob) +{ + int ret; + TALLOC_CTX *frame = talloc_stackframe(); + struct smb_acl_wrapper acl_wrapper = {}; + struct smb_filename *smb_fname = NULL; + NTSTATUS status = create_synthetic_smb_fname_split(frame, path_p, + NULL, + &smb_fname); + if (!NT_STATUS_IS_OK(status)) { + errno = map_errno_from_nt_status(status); + TALLOC_FREE(frame); + return -1; + } + + acl_wrapper.access_acl + = smb_vfs_call_sys_acl_get_file(handle, + path_p, + SMB_ACL_TYPE_ACCESS, + frame); + + ret = smb_vfs_call_stat(handle, smb_fname); + if (ret == -1) { + TALLOC_FREE(frame); + return -1; + } + + if (S_ISDIR(smb_fname->st.st_ex_mode)) { + acl_wrapper.default_acl + = smb_vfs_call_sys_acl_get_file(handle, + path_p, + SMB_ACL_TYPE_DEFAULT, + frame); + } + + acl_wrapper.owner = smb_fname->st.st_ex_uid; + acl_wrapper.group = smb_fname->st.st_ex_gid; + acl_wrapper.mode = smb_fname->st.st_ex_mode; + + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_push_struct_blob(blob, mem_ctx, + &acl_wrapper, + (ndr_push_flags_fn_t)ndr_push_smb_acl_wrapper))) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + *blob_description = talloc_strdup(mem_ctx, "posix_acl"); + if (!*blob_description) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + TALLOC_FREE(frame); + return 0; +} + +int posix_sys_acl_blob_get_fd(vfs_handle_struct *handle, + files_struct *fsp, + TALLOC_CTX *mem_ctx, + char **blob_description, + DATA_BLOB *blob) +{ + SMB_STRUCT_STAT sbuf; + TALLOC_CTX *frame; + struct smb_acl_wrapper acl_wrapper; + int ret; + + /* This ensures that we also consider the default ACL */ + if (fsp->is_directory || fsp->fh->fd == -1) { + return posix_sys_acl_blob_get_file(handle, fsp->fsp_name->base_name, + mem_ctx, blob_description, blob); + } + frame = talloc_stackframe(); + + acl_wrapper.default_acl = NULL; + + acl_wrapper.access_acl = smb_vfs_call_sys_acl_get_file(handle, fsp->fsp_name->base_name, + SMB_ACL_TYPE_ACCESS, frame); + + ret = smb_vfs_call_fstat(handle, fsp, &sbuf); + if (ret == -1) { + TALLOC_FREE(frame); + return -1; + } + + acl_wrapper.owner = sbuf.st_ex_uid; + acl_wrapper.group = sbuf.st_ex_gid; + acl_wrapper.mode = sbuf.st_ex_mode; + + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_push_struct_blob(blob, mem_ctx, + &acl_wrapper, + (ndr_push_flags_fn_t)ndr_push_smb_acl_wrapper))) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + *blob_description = talloc_strdup(mem_ctx, "posix_acl"); + if (!*blob_description) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + TALLOC_FREE(frame); + return 0; +} diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h index 1e5883b0392..1b3c23227d2 100644 --- a/source3/smbd/proto.h +++ b/source3/smbd/proto.h @@ -739,6 +739,16 @@ NTSTATUS make_default_filesystem_acl(TALLOC_CTX *ctx, const char *name, SMB_STRUCT_STAT *psbuf, struct security_descriptor **ppdesc); +int posix_sys_acl_blob_get_file(vfs_handle_struct *handle, + const char *path_p, + TALLOC_CTX *mem_ctx, + char **blob_description, + DATA_BLOB *blob); +int posix_sys_acl_blob_get_fd(vfs_handle_struct *handle, + files_struct *fsp, + TALLOC_CTX *mem_ctx, + char **blob_description, + DATA_BLOB *blob); /* The following definitions come from smbd/process.c */ -- 2.11.4.GIT