From edea79f789df726dbcabc74284fcb06a9991acad Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 27 Oct 2011 16:42:44 +0200 Subject: [PATCH 1/4] s3:smb2_server: echo the SMB2_HDR_CREDIT_CHARGE and SMB2_HDR_SIGNATURE fields Windows just echos back the given values by default. metze (cherry picked from commit c7d3b6b2c38711943910aebff72b0188b0c346db) --- source3/smbd/smb2_server.c | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-) diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c index 1c50d21..c1fa454 100644 --- a/source3/smbd/smb2_server.c +++ b/source3/smbd/smb2_server.c @@ -574,7 +574,8 @@ static NTSTATUS smbd_smb2_request_setup_out(struct smbd_smb2_request *req) /* setup the SMB2 header */ SIVAL(outhdr, SMB2_HDR_PROTOCOL_ID, SMB2_MAGIC); SSVAL(outhdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY); - SSVAL(outhdr, SMB2_HDR_EPOCH, 0); + SSVAL(outhdr, SMB2_HDR_CREDIT_CHARGE, + SVAL(inhdr, SMB2_HDR_CREDIT_CHARGE)); SIVAL(outhdr, SMB2_HDR_STATUS, NT_STATUS_V(NT_STATUS_INTERNAL_ERROR)); SSVAL(outhdr, SMB2_HDR_OPCODE, @@ -590,7 +591,8 @@ static NTSTATUS smbd_smb2_request_setup_out(struct smbd_smb2_request *req) IVAL(inhdr, SMB2_HDR_TID)); SBVAL(outhdr, SMB2_HDR_SESSION_ID, BVAL(inhdr, SMB2_HDR_SESSION_ID)); - memset(outhdr + SMB2_HDR_SIGNATURE, 0, 16); + memcpy(outhdr + SMB2_HDR_SIGNATURE, + inhdr + SMB2_HDR_SIGNATURE, 16); /* setup error body header */ SSVAL(outbody, 0x00, 0x08 + 1); -- 1.7.3.1 From 2844f149c6042d583abf9821f31d57895b03270d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 31 Oct 2011 15:15:09 -0700 Subject: [PATCH 2/4] s3:smb2_server: don't reset the tid and session id in the out hdr of compound requests Windows also leaves tid (0xFFFFFFFF) and session id (0xFFFFFFFFFFFFFFFF) as the client requested them. Based on commit 8d07d7148bf47ea14e62d39ed8a8cc4f1366810e from master. metze --- source3/smbd/smb2_sesssetup.c | 7 ------- source3/smbd/smb2_tcon.c | 8 -------- 2 files changed, 0 insertions(+), 15 deletions(-) diff --git a/source3/smbd/smb2_sesssetup.c b/source3/smbd/smb2_sesssetup.c index 53f9d10..14f9654 100644 --- a/source3/smbd/smb2_sesssetup.c +++ b/source3/smbd/smb2_sesssetup.c @@ -818,7 +818,6 @@ NTSTATUS smbd_smb2_request_check_session(struct smbd_smb2_request *req) uint64_t in_session_id; void *p; struct smbd_smb2_session *session; - bool chained_fixup = false; inhdr = (const uint8_t *)req->in.vector[i+0].iov_base; @@ -839,7 +838,6 @@ NTSTATUS smbd_smb2_request_check_session(struct smbd_smb2_request *req) */ outhdr = (const uint8_t *)req->out.vector[i-3].iov_base; in_session_id = BVAL(outhdr, SMB2_HDR_SESSION_ID); - chained_fixup = true; } } @@ -860,11 +858,6 @@ NTSTATUS smbd_smb2_request_check_session(struct smbd_smb2_request *req) req->session = session; - if (chained_fixup) { - /* Fix up our own outhdr. */ - outhdr = (const uint8_t *)req->out.vector[i].iov_base; - SBVAL(outhdr, SMB2_HDR_SESSION_ID, in_session_id); - } return NT_STATUS_OK; } diff --git a/source3/smbd/smb2_tcon.c b/source3/smbd/smb2_tcon.c index 8644e56..8d2aae7 100644 --- a/source3/smbd/smb2_tcon.c +++ b/source3/smbd/smb2_tcon.c @@ -286,7 +286,6 @@ NTSTATUS smbd_smb2_request_check_tcon(struct smbd_smb2_request *req) uint32_t in_tid; void *p; struct smbd_smb2_tcon *tcon; - bool chained_fixup = false; inhdr = (const uint8_t *)req->in.vector[i+0].iov_base; @@ -307,7 +306,6 @@ NTSTATUS smbd_smb2_request_check_tcon(struct smbd_smb2_request *req) */ outhdr = (const uint8_t *)req->out.vector[i-3].iov_base; in_tid = IVAL(outhdr, SMB2_HDR_TID); - chained_fixup = true; } } @@ -329,12 +327,6 @@ NTSTATUS smbd_smb2_request_check_tcon(struct smbd_smb2_request *req) req->tcon = tcon; - if (chained_fixup) { - /* Fix up our own outhdr. */ - outhdr = (const uint8_t *)req->out.vector[i].iov_base; - SIVAL(outhdr, SMB2_HDR_TID, in_tid); - } - return NT_STATUS_OK; } -- 1.7.3.1 From eb983ef2b96391d0818713d46682c63b64999d78 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 30 Aug 2011 11:48:16 +0200 Subject: [PATCH 3/4] smb2_constants: add SMB2_HDR_CREDIT_CHARGE SMB2_HDR_EPOCH was never used and SMB 2.10 uses it as SMB2_HDR_CREDIT_CHARGE. We keep SMB2_HDR_EPOCH as alias for now, until all callers are fixed. metze Autobuild-User: Stefan Metzmacher Autobuild-Date: Tue Aug 30 23:49:56 CEST 2011 on sn-devel-104 (cherry picked from commit 480a031c5b9a2ffe1e03e3fcb197e526e6d69e72) --- libcli/smb/smb2_constants.h | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/libcli/smb/smb2_constants.h b/libcli/smb/smb2_constants.h index 7ab496d..0e2c267 100644 --- a/libcli/smb/smb2_constants.h +++ b/libcli/smb/smb2_constants.h @@ -25,7 +25,8 @@ /* offsets into header elements for a sync SMB2 request */ #define SMB2_HDR_PROTOCOL_ID 0x00 #define SMB2_HDR_LENGTH 0x04 -#define SMB2_HDR_EPOCH 0x06 +#define SMB2_HDR_CREDIT_CHARGE 0x06 +#define SMB2_HDR_EPOCH SMB2_HDR_CREDIT_CHARGE /* TODO: remove this */ #define SMB2_HDR_STATUS 0x08 #define SMB2_HDR_OPCODE 0x0c #define SMB2_HDR_CREDIT 0x0e -- 1.7.3.1 From 408a81c123477ec5e319e18a1d2d093664bd44dc Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Nov 2011 10:55:17 -0700 Subject: [PATCH 4/4] s3:smb2_server: FLAG_CHAINED means we always use the last session_id and tid Based on master commit 91648aeb6409787c7766943225f5c7a9c695aa0b. metze --- source3/smbd/globals.h | 2 ++ source3/smbd/smb2_server.c | 3 +++ source3/smbd/smb2_sesssetup.c | 25 ++++++++----------------- source3/smbd/smb2_tcon.c | 24 +++++++----------------- 4 files changed, 20 insertions(+), 34 deletions(-) diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h index f5f83bd..4ab04bf 100644 --- a/source3/smbd/globals.h +++ b/source3/smbd/globals.h @@ -349,9 +349,11 @@ struct smbd_smb2_request { /* the session the request operates on, maybe NULL */ struct smbd_smb2_session *session; + uint64_t last_session_id; /* the tcon the request operates on, maybe NULL */ struct smbd_smb2_tcon *tcon; + uint32_t last_tid; int current_idx; bool do_signing; diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c index c1fa454..4da1e15 100644 --- a/source3/smbd/smb2_server.c +++ b/source3/smbd/smb2_server.c @@ -206,6 +206,9 @@ static struct smbd_smb2_request *smbd_smb2_request_allocate(TALLOC_CTX *mem_ctx) req->mem_pool = mem_pool; req->parent = parent; + req->last_session_id = UINT64_MAX; + req->last_tid = UINT32_MAX; + talloc_set_destructor(parent, smbd_smb2_request_parent_destructor); talloc_set_destructor(req, smbd_smb2_request_destructor); diff --git a/source3/smbd/smb2_sesssetup.c b/source3/smbd/smb2_sesssetup.c index 14f9654..a081290 100644 --- a/source3/smbd/smb2_sesssetup.c +++ b/source3/smbd/smb2_sesssetup.c @@ -813,32 +813,22 @@ static NTSTATUS smbd_smb2_session_setup(struct smbd_smb2_request *smb2req, NTSTATUS smbd_smb2_request_check_session(struct smbd_smb2_request *req) { const uint8_t *inhdr; - const uint8_t *outhdr; int i = req->current_idx; + uint32_t in_flags; uint64_t in_session_id; void *p; struct smbd_smb2_session *session; + req->session = NULL; + req->tcon = NULL; + inhdr = (const uint8_t *)req->in.vector[i+0].iov_base; + in_flags = IVAL(inhdr, SMB2_HDR_FLAGS); in_session_id = BVAL(inhdr, SMB2_HDR_SESSION_ID); - if (in_session_id == (0xFFFFFFFFFFFFFFFFLL)) { - if (req->async) { - /* - * async request - fill in session_id from - * already setup request out.vector[].iov_base. - */ - outhdr = (const uint8_t *)req->out.vector[i].iov_base; - in_session_id = BVAL(outhdr, SMB2_HDR_SESSION_ID); - } else if (i > 2) { - /* - * Chained request - fill in session_id from - * the previous request out.vector[].iov_base. - */ - outhdr = (const uint8_t *)req->out.vector[i-3].iov_base; - in_session_id = BVAL(outhdr, SMB2_HDR_SESSION_ID); - } + if (in_flags & SMB2_HDR_FLAG_CHAINED) { + in_session_id = req->last_session_id; } /* lookup an existing session */ @@ -857,6 +847,7 @@ NTSTATUS smbd_smb2_request_check_session(struct smbd_smb2_request *req) session->session_info->info3->base.domain.string); req->session = session; + req->last_session_id = in_session_id; return NT_STATUS_OK; } diff --git a/source3/smbd/smb2_tcon.c b/source3/smbd/smb2_tcon.c index 8d2aae7..f1f03e8 100644 --- a/source3/smbd/smb2_tcon.c +++ b/source3/smbd/smb2_tcon.c @@ -281,32 +281,21 @@ static NTSTATUS smbd_smb2_tree_connect(struct smbd_smb2_request *req, NTSTATUS smbd_smb2_request_check_tcon(struct smbd_smb2_request *req) { const uint8_t *inhdr; - const uint8_t *outhdr; int i = req->current_idx; + uint32_t in_flags; uint32_t in_tid; void *p; struct smbd_smb2_tcon *tcon; + req->tcon = NULL; + inhdr = (const uint8_t *)req->in.vector[i+0].iov_base; + in_flags = IVAL(inhdr, SMB2_HDR_FLAGS); in_tid = IVAL(inhdr, SMB2_HDR_TID); - if (in_tid == (0xFFFFFFFF)) { - if (req->async) { - /* - * async request - fill in tid from - * already setup out.vector[].iov_base. - */ - outhdr = (const uint8_t *)req->out.vector[i].iov_base; - in_tid = IVAL(outhdr, SMB2_HDR_TID); - } else if (i > 2) { - /* - * Chained request - fill in tid from - * the previous request out.vector[].iov_base. - */ - outhdr = (const uint8_t *)req->out.vector[i-3].iov_base; - in_tid = IVAL(outhdr, SMB2_HDR_TID); - } + if (in_flags & SMB2_HDR_FLAG_CHAINED) { + in_tid = req->last_tid; } /* lookup an existing session */ @@ -326,6 +315,7 @@ NTSTATUS smbd_smb2_request_check_tcon(struct smbd_smb2_request *req) } req->tcon = tcon; + req->last_tid = in_tid; return NT_STATUS_OK; } -- 1.7.3.1