diff options
author | Andrew Bartlett <abartlet@samba.org> | 2012-10-10 16:49:59 +1100 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2012-10-11 12:25:11 +1100 |
commit | ddcaac99f0262909be57eceac4535bd3684096b3 (patch) | |
tree | 552acc1d65e8316a3f0faf2ec779a7dbde6187ed /source3 | |
parent | 1f36ec129300e4f69efe26d4950fe3a7cfbfb233 (diff) | |
download | samba-ddcaac99f0262909be57eceac4535bd3684096b3.tar.gz samba-ddcaac99f0262909be57eceac4535bd3684096b3.tar.bz2 samba-ddcaac99f0262909be57eceac4535bd3684096b3.zip |
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
Diffstat (limited to 'source3')
-rw-r--r-- | source3/Makefile.in | 2 | ||||
-rw-r--r-- | source3/smbd/posix_acls.c | 115 | ||||
-rw-r--r-- | source3/smbd/proto.h | 10 |
3 files changed, 126 insertions, 1 deletions
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 */ |