[PATCH] Fix for bug #9706 - Parameter is incorrect on Android

Jeremy Allison jra at samba.org
Wed Mar 13 18:16:12 MDT 2013


On Tue, Mar 12, 2013 at 08:14:00AM +0100, Stefan (metze) Metzmacher wrote:
> Am 11.03.2013 22:54, schrieb Jeremy Allison:
> > On Mon, Mar 11, 2013 at 01:55:12PM -0700, Jeremy Allison wrote:
> >> We need to tweak the 'large read' detection code some more...
> > 
> > Ok, here's a version with the correct MS-doc reference
> > in the comment, and also a better order of tests in the
> > second part.
> > 
> > Please review (and test :-) and push if you're happy.
> 
> Can you write some tests which verifies both patches?

Ok, here is the patchset I've attached to the bug.
Applies cleanly to 4.0.next.

It includes a new test suite, LARGE_READX which tests around the boundaries of
large readX calls with read requests of:

0xFFFF0001 (which should return 1 byte).
0x10000 (which should always return 0x10000)
0x1FFFF (which returns 0x1FFFF on Samba, and 0x10000 on Windows)
0x100000 (which returns 0x100000 on Samba, and 0x10000 on Windows).

Please review,

Cheers,

	Jeremy.
-------------- next part --------------
From 8cc6ab9e4e1fa3de9b5c76f7f5f34426aeb6f91c Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Wed, 13 Mar 2013 14:56:06 -0700
Subject: [PATCH 1/9] Ensure we send CAP_LARGE_READX/CAP_LARGE_WRITEX to the
 server on SMB1 sessionsetupX.

A Windows client doesn't do this, but that's because they never do large
reads/writes over SMB1. It's in the spec that this should occur, and
Samba 3.6.x uses it. Also, MacOSX, CIFSFS and Android (jCIFS) honour
this setting and send it. We need to as well in order to give servers
a better idea of our capabilities.

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 libcli/smb/smb_constants.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libcli/smb/smb_constants.h b/libcli/smb/smb_constants.h
index f1ecbe9..c447795 100644
--- a/libcli/smb/smb_constants.h
+++ b/libcli/smb/smb_constants.h
@@ -234,6 +234,8 @@ enum smb_signing_setting {
 	CAP_NT_SMBS | \
 	CAP_STATUS32 | \
 	CAP_LEVEL_II_OPLOCKS | \
+	CAP_LARGE_READX | \
+	CAP_LARGE_WRITEX | \
 	CAP_EXTENDED_SECURITY | \
 	0)
 #define SMB_CAP_SERVER_MASK ( \
@@ -245,8 +247,6 @@ enum smb_signing_setting {
 	CAP_NT_FIND | \
 	CAP_DFS | \
 	CAP_W2K_SMBS | \
-	CAP_LARGE_READX | \
-	CAP_LARGE_WRITEX | \
 	CAP_LWIO | \
 	CAP_UNIX | \
 	0)
-- 
1.8.1.3


From 2147c9180505489bfda00dfa3fb0bc9de0495454 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Wed, 13 Mar 2013 15:23:52 -0700
Subject: [PATCH 2/9] smb1cli_inbuf_parse_chain() and
 smb1cli_conn_dispatch_incoming() should use smb_len_tcp.

