summaryrefslogtreecommitdiff
path: root/source3/smbd/posix_acls.c
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2012-10-10 16:49:59 +1100
committerAndrew Bartlett <abartlet@samba.org>2012-10-11 12:25:11 +1100
commitddcaac99f0262909be57eceac4535bd3684096b3 (patch)
tree552acc1d65e8316a3f0faf2ec779a7dbde6187ed /source3/smbd/posix_acls.c
parent1f36ec129300e4f69efe26d4950fe3a7cfbfb233 (diff)
downloadsamba-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/smbd/posix_acls.c')
-rw-r--r--source3/smbd/posix_acls.c115
1 files changed, 115 insertions, 0 deletions
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;
+}