smb2_server: set req->do_encryption = true earlier
authorStefan Metzmacher <metze@samba.org>
Fri, 17 Aug 2018 09:35:41 +0000 (11:35 +0200)
committerVolker Lendecke <vl@samba.org>
Tue, 2 Oct 2018 12:11:30 +0000 (14:11 +0200)
The STATUS_SESSION_EXPIRED error was returned unencrypted,
if the request was encrypted.

If clients use SMB3 encryption and the kerberos authenticated session
expires, clients disconnect the connection instead of doing a reauthentication.

From https://blogs.msdn.microsoft.com/openspecification/2012/10/05/encryption-in-smb-3-0-a-protocol-perspective/

  The sender encrypts the message if any of the following conditions is
  satisfied:

    - If the sender is sending a response to an encrypted request.
    - If Session.EncryptData is TRUE and the request or response being
      sent is not NEGOTIATE.
    - If Session.EncryptData is FALSE, the request or response being sent
      is not NEGOTIATE or SESSION_SETUP or TREE_CONNECT, and
      <TreeConnect|Share>.EncryptData is TRUE.

[MS-SMB2] 3.3.4.1.4 Encrypting the Message

 If Connection.Dialect belongs to the SMB 3.x dialect family and
 Connection.ClientCapabilities includes the SMB2_GLOBAL_CAP_ENCRYPTION
 bit, the server MUST encrypt the message before sending, if any of the
 following conditions are satisfied:

 - If the message being sent is any response to a client request for which
   Request.IsEncrypted is TRUE.

 - If Session.EncryptData is TRUE and the response being sent is not
   SMB2_NEGOTIATE or SMB2 SESSION_SETUP.

 - If Session.EncryptData is FALSE, the response being sent is not
   SMB2_NEGOTIATE or SMB2 SESSION_SETUP or SMB2 TREE_CONNECT, and
   Share.EncryptData for the share associated with the TreeId in the SMB2
   header of the response is TRUE.

 The server MUST encrypt the message as specified in section 3.1.4.3,
 before sending it to the client.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=13624

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Autobuild-User(master): Volker Lendecke <vl@samba.org>
Autobuild-Date(master): Tue Oct  2 14:11:30 CEST 2018 on sn-devel-144

selftest/knownfail.d/session-expire [deleted file]
source3/smbd/smb2_server.c

diff --git a/selftest/knownfail.d/session-expire b/selftest/knownfail.d/session-expire
deleted file mode 100644 (file)
index 033564a..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-^samba3.smb2.session krb5.expire1e
-^samba3.smb2.session krb5.expire2e
index 229f8ab0e856beb86cdf3e5c32a608bb467919ac..e36db1e55f5e3ce12b888927aac053e45e27e3e1 100644 (file)
@@ -2359,7 +2359,11 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
 
        req->async_internal = false;
        req->do_signing = false;
-       req->do_encryption = false;
+       if (opcode != SMB2_OP_SESSSETUP) {
+               req->do_encryption = encryption_desired;
+       } else {
+               req->do_encryption = false;
+       }
        req->was_encrypted = false;
        if (intf_v->iov_len == SMB2_TF_HDR_SIZE) {
                const uint8_t *intf = SMBD_SMB2_IN_TF_PTR(req);
@@ -2383,9 +2387,11 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
                }
 
                req->was_encrypted = true;
+               req->do_encryption = true;
        }
 
        if (encryption_required && !req->was_encrypted) {
+               req->do_encryption = true;
                return smbd_smb2_request_error(req,
                                NT_STATUS_ACCESS_DENIED);
        }
@@ -2523,8 +2529,11 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
                        encryption_required = true;
                }
                if (encryption_required && !req->was_encrypted) {
+                       req->do_encryption = true;
                        return smbd_smb2_request_error(req,
                                NT_STATUS_ACCESS_DENIED);
+               } else if (encryption_desired) {
+                       req->do_encryption = true;
                }
        } else if (call->need_session) {
                struct auth_session_info *session_info = NULL;
@@ -2544,10 +2553,6 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
                                      session_info->info->domain_name);
        }
 
-       if (req->was_encrypted || encryption_desired) {
-               req->do_encryption = true;
-       }
-
        if (req->session) {
                bool update_session_global = false;
                bool update_tcon_global = false;