From c8ade07760ae0ccfdf2d875c9f3027926e62321b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 10 Oct 2012 11:50:27 +1100 Subject: [PATCH] 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 --- examples/VFS/skel_opaque.c | 8 ++- examples/VFS/skel_transparent.c | 12 ++-- source3/include/vfs.h | 4 ++ source3/include/vfs_macros.h | 18 +++--- source3/modules/nfs4_acls.c | 18 ++++-- source3/modules/nfs4_acls.h | 2 + source3/modules/vfs_acl_common.c | 68 +++++++++++++++-------- source3/modules/vfs_afsacl.c | 16 ++++-- source3/modules/vfs_aixacl2.c | 16 ++++-- source3/modules/vfs_catia.c | 3 +- source3/modules/vfs_default.c | 8 ++- source3/modules/vfs_full_audit.c | 12 ++-- source3/modules/vfs_gpfs.c | 14 +++-- source3/modules/vfs_media_harmony.c | 13 +++-- source3/modules/vfs_shadow_copy2.c | 11 +++- source3/modules/vfs_time_audit.c | 8 ++- source3/modules/vfs_zfsacl.c | 18 +++--- source3/rpc_server/srvsvc/srv_srvsvc_nt.c | 16 +++--- source3/smbd/file_access.c | 4 +- source3/smbd/nttrans.c | 13 +++-- source3/smbd/open.c | 22 +++++--- source3/smbd/posix_acls.c | 52 +++++++++++------ source3/smbd/proto.h | 5 +- source3/smbd/vfs.c | 6 +- source3/torture/cmd_vfs.c | 8 ++- 25 files changed, 245 insertions(+), 130 deletions(-) diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c index 3b918483a84..6dd83bb584c 100644 --- a/examples/VFS/skel_opaque.c +++ b/examples/VFS/skel_opaque.c @@ -545,13 +545,17 @@ static NTSTATUS skel_fsctl(struct vfs_handle_struct *handle, } static NTSTATUS skel_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, - uint32 security_info, struct security_descriptor **ppdesc) + uint32 security_info, + TALLOC_CTX *mem_ctx, + struct security_descriptor **ppdesc) { return NT_STATUS_NOT_IMPLEMENTED; } static NTSTATUS skel_get_nt_acl(vfs_handle_struct *handle, - const char *name, uint32 security_info, struct security_descriptor **ppdesc) + const char *name, uint32 security_info, + TALLOC_CTX *mem_ctx, + struct security_descriptor **ppdesc) { return NT_STATUS_NOT_IMPLEMENTED; } diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c index a00b0e1bef6..f8a743e06e7 100644 --- a/examples/VFS/skel_transparent.c +++ b/examples/VFS/skel_transparent.c @@ -662,15 +662,19 @@ static NTSTATUS skel_fsctl(struct vfs_handle_struct *handle, } static NTSTATUS skel_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, - uint32 security_info, struct security_descriptor **ppdesc) + uint32 security_info, + TALLOC_CTX *mem_ctx, + struct security_descriptor **ppdesc) { - return SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info, ppdesc); + return SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info, mem_ctx, ppdesc); } static NTSTATUS skel_get_nt_acl(vfs_handle_struct *handle, - const char *name, uint32 security_info, struct security_descriptor **ppdesc) + const char *name, uint32 security_info, + TALLOC_CTX *mem_ctx, + struct security_descriptor **ppdesc) { - return SMB_VFS_NEXT_GET_NT_ACL(handle, name, security_info, ppdesc); + return SMB_VFS_NEXT_GET_NT_ACL(handle, name, security_info, mem_ctx, ppdesc); } static NTSTATUS skel_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, diff --git a/source3/include/vfs.h b/source3/include/vfs.h index 4ba11be94e1..2d18265aac1 100644 --- a/source3/include/vfs.h +++ b/source3/include/vfs.h @@ -671,10 +671,12 @@ struct vfs_fn_pointers { NTSTATUS (*fget_nt_acl_fn)(struct vfs_handle_struct *handle, struct files_struct *fsp, uint32 security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc); NTSTATUS (*get_nt_acl_fn)(struct vfs_handle_struct *handle, const char *name, uint32 security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc); NTSTATUS (*fset_nt_acl_fn)(struct vfs_handle_struct *handle, struct files_struct *fsp, @@ -1079,10 +1081,12 @@ NTSTATUS smb_vfs_call_fsctl(struct vfs_handle_struct *handle, NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle, struct files_struct *fsp, uint32 security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc); NTSTATUS smb_vfs_call_get_nt_acl(struct vfs_handle_struct *handle, const char *name, uint32 security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc); NTSTATUS smb_vfs_call_fset_nt_acl(struct vfs_handle_struct *handle, struct files_struct *fsp, diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h index f1bc8ffa4ca..a5ff90bc9d9 100644 --- a/source3/include/vfs_macros.h +++ b/source3/include/vfs_macros.h @@ -399,15 +399,15 @@ #define SMB_VFS_NEXT_FSCTL(handle, fsp, ctx, function, req_flags, in_data, in_len, out_data, max_out_len, out_len) \ smb_vfs_call_fsctl((handle)->next, (fsp), (ctx), (function), (req_flags), (in_data), (in_len), (out_data), (max_out_len), (out_len)) -#define SMB_VFS_FGET_NT_ACL(fsp, security_info, ppdesc) \ - smb_vfs_call_fget_nt_acl((fsp)->conn->vfs_handles, (fsp), (security_info), (ppdesc)) -#define SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info, ppdesc) \ - smb_vfs_call_fget_nt_acl((handle)->next, (fsp), (security_info), (ppdesc)) - -#define SMB_VFS_GET_NT_ACL(conn, name, security_info, ppdesc) \ - smb_vfs_call_get_nt_acl((conn)->vfs_handles, (name), (security_info), (ppdesc)) -#define SMB_VFS_NEXT_GET_NT_ACL(handle, name, security_info, ppdesc) \ - smb_vfs_call_get_nt_acl((handle)->next, (name), (security_info), (ppdesc)) +#define SMB_VFS_FGET_NT_ACL(fsp, security_info, mem_ctx, ppdesc) \ + smb_vfs_call_fget_nt_acl((fsp)->conn->vfs_handles, (fsp), (security_info), (mem_ctx), (ppdesc)) +#define SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info, mem_ctx, ppdesc) \ + smb_vfs_call_fget_nt_acl((handle)->next, (fsp), (security_info), (mem_ctx), (ppdesc)) + +#define SMB_VFS_GET_NT_ACL(conn, name, security_info, mem_ctx, ppdesc) \ + smb_vfs_call_get_nt_acl((conn)->vfs_handles, (name), (security_info), (mem_ctx), (ppdesc)) +#define SMB_VFS_NEXT_GET_NT_ACL(handle, name, security_info, mem_ctx, ppdesc) \ + smb_vfs_call_get_nt_acl((handle)->next, (name), (security_info), (mem_ctx), (ppdesc)) #define SMB_VFS_AUDIT_FILE(conn, name, sacl, access_requested, access_denied) \ smb_vfs_call_audit_file((conn)->vfs_handles, (name), (sacl), (access_requested), (access_denied)) diff --git a/source3/modules/nfs4_acls.c b/source3/modules/nfs4_acls.c index 05f90f77dfc..48b045feb0e 100644 --- a/source3/modules/nfs4_acls.c +++ b/source3/modules/nfs4_acls.c @@ -370,7 +370,7 @@ static bool smbacl4_nfs42win(TALLOC_CTX *mem_ctx, SMB4ACL_T *theacl, /* in */ } static NTSTATUS smb_get_nt_acl_nfs4_common(const SMB_STRUCT_STAT *sbuf, - uint32 security_info, + uint32 security_info, TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc, SMB4ACL_T *theacl) { int good_aces = 0; @@ -378,7 +378,7 @@ static NTSTATUS smb_get_nt_acl_nfs4_common(const SMB_STRUCT_STAT *sbuf, size_t sd_size = 0; struct security_ace *nt_ace_list = NULL; struct security_acl *psa = NULL; - TALLOC_CTX *mem_ctx = talloc_tos(); + TALLOC_CTX *frame = talloc_stackframe(); if (theacl==NULL || smb_get_naces(theacl)==0) return NT_STATUS_ACCESS_DENIED; /* special because we @@ -392,12 +392,14 @@ static NTSTATUS smb_get_nt_acl_nfs4_common(const SMB_STRUCT_STAT *sbuf, S_ISDIR(sbuf->st_ex_mode), &nt_ace_list, &good_aces)==False) { DEBUG(8,("smbacl4_nfs42win failed\n")); + TALLOC_FREE(frame); return map_nt_error_from_unix(errno); } - psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, good_aces, nt_ace_list); + psa = make_sec_acl(frame, NT4_ACL_REVISION, good_aces, nt_ace_list); if (psa == NULL) { DEBUG(2,("make_sec_acl failed\n")); + TALLOC_FREE(frame); return NT_STATUS_NO_MEMORY; } @@ -409,6 +411,7 @@ static NTSTATUS smb_get_nt_acl_nfs4_common(const SMB_STRUCT_STAT *sbuf, NULL, psa, &sd_size); if (*ppdesc==NULL) { DEBUG(2,("make_sec_desc failed\n")); + TALLOC_FREE(frame); return NT_STATUS_NO_MEMORY; } @@ -416,11 +419,13 @@ static NTSTATUS smb_get_nt_acl_nfs4_common(const SMB_STRUCT_STAT *sbuf, "sd_size %d\n", (int)ndr_size_security_descriptor(*ppdesc, 0))); + TALLOC_FREE(frame); return NT_STATUS_OK; } NTSTATUS smb_fget_nt_acl_nfs4(files_struct *fsp, uint32 security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc, SMB4ACL_T *theacl) { @@ -432,13 +437,15 @@ NTSTATUS smb_fget_nt_acl_nfs4(files_struct *fsp, return map_nt_error_from_unix(errno); } - return smb_get_nt_acl_nfs4_common(&sbuf, security_info, ppdesc, + return smb_get_nt_acl_nfs4_common(&sbuf, security_info, + mem_ctx, ppdesc, theacl); } NTSTATUS smb_get_nt_acl_nfs4(struct connection_struct *conn, const char *name, uint32 security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc, SMB4ACL_T *theacl) { @@ -450,7 +457,8 @@ NTSTATUS smb_get_nt_acl_nfs4(struct connection_struct *conn, return map_nt_error_from_unix(errno); } - return smb_get_nt_acl_nfs4_common(&sbuf, security_info, ppdesc, + return smb_get_nt_acl_nfs4_common(&sbuf, security_info, + mem_ctx, ppdesc, theacl); } diff --git a/source3/modules/nfs4_acls.h b/source3/modules/nfs4_acls.h index fcab6359154..c461229c6c1 100644 --- a/source3/modules/nfs4_acls.h +++ b/source3/modules/nfs4_acls.h @@ -132,11 +132,13 @@ uint32 smb_get_naces(SMB4ACL_T *theacl); NTSTATUS smb_fget_nt_acl_nfs4(files_struct *fsp, uint32 security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc, SMB4ACL_T *theacl); NTSTATUS smb_get_nt_acl_nfs4(connection_struct *conn, const char *name, uint32 security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc, SMB4ACL_T *theacl); /* Callback function needed to set the native acl diff --git a/source3/modules/vfs_acl_common.c b/source3/modules/vfs_acl_common.c index c2ac875fa18..ef2dda1b455 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; } diff --git a/source3/modules/vfs_afsacl.c b/source3/modules/vfs_afsacl.c index 770f6a33f01..96521bc2663 100644 --- a/source3/modules/vfs_afsacl.c +++ b/source3/modules/vfs_afsacl.c @@ -594,6 +594,7 @@ static uint32 nt_to_afs_file_rights(const char *filename, const struct security_ static size_t afs_to_nt_acl_common(struct afs_acl *afs_acl, SMB_STRUCT_STAT *psbuf, uint32 security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc) { struct security_ace *nt_ace_list; @@ -601,7 +602,6 @@ static size_t afs_to_nt_acl_common(struct afs_acl *afs_acl, struct security_acl *psa = NULL; int good_aces; size_t sd_size; - TALLOC_CTX *mem_ctx = talloc_tos(); struct afs_ace *afs_ace; @@ -663,6 +663,7 @@ static size_t afs_to_nt_acl(struct afs_acl *afs_acl, struct connection_struct *conn, struct smb_filename *smb_fname, uint32 security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc) { int ret; @@ -678,12 +679,13 @@ static size_t afs_to_nt_acl(struct afs_acl *afs_acl, } return afs_to_nt_acl_common(afs_acl, &smb_fname->st, security_info, - ppdesc); + mem_ctx, ppdesc); } static size_t afs_fto_nt_acl(struct afs_acl *afs_acl, struct files_struct *fsp, uint32 security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc) { SMB_STRUCT_STAT sbuf; @@ -691,7 +693,7 @@ static size_t afs_fto_nt_acl(struct afs_acl *afs_acl, if (fsp->fh->fd == -1) { /* Get the stat struct for the owner info. */ return afs_to_nt_acl(afs_acl, fsp->conn, fsp->fsp_name, - security_info, ppdesc); + security_info, mem_ctx, ppdesc); } if(SMB_VFS_FSTAT(fsp, &sbuf) != 0) { @@ -1008,6 +1010,7 @@ static NTSTATUS afs_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, static NTSTATUS afsacl_fget_nt_acl(struct vfs_handle_struct *handle, struct files_struct *fsp, uint32 security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc) { struct afs_acl acl; @@ -1021,7 +1024,7 @@ static NTSTATUS afsacl_fget_nt_acl(struct vfs_handle_struct *handle, return NT_STATUS_ACCESS_DENIED; } - sd_size = afs_fto_nt_acl(&acl, fsp, security_info, ppdesc); + sd_size = afs_fto_nt_acl(&acl, fsp, security_info, mem_ctx, ppdesc); free_afs_acl(&acl); @@ -1029,7 +1032,8 @@ static NTSTATUS afsacl_fget_nt_acl(struct vfs_handle_struct *handle, } static NTSTATUS afsacl_get_nt_acl(struct vfs_handle_struct *handle, - const char *name, uint32 security_info, + const char *name, uint32 security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc) { struct afs_acl acl; @@ -1053,7 +1057,7 @@ static NTSTATUS afsacl_get_nt_acl(struct vfs_handle_struct *handle, } sd_size = afs_to_nt_acl(&acl, handle->conn, smb_fname, security_info, - ppdesc); + mem_ctx, ppdesc); TALLOC_FREE(smb_fname); free_afs_acl(&acl); diff --git a/source3/modules/vfs_aixacl2.c b/source3/modules/vfs_aixacl2.c index 0d754d7b437..0f89eb66474 100644 --- a/source3/modules/vfs_aixacl2.c +++ b/source3/modules/vfs_aixacl2.c @@ -157,6 +157,7 @@ static bool aixjfs2_get_nfs4_acl(const char *name, static NTSTATUS aixjfs2_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, uint32 security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc) { SMB4ACL_T *pacl = NULL; @@ -169,17 +170,21 @@ static NTSTATUS aixjfs2_fget_nt_acl(vfs_handle_struct *handle, if (retryPosix) { DEBUG(10, ("retrying with posix acl...\n")); - return posix_fget_nt_acl(fsp, security_info, ppdesc); + return posix_fget_nt_acl(fsp, security_info, + mem_ctx, ppdesc); } if (result==False) return NT_STATUS_ACCESS_DENIED; - return smb_fget_nt_acl_nfs4(fsp, security_info, ppdesc, pacl); + return smb_fget_nt_acl_nfs4(fsp, security_info, ppdesc, + mem_ctx, pacl); } static NTSTATUS aixjfs2_get_nt_acl(vfs_handle_struct *handle, const char *name, - uint32 security_info, struct security_descriptor **ppdesc) + uint32 security_info, + TALLOC_CTX *mem_ctx, + struct security_descriptor **ppdesc) { SMB4ACL_T *pacl = NULL; bool result; @@ -191,12 +196,13 @@ static NTSTATUS aixjfs2_get_nt_acl(vfs_handle_struct *handle, { DEBUG(10, ("retrying with posix acl...\n")); return posix_get_nt_acl(handle->conn, name, security_info, - ppdesc); + mem_ctx, ppdesc); } if (result==False) return NT_STATUS_ACCESS_DENIED; - return smb_get_nt_acl_nfs4(handle->conn, name, security_info, ppdesc, + return smb_get_nt_acl_nfs4(handle->conn, name, security_info, + mem_ctx, ppdesc, pacl); } diff --git a/source3/modules/vfs_catia.c b/source3/modules/vfs_catia.c index a2bef443701..b9f241e240b 100644 --- a/source3/modules/vfs_catia.c +++ b/source3/modules/vfs_catia.c @@ -703,6 +703,7 @@ static NTSTATUS catia_get_nt_acl(struct vfs_handle_struct *handle, const char *path, uint32 security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc) { char *mapped_name = NULL; @@ -715,7 +716,7 @@ catia_get_nt_acl(struct vfs_handle_struct *handle, return status; } status = SMB_VFS_NEXT_GET_NT_ACL(handle, mapped_name, - security_info, ppdesc); + security_info, mem_ctx, ppdesc); TALLOC_FREE(mapped_name); return status; diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index aa91a48a2ea..2aa4ca5b143 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -2039,12 +2039,14 @@ static void vfswrap_strict_unlock(struct vfs_handle_struct *handle, static NTSTATUS vfswrap_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, uint32 security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc) { NTSTATUS result; START_PROFILE(fget_nt_acl); - result = posix_fget_nt_acl(fsp, security_info, ppdesc); + result = posix_fget_nt_acl(fsp, security_info, + mem_ctx, ppdesc); END_PROFILE(fget_nt_acl); return result; } @@ -2052,12 +2054,14 @@ static NTSTATUS vfswrap_fget_nt_acl(vfs_handle_struct *handle, static NTSTATUS vfswrap_get_nt_acl(vfs_handle_struct *handle, const char *name, uint32 security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc) { NTSTATUS result; START_PROFILE(get_nt_acl); - result = posix_get_nt_acl(handle->conn, name, security_info, ppdesc); + result = posix_get_nt_acl(handle->conn, name, security_info, + mem_ctx, ppdesc); END_PROFILE(get_nt_acl); return result; } diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c index e56c4a82a0d..be8989cdb52 100644 --- a/source3/modules/vfs_full_audit.c +++ b/source3/modules/vfs_full_audit.c @@ -1733,12 +1733,14 @@ static NTSTATUS smb_full_audit_translate_name(struct vfs_handle_struct *handle, } static NTSTATUS smb_full_audit_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, - uint32 security_info, - struct security_descriptor **ppdesc) + uint32 security_info, + TALLOC_CTX *mem_ctx, + struct security_descriptor **ppdesc) { NTSTATUS result; - result = SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info, ppdesc); + result = SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info, + mem_ctx, ppdesc); do_log(SMB_VFS_OP_FGET_NT_ACL, NT_STATUS_IS_OK(result), handle, "%s", fsp_str_do_log(fsp)); @@ -1749,11 +1751,13 @@ static NTSTATUS smb_full_audit_fget_nt_acl(vfs_handle_struct *handle, files_stru static NTSTATUS smb_full_audit_get_nt_acl(vfs_handle_struct *handle, const char *name, uint32 security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc) { NTSTATUS result; - result = SMB_VFS_NEXT_GET_NT_ACL(handle, name, security_info, ppdesc); + result = SMB_VFS_NEXT_GET_NT_ACL(handle, name, security_info, + mem_ctx, ppdesc); do_log(SMB_VFS_OP_GET_NT_ACL, NT_STATUS_IS_OK(result), handle, "%s", name); diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index 412c48c4404..5ab5d4a2ad1 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -348,6 +348,7 @@ static int gpfs_get_nfs4_acl(const char *fname, SMB4ACL_T **ppacl) static NTSTATUS gpfsacl_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, uint32 security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc) { SMB4ACL_T *pacl = NULL; @@ -367,11 +368,11 @@ static NTSTATUS gpfsacl_fget_nt_acl(vfs_handle_struct *handle, result = gpfs_get_nfs4_acl(fsp->fsp_name->base_name, &pacl); if (result == 0) - return smb_fget_nt_acl_nfs4(fsp, security_info, ppdesc, pacl); + return smb_fget_nt_acl_nfs4(fsp, security_info, mem_ctx, ppdesc, pacl); if (result > 0) { DEBUG(10, ("retrying with posix acl...\n")); - return posix_fget_nt_acl(fsp, security_info, ppdesc); + return posix_fget_nt_acl(fsp, security_info, mem_ctx, ppdesc); } /* GPFS ACL was not read, something wrong happened, error code is set in errno */ @@ -380,7 +381,8 @@ static NTSTATUS gpfsacl_fget_nt_acl(vfs_handle_struct *handle, static NTSTATUS gpfsacl_get_nt_acl(vfs_handle_struct *handle, const char *name, - uint32 security_info, struct security_descriptor **ppdesc) + uint32 security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc) { SMB4ACL_T *pacl = NULL; int result; @@ -399,11 +401,13 @@ static NTSTATUS gpfsacl_get_nt_acl(vfs_handle_struct *handle, result = gpfs_get_nfs4_acl(name, &pacl); if (result == 0) - return smb_get_nt_acl_nfs4(handle->conn, name, security_info, ppdesc, pacl); + return smb_get_nt_acl_nfs4(handle->conn, name, security_info, + mem_ctx, ppdesc, pacl); if (result > 0) { DEBUG(10, ("retrying with posix acl...\n")); - return posix_get_nt_acl(handle->conn, name, security_info, ppdesc); + return posix_get_nt_acl(handle->conn, name, security_info, + mem_ctx, ppdesc); } /* GPFS ACL was not read, something wrong happened, error code is set in errno */ diff --git a/source3/modules/vfs_media_harmony.c b/source3/modules/vfs_media_harmony.c index a10eb5e5d39..360fca69297 100644 --- a/source3/modules/vfs_media_harmony.c +++ b/source3/modules/vfs_media_harmony.c @@ -2009,9 +2009,10 @@ out: * In this case, "name" is a path. */ static NTSTATUS mh_get_nt_acl(vfs_handle_struct *handle, - const char *name, - uint32 security_info, - struct security_descriptor **ppdesc) + const char *name, + uint32 security_info, + TALLOC_CTX *mem_ctx, + struct security_descriptor **ppdesc) { NTSTATUS status; char *clientPath; @@ -2021,7 +2022,8 @@ static NTSTATUS mh_get_nt_acl(vfs_handle_struct *handle, if (!is_in_media_files(name)) { status = SMB_VFS_NEXT_GET_NT_ACL(handle, name, - security_info, ppdesc); + security_info, + mem_ctx, ppdesc); goto out; } @@ -2037,7 +2039,8 @@ static NTSTATUS mh_get_nt_acl(vfs_handle_struct *handle, } status = SMB_VFS_NEXT_GET_NT_ACL(handle, clientPath, - security_info, ppdesc); + security_info, + mem_ctx, ppdesc); err: TALLOC_FREE(clientPath); out: diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c index 7c42052af73..1cf8e37ba4a 100644 --- a/source3/modules/vfs_shadow_copy2.c +++ b/source3/modules/vfs_shadow_copy2.c @@ -1188,6 +1188,7 @@ static int shadow_copy2_get_shadow_copy_data( static NTSTATUS shadow_copy2_fget_nt_acl(vfs_handle_struct *handle, struct files_struct *fsp, uint32 security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc) { time_t timestamp; @@ -1202,6 +1203,7 @@ static NTSTATUS shadow_copy2_fget_nt_acl(vfs_handle_struct *handle, } if (timestamp == 0) { return SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info, + mem_ctx, ppdesc); } conv = shadow_copy2_convert(talloc_tos(), handle, stripped, timestamp); @@ -1209,7 +1211,8 @@ static NTSTATUS shadow_copy2_fget_nt_acl(vfs_handle_struct *handle, if (conv == NULL) { return map_nt_error_from_unix(errno); } - status = SMB_VFS_NEXT_GET_NT_ACL(handle, conv, security_info, ppdesc); + status = SMB_VFS_NEXT_GET_NT_ACL(handle, conv, security_info, + mem_ctx, ppdesc); TALLOC_FREE(conv); return status; } @@ -1217,6 +1220,7 @@ static NTSTATUS shadow_copy2_fget_nt_acl(vfs_handle_struct *handle, static NTSTATUS shadow_copy2_get_nt_acl(vfs_handle_struct *handle, const char *fname, uint32 security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc) { time_t timestamp; @@ -1230,14 +1234,15 @@ static NTSTATUS shadow_copy2_get_nt_acl(vfs_handle_struct *handle, } if (timestamp == 0) { return SMB_VFS_NEXT_GET_NT_ACL(handle, fname, security_info, - ppdesc); + mem_ctx, ppdesc); } conv = shadow_copy2_convert(talloc_tos(), handle, stripped, timestamp); TALLOC_FREE(stripped); if (conv == NULL) { return map_nt_error_from_unix(errno); } - status = SMB_VFS_NEXT_GET_NT_ACL(handle, conv, security_info, ppdesc); + status = SMB_VFS_NEXT_GET_NT_ACL(handle, conv, security_info, + mem_ctx, ppdesc); TALLOC_FREE(conv); return status; } diff --git a/source3/modules/vfs_time_audit.c b/source3/modules/vfs_time_audit.c index b7d399b2631..6ff1a5571d9 100644 --- a/source3/modules/vfs_time_audit.c +++ b/source3/modules/vfs_time_audit.c @@ -1671,6 +1671,7 @@ static NTSTATUS smb_time_audit_translate_name(struct vfs_handle_struct *handle, static NTSTATUS smb_time_audit_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, uint32 security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc) { NTSTATUS result; @@ -1678,7 +1679,8 @@ static NTSTATUS smb_time_audit_fget_nt_acl(vfs_handle_struct *handle, double timediff; clock_gettime_mono(&ts1); - result = SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info, ppdesc); + result = SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info, + mem_ctx, ppdesc); clock_gettime_mono(&ts2); timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9; @@ -1692,6 +1694,7 @@ static NTSTATUS smb_time_audit_fget_nt_acl(vfs_handle_struct *handle, static NTSTATUS smb_time_audit_get_nt_acl(vfs_handle_struct *handle, const char *name, uint32 security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc) { NTSTATUS result; @@ -1699,7 +1702,8 @@ static NTSTATUS smb_time_audit_get_nt_acl(vfs_handle_struct *handle, double timediff; clock_gettime_mono(&ts1); - result = SMB_VFS_NEXT_GET_NT_ACL(handle, name, security_info, ppdesc); + result = SMB_VFS_NEXT_GET_NT_ACL(handle, name, security_info, + mem_ctx, ppdesc); clock_gettime_mono(&ts2); timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9; diff --git a/source3/modules/vfs_zfsacl.c b/source3/modules/vfs_zfsacl.c index 7858a6a4753..bf068814627 100644 --- a/source3/modules/vfs_zfsacl.c +++ b/source3/modules/vfs_zfsacl.c @@ -192,14 +192,16 @@ static NTSTATUS zfs_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, } static NTSTATUS zfsacl_fget_nt_acl(struct vfs_handle_struct *handle, - struct files_struct *fsp, - uint32 security_info, - struct security_descriptor **ppdesc) + struct files_struct *fsp, + uint32 security_info, + TALLOC_CTX *mem_ctx, + struct security_descriptor **ppdesc) { SMB4ACL_T *pacl; NTSTATUS status; - status = zfs_get_nt_acl_common(fsp->fsp_name->base_name, security_info, + status = zfs_get_nt_acl_common(fsp->fsp_name->base_name, + mem_ctx, security_info, &pacl); if (!NT_STATUS_IS_OK(status)) { return status; @@ -209,8 +211,9 @@ static NTSTATUS zfsacl_fget_nt_acl(struct vfs_handle_struct *handle, } static NTSTATUS zfsacl_get_nt_acl(struct vfs_handle_struct *handle, - const char *name, uint32 security_info, - struct security_descriptor **ppdesc) + const char *name, uint32 security_info, + TALLOC_CTX *mem_ctx, + struct security_descriptor **ppdesc) { SMB4ACL_T *pacl; NTSTATUS status; @@ -220,7 +223,8 @@ static NTSTATUS zfsacl_get_nt_acl(struct vfs_handle_struct *handle, return status; } - return smb_get_nt_acl_nfs4(handle->conn, name, security_info, ppdesc, + return smb_get_nt_acl_nfs4(handle->conn, name, security_info, + mem_ctx, ppdesc, pacl); } diff --git a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c index 982b0b479b3..0249ef56610 100644 --- a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c +++ b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c @@ -2185,15 +2185,22 @@ WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p, goto error_exit; } + sd_buf = talloc_zero(p->mem_ctx, struct sec_desc_buf); + if (!sd_buf) { + werr = WERR_NOMEM; + goto error_exit; + } + nt_status = SMB_VFS_FGET_NT_ACL(fsp, (SECINFO_OWNER |SECINFO_GROUP - |SECINFO_DACL), &psd); + |SECINFO_DACL), sd_buf, &sd_buf->sd); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL " "for file %s\n", smb_fname_str_dbg(smb_fname))); werr = ntstatus_to_werror(nt_status); + TALLOC_FREE(sd_buf); goto error_exit; } @@ -2203,14 +2210,7 @@ WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p, sd_size = ndr_size_security_descriptor(psd, 0); - sd_buf = talloc_zero(p->mem_ctx, struct sec_desc_buf); - if (!sd_buf) { - werr = WERR_NOMEM; - goto error_exit; - } - sd_buf->sd_size = sd_size; - sd_buf->sd = talloc_move(p->mem_ctx, &psd); *r->out.sd_buf = sd_buf; diff --git a/source3/smbd/file_access.c b/source3/smbd/file_access.c index 015679deb0b..0e74207b84d 100644 --- a/source3/smbd/file_access.c +++ b/source3/smbd/file_access.c @@ -151,11 +151,11 @@ bool can_write_to_file(connection_struct *conn, bool directory_has_default_acl(connection_struct *conn, const char *fname) { - /* returns talloced off tos. */ struct security_descriptor *secdesc = NULL; unsigned int i; NTSTATUS status = SMB_VFS_GET_NT_ACL(conn, fname, - SECINFO_DACL, &secdesc); + SECINFO_DACL, talloc_tos(), + &secdesc); if (!NT_STATUS_IS_OK(status) || secdesc == NULL || diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index 6848d10397f..1011bd7025d 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -1907,6 +1907,7 @@ NTSTATUS smbd_do_query_security_desc(connection_struct *conn, { NTSTATUS status; struct security_descriptor *psd = NULL; + TALLOC_CTX *frame = talloc_stackframe(); /* * Get the permissions to return. @@ -1932,13 +1933,13 @@ NTSTATUS smbd_do_query_security_desc(connection_struct *conn, } if (!lp_nt_acl_support(SNUM(conn))) { - status = get_null_nt_acl(mem_ctx, &psd); + status = get_null_nt_acl(frame, &psd); } else if (security_info_wanted & SECINFO_LABEL) { /* Like W2K3 return a null object. */ - status = get_null_nt_acl(mem_ctx, &psd); + status = get_null_nt_acl(frame, &psd); } else { status = SMB_VFS_FGET_NT_ACL( - fsp, security_info_wanted, &psd); + fsp, security_info_wanted, frame, &psd); } if (!NT_STATUS_IS_OK(status)) { return status; @@ -1989,7 +1990,7 @@ NTSTATUS smbd_do_query_security_desc(connection_struct *conn, } if (max_data_count < *psd_size) { - TALLOC_FREE(psd); + TALLOC_FREE(frame); return NT_STATUS_BUFFER_TOO_SMALL; } @@ -1997,11 +1998,11 @@ NTSTATUS smbd_do_query_security_desc(connection_struct *conn, ppmarshalled_sd, psd_size); if (!NT_STATUS_IS_OK(status)) { - TALLOC_FREE(psd); + TALLOC_FREE(frame); return status; } - TALLOC_FREE(psd); + TALLOC_FREE(frame); return NT_STATUS_OK; } diff --git a/source3/smbd/open.c b/source3/smbd/open.c index d4babd40f7d..efabe4a480e 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -115,7 +115,7 @@ NTSTATUS smbd_check_access_rights(struct connection_struct *conn, status = SMB_VFS_GET_NT_ACL(conn, smb_fname->base_name, (SECINFO_OWNER | SECINFO_GROUP | - SECINFO_DACL),&sd); + SECINFO_DACL), talloc_tos(), &sd); if (!NT_STATUS_IS_OK(status)) { DEBUG(10, ("smbd_check_access_rights: Could not get acl " @@ -237,6 +237,7 @@ static NTSTATUS check_parent_access(struct connection_struct *conn, status = SMB_VFS_GET_NT_ACL(conn, parent_dir, SECINFO_DACL, + talloc_tos(), &parent_sd); if (!NT_STATUS_IS_OK(status)) { @@ -1683,7 +1684,8 @@ static NTSTATUS smbd_calculate_maximum_allowed_access( status = SMB_VFS_GET_NT_ACL(conn, smb_fname->base_name, (SECINFO_OWNER | SECINFO_GROUP | - SECINFO_DACL),&sd); + SECINFO_DACL), + talloc_tos(), &sd); if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { /* @@ -3425,7 +3427,7 @@ NTSTATUS open_streams_for_delete(connection_struct *conn, static NTSTATUS inherit_new_acl(files_struct *fsp) { - TALLOC_CTX *ctx = talloc_tos(); + TALLOC_CTX *frame = talloc_stackframe(); char *parent_name = NULL; struct security_descriptor *parent_desc = NULL; NTSTATUS status = NT_STATUS_OK; @@ -3437,14 +3439,15 @@ static NTSTATUS inherit_new_acl(files_struct *fsp) bool inheritable_components = false; size_t size = 0; - if (!parent_dirname(ctx, fsp->fsp_name->base_name, &parent_name, NULL)) { + if (!parent_dirname(frame, fsp->fsp_name->base_name, &parent_name, NULL)) { return NT_STATUS_NO_MEMORY; } status = SMB_VFS_GET_NT_ACL(fsp->conn, - parent_name, - (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL), - &parent_desc); + parent_name, + (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL), + frame, + &parent_desc); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -3453,6 +3456,7 @@ static NTSTATUS inherit_new_acl(files_struct *fsp) fsp->is_directory); if (!inheritable_components && !inherit_owner) { + TALLOC_FREE(frame); /* Nothing to inherit and not setting owner. */ return NT_STATUS_OK; } @@ -3478,7 +3482,7 @@ static NTSTATUS inherit_new_acl(files_struct *fsp) group_sid = &fsp->conn->session_info->security_token->sids[PRIMARY_GROUP_SID_INDEX]; } - status = se_create_child_secdesc(ctx, + status = se_create_child_secdesc(frame, &psd, &size, parent_desc, @@ -3486,6 +3490,7 @@ static NTSTATUS inherit_new_acl(files_struct *fsp) group_sid, fsp->is_directory); if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); return status; } @@ -3516,6 +3521,7 @@ static NTSTATUS inherit_new_acl(files_struct *fsp) if (inherit_owner) { unbecome_root(); } + TALLOC_FREE(frame); return status; } diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index c535502efee..05cd2a740d0 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -3389,6 +3389,7 @@ static NTSTATUS posix_get_nt_acl_common(struct connection_struct *conn, SMB_ACL_T posix_acl, SMB_ACL_T def_acl, uint32_t security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc) { struct dom_sid owner_sid; @@ -3601,7 +3602,7 @@ static NTSTATUS posix_get_nt_acl_common(struct connection_struct *conn, } } /* security_info & SECINFO_DACL */ - psd = make_standard_sec_desc( talloc_tos(), + psd = make_standard_sec_desc(mem_ctx, (security_info & SECINFO_OWNER) ? &owner_sid : NULL, (security_info & SECINFO_GROUP) ? &group_sid : NULL, psa, @@ -3652,11 +3653,14 @@ static NTSTATUS posix_get_nt_acl_common(struct connection_struct *conn, } NTSTATUS posix_fget_nt_acl(struct files_struct *fsp, uint32_t security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc) { SMB_STRUCT_STAT sbuf; SMB_ACL_T posix_acl = NULL; struct pai_val *pal; + TALLOC_CTX *frame = talloc_stackframe(); + NTSTATUS status; *ppdesc = NULL; @@ -3665,33 +3669,42 @@ NTSTATUS posix_fget_nt_acl(struct files_struct *fsp, uint32_t security_info, /* can it happen that fsp_name == NULL ? */ if (fsp->is_directory || fsp->fh->fd == -1) { - return posix_get_nt_acl(fsp->conn, fsp->fsp_name->base_name, - security_info, ppdesc); + status = posix_get_nt_acl(fsp->conn, fsp->fsp_name->base_name, + security_info, mem_ctx, ppdesc); + TALLOC_FREE(frame); + return status; } /* Get the stat struct for the owner info. */ if(SMB_VFS_FSTAT(fsp, &sbuf) != 0) { + TALLOC_FREE(frame); return map_nt_error_from_unix(errno); } /* Get the ACL from the fd. */ - posix_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, talloc_tos()); + posix_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, frame); pal = fload_inherited_info(fsp); - return posix_get_nt_acl_common(fsp->conn, fsp->fsp_name->base_name, - &sbuf, pal, posix_acl, NULL, - security_info, ppdesc); + status = posix_get_nt_acl_common(fsp->conn, fsp->fsp_name->base_name, + &sbuf, pal, posix_acl, NULL, + security_info, mem_ctx, ppdesc); + TALLOC_FREE(frame); + return status; } NTSTATUS posix_get_nt_acl(struct connection_struct *conn, const char *name, - uint32_t security_info, struct security_descriptor **ppdesc) + uint32_t security_info, + TALLOC_CTX *mem_ctx, + struct security_descriptor **ppdesc) { SMB_ACL_T posix_acl = NULL; SMB_ACL_T def_acl = NULL; struct pai_val *pal; struct smb_filename smb_fname; int ret; + TALLOC_CTX *frame = talloc_stackframe(); + NTSTATUS status; *ppdesc = NULL; @@ -3708,26 +3721,29 @@ NTSTATUS posix_get_nt_acl(struct connection_struct *conn, const char *name, } if (ret == -1) { + TALLOC_FREE(frame); return map_nt_error_from_unix(errno); } /* Get the ACL from the path. */ posix_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, name, - SMB_ACL_TYPE_ACCESS, talloc_tos()); + SMB_ACL_TYPE_ACCESS, frame); /* If it's a directory get the default POSIX ACL. */ if(S_ISDIR(smb_fname.st.st_ex_mode)) { def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, name, - SMB_ACL_TYPE_DEFAULT, - talloc_tos()); + SMB_ACL_TYPE_DEFAULT, frame); def_acl = free_empty_sys_acl(conn, def_acl); } pal = load_inherited_info(conn, name); - return posix_get_nt_acl_common(conn, name, &smb_fname.st, pal, - posix_acl, def_acl, security_info, - ppdesc); + status = posix_get_nt_acl_common(conn, name, &smb_fname.st, pal, + posix_acl, def_acl, security_info, + mem_ctx, + ppdesc); + TALLOC_FREE(frame); + return status; } /**************************************************************************** @@ -4953,7 +4969,7 @@ bool set_unix_posix_acl(connection_struct *conn, files_struct *fsp, const char * struct security_descriptor *get_nt_acl_no_snum( TALLOC_CTX *ctx, const char *fname, uint32 security_info_wanted) { - struct security_descriptor *psd, *ret_sd; + struct security_descriptor *ret_sd; connection_struct *conn; files_struct finfo; struct fd_handle fh; @@ -4999,7 +5015,9 @@ struct security_descriptor *get_nt_acl_no_snum( TALLOC_CTX *ctx, const char *fna return NULL; } - if (!NT_STATUS_IS_OK(SMB_VFS_FGET_NT_ACL( &finfo, security_info_wanted, &psd))) { + if (!NT_STATUS_IS_OK(SMB_VFS_FGET_NT_ACL( &finfo, + security_info_wanted, + ctx, &ret_sd))) { DEBUG(0,("get_nt_acl_no_snum: get_nt_acl returned zero.\n")); TALLOC_FREE(finfo.fsp_name); conn_free(conn); @@ -5007,8 +5025,6 @@ struct security_descriptor *get_nt_acl_no_snum( TALLOC_CTX *ctx, const char *fna return NULL; } - ret_sd = dup_sec_desc( ctx, psd ); - TALLOC_FREE(finfo.fsp_name); conn_free(conn); TALLOC_FREE(frame); diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h index 143da491e0f..1e5883b0392 100644 --- a/source3/smbd/proto.h +++ b/source3/smbd/proto.h @@ -714,9 +714,12 @@ NTSTATUS unpack_nt_owners(connection_struct *conn, uid_t *puser, gid_t *pgrp, ui bool current_user_in_group(connection_struct *conn, gid_t gid); SMB_ACL_T free_empty_sys_acl(connection_struct *conn, SMB_ACL_T the_acl); NTSTATUS posix_fget_nt_acl(struct files_struct *fsp, uint32_t security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc); NTSTATUS posix_get_nt_acl(struct connection_struct *conn, const char *name, - uint32_t security_info, struct security_descriptor **ppdesc); + uint32_t security_info, + TALLOC_CTX *mem_ctx, + struct security_descriptor **ppdesc); NTSTATUS try_chown(files_struct *fsp, uid_t uid, gid_t gid); NTSTATUS append_parent_acl(files_struct *fsp, const struct security_descriptor *pcsd, diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index 182e334ade3..3a95c588c55 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -2165,20 +2165,22 @@ NTSTATUS smb_vfs_call_fsctl(struct vfs_handle_struct *handle, NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle, struct files_struct *fsp, uint32 security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc) { VFS_FIND(fget_nt_acl); return handle->fns->fget_nt_acl_fn(handle, fsp, security_info, - ppdesc); + mem_ctx, ppdesc); } NTSTATUS smb_vfs_call_get_nt_acl(struct vfs_handle_struct *handle, const char *name, uint32 security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc) { VFS_FIND(get_nt_acl); - return handle->fns->get_nt_acl_fn(handle, name, security_info, ppdesc); + return handle->fns->get_nt_acl_fn(handle, name, security_info, mem_ctx, ppdesc); } NTSTATUS smb_vfs_call_fset_nt_acl(struct vfs_handle_struct *handle, diff --git a/source3/torture/cmd_vfs.c b/source3/torture/cmd_vfs.c index 7755f8ac2af..a37c9fc7a7b 100644 --- a/source3/torture/cmd_vfs.c +++ b/source3/torture/cmd_vfs.c @@ -1374,7 +1374,9 @@ static NTSTATUS cmd_fget_nt_acl(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, return NT_STATUS_OK; } - status = SMB_VFS_FGET_NT_ACL(vfs->files[fd], SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL, &sd); + status = SMB_VFS_FGET_NT_ACL(vfs->files[fd], + SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL, + talloc_tos(), &sd); if (!NT_STATUS_IS_OK(status)) { printf("fget_nt_acl returned (%s)\n", nt_errstr(status)); return status; @@ -1395,7 +1397,9 @@ static NTSTATUS cmd_get_nt_acl(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, return NT_STATUS_OK; } - status = SMB_VFS_GET_NT_ACL(vfs->conn, argv[1], SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL, &sd); + status = SMB_VFS_GET_NT_ACL(vfs->conn, argv[1], + SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL, + talloc_tos(), &sd); if (!NT_STATUS_IS_OK(status)) { printf("get_nt_acl returned (%s)\n", nt_errstr(status)); return status; -- 2.34.1