[SCM] Samba Shared Repository - branch master updated
Jeremy Allison
jra at samba.org
Wed Aug 31 13:19:02 MDT 2011
The branch, master has been updated
via 786fe9f Fix bug 8429 - Compound SMB2 requests on an IPC connection can corrupt the reply stream.
via 726b468 Based on metze's fix for Bug 8407 - SMB2 server can return requests out-of-order when processing a compound request. (cherry picked from commit 19db1c98c6ba3cb5e883e16e865c44900ce17444)
via 0d450d1 s3:smb2_server: keep compound_related on struct smbd_smb2_request
from fe6c565 s3-waf: fix unresolved symbols in the group policy client side extensions subsystem.
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 786fe9fab223723e4d2340f285592b2a44945d73
Author: Jeremy Allison <jra at samba.org>
Date: Tue Aug 30 17:37:19 2011 -0700
Fix bug 8429 - Compound SMB2 requests on an IPC connection can corrupt the reply stream.
Autobuild-User: Jeremy Allison <jra at samba.org>
Autobuild-Date: Wed Aug 31 21:18:11 CEST 2011 on sn-devel-104
commit 726b4685aa25b0b3b4470bfec5d514fb2db7a95e
Author: Jeremy Allison <jra at samba.org>
Date: Fri Aug 26 14:23:26 2011 -0700
Based on metze's fix for Bug 8407 - SMB2 server can return requests out-of-order when processing a compound request. (cherry picked from commit 19db1c98c6ba3cb5e883e16e865c44900ce17444)
commit 0d450d166bab952daf37d922e5c2e5cac16f1cc3
Author: Stefan Metzmacher <metze at samba.org>
Date: Thu Aug 25 23:33:41 2011 +0200
s3:smb2_server: keep compound_related on struct smbd_smb2_request
metze
(cherry picked from commit cda93f04eb4e7e975b192a5fd33275ec638140ac)
-----------------------------------------------------------------------
Summary of changes:
source3/smbd/globals.h | 2 +
source3/smbd/smb2_server.c | 76 +++++++++++++++++++++++++++++++++----------
2 files changed, 60 insertions(+), 18 deletions(-)
Changeset truncated at 500 lines:
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index b9bd212..35c44ee 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -355,6 +355,7 @@ struct smbd_smb2_request {
bool do_signing;
bool async;
bool cancelled;
+ bool compound_related;
/* fake smb1 request. */
struct smb_request *smb1req;
@@ -605,6 +606,7 @@ struct smbd_server_connection {
uint32_t credits_granted;
uint32_t max_credits;
struct bitmap *credits_bitmap;
+ bool compound_related_in_progress;
} smb2;
};
diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c
index 6fc4b5d..fa4801c 100644
--- a/source3/smbd/smb2_server.c
+++ b/source3/smbd/smb2_server.c
@@ -360,7 +360,6 @@ static NTSTATUS smbd_smb2_request_validate(struct smbd_smb2_request *req)
{
int count;
int idx;
- bool compound_related = false;
count = req->in.vector_count;
@@ -408,7 +407,7 @@ static NTSTATUS smbd_smb2_request_validate(struct smbd_smb2_request *req)
* compounded requests
*/
if (flags & SMB2_HDR_FLAG_CHAINED) {
- compound_related = true;
+ req->compound_related = true;
}
} else if (idx > 4) {
#if 0
@@ -421,13 +420,13 @@ static NTSTATUS smbd_smb2_request_validate(struct smbd_smb2_request *req)
* all other requests should match the 2nd one
*/
if (flags & SMB2_HDR_FLAG_CHAINED) {
- if (!compound_related) {
+ if (!req->compound_related) {
req->next_status =
NT_STATUS_INVALID_PARAMETER;
return NT_STATUS_OK;
}
} else {
- if (compound_related) {
+ if (req->compound_related) {
req->next_status =
NT_STATUS_INVALID_PARAMETER;
return NT_STATUS_OK;
@@ -887,11 +886,25 @@ NTSTATUS smbd_smb2_request_pending_queue(struct smbd_smb2_request *req,
if (!NT_STATUS_IS_OK(status)) {
return status;
}
+
+ /*
+ * We're splitting off the last SMB2
+ * request in a compound set, and the
+ * smb2_send_async_interim_response()
+ * call above just sent all the replies
+ * for the previous SMB2 requests in
+ * this compound set. So we're no longer
+ * in the "compound_related_in_progress"
+ * state, and this is no longer a compound
+ * request.
+ */
+ req->compound_related = false;
+ req->sconn->smb2.compound_related_in_progress = false;
}
/* Don't return an intermediate packet on a pipe read/write. */
if (req->tcon && req->tcon->compat_conn && IS_IPC(req->tcon->compat_conn)) {
- return NT_STATUS_OK;
+ goto ipc_out;
}
reqhdr = (uint8_t *)req->out.vector[i].iov_base;
@@ -980,6 +993,8 @@ NTSTATUS smbd_smb2_request_pending_queue(struct smbd_smb2_request *req,
/* Note we're going async with this request. */
req->async = true;
+ ipc_out:
+
/*
* Now manipulate req so that the outstanding async request
* is the only one left in the struct smbd_smb2_request.
@@ -1027,19 +1042,22 @@ NTSTATUS smbd_smb2_request_pending_queue(struct smbd_smb2_request *req,
smb2_setup_nbt_length(req->out.vector,
req->out.vector_count);
- /* Ensure our final reply matches the interim one. */
- reqhdr = (uint8_t *)req->out.vector[1].iov_base;
- SIVAL(reqhdr, SMB2_HDR_FLAGS, flags | SMB2_HDR_FLAG_ASYNC);
- SBVAL(reqhdr, SMB2_HDR_PID, async_id);
+ if (req->async) {
+ /* Ensure our final reply matches the interim one. */
+ reqhdr = (uint8_t *)req->out.vector[1].iov_base;
+ SIVAL(reqhdr, SMB2_HDR_FLAGS, flags | SMB2_HDR_FLAG_ASYNC);
+ SBVAL(reqhdr, SMB2_HDR_PID, async_id);
- {
- const uint8_t *inhdr =
- (const uint8_t *)req->in.vector[1].iov_base;
- DEBUG(10,("smbd_smb2_request_pending_queue: opcode[%s] mid %llu "
- "going async\n",
- smb2_opcode_name((uint16_t)IVAL(inhdr, SMB2_HDR_OPCODE)),
- (unsigned long long)async_id ));
+ {
+ const uint8_t *inhdr =
+ (const uint8_t *)req->in.vector[1].iov_base;
+ DEBUG(10,("smbd_smb2_request_pending_queue: opcode[%s] mid %llu "
+ "going async\n",
+ smb2_opcode_name((uint16_t)IVAL(inhdr, SMB2_HDR_OPCODE)),
+ (unsigned long long)async_id ));
+ }
}
+
return NT_STATUS_OK;
}
@@ -1306,6 +1324,10 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
req->compat_chain_fsp = NULL;
}
+ if (req->compound_related) {
+ req->sconn->smb2.compound_related_in_progress = true;
+ }
+
switch (opcode) {
case SMB2_OP_NEGPROT:
/* This call needs to be run as root */
@@ -1752,6 +1774,10 @@ static NTSTATUS smbd_smb2_request_reply(struct smbd_smb2_request *req)
return NT_STATUS_OK;
}
+ if (req->compound_related) {
+ req->sconn->smb2.compound_related_in_progress = false;
+ }
+
smb2_setup_nbt_length(req->out.vector, req->out.vector_count);
/* Set credit for this operation (zero credits if this
@@ -1802,6 +1828,8 @@ static NTSTATUS smbd_smb2_request_reply(struct smbd_smb2_request *req)
return NT_STATUS_OK;
}
+static NTSTATUS smbd_smb2_request_next_incoming(struct smbd_server_connection *sconn);
+
void smbd_smb2_request_dispatch_immediate(struct tevent_context *ctx,
struct tevent_immediate *im,
void *private_data)
@@ -1824,9 +1852,13 @@ void smbd_smb2_request_dispatch_immediate(struct tevent_context *ctx,
smbd_server_connection_terminate(sconn, nt_errstr(status));
return;
}
-}
-static NTSTATUS smbd_smb2_request_next_incoming(struct smbd_server_connection *sconn);
+ status = smbd_smb2_request_next_incoming(sconn);
+ if (!NT_STATUS_IS_OK(status)) {
+ smbd_server_connection_terminate(sconn, nt_errstr(status));
+ return;
+ }
+}
static void smbd_smb2_request_writev_done(struct tevent_req *subreq)
{
@@ -2465,6 +2497,14 @@ static NTSTATUS smbd_smb2_request_next_incoming(struct smbd_server_connection *s
size_t cur_send_queue_len;
struct tevent_req *subreq;
+ if (sconn->smb2.compound_related_in_progress) {
+ /*
+ * Can't read another until the related
+ * compound is done.
+ */
+ return NT_STATUS_OK;
+ }
+
if (tevent_queue_length(sconn->smb2.recv_queue) > 0) {
/*
* if there is already a smbd_smb2_request_read
--
Samba Shared Repository
More information about the samba-cvs
mailing list