From: Stefan Metzmacher Date: Tue, 1 Nov 2011 17:55:17 +0000 (-0700) Subject: s3:smb2_server: FLAG_CHAINED means we always use the last session_id and tid X-Git-Tag: samba-3.6.2~82 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=36d7235e4fa7f89187b6733084726c983c4c7b84;p=thirdparty%2Fsamba.git s3:smb2_server: FLAG_CHAINED means we always use the last session_id and tid Based on master commit 91648aeb6409787c7766943225f5c7a9c695aa0b. metze The last 4 patches address bug #8560 (SMB2 doesn't handle compound request headers in the same way as Windows). (cherry picked from commit 2971e74fd522998d30b2923a2a308d8e28c04aa9) --- diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h index 9304a43cdd3..663daa4b640 100644 --- a/source3/smbd/globals.h +++ b/source3/smbd/globals.h @@ -353,9 +353,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 c1fa45483a5..4da1e15eea0 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 14f9654798a..a081290170a 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 8d2aae7410a..f1f03e89043 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; }