X-Git-Url: http://git.samba.org/samba.git/?p=jelmer%2Fsamba4-debian.git;a=blobdiff_plain;f=source%2Flibcli%2Fraw%2Fclitransport.c;h=62c32d305845908c9780278bd6845b322bad8131;hp=641ad38031057310c4cb869c58120371088c5d60;hb=8a97886e24a4b969aa91409c06f423b71a45f6eb;hpb=49b96ac44a883c020c69df7a12df154dc4faa4d5 diff --git a/source/libcli/raw/clitransport.c b/source/libcli/raw/clitransport.c index 641ad3803..62c32d305 100644 --- a/source/libcli/raw/clitransport.c +++ b/source/libcli/raw/clitransport.c @@ -7,7 +7,7 @@ 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 2 of the License, or + 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, @@ -16,17 +16,17 @@ 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, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" #include "libcli/raw/libcliraw.h" #include "lib/socket/socket.h" -#include "dlinklist.h" +#include "lib/util/dlinklist.h" #include "lib/events/events.h" #include "lib/stream/packet.h" #include "librpc/gen_ndr/ndr_nbt.h" +#include "param/param.h" /* @@ -72,7 +72,9 @@ static NTSTATUS smbcli_transport_finish_recv(void *private, DATA_BLOB blob); create a transport structure based on an established socket */ struct smbcli_transport *smbcli_transport_init(struct smbcli_socket *sock, - TALLOC_CTX *parent_ctx, BOOL primary) + TALLOC_CTX *parent_ctx, + bool primary, + struct smbcli_options *options) { struct smbcli_transport *transport; @@ -85,11 +87,7 @@ struct smbcli_transport *smbcli_transport_init(struct smbcli_socket *sock, transport->socket = talloc_reference(transport, sock); } transport->negotiate.protocol = PROTOCOL_NT1; - transport->options.use_spnego = lp_use_spnego() && lp_nt_status_support(); - transport->options.max_xmit = lp_max_xmit(); - transport->options.max_mux = lp_maxmux(); - transport->options.request_timeout = SMB_REQUEST_TIMEOUT; - + transport->options = *options; transport->negotiate.max_xmit = transport->options.max_xmit; /* setup the stream -> packet parser */ @@ -138,8 +136,11 @@ void smbcli_transport_dead(struct smbcli_transport *transport, NTSTATUS status) status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; } - /* kill all pending receives */ - while (transport->pending_recv) { + /* kill only the first pending receive - this is so that if + that async function frees the connection we don't die trying + to use old memory. The caller has to cope with only one + network error */ + if (transport->pending_recv) { struct smbcli_request *req = transport->pending_recv; req->state = SMBCLI_REQUEST_ERROR; req->status = status; @@ -257,7 +258,7 @@ NTSTATUS smbcli_transport_connect_recv(struct smbcli_request *req) /* send a session request (if needed) */ -BOOL smbcli_transport_connect(struct smbcli_transport *transport, +bool smbcli_transport_connect(struct smbcli_transport *transport, struct nbt_name *calling, struct nbt_name *called) { @@ -265,7 +266,7 @@ BOOL smbcli_transport_connect(struct smbcli_transport *transport, NTSTATUS status; if (transport->socket->port == 445) { - return True; + return true; } req = smbcli_transport_connect_send(transport, @@ -496,16 +497,16 @@ error: /* process some read/write requests that are pending - return False if the socket is dead + return false if the socket is dead */ -BOOL smbcli_transport_process(struct smbcli_transport *transport) +bool smbcli_transport_process(struct smbcli_transport *transport) { NTSTATUS status; size_t npending; packet_queue_run(transport->packet); if (transport->socket->sock == NULL) { - return False; + return false; } status = socket_pending(transport->socket->sock, &npending); @@ -513,9 +514,9 @@ BOOL smbcli_transport_process(struct smbcli_transport *transport) packet_recv(transport->packet); } if (transport->socket->sock == NULL) { - return False; + return false; } - return True; + return true; } /* @@ -590,3 +591,71 @@ void smbcli_transport_send(struct smbcli_request *req) talloc_set_destructor(req, smbcli_request_destructor); } + + +/**************************************************************************** + Send an SMBecho (async send) +*****************************************************************************/ +struct smbcli_request *smb_raw_echo_send(struct smbcli_transport *transport, + struct smb_echo *p) +{ + struct smbcli_request *req; + + req = smbcli_request_setup_transport(transport, SMBecho, 1, p->in.size); + if (!req) return NULL; + + SSVAL(req->out.vwv, VWV(0), p->in.repeat_count); + + memcpy(req->out.data, p->in.data, p->in.size); + + ZERO_STRUCT(p->out); + + if (!smbcli_request_send(req)) { + smbcli_request_destroy(req); + return NULL; + } + + return req; +} + +/**************************************************************************** + raw echo interface (async recv) +****************************************************************************/ +NTSTATUS smb_raw_echo_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, + struct smb_echo *p) +{ + if (!smbcli_request_receive(req) || + smbcli_request_is_error(req)) { + goto failed; + } + + SMBCLI_CHECK_WCT(req, 1); + p->out.count++; + p->out.sequence_number = SVAL(req->in.vwv, VWV(0)); + p->out.size = req->in.data_size; + talloc_free(p->out.data); + p->out.data = talloc_array(mem_ctx, uint8_t, p->out.size); + NT_STATUS_HAVE_NO_MEMORY(p->out.data); + + if (!smbcli_raw_pull_data(req, req->in.data, p->out.size, p->out.data)) { + req->status = NT_STATUS_BUFFER_TOO_SMALL; + } + + if (p->out.count == p->in.repeat_count) { + return smbcli_request_destroy(req); + } + + return NT_STATUS_OK; + +failed: + return smbcli_request_destroy(req); +} + +/**************************************************************************** + Send a echo (sync interface) +*****************************************************************************/ +NTSTATUS smb_raw_echo(struct smbcli_transport *transport, struct smb_echo *p) +{ + struct smbcli_request *req = smb_raw_echo_send(transport, p); + return smbcli_request_simple_recv(req); +}