The Samba-Bugzilla – Attachment 8667 Details for
Bug 9706
Parameter is incorrect on Android
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
git-am fix for 4.0.x.
large-read-4.0.patches (text/plain), 34.69 KB, created by
Jeremy Allison
on 2013-03-20 19:39:50 UTC
(
hide
)
Description:
git-am fix for 4.0.x.
Filename:
MIME Type:
Creator:
Jeremy Allison
Created:
2013-03-20 19:39:50 UTC
Size:
34.69 KB
patch
obsolete
>From 73d7c14fadeb735c51d9039375b40b21950f9fcf Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 19 Mar 2013 09:02:52 +0100 >Subject: [PATCH 01/16] 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@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >--- > libcli/smb/smb_constants.h | 10 ++++++++++ > 1 file changed, 10 insertions(+) > >diff --git a/libcli/smb/smb_constants.h b/libcli/smb/smb_constants.h >index 8cb3b6e..bcfd84e 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 { >-- >1.8.1.3 > > >From 1b24d5d7e15ee40509f81ae64893f38b9ed7f5cb Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 19 Mar 2013 09:03:38 +0100 >Subject: [PATCH 02/16] 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@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >--- > source3/libsmb/cliconnect.c | 8 ++++++-- > 1 file changed, 6 insertions(+), 2 deletions(-) > >diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c >index 9ce013e..d1e161f 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 >-- >1.8.1.3 > > >From 705f9c20aa1f37a9af5c181d113957ce99deb5fe Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Mon, 18 Mar 2013 15:02:55 +0100 >Subject: [PATCH 03/16] 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@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >--- > libcli/smb/smbXcli_base.c | 9 +++++++++ > 1 file changed, 9 insertions(+) > >diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c >index c547515..2523dfb 100644 >--- a/libcli/smb/smbXcli_base.c >+++ b/libcli/smb/smbXcli_base.c >@@ -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"; >-- >1.8.1.3 > > >From 6cbbf63036cae745fcd0a27190c459e71ed3ce48 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Wed, 13 Mar 2013 15:23:52 -0700 >Subject: [PATCH 04/16] 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@samba.org> >Reviewed-by: Stefan Metzmacher <metze@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 2523dfb..c971a6d 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 c6f8bbaa0a8d9c0c8fe60dfd304ae8bc39d2c554 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Mon, 18 Mar 2013 09:33:00 +0100 >Subject: [PATCH 05/16] 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@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >--- > source3/libsmb/clireadwrite.c | 7 ------- > 1 file changed, 7 deletions(-) > >diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c >index 3cc6cf8..c429d30 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; >-- >1.8.1.3 > > >From 1a596a7b46d89489f94ed970cea3ed6eb105cc92 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Mon, 18 Mar 2013 10:10:25 +0100 >Subject: [PATCH 06/16] s3:smbd: keep global_client_caps and max_send from the > first successful session setup > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >--- > source3/smbd/sesssetup.c | 14 ++++++++++---- > 1 file changed, 10 insertions(+), 4 deletions(-) > >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)) { >-- >1.8.1.3 > > >From 8b805f9a8fb692691c8a85971edb55bd0b3fb0c0 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 19 Mar 2013 13:24:46 +0100 >Subject: [PATCH 07/16] 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@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >--- > source3/smbd/negprot.c | 5 ++--- > 1 file changed, 2 insertions(+), 3 deletions(-) > >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; >-- >1.8.1.3 > > >From 804f5749f8622768ac7e4925fc78bcd07f9fe234 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Mon, 18 Mar 2013 12:36:30 +0100 >Subject: [PATCH 08/16] s3:smbd: add some const to req_is_in_chain() > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >--- > source3/smbd/process.c | 2 +- > source3/smbd/proto.h | 2 +- > 2 files changed, 2 insertions(+), 2 deletions(-) > >diff --git a/source3/smbd/process.c b/source3/smbd/process.c >index e934eaa..43bf76e 100644 >--- a/source3/smbd/process.c >+++ b/source3/smbd/process.c >@@ -3631,7 +3631,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 fae1407..35ae8a2 100644 >--- a/source3/smbd/proto.h >+++ b/source3/smbd/proto.h >@@ -786,7 +786,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, >-- >1.8.1.3 > > >From 77cb710192e1a0bd6204a0a87ad3642e59c040a6 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Mon, 18 Mar 2013 15:05:24 -0700 >Subject: [PATCH 09/16] 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@samba.org> >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >--- > source3/smbd/process.c | 17 +++++++++++------ > 1 file changed, 11 insertions(+), 6 deletions(-) > >diff --git a/source3/smbd/process.c b/source3/smbd/process.c >index 43bf76e..f03a20f 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; >-- >1.8.1.3 > > >From 3e9234b1ec071457e3f03f2270b6d778c66df2e0 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Fri, 15 Mar 2013 11:53:04 -0700 >Subject: [PATCH 10/16] 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@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >--- > source3/smbd/reply.c | 29 +---------------------------- > 1 file changed, 1 insertion(+), 28 deletions(-) > >diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c >index 1c5627c..ffc5ff7 100644 >--- a/source3/smbd/reply.c >+++ b/source3/smbd/reply.c >@@ -3848,26 +3848,6 @@ 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. >-****************************************************************************/ >- >-static bool server_will_accept_large_read(void) >-{ >- /* Samba client ? No problem. */ >- if (get_remote_arch() == RA_SAMBA) { >- return true; >- } >- /* Need UNIX extensions. */ >- if (!lp_unix_extensions()) { >- return false; >- } >- return true; >-} >- >-/**************************************************************************** > Reply to a read and X. > ****************************************************************************/ > >@@ -3913,14 +3893,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()) { >- /* >- * 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. >- */ >+ if (upper_size != 0) { > smb_maxcnt |= (upper_size<<16); > if (upper_size > 1) { > /* Can't do this on a chained packet. */ >-- >1.8.1.3 > > >From 9b5751b4ae77ac6a46820350377b26765ca8844f Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Fri, 15 Mar 2013 11:57:48 -0700 >Subject: [PATCH 11/16] 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@samba.org> >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >--- > source3/smbd/reply.c | 111 +++++++++++++++++++++++++++++++++++++++------------ > 1 file changed, 86 insertions(+), 25 deletions(-) > >diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c >index ffc5ff7..2326015 100644 >--- a/source3/smbd/reply.c >+++ b/source3/smbd/reply.c >@@ -3848,6 +3848,84 @@ nosendfile_read: > } > > /**************************************************************************** >+ Work out how much space we have for a read return. >+****************************************************************************/ >+ >+static size_t calc_max_read_pdu(const struct smb_request *req) >+{ >+ if (req->sconn->conn->protocol < PROTOCOL_NT1) { >+ return req->sconn->smb1.sessions.max_send; >+ } >+ >+ 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 0x1FFFF; >+ } >+ >+ /* >+ * 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); >+} >+ >+/**************************************************************************** > Reply to a read and X. > ****************************************************************************/ > >@@ -3893,31 +3971,14 @@ void reply_read_and_X(struct smb_request *req) > } > > upper_size = SVAL(req->vwv+7, 0); >- if (upper_size != 0) { >- 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; >- } >+ smb_maxcnt = calc_read_size(req, upper_size, smb_maxcnt); >+ if (smb_maxcnt > (0x1FFFF - (MIN_SMB_SIZE + VWV(12)))) { >+ /* >+ * This is a heuristic to avoid keeping large >+ * outgoing buffers around over long-lived aio >+ * requests. >+ */ >+ big_readX = True; > } > > if (req->wct == 12) { >-- >1.8.1.3 > > >From 608106f67a4f411dba096d104a9258401a67211c Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Mon, 18 Mar 2013 19:50:38 +0100 >Subject: [PATCH 12/16] s4:smb_server: fix large read_andx requests > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >--- > source4/smb_server/smb/reply.c | 18 ++++++++++++------ > 1 file changed, 12 insertions(+), 6 deletions(-) > >diff --git a/source4/smb_server/smb/reply.c b/source4/smb_server/smb/reply.c >index bae6b2c..7ce5f5d 100644 >--- a/source4/smb_server/smb/reply.c >+++ b/source4/smb_server/smb/reply.c >@@ -848,6 +848,7 @@ static void reply_read_and_X_send(struct ntvfs_request *ntvfs) > void smbsrv_reply_read_and_X(struct smbsrv_request *req) > { > union smb_read *io; >+ uint16_t high_part = 0; > > /* parse request */ > if (req->in.wct != 12) { >@@ -869,13 +870,18 @@ void smbsrv_reply_read_and_X(struct smbsrv_request *req) > io->readx.in.read_for_execute = false; > } > >- if (req->smb_conn->negotiate.client_caps & CAP_LARGE_READX) { >- uint32_t high_part = IVAL(req->in.vwv, VWV(7)); >- if (high_part == 1) { >- io->readx.in.maxcnt |= high_part << 16; >- } >+ if (req->smb_conn->negotiate.protocol == PROTOCOL_NT1) { >+ high_part = SVAL(req->in.vwv, VWV(7)); > } >- >+ if (high_part != UINT16_MAX) { >+ io->readx.in.maxcnt |= high_part << 16; >+ } >+ >+ /* >+ * Windows truncates the length to 0x10000 >+ */ >+ io->readx.in.maxcnt = MIN(io->readx.in.maxcnt, 0x10000); >+ > /* the 64 bit variant */ > if (req->in.wct == 12) { > uint32_t offset_high = IVAL(req->in.vwv, VWV(10)); >-- >1.8.1.3 > > >From 822e7d7d8c84c8b756e13c00dc870a7964ac54cc Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Wed, 13 Mar 2013 15:43:21 -0700 >Subject: [PATCH 13/16] s3:torture: Add new LARGE_READX test to investigate > large SMBreadX behavior. > >Signed-off-by: Jeremy Allison <jra@samba.org> >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >--- > source3/torture/torture.c | 338 +++++++++++++++++++++++++++++++++++++++++++++- > 1 file changed, 337 insertions(+), 1 deletion(-) > >diff --git a/source3/torture/torture.c b/source3/torture/torture.c >index cd885a1..21dcf9b 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; >@@ -7237,6 +7237,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 = 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; >+ } >+ /* A read of 0x1FFFF - (MIN_SMB_SIZE + VWV(12) should return >+ the requested number of bytes. */ >+ if (check_read_call(cli, fnum, buf, 0x1FFFF - (MIN_SMB_SIZE + VWV(12))) == false) { >+ return false; >+ } >+ /* A read of 1MB should return 1MB bytes (on Samba). */ >+ if (check_read_call(cli, fnum, buf, 0x100000) == false) { >+ return false; >+ } >+ >+ if (check_read_call(cli, fnum, buf, 0x20001) == false) { >+ return false; >+ } >+ if (check_read_call(cli, fnum, buf, 0x22000001) == false) { >+ return false; >+ } >+ if (check_read_call(cli, fnum, buf, 0xFFFE0001) == false) { >+ return false; >+ } >+ return true; >+} >+ >+static bool run_large_readx(int dummy) >+{ >+ uint8_t *buf = NULL; >+ struct cli_state *cli1 = NULL; >+ struct cli_state *cli2 = NULL; >+ bool correct = false; >+ const char *fname = "\\large_readx.dat"; >+ NTSTATUS status; >+ uint16_t fnum1 = UINT16_MAX; >+ uint32_t normal_caps = 0; >+ size_t file_size = 20*1024*1024; >+ TALLOC_CTX *frame = talloc_stackframe(); >+ size_t i; >+ struct { >+ const char *name; >+ enum smb_signing_setting signing_setting; >+ enum protocol_types protocol; >+ } runs[] = { >+ { >+ .name = "NT1", >+ .signing_setting = SMB_SIGNING_IF_REQUIRED, >+ .protocol = PROTOCOL_NT1, >+ },{ >+ .name = "NT1 - SIGNING_REQUIRED", >+ .signing_setting = SMB_SIGNING_REQUIRED, >+ .protocol = PROTOCOL_NT1, >+ }, >+ }; >+ >+ printf("starting large_readx test\n"); >+ >+ if (!torture_open_connection(&cli1, 0)) { >+ goto out; >+ } >+ >+ normal_caps = smb1cli_conn_capabilities(cli1->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; >+ } >+ >+ /* Create a file of size 4MB. */ >+ status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS, >+ FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, >+ 0, 0, &fnum1); >+ >+ if (!NT_STATUS_IS_OK(status)) { >+ d_printf("open %s failed: %s\n", fname, nt_errstr(status)); >+ goto out; >+ } >+ >+ /* Write file_size bytes. */ >+ buf = talloc_zero_array(frame, uint8_t, file_size); >+ if (buf == NULL) { >+ goto out; >+ } >+ >+ status = cli_writeall(cli1, >+ fnum1, >+ 0, >+ buf, >+ 0, >+ file_size, >+ NULL); >+ if (!NT_STATUS_IS_OK(status)) { >+ d_printf("cli_writeall failed: %s\n", nt_errstr(status)); >+ goto out; >+ } >+ >+ status = cli_close(cli1, fnum1); >+ if (!NT_STATUS_IS_OK(status)) { >+ d_printf("cli_close failed: %s\n", nt_errstr(status)); >+ goto out; >+ } >+ >+ fnum1 = UINT16_MAX; >+ >+ for (i=0; i < ARRAY_SIZE(runs); i++) { >+ enum smb_signing_setting saved_signing_setting = signing_state; >+ uint16_t fnum2 = -1; >+ >+ if (do_encrypt && >+ (runs[i].signing_setting == SMB_SIGNING_REQUIRED)) >+ { >+ d_printf("skip[%u] - %s\n", (unsigned)i, runs[i].name); >+ continue; >+ } >+ >+ d_printf("run[%u] - %s\n", (unsigned)i, runs[i].name); >+ >+ signing_state = runs[i].signing_setting; >+ cli2 = open_nbt_connection(); >+ signing_state = saved_signing_setting; >+ if (cli2 == NULL) { >+ goto out; >+ } >+ >+ status = smbXcli_negprot(cli2->conn, >+ cli2->timeout, >+ runs[i].protocol, >+ runs[i].protocol); >+ if (!NT_STATUS_IS_OK(status)) { >+ goto out; >+ } >+ >+ status = cli_session_setup(cli2, >+ username, >+ password, >+ strlen(password)+1, >+ password, >+ strlen(password)+1, >+ workgroup); >+ if (!NT_STATUS_IS_OK(status)) { >+ goto out; >+ } >+ >+ status = cli_tree_connect(cli2, >+ share, >+ "?????", >+ password, >+ strlen(password)+1); >+ if (!NT_STATUS_IS_OK(status)) { >+ goto out; >+ } >+ >+ cli_set_timeout(cli2, 120000); /* set a really long timeout (2 minutes) */ >+ >+ normal_caps = smb1cli_conn_capabilities(cli2->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; >+ } >+ >+ if (do_encrypt) { >+ if (force_cli_encryption(cli2, share) == false) { >+ goto out; >+ } >+ } else if (SERVER_HAS_UNIX_CIFS(cli2)) { >+ uint16_t major, minor; >+ uint32_t caplow, caphigh; >+ >+ status = cli_unix_extensions_version(cli2, >+ &major, &minor, >+ &caplow, &caphigh); >+ if (!NT_STATUS_IS_OK(status)) { >+ goto out; >+ } >+ } >+ >+ status = cli_ntcreate(cli2, fname, 0, FILE_READ_DATA, >+ FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN, >+ 0, 0, &fnum2); >+ if (!NT_STATUS_IS_OK(status)) { >+ d_printf("Second open %s failed: %s\n", fname, nt_errstr(status)); >+ goto out; >+ } >+ >+ /* All reads must return less than file_size bytes. */ >+ if (!large_readx_tests(cli2, fnum2, buf)) { >+ goto out; >+ } >+ >+ status = cli_close(cli2, fnum2); >+ if (!NT_STATUS_IS_OK(status)) { >+ d_printf("cli_close failed: %s\n", nt_errstr(status)); >+ goto out; >+ } >+ fnum2 = -1; >+ >+ if (!torture_close_connection(cli2)) { >+ goto out; >+ } >+ cli2 = NULL; >+ } >+ >+ correct = true; >+ printf("Success on large_readx test\n"); >+ >+ out: >+ >+ if (cli2) { >+ if (!torture_close_connection(cli2)) { >+ correct = false; >+ } >+ } >+ >+ if (cli1) { >+ if (fnum1 != UINT16_MAX) { >+ status = cli_close(cli1, fnum1); >+ if (!NT_STATUS_IS_OK(status)) { >+ d_printf("cli_close failed: %s\n", nt_errstr(status)); >+ } >+ fnum1 = UINT16_MAX; >+ } >+ >+ status = cli_unlink(cli1, fname, >+ FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); >+ if (!NT_STATUS_IS_OK(status)) { >+ printf("unlink failed (%s)\n", nt_errstr(status)); >+ } >+ >+ if (!torture_close_connection(cli1)) { >+ correct = false; >+ } >+ } >+ >+ TALLOC_FREE(frame); >+ >+ printf("finished large_readx test\n"); >+ return correct; >+} >+ > static bool run_cli_echo(int dummy) > { > struct cli_state *cli; >@@ -9151,6 +9486,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 a583f665617302e4e554e01014eb34aeaaece16c Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Wed, 13 Mar 2013 15:45:12 -0700 >Subject: [PATCH 14/16] s3:selftest: Add LARGE_READX test into our make test > infrastructure. > >Tested against non-encrypted and encrypted connections. > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Stefan Metzmacher <metze@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 57c80f2..4453c4d 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 > > >From 6aabf00e5d4dbab653bc60164d855e2f8452541f Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 19 Mar 2013 17:11:03 +0100 >Subject: [PATCH 15/16] s4:torture: raw.read fix large reads against windows > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >--- > source4/torture/raw/read.c | 12 +++--------- > 1 file changed, 3 insertions(+), 9 deletions(-) > >diff --git a/source4/torture/raw/read.c b/source4/torture/raw/read.c >index 6586177..5a5ffee 100644 >--- a/source4/torture/raw/read.c >+++ b/source4/torture/raw/read.c >@@ -529,7 +529,7 @@ static bool test_readx(struct torture_context *tctx, struct smbcli_state *cli) > printf("SAMBA: large read extension\n"); > CHECK_VALUE(io.readx.out.nread, 80000); > } else { >- CHECK_VALUE(io.readx.out.nread, 0); >+ CHECK_VALUE(io.readx.out.nread, 0x10000); > } > CHECK_BUFFER(buf, seed, io.readx.out.nread); > >@@ -569,13 +569,7 @@ static bool test_readx(struct torture_context *tctx, struct smbcli_state *cli) > io.readx.in.maxcnt = 0x10000; > status = smb_raw_read(cli->tree, &io); > CHECK_STATUS(status, NT_STATUS_OK); >- if (torture_setting_bool(tctx, "samba3", false) || >- torture_setting_bool(tctx, "samba4", false)) { >- printf("SAMBA: large read extension\n"); >- CHECK_VALUE(io.readx.out.nread, 0x10000); >- } else { >- CHECK_VALUE(io.readx.out.nread, 0); >- } >+ CHECK_VALUE(io.readx.out.nread, 0x10000); > > io.readx.in.maxcnt = 0x10001; > status = smb_raw_read(cli->tree, &io); >@@ -585,7 +579,7 @@ static bool test_readx(struct torture_context *tctx, struct smbcli_state *cli) > printf("SAMBA: large read extension\n"); > CHECK_VALUE(io.readx.out.nread, 0x10001); > } else { >- CHECK_VALUE(io.readx.out.nread, 0); >+ CHECK_VALUE(io.readx.out.nread, 0x10000); > } > } else { > printf("Server does not support the CAP_LARGE_READX extension\n"); >-- >1.8.1.3 > > >From d51a804664e5525c12d979da7788a4aa21e42af3 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 20 Mar 2013 08:49:20 +0100 >Subject: [PATCH 16/16] s4:torture: let raw.read accept larger reads than > 0x10000 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >--- > source4/torture/raw/read.c | 6 ++---- > 1 file changed, 2 insertions(+), 4 deletions(-) > >diff --git a/source4/torture/raw/read.c b/source4/torture/raw/read.c >index 5a5ffee..59089bf 100644 >--- a/source4/torture/raw/read.c >+++ b/source4/torture/raw/read.c >@@ -524,8 +524,7 @@ static bool test_readx(struct torture_context *tctx, struct smbcli_state *cli) > CHECK_STATUS(status, NT_STATUS_OK); > CHECK_VALUE(io.readx.out.remaining, 0xFFFF); > CHECK_VALUE(io.readx.out.compaction_mode, 0); >- if (torture_setting_bool(tctx, "samba3", false) || >- torture_setting_bool(tctx, "samba4", false)) { >+ if (io.readx.out.nread == io.readx.in.maxcnt) { > printf("SAMBA: large read extension\n"); > CHECK_VALUE(io.readx.out.nread, 80000); > } else { >@@ -574,8 +573,7 @@ static bool test_readx(struct torture_context *tctx, struct smbcli_state *cli) > io.readx.in.maxcnt = 0x10001; > status = smb_raw_read(cli->tree, &io); > CHECK_STATUS(status, NT_STATUS_OK); >- if (torture_setting_bool(tctx, "samba3", false) || >- torture_setting_bool(tctx, "samba4", false)) { >+ if (io.readx.out.nread == io.readx.in.maxcnt) { > printf("SAMBA: large read extension\n"); > CHECK_VALUE(io.readx.out.nread, 0x10001); > } else { >-- >1.8.1.3 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Flags:
metze
:
review+
Actions:
View
Attachments on
bug 9706
:
8627
|
8631
|
8632
|
8637
|
8638
|
8651
|
8659
|
8663
|
8664
|
8665
|
8666
| 8667