[SCM] Samba Shared Repository - branch master updated
Jeremy Allison
jra at samba.org
Wed Mar 20 14:54:02 MDT 2013
The branch, master has been updated
via 599a699 s4:torture: let raw.read accept larger reads than 0x10000
via c9066b0 s4:torture: raw.read fix large reads against windows
via df618e3 s3:selftest: Add LARGE_READX test into our make test infrastructure.
via d9afb2b s3:torture: Add new LARGE_READX test to investigate large SMBreadX behavior.
via 5a05e68 s4:smb_server: fix large read_andx requests
via fd88520 s3:smbd: Add functions calc_max_read_pdu()/calc_read_size() to work out the length we should return.
via 21707de s3:smbd: Remove server_will_accept_large_read() and erroneous comment.
via 36f6a8a s3:smbd: Fix off-by 4 error in wrap protection code in create_outbuf()
via b80111a s3:smbd: add some const to req_is_in_chain()
via be98c1c s3:smbd: remove silly (SMB_OFF_T_BITS == 64) checks
via d24b8af s3:smbd: keep global_client_caps and max_send from the first successful session setup
via 40c3db9 s3:libsmb: let cli_read_andx_create() accept any length
via 1111d46 libcli/smb: smb1cli_inbuf_parse_chain() and smb1cli_conn_dispatch_incoming() should use smb_len_tcp.
via 53d348d libcli/smb: defer failing for missing NEGOTIATE_SECURITY_SIGNATURES_ENABLED
via b041dc9 s3:libsmb: make use of SMB_CAP_LEGACY_CLIENT_MASK instead of SMB_CAP_CLIENT_MASK
via 3d7a4db libcli/smb: add SMB_CAP_LEGACY_CLIENT_MASK define
from f7564ca s3:registry accept windows like long hivenames
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 599a699adec1f8f0a432d9c34f378d48930ca29b
Author: Stefan Metzmacher <metze at samba.org>
Date: Wed Mar 20 08:49:20 2013 +0100
s4:torture: let raw.read accept larger reads than 0x10000
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
Autobuild-User(master): Jeremy Allison <jra at samba.org>
Autobuild-Date(master): Wed Mar 20 21:53:20 CET 2013 on sn-devel-104
commit c9066b057a6aa3cc1960124c9f2519413a2b57da
Author: Stefan Metzmacher <metze at samba.org>
Date: Tue Mar 19 17:11:03 2013 +0100
s4:torture: raw.read fix large reads against windows
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit df618e33ac011c018374af8da021c7b5f1cc1427
Author: Jeremy Allison <jra at samba.org>
Date: Wed Mar 13 15:45:12 2013 -0700
s3:selftest: 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>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit d9afb2b14df642de5d9225d10cc20cac7fd5133f
Author: Jeremy Allison <jra at samba.org>
Date: Wed Mar 13 15:43:21 2013 -0700
s3:torture: Add new LARGE_READX test to investigate large SMBreadX behavior.
Signed-off-by: Jeremy Allison <jra at samba.org>
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit 5a05e687ce724ea808cdb1e6627b9c67804eb879
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Mar 18 19:50:38 2013 +0100
s4:smb_server: fix large read_andx requests
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit fd88520497b4043e9d81656f7cb56a7b25245c2a
Author: Jeremy Allison <jra at samba.org>
Date: Fri Mar 15 11:57:48 2013 -0700
s3:smbd: Add functions calc_max_read_pdu()/calc_read_size() to work out the length we should return.
LARGE_READX test shows it's always safe to return a short read.
Windows does so. Do the calculations to return what will fit
in a read depending on what the client negotiated.
Signed-off-by: Jeremy Allison <jra at samba.org>
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit 21707defe06e1db18a6645b0b56db4178e3df5f6
Author: Jeremy Allison <jra at samba.org>
Date: Fri Mar 15 11:53:04 2013 -0700
s3:smbd: Remove server_will_accept_large_read() and erroneous comment.
We're going to replace this with a function that calculates
the max PDU to return on a read and supports short reads.
Signed-off-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit 36f6a8abb2ad0c7d0551679cc61a29fa2dc16d80
Author: Jeremy Allison <jra at samba.org>
Date: Mon Mar 18 15:05:24 2013 -0700
s3:smbd: Fix off-by 4 error in wrap protection code in create_outbuf()
Subtract 4 from smb_size (39) here as the length
of the SMB reply following the 4 byte type+length
field can be up to 0xFFFFFF bytes.
Signed-off-by: Jeremy Allison <jra at samba.org>
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit b80111adb3a30ff386b3c45fcf962c417256bb59
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Mar 18 12:36:30 2013 +0100
s3:smbd: add some const to req_is_in_chain()
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit be98c1c889166a5f2b83e1e29d7dcbbaf6baab8f
Author: Stefan Metzmacher <metze at samba.org>
Date: Tue Mar 19 13:24:46 2013 +0100
s3:smbd: remove silly (SMB_OFF_T_BITS == 64) checks
configure will abort if sizeof(off_t) is not 8.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit d24b8afb79f75b1db9301b79862be484a4932979
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Mar 18 10:10:25 2013 +0100
s3:smbd: keep global_client_caps and max_send from the first successful session setup
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit 40c3db9b6a584a6c243fd02b12269d54e7425fea
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Mar 18 09:33:00 2013 +0100
s3:libsmb: let cli_read_andx_create() accept any length
It's up to the server to decide the allowed length.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit 1111d46cc52e868cf4894909b71f1574196e2887
Author: Jeremy Allison <jra at samba.org>
Date: Wed Mar 13 15:23:52 2013 -0700
libcli/smb: 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>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit 53d348dff082f9c18e06f99ec646127467f339e7
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Mar 18 15:02:55 2013 +0100
libcli/smb: defer failing for missing NEGOTIATE_SECURITY_SIGNATURES_ENABLED
Windows servers take a look at the FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED
flag during a session setup and turn on signing if the client requires it.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit b041dc9451e210acc82a82b75e02e4166d8973d5
Author: Stefan Metzmacher <metze at samba.org>
Date: Tue Mar 19 09:03:38 2013 +0100
s3:libsmb: make use of SMB_CAP_LEGACY_CLIENT_MASK instead of SMB_CAP_CLIENT_MASK
This should allow smbclient to keep using large reads against older Samba versions
(<= 3.6.x) and other servers that may also require this.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit 3d7a4db6bc5cd42432393bf69622c435e67e811f
Author: Stefan Metzmacher <metze at samba.org>
Date: Tue Mar 19 09:02:52 2013 +0100
libcli/smb: add SMB_CAP_LEGACY_CLIENT_MASK define
Older Samba releases (<= 3.6.x)
expect the client to send CAP_LARGE_READX
in order to let the client use large reads.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
-----------------------------------------------------------------------
Summary of changes:
libcli/smb/smbXcli_base.c | 13 ++-
libcli/smb/smb_constants.h | 10 ++
source3/libsmb/cliconnect.c | 8 +-
source3/libsmb/clireadwrite.c | 7 -
source3/selftest/tests.py | 2 +-
source3/smbd/negprot.c | 5 +-
source3/smbd/process.c | 19 ++-
source3/smbd/proto.h | 2 +-
source3/smbd/reply.c | 116 +++++++++-----
source3/smbd/sesssetup.c | 14 ++-
source3/torture/torture.c | 338 +++++++++++++++++++++++++++++++++++++++-
source4/smb_server/smb/reply.c | 18 ++-
source4/torture/raw/read.c | 18 +--
13 files changed, 482 insertions(+), 88 deletions(-)
Changeset truncated at 500 lines:
diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c
index 4c60a05..5a5828a 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;
@@ -4046,6 +4046,15 @@ static void smbXcli_negprot_smb1_done(struct tevent_req *subreq)
if (server_security_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) {
server_signing = "supported";
server_allowed = true;
+ } else if (conn->mandatory_signing) {
+ /*
+ * We have mandatory signing as client
+ * lets assume the server will look at our
+ * FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED
+ * flag in the session setup
+ */
+ server_signing = "not announced";
+ server_allowed = true;
}
if (server_security_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) {
server_signing = "required";
diff --git a/libcli/smb/smb_constants.h b/libcli/smb/smb_constants.h
index f1ecbe9..6dd7b28 100644
--- a/libcli/smb/smb_constants.h
+++ b/libcli/smb/smb_constants.h
@@ -253,6 +253,16 @@ enum smb_signing_setting {
#define SMB_CAP_CLIENT_MASK ( \
CAP_DYNAMIC_REAUTH | \
0)
+/*
+ * Older Samba releases (<= 3.6.x)
+ * expect the client to send CAP_LARGE_READX
+ * in order to let the client use large reads.
+ */
+#define SMB_CAP_LEGACY_CLIENT_MASK ( \
+ SMB_CAP_CLIENT_MASK | \
+ CAP_LARGE_READX | \
+ CAP_LARGE_WRITEX | \
+ 0)
/* Client-side offline caching policy types */
enum csc_policy {
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index 52d8e0c..872900c 100644
--- a/source3/libsmb/cliconnect.c
+++ b/source3/libsmb/cliconnect.c
@@ -341,9 +341,13 @@ static uint32_t cli_session_setup_capabilities(struct cli_state *cli,
* - client only flags
* - flags used in both directions
*
- * We do not echo the server only flags.
+ * We do not echo the server only flags, except some legacy flags.
+ *
+ * SMB_CAP_LEGACY_CLIENT_MASK contains CAP_LARGE_READX and
+ * CAP_LARGE_WRITEX in order to allow us to do large reads
+ * against old Samba releases (<= 3.6.x).
*/
- client_capabilities &= (SMB_CAP_BOTH_MASK | SMB_CAP_CLIENT_MASK);
+ client_capabilities &= (SMB_CAP_BOTH_MASK | SMB_CAP_LEGACY_CLIENT_MASK);
/*
* Session Setup specific flags CAP_DYNAMIC_REAUTH
diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c
index 75c1683..47e7f1b 100644
--- a/source3/libsmb/clireadwrite.c
+++ b/source3/libsmb/clireadwrite.c
@@ -132,13 +132,6 @@ struct tevent_req *cli_read_andx_create(TALLOC_CTX *mem_ctx,
struct cli_read_andx_state *state;
uint8_t wct = 10;
- if (size > cli_read_max_bufsize(cli)) {
- DEBUG(0, ("cli_read_andx_send got size=%d, can only handle "
- "size=%d\n", (int)size,
- (int)cli_read_max_bufsize(cli)));
- return NULL;
- }
-
req = tevent_req_create(mem_ctx, &state, struct cli_read_andx_state);
if (req == NULL) {
return NULL;
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",
diff --git a/source3/smbd/negprot.c b/source3/smbd/negprot.c
index e33350c..cfe0983 100644
--- a/source3/smbd/negprot.c
+++ b/source3/smbd/negprot.c
@@ -284,11 +284,10 @@ static void reply_nt1(struct smb_request *req, uint16 choice)
capabilities |= CAP_UNIX;
}
- if (lp_large_readwrite() && (SMB_OFF_T_BITS == 64))
+ if (lp_large_readwrite())
capabilities |= CAP_LARGE_READX|CAP_LARGE_WRITEX|CAP_W2K_SMBS;
- if (SMB_OFF_T_BITS == 64)
- capabilities |= CAP_LARGE_FILES;
+ capabilities |= CAP_LARGE_FILES;
if (lp_readraw() && lp_writeraw())
capabilities |= CAP_RAW_MODE;
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 1640cca..1ebda79 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -1270,11 +1270,13 @@ static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
const char *inbuf, char **outbuf, uint8_t num_words,
uint32_t num_bytes)
{
+ size_t smb_len = MIN_SMB_SIZE + VWV(num_words) + num_bytes;
+
/*
- * Protect against integer wrap
- */
- if ((num_bytes > 0xffffff)
- || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
+ * Protect against integer wrap.
+ * The SMB layer reply can be up to 0xFFFFFF bytes.
+ */
+ if ((num_bytes > 0xffffff) || (smb_len > 0xffffff)) {
char *msg;
if (asprintf(&msg, "num_bytes too large: %u",
(unsigned)num_bytes) == -1) {
@@ -1283,8 +1285,11 @@ static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
smb_panic(msg);
}
+ /*
+ * Here we include the NBT header for now.
+ */
*outbuf = talloc_array(mem_ctx, char,
- smb_size + num_words*2 + num_bytes);
+ NBT_HDR_SIZE + smb_len);
if (*outbuf == NULL) {
return false;
}
@@ -1296,7 +1301,7 @@ static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
* himself
*/
if (num_words != 0) {
- memset(*outbuf + smb_vwv0, 0, num_words*2);
+ memset(*outbuf + (NBT_HDR_SIZE + HDR_VWV), 0, VWV(num_words));
}
return true;
@@ -3631,7 +3636,7 @@ void smbd_process(struct tevent_context *ev_ctx,
exit_server_cleanly(NULL);
}
-bool req_is_in_chain(struct smb_request *req)
+bool req_is_in_chain(const struct smb_request *req)
{
if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
/*
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index bd22dd3..7e13049 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -801,7 +801,7 @@ bool smb1_parse_chain(TALLOC_CTX *mem_ctx, const uint8_t *buf,
struct smbd_server_connection *sconn,
bool encrypted, uint32_t seqnum,
struct smb_request ***reqs, unsigned *num_reqs);
-bool req_is_in_chain(struct smb_request *req);
+bool req_is_in_chain(const struct smb_request *req);
void smbd_process(struct tevent_context *ev_ctx,
struct messaging_context *msg_ctx,
int sock_fd,
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index 2c31f15..8b500c5 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -3848,23 +3848,81 @@ nosendfile_read:
}
/****************************************************************************
- MacOSX clients send large reads without telling us they are going to do that.
- 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.
+ Work out how much space we have for a read return.
****************************************************************************/
-static bool server_will_accept_large_read(void)
+static size_t calc_max_read_pdu(const struct smb_request *req)
{
- /* Samba client ? No problem. */
- if (get_remote_arch() == RA_SAMBA) {
- return true;
+ if (req->sconn->conn->protocol < PROTOCOL_NT1) {
+ return req->sconn->smb1.sessions.max_send;
}
- /* Need UNIX extensions. */
+
+ if (!lp_large_readwrite()) {
+ return req->sconn->smb1.sessions.max_send;
+ }
+
+ if (req_is_in_chain(req)) {
+ return req->sconn->smb1.sessions.max_send;
+ }
+
+ if (req->encrypted) {
+ /*
+ * Don't take encrypted traffic up to the
+ * limit. There are padding considerations
+ * that make that tricky.
+ */
+ return req->sconn->smb1.sessions.max_send;
+ }
+
+ if (srv_is_signing_active(req->sconn)) {
+ return 0x1FFFF;
+ }
+
if (!lp_unix_extensions()) {
- return false;
+ return 0x1FFFF;
}
- return true;
+
+ /*
+ * We can do ultra-large POSIX reads.
+ */
+ return 0xFFFFFF;
+}
+
+/****************************************************************************
+ Calculate how big a read can be. Copes with all clients. It's always
+ safe to return a short read - Windows does this.
+****************************************************************************/
+
+static size_t calc_read_size(const struct smb_request *req,
+ size_t upper_size,
+ size_t lower_size)
+{
+ size_t max_pdu = calc_max_read_pdu(req);
+ size_t total_size = 0;
+ size_t hdr_len = MIN_SMB_SIZE + VWV(12);
+ size_t max_len = max_pdu - hdr_len;
+
+ /*
+ * 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) {
+ upper_size = 0;
+ }
+
+ if (req->sconn->conn->protocol < PROTOCOL_NT1) {
+ upper_size = 0;
+ }
+
+ total_size = ((upper_size<<16) | lower_size);
+
+ /*
+ * LARGE_READX test shows it's always safe to return
+ * a short read. Windows does so.
+ */
+ return MIN(total_size, max_len);
}
/****************************************************************************
@@ -3913,38 +3971,14 @@ 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()) {
+ smb_maxcnt = calc_read_size(req, upper_size, smb_maxcnt);
+ if (smb_maxcnt > (0x1FFFF - (MIN_SMB_SIZE + VWV(12)))) {
/*
- * 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.
+ * This is a heuristic to avoid keeping large
+ * outgoing buffers around over long-lived aio
+ * requests.
*/
- smb_maxcnt |= (upper_size<<16);
- if (upper_size > 1) {
- /* Can't do this on a chained packet. */
- if ((CVAL(req->vwv+0, 0) != 0xFF)) {
- reply_nterror(req, NT_STATUS_NOT_SUPPORTED);
- END_PROFILE(SMBreadX);
- return;
- }
- /* We currently don't do this on signed or sealed data. */
- if (srv_is_signing_active(req->sconn) ||
- is_encrypted_packet(req->sconn, req->inbuf)) {
- reply_nterror(req, NT_STATUS_NOT_SUPPORTED);
- END_PROFILE(SMBreadX);
- return;
- }
- /* Is there room in the reply for this data ? */
- if (smb_maxcnt > (0xFFFFFF - (smb_size -4 + 12*2))) {
- reply_nterror(req,
- NT_STATUS_INVALID_PARAMETER);
- END_PROFILE(SMBreadX);
- return;
- }
- big_readX = True;
- }
+ big_readX = True;
}
if (req->wct == 12) {
diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c
index 890189c..4728759 100644
--- a/source3/smbd/sesssetup.c
+++ b/source3/smbd/sesssetup.c
@@ -132,11 +132,12 @@ static void reply_sesssetup_and_X_spnego(struct smb_request *req)
uint16_t action = 0;
NTTIME now = timeval_to_nttime(&req->request_time);
struct smbXsrv_session *session = NULL;
+ uint16_t smb_bufsize = SVAL(req->vwv+2, 0);
uint32_t client_caps = IVAL(req->vwv+10, 0);
DEBUG(3,("Doing spnego session setup\n"));
- if (global_client_caps == 0) {
+ if (!sconn->smb1.sessions.done_sesssetup) {
global_client_caps = client_caps;
if (!(global_client_caps & CAP_STATUS32)) {
@@ -377,6 +378,12 @@ static void reply_sesssetup_and_X_spnego(struct smb_request *req)
return;
}
+ if (!sconn->smb1.sessions.done_sesssetup) {
+ sconn->smb1.sessions.max_send =
+ MIN(sconn->smb1.sessions.max_send,smb_bufsize);
+ }
+ sconn->smb1.sessions.done_sesssetup = true;
+
/* current_user_info is changed on new vuid */
reload_services(sconn, conn_snum_used, true);
} else if (NT_STATUS_IS_OK(status)) {
@@ -560,7 +567,7 @@ static void setup_new_vc_session(struct smbd_server_connection *sconn)
void reply_sesssetup_and_X(struct smb_request *req)
{
uint64_t sess_vuid;
- int smb_bufsize;
+ uint16_t smb_bufsize;
DATA_BLOB lm_resp;
DATA_BLOB nt_resp;
DATA_BLOB plaintext_password;
@@ -671,8 +678,7 @@ void reply_sesssetup_and_X(struct smb_request *req)
const uint8_t *save_p = req->buf;
uint16 byte_count;
-
- if(global_client_caps == 0) {
+ if (!sconn->smb1.sessions.done_sesssetup) {
global_client_caps = IVAL(req->vwv+11, 0);
if (!(global_client_caps & CAP_STATUS32)) {
diff --git a/source3/torture/torture.c b/source3/torture/torture.c
index 93b9cfd..3c6db30 100644
--- a/source3/torture/torture.c
+++ b/source3/torture/torture.c
@@ -65,7 +65,7 @@ static fstring multishare_conn_fname;
static bool use_multishare_conn = False;
static bool do_encrypt;
static const char *local_path = NULL;
-static int signing_state = SMB_SIGNING_DEFAULT;
+static enum smb_signing_setting signing_state = SMB_SIGNING_DEFAULT;
char *test_filename;
bool torture_showall = False;
@@ -7239,6 +7239,341 @@ static bool run_windows_write(int dummy)
return ret;
}
+static size_t calc_expected_return(struct cli_state *cli, size_t len_requested)
+{
+ size_t max_pdu = 0x1FFFF;
+
+ if (cli->server_posix_capabilities & CIFS_UNIX_LARGE_READ_CAP) {
+ max_pdu = 0xFFFFFF;
+ }
+
+ if (smb1cli_conn_signing_is_active(cli->conn)) {
+ max_pdu = 0x1FFFF;
+ }
+
+ if (smb1cli_conn_encryption_on(cli->conn)) {
+ max_pdu = CLI_BUFFER_SIZE;
+ }
+
+ if ((len_requested & 0xFFFF0000) == 0xFFFF0000) {
+ len_requested &= 0xFFFF;
+ }
+
+ return MIN(len_requested, max_pdu - (MIN_SMB_SIZE + VWV(12)));
+}
+
+static bool check_read_call(struct cli_state *cli,
+ uint16_t fnum,
+ uint8_t *buf,
+ size_t len_requested)
+{
+ NTSTATUS status;
+ struct tevent_req *subreq = NULL;
+ ssize_t len_read = 0;
+ size_t len_expected = 0;
+ struct tevent_context *ev = NULL;
+
+ ev = samba_tevent_context_init(talloc_tos());
+ if (ev == NULL) {
+ return false;
+ }
+
+ subreq = cli_read_andx_send(talloc_tos(),
+ ev,
+ cli,
+ fnum,
+ 0,
+ len_requested);
+
+ if (!tevent_req_poll_ntstatus(subreq, ev, &status)) {
+ return false;
+ }
+
+ status = cli_read_andx_recv(subreq, &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(subreq);
+ TALLOC_FREE(ev);
+
+ len_expected = calc_expected_return(cli, len_requested);
+
+ if (len_expected > 0x10000 && 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 0x%x\n",
+ (unsigned int)len_requested);
+ } else if (len_read != len_expected) {
+ d_printf("read of 0x%x failed: got 0x%x, expected 0x%x\n",
+ (unsigned int)len_requested,
+ (unsigned int)len_read,
+ (unsigned int)len_expected);
+ return false;
+ } else {
+ d_printf("Correct read reply.\n");
+ }
+
+ return true;
+}
+
+/* Test large readX variants. */
+static bool large_readx_tests(struct cli_state *cli,
+ uint16_t fnum,
+ uint8_t *buf)
+{
+ /* A read of 0xFFFF0001 should *always* return 1 byte. */
+ if (check_read_call(cli, fnum, buf, 0xFFFF0001) == false) {
+ return false;
+ }
+ /* A read of 0x10000 should return 0x10000 bytes. */
+ if (check_read_call(cli, fnum, buf, 0x10000) == false) {
+ return false;
+ }
+ /* A read of 0x10000 should return 0x10001 bytes. */
+ if (check_read_call(cli, fnum, buf, 0x10001) == false) {
+ return false;
+ }
--
Samba Shared Repository
More information about the samba-cvs
mailing list