From 86621dc190bb78d2ccae3d89e895029c7ea67106 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 13 Aug 2024 12:47:59 +0200 Subject: [PATCH 1/2] s4:torture/smb2: let smb2.session.expire2* also check compound requests This shows that all compound related requests should get NT_STATUS_NETWORK_SESSION_EXPIRED. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15696 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison (cherry picked from commit f6009aa73b9234df1e6ab689de322487ad1394ed) --- .../samba3.smb2.session.krb5.expire2 | 1 + source4/torture/smb2/session.c | 56 +++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 selftest/knownfail.d/samba3.smb2.session.krb5.expire2 diff --git a/selftest/knownfail.d/samba3.smb2.session.krb5.expire2 b/selftest/knownfail.d/samba3.smb2.session.krb5.expire2 new file mode 100644 index 000000000000..718d578531b5 --- /dev/null +++ b/selftest/knownfail.d/samba3.smb2.session.krb5.expire2 @@ -0,0 +1 @@ +^samba3.smb2.session.krb5.expire2 diff --git a/source4/torture/smb2/session.c b/source4/torture/smb2/session.c index 2a3d0e6e8536..ecaac76e6c3b 100644 --- a/source4/torture/smb2/session.c +++ b/source4/torture/smb2/session.c @@ -1317,6 +1317,7 @@ static bool test_session_expire2i(struct torture_context *tctx, char fname[256]; struct smb2_handle dh; struct smb2_handle dh2; + struct smb2_handle relhandle = { .data = { UINT64_MAX, UINT64_MAX } }; struct smb2_handle _h1; struct smb2_handle *h1 = NULL; struct smb2_create io1; @@ -1330,7 +1331,10 @@ static bool test_session_expire2i(struct torture_context *tctx, struct smb2_ioctl ctl; struct smb2_break oack; struct smb2_lease_break_ack lack; + struct smb2_create cio; struct smb2_find fnd; + struct smb2_close cl; + struct smb2_request *reqs[3] = { NULL, }; union smb_search_data *d = NULL; unsigned int count; struct smb2_request *req = NULL; @@ -1562,6 +1566,58 @@ static bool test_session_expire2i(struct torture_context *tctx, ret, done, "smb2_find_level " "returned unexpected status"); + /* Now do a compound open + query directory + close handle. */ + smb2_transport_compound_start(tree->session->transport, 3); + torture_comment(tctx, "Compound: Open+QueryDirectory+Close => EXPIRED\n"); + + ZERO_STRUCT(cio); + cio.in.oplock_level = 0; + cio.in.desired_access = SEC_STD_SYNCHRONIZE | SEC_DIR_READ_ATTRIBUTE | SEC_DIR_LIST; + cio.in.file_attributes = 0; + cio.in.create_disposition = NTCREATEX_DISP_OPEN; + cio.in.share_access = NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_DELETE; + cio.in.create_options = NTCREATEX_OPTIONS_ASYNC_ALERT; + cio.in.fname = ""; + + reqs[0] = smb2_create_send(tree, &cio); + torture_assert_not_null_goto(tctx, reqs[0], ret, done, + "smb2_create_send failed\n"); + + smb2_transport_compound_set_related(tree->session->transport, true); + + ZERO_STRUCT(fnd); + fnd.in.file.handle = relhandle; + fnd.in.pattern = "*"; + fnd.in.continue_flags = SMB2_CONTINUE_FLAG_SINGLE; + fnd.in.max_response_size= 0x100; + fnd.in.level = SMB2_FIND_BOTH_DIRECTORY_INFO; + + reqs[1] = smb2_find_send(tree, &fnd); + torture_assert_not_null_goto(tctx, reqs[1], ret, done, + "smb2_find_send failed\n"); + + ZERO_STRUCT(cl); + cl.in.file.handle = relhandle; + reqs[2] = smb2_close_send(tree, &cl); + torture_assert_not_null_goto(tctx, reqs[2], ret, done, + "smb2_close_send failed\n"); + + status = smb2_create_recv(reqs[0], tree, &cio); + torture_assert_ntstatus_equal_goto(tctx, status, + NT_STATUS_NETWORK_SESSION_EXPIRED, + ret, done, "smb2_create " + "returned unexpected status"); + status = smb2_find_recv(reqs[1], tree, &fnd); + torture_assert_ntstatus_equal_goto(tctx, status, + NT_STATUS_NETWORK_SESSION_EXPIRED, + ret, done, "smb2_find " + "returned unexpected status"); + status = smb2_close_recv(reqs[2], &cl); + torture_assert_ntstatus_equal_goto(tctx, status, + NT_STATUS_NETWORK_SESSION_EXPIRED, + ret, done, "smb2_close " + "returned unexpected status"); + torture_comment(tctx, "1st notify => CANCEL\n"); smb2_cancel(req); -- 2.34.1 From 25b3a776d83c0bf93f6a00f98cf2ea82b83c5879 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 13 Aug 2024 14:07:06 +0200 Subject: [PATCH 2/2] s3:smb2_server: return NT_STATUS_NETWORK_SESSION_EXPIRED for compound requests BUG: https://bugzilla.samba.org/show_bug.cgi?id=15696 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison Autobuild-User(master): Jeremy Allison Autobuild-Date(master): Tue Aug 13 22:29:28 UTC 2024 on atb-devel-224 (cherry picked from commit 4df1bfd07012dd3d2d2921281e6d6e309303b88d) --- .../knownfail.d/samba3.smb2.session.krb5.expire2 | 1 - source3/smbd/smb2_server.c | 16 +++++++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) delete mode 100644 selftest/knownfail.d/samba3.smb2.session.krb5.expire2 diff --git a/selftest/knownfail.d/samba3.smb2.session.krb5.expire2 b/selftest/knownfail.d/samba3.smb2.session.krb5.expire2 deleted file mode 100644 index 718d578531b5..000000000000 --- a/selftest/knownfail.d/samba3.smb2.session.krb5.expire2 +++ /dev/null @@ -1 +0,0 @@ -^samba3.smb2.session.krb5.expire2 diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c index 5b83d4d96522..9eba42dfcf20 100644 --- a/source3/smbd/smb2_server.c +++ b/source3/smbd/smb2_server.c @@ -3049,6 +3049,7 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) bool signing_required = false; bool encryption_desired = false; bool encryption_required = false; + bool session_expired = false; inhdr = SMBD_SMB2_IN_HDR_PTR(req); @@ -3097,6 +3098,9 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) signing_required = x->global->signing_flags & SMBXSRV_SIGNING_REQUIRED; encryption_desired = x->global->encryption_flags & SMBXSRV_ENCRYPTION_DESIRED; encryption_required = x->global->encryption_flags & SMBXSRV_ENCRYPTION_REQUIRED; + session_expired = + NT_STATUS_EQUAL(session_status, + NT_STATUS_NETWORK_SESSION_EXPIRED); } req->async_internal = false; @@ -3169,7 +3173,7 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) * This check is mostly for giving the correct error code * for compounded requests. */ - if (!NT_STATUS_IS_OK(session_status)) { + if (!session_expired && !NT_STATUS_IS_OK(session_status)) { return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER); } } else { @@ -3255,6 +3259,9 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) } if (!NT_STATUS_IS_OK(session_status)) { + if (session_expired && opcode == SMB2_OP_CREATE) { + req->compound_create_err = session_status; + } return smbd_smb2_request_error(req, session_status); } } @@ -3306,11 +3313,18 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) skipped_signing: if (flags & SMB2_HDR_FLAG_CHAINED) { + if (!NT_STATUS_IS_OK(req->compound_create_err)) { + return smbd_smb2_request_error(req, + req->compound_create_err); + } req->compound_related = true; } if (call->need_session) { if (!NT_STATUS_IS_OK(session_status)) { + if (session_expired && opcode == SMB2_OP_CREATE) { + req->compound_create_err = session_status; + } return smbd_smb2_request_error(req, session_status); } } -- 2.34.1