smbd:smb2: separate between encryption required and enc desired
authorMichael Adam <obnox@samba.org>
Wed, 1 Jul 2015 15:42:58 +0000 (17:42 +0200)
committerKarolin Seeger <kseeger@samba.org>
Sun, 19 Jul 2015 18:13:10 +0000 (20:13 +0200)
this means we:
- accept unencrypted requests if encryption only desired
  and not required,
- but we always send encrypted responses in the desired
  case, not only when the request was encrypted.

For this purpose, the do_encryption in the request
structure is separated into was_encrypted and do_encryption.

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

Signed-off-by: Michael Adam <obnox@samba.org>
Reviewed-by: Guenther Deschner <gd@samba.org>
(cherry picked from commit 3bb299944391633c45d87d5e8ad48c2c14428592)

source3/smbd/globals.h
source3/smbd/smb2_server.c

index 66358fb41fee7ce55647bce8d283333c566451ef..93624bbb24ac7f524f805244d3fb63a37cdfe82b 100644 (file)
@@ -503,6 +503,9 @@ struct smbd_smb2_request {
 
        int current_idx;
        bool do_signing;
+       /* Was the request encrypted? */
+       bool was_encrypted;
+       /* Should we encrypt? */
        bool do_encryption;
        struct tevent_timer *async_te;
        bool compound_related;
index eed0b0e380ab49ac0c2bc8a5f21afac70b9559fd..70ffc3cfe3ae4976fe00ccb543eedbb5367a47a9 100644 (file)
@@ -1862,6 +1862,7 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
        NTSTATUS return_value;
        struct smbXsrv_session *x = NULL;
        bool signing_required = false;
+       bool encryption_desired = false;
        bool encryption_required = false;
 
        inhdr = SMBD_SMB2_IN_HDR_PTR(req);
@@ -1907,11 +1908,13 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
        x = req->session;
        if (x != NULL) {
                signing_required = x->global->signing_required;
+               encryption_desired = x->encryption_desired;
                encryption_required = x->global->encryption_required;
        }
 
        req->do_signing = false;
        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);
                uint64_t tf_session_id = BVAL(intf, SMB2_TF_SESSION_ID);
@@ -1933,10 +1936,10 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
                                        NT_STATUS_ACCESS_DENIED);
                }
 
-               req->do_encryption = true;
+               req->was_encrypted = true;
        }
 
-       if (encryption_required && !req->do_encryption) {
+       if (encryption_required && !req->was_encrypted) {
                return smbd_smb2_request_error(req,
                                NT_STATUS_ACCESS_DENIED);
        }
@@ -1968,7 +1971,7 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
                req->compat_chain_fsp = NULL;
        }
 
-       if (req->do_encryption) {
+       if (req->was_encrypted) {
                signing_required = false;
        } else if (signing_required || (flags & SMB2_HDR_FLAG_SIGNED)) {
                DATA_BLOB signing_key;
@@ -2039,15 +2042,22 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
                if (!NT_STATUS_IS_OK(status)) {
                        return smbd_smb2_request_error(req, status);
                }
+               if (req->tcon->encryption_desired) {
+                       encryption_desired = true;
+               }
                if (req->tcon->global->encryption_required) {
                        encryption_required = true;
                }
-               if (encryption_required && !req->do_encryption) {
+               if (encryption_required && !req->was_encrypted) {
                        return smbd_smb2_request_error(req,
                                NT_STATUS_ACCESS_DENIED);
                }
        }
 
+       if (req->was_encrypted || encryption_desired) {
+               req->do_encryption = true;
+       }
+
        if (call->fileid_ofs != 0) {
                size_t needed = call->fileid_ofs + 16;
                const uint8_t *body = SMBD_SMB2_IN_BODY_PTR(req);