svn commit: samba r4229 - in branches/SAMBA_4_0/source/libcli/raw: .

tridge at samba.org tridge at samba.org
Thu Dec 16 12:29:04 GMT 2004


Author: tridge
Date: 2004-12-16 12:29:04 +0000 (Thu, 16 Dec 2004)
New Revision: 4229

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=4229

Log:
- added support for multi-part SMBtrans and SMBtrans2 requests in the
  client code. This was essential to test the multi-part server code
  (which I will commit soon)

- when the request state is an error, ensure that req->status is not NT_STATUS_OK



Modified:
   branches/SAMBA_4_0/source/libcli/raw/rawrequest.c
   branches/SAMBA_4_0/source/libcli/raw/rawtrans.c


Changeset:
Modified: branches/SAMBA_4_0/source/libcli/raw/rawrequest.c
===================================================================
--- branches/SAMBA_4_0/source/libcli/raw/rawrequest.c	2004-12-16 12:25:23 UTC (rev 4228)
+++ branches/SAMBA_4_0/source/libcli/raw/rawrequest.c	2004-12-16 12:29:04 UTC (rev 4229)
@@ -48,8 +48,11 @@
 		DLIST_REMOVE(req->transport->pending_recv, req);
 	}
 
-	/* ahh, its so nice to destroy a complex structure in such a
-	   simple way! */
+	if (req->state == SMBCLI_REQUEST_ERROR &&
+	    NT_STATUS_IS_OK(req->status)) {
+		req->status = NT_STATUS_INTERNAL_ERROR;
+	}
+
 	status = req->status;
 	talloc_free(req);
 	return status;
