[SCM] Samba Shared Repository - branch v4-0-test updated - release-4-0-0alpha5-37-g9a5f7bf

Stefan Metzmacher metze at samba.org
Mon Jul 7 19:42:03 GMT 2008


The branch, v4-0-test has been updated
       via  9a5f7bf68b20e3b490b209b5cfc4408566320f2e (commit)
       via  36a39b92d732a682e38ad4b3f733951fee4757ed (commit)
       via  d235ce673705641e06b4ad5f5679e146b59a19e1 (commit)
       via  ba8499867af90dcd88455476b1f58a2ab18f159b (commit)
       via  66e0c1754f14cf0100ca2d3e9c0cd8c87f9dc1e6 (commit)
       via  6813e22e9d300696a40993476629227d5cc4d35f (commit)
       via  a6aa055097313975299f214d8ebe8d45aa51d10a (commit)
       via  1b507a9b8e2ede5a4eb542bdf7a0eab9269b9f7b (commit)
       via  48ccb51caf7976ec07c8a9bfc1afd3076bf4ee22 (commit)
       via  e1d81388fcabba9a947ed0be9ccae875e2b19135 (commit)
       via  ec67c61b6a82e4f39a15f37a98ae3fe93bb81316 (commit)
       via  5bf136e233e26b4372155f494bae5118ef777a76 (commit)
       via  6d84af89ba96627abe142ba7080c24ae2421ed6c (commit)
       via  a65599cc83a12ec61e5a6ba6ad9628619a0dc8a3 (commit)
       via  4287b7c1323796cf0688d0fae9b5bd4e840e3d48 (commit)
       via  221f4d6e534a40b7def6e51dc6b4f9e8057d18b7 (commit)
      from  351947dba3f7a26ac871d4aa7b6bba4cd472383a (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v4-0-test


- Log -----------------------------------------------------------------
commit 9a5f7bf68b20e3b490b209b5cfc4408566320f2e
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Jul 7 19:40:35 2008 +0200

    smb_server/smb: handle incoming multi fragmented nttrans requests
    
    metze

commit 36a39b92d732a682e38ad4b3f733951fee4757ed
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Jul 7 19:37:14 2008 +0200

    smb_server/smb: prepare multi fragmented nttrans requests
    
    metze

commit d235ce673705641e06b4ad5f5679e146b59a19e1
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Jul 7 16:34:36 2008 +0200

    libcli/raw: remove unused smb_raw_max_trans_data() function
    
    metze

commit ba8499867af90dcd88455476b1f58a2ab18f159b
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Jul 7 18:07:47 2008 +0200

    torture: .in.max_data should not depend on the smb max size
    
    We now support async multi fragment SMBtrans calls.
    
    metze

commit 66e0c1754f14cf0100ca2d3e9c0cd8c87f9dc1e6
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Jul 7 18:04:44 2008 +0200

    rap: trans->in.max_data should not depend on the smb max size
    
    We now support async multi fragment SMBtrans calls.
    
    metze

commit 6813e22e9d300696a40993476629227d5cc4d35f
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Jul 7 18:01:28 2008 +0200

    dcerpc_smb: trans->in.max_data should not depend on the smb max size
    
    We now support async multi fragment SMBtrans calls.
    
    metze

commit a6aa055097313975299f214d8ebe8d45aa51d10a
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Jul 7 15:04:59 2008 +0200

    libcli/raw: make multi fragmented nttrans requests possible
    
    metze

commit 1b507a9b8e2ede5a4eb542bdf7a0eab9269b9f7b
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Jul 7 14:00:53 2008 +0200

    smb_server/smb: trans(2) setup count is uint8_t
    
    metze

commit 48ccb51caf7976ec07c8a9bfc1afd3076bf4ee22
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Jul 7 14:00:09 2008 +0200

    libcli/raw: trans(2) setup count is uint8_t
    
    metze

commit e1d81388fcabba9a947ed0be9ccae875e2b19135
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Jul 4 20:47:24 2008 +0200

    libcli/raw: remove unused smbcli_request_receive_more() function
    
    metze

commit ec67c61b6a82e4f39a15f37a98ae3fe93bb81316
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Jul 4 20:46:10 2008 +0200

    libcli/raw: use the new recv_helper infrastructure for trans/trans2 replies
    
    metze

commit 5bf136e233e26b4372155f494bae5118ef777a76
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Jul 4 20:07:52 2008 +0200

    libcli/raw: use the new recv_helper infrastructure for nttrans replies
    
    metze

commit 6d84af89ba96627abe142ba7080c24ae2421ed6c
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Jul 4 19:52:23 2008 +0200

    libcli/raw: add a recv_helper hook infrastructure
    
    The recv helper will be called when a response comes
    and the recv helper can decide to let the request
    on the SMBCLI_REQUEST_RECV when more reponse packets
    are expected. It's up to the helper function
    to keep a reference to the in buffers, each incoming
    response overwrites req->in.
    
    metze

commit a65599cc83a12ec61e5a6ba6ad9628619a0dc8a3
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Jul 4 20:16:36 2008 +0200

    libcli/raw: the nttrans setup count is only 8-bit
    
    metze

commit 4287b7c1323796cf0688d0fae9b5bd4e840e3d48
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Jul 7 13:00:24 2008 +0200

    smb_server/smb: transs and transs2 calls have different word counts
    
    Also add a note about NT_STATUS_DOS(ERRSRV, ERRerror).
    
    metze

commit 221f4d6e534a40b7def6e51dc6b4f9e8057d18b7
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Jul 7 12:56:26 2008 +0200

    smb_server/smb: fix crash bug with fragmented trans calls
    
    We need to use smbsrv_setup_secondary_request(req) to send the
    trans ack, because smbsrv_send_reply(req) destroys 'req'
    and the partial trans list had dead elements in the list.
    
    Also make sure the partial list element is removed by a talloc
    destructor.
    
    metze

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

Summary of changes:
 source/libcli/raw/clitransport.c |   16 +-
 source/libcli/raw/interfaces.h   |    2 +-
 source/libcli/raw/libcliraw.h    |    8 +
 source/libcli/raw/rawrequest.c   |   13 -
 source/libcli/raw/rawtrans.c     |  967 +++++++++++++++++++++++++-------------
 source/librpc/rpc/dcerpc_smb.c   |    9 +-
 source/smb_server/smb/nttrans.c  |  168 ++++++-
 source/smb_server/smb/trans2.c   |   55 ++-
 source/smb_server/smb_server.h   |    5 +-
 source/torture/basic/aliases.c   |   10 +-
 source/torture/basic/scanner.c   |    8 +-
 source/torture/rap/rap.c         |    2 +-
 12 files changed, 880 insertions(+), 383 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source/libcli/raw/clitransport.c b/source/libcli/raw/clitransport.c
index 34fb962..e95ae32 100644
--- a/source/libcli/raw/clitransport.c
+++ b/source/libcli/raw/clitransport.c
@@ -480,8 +480,22 @@ async:
 	/* if this request has an async handler then call that to
 	   notify that the reply has been received. This might destroy
 	   the request so it must happen last */
-	DLIST_REMOVE(transport->pending_recv, req);
+
 	req->state = SMBCLI_REQUEST_DONE;
+
+	if (req->recv_helper.fn) {
+		/*
+		 * let the recv helper decide in
+		 * what state the request really is
+		 */
+		req->state = req->recv_helper.fn(req);
+
+		/* if more parts are needed, wait for them */
+		if (req->state <= SMBCLI_REQUEST_RECV) {
+			return NT_STATUS_OK;
+		}
+	}
+	DLIST_REMOVE(transport->pending_recv, req);
 	if (req->async.fn) {
 		req->async.fn(req);
 	}
diff --git a/source/libcli/raw/interfaces.h b/source/libcli/raw/interfaces.h
index 8e23510..537041c 100644
--- a/source/libcli/raw/interfaces.h
+++ b/source/libcli/raw/interfaces.h
@@ -2258,7 +2258,7 @@ struct smb_nttrans {
 		uint8_t  max_setup;
 		uint32_t max_param;
 		uint32_t max_data;
-		uint32_t setup_count;
+		uint8_t setup_count;
 		uint16_t function;
 		uint8_t  *setup;
 		DATA_BLOB params;
diff --git a/source/libcli/raw/libcliraw.h b/source/libcli/raw/libcliraw.h
index 16a98ad..d55b4cc 100644
--- a/source/libcli/raw/libcliraw.h
+++ b/source/libcli/raw/libcliraw.h
@@ -231,6 +231,14 @@ struct smbcli_request {
 	struct smbcli_session *session;
 	struct smbcli_tree *tree;
 
+	/* a receive helper, smbcli_transport_finish_recv will not call
+	   req->async.fn callback handler unless the recv_helper returns
+	   a value > SMBCLI_REQUEST_RECV. */
+	struct {
+		enum smbcli_request_state (*fn)(struct smbcli_request *);
+		void *private_data;
+	} recv_helper;
+
 	/* the flags2 from the SMB request, in raw form (host byte
 	   order). Used to parse strings */
 	uint16_t flags2;
diff --git a/source/libcli/raw/rawrequest.c b/source/libcli/raw/rawrequest.c
index ef856c6..a0e6452 100644
--- a/source/libcli/raw/rawrequest.c
+++ b/source/libcli/raw/rawrequest.c
@@ -365,19 +365,6 @@ bool smbcli_request_receive(struct smbcli_request *req)
 
 
 /*
-  receive another reply to a request - this is used for requests that
-  have multi-part replies (such as SMBtrans2)
-*/
-bool smbcli_request_receive_more(struct smbcli_request *req)
-{
-	req->state = SMBCLI_REQUEST_RECV;
-	DLIST_ADD(req->transport->pending_recv, req);
-
-	return smbcli_request_receive(req);
-}
-
-
-/*
   handle oplock break requests from the server - return true if the request was
   an oplock break
 */
diff --git a/source/libcli/raw/rawtrans.c b/source/libcli/raw/rawtrans.c
index 0f15b21..2f52986 100644
--- a/source/libcli/raw/rawtrans.c
+++ b/source/libcli/raw/rawtrans.c
@@ -49,148 +49,188 @@ static bool raw_trans_oob(struct smbcli_request *req,
 	return false;	
 }
 
-/****************************************************************************
-  receive a SMB trans or trans2 response allocating the necessary memory
-  ****************************************************************************/
+static size_t raw_trans_space_left(struct smbcli_request *req)
+{
+	if (req->transport->negotiate.max_xmit <= req->out.size) {
+		return 0;
+	}
+
+	return req->transport->negotiate.max_xmit - req->out.size;
+}
+
+struct smb_raw_trans2_recv_state {
+	uint8_t command;
+	uint32_t params_total;
+	uint32_t data_total;
+	uint32_t params_left;
+	uint32_t data_left;
+	bool got_first;
+	uint32_t recvd_data;
+	uint32_t recvd_param;
+	struct smb_trans2 io;
+};
+
 NTSTATUS smb_raw_trans2_recv(struct smbcli_request *req,
 			     TALLOC_CTX *mem_ctx,
 			     struct smb_trans2 *parms)
 {
-	int total_data=0;
-	int total_param=0;
-	uint8_t *tdata;
-	uint8_t *tparam;
-
-	parms->out.data.length = 0;
-	parms->out.data.data = NULL;
-	parms->out.params.length = 0;
-	parms->out.params.data = NULL;
+	struct smb_raw_trans2_recv_state *state;
 
-	if (!smbcli_request_receive(req)) {
-		return smbcli_request_destroy(req);
+	if (!smbcli_request_receive(req) ||
+	    smbcli_request_is_error(req)) {
+		goto failed;
 	}
-	
+
+	state = talloc_get_type(req->recv_helper.private_data,
+				struct smb_raw_trans2_recv_state);
+
+	parms->out = state->io.out;
+	talloc_steal(mem_ctx, parms->out.setup);
+	talloc_steal(mem_ctx, parms->out.params.data);
+	talloc_steal(mem_ctx, parms->out.data.data);
+	talloc_free(state);
+
+	ZERO_STRUCT(req->recv_helper);
+
+failed:
+	return smbcli_request_destroy(req);
+}
+
+static enum smbcli_request_state smb_raw_trans2_ship_rest(struct smbcli_request *req,
+							  struct smb_raw_trans2_recv_state *state);
+
+/*
+ * This helper returns SMBCLI_REQUEST_RECV until all data has arrived
+ */
+static enum smbcli_request_state smb_raw_trans2_recv_helper(struct smbcli_request *req)
+{
+	struct smb_raw_trans2_recv_state *state = talloc_get_type(req->recv_helper.private_data,
+						  struct smb_raw_trans2_recv_state);
+	uint16_t param_count, param_ofs, param_disp;
+	uint16_t data_count, data_ofs, data_disp;
+	uint16_t total_data, total_param;
+	uint8_t setup_count;
+
 	/*
 	 * An NT RPC pipe call can return ERRDOS, ERRmoredata
 	 * to a trans call. This is not an error and should not
 	 * be treated as such.
 	 */
-	if (NT_STATUS_IS_ERR(req->status)) {
-		return smbcli_request_destroy(req);
+	if (smbcli_request_is_error(req)) {
+		goto failed;
+	}
+
+	if (state->params_left > 0 || state->data_left > 0) {
+		return smb_raw_trans2_ship_rest(req, state);
 	}
 
 	SMBCLI_CHECK_MIN_WCT(req, 10);
 
-	/* parse out the lengths */
 	total_data = SVAL(req->in.vwv, VWV(1));
 	total_param = SVAL(req->in.vwv, VWV(0));
-
-	/* allocate it */
-	if (total_data != 0) {
-		tdata = talloc_array(mem_ctx, uint8_t, total_data);
-		if (!tdata) {
-			DEBUG(0,("smb_raw_receive_trans: failed to enlarge data buffer to %d bytes\n", total_data));
-			req->status = NT_STATUS_NO_MEMORY;
-			return smbcli_request_destroy(req);
+	setup_count = CVAL(req->in.vwv, VWV(9));
+
+	param_count = SVAL(req->in.vwv, VWV(3));
+	param_ofs   = SVAL(req->in.vwv, VWV(4));
+	param_disp  = SVAL(req->in.vwv, VWV(5));
+
+	data_count = SVAL(req->in.vwv, VWV(6));
+	data_ofs   = SVAL(req->in.vwv, VWV(7));
+	data_disp  = SVAL(req->in.vwv, VWV(8));
+
+	if (!state->got_first) {
+		if (total_param > 0) {
+			state->io.out.params = data_blob_talloc(state, NULL, total_param);
+			if (!state->io.out.params.data) {
+				goto nomem;
+			}
 		}
-		parms->out.data.data = tdata;
-	}
 
-	if (total_param != 0) {
-		tparam = talloc_array(mem_ctx, uint8_t, total_param);
-		if (!tparam) {
-			DEBUG(0,("smb_raw_receive_trans: failed to enlarge param buffer to %d bytes\n", total_param));
-			req->status = NT_STATUS_NO_MEMORY;
-			return smbcli_request_destroy(req);
+		if (total_data > 0) {
+			state->io.out.data = data_blob_talloc(state, NULL, total_data);
+			if (!state->io.out.data.data) {
+				goto nomem;
+			}
 		}
-		parms->out.params.data = tparam;
-	}
 
-	parms->out.setup_count = SVAL(req->in.vwv, VWV(9));
-	SMBCLI_CHECK_WCT(req, 10 + parms->out.setup_count);
+		if (setup_count > 0) {
+			uint16_t i;
 
-	if (parms->out.setup_count > 0) {
-		int i;
-		parms->out.setup = talloc_array(mem_ctx, uint16_t, parms->out.setup_count);
-		if (!parms->out.setup) {
-			req->status = NT_STATUS_NO_MEMORY;
-			return smbcli_request_destroy(req);
-		}
-		for (i=0;i<parms->out.setup_count;i++) {
-			parms->out.setup[i] = SVAL(req->in.vwv, VWV(10+i));
+			SMBCLI_CHECK_WCT(req, 10 + setup_count);
+
+			state->io.out.setup_count = setup_count;
+			state->io.out.setup = talloc_array(state, uint16_t, setup_count);
+			if (!state->io.out.setup) {
+				goto nomem;
+			}
+			for (i=0; i < setup_count; i++) {
+				state->io.out.setup[i] = SVAL(req->in.vwv, VWV(10+i));
+			}
 		}
-	}
 
-	while (1)  {
-		uint16_t param_count, param_ofs, param_disp;
-		uint16_t data_count, data_ofs, data_disp;
-		uint16_t total_data2, total_param2;
+		state->got_first = true;
+	}
 
-		/* parse out the total lengths again - they can shrink! */
-		total_data2 = SVAL(req->in.vwv, VWV(1));
-		total_param2 = SVAL(req->in.vwv, VWV(0));
+	if (total_data > state->io.out.data.length ||
+	    total_param > state->io.out.params.length) {
+		/* they must *only* shrink */
+		DEBUG(1,("smb_raw_trans2_recv_helper: data/params expanded!\n"));
+		req->status = NT_STATUS_BUFFER_TOO_SMALL;
+		goto failed;
+	}
 
-		if (total_data2 > total_data ||
-		    total_param2 > total_param) {
-			/* they must *only* shrink */
-			DEBUG(1,("smb_raw_receive_trans: data/params expanded!\n"));
-			req->status = NT_STATUS_BUFFER_TOO_SMALL;
-			return smbcli_request_destroy(req);
-		}
+	state->io.out.data.length = total_data;
+	state->io.out.params.length = total_param;
 
-		total_data = total_data2;
-		total_param = total_param2;		
+	if (data_count + data_disp > total_data ||
+	    param_count + param_disp > total_param) {
+		DEBUG(1,("smb_raw_trans2_recv_helper: Buffer overflow\n"));
+		req->status = NT_STATUS_BUFFER_TOO_SMALL;
+		goto failed;
+	}
 
-		/* parse params for this lump */
-		param_count = SVAL(req->in.vwv, VWV(3));
-		param_ofs   = SVAL(req->in.vwv, VWV(4));
-		param_disp  = SVAL(req->in.vwv, VWV(5));
+	/* check the server isn't being nasty */
+	if (raw_trans_oob(req, param_ofs, param_count) ||
+	    raw_trans_oob(req, data_ofs, data_count)) {
+		DEBUG(1,("smb_raw_trans2_recv_helper: out of bounds parameters!\n"));
+		req->status = NT_STATUS_BUFFER_TOO_SMALL;
+		goto failed;
+	}
 
-		data_count = SVAL(req->in.vwv, VWV(6));
-		data_ofs   = SVAL(req->in.vwv, VWV(7));
-		data_disp  = SVAL(req->in.vwv, VWV(8));
+	if (data_count) {
+		memcpy(state->io.out.data.data + data_disp,
+		       req->in.hdr + data_ofs,
+		       data_count);
+	}
 
-		if (data_count + data_disp > total_data ||
-		    param_count + param_disp > total_param) {
-			DEBUG(1,("smb_raw_receive_trans: Buffer overflow\n"));
-			req->status = NT_STATUS_BUFFER_TOO_SMALL;
-			return smbcli_request_destroy(req);
-		}
-		
-		/* check the server isn't being nasty */
-		if (raw_trans_oob(req, param_ofs, param_count) ||
-		    raw_trans_oob(req, data_ofs, data_count)) {
-			DEBUG(1,("smb_raw_receive_trans: out of bounds parameters!\n"));
-			req->status = NT_STATUS_BUFFER_TOO_SMALL;
-			return smbcli_request_destroy(req);
-		}
+	if (param_count) {
+		memcpy(state->io.out.params.data + param_disp,
+		       req->in.hdr + param_ofs,
+		       param_count);
+	}
 
-		if (data_count) {
-			memcpy(parms->out.data.data + data_disp,
-			       req->in.hdr + data_ofs, 
-			       data_count);
-		}
+	state->recvd_param += param_count;
+	state->recvd_data += data_count;
 
-		if (param_count) {
-			memcpy(parms->out.params.data + param_disp,
-			       req->in.hdr + param_ofs, 
-			       param_count);
-		}
+	if (state->recvd_data < total_data ||
+	    state->recvd_param < total_param) {
 
-		parms->out.data.length += data_count;
-		parms->out.params.length += param_count;
+		/* we don't need the in buffer any more */
+		talloc_free(req->in.buffer);
+		ZERO_STRUCT(req->in);
 
-		if (total_data <= parms->out.data.length && total_param <= parms->out.params.length)
-			break;
-	
-		if (!smbcli_request_receive_more(req)) {
-			req->status = NT_STATUS_UNSUCCESSFUL;
-			return smbcli_request_destroy(req);
-		}
+		/* we still wait for more data */
+		DEBUG(10,("smb_raw_trans2_recv_helper: more data needed\n"));
+		return SMBCLI_REQUEST_RECV;
 	}
 
+	DEBUG(10,("smb_raw_trans2_recv_helper: done\n"));
+	return SMBCLI_REQUEST_DONE;
+
+nomem:
+	req->status = NT_STATUS_NO_MEMORY;
 failed:
-	return smbcli_request_destroy(req);
+	return SMBCLI_REQUEST_ERROR;
 }
 
 _PUBLIC_ NTSTATUS smb_raw_trans_recv(struct smbcli_request *req,
@@ -208,13 +248,17 @@ struct smbcli_request *smb_raw_trans_send_backend(struct smbcli_tree *tree,
 						  struct smb_trans2 *parms,
 						  uint8_t command)
 {
-	int wct = 14 + parms->in.setup_count;
-	struct smbcli_request *req, *req2; 
-	uint8_t *outdata,*outparam;
+	struct smb_raw_trans2_recv_state *state;
+	struct smbcli_request *req;
 	int i;
 	int padding;
+	size_t space_left;
 	size_t namelen = 0;
-	uint16_t data_disp, data_length, max_data;
+	DATA_BLOB params_chunk;
+	uint16_t ofs;
+	uint16_t params_ofs = 0;
+	DATA_BLOB data_chunk;
+	uint16_t data_ofs = 0;
 
 	if (parms->in.params.length > UINT16_MAX ||
 	    parms->in.data.length > UINT16_MAX) {
@@ -229,136 +273,223 @@ struct smbcli_request *smb_raw_trans_send_backend(struct smbcli_tree *tree,
 	else
 		padding = 3;
 	
-	req = smbcli_request_setup(tree, command, wct, padding);
+	req = smbcli_request_setup(tree, command,
+				   14 + parms->in.setup_count,
+				   padding);
 	if (!req) {
 		return NULL;
 	}
 
+	state = talloc_zero(req, struct smb_raw_trans2_recv_state);
+	if (!state) {
+		smbcli_request_destroy(req);
+		return NULL;
+	}
+
+	state->command = command;
+
+	/* make sure we don't leak data via the padding */
+	memset(req->out.data, 0, padding);
+
 	/* Watch out, this changes the req->out.* pointers */
 	if (command == SMBtrans && parms->in.trans_name) {
 		namelen = smbcli_req_append_string(req, parms->in.trans_name, 
 						STR_TERMINATE);
 	}
 
-	/* fill in SMB parameters */
-	outparam = req->out.data + padding;
-	outdata = outparam + parms->in.params.length;
+	ofs = PTR_DIFF(req->out.data,req->out.hdr)+padding+namelen;
 
-	/* make sure we don't leak data via the padding */
-	memset(req->out.data, 0, padding);
+	/* see how much bytes of the params block we can ship in the first request */
+	space_left = raw_trans_space_left(req);
 
-	data_length = parms->in.data.length;
+	params_chunk.length = MIN(parms->in.params.length, space_left);
+	params_chunk.data = parms->in.params.data;
+	params_ofs = ofs;
 
-	max_data = smb_raw_max_trans_data(tree, parms->in.params.length);
-	if (max_data < data_length) {
-		data_length = max_data;
+	state->params_left = parms->in.params.length - params_chunk.length;
+
+	if (state->params_left > 0) {
+		/* we copy the whole params block, if needed we can optimize that latter */
+		state->io.in.params = data_blob_talloc(state, NULL, parms->in.params.length);
+		if (!state->io.in.params.data) {
+			smbcli_request_destroy(req);
+			return NULL;
+		}
+		memcpy(state->io.in.params.data,
+		       parms->in.params.data,
+		       parms->in.params.length);
 	}
 
+	/* see how much bytes of the data block we can ship in the first request */
+	space_left -= params_chunk.length;
+
 #if TORTURE_TRANS_DATA
-	if (data_length > 1) {
-		data_length /= 2;
+	if (space_left > 1) {
+		space_left /= 2;
 	}
 #endif
 
+	data_chunk.length = MIN(parms->in.data.length, space_left);
+	data_chunk.data = parms->in.data.data;
+	data_ofs = params_ofs + params_chunk.length;
+
+	state->data_left = parms->in.data.length - data_chunk.length;
+
+	if (state->data_left > 0) {
+		/* we copy the whole params block, if needed we can optimize that latter */
+		state->io.in.data = data_blob_talloc(state, NULL, parms->in.data.length);
+		if (!state->io.in.data.data) {
+			smbcli_request_destroy(req);
+			return NULL;
+		}
+		memcpy(state->io.in.data.data,
+		       parms->in.data.data,
+		       parms->in.data.length);
+	}
+
+	state->params_total = parms->in.params.length;
+	state->data_total = parms->in.data.length;
+
 	/* primary request */
 	SSVAL(req->out.vwv,VWV(0),parms->in.params.length);
 	SSVAL(req->out.vwv,VWV(1),parms->in.data.length);


-- 
Samba Shared Repository


More information about the samba-cvs mailing list