summaryrefslogtreecommitdiff
path: root/source3/modules
diff options
context:
space:
mode:
authorRalph Boehme <slow@samba.org>2016-08-23 17:07:20 +0200
committerJeremy Allison <jra@samba.org>2016-08-30 21:12:25 +0200
commit335527c647331148927feea2a7ae2f2c88986bc6 (patch)
treea65cfc18385a0c0b3440fdd978d2d01d6767bd48 /source3/modules
parente6f1254a00a6bf85b8d95bfbafef7d3e39ce1dde (diff)
downloadsamba-335527c647331148927feea2a7ae2f2c88986bc6.tar.gz
vfs_acl_common: simplify ACL logic, cleanup and talloc hierarchy
No change in behaviour (hopefully! :-). This paves the way for moving the ACL blob validation to a helper function in the next commit. Bug: https://bugzilla.samba.org/show_bug.cgi?id=12177 Signed-off-by: Ralph Boehme <slow@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org>
Diffstat (limited to 'source3/modules')
-rw-r--r--source3/modules/vfs_acl_common.c131
1 files changed, 61 insertions, 70 deletions
diff --git a/source3/modules/vfs_acl_common.c b/source3/modules/vfs_acl_common.c
index 0c40f376066..66c58e73ad5 100644
--- a/source3/modules/vfs_acl_common.c
+++ b/source3/modules/vfs_acl_common.c
@@ -488,6 +488,7 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle,
uint8_t sys_acl_hash[XATTR_SD_HASH_SIZE];
uint8_t hash_tmp[XATTR_SD_HASH_SIZE];
uint8_t sys_acl_hash_tmp[XATTR_SD_HASH_SIZE];
+ struct security_descriptor *psd = NULL;
struct security_descriptor *psd_blob = NULL;
struct security_descriptor *psd_fs = NULL;
const struct smb_filename *smb_fname = NULL;
@@ -495,7 +496,9 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle,
ACL_MODULE_NAME,
"ignore system acls",
false);
- TALLOC_CTX *frame = talloc_stackframe();
+ char *sys_acl_blob_description = NULL;
+ DATA_BLOB sys_acl_blob = { 0 };
+ bool psd_is_from_fs = false;
if (fsp && smb_fname_in == NULL) {
smb_fname = fsp->fsp_name;
@@ -505,11 +508,10 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle,
DEBUG(10, ("get_nt_acl_internal: name=%s\n", smb_fname->base_name));
- status = get_acl_blob(frame, handle, fsp, smb_fname, &blob);
+ status = get_acl_blob(mem_ctx, handle, fsp, smb_fname, &blob);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(10, ("get_nt_acl_internal: get_acl_blob returned %s\n",
nt_errstr(status)));
- psd_blob = NULL;
goto out;
} else {
status = parse_acl_blob(&blob, mem_ctx, &psd_blob,
@@ -517,17 +519,12 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle,
if (!NT_STATUS_IS_OK(status)) {
DEBUG(10, ("parse_acl_blob returned %s\n",
nt_errstr(status)));
- psd_blob = NULL;
+ TALLOC_FREE(blob.data);
goto out;
}
}
- /* Ensure we don't leak psd_blob if we don't choose it.
- *
- * We don't allocate it onto frame as it is preferred not to
- * steal from a talloc pool.
- */
- talloc_steal(frame, psd_blob);
+ TALLOC_FREE(blob.data);
/* determine which type of xattr we got */
switch (xattr_version) {
@@ -537,10 +534,14 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle,
* require confirmation of the hash. In particular,
* the NTVFS file server uses version 1, but
* 'samba-tool ntacl' can set these as well */
+ psd = psd_blob;
+ psd_blob = NULL;
goto out;
case 3:
case 4:
if (ignore_file_system_acl) {
+ psd = psd_blob;
+ psd_blob = NULL;
goto out;
}
@@ -569,20 +570,18 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle,
case 4:
{
int ret;
- char *sys_acl_blob_description;
- DATA_BLOB sys_acl_blob;
if (fsp) {
/* Get the full underlying sd, then hash. */
ret = SMB_VFS_NEXT_SYS_ACL_BLOB_GET_FD(handle,
fsp,
- frame,
+ mem_ctx,
&sys_acl_blob_description,
&sys_acl_blob);
} else {
/* Get the full underlying sd, then hash. */
ret = SMB_VFS_NEXT_SYS_ACL_BLOB_GET_FILE(handle,
smb_fname->base_name,
- frame,
+ mem_ctx,
&sys_acl_blob_description,
&sys_acl_blob);
}
@@ -592,16 +591,20 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle,
if (ret == 0) {
status = hash_blob_sha256(sys_acl_blob, sys_acl_hash_tmp);
if (!NT_STATUS_IS_OK(status)) {
- TALLOC_FREE(frame);
- return status;
+ goto fail;
}
+ TALLOC_FREE(sys_acl_blob_description);
+ TALLOC_FREE(sys_acl_blob.data);
+
if (memcmp(&sys_acl_hash[0], &sys_acl_hash_tmp[0],
XATTR_SD_HASH_SIZE) == 0) {
/* Hash matches, return blob sd. */
DEBUG(10, ("get_nt_acl_internal: blob hash "
"matches for file %s\n",
smb_fname->base_name ));
+ psd = psd_blob;
+ psd_blob = NULL;
goto out;
}
}
@@ -630,21 +633,15 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle,
"returned %s\n",
smb_fname->base_name,
nt_errstr(status)));
- TALLOC_FREE(frame);
- return status;
+ goto fail;
}
- /* Ensure we don't leak psd_fs if we don't choose it.
- *
- * We don't allocate it onto frame as it is preferred not to
- * steal from a talloc pool.
- */
- talloc_steal(frame, psd_fs);
-
status = hash_sd_sha256(psd_fs, hash_tmp);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(psd_blob);
- psd_blob = psd_fs;
+ psd = psd_fs;
+ psd_fs = NULL;
+ psd_is_from_fs = true;
goto out;
}
@@ -653,6 +650,8 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle,
DEBUG(10, ("get_nt_acl_internal: blob hash "
"matches for file %s\n",
smb_fname->base_name ));
+ psd = psd_blob;
+ psd_blob = NULL;
goto out;
}
@@ -669,11 +668,13 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle,
}
TALLOC_FREE(psd_blob);
- psd_blob = psd_fs;
+ psd = psd_fs;
+ psd_fs = NULL;
+ psd_is_from_fs = true;
}
- out:
- if (psd_blob == NULL) {
+out:
+ if (psd == NULL) {
/* Get the full underlying sd, as we failed to get the
* blob for the hash, or the revision/hash type wasn't
* known */
@@ -682,13 +683,13 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle,
fsp,
security_info,
mem_ctx,
- &psd_fs);
+ &psd);
} else {
status = SMB_VFS_NEXT_GET_NT_ACL(handle,
smb_fname,
security_info,
mem_ctx,
- &psd_fs);
+ &psd);
}
if (!NT_STATUS_IS_OK(status)) {
@@ -696,24 +697,13 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle,
"returned %s\n",
smb_fname->base_name,
nt_errstr(status)));
- TALLOC_FREE(frame);
- return status;
+ goto fail;
}
- /* Ensure we don't leak psd_fs if we don't choose it.
- *
- * We don't allocate it onto frame as it is preferred not to
- * steal from a talloc pool.
- */
- talloc_steal(frame, psd_fs);
- psd_blob = psd_fs;
+ psd_is_from_fs = true;
}
- if (psd_blob != psd_fs) {
- /* We're returning the blob, throw
- * away the filesystem SD. */
- TALLOC_FREE(psd_fs);
- } else {
+ if (psd_is_from_fs) {
SMB_STRUCT_STAT sbuf;
SMB_STRUCT_STAT *psbuf = &sbuf;
bool is_directory = false;
@@ -725,8 +715,7 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle,
if (fsp) {
status = vfs_stat_fsp(fsp);
if (!NT_STATUS_IS_OK(status)) {
- TALLOC_FREE(frame);
- return status;
+ goto fail;
}
psbuf = &fsp->fsp_name->st;
} else {
@@ -751,72 +740,74 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle,
smb_fname,
&sbuf);
if (ret == -1) {
- TALLOC_FREE(frame);
- return map_nt_error_from_unix(errno);
+ status = map_nt_error_from_unix(errno);
+ goto fail;
}
}
is_directory = S_ISDIR(psbuf->st_ex_mode);
if (ignore_file_system_acl) {
- TALLOC_FREE(psd_fs);
+ TALLOC_FREE(psd);
status = make_default_filesystem_acl(mem_ctx,
smb_fname->base_name,
psbuf,
- &psd_blob);
+ &psd);
if (!NT_STATUS_IS_OK(status)) {
- TALLOC_FREE(frame);
- return status;
+ goto fail;
}
} else {
if (is_directory &&
- !sd_has_inheritable_components(psd_blob,
+ !sd_has_inheritable_components(psd,
true)) {
status = add_directory_inheritable_components(
handle,
smb_fname->base_name,
psbuf,
- psd_blob);
+ psd);
if (!NT_STATUS_IS_OK(status)) {
- TALLOC_FREE(frame);
- return status;
+ goto fail;
}
}
/* The underlying POSIX module always sets
the ~SEC_DESC_DACL_PROTECTED bit, as ACLs
can't be inherited in this way under POSIX.
Remove it for Windows-style ACLs. */
- psd_blob->type &= ~SEC_DESC_DACL_PROTECTED;
+ psd->type &= ~SEC_DESC_DACL_PROTECTED;
}
}
if (!(security_info & SECINFO_OWNER)) {
- psd_blob->owner_sid = NULL;
+ psd->owner_sid = NULL;
}
if (!(security_info & SECINFO_GROUP)) {
- psd_blob->group_sid = NULL;
+ psd->group_sid = NULL;
}
if (!(security_info & SECINFO_DACL)) {
- psd_blob->type &= ~SEC_DESC_DACL_PRESENT;
- psd_blob->dacl = NULL;
+ psd->type &= ~SEC_DESC_DACL_PRESENT;
+ psd->dacl = NULL;
}
if (!(security_info & SECINFO_SACL)) {
- psd_blob->type &= ~SEC_DESC_SACL_PRESENT;
- psd_blob->sacl = NULL;
+ psd->type &= ~SEC_DESC_SACL_PRESENT;
+ psd->sacl = NULL;
}
- TALLOC_FREE(blob.data);
-
if (DEBUGLEVEL >= 10) {
DEBUG(10,("get_nt_acl_internal: returning acl for %s is:\n",
smb_fname->base_name ));
- NDR_PRINT_DEBUG(security_descriptor, psd_blob);
+ NDR_PRINT_DEBUG(security_descriptor, psd);
}
- /* The VFS API is that the ACL is expected to be on mem_ctx */
- *ppdesc = talloc_move(mem_ctx, &psd_blob);
+ *ppdesc = psd;
- TALLOC_FREE(frame);
return NT_STATUS_OK;
+
+fail:
+ TALLOC_FREE(psd);
+ TALLOC_FREE(psd_blob);
+ TALLOC_FREE(psd_fs);
+ TALLOC_FREE(sys_acl_blob_description);
+ TALLOC_FREE(sys_acl_blob.data);
+ return status;
}
/*********************************************************************