diff options
-rw-r--r-- | source3/smbd/globals.h | 2 | ||||
-rw-r--r-- | source3/smbd/smb2_server.c | 51 |
2 files changed, 20 insertions, 33 deletions
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h index 14337e0c95..2e94b55a04 100644 --- a/source3/smbd/globals.h +++ b/source3/smbd/globals.h @@ -339,9 +339,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 5bb3c3bc58..5b41c3b6d2 100644 --- a/source3/smbd/smb2_server.c +++ b/source3/smbd/smb2_server.c @@ -209,6 +209,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); @@ -1141,30 +1144,20 @@ static 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 */ @@ -1184,6 +1177,7 @@ static NTSTATUS smbd_smb2_request_check_tcon(struct smbd_smb2_request *req) } req->tcon = tcon; + req->last_tid = in_tid; return NT_STATUS_OK; } @@ -1197,31 +1191,21 @@ static 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; - bool chained_fixup = false; + + 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 */ @@ -1240,6 +1224,7 @@ static NTSTATUS smbd_smb2_request_check_session(struct smbd_smb2_request *req) session->session_info->info->domain_name); req->session = session; + req->last_session_id = in_session_id; return NT_STATUS_OK; } |