The branch, master has been updated via 40172f3... Test using (-1) for tid and sessionid in compound related requests. via 556b42a... On compound requests, MS-SMB2 says clients MAY use 0xFFFFFFFF for compound tid and 0xFFFFFFFFFFFFFFFF for compound sessionid values. Cope with this. via 146c161... Don't forget to initialize *p_creds_requested. from c76bd65... s4-samdb: Allow skipping global schema.
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 40172f374ba6d5a6edde2834f7f0a28a5fe49928 Author: Jeremy Allison <j...@samba.org> Date: Wed Apr 7 10:33:02 2010 -0700 Test using (-1) for tid and sessionid in compound related requests. Jeremy. commit 556b42a351e3584550f79d1c7ad83b44f3a5562b Author: Jeremy Allison <j...@samba.org> Date: Wed Apr 7 10:32:01 2010 -0700 On compound requests, MS-SMB2 says clients MAY use 0xFFFFFFFF for compound tid and 0xFFFFFFFFFFFFFFFF for compound sessionid values. Cope with this. Jeremy. commit 146c1618e44591a11afade87f67797e6f80fa813 Author: Jeremy Allison <j...@samba.org> Date: Wed Apr 7 10:31:43 2010 -0700 Don't forget to initialize *p_creds_requested. Jeremy. ----------------------------------------------------------------------- Summary of changes: source3/smbd/smb2_server.c | 1 + source3/smbd/smb2_sesssetup.c | 20 ++++++++++++++++++++ source3/smbd/smb2_tcon.c | 19 +++++++++++++++++++ source4/torture/smb2/compound.c | 25 +++++++++++++++++++++++++ 4 files changed, 65 insertions(+), 0 deletions(-) Changeset truncated at 500 lines: diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c index 7fd3ef4..f5e3765 100644 --- a/source3/smbd/smb2_server.c +++ b/source3/smbd/smb2_server.c @@ -241,6 +241,7 @@ static NTSTATUS smbd_smb2_request_validate(struct smbd_smb2_request *req, int idx; bool compound_related = false; + *p_creds_requested = 0; count = req->in.vector_count; if (count < 4) { diff --git a/source3/smbd/smb2_sesssetup.c b/source3/smbd/smb2_sesssetup.c index 0df4bd6..b3ea3fa 100644 --- a/source3/smbd/smb2_sesssetup.c +++ b/source3/smbd/smb2_sesssetup.c @@ -338,15 +338,29 @@ static NTSTATUS smbd_smb2_session_setup(struct smbd_smb2_request *req, NTSTATUS smbd_smb2_request_check_session(struct smbd_smb2_request *req) { const uint8_t *inhdr; + const uint8_t *outhdr; int i = req->current_idx; 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; in_session_id = BVAL(inhdr, SMB2_HDR_SESSION_ID); + if (i > 2 && in_session_id == (0xFFFFFFFFFFFFFFFFLL)) { + /* + * Chained request - fill in session_id from + * the previous request out.vector[].iov_base. + * We can't modify the inhdr here as we have + * yet to check signing. + */ + outhdr = (const uint8_t *)req->out.vector[i-3].iov_base; + in_session_id = BVAL(outhdr, SMB2_HDR_SESSION_ID); + chained_fixup = true; + } + /* lookup an existing session */ p = idr_find(req->sconn->smb2.sessions.idtree, in_session_id); if (p == NULL) { @@ -363,6 +377,12 @@ NTSTATUS smbd_smb2_request_check_session(struct smbd_smb2_request *req) pdb_get_domain(session->server_info->sam_account)); 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 bd33007..3eb9da2 100644 --- a/source3/smbd/smb2_tcon.c +++ b/source3/smbd/smb2_tcon.c @@ -220,15 +220,27 @@ 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_tid; void *p; struct smbd_smb2_tcon *tcon; + bool chained_fixup = false; inhdr = (const uint8_t *)req->in.vector[i+0].iov_base; in_tid = IVAL(inhdr, SMB2_HDR_TID); + if (i > 2 && in_tid == (0xFFFFFFFF)) { + /* + * 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); + chained_fixup = true; + } + /* lookup an existing session */ p = idr_find(req->session->tcons.idtree, in_tid); if (p == NULL) { @@ -246,6 +258,13 @@ 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; } diff --git a/source4/torture/smb2/compound.c b/source4/torture/smb2/compound.c index 858ffde..bb506a0 100644 --- a/source4/torture/smb2/compound.c +++ b/source4/torture/smb2/compound.c @@ -46,6 +46,8 @@ static bool test_compound_related1(struct torture_context *tctx, struct smb2_close cl; bool ret = true; struct smb2_request *req[2]; + uint32_t saved_tid = tree->tid; + uint64_t saved_uid = tree->session->uid; smb2_transport_credits_ask_num(tree->session->transport, 2); @@ -82,6 +84,10 @@ static bool test_compound_related1(struct torture_context *tctx, ZERO_STRUCT(cl); cl.in.file.handle = hd; + + tree->tid = 0xFFFFFFFF; + tree->session->uid = UINT64_MAX; + req[1] = smb2_close_send(tree, &cl); status = smb2_create_recv(req[0], tree, &cr); @@ -89,6 +95,9 @@ static bool test_compound_related1(struct torture_context *tctx, status = smb2_close_recv(req[1], &cl); CHECK_STATUS(status, NT_STATUS_OK); + tree->tid = saved_tid; + tree->session->uid = saved_uid; + smb2_util_unlink(tree, fname); done: return ret; @@ -104,6 +113,8 @@ static bool test_compound_related2(struct torture_context *tctx, struct smb2_close cl; bool ret = true; struct smb2_request *req[5]; + uint32_t saved_tid = tree->tid; + uint64_t saved_uid = tree->session->uid; smb2_transport_credits_ask_num(tree->session->transport, 5); @@ -140,6 +151,9 @@ static bool test_compound_related2(struct torture_context *tctx, ZERO_STRUCT(cl); cl.in.file.handle = hd; + tree->tid = 0xFFFFFFFF; + tree->session->uid = UINT64_MAX; + req[1] = smb2_close_send(tree, &cl); req[2] = smb2_close_send(tree, &cl); req[3] = smb2_close_send(tree, &cl); @@ -156,6 +170,9 @@ static bool test_compound_related2(struct torture_context *tctx, status = smb2_close_recv(req[4], &cl); CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER); + tree->tid = saved_tid; + tree->session->uid = saved_uid; + smb2_util_unlink(tree, fname); done: return ret; @@ -296,6 +313,8 @@ static bool test_compound_invalid2(struct torture_context *tctx, struct smb2_close cl; bool ret = true; struct smb2_request *req[5]; + uint32_t saved_tid = tree->tid; + uint64_t saved_uid = tree->session->uid; smb2_transport_credits_ask_num(tree->session->transport, 5); @@ -332,6 +351,9 @@ static bool test_compound_invalid2(struct torture_context *tctx, ZERO_STRUCT(cl); cl.in.file.handle = hd; + tree->tid = 0xFFFFFFFF; + tree->session->uid = UINT64_MAX; + req[1] = smb2_close_send(tree, &cl); /* strange that this is not generating invalid parameter */ smb2_transport_compound_set_related(tree->session->transport, false); @@ -351,6 +373,9 @@ static bool test_compound_invalid2(struct torture_context *tctx, status = smb2_close_recv(req[4], &cl); CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER); + tree->tid = saved_tid; + tree->session->uid = saved_uid; + smb2_util_unlink(tree, fname); done: return ret; -- Samba Shared Repository