From c8ade07760ae0ccfdf2d875c9f3027926e62321b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 10 Oct 2012 11:50:27 +1100 Subject: smbd: Add mem_ctx to {f,}get_nt_acl VFS call This makes it clear which context the returned SD is allocated on, as a number of callers do not want it on talloc_tos(). As the ACL transformation allocates and then no longer needs a great deal of memory, a talloc_stackframe() call is used to contain the memory that is not returned further up the stack. Andrew Bartlett --- source3/modules/vfs_acl_common.c | 68 ++++++++++++++++++++++++++-------------- 1 file changed, 45 insertions(+), 23 deletions(-) (limited to 'source3/modules/vfs_acl_common.c') diff --git a/source3/modules/vfs_acl_common.c b/source3/modules/vfs_acl_common.c index c2ac875fa1..ef2dda1b45 100644 --- a/source3/modules/vfs_acl_common.c +++ b/source3/modules/vfs_acl_common.c @@ -74,27 +74,29 @@ static NTSTATUS hash_sd_sha256(struct security_descriptor *psd, *******************************************************************/ static NTSTATUS parse_acl_blob(const DATA_BLOB *pblob, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc, uint16_t *p_hash_type, uint8_t hash[XATTR_SD_HASH_SIZE]) { - TALLOC_CTX *ctx = talloc_tos(); struct xattr_NTACL xacl; enum ndr_err_code ndr_err; size_t sd_size; + TALLOC_CTX *frame = talloc_stackframe(); - ndr_err = ndr_pull_struct_blob(pblob, ctx, &xacl, + ndr_err = ndr_pull_struct_blob(pblob, frame, &xacl, (ndr_pull_flags_fn_t)ndr_pull_xattr_NTACL); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { DEBUG(5, ("parse_acl_blob: ndr_pull_xattr_NTACL failed: %s\n", ndr_errstr(ndr_err))); + TALLOC_FREE(frame); return ndr_map_error2ntstatus(ndr_err); } switch (xacl.version) { case 1: - *ppdesc = make_sec_desc(ctx, SD_REVISION, + *ppdesc = make_sec_desc(mem_ctx, SD_REVISION, xacl.info.sd->type | SEC_DESC_SELF_RELATIVE, xacl.info.sd->owner_sid, xacl.info.sd->group_sid, @@ -106,7 +108,7 @@ static NTSTATUS parse_acl_blob(const DATA_BLOB *pblob, memset(hash, '\0', XATTR_SD_HASH_SIZE); break; case 2: - *ppdesc = make_sec_desc(ctx, SD_REVISION, + *ppdesc = make_sec_desc(mem_ctx, SD_REVISION, xacl.info.sd_hs2->sd->type | SEC_DESC_SELF_RELATIVE, xacl.info.sd_hs2->sd->owner_sid, xacl.info.sd_hs2->sd->group_sid, @@ -118,7 +120,7 @@ static NTSTATUS parse_acl_blob(const DATA_BLOB *pblob, memset(hash, '\0', XATTR_SD_HASH_SIZE); break; case 3: - *ppdesc = make_sec_desc(ctx, SD_REVISION, + *ppdesc = make_sec_desc(mem_ctx, SD_REVISION, xacl.info.sd_hs3->sd->type | SEC_DESC_SELF_RELATIVE, xacl.info.sd_hs3->sd->owner_sid, xacl.info.sd_hs3->sd->group_sid, @@ -130,10 +132,11 @@ static NTSTATUS parse_acl_blob(const DATA_BLOB *pblob, memcpy(hash, xacl.info.sd_hs3->hash, XATTR_SD_HASH_SIZE); break; default: + TALLOC_FREE(frame); return NT_STATUS_REVISION_MISMATCH; } - TALLOC_FREE(xacl.info.sd); + TALLOC_FREE(frame); return (*ppdesc != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY; } @@ -274,7 +277,8 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32_t security_info, - struct security_descriptor **ppdesc) + TALLOC_CTX *mem_ctx, + struct security_descriptor **ppdesc) { DATA_BLOB blob = data_blob_null; NTSTATUS status; @@ -298,14 +302,16 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle, or to return as backup. */ if (fsp) { status = SMB_VFS_NEXT_FGET_NT_ACL(handle, - fsp, - HASH_SECURITY_INFO, - &pdesc_next); + fsp, + HASH_SECURITY_INFO, + mem_ctx, + &pdesc_next); } else { status = SMB_VFS_NEXT_GET_NT_ACL(handle, - name, - HASH_SECURITY_INFO, - &pdesc_next); + name, + HASH_SECURITY_INFO, + mem_ctx, + &pdesc_next); } if (!NT_STATUS_IS_OK(status)) { @@ -324,7 +330,7 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle, goto out; } - status = parse_acl_blob(&blob, &psd, + status = parse_acl_blob(&blob, mem_ctx, &psd, &hash_type, &hash[0]); if (!NT_STATUS_IS_OK(status)) { DEBUG(10, ("parse_acl_blob returned %s\n", @@ -417,7 +423,7 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle, if (ignore_file_system_acl) { TALLOC_FREE(pdesc_next); - status = make_default_filesystem_acl(talloc_tos(), + status = make_default_filesystem_acl(mem_ctx, name, psbuf, &psd); @@ -476,11 +482,14 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle, Fetch a security descriptor given an fsp. *********************************************************************/ -static NTSTATUS fget_nt_acl_common(vfs_handle_struct *handle, files_struct *fsp, - uint32_t security_info, struct security_descriptor **ppdesc) +static NTSTATUS fget_nt_acl_common(vfs_handle_struct *handle, + files_struct *fsp, + uint32_t security_info, + TALLOC_CTX *mem_ctx, + struct security_descriptor **ppdesc) { return get_nt_acl_internal(handle, fsp, - NULL, security_info, ppdesc); + NULL, security_info, mem_ctx, ppdesc); } /********************************************************************* @@ -488,10 +497,13 @@ static NTSTATUS fget_nt_acl_common(vfs_handle_struct *handle, files_struct *fsp, *********************************************************************/ static NTSTATUS get_nt_acl_common(vfs_handle_struct *handle, - const char *name, uint32_t security_info, struct security_descriptor **ppdesc) + const char *name, + uint32_t security_info, + TALLOC_CTX *mem_ctx, + struct security_descriptor **ppdesc) { return get_nt_acl_internal(handle, NULL, - name, security_info, ppdesc); + name, security_info, mem_ctx, ppdesc); } /********************************************************************* @@ -507,6 +519,7 @@ static NTSTATUS fset_nt_acl_common(vfs_handle_struct *handle, files_struct *fsp, struct security_descriptor *psd = NULL; uint8_t hash[XATTR_SD_HASH_SIZE]; bool chown_needed = false; + TALLOC_CTX *frame = talloc_stackframe(); if (DEBUGLEVEL >= 10) { DEBUG(10,("fset_nt_acl_xattr: incoming sd for file %s\n", @@ -518,9 +531,11 @@ static NTSTATUS fset_nt_acl_common(vfs_handle_struct *handle, files_struct *fsp, status = get_nt_acl_internal(handle, fsp, NULL, SECINFO_OWNER|SECINFO_GROUP|SECINFO_DACL|SECINFO_SACL, + frame, &psd); if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); return status; } @@ -554,6 +569,7 @@ static NTSTATUS fset_nt_acl_common(vfs_handle_struct *handle, files_struct *fsp, status = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent, psd); if (!NT_STATUS_IS_OK(status)) { if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) { + TALLOC_FREE(frame); return status; } /* We got access denied here. If we're already root, @@ -578,22 +594,26 @@ static NTSTATUS fset_nt_acl_common(vfs_handle_struct *handle, files_struct *fsp, security_info_sent, psd); unbecome_root(); if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); return status; } } /* Get the full underlying sd, then hash. */ status = SMB_VFS_NEXT_FGET_NT_ACL(handle, - fsp, - HASH_SECURITY_INFO, - &pdesc_next); + fsp, + HASH_SECURITY_INFO, + frame, + &pdesc_next); if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); return status; } status = hash_sd_sha256(pdesc_next, hash); if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); return status; } @@ -610,11 +630,13 @@ static NTSTATUS fset_nt_acl_common(vfs_handle_struct *handle, files_struct *fsp, status = create_acl_blob(psd, &blob, XATTR_SD_HASH_TYPE_SHA256, hash); if (!NT_STATUS_IS_OK(status)) { DEBUG(10, ("fset_nt_acl_xattr: create_acl_blob failed\n")); + TALLOC_FREE(frame); return status; } status = store_acl_blob_fsp(handle, fsp, &blob); + TALLOC_FREE(frame); return status; } -- cgit