They have to cope with large READX call replies that have
a length greater than smb_len_nbt() can handle.

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 libcli/smb/smbXcli_base.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c
index 4c60a05..b8cd7df 100644
--- a/libcli/smb/smbXcli_base.c
+++ b/libcli/smb/smbXcli_base.c
@@ -1618,7 +1618,7 @@ static NTSTATUS smb1cli_inbuf_parse_chain(uint8_t *buf, TALLOC_CTX *mem_ctx,
 	NTSTATUS status;
 	size_t min_size = MIN_SMB_SIZE;
 
-	buflen = smb_len_nbt(buf);
+	buflen = smb_len_tcp(buf);
 	taken = 0;
 
 	hdr = buf + NBT_HDR_SIZE;
@@ -1845,7 +1845,7 @@ static NTSTATUS smb1cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
 	uint16_t mid;
 	bool oplock_break;
 	uint8_t *inhdr = inbuf + NBT_HDR_SIZE;
-	size_t len = smb_len_nbt(inbuf);
+	size_t len = smb_len_tcp(inbuf);
 	struct iovec *iov = NULL;
 	int num_iov = 0;
 	struct tevent_req **chain = NULL;
-- 
1.8.1.3


From 2b834eaf4adcd8ed962f062721f5fd72c28d0455 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Wed, 13 Mar 2013 15:32:13 -0700
Subject: [PATCH 3/9] Fix the algorithm for looking at upper length field in
 read_and_X.

If the upper len is 0xFFFF, ignore. This cannot be a valid value
(some clients deliberately send this).

If the client is Samba, always look (we always correctly set
the upper length value).

If the client has told us via UNIX extensions it can do
large READ, look at the upper length value.

If the client has sent the CAP_LARGE_READX in sessionsetupX,
look at the upper length value.

Otherwise ignore.

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 source3/smbd/reply.c | 46 ++++++++++++++++++++++++++++++++++++----------
 1 file changed, 36 insertions(+), 10 deletions(-)

diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index 64c4fdb..afa2064 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -3849,23 +3849,48 @@ nosendfile_read:
 }
 
 /****************************************************************************
- MacOSX clients send large reads without telling us they are going to do that.
+ MacOSX clients send large reads without telling us they are going to do that
+ via the UNIX extensions mechanism (they do set the client CAP_LARGE_READX
+ bit in their SessionSetupX reply).
  Bug #9572 - File corruption during SMB1 read by Mac OSX 10.8.2 clients
- Allow this if we are talking to a Samba client, or if we told the client
- we supported this.
+ Allow this if we are talking to a Samba client, or if the client told us
+ it supported this via the UNIX extensions or the client capabilities.
 ****************************************************************************/
 
