The Samba-Bugzilla – Attachment 8216 Details for
Bug 9412
SMB2 server doesn't support recvfile.
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
test git-am fix for 3.6.x
samba3.6-smb2-recvfile.patchset (text/plain), 13.42 KB, created by
Jeremy Allison
on 2012-11-21 06:18:34 UTC
(
hide
)
Description:
test git-am fix for 3.6.x
Filename:
MIME Type:
Creator:
Jeremy Allison
Created:
2012-11-21 06:18:34 UTC
Size:
13.42 KB
patch
obsolete
>From 21d8547cca56ab5219349a64136879ab8c729f60 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Tue, 20 Nov 2012 20:58:24 -0800 >Subject: [PATCH 1/9] Ensure we don't do an SMB2 aio write if RECVFILE is > active. > >Part of bug #9412 - SMB2 server doesn't support recvfile. > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/smbd/aio.c | 5 +++++ > 1 file changed, 5 insertions(+) > >diff --git a/source3/smbd/aio.c b/source3/smbd/aio.c >index b0b90c0..2d64c55 100644 >--- a/source3/smbd/aio.c >+++ b/source3/smbd/aio.c >@@ -502,6 +502,11 @@ NTSTATUS schedule_aio_smb2_write(connection_struct *conn, > size_t min_aio_write_size = lp_aio_write_size(SNUM(conn)); > int ret; > >+ if (smbreq->unread_bytes) { >+ /* Can't do async with recvfile. */ >+ return NT_STATUS_RETRY; >+ } >+ > /* Ensure aio is initialized. */ > if (!initialize_async_io_handler()) { > return NT_STATUS_RETRY; >-- >1.7.10.4 > > >From b7d502d97e0b14c884e87e5b90b0b283bfbe86d7 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Tue, 20 Nov 2012 21:02:37 -0800 >Subject: [PATCH 2/9] If we already have an smb1req attached to the struct > smbd_smb2_request, don't recreate it. > >Part of bug #9412 - SMB2 server doesn't support recvfile. > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/smbd/smb2_glue.c | 10 +++++++--- > 1 file changed, 7 insertions(+), 3 deletions(-) > >diff --git a/source3/smbd/smb2_glue.c b/source3/smbd/smb2_glue.c >index 360a73a..311e575 100644 >--- a/source3/smbd/smb2_glue.c >+++ b/source3/smbd/smb2_glue.c >@@ -31,9 +31,13 @@ struct smb_request *smbd_smb2_fake_smb_request(struct smbd_smb2_request *req) > > inhdr = (const uint8_t *)req->in.vector[i+0].iov_base; > >- smbreq = talloc_zero(req, struct smb_request); >- if (smbreq == NULL) { >- return NULL; >+ if (req->smb1req) { >+ smbreq = req->smb1req; >+ } else { >+ smbreq = talloc_zero(req, struct smb_request); >+ if (smbreq == NULL) { >+ return NULL; >+ } > } > > smbreq->vuid = req->session->compat_vuser->vuid; >-- >1.7.10.4 > > >From ac057320a2c6bdd4e6b37db4e72d30a0644fb83e Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Tue, 20 Nov 2012 21:12:05 -0800 >Subject: [PATCH 3/9] Add function smbd_smb2_unread_bytes(). > >Returns number of bytes left to read for recvfile. Will be >used in SMB_2_WRITE_FILE code path. > >Part of bug #9412 - SMB2 server doesn't support recvfile. > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/smbd/globals.h | 1 + > source3/smbd/smb2_glue.c | 12 ++++++++++++ > 2 files changed, 13 insertions(+) > >diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h >index f515f19..24dcd3d 100644 >--- a/source3/smbd/globals.h >+++ b/source3/smbd/globals.h >@@ -276,6 +276,7 @@ NTSTATUS smbd_smb2_request_check_session(struct smbd_smb2_request *req); > NTSTATUS smbd_smb2_request_check_tcon(struct smbd_smb2_request *req); > > struct smb_request *smbd_smb2_fake_smb_request(struct smbd_smb2_request *req); >+size_t smbd_smb2_unread_bytes(struct smbd_smb2_request *req); > void remove_smb2_chained_fsp(files_struct *fsp); > > NTSTATUS smbd_smb2_request_verify_sizes(struct smbd_smb2_request *req, >diff --git a/source3/smbd/smb2_glue.c b/source3/smbd/smb2_glue.c >index 311e575..e64949d 100644 >--- a/source3/smbd/smb2_glue.c >+++ b/source3/smbd/smb2_glue.c >@@ -61,6 +61,18 @@ struct smb_request *smbd_smb2_fake_smb_request(struct smbd_smb2_request *req) > } > > /********************************************************* >+ Are there unread bytes for recvfile ? >+*********************************************************/ >+ >+size_t smbd_smb2_unread_bytes(struct smbd_smb2_request *req) >+{ >+ if (req->smb1req && req->smb1req->unread_bytes) { >+ return req->smb1req->unread_bytes; >+ } >+ return 0; >+} >+ >+/********************************************************* > Called from file_free() to remove any chained fsp pointers. > *********************************************************/ > >-- >1.7.10.4 > > >From 204522ab2e73208821db47a86eec9f39f431e50e Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Tue, 20 Nov 2012 21:21:20 -0800 >Subject: [PATCH 4/9] Allow smbd_smb2_request_process_write() to cope with > RECVFILE. > >Cope with unread_bytes in the socket buffer. > >Part of bug #9412 - SMB2 server doesn't support recvfile. > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/smbd/smb2_write.c | 13 ++++++++++++- > 1 file changed, 12 insertions(+), 1 deletion(-) > >diff --git a/source3/smbd/smb2_write.c b/source3/smbd/smb2_write.c >index 5aeed8c7..6fb0a14 100644 >--- a/source3/smbd/smb2_write.c >+++ b/source3/smbd/smb2_write.c >@@ -53,6 +53,7 @@ NTSTATUS smbd_smb2_request_process_write(struct smbd_smb2_request *req) > struct files_struct *in_fsp; > uint32_t in_flags; > struct tevent_req *subreq; >+ size_t unread_bytes; > > status = smbd_smb2_request_verify_sizes(req, 0x31); > if (!NT_STATUS_IS_OK(status)) { >@@ -74,7 +75,17 @@ NTSTATUS smbd_smb2_request_process_write(struct smbd_smb2_request *req) > return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER); > } > >- if (in_data_length > req->in.vector[i+2].iov_len) { >+ unread_bytes = smbd_smb2_unread_bytes(req); >+ if (unread_bytes) { >+ /* >+ * RECVFILE code path. Ensure we have the >+ * correct number of bytes left in the socket >+ * buffers. >+ */ >+ if (in_data_length != unread_bytes) { >+ return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER); >+ } >+ } else if (in_data_length > req->in.vector[i+2].iov_len) { > return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER); > } > >-- >1.7.10.4 > > >From e7df4d1e051c6f5b6e8e9d938379b3fbc61d713c Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Tue, 20 Nov 2012 21:24:08 -0800 >Subject: [PATCH 5/9] Allow smbd_smb2_request_verify_sizes() to cope with > unread bytes in the socket buffer (when RECVFILE is > turned on). > >Part of bug #9412 - SMB2 server doesn't support recvfile. > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/smbd/smb2_server.c | 5 +++++ > 1 file changed, 5 insertions(+) > >diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c >index a0e390e..3281b39 100644 >--- a/source3/smbd/smb2_server.c >+++ b/source3/smbd/smb2_server.c >@@ -1241,6 +1241,11 @@ NTSTATUS smbd_smb2_request_verify_sizes(struct smbd_smb2_request *req, > case SMB2_OP_GETINFO: > min_dyn_size = 0; > break; >+ case SMB2_OP_WRITE: >+ if (req->smb1req && req->smb1req->unread_bytes) { >+ min_dyn_size = 0; >+ } >+ break; > } > > /* >-- >1.7.10.4 > > >From a18990f635fcbbf82db30f8aa0853c04948f2098 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Tue, 20 Nov 2012 21:26:01 -0800 >Subject: [PATCH 6/9] Allow smbd_smb2_request_error_ex() to cope with unread > bytes on error. > >Drain the socket if a RECVFILE write failed. > >Part of bug #9412 - SMB2 server doesn't support recvfile. > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/smbd/smb2_server.c | 10 ++++++++++ > 1 file changed, 10 insertions(+) > >diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c >index 3281b39..c669f50 100644 >--- a/source3/smbd/smb2_server.c >+++ b/source3/smbd/smb2_server.c >@@ -2039,6 +2039,16 @@ NTSTATUS smbd_smb2_request_error_ex(struct smbd_smb2_request *req, > i, nt_errstr(status), info ? " +info" : "", > location)); > >+ if (req->smb1req && req->smb1req->unread_bytes) { >+ /* Recvfile error. Drain incoming socket. */ >+ if (drain_socket(req->sconn->sock, >+ req->smb1req->unread_bytes) != >+ req->smb1req->unread_bytes) >+ { >+ smb_panic("Failed to drain SMB2 socket\n"); >+ } >+ } >+ > body.data = outhdr + SMB2_HDR_BODY; > body.length = 8; > SSVAL(body.data, 0, 9); >-- >1.7.10.4 > > >From ea4f1a4973b98751fee0dfba0980f47050682ca5 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Tue, 20 Nov 2012 21:28:02 -0800 >Subject: [PATCH 7/9] Move the initialization of body vector to just after its > creation. > >Part of bug #9412 - SMB2 server doesn't support recvfile. > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/smbd/smb2_server.c | 5 +++-- > 1 file changed, 3 insertions(+), 2 deletions(-) > >diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c >index c669f50..e0c81e9 100644 >--- a/source3/smbd/smb2_server.c >+++ b/source3/smbd/smb2_server.c >@@ -2417,13 +2417,14 @@ static int smbd_smb2_request_next_vector(struct tstream_context *stream, > return -1; > } > >+ req->in.vector[idx].iov_base = (void *)body; >+ req->in.vector[idx].iov_len = body_size; >+ > dyn = talloc_array(req->in.vector, uint8_t, dyn_size); > if (dyn == NULL) { > return -1; > } > >- req->in.vector[idx].iov_base = (void *)body; >- req->in.vector[idx].iov_len = body_size; > req->in.vector[idx+1].iov_base = (void *)dyn; > req->in.vector[idx+1].iov_len = dyn_size; > >-- >1.7.10.4 > > >From 997c6ee90a081d50c10ec924d08f3faa4f268b28 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Tue, 20 Nov 2012 21:35:07 -0800 >Subject: [PATCH 8/9] Add is_smb2_recvfile_write(). > >This is the guts of the SMB2_WRITE RECVFILE detection code. > >Part of bug #9412 - SMB2 server doesn't support recvfile. > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/smbd/smb2_server.c | 96 ++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 96 insertions(+) > >diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c >index e0c81e9..93ac03d 100644 >--- a/source3/smbd/smb2_server.c >+++ b/source3/smbd/smb2_server.c >@@ -2175,6 +2175,102 @@ struct smbd_smb2_request_read_state { > struct smbd_smb2_request *smb2_req; > }; > >+static bool is_smb2_recvfile_write(struct smbd_smb2_request_read_state *state, >+ int idx, >+ size_t dyn_size) >+{ >+ const uint8_t *inhdr; >+ int min_recv_size = lp_min_receive_file_size(); >+ struct smbd_smb2_request *req = state->smb2_req; >+ uint16_t opcode; >+ uint32_t in_flags; >+ uint32_t in_tid; >+ uint64_t in_session_id; >+ void *p; >+ struct smbd_smb2_tcon *tcon; >+ struct smbd_smb2_session *session; >+ >+ if (min_recv_size == 0) { >+ /* recvfile not turned on. Nothing to do here. */ >+ return false; >+ } >+ >+ if (req->do_signing) { >+ /* Can't do recvfile on signed connection. */ >+ return false; >+ } >+ >+ if (req->in.vector[idx-1].iov_len != SMB2_HDR_BODY) { >+ /* Bad header. Let the caller deal with it. */ >+ return false; >+ } >+ >+ inhdr = (const uint8_t *)req->in.vector[idx-1].iov_base; >+ >+ opcode = SVAL(inhdr, SMB2_HDR_OPCODE); >+ if (opcode != SMB2_OP_WRITE) { >+ /* Only do recvfile in SMB2_WRITE. */ >+ return false; >+ } >+ >+ /* Check that body size == 0x30 - this is a SMB2_WRITE body */ >+ if (req->in.vector[idx].iov_len != 0x30) { >+ /* Incorrect body size. Caller handle. */ >+ return false; >+ } >+ >+ if (dyn_size == 0 || dyn_size < min_recv_size) { >+ /* Bad write, or too small for us. Caller handle. */ >+ return false; >+ } >+ >+ in_flags = IVAL(inhdr, SMB2_HDR_FLAGS); >+ if (in_flags & SMB2_HDR_FLAG_CHAINED) { >+ /* Can't do recvfile on chained requests. */ >+ return false; >+ } >+ >+ /* >+ * We have to look up the session and tree id's, >+ * as we can't do recvfile on IPC or print connections. >+ */ >+ >+ in_session_id = BVAL(inhdr, SMB2_HDR_SESSION_ID); >+ >+ /* Lookup an existing session */ >+ p = idr_find(req->sconn->smb2.sessions.idtree, in_session_id); >+ if (p == NULL) { >+ /* Bad session id. Caller handle. */ >+ return false; >+ } >+ session = talloc_get_type_abort(p, struct smbd_smb2_session); >+ if (!NT_STATUS_IS_OK(session->status)) { >+ /* Session is invalid. Caller handle. */ >+ return false; >+ } >+ >+ in_tid = IVAL(inhdr, SMB2_HDR_TID); >+ >+ /* Lookup an existing tree id to make sure it's a file share. */ >+ p = idr_find(session->tcons.idtree, in_tid); >+ if (p == NULL) { >+ /* Bad tid. Caller handle. */ >+ return false; >+ } >+ tcon = talloc_get_type_abort(p, struct smbd_smb2_tcon); >+ >+ if (IS_IPC(tcon->compat_conn) || IS_PRINT(tcon->compat_conn)) { >+ return false; >+ } >+ >+ /* >+ * OK, this is a recvfile we can handle on >+ * a file share. >+ */ >+ >+ return true; >+} >+ > static int smbd_smb2_request_next_vector(struct tstream_context *stream, > void *private_data, > TALLOC_CTX *mem_ctx, >-- >1.7.10.4 > > >From 1bb58dda689656d0ad45171aa2aeb9a4d15c670b Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Tue, 20 Nov 2012 22:17:22 -0800 >Subject: [PATCH 9/9] Plumb the new recvfile detection into the main SMB2 > server path. > >Part of bug #9412 - SMB2 server doesn't support recvfile. > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/smbd/smb2_server.c | 31 +++++++++++++++++++++++++++++++ > 1 file changed, 31 insertions(+) > >diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c >index 93ac03d..363ddef 100644 >--- a/source3/smbd/smb2_server.c >+++ b/source3/smbd/smb2_server.c >@@ -2516,6 +2516,37 @@ static int smbd_smb2_request_next_vector(struct tstream_context *stream, > req->in.vector[idx].iov_base = (void *)body; > req->in.vector[idx].iov_len = body_size; > >+ /* >+ * Might this be an SMB2_WRITE with recvfile turned on ? >+ * If so, adjust the lengths. >+ */ >+ if (!invalid && (next_command_ofs == 0)) { >+ if (is_smb2_recvfile_write(state, idx, dyn_size)) { >+ /* >+ * Adjust the sizes to ignore >+ * the write data left in the TCP >+ * buffers, and allocate a >+ * struct smb_request to hold >+ * the unread_bytes variable. >+ * That's how we know we're doing >+ * recvfile in the SMB2_WRITE code. >+ */ >+ req->smb1req = talloc_zero(req, >+ struct smb_request); >+ if (!req->smb1req) { >+ return -1; >+ } >+ >+ /* >+ * We don't adjust state->missing >+ * here as it's already been decremented >+ * for dyn_size. >+ */ >+ req->smb1req->unread_bytes = dyn_size; >+ dyn_size = 0; >+ } >+ } >+ > dyn = talloc_array(req->in.vector, uint8_t, dyn_size); > if (dyn == NULL) { > return -1; >-- >1.7.10.4 >
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
Actions:
View
Attachments on
bug 9412
:
8216
|
8702
|
8706
|
8707
|
8716
|
8728
|
8737
|
8803
|
8804