diff options
author | Andrew Bartlett <abartlet@samba.org> | 2012-10-10 11:50:27 +1100 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2012-10-11 12:25:11 +1100 |
commit | c8ade07760ae0ccfdf2d875c9f3027926e62321b (patch) | |
tree | abac36ce81b1e0737bfeb607699a41773beb958e /source3/smbd | |
parent | 9158974540d0e311021f04789ed75ebda466c5b3 (diff) | |
download | samba-c8ade07760ae0ccfdf2d875c9f3027926e62321b.tar.gz samba-c8ade07760ae0ccfdf2d875c9f3027926e62321b.tar.bz2 samba-c8ade07760ae0ccfdf2d875c9f3027926e62321b.zip |
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
Diffstat (limited to 'source3/smbd')
-rw-r--r-- | source3/smbd/file_access.c | 4 | ||||
-rw-r--r-- | source3/smbd/nttrans.c | 13 | ||||
-rw-r--r-- | source3/smbd/open.c | 22 | ||||
-rw-r--r-- | source3/smbd/posix_acls.c | 52 | ||||
-rw-r--r-- | source3/smbd/proto.h | 5 | ||||
-rw-r--r-- | source3/smbd/vfs.c | 6 |
6 files changed, 65 insertions, 37 deletions
diff --git a/source3/smbd/file_access.c b/source3/smbd/file_access.c index 015679deb0..0e74207b84 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 6848d10397..1011bd7025 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 d4babd40f7..efabe4a480 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 c535502efe..05cd2a740d 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 143da491e0..1e5883b039 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 182e334ade..3a95c588c5 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, |