CVE-2016-2114: s3:smbd: use the correct default values for "smb signing"
authorStefan Metzmacher <metze@samba.org>
Wed, 15 Jul 2015 08:57:03 +0000 (10:57 +0200)
committerStefan Metzmacher <metze@samba.org>
Tue, 12 Apr 2016 17:25:25 +0000 (19:25 +0200)
This means an ad_dc will now require signing by default.
This matches the default behavior of Windows dc and avoids
man in the middle attacks.

The main logic for this hides in lpcfg_server_signing_allowed().

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

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: G√ľnther Deschner <gd@samba.org>
source3/smbd/negprot.c
source3/smbd/smb2_negprot.c
source3/smbd/smb2_sesssetup.c

index 759042183902b426276c4c9fc8abe73fe7e7f487..d2e5e2ee27e3b86c07069d9e583fcedda5a457ca 100644 (file)
@@ -543,6 +543,7 @@ void reply_negprot(struct smb_request *req)
        size_t converted_size;
        struct smbXsrv_connection *xconn = req->xconn;
        struct smbd_server_connection *sconn = req->sconn;
+       bool signing_required = true;
 
        START_PROFILE(SMBnegprot);
 
@@ -716,8 +717,9 @@ void reply_negprot(struct smb_request *req)
 
        DEBUG( 5, ( "negprot index=%d\n", choice ) );
 
-       if ((lp_server_signing() == SMB_SIGNING_REQUIRED)
-           && (chosen_level < PROTOCOL_NT1)) {
+       /* We always have xconn->smb1.signing_state also for >= SMB2_02 */
+       signing_required = smb_signing_is_mandatory(xconn->smb1.signing_state);
+       if (signing_required && (chosen_level < PROTOCOL_NT1)) {
                exit_server_cleanly("SMB signing is required and "
                        "client negotiated a downlevel protocol");
        }
index e48d2b80add75a4f76753094212b030033129010..9c03b2ca8b86158db1814aff4c7dc828dd253c8b 100644 (file)
@@ -25,6 +25,7 @@
 #include "../libcli/smb/smb2_negotiate_context.h"
 #include "../lib/tsocket/tsocket.h"
 #include "../librpc/ndr/libndr.h"
+#include "../libcli/smb/smb_signing.h"
 
 extern fstring remote_proto;
 
@@ -160,6 +161,7 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
        uint32_t max_read = lp_smb2_max_read();
        uint32_t max_write = lp_smb2_max_write();
        NTTIME now = timeval_to_nttime(&req->request_time);
+       bool signing_required = true;
 
        status = smbd_smb2_request_verify_sizes(req, 0x24);
        if (!NT_STATUS_IS_OK(status)) {
@@ -294,7 +296,13 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
        }
 
        security_mode = SMB2_NEGOTIATE_SIGNING_ENABLED;
-       if (lp_server_signing() == SMB_SIGNING_REQUIRED) {
+       /*
+        * We use xconn->smb1.signing_state as that's already present
+        * and used lpcfg_server_signing_allowed() to get the correct
+        * defaults, e.g. signing_required for an ad_dc.
+        */
+       signing_required = smb_signing_is_mandatory(xconn->smb1.signing_state);
+       if (signing_required) {
                security_mode |= SMB2_NEGOTIATE_SIGNING_REQUIRED;
        }
 
index a95f8a1a4997f04d6cbd6ce58ec5f6610ed77e25..78bda7b23335f4d5528abd843b07d5919c51ac43 100644 (file)
@@ -262,7 +262,8 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbXsrv_session *session,
        }
 
        if ((in_security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) ||
-           lp_server_signing() == SMB_SIGNING_REQUIRED) {
+           (xconn->smb2.server.security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED))
+       {
                x->global->signing_flags = SMBXSRV_SIGNING_REQUIRED;
        }