-static bool server_will_accept_large_read(void)
+static bool server_will_accept_large_read(struct smbd_server_connection *sconn,
+					size_t upper_size)
 {
-	/* Samba client ? No problem. */
+	/*
+	 * Windows explicitly ignores upper size of 0xFFFF.
+	 * See [MS-SMB].pdf <26> Section 2.2.4.2.1:
+	 * We must do the same as these will never fit even in
+	 * an extended size NetBIOS packet.
+	 */
+	if (upper_size == 0xFFFF) {
+		return false;
+	}
+
+	/*
+	 * Samba early 4.0.x client doesn't set
+	 * CAP_LARGE_READX in the sessionsetupX request so
+	 * just assume for a Samba client it's ok.
+	 */
 	if (get_remote_arch() == RA_SAMBA) {
 		return true;
 	}
-	/* Need UNIX extensions. */
-	if (!lp_unix_extensions()) {
-		return false;
+
+	/*
+	 * Client told us via UNIX extensions it can do this.
+	 */
+	if (sconn->smb1.unix_info.client_cap_low & CIFS_UNIX_LARGE_READ_CAP) {
+		return true;
 	}
-	return true;
+
+	/*
+	 * Clients that use LARGE_READX (MacOSX, CIFSFS, Samba)
+	 * set CAP_LARGE_READX in their sessionsetupX requests.
+	*/
+	return (global_client_caps & CAP_LARGE_READX);
 }
 
 /****************************************************************************
@@ -3874,6 +3899,7 @@ static bool server_will_accept_large_read(void)
 
 void reply_read_and_X(struct smb_request *req)
 {
+	struct smbd_server_connection *sconn = req->sconn;
 	connection_struct *conn = req->conn;
 	files_struct *fsp;
 	off_t startpos;
@@ -3914,7 +3940,7 @@ void reply_read_and_X(struct smb_request *req)
 	}
 
 	upper_size = SVAL(req->vwv+7, 0);
-	if ((upper_size != 0) && server_will_accept_large_read()) {
+	if ((upper_size != 0) && server_will_accept_large_read(sconn, upper_size)) {
 		/*
 		 * This is Samba only behavior (up to Samba 3.6)!
 		 *
-- 
1.8.1.3


From 62328bcc198631422a2ae4628b7b37eac9513860 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Wed, 13 Mar 2013 15:36:56 -0700
Subject: [PATCH 4/9] Remove out of date comment.

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 source3/smbd/reply.c | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index afa2064..14cb3c8 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -3941,13 +3941,6 @@ void reply_read_and_X(struct smb_request *req)
 
 	upper_size = SVAL(req->vwv+7, 0);
 	if ((upper_size != 0) && server_will_accept_large_read(sconn, upper_size)) {
-		/*
-		 * This is Samba only behavior (up to Samba 3.6)!
-		 *
-		 * Windows 2008 R2 ignores the upper_size,
-		 * so we do unless unix extentions are active
-		 * or "smbclient" is talking to us.
-		 */
 		smb_maxcnt |= (upper_size<<16);
 		if (upper_size > 1) {
 			/* Can't do this on a chained packet. */
-- 
1.8.1.3


From ca07c87af2cfa6b3c8c19ea3063787d65f4a5fb7 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Wed, 13 Mar 2013 15:37:50 -0700
Subject: [PATCH 5/9] Fix identification of a large_readX.

We can't just look for the upper length value being
greater than 1, as the actual limit is 0x1FFFF minus
the SMB header and VWV sizes.

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 source3/smbd/reply.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index 14cb3c8..4868a8f 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -3942,7 +3942,7 @@ void reply_read_and_X(struct smb_request *req)
 	upper_size = SVAL(req->vwv+7, 0);
 	if ((upper_size != 0) && server_will_accept_large_read(sconn, upper_size)) {
 		smb_maxcnt |= (upper_size<<16);
-		if (upper_size > 1) {
+		if (smb_maxcnt > (0x1FFFF - (smb_size -4 + 12*2)))  {
 			/* Can't do this on a chained packet. */
 			if ((CVAL(req->vwv+0, 0) != 0xFF)) {
 				reply_nterror(req, NT_STATUS_NOT_SUPPORTED);
-- 
1.8.1.3


From e23bb3e44c8d775f584c9a9ff4c693b044ed1251 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Wed, 13 Mar 2013 15:41:05 -0700
Subject: [PATCH 6/9] Add set_XX() functions for fields we need to modify for
 testing large READX.

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 libcli/smb/smbXcli_base.c | 10 ++++++++++
 libcli/smb/smbXcli_base.h |  2 ++
 2 files changed, 12 insertions(+)

diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c
index b8cd7df..571ef28 100644
--- a/libcli/smb/smbXcli_base.c
+++ b/libcli/smb/smbXcli_base.c
@@ -585,11 +585,21 @@ uint32_t smb1cli_conn_capabilities(struct smbXcli_conn *conn)
 	return conn->smb1.capabilities;
 }
 
+void smb1cli_conn_set_capabilities(struct smbXcli_conn *conn, uint32_t capabilities)
+{
+	conn->smb1.capabilities = capabilities;
+}
+
 uint32_t smb1cli_conn_max_xmit(struct smbXcli_conn *conn)
 {
 	return conn->smb1.max_xmit;
 }
 
+void smb1cli_conn_set_max_xmit(struct smbXcli_conn *conn, uint32_t max_xmit)
+{
+	conn->smb1.max_xmit = max_xmit;
+}
+
 uint32_t smb1cli_conn_server_session_key(struct smbXcli_conn *conn)
 {
 	return conn->smb1.server.session_key;
diff --git a/libcli/smb/smbXcli_base.h b/libcli/smb/smbXcli_base.h
index f7b60d3..476f68d 100644
--- a/libcli/smb/smbXcli_base.h
+++ b/libcli/smb/smbXcli_base.h
@@ -67,7 +67,9 @@ void smbXcli_req_unset_pending(struct tevent_req *req);
 bool smbXcli_req_set_pending(struct tevent_req *req);
 
 uint32_t smb1cli_conn_capabilities(struct smbXcli_conn *conn);
+void smb1cli_conn_set_capabilities(struct smbXcli_conn *conn, uint32_t capabilities);
 uint32_t smb1cli_conn_max_xmit(struct smbXcli_conn *conn);
+void smb1cli_conn_set_max_xmit(struct smbXcli_conn *conn, uint32_t max_xmit);
 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);
-- 
1.8.1.3


From 1fb6eef989ce7c5c5f9da54835c176c5ec650a90 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Wed, 13 Mar 2013 15:43:21 -0700
Subject: [PATCH 7/9] Add new LARGE_READX test to investigate large SMBreadX
 behavior.

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 source3/torture/torture.c | 354 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 354 insertions(+)

diff --git a/source3/torture/torture.c b/source3/torture/torture.c
index 93b9cfd..b5678f1 100644
--- a/source3/torture/torture.c
+++ b/source3/torture/torture.c
@@ -7239,6 +7239,359 @@ static bool run_windows_write(int dummy)
 	return ret;
 }
 
+/* Test large readX variants. */
+static bool large_readx_tests(struct cli_state *cli,
+				uint16_t fnum,
+				uint8_t *buf)
+{
+	NTSTATUS status;
+	struct tevent_req *req = NULL;
+	ssize_t len_read = 0;
+	struct tevent_context *ev = NULL;
+
+	ev = samba_tevent_context_init(talloc_tos());
+	if (ev == NULL) {
+		return false;
+	}
+
+	/* A read of 0xFFFF0001 should *always* return 1 byte. */
+	req = cli_read_andx_send(talloc_tos(),
+				ev,
+				cli,
+				fnum,
+				0,
+				0xFFFF0001);
+
+	if (!tevent_req_poll_ntstatus(req, ev, &status)) {
+		return false;
+	}
+
+	status = cli_read_andx_recv(req, &len_read, &buf);
+	if (!NT_STATUS_IS_OK(status)) {
+		d_printf("cli_read_andx_recv failed: %s\n", nt_errstr(status));
+		return false;
+	}
+
+	TALLOC_FREE(req);
+
+	if (len_read != 1) {
+		d_printf("read of 0xFFFF001 failed: returned %d "
+			"(should return 1)\n",
+			(int)len_read);
+		return false;
+	}
+
+	/* A read of 0x10000 should return 10000 bytes. */
+	req = cli_read_andx_send(talloc_tos(),
+				ev,
+				cli,
+				fnum,
+				0,
+				0x10000);
+
+	if (!tevent_req_poll_ntstatus(req, ev, &status)) {
+		return false;
+	}
+
+	status = cli_read_andx_recv(req, &len_read, &buf);
+	if (!NT_STATUS_IS_OK(status)) {
+		d_printf("cli_read_andx_recv failed: %s\n", nt_errstr(status));
+		return false;
+	}
+
+	TALLOC_FREE(req);
+
+	if (len_read != 0x10000) {
+		d_printf("read of 0x10000 failed: %d\n", (int)len_read);
+		return false;
+	}
+
+	/*
+	 * With signing or encryption
+	 * doing reads >= 0x1FFFF are
+	 * not supported.
+	 */
+	if (smb1cli_conn_signing_is_active(cli->conn)) {
+		d_printf("Server is signing - not testing reads > 0x10000\n");
+		return true;
+	}
+	if (smb1cli_conn_encryption_on(cli->conn)) {
+		d_printf("Server is sealing - not testing reads > 0x10000\n");
+		return true;
+	}
+
+	/* A read of 0x1FFFF should return 1FFFF bytes. */
+	req = cli_read_andx_send(talloc_tos(),
+				ev,
+				cli,
+				fnum,
+				0,
+				0x1FFFF);
+
+	if (!tevent_req_poll_ntstatus(req, ev, &status)) {
+		return false;
+	}
+
+	status = cli_read_andx_recv(req, &len_read, &buf);
+	if (!NT_STATUS_IS_OK(status)) {
+		d_printf("cli_read_andx_recv failed: %s\n", nt_errstr(status));
+		return false;
+	}
+
+	TALLOC_FREE(req);
+
+	if (len_read == 0x10000) {
+		/* Windows servers only return a max of 0x10000,
+		   doesn't matter if you set CAP_LARGE_READX in
+		   the client sessionsetupX call or not. */
+		d_printf("Windows server - returned 0x10000 on a read of 0x1FFFF\n");
+	} else if (len_read != 0x1FFFF) {
+		d_printf("read of 0x1FFFF failed: %d\n", (int)len_read);
+		return false;
+	} else {
+		d_printf("Server supports CAP_LARGE_READX fully\n");
+	}
+
+	/*
+	 * With signing or encryption
+	 * doing reads > 0x1FFFF returns
+	 * NT_STATUS_NOT_SUPPORTED.
+	 */
+	if (smb1cli_conn_signing_is_active(cli->conn)) {
+		d_printf("Server is signing - not testing 1MB read\n");
+		return true;
+	}
+	if (smb1cli_conn_encryption_on(cli->conn)) {
+		d_printf("Server is sealing - not testing 1MB read\n");
+		return true;
+	}
+
+	/* A read of 1MB should return 1MB bytes. */
+	req = cli_read_andx_send(talloc_tos(),
+				ev,
+				cli,
+				fnum,
+				0,
+				0x100000);
+
+	if (!tevent_req_poll_ntstatus(req, ev, &status)) {
+		return false;
+	}
+
+	status = cli_read_andx_recv(req, &len_read, &buf);
+	if (!NT_STATUS_IS_OK(status)) {
+		d_printf("cli_read_andx_recv failed: %s\n", nt_errstr(status));
+		return false;
+	}
+
+	if (len_read == 0x10000) {
+		/* Windows servers only return a max of 0x10000,
+		   doesn't matter if you set CAP_LARGE_READX in
+		   the client sessionsetupX call or not. */
+		d_printf("Windows server - returned 0x10000 on a read of 0x100000\n");
+	} else if (len_read != 0x100000) {
+		d_printf("read of 0x100000 failed: %d\n", (int)len_read);
+		return false;
+	} else {
+		d_printf("Server supports CAP_LARGE_READX fully\n");
+	}
+
+	return true;
+}
+
+static bool run_large_readx(int dummy)
+{
+	uint8_t *buf = NULL;
+	struct cli_state *cli = NULL;
+	bool correct = false;
+	const char *fname = "\\large_readx.dat";
+	NTSTATUS status;
+	uint16_t fnum = -1;
+	uint32_t normal_caps = 0;
+	TALLOC_CTX *frame = talloc_stackframe();
+
+	printf("starting large_readx test\n");
+
+	if (!torture_open_connection(&cli, 0)) {
+		goto out;
+	}
+
+	normal_caps = smb1cli_conn_capabilities(cli->conn);
+
+	if (!(normal_caps & CAP_LARGE_READX)) {
+		d_printf("Server doesn't have CAP_LARGE_READX 0x%x\n",
+			(unsigned int)normal_caps);
+		goto out;
+	}
+
+	cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
+
+	/* Create a file of size 4MB. */
+	status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS,
+			FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
+			0, 0, &fnum);
+
+	if (!NT_STATUS_IS_OK(status)) {
+		d_printf("open %s failed: %s\n", fname, nt_errstr(status));
+		goto out;
+	}
+
+	/* Write 4MB. */
+	buf = talloc_zero_array(frame, uint8_t, 4*1024*1024);
+	if (buf == NULL) {
+		goto out;
+	}
+
+	status = cli_writeall(cli,
+				fnum,
+				0,
+				buf,
+				0,
+				4*1024*1024,
+				NULL);
+
+	if (!NT_STATUS_IS_OK(status)) {
+		d_printf("cli_writeall failed: %s\n", nt_errstr(status));
+		goto out;
+	}
+
+	/*
+	 * Mangle the cli state to allow us to do a read
+	 * with upper bytes of 0xFFFF.
+	 */
+	cli->server_posix_capabilities &= ~CIFS_UNIX_LARGE_READ_CAP;
+	smb1cli_conn_set_max_xmit(cli->conn, 0xFFFFFF00);
+	smb1cli_conn_set_capabilities(cli->conn, (normal_caps & ~CAP_LARGE_READX));
+
+	if (!large_readx_tests(cli, fnum, buf)) {
+		goto out;
+	}
+
+	status = cli_close(cli, fnum);
+	if (!NT_STATUS_IS_OK(status)) {
+		d_printf("cli_close failed: %s\n", nt_errstr(status));
+		goto out;
+	}
+
+	fnum = -1;
+
+	if (!torture_close_connection(cli)) {
+		goto out;
+	}
+
+	cli = NULL;
+
+	/*
+	 * Open a second connection ensuring we don't
+	 * announce ourselves as Samba. This way we
+	 * should elicit the same behavior from a
+	 * Samba server as we give to a Windows
+	 * or MacOSX client.
+	 */
+
+	if (!(cli = open_nbt_connection())) {
+		goto out;
+	}
+
+	/* Ensure we don't announce ourselves as Samba. */
+	status = smbXcli_negprot(cli->conn,
+				cli->timeout,
+				PROTOCOL_NT1,
+				PROTOCOL_NT1);
+	if (!NT_STATUS_IS_OK(status)) {
+		goto out;
+	}
+
+	status = cli_session_setup(cli,
+				username,
+				password,
+				strlen(password)+1,
+				password,
+				strlen(password)+1,
+				workgroup);
+	if (!NT_STATUS_IS_OK(status)) {
+		goto out;
+	}
+
+	status = cli_tree_connect(cli,
+				share,
+				"?????",
+				password,
+				strlen(password)+1);
+	if (!NT_STATUS_IS_OK(status)) {
+		goto out;
+	}
+
+	cli_set_timeout(cli, 120000); /* set a really long timeout (2 minutes) */
+
+	if (do_encrypt) {
+		if (force_cli_encryption(cli, share) == false) {
+			goto out;
+		}
+	}
+
+	normal_caps = smb1cli_conn_capabilities(cli->conn);
+
+	if (!(normal_caps & CAP_LARGE_READX)) {
+		d_printf("Server doesn't have CAP_LARGE_READX 0x%x\n",
+			(unsigned int)normal_caps);
+		goto out;
+	}
+
+	status = cli_ntcreate(cli, fname, 0, FILE_READ_DATA,
+			FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN,
+			0, 0, &fnum);
+
+	if (!NT_STATUS_IS_OK(status)) {
+		d_printf("Second open %s failed: %s\n", fname, nt_errstr(status));
+		goto out;
+	}
+
+	/*
+	 * Mangle the cli state to allow us to do a read
+	 * with upper bytes of 0xFFFF.
+	 */
+	cli->server_posix_capabilities &= ~CIFS_UNIX_LARGE_READ_CAP;
+	smb1cli_conn_set_max_xmit(cli->conn, 0xFFFFFF00);
+	smb1cli_conn_set_capabilities(cli->conn, (normal_caps & ~CAP_LARGE_READX));
+
+	if (!large_readx_tests(cli, fnum, buf)) {
+		goto out;
+	}
+
+	correct = true;
+	printf("Success on large_readx test\n");
+
+  out:
+
+	if (fnum != -1) {
+		status = cli_close(cli, fnum);
+		if (!NT_STATUS_IS_OK(status)) {
+			d_printf("cli_close failed: %s\n", nt_errstr(status));
+		}
+		fnum = -1;
+	}
+
+	status = cli_unlink(cli,
+				fname,
+				FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
+	if (!NT_STATUS_IS_OK(status)) {
+		printf("unlink failed (%s)\n", nt_errstr(status));
+	}
+
+	if (cli) {
+		if (!torture_close_connection(cli)) {
+			correct = false;
+		}
+	}
+
+	TALLOC_FREE(frame);
+
+	printf("finished large_readx test\n");
+	return correct;
+}
+
+
 static bool run_cli_echo(int dummy)
 {
 	struct cli_state *cli;
@@ -9153,6 +9506,7 @@ static struct {
 	{ "CHAIN2", run_chain2, 0},
 	{ "CHAIN3", run_chain3, 0},
 	{ "WINDOWS-WRITE", run_windows_write, 0},
+	{ "LARGE_READX", run_large_readx, 0},
 	{ "NTTRANS-CREATE", run_nttrans_create, 0},
 	{ "NTTRANS-FSCTL", run_nttrans_fsctl, 0},
 	{ "CLI_ECHO", run_cli_echo, 0},
-- 
1.8.1.3


From bbd2c04b21b55a2a014dcc106e601e15d8f34479 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Wed, 13 Mar 2013 15:44:22 -0700
Subject: [PATCH 8/9] New LARGE_READX doesn't work against ntvfs server.

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 selftest/knownfail | 1 +
 1 file changed, 1 insertion(+)

diff --git a/selftest/knownfail b/selftest/knownfail
index 180a543..cdd7227 100644
--- a/selftest/knownfail
+++ b/selftest/knownfail
@@ -13,6 +13,7 @@
 ^samba3.smbtorture_s3.plain\(dc\).DIR-CREATETIME # Fails against the s4 ntvfs server
 ^samba3.smbtorture_s3.plain\(dc\).DELETE-LN # Fails against the s4 ntvfs server
 ^samba3.smbtorture_s3.plain\(dc\).POSIX # Fails against the s4 ntvfs server
+^samba3.smbtorture_s3.plain\(dc\).LARGE_READX # Fails against the s4 ntvfs server
 ^samba3.smbtorture_s3.plain\(dc\).UID-REGRESSION-TEST # Fails against the s4 ntvfs server
 ^samba3.smbtorture_s3.plain\(dc\).SHORTNAME-TEST # Fails against the s4 ntvfs server
 ^samba3.smbtorture_s3.plain\(dc\).POSIX-APPEND # Fails against the s4 ntvfs server
-- 
1.8.1.3


From 80479ed8171ae0064cbe15ae576363242f1e27a2 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Wed, 13 Mar 2013 15:45:12 -0700
Subject: [PATCH 9/9] Add LARGE_READX test into our make test infrastructure.

Tested against non-encrypted and encrypted connections.

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 source3/selftest/tests.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py
index 30253ca..1c123f5 100755
--- a/source3/selftest/tests.py
+++ b/source3/selftest/tests.py
@@ -54,7 +54,7 @@ plantestsuite("samba3.blackbox.registry.upgrade", "s3dc:local", [os.path.join(sa
 tests = ["FDPASS", "LOCK1", "LOCK2", "LOCK3", "LOCK4", "LOCK5", "LOCK6", "LOCK7", "LOCK9",
         "UNLINK", "BROWSE", "ATTR", "TRANS2", "TORTURE",
         "OPLOCK1", "OPLOCK2", "OPLOCK4", "STREAMERROR",
-        "DIR", "DIR1", "DIR-CREATETIME", "TCON", "TCONDEV", "RW1", "RW2", "RW3", "RW-SIGNING",
+        "DIR", "DIR1", "DIR-CREATETIME", "TCON", "TCONDEV", "RW1", "RW2", "RW3", "LARGE_READX", "RW-SIGNING",
         "OPEN", "XCOPY", "RENAME", "DELETE", "DELETE-LN", "PROPERTIES", "W2K",
         "TCON2", "IOCTL", "CHKPATH", "FDSESS", "CHAIN1", "CHAIN2",
         "CHAIN3",
-- 
1.8.1.3



More information about the samba-technical mailing list