[SCM] Samba Shared Repository - branch master updated

Stefan Metzmacher metze at samba.org
Tue Nov 29 09:35:05 MST 2011


The branch, master has been updated
       via  6b5cfa3 s4:libcli/raw: copy smbcli_transport_connect_* to clisocket.c
       via  b3d3395 s4:libcli/raw: add transport->ev as copy of transport->socket->event.ctx
       via  511dc93 s4:torture: use tctx->ev as event context for polling
       via  13dbef2 smbXcli: add support for SMBreadBraw
       via  e450c45 smbXcli: add smb1cli_conn_server_{readbraw,writebraw,lockread,writeunlock}()
       via  46f0b73 s4:gentest: get the tid from the smbcli_tree struct
       via  04fa5b4 s4:libcli/smb2: make sure only one idle event runs at a time
       via  51a7201 smb1cli_trans: add support for tevent_req_cancel()
       via  524d066 smb1cli_trans: return the status from the server if possible
       via  f0d8038 smbXcli: rebuild smb1.recv_iov array if we expect more than one response
       via  8c7e7ee smbXcli: allow up to 10 iovec elements for the bytes in smb1cli_req_create()
       via  3453665 smbXcli: s/smb2cli_writev_done/smb2cli_req_writev_done
       via  c9ca3bb smbXcli: call tevent_queue_stop() for the outgoing queue on disconnect
       via  91cb09f smbXcli: use talloc_stackframe() instead of talloc_tos() in smb1cli_conn_signv()
       via  9f6454a libcli/smb: remove unused smb_signing_set_bsrspyl() prototype
      from  023558a s3-passdb: make pdb_password_change_time_max static.

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 6b5cfa39f252c7272f3cef0a00d6a5d01db81024
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Nov 29 12:21:48 2011 +0100

    s4:libcli/raw: copy smbcli_transport_connect_* to clisocket.c
    
    metze
    
    Autobuild-User: Stefan Metzmacher <metze at samba.org>
    Autobuild-Date: Tue Nov 29 17:34:52 CET 2011 on sn-devel-104

commit b3d3395e01a015b440a84878c4d540dbaa437a32
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Nov 22 09:36:30 2011 +0100

    s4:libcli/raw: add transport->ev as copy of transport->socket->event.ctx
    
    We'll remove transport->socket soon, but removing transport->ev
    will take a bit longer.
    
    metze

commit 511dc9358d8954f9ef04c01fb7cc3f776625c1f2
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Sep 22 21:30:13 2011 +0200

    s4:torture: use tctx->ev as event context for polling
    
    metze

commit 13dbef241b24d54c7e8793ff81090614393d76ad
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Nov 25 14:49:24 2011 +0100

    smbXcli: add support for SMBreadBraw
    
    metze

commit e450c45e6738900daf9a1800bd6998268fb7d6d6
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Nov 25 15:13:38 2011 +0100

    smbXcli: add smb1cli_conn_server_{readbraw,writebraw,lockread,writeunlock}()
    
    metze

commit 46f0b73c8a1fd372299fae5618d2e67f09e3f5e0
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Nov 28 20:46:19 2011 +0100

    s4:gentest: get the tid from the smbcli_tree struct
    
    metze

commit 04fa5b4957d4d668be612ded509d6d6c8070d270
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Nov 22 10:10:30 2011 +0100

    s4:libcli/smb2: make sure only one idle event runs at a time
    
    metze

commit 51a7201a12856a11695ecb1b769c31fedf984e9c
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Nov 28 10:41:25 2011 +0100

    smb1cli_trans: add support for tevent_req_cancel()
    
    metze

commit 524d06615fd1b28f8cef14f6b7e083c4b24cae13
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Nov 28 09:15:11 2011 +0100

    smb1cli_trans: return the status from the server if possible
    
    metze

commit f0d8038ed8030655223fc03251dbd2245b7ec402
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Nov 28 17:48:44 2011 +0100

    smbXcli: rebuild smb1.recv_iov array if we expect more than one response
    
    metze

commit 8c7e7ee91beda577ec6a9acf36a856a3dadb30c6
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Nov 28 15:28:31 2011 +0100

    smbXcli: allow up to 10 iovec elements for the bytes in smb1cli_req_create()
    
    The smb1cli_trans_* code uses up to 6 elements, which was too much for
    the current limit of 5.
    
    metze

