From ddcaac99f0262909be57eceac4535bd3684096b3 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 10 Oct 2012 16:49:59 +1100 Subject: 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(-) (limited to 'source3') diff --git a/source3/Makefile.in b/source3/Makefile.in index a29aae2e0a..b202df3745 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 05cd2a740d..fadd22922e 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 1e5883b039..1b3c23227d 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 */ -- cgit