From: Stefan Metzmacher Date: Wed, 20 Dec 2017 13:05:54 +0000 (+0100) Subject: s3:smb2_server: allow logoff, close, unlock, cancel and echo on expired sessions X-Git-Tag: samba-4.6.15~39 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b7267199ddd79f79360769cd732a9079a7ce09bd;p=thirdparty%2Fsamba.git 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 --- diff --git a/selftest/knownfail.d/session.expire2 b/selftest/knownfail.d/session.expire2 deleted file mode 100644 index 998ccbd72b5..00000000000 --- 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 2fcd3592624..45b833cbca6 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 e6bc7536938..de2f922cffa 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; }