From d2cf97aeba14a4d336fb57b01f19bd5a08dcb003 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 29 Nov 2007 13:24:54 -0800 Subject: Remove the explicit TALLOC_CTX * from cli_struct. Make us very explicit about how long a talloc ctx should last. Jeremy. (This used to be commit ba9e2be2b5a59684e854609f9d82ea1633448c62) --- source3/libsmb/cliconnect.c | 18 +++++++++--- source3/libsmb/clidfs.c | 9 ++++-- source3/libsmb/clientgen.c | 8 ------ source3/libsmb/clierror.c | 6 ++++ source3/libsmb/clioplock.c | 5 ++-- source3/libsmb/cliprint.c | 64 +++++++++++++++++++++---------------------- source3/libsmb/clirap.c | 2 +- source3/libsmb/libsmbclient.c | 28 ++++++++++++++----- source3/libsmb/passchange.c | 4 +-- 9 files changed, 85 insertions(+), 59 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index f0b03a85cf..e3800bfb33 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1803,13 +1803,18 @@ struct cli_state *get_ipc_connect(char *server, * entire network browse list) */ -struct cli_state *get_ipc_connect_master_ip(struct ip_service *mb_ip, pstring workgroup, struct user_auth_info *user_info) +struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx, + struct ip_service *mb_ip, + struct user_auth_info *user_info, + char **pp_workgroup_out) { char addr[INET6_ADDRSTRLEN]; fstring name; struct cli_state *cli; struct sockaddr_storage server_ss; + *pp_workgroup_out = NULL; + print_sockaddr(addr, sizeof(addr), &mb_ip->ss); DEBUG(99, ("Looking up name of master browser %s\n", addr)); @@ -1838,7 +1843,7 @@ struct cli_state *get_ipc_connect_master_ip(struct ip_service *mb_ip, pstring wo return NULL; } - pstrcpy(workgroup, name); + *pp_workgroup_out = talloc_strdup(ctx, name); DEBUG(4, ("found master browser %s, %s\n", name, addr)); @@ -1853,12 +1858,16 @@ struct cli_state *get_ipc_connect_master_ip(struct ip_service *mb_ip, pstring wo * connect to it. */ -struct cli_state *get_ipc_connect_master_ip_bcast(pstring workgroup, struct user_auth_info *user_info) +struct cli_state *get_ipc_connect_master_ip_bcast(TALLOC_CTX *ctx, + struct user_auth_info *user_info, + char **pp_workgroup_out) { struct ip_service *ip_list; struct cli_state *cli; int i, count; + *pp_workgroup_out = NULL; + DEBUG(99, ("Do broadcast lookup for workgroups on local network\n")); /* Go looking for workgroups by broadcasting on the local network */ @@ -1874,7 +1883,8 @@ struct cli_state *get_ipc_connect_master_ip_bcast(pstring workgroup, struct user print_sockaddr(addr, sizeof(addr), &ip_list[i].ss); DEBUG(99, ("Found master browser %s\n", addr)); - cli = get_ipc_connect_master_ip(&ip_list[i], workgroup, user_info); + cli = get_ipc_connect_master_ip(ctx, &ip_list[i], + user_info, pp_workgroup_out); if (cli) return(cli); } diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index 037c0d6b26..469cb231d2 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -245,9 +245,12 @@ static struct cli_state *cli_cm_connect( const char *server, bool show_hdr) { struct client_connection *node; - - node = SMB_XMALLOC_P( struct client_connection ); - + + node = SMB_CALLOC_ARRAY( struct client_connection, 1); + if (!node) { + return NULL; + } + node->cli = do_connect( server, share, show_hdr ); if ( !node->cli ) { diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index ee1a0fe3db..1a6fb8f93f 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -492,9 +492,6 @@ struct cli_state *cli_initialise(void) if (!cli->outbuf || !cli->inbuf) goto error; - if ((cli->mem_ctx = talloc_init("cli based talloc")) == NULL) - goto error; - memset(cli->outbuf, 0, cli->bufsize); memset(cli->inbuf, 0, cli->bufsize); @@ -605,11 +602,6 @@ void cli_shutdown(struct cli_state *cli) data_blob_free(&cli->secblob); data_blob_free(&cli->user_session_key); - if (cli->mem_ctx) { - talloc_destroy(cli->mem_ctx); - cli->mem_ctx = NULL; - } - if (cli->fd != -1) { close(cli->fd); } diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index c9c5a6cd30..587abade59 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -84,6 +84,8 @@ static NTSTATUS cli_smb_rw_error_to_ntstatus(struct cli_state *cli) return NT_STATUS_UNEXPECTED_NETWORK_ERROR; case SMB_READ_BAD_SIG: return NT_STATUS_INVALID_PARAMETER; + case SMB_NO_MEMORY: + return NT_STATUS_NO_MEMORY; default: break; } @@ -133,6 +135,10 @@ const char *cli_errstr(struct cli_state *cli) slprintf(cli_error_message, sizeof(cli_error_message) - 1, "Server packet had invalid SMB signature!"); break; + case SMB_NO_MEMORY: + slprintf(cli_error_message, sizeof(cli_error_message) - 1, + "Out of memory"); + break; default: slprintf(cli_error_message, sizeof(cli_error_message) - 1, "Unknown error code %d\n", cli->smb_rw_error ); diff --git a/source3/libsmb/clioplock.c b/source3/libsmb/clioplock.c index effd4a5565..2e54f5a781 100644 --- a/source3/libsmb/clioplock.c +++ b/source3/libsmb/clioplock.c @@ -22,10 +22,11 @@ /**************************************************************************** send an ack for an oplock break request ****************************************************************************/ + bool cli_oplock_ack(struct cli_state *cli, int fnum, unsigned char level) { char *oldbuf = cli->outbuf; - pstring buf; + char buf[smb_size+16]; bool ret; cli->outbuf = buf; @@ -47,7 +48,7 @@ bool cli_oplock_ack(struct cli_state *cli, int fnum, unsigned char level) SSVAL(buf,smb_vwv6,0); /* unlockcount */ SSVAL(buf,smb_vwv7,0); /* lockcount */ - ret = cli_send_smb(cli); + ret = cli_send_smb(cli); cli->outbuf = oldbuf; diff --git a/source3/libsmb/cliprint.c b/source3/libsmb/cliprint.c index cab890b08b..7fbdb97c01 100644 --- a/source3/libsmb/cliprint.c +++ b/source3/libsmb/cliprint.c @@ -1,18 +1,18 @@ -/* +/* Unix SMB/CIFS implementation. client print routines Copyright (C) Andrew Tridgell 1994-1998 - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -21,13 +21,14 @@ /***************************************************************************** Convert a character pointer in a cli_call_api() response to a form we can use. - This function contains code to prevent core dumps if the server returns + This function contains code to prevent core dumps if the server returns invalid data. *****************************************************************************/ -static const char *fix_char_ptr(unsigned int datap, unsigned int converter, +static const char *fix_char_ptr(unsigned int datap, unsigned int converter, char *rdata, int rdrcnt) { - if (datap == 0) { /* turn NULL pointers into zero length strings */ + if (datap == 0) { + /* turn NULL pointers into zero length strings */ return ""; } else { unsigned int offset = datap - converter; @@ -42,41 +43,41 @@ static const char *fix_char_ptr(unsigned int datap, unsigned int converter, } } - /**************************************************************************** call fn() on each entry in a print queue ****************************************************************************/ -int cli_print_queue(struct cli_state *cli, + +int cli_print_queue(struct cli_state *cli, void (*fn)(struct print_job_info *)) { char *rparam = NULL; char *rdata = NULL; char *p; unsigned int rdrcnt, rprcnt; - pstring param; + char param[1024]; int result_code=0; int i = -1; - + memset(param,'\0',sizeof(param)); p = param; SSVAL(p,0,76); /* API function number 76 (DosPrintJobEnum) */ p += 2; - pstrcpy_base(p,"zWrLeh", param); /* parameter description? */ + safe_strcpy_base(p,"zWrLeh", param, sizeof(param)); /* parameter description? */ p = skip_string(param,sizeof(param),p); - pstrcpy_base(p,"WWzWWDDzz", param); /* returned data format */ + safe_strcpy_base(p,"WWzWWDDzz", param, sizeof(param)); /* returned data format */ p = skip_string(param,sizeof(param),p); - pstrcpy_base(p,cli->share, param); /* name of queue */ + safe_strcpy_base(p,cli->share, param, sizeof(param)); /* name of queue */ p = skip_string(param,sizeof(param),p); SSVAL(p,0,2); /* API function level 2, PRJINFO_2 data structure */ SSVAL(p,2,1000); /* size of bytes of returned data buffer */ p += 4; - pstrcpy_base(p,"", param); /* subformat */ + safe_strcpy_base(p,"", param,sizeof(param)); /* subformat */ p = skip_string(param,sizeof(param),p); DEBUG(4,("doing cli_print_queue for %s\n", cli->share)); - if (cli_api(cli, + if (cli_api(cli, param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */ NULL, 0, CLI_BUFFER_SIZE, /* data, length, maxlen */ &rparam, &rprcnt, /* return params, length */ @@ -87,21 +88,21 @@ int cli_print_queue(struct cli_state *cli, if (result_code == 0) { struct print_job_info job; - - p = rdata; + + p = rdata; for (i = 0; i < SVAL(rparam,4); ++i) { job.id = SVAL(p,0); job.priority = SVAL(p,2); fstrcpy(job.user, - fix_char_ptr(SVAL(p,4), converter, + fix_char_ptr(SVAL(p,4), converter, rdata, rdrcnt)); job.t = cli_make_unix_date3(cli, p + 12); job.size = IVAL(p,16); - fstrcpy(job.name,fix_char_ptr(SVAL(p,24), - converter, + fstrcpy(job.name,fix_char_ptr(SVAL(p,24), + converter, rdata, rdrcnt)); - fn(&job); + fn(&job); p += 28; } } @@ -117,6 +118,7 @@ int cli_print_queue(struct cli_state *cli, /**************************************************************************** cancel a print job ****************************************************************************/ + int cli_printjob_del(struct cli_state *cli, int job) { char *rparam = NULL; @@ -124,21 +126,21 @@ int cli_printjob_del(struct cli_state *cli, int job) char *p; unsigned int rdrcnt,rprcnt; int ret = -1; - pstring param; + char param[1024]; memset(param,'\0',sizeof(param)); p = param; SSVAL(p,0,81); /* DosPrintJobDel() */ p += 2; - pstrcpy_base(p,"W", param); + safe_strcpy_base(p,"W", param,sizeof(param)); p = skip_string(param,sizeof(param),p); - pstrcpy_base(p,"", param); + safe_strcpy_base(p,"", param,sizeof(param)); p = skip_string(param,sizeof(param),p); - SSVAL(p,0,job); + SSVAL(p,0,job); p += 2; - - if (cli_api(cli, + + if (cli_api(cli, param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */ NULL, 0, CLI_BUFFER_SIZE, /* data, length, maxlen */ &rparam, &rprcnt, /* return params, length */ @@ -178,7 +180,7 @@ int cli_spl_open(struct cli_state *cli, const char *fname, int flags, int share_ accessmode |= 2; } else if ((flags & O_ACCMODE) == O_WRONLY) { accessmode |= 1; - } + } #if defined(O_SYNC) if ((flags & O_SYNC) == O_SYNC) { @@ -213,7 +215,7 @@ int cli_spl_open(struct cli_state *cli, const char *fname, int flags, int share_ FLAG_REQUEST_OPLOCK|FLAG_REQUEST_BATCH_OPLOCK); SSVAL(cli->outbuf,smb_vwv2,SVAL(cli->outbuf,smb_vwv2) | 6); } - + p = smb_buf(cli->outbuf); p += clistr_push(cli, p, fname, -1, STR_TERMINATE); @@ -256,5 +258,3 @@ bool cli_spl_close(struct cli_state *cli, int fnum) return !cli_is_error(cli); } - - diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 848a8d5482..c877dfa2ab 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -399,7 +399,7 @@ bool cli_qpathinfo(struct cli_state *cli, const char *fname, char *rparam=NULL, *rdata=NULL; int count=8; bool ret; - time_t (*date_fn)(struct cli_state *, void *); + time_t (*date_fn)(struct cli_state *, const void *); char *p; p = param; diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index ee560b65c3..4f2503731d 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -1008,7 +1008,7 @@ smbc_attr_server(SMBCCTX *context, nt_status = rpccli_lsa_open_policy( pipe_hnd, - ipc_srv->cli->mem_ctx, + talloc_tos(), True, GENERIC_EXECUTE_ACCESS, pol); @@ -1964,7 +1964,7 @@ smbc_lseek_ctx(SMBCCTX *context, fstring server, share, user, password; pstring path, targetpath; struct cli_state *targetcli; - TALLOC_CTX *frame = talloc_tos(); + TALLOC_CTX *frame = talloc_stackframe(); if (!context || !context->internal || !context->internal->_initialized) { @@ -2767,18 +2767,23 @@ smbc_opendir_ctx(SMBCCTX *context, for (i = 0; i < count && i < max_lmb_count; i++) { char addr[INET6_ADDRSTRLEN]; + char *wg_ptr = NULL; + print_sockaddr(addr, sizeof(addr), &ip_list[i].ss); DEBUG(99, ("Found master browser %d of %d: %s\n", i+1, MAX(count, max_lmb_count), addr)); - cli = get_ipc_connect_master_ip(&ip_list[i], - workgroup, &u_info); + cli = get_ipc_connect_master_ip(talloc_tos(), + &ip_list[i], + &u_info, + &wg_ptr); /* cli == NULL is the master browser refused to talk or could not be found */ if ( !cli ) continue; + pstrcpy(workgroup, wg_ptr); fstrcpy(server, cli->desthost); cli_shutdown(cli); @@ -3089,7 +3094,7 @@ static int smbc_closedir_ctx(SMBCCTX *context, SMBCFILE *dir) { - TALLOC_CTX *frame = talloc_tos(); + TALLOC_CTX *frame = talloc_stackframe(); if (!context || !context->internal || !context->internal->_initialized) { @@ -4025,6 +4030,8 @@ convert_sid_to_string(struct cli_state *ipc_cli, char **names = NULL; enum lsa_SidType *types = NULL; struct rpc_pipe_client *pipe_hnd = find_lsa_pipe_hnd(ipc_cli); + TALLOC_CTX *ctx; + sid_to_string(str, sid); if (numeric) { @@ -4037,13 +4044,17 @@ convert_sid_to_string(struct cli_state *ipc_cli, /* Ask LSA to convert the sid to a name */ - if (!NT_STATUS_IS_OK(rpccli_lsa_lookup_sids(pipe_hnd, ipc_cli->mem_ctx, + ctx = talloc_stackframe(); + + if (!NT_STATUS_IS_OK(rpccli_lsa_lookup_sids(pipe_hnd, ctx, pol, 1, sid, &domains, &names, &types)) || !domains || !domains[0] || !names || !names[0]) { + TALLOC_FREE(ctx); return; } + TALLOC_FREE(ctx); /* Converted OK */ slprintf(str, sizeof(fstring) - 1, "%s%s%s", @@ -4062,6 +4073,7 @@ convert_string_to_sid(struct cli_state *ipc_cli, enum lsa_SidType *types = NULL; DOM_SID *sids = NULL; bool result = True; + TALLOC_CTX *ctx; struct rpc_pipe_client *pipe_hnd = find_lsa_pipe_hnd(ipc_cli); if (!pipe_hnd) { @@ -4077,7 +4089,8 @@ convert_string_to_sid(struct cli_state *ipc_cli, goto done; } - if (!NT_STATUS_IS_OK(rpccli_lsa_lookup_names(pipe_hnd, ipc_cli->mem_ctx, + ctx = talloc_stackframe(); + if (!NT_STATUS_IS_OK(rpccli_lsa_lookup_names(pipe_hnd, ctx, pol, 1, &str, NULL, 1, &sids, &types))) { result = False; @@ -4087,6 +4100,7 @@ convert_string_to_sid(struct cli_state *ipc_cli, sid_copy(sid, &sids[0]); done: + TALLOC_FREE(ctx); return result; } diff --git a/source3/libsmb/passchange.c b/source3/libsmb/passchange.c index 9941b728ae..468750f801 100644 --- a/source3/libsmb/passchange.c +++ b/source3/libsmb/passchange.c @@ -177,7 +177,7 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam } } - if (NT_STATUS_IS_OK(result = rpccli_samr_chgpasswd_user(pipe_hnd, cli->mem_ctx, user_name, + if (NT_STATUS_IS_OK(result = rpccli_samr_chgpasswd_user(pipe_hnd, pipe_hnd->mem_ctx, user_name, new_passwd, old_passwd))) { /* Great - it all worked! */ cli_shutdown(cli); @@ -207,7 +207,7 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam if ( pipe_hnd && (NT_STATUS_IS_OK(result = rpccli_samr_chgpasswd_user(pipe_hnd, - cli->mem_ctx, + pipe_hnd->mem_ctx, user_name, new_passwd, old_passwd)))) { -- cgit