commit 3453665bcb408e2961920d156353ae45402d682f
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Nov 28 10:24:18 2011 +0100

    smbXcli: s/smb2cli_writev_done/smb2cli_req_writev_done
    
    This is a better name and it matches smb1cli_req_writev_done
    
    metze

commit c9ca3bb4921882634058ee203205aa72b30fb4a7
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Nov 28 10:23:23 2011 +0100

    smbXcli: call tevent_queue_stop() for the outgoing queue on disconnect
    
    metze

commit 91cb09fa0cdcdd04b2779736dd9855a5572bd0b4
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Nov 25 13:12:35 2011 +0100

    smbXcli: use talloc_stackframe() instead of talloc_tos() in smb1cli_conn_signv()
    
    metze

commit 9f6454af3927033d9bf1ed9e4f6cb1d748f24220
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Nov 23 08:47:31 2011 +0100

    libcli/smb: remove unused smb_signing_set_bsrspyl() prototype
    
    metze

-----------------------------------------------------------------------

Summary of changes:
 libcli/smb/smb1cli_trans.c               |   33 ++++++++-
 libcli/smb/smbXcli_base.c                |  127 +++++++++++++++++++++++++++---
 libcli/smb/smbXcli_base.h                |    4 +
 libcli/smb/smb_signing.h                 |    1 -
 source4/libcli/raw/clisocket.c           |  123 +++++++++++++++++++++++++++++
 source4/libcli/raw/clitransport.c        |  125 +-----------------------------
 source4/libcli/raw/libcliraw.h           |    2 +
 source4/libcli/raw/rawrequest.c          |    2 +-
 source4/libcli/smb2/smb2.h               |    1 +
 source4/libcli/smb2/transport.c          |   25 ++++--
 source4/libcli/smb_composite/appendacl.c |    2 +-
 source4/libcli/smb_composite/loadfile.c  |    2 +-
 source4/libcli/smb_composite/savefile.c  |    2 +-
 source4/libcli/smb_composite/sesssetup.c |    2 +-
 source4/libcli/util/clilsa.c             |    2 +-
 source4/torture/basic/base.c             |    2 +-
 source4/torture/gentest.c                |    6 +-
 source4/torture/raw/composite.c          |    4 +-
 source4/torture/raw/oplock.c             |    3 +-
 source4/torture/raw/qfileinfo.c          |    2 +-
 source4/torture/raw/samba3misc.c         |    5 +-
 source4/torture/rpc/samba3rpc.c          |   20 ++---
 22 files changed, 317 insertions(+), 178 deletions(-)


Changeset truncated at 500 lines:

diff --git a/libcli/smb/smb1cli_trans.c b/libcli/smb/smb1cli_trans.c
index 791c440..fadac8e 100644
--- a/libcli/smb/smb1cli_trans.c
+++ b/libcli/smb/smb1cli_trans.c
@@ -65,6 +65,8 @@ struct smb1cli_trans_state {
 	uint8_t zero_pad[4];
 	uint16_t vwv[32];
 
+	NTSTATUS status;
+
 	struct tevent_req *primary_subreq;
 };
 
@@ -404,6 +406,7 @@ static void smb1cli_trans_format(struct smb1cli_trans_state *state,
 	*piov_count = iov - state->iov;
 }
 
+static bool smb1cli_trans_cancel(struct tevent_req *req);
 static void smb1cli_trans_done(struct tevent_req *subreq);
 
 struct tevent_req *smb1cli_trans_send(
@@ -534,9 +537,24 @@ struct tevent_req *smb1cli_trans_send(
 	state->primary_subreq = subreq;
 	talloc_set_destructor(state, smb1cli_trans_state_destructor);
 
+	tevent_req_set_cancel_fn(req, smb1cli_trans_cancel);
+
 	return req;
 }
 
+static bool smb1cli_trans_cancel(struct tevent_req *req)
+{
+	struct smb1cli_trans_state *state =
+		tevent_req_data(req,
+		struct smb1cli_trans_state);
+
+	if (state->primary_subreq == NULL) {
+		return false;
+	}
+
+	return tevent_req_cancel(state->primary_subreq);
+}
+
 static void smb1cli_trans_done2(struct tevent_req *subreq);
 
 static void smb1cli_trans_done(struct tevent_req *subreq)
@@ -593,6 +611,12 @@ static void smb1cli_trans_done(struct tevent_req *subreq)
 		goto fail;
 	}
 
+	if (recv_iov == NULL) {
+		status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+		goto fail;
+	}
+	state->status = status;
+
 	sent_all = ((state->param_sent == state->num_param)
 		    && (state->data_sent == state->num_data));
 