@@ -95,7 +98,7 @@
   setup a SMB packet at transport level
 */
 struct smbcli_request *smbcli_request_setup_transport(struct smbcli_transport *transport,
-						uint8_t command, uint_t wct, uint_t buflen)
+						      uint8_t command, uint_t wct, uint_t buflen)
 {
 	struct smbcli_request *req;
 
@@ -119,8 +122,10 @@
 	SCVAL(req->out.hdr,HDR_FLG, FLAG_CASELESS_PATHNAMES);
 	SSVAL(req->out.hdr,HDR_FLG2, 0);
 
-	/* assign a mid */
-	req->mid = smbcli_transport_next_mid(transport);
+	if (command != SMBtranss && command != SMBtranss2) {
+		/* assign a mid */
+		req->mid = smbcli_transport_next_mid(transport);
+	}
 
 	/* copy the pid, uid and mid to the request */
 	SSVAL(req->out.hdr, HDR_PID, 0);

Modified: branches/SAMBA_4_0/source/libcli/raw/rawtrans.c
===================================================================
--- branches/SAMBA_4_0/source/libcli/raw/rawtrans.c	2004-12-16 12:25:23 UTC (rev 4228)
+++ branches/SAMBA_4_0/source/libcli/raw/rawtrans.c	2004-12-16 12:29:04 UTC (rev 4229)
@@ -20,8 +20,10 @@
 */
 
 #include "includes.h"
+#include "dlinklist.h"
 #include "libcli/raw/libcliraw.h"
 
+#define TORTURE_TRANS_DATA 0
 
 /*
   check out of bounds for incoming data
@@ -198,20 +200,21 @@
 	return smb_raw_trans2_recv(req, mem_ctx, parms);
 }
 
-/****************************************************************************
- trans/trans2 raw async interface - only BLOBs used in this interface.
- note that this doesn't yet support multi-part requests
-****************************************************************************/
+
+/*
+  trans/trans2 raw async interface - only BLOBs used in this interface.
+*/
 struct smbcli_request *smb_raw_trans_send_backend(struct smbcli_tree *tree,
-					       struct smb_trans2 *parms,
-					       uint8_t command)
+						  struct smb_trans2 *parms,
+						  uint8_t command)
 {
 	int wct = 14 + parms->in.setup_count;
-	struct smbcli_request *req; 
+	struct smbcli_request *req, *req2; 
 	uint8_t *outdata,*outparam;
 	int i;
 	int padding;
 	size_t namelen = 0;
+	uint16_t data_disp, data_length, max_data;
 
 	if (command == SMBtrans)
 		padding = 1;
@@ -236,6 +239,19 @@
 	/* make sure we don't leak data via the padding */
 	memset(req->out.data, 0, padding);
 
+	data_length = parms->in.data.length;
+
+	max_data = smb_raw_max_trans_data(tree, parms->in.params.length);
+	if (max_data < data_length) {
+		data_length = max_data;
+	}
+
+#if TORTURE_TRANS_DATA
+	if (data_length > 1) {
+		data_length /= 2;
+	}
+#endif
+
 	/* primary request */
 	SSVAL(req->out.vwv,VWV(0),parms->in.params.length);
 	SSVAL(req->out.vwv,VWV(1),parms->in.data.length);
@@ -247,7 +263,7 @@
 	SSVAL(req->out.vwv,VWV(8),0); /* reserved */
 	SSVAL(req->out.vwv,VWV(9),parms->in.params.length);
 	SSVAL(req->out.vwv,VWV(10),PTR_DIFF(outparam,req->out.hdr)+namelen);
-	SSVAL(req->out.vwv,VWV(11),parms->in.data.length);
+	SSVAL(req->out.vwv,VWV(11),data_length);
 	SSVAL(req->out.vwv,VWV(12),PTR_DIFF(outdata,req->out.hdr)+namelen);
 	SSVAL(req->out.vwv,VWV(13),parms->in.setup_count);
 	for (i=0;i<parms->in.setup_count;i++)	{
@@ -257,22 +273,88 @@
 		smbcli_req_append_blob(req, &parms->in.params);
 	}
 	if (parms->in.data.data) {
-		smbcli_req_append_blob(req, &parms->in.data);
+		DATA_BLOB data;
+		data.data = parms->in.data.data;
+		data.length = data_length;
+		smbcli_req_append_blob(req, &data);
 	}
 
 	if (!smbcli_request_send(req)) {
 		smbcli_request_destroy(req);
 		return NULL;
 	}
+
+	data_disp = data_length;
+
+
+	if (data_disp != parms->in.data.length) {
+		/* TODO: this should be done asynchronously .... */
+		if (!smbcli_request_receive(req) ||
+		    !NT_STATUS_IS_OK(req->status)) {
+			return req;
+		}
+
+		req->state = SMBCLI_REQUEST_RECV;
+		DLIST_ADD(req->transport->pending_recv, req);
+	}
+
+
+	while (data_disp != parms->in.data.length) {
+		data_length = parms->in.data.length - data_disp;
+
+		max_data = smb_raw_max_trans_data(tree, 0);
+		if (max_data < data_length) {
+			data_length = max_data;
+		}
+
+#if TORTURE_TRANS_DATA
+		if (data_length > 1) {
+			data_length /= 2;
+		}
+#endif
+
+		req2 = smbcli_request_setup(tree, command+1, 9, data_length);
+		if (!req2) {
+			return NULL;
+		}
+		req2->mid = req->mid;
+		SSVAL(req2->out.hdr, HDR_MID, req2->mid);
+
+		outdata = req2->out.data;
+
+		SSVAL(req2->out.vwv,VWV(0), parms->in.params.length);
+		SSVAL(req2->out.vwv,VWV(1), parms->in.data.length);
+		SSVAL(req2->out.vwv,VWV(2), 0);
+		SSVAL(req2->out.vwv,VWV(3), 0);
+		SSVAL(req2->out.vwv,VWV(4), 0);
+		SSVAL(req2->out.vwv,VWV(5), data_length);
+		SSVAL(req2->out.vwv,VWV(6), PTR_DIFF(outdata,req2->out.hdr));
+		SSVAL(req2->out.vwv,VWV(7), data_disp);
+		SSVAL(req2->out.vwv,VWV(8), 0xFFFF);
+
+		memcpy(req2->out.data, parms->in.data.data + data_disp, data_length);
+		
+		data_disp += data_length;
+
+		req2->one_way_request = 1;
+
+		if (!smbcli_request_send(req2)) {
+			smbcli_request_destroy(req2);
+			return NULL;
+		}
+
+		req->seq_num = req2->seq_num;
+	}
 	
+	
 	return req;
 }
 
-/****************************************************************************
- trans/trans2 raw async interface - only BLOBs used in this interface.
-note that this doesn't yet support multi-part requests
-****************************************************************************/
 
+/*
+  trans/trans2 raw async interface - only BLOBs used in this interface.
+  note that this doesn't yet support multi-part requests
+*/
 struct smbcli_request *smb_raw_trans_send(struct smbcli_tree *tree,
 				       struct smb_trans2 *parms)
 {
@@ -312,6 +394,7 @@
 	return smb_raw_trans_recv(req, mem_ctx, parms);
 }
 
+
 /****************************************************************************
   receive a SMB nttrans response allocating the necessary memory
   ****************************************************************************/



More information about the samba-cvs mailing list