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++) {
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;
}