@@ -767,12 +791,17 @@ NTSTATUS smb1cli_trans_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
 	smb1cli_trans_cleanup_primary(state);
 
 	if (tevent_req_is_nterror(req, &status)) {
+		if (!NT_STATUS_IS_ERR(status)) {
+			status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+		}
+		tevent_req_received(req);
 		return status;
 	}
 
 	if ((state->num_rsetup < min_setup)
 	    || (state->rparam.total < min_param)
 	    || (state->rdata.total < min_data)) {
+		tevent_req_received(req);
 		return NT_STATUS_INVALID_NETWORK_RESPONSE;
 	}
 
@@ -801,7 +830,9 @@ NTSTATUS smb1cli_trans_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
 		TALLOC_FREE(state->rdata.data);
 	}
 
-	return NT_STATUS_OK;
+	status = state->status;
+	tevent_req_received(req);
+	return status;
 }
 
 NTSTATUS smb1cli_trans(TALLOC_CTX *mem_ctx, struct smbXcli_conn *conn,
diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c
index 16f594b..6aa30ba 100644
--- a/libcli/smb/smbXcli_base.c
+++ b/libcli/smb/smbXcli_base.c
@@ -96,6 +96,8 @@ struct smbXcli_conn {
 
 		struct smb_signing_state *signing;
 		struct smb_trans_enc_state *trans_enc;
+
+		struct tevent_req *read_braw_req;
 	} smb1;
 
 	struct {
@@ -164,7 +166,7 @@ struct smbXcli_req_state {
 		uint16_t *vwv;
 		uint8_t bytecount_buf[2];
 
-#define MAX_SMB_IOV 5
+#define MAX_SMB_IOV 10
 		/* length_hdr, hdr, words, byte_count, buffers */
 		struct iovec iov[1 + 3 + MAX_SMB_IOV];
 		int iov_count;
@@ -447,6 +449,26 @@ uint16_t smb1cli_conn_server_security_mode(struct smbXcli_conn *conn)
 	return conn->smb1.server.security_mode;
 }
 
+bool smb1cli_conn_server_readbraw(struct smbXcli_conn *conn)
+{
+	return conn->smb1.server.readbraw;
+}
+
+bool smb1cli_conn_server_writebraw(struct smbXcli_conn *conn)
+{
+	return conn->smb1.server.writebraw;
+}
+
+bool smb1cli_conn_server_lockread(struct smbXcli_conn *conn)
+{
+	return conn->smb1.server.lockread;
+}
+
+bool smb1cli_conn_server_writeunlock(struct smbXcli_conn *conn)
+{
+	return conn->smb1.server.writeunlock;
+}
+
 int smb1cli_conn_server_time_zone(struct smbXcli_conn *conn)
 {
 	return conn->smb1.server.time_zone;
@@ -743,6 +765,8 @@ static bool smbXcli_conn_receive_next(struct smbXcli_conn *conn)
 
 void smbXcli_conn_disconnect(struct smbXcli_conn *conn, NTSTATUS status)
 {
+	tevent_queue_stop(conn->outgoing);
+
 	if (conn->read_fd != -1) {
 		close(conn->read_fd);
 	}
@@ -1118,6 +1142,7 @@ static NTSTATUS smb1cli_conn_signv(struct smbXcli_conn *conn,
 				   uint32_t *seqnum,
 				   bool one_way_seqnum)
 {
+	TALLOC_CTX *frame = NULL;
 	uint8_t *buf;
 
 	/*
@@ -1141,7 +1166,9 @@ static NTSTATUS smb1cli_conn_signv(struct smbXcli_conn *conn,
 		return NT_STATUS_INVALID_PARAMETER_MIX;
 	}
 
-	buf = smbXcli_iov_concat(talloc_tos(), iov, iov_count);
+	frame = talloc_stackframe();
+
+	buf = smbXcli_iov_concat(frame, iov, iov_count);
 	if (buf == NULL) {
 		return NT_STATUS_NO_MEMORY;
 	}
@@ -1151,7 +1178,7 @@ static NTSTATUS smb1cli_conn_signv(struct smbXcli_conn *conn,
 	smb_signing_sign_pdu(conn->smb1.signing, buf, *seqnum);
 	memcpy(iov[1].iov_base, buf+4, iov[1].iov_len);
 
-	TALLOC_FREE(buf);
+	TALLOC_FREE(frame);
 	return NT_STATUS_OK;
 }
 
@@ -1166,6 +1193,7 @@ static NTSTATUS smb1cli_req_writev_submit(struct tevent_req *req,
 {
 	struct tevent_req *subreq;
 	NTSTATUS status;
+	uint8_t cmd;
 	uint16_t mid;
 
 	if (!smbXcli_conn_is_connected(state->conn)) {
@@ -1192,6 +1220,14 @@ static NTSTATUS smb1cli_req_writev_submit(struct tevent_req *req,
 		return NT_STATUS_INVALID_PARAMETER_MIX;
 	}
 
+	cmd = CVAL(iov[1].iov_base, HDR_COM);
+	if (cmd == SMBreadBraw) {
+		if (smbXcli_conn_has_async_calls(state->conn)) {
+			return NT_STATUS_INVALID_PARAMETER_MIX;
+		}
+		state->conn->smb1.read_braw_req = req;
+	}
+
 	if (state->smb1.mid != 0) {
 		mid = state->smb1.mid;
 	} else {
@@ -1576,6 +1612,40 @@ static NTSTATUS smb1cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
 	size_t num_chained = 0;
 	size_t num_responses = 0;
 
+	if (conn->smb1.read_braw_req != NULL) {
+		req = conn->smb1.read_braw_req;
+		conn->smb1.read_braw_req = NULL;
+		state = tevent_req_data(req, struct smbXcli_req_state);
+
+		smbXcli_req_unset_pending(req);
+
+		if (state->smb1.recv_iov == NULL) {
+			/*
+			 * For requests with more than
+			 * one response, we have to readd the
+			 * recv_iov array.
+			 */
+			state->smb1.recv_iov = talloc_zero_array(state,
+								 struct iovec,
+								 3);
+			if (tevent_req_nomem(state->smb1.recv_iov, req)) {
+				return NT_STATUS_OK;
+			}
+		}
+
+		state->smb1.recv_iov[0].iov_base = (void *)(inbuf + NBT_HDR_SIZE);
+		state->smb1.recv_iov[0].iov_len = smb_len_nbt(inbuf);
+		ZERO_STRUCT(state->smb1.recv_iov[1]);
+		ZERO_STRUCT(state->smb1.recv_iov[2]);
+
+		state->smb1.recv_cmd = SMBreadBraw;
+		state->smb1.recv_status = NT_STATUS_OK;
+		state->inbuf = talloc_move(state->smb1.recv_iov, &inbuf);
+
+		tevent_req_done(req);
+		return NT_STATUS_OK;
+	}
+
 	if ((IVAL(inhdr, 0) != SMB_MAGIC) /* 0xFF"SMB" */
 	    && (SVAL(inhdr, 0) != 0x45ff)) /* 0xFF"E" */ {
 		DEBUG(10, ("Got non-SMB PDU\n"));
@@ -1672,6 +1742,20 @@ static NTSTATUS smb1cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
 
 		smbXcli_req_unset_pending(req);
 
+		if (state->smb1.recv_iov == NULL) {
+			/*
+			 * For requests with more than
+			 * one response, we have to readd the
+			 * recv_iov array.
+			 */
+			state->smb1.recv_iov = talloc_zero_array(state,
+								 struct iovec,
+								 3);
+			if (tevent_req_nomem(state->smb1.recv_iov, req)) {
+				return NT_STATUS_OK;
+			}
+		}
+
 		state->smb1.recv_cmd = cmd;
 		state->smb1.recv_status = status;
 		state->inbuf = talloc_move(state->smb1.recv_iov, &inbuf);
@@ -1720,6 +1804,20 @@ static NTSTATUS smb1cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
 			continue;
 		}
 
+		if (state->smb1.recv_iov == NULL) {
+			/*
+			 * For requests with more than
+			 * one response, we have to readd the
+			 * recv_iov array.
+			 */
+			state->smb1.recv_iov = talloc_zero_array(state,
+								 struct iovec,
+								 3);
+			if (tevent_req_nomem(state->smb1.recv_iov, req)) {
+				continue;
+			}
+		}
+
 		state->smb1.recv_cmd = cmd;
 
 		if (i == (num_responses - 1)) {
@@ -1814,13 +1912,16 @@ NTSTATUS smb1cli_req_recv(struct tevent_req *req,
 
 	if (state->inbuf != NULL) {
 		recv_iov = state->smb1.recv_iov;
-		hdr = (uint8_t *)recv_iov[0].iov_base;
-		wct = recv_iov[1].iov_len/2;
-		vwv = (uint16_t *)recv_iov[1].iov_base;
-		vwv_offset = PTR_DIFF(vwv, hdr);
-		num_bytes = recv_iov[2].iov_len;
-		bytes = (uint8_t *)recv_iov[2].iov_base;
-		bytes_offset = PTR_DIFF(bytes, hdr);
+		state->smb1.recv_iov = NULL;
+		if (state->smb1.recv_cmd != SMBreadBraw) {
+			hdr = (uint8_t *)recv_iov[0].iov_base;
+			wct = recv_iov[1].iov_len/2;
+			vwv = (uint16_t *)recv_iov[1].iov_base;
+			vwv_offset = PTR_DIFF(vwv, hdr);
+			num_bytes = recv_iov[2].iov_len;
+			bytes = (uint8_t *)recv_iov[2].iov_base;
+			bytes_offset = PTR_DIFF(bytes, hdr);
+		}
 	}
 
 	if (tevent_req_is_nterror(req, &status)) {
@@ -2261,7 +2362,7 @@ void smb2cli_req_set_notify_async(struct tevent_req *req)
 	state->smb2.notify_async = true;
 }
 
-static void smb2cli_writev_done(struct tevent_req *subreq);
+static void smb2cli_req_writev_done(struct tevent_req *subreq);
 static NTSTATUS smb2cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
 					       TALLOC_CTX *tmp_mem,
 					       uint8_t *inbuf);
@@ -2425,7 +2526,7 @@ skip_credits:
 	if (subreq == NULL) {
 		return NT_STATUS_NO_MEMORY;
 	}
-	tevent_req_set_callback(subreq, smb2cli_writev_done, reqs[0]);
+	tevent_req_set_callback(subreq, smb2cli_req_writev_done, reqs[0]);
 	return NT_STATUS_OK;
 }
 
@@ -2474,7 +2575,7 @@ struct tevent_req *smb2cli_req_send(TALLOC_CTX *mem_ctx,
 	return req;
 }
 
-static void smb2cli_writev_done(struct tevent_req *subreq)
+static void smb2cli_req_writev_done(struct tevent_req *subreq)
 {
 	struct tevent_req *req =
 		tevent_req_callback_data(subreq,
diff --git a/libcli/smb/smbXcli_base.h b/libcli/smb/smbXcli_base.h
index 8cb3b8e..0eaf797 100644
--- a/libcli/smb/smbXcli_base.h
+++ b/libcli/smb/smbXcli_base.h
@@ -59,6 +59,10 @@ uint32_t smb1cli_conn_max_xmit(struct smbXcli_conn *conn);
 uint32_t smb1cli_conn_server_session_key(struct smbXcli_conn *conn);
 const uint8_t *smb1cli_conn_server_challenge(struct smbXcli_conn *conn);
 uint16_t smb1cli_conn_server_security_mode(struct smbXcli_conn *conn);
+bool smb1cli_conn_server_readbraw(struct smbXcli_conn *conn);
+bool smb1cli_conn_server_writebraw(struct smbXcli_conn *conn);
+bool smb1cli_conn_server_lockread(struct smbXcli_conn *conn);
+bool smb1cli_conn_server_writeunlock(struct smbXcli_conn *conn);
 int smb1cli_conn_server_time_zone(struct smbXcli_conn *conn);
 
 bool smb1cli_conn_activate_signing(struct smbXcli_conn *conn,
diff --git a/libcli/smb/smb_signing.h b/libcli/smb/smb_signing.h
index 481be1d..b5deec6 100644
--- a/libcli/smb/smb_signing.h
+++ b/libcli/smb/smb_signing.h
@@ -40,7 +40,6 @@ void smb_signing_sign_pdu(struct smb_signing_state *si,
 			  uint8_t *outbuf, uint32_t seqnum);
 bool smb_signing_check_pdu(struct smb_signing_state *si,
 			   const uint8_t *inbuf, uint32_t seqnum);
-bool smb_signing_set_bsrspyl(struct smb_signing_state *si);
 bool smb_signing_activate(struct smb_signing_state *si,
 			  const DATA_BLOB user_session_key,
 			  const DATA_BLOB response);
diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c
index bf608f1..70a83a4 100644
--- a/source4/libcli/raw/clisocket.c
+++ b/source4/libcli/raw/clisocket.c
@@ -29,6 +29,129 @@
 #include "param/param.h"
 #include "libcli/raw/raw_proto.h"
 
+/*
+  send a session request
+*/
+struct smbcli_request *smbcli_transport_connect_send(struct smbcli_transport *transport,
+						     struct nbt_name *calling, 
+						     struct nbt_name *called)
+{
+	uint8_t *p;
+	struct smbcli_request *req;
+	DATA_BLOB calling_blob, called_blob;
+	TALLOC_CTX *tmp_ctx = talloc_new(transport);
+	NTSTATUS status;
+
+	status = nbt_name_dup(transport, called, &transport->called);
+	if (!NT_STATUS_IS_OK(status)) goto failed;
+	
+	status = nbt_name_to_blob(tmp_ctx, &calling_blob, calling);
+	if (!NT_STATUS_IS_OK(status)) goto failed;
+
+	status = nbt_name_to_blob(tmp_ctx, &called_blob, called);
+	if (!NT_STATUS_IS_OK(status)) goto failed;
+
+  	/* allocate output buffer */
+	req = smbcli_request_setup_nonsmb(transport, 
+					  NBT_HDR_SIZE + 
+					  calling_blob.length + called_blob.length);
+	if (req == NULL) goto failed;
+
+	/* put in the destination name */
+	p = req->out.buffer + NBT_HDR_SIZE;
+	memcpy(p, called_blob.data, called_blob.length);
+	p += called_blob.length;
+
+	memcpy(p, calling_blob.data, calling_blob.length);
+	p += calling_blob.length;
+
+	_smb_setlen_nbt(req->out.buffer, PTR_DIFF(p, req->out.buffer) - NBT_HDR_SIZE);
+	SCVAL(req->out.buffer,0,0x81);
+
+	if (!smbcli_request_send(req)) {
+		smbcli_request_destroy(req);
+		goto failed;
+	}
+
+	talloc_free(tmp_ctx);
+	return req;
+
+failed:
+	talloc_free(tmp_ctx);
+	return NULL;
+}
+
+/*
+  map a session request error to a NTSTATUS
+ */
+static NTSTATUS map_session_refused_error(uint8_t error)
+{
+	switch (error) {
+	case 0x80:
+	case 0x81:
+		return NT_STATUS_REMOTE_NOT_LISTENING;
+	case 0x82:
+		return NT_STATUS_RESOURCE_NAME_NOT_FOUND;
+	case 0x83:
+		return NT_STATUS_REMOTE_RESOURCES;
+	}
+	return NT_STATUS_UNEXPECTED_IO_ERROR;
+}
+
+
+/*
+  finish a smbcli_transport_connect()
+*/
+NTSTATUS smbcli_transport_connect_recv(struct smbcli_request *req)
+{
+	NTSTATUS status;
+
+	if (!smbcli_request_receive(req)) {
+		smbcli_request_destroy(req);
+		return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
+	}
+
+	switch (CVAL(req->in.buffer,0)) {
+	case 0x82:
+		status = NT_STATUS_OK;
+		break;
+	case 0x83:
+		status = map_session_refused_error(CVAL(req->in.buffer,4));
+		break;
+	case 0x84:
+		DEBUG(1,("Warning: session retarget not supported\n"));
+		status = NT_STATUS_NOT_SUPPORTED;
+		break;
+	default:
+		status = NT_STATUS_UNEXPECTED_IO_ERROR;
+		break;
+	}
+
+	smbcli_request_destroy(req);
+	return status;
+}
+
+
+/*
+  send a session request (if needed)
+*/
+bool smbcli_transport_connect(struct smbcli_transport *transport,
+			      struct nbt_name *calling, 
+			      struct nbt_name *called)
+{
+	struct smbcli_request *req;
+	NTSTATUS status;
+
+	if (transport->socket->port == 445) {
+		return true;
+	}
+
+	req = smbcli_transport_connect_send(transport, 
+					    calling, called);
+	status = smbcli_transport_connect_recv(req);
+	return NT_STATUS_IS_OK(status);
+}
+
 struct sock_connect_state {
 	struct composite_context *ctx;
 	const char *host_name;
diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c
index b8df09e..b83a070 100644
--- a/source4/libcli/raw/clitransport.c
+++ b/source4/libcli/raw/clitransport.c
@@ -88,6 +88,7 @@ struct smbcli_transport *smbcli_transport_init(struct smbcli_socket *sock,
 		transport->socket = talloc_reference(transport, sock);
 	}
 	transport->negotiate.protocol = PROTOCOL_NT1;


-- 
Samba Shared Repository


More information about the samba-cvs mailing list