The Samba-Bugzilla – Attachment 14024 Details for
Bug 13197
SMB2 close/lock/logoff can generate NT_STATUS_NETWORK_SESSION_EXPIRED
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Patches for v4-6-test
tmp46.diff.txt (text/plain), 18.98 KB, created by
Stefan Metzmacher
on 2018-03-07 11:08:32 UTC
(
hide
)
Description:
Patches for v4-6-test
Filename:
MIME Type:
Creator:
Stefan Metzmacher
Created:
2018-03-07 11:08:32 UTC
Size:
18.98 KB
patch
obsolete
>From ce0fc6934ccd9e30987d221cdec25073556270d0 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 21 Dec 2017 12:53:02 +0100 >Subject: [PATCH 1/3] s4:torture: add smb2.session.expire2 test > >This demonstrates the interaction of NT_STATUS_NETWORK_SESSION_EXPIRED >and various SMB2 opcodes. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=13197 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >--- > selftest/knownfail.d/session.expire2 | 1 + > source4/libcli/smb2/keepalive.c | 7 +- > source4/torture/smb2/session.c | 362 +++++++++++++++++++++++++++++++++++ > 3 files changed, 368 insertions(+), 2 deletions(-) > create mode 100644 selftest/knownfail.d/session.expire2 > >diff --git a/selftest/knownfail.d/session.expire2 b/selftest/knownfail.d/session.expire2 >new file mode 100644 >index 0000000..998ccbd >--- /dev/null >+++ b/selftest/knownfail.d/session.expire2 >@@ -0,0 +1 @@ >+^samba3.smb2.session.*krb5.expire2 >diff --git a/source4/libcli/smb2/keepalive.c b/source4/libcli/smb2/keepalive.c >index 402b063..71004aa14 100644 >--- a/source4/libcli/smb2/keepalive.c >+++ b/source4/libcli/smb2/keepalive.c >@@ -26,7 +26,8 @@ > /* > send a keepalive request > */ >-struct smb2_request *smb2_keepalive_send(struct smb2_transport *transport) >+struct smb2_request *smb2_keepalive_send(struct smb2_transport *transport, >+ struct smb2_session *session) > { > struct smb2_request *req; > >@@ -35,6 +36,8 @@ struct smb2_request *smb2_keepalive_send(struct smb2_transport *transport) > > SSVAL(req->out.body, 0x02, 0); > >+ req->session = session; >+ > smb2_transport_send(req); > > return req; >@@ -60,6 +63,6 @@ NTSTATUS smb2_keepalive_recv(struct smb2_request *req) > */ > NTSTATUS smb2_keepalive(struct smb2_transport *transport) > { >- struct smb2_request *req = smb2_keepalive_send(transport); >+ struct smb2_request *req = smb2_keepalive_send(transport, NULL); > return smb2_keepalive_recv(req); > } >diff --git a/source4/torture/smb2/session.c b/source4/torture/smb2/session.c >index e35ec85..7614138 100644 >--- a/source4/torture/smb2/session.c >+++ b/source4/torture/smb2/session.c >@@ -31,6 +31,7 @@ > #include "libcli/security/security.h" > #include "libcli/resolve/resolve.h" > #include "lib/param/param.h" >+#include "lib/util/tevent_ntstatus.h" > > #define CHECK_CREATED(tctx, __io, __created, __attribute) \ > do { \ >@@ -1166,6 +1167,366 @@ done: > return ret; > } > >+static bool test_session_expire2(struct torture_context *tctx) >+{ >+ NTSTATUS status; >+ bool ret = false; >+ struct smbcli_options options; >+ const char *host = torture_setting_string(tctx, "host", NULL); >+ const char *share = torture_setting_string(tctx, "share", NULL); >+ struct cli_credentials *credentials = cmdline_credentials; >+ struct smb2_tree *tree = NULL; >+ const char *unc = NULL; >+ struct smb2_tree *tree2 = NULL; >+ struct tevent_req *subreq = NULL; >+ uint32_t timeout_msec; >+ enum credentials_use_kerberos use_kerberos; >+ uint32_t caps; >+ char fname[256]; >+ struct smb2_handle dh; >+ struct smb2_handle dh2; >+ struct smb2_handle _h1; >+ struct smb2_handle *h1 = NULL; >+ struct smb2_create io1; >+ union smb_fileinfo qfinfo; >+ union smb_setfileinfo sfinfo; >+ struct smb2_flush flsh; >+ struct smb2_read rd; >+ const uint8_t wd = 0; >+ struct smb2_lock lck; >+ struct smb2_lock_element el; >+ struct smb2_ioctl ctl; >+ struct smb2_break oack; >+ struct smb2_lease_break_ack lack; >+ struct smb2_find fnd; >+ union smb_search_data *d = NULL; >+ unsigned int count; >+ struct smb2_request *req = NULL; >+ struct smb2_notify ntf1; >+ struct smb2_notify ntf2; >+ >+ use_kerberos = cli_credentials_get_kerberos_state(credentials); >+ if (use_kerberos != CRED_MUST_USE_KERBEROS) { >+ torture_warning(tctx, "smb2.session.expire2 requires -k yes!"); >+ torture_skip(tctx, "smb2.session.expire2 requires -k yes!"); >+ } >+ >+ torture_assert_int_equal(tctx, use_kerberos, CRED_MUST_USE_KERBEROS, >+ "please use -k yes"); >+ >+ lpcfg_set_option(tctx->lp_ctx, "gensec_gssapi:requested_life_time=4"); >+ >+ lpcfg_smbcli_options(tctx->lp_ctx, &options); >+ >+ unc = talloc_asprintf(tctx, "\\\\%s\\%s", host, share); >+ torture_assert(tctx, unc != NULL, "talloc_asprintf"); >+ >+ status = smb2_connect(tctx, >+ host, >+ lpcfg_smb_ports(tctx->lp_ctx), >+ share, >+ lpcfg_resolve_context(tctx->lp_ctx), >+ credentials, >+ &tree, >+ tctx->ev, >+ &options, >+ lpcfg_socket_options(tctx->lp_ctx), >+ lpcfg_gensec_settings(tctx, tctx->lp_ctx) >+ ); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "smb2_connect failed"); >+ >+ caps = smb2cli_conn_server_capabilities(tree->session->transport->conn); >+ >+ /* Add some random component to the file name. */ >+ snprintf(fname, sizeof(fname), "session_expire2_%s.dat", >+ generate_random_str(tctx, 8)); >+ >+ smb2_util_unlink(tree, fname); >+ >+ status = smb2_util_roothandle(tree, &dh); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "smb2_util_roothandle failed"); >+ >+ smb2_oplock_create_share(&io1, fname, >+ smb2_util_share_access(""), >+ smb2_util_oplock_level("b")); >+ io1.in.create_options |= NTCREATEX_OPTIONS_DELETE_ON_CLOSE; >+ >+ status = smb2_create(tree, tctx, &io1); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "smb2_create failed"); >+ _h1 = io1.out.file.handle; >+ h1 = &_h1; >+ CHECK_CREATED(tctx, &io1, CREATED, FILE_ATTRIBUTE_ARCHIVE); >+ torture_assert_int_equal(tctx, io1.out.oplock_level, >+ smb2_util_oplock_level("b"), >+ "oplock_level incorrect"); >+ >+ /* get the security descriptor */ >+ >+ ZERO_STRUCT(qfinfo); >+ >+ qfinfo.access_information.level = RAW_FILEINFO_ACCESS_INFORMATION; >+ qfinfo.access_information.in.file.handle = _h1; >+ >+ torture_comment(tctx, "query info => OK\n"); >+ >+ ZERO_STRUCT(qfinfo.access_information.out); >+ status = smb2_getinfo_file(tree, tctx, &qfinfo); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "smb2_getinfo_file failed"); >+ >+ torture_comment(tctx, "lock => OK\n"); >+ ZERO_STRUCT(lck); >+ lck.in.locks = ⪙ >+ lck.in.lock_count = 0x0001; >+ lck.in.lock_sequence = 0x00000000; >+ lck.in.file.handle = *h1; >+ ZERO_STRUCT(el); >+ el.flags = SMB2_LOCK_FLAG_EXCLUSIVE | >+ SMB2_LOCK_FLAG_FAIL_IMMEDIATELY; >+ el.offset = 0x0000000000000000; >+ el.length = 0x0000000000000001; >+ status = smb2_lock(tree, &lck); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "smb2_lock lock failed"); >+ >+ torture_comment(tctx, "1st notify => PENDING\n"); >+ ZERO_STRUCT(ntf1); >+ ntf1.in.file.handle = dh; >+ ntf1.in.recursive = 0x0000; >+ ntf1.in.buffer_size = 128; >+ ntf1.in.completion_filter= FILE_NOTIFY_CHANGE_ATTRIBUTES; >+ ntf1.in.unknown = 0x00000000; >+ req = smb2_notify_send(tree, &ntf1); >+ >+ while (!req->cancel.can_cancel && req->state <= SMB2_REQUEST_RECV) { >+ if (tevent_loop_once(tctx->ev) != 0) { >+ break; >+ } >+ } >+ >+ torture_assert_goto(tctx, req->state <= SMB2_REQUEST_RECV, ret, done, >+ "smb2_notify finished"); >+ >+ torture_comment(tctx, "sleep 10 seconds\n"); >+ smb_msleep(10*1000); >+ >+ torture_comment(tctx, "query info => EXPIRED\n"); >+ ZERO_STRUCT(qfinfo.access_information.out); >+ status = smb2_getinfo_file(tree, tctx, &qfinfo); >+ torture_assert_ntstatus_equal_goto(tctx, status, >+ NT_STATUS_NETWORK_SESSION_EXPIRED, >+ ret, done, "smb2_getinfo_file " >+ "returned unexpected status"); >+ >+ >+ torture_comment(tctx, "set info => EXPIRED\n"); >+ ZERO_STRUCT(sfinfo); >+ sfinfo.end_of_file_info.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION; >+ sfinfo.end_of_file_info.in.file.handle = *h1; >+ sfinfo.end_of_file_info.in.size = 1; >+ status = smb2_setinfo_file(tree, &sfinfo); >+ torture_assert_ntstatus_equal_goto(tctx, status, >+ NT_STATUS_NETWORK_SESSION_EXPIRED, >+ ret, done, "smb2_setinfo_file " >+ "returned unexpected status"); >+ >+ torture_comment(tctx, "flush => EXPIRED\n"); >+ ZERO_STRUCT(flsh); >+ flsh.in.file.handle = *h1; >+ status = smb2_flush(tree, &flsh); >+ torture_assert_ntstatus_equal_goto(tctx, status, >+ NT_STATUS_NETWORK_SESSION_EXPIRED, >+ ret, done, "smb2_flush " >+ "returned unexpected status"); >+ >+ torture_comment(tctx, "read => EXPIRED\n"); >+ ZERO_STRUCT(rd); >+ rd.in.file.handle = *h1; >+ rd.in.length = 5; >+ rd.in.offset = 0; >+ status = smb2_read(tree, tctx, &rd); >+ torture_assert_ntstatus_equal_goto(tctx, status, >+ NT_STATUS_NETWORK_SESSION_EXPIRED, >+ ret, done, "smb2_read " >+ "returned unexpected status"); >+ >+ torture_comment(tctx, "write => EXPIRED\n"); >+ status = smb2_util_write(tree, *h1, &wd, 0, 1); >+ torture_assert_ntstatus_equal_goto(tctx, status, >+ NT_STATUS_NETWORK_SESSION_EXPIRED, >+ ret, done, "smb2_util_write " >+ "returned unexpected status"); >+ >+ torture_comment(tctx, "ioctl => EXPIRED\n"); >+ ZERO_STRUCT(ctl); >+ ctl.in.file.handle = *h1; >+ ctl.in.function = FSCTL_SRV_ENUM_SNAPS; >+ ctl.in.max_response_size = 16; >+ ctl.in.flags = SMB2_IOCTL_FLAG_IS_FSCTL; >+ status = smb2_ioctl(tree, tctx, &ctl); >+ torture_assert_ntstatus_equal_goto(tctx, status, >+ NT_STATUS_NETWORK_SESSION_EXPIRED, >+ ret, done, "smb2_ioctl " >+ "returned unexpected status"); >+ >+ torture_comment(tctx, "oplock ack => EXPIRED\n"); >+ ZERO_STRUCT(oack); >+ oack.in.file.handle = *h1; >+ status = smb2_break(tree, &oack); >+ torture_assert_ntstatus_equal_goto(tctx, status, >+ NT_STATUS_NETWORK_SESSION_EXPIRED, >+ ret, done, "smb2_break " >+ "returned unexpected status"); >+ >+ if (caps & SMB2_CAP_LEASING) { >+ torture_comment(tctx, "lease ack => EXPIRED\n"); >+ ZERO_STRUCT(lack); >+ lack.in.lease.lease_version = 1; >+ lack.in.lease.lease_key.data[0] = 1; >+ lack.in.lease.lease_key.data[0] = 2; >+ status = smb2_lease_break_ack(tree, &lack); >+ torture_assert_ntstatus_equal_goto(tctx, status, >+ NT_STATUS_NETWORK_SESSION_EXPIRED, >+ ret, done, "smb2_break " >+ "returned unexpected status"); >+ } >+ >+ torture_comment(tctx, "query directory => EXPIRED\n"); >+ ZERO_STRUCT(fnd); >+ fnd.in.file.handle = dh; >+ 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; >+ status = smb2_find_level(tree, tree, &fnd, &count, &d); >+ torture_assert_ntstatus_equal_goto(tctx, status, >+ NT_STATUS_NETWORK_SESSION_EXPIRED, >+ ret, done, "smb2_find_level " >+ "returned unexpected status"); >+ >+ torture_comment(tctx, "1st notify => CANCEL\n"); >+ smb2_cancel(req); >+ >+ torture_comment(tctx, "2nd notify => EXPIRED\n"); >+ ZERO_STRUCT(ntf2); >+ ntf2.in.file.handle = dh; >+ ntf2.in.recursive = 0x0000; >+ ntf2.in.buffer_size = 128; >+ ntf2.in.completion_filter= FILE_NOTIFY_CHANGE_ATTRIBUTES; >+ ntf2.in.unknown = 0x00000000; >+ status = smb2_notify(tree, tctx, &ntf2); >+ torture_assert_ntstatus_equal_goto(tctx, status, >+ NT_STATUS_NETWORK_SESSION_EXPIRED, >+ ret, done, "smb2_notify " >+ "returned unexpected status"); >+ >+ torture_assert_goto(tctx, req->state > SMB2_REQUEST_RECV, ret, done, >+ "smb2_notify (1st) not finished"); >+ >+ status = smb2_notify_recv(req, tctx, &ntf1); >+ torture_assert_ntstatus_equal_goto(tctx, status, >+ NT_STATUS_CANCELLED, >+ ret, done, "smb2_notify cancelled" >+ "returned unexpected status"); >+ >+ torture_comment(tctx, "tcon => EXPIRED\n"); >+ tree2 = smb2_tree_init(tree->session, tctx, false); >+ torture_assert(tctx, tree2 != NULL, "smb2_tree_init"); >+ timeout_msec = tree->session->transport->options.request_timeout * 1000; >+ subreq = smb2cli_tcon_send(tree2, tctx->ev, >+ tree2->session->transport->conn, >+ timeout_msec, >+ tree2->session->smbXcli, >+ tree2->smbXcli, >+ 0, /* flags */ >+ unc); >+ torture_assert(tctx, subreq != NULL, "smb2cli_tcon_send"); >+ torture_assert(tctx, >+ tevent_req_poll_ntstatus(subreq, tctx->ev, &status), >+ "tevent_req_poll_ntstatus"); >+ status = smb2cli_tcon_recv(subreq); >+ TALLOC_FREE(subreq); >+ torture_assert_ntstatus_equal_goto(tctx, status, >+ NT_STATUS_NETWORK_SESSION_EXPIRED, >+ ret, done, "smb2cli_tcon" >+ "returned unexpected status"); >+ >+ torture_comment(tctx, "create => EXPIRED\n"); >+ status = smb2_util_roothandle(tree, &dh2); >+ torture_assert_ntstatus_equal_goto(tctx, status, >+ NT_STATUS_NETWORK_SESSION_EXPIRED, >+ ret, done, "smb2_util_roothandle" >+ "returned unexpected status"); >+ >+ torture_comment(tctx, "tdis => EXPIRED\n"); >+ status = smb2_tdis(tree); >+ torture_assert_ntstatus_equal_goto(tctx, status, >+ NT_STATUS_NETWORK_SESSION_EXPIRED, >+ ret, done, "smb2cli_tdis" >+ "returned unexpected status"); >+ >+ /* >+ * (Un)Lock, Close and Logoff are still possible >+ */ >+ >+ torture_comment(tctx, "1st unlock => OK\n"); >+ el.flags = SMB2_LOCK_FLAG_UNLOCK; >+ status = smb2_lock(tree, &lck); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "smb2_lock unlock failed"); >+ >+ torture_comment(tctx, "2nd unlock => RANGE_NOT_LOCKED\n"); >+ status = smb2_lock(tree, &lck); >+ torture_assert_ntstatus_equal_goto(tctx, status, >+ NT_STATUS_RANGE_NOT_LOCKED, >+ ret, done, "smb2_lock 2nd unlock" >+ "returned unexpected status"); >+ >+ torture_comment(tctx, "lock => EXPIRED\n"); >+ el.flags = SMB2_LOCK_FLAG_EXCLUSIVE | >+ SMB2_LOCK_FLAG_FAIL_IMMEDIATELY; >+ status = smb2_lock(tree, &lck); >+ torture_assert_ntstatus_equal_goto(tctx, status, >+ NT_STATUS_NETWORK_SESSION_EXPIRED, >+ ret, done, "smb2_util_roothandle" >+ "returned unexpected status"); >+ >+ torture_comment(tctx, "close => OK\n"); >+ status = smb2_util_close(tree, *h1); >+ h1 = NULL; >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "smb2_close failed"); >+ >+ torture_comment(tctx, "echo without session => OK\n"); >+ status = smb2_keepalive(tree->session->transport); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "smb2_keepalive without session failed"); >+ >+ torture_comment(tctx, "echo with session => OK\n"); >+ req = smb2_keepalive_send(tree->session->transport, tree->session); >+ status = smb2_keepalive_recv(req); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "smb2_keepalive with session failed"); >+ >+ torture_comment(tctx, "logoff => OK\n"); >+ status = smb2_logoff(tree->session); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "smb2_logoff failed"); >+ >+ ret = true; >+done: >+ if (h1 != NULL) { >+ smb2_util_close(tree, *h1); >+ } >+ >+ talloc_free(tree); >+ lpcfg_set_option(tctx->lp_ctx, "gensec_gssapi:requested_life_time=0"); >+ return ret; >+} >+ > bool test_session_bind1(struct torture_context *tctx, struct smb2_tree *tree1) > { > const char *host = torture_setting_string(tctx, "host", NULL); >@@ -1320,6 +1681,7 @@ struct torture_suite *torture_smb2_session_init(void) > torture_suite_add_1smb2_test(suite, "reauth5", test_session_reauth5); > torture_suite_add_1smb2_test(suite, "reauth6", test_session_reauth6); > torture_suite_add_simple_test(suite, "expire1", test_session_expire1); >+ torture_suite_add_simple_test(suite, "expire2", test_session_expire2); > torture_suite_add_1smb2_test(suite, "bind1", test_session_bind1); > > suite->description = talloc_strdup(suite, "SMB2-SESSION tests"); >-- >1.9.1 > > >From c8d70f088d30737c37393573be2b4d20bfd55212 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 21 Dec 2017 14:47:06 +0100 >Subject: [PATCH 2/3] s3:smbd: return the correct error for cancelled SMB2 > notifies on expired sessions > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=13197 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >--- > source3/smbd/notify.c | 17 +++++++++++++---- > 1 file changed, 13 insertions(+), 4 deletions(-) > >diff --git a/source3/smbd/notify.c b/source3/smbd/notify.c >index f64185d..add59089 100644 >--- a/source3/smbd/notify.c >+++ b/source3/smbd/notify.c >@@ -391,12 +391,21 @@ static void smbd_notify_cancel_by_map(struct notify_mid_map *map) > NTSTATUS notify_status = NT_STATUS_CANCELLED; > > if (smb2req != NULL) { >+ NTSTATUS sstatus; >+ > if (smb2req->session == NULL) { >- notify_status = STATUS_NOTIFY_CLEANUP; >- } else if (!NT_STATUS_IS_OK(smb2req->session->status)) { >- notify_status = STATUS_NOTIFY_CLEANUP; >+ sstatus = NT_STATUS_USER_SESSION_DELETED; >+ } else { >+ sstatus = smb2req->session->status; > } >- if (smb2req->tcon == NULL) { >+ >+ if (NT_STATUS_EQUAL(sstatus, NT_STATUS_NETWORK_SESSION_EXPIRED)) { >+ sstatus = NT_STATUS_OK; >+ } >+ >+ if (!NT_STATUS_IS_OK(sstatus)) { >+ notify_status = STATUS_NOTIFY_CLEANUP; >+ } else if (smb2req->tcon == NULL) { > notify_status = STATUS_NOTIFY_CLEANUP; > } else if (!NT_STATUS_IS_OK(smb2req->tcon->status)) { > notify_status = STATUS_NOTIFY_CLEANUP; >-- >1.9.1 > > >From b37c42846f353fcd2ef4f94e59b41e03e30560f8 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 20 Dec 2017 14:05:54 +0100 >Subject: [PATCH 3/3] s3:smb2_server: allow logoff, close, unlock, cancel and > echo on expired sessions > >Windows client at least doesn't have code to replay >a SMB2 Close after getting NETWORK_SESSION_EXPIRED, >which locks out a the client and generates an endless >loop around NT_STATUS_SHARING_VIOLATION. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=13197 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >--- > selftest/knownfail.d/session.expire2 | 1 - > source3/smbd/smb2_lock.c | 17 +++++++++++++++++ > source3/smbd/smb2_server.c | 19 +++++++++++++++++++ > 3 files changed, 36 insertions(+), 1 deletion(-) > delete mode 100644 selftest/knownfail.d/session.expire2 > >diff --git a/selftest/knownfail.d/session.expire2 b/selftest/knownfail.d/session.expire2 >deleted file mode 100644 >index 998ccbd..0000000 >--- a/selftest/knownfail.d/session.expire2 >+++ /dev/null >@@ -1 +0,0 @@ >-^samba3.smb2.session.*krb5.expire2 >diff --git a/source3/smbd/smb2_lock.c b/source3/smbd/smb2_lock.c >index 2fcd359..45b833c 100644 >--- a/source3/smbd/smb2_lock.c >+++ b/source3/smbd/smb2_lock.c >@@ -98,6 +98,23 @@ NTSTATUS smbd_smb2_request_process_lock(struct smbd_smb2_request *req) > in_locks[l].flags = IVAL(lock_buffer, 0x10); > /* 0x14 - 4 reserved bytes */ > >+ status = req->session->status; >+ if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) { >+ /* >+ * We need to catch NT_STATUS_NETWORK_SESSION_EXPIRED >+ * for lock requests only. >+ * >+ * Unlock requests still need to be processed! >+ * >+ * This means smbd_smb2_request_check_session() >+ * can't handle the difference and always >+ * allows SMB2_OP_LOCK. >+ */ >+ if (in_locks[0].flags != SMB2_LOCK_FLAG_UNLOCK) { >+ return smbd_smb2_request_error(req, status); >+ } >+ } >+ > lock_buffer = SMBD_SMB2_IN_DYN_PTR(req); > > for (l=1; l < in_lock_count; l++) { >diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c >index e6bc753..de2f922c 100644 >--- a/source3/smbd/smb2_server.c >+++ b/source3/smbd/smb2_server.c >@@ -1885,6 +1885,25 @@ static NTSTATUS smbd_smb2_request_check_session(struct smbd_smb2_request *req) > case SMB2_OP_SESSSETUP: > status = NT_STATUS_OK; > break; >+ case SMB2_OP_LOGOFF: >+ case SMB2_OP_CLOSE: >+ case SMB2_OP_LOCK: >+ case SMB2_OP_CANCEL: >+ case SMB2_OP_KEEPALIVE: >+ /* >+ * [MS-SMB2] 3.3.5.2.9 Verifying the Session >+ * specifies that LOGOFF, CLOSE and (UN)LOCK >+ * should always be processed even on expired sessions. >+ * >+ * Also see the logic in >+ * smbd_smb2_request_process_lock(). >+ * >+ * The smb2.session.expire2 test shows that >+ * CANCEL and KEEPALIVE/ECHO should also >+ * be processed. >+ */ >+ status = NT_STATUS_OK; >+ break; > default: > break; > } >-- >1.9.1 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Flags:
metze
:
review?
(
slow
)
jra
:
review+
Actions:
View
Attachments on
bug 13197
:
14021
| 14024