The branch, master has been updated
       via  9945f3e3548 CVE-2020-1472(ZeroLogon): s4 torture rpc: repeated 
bytes in client challenge
       via  4b262b03e1e CVE-2020-1472(ZeroLogon): s4 torture rpc: Test empty 
machine acct pwd
       via  d1790a0b5ae CVE-2020-1472(ZeroLogon): docs-xml: document 'server 
require schannel:COMPUTERACCOUNT'
       via  b8e4b0f4306 CVE-2020-1472(ZeroLogon): s3:rpc_server/netlogon: log 
warnings about unsecure configurations
       via  b74017d2dd1 CVE-2020-1472(ZeroLogon): s3:rpc_server/netlogon: 
support "server require schannel:WORKSTATION$ = no"
       via  9ef5b63e7a1 CVE-2020-1472(ZeroLogon): s3:rpc_server/netlogon: 
refactor dcesrv_netr_creds_server_step_check()
       via  ca8a0098ac2 CVE-2020-1472(ZeroLogon): s4:rpc_server/netlogon: log 
warnings about unsecure configurations
       via  f9b772bf286 CVE-2020-1472(ZeroLogon): s4:rpc_server/netlogon: 
support "server require schannel:WORKSTATION$ = no"
       via  be8e6394990 CVE-2020-1472(ZeroLogon): s4:rpc_server/netlogon: 
refactor dcesrv_netr_creds_server_step_check()
       via  82d41977a8b CVE-2020-1472(ZeroLogon): s3:rpc_server/netlogon: 
protect netr_ServerPasswordSet2 against unencrypted passwords
       via  9ec8b59bdea CVE-2020-1472(ZeroLogon): s3:rpc_server/netlogon: Fix 
mem leak onto p->mem_ctx in error path of _netr_ServerPasswordSet2().
       via  d8a6e6549c1 CVE-2020-1472(ZeroLogon): s4:rpc_server/netlogon: 
protect netr_ServerPasswordSet2 against unencrypted passwords
       via  d3123858fb5 CVE-2020-1472(ZeroLogon): libcli/auth: reject weak 
client challenges in netlogon_creds_server_init()
       via  53528c71ffd CVE-2020-1472(ZeroLogon): libcli/auth: add 
netlogon_creds_is_random_challenge() to avoid weak values
       via  74eb448adf7 CVE-2020-1472(ZeroLogon): s4:rpc_server:netlogon: make 
use of netlogon_creds_random_challenge()
       via  caba2d8082d CVE-2020-1472(ZeroLogon): s3:rpc_server:netlogon: make 
use of netlogon_creds_random_challenge()
       via  46642fd32d9 CVE-2020-1472(ZeroLogon): libcli/auth: make use of 
netlogon_creds_random_challenge() in netlogon_creds_cli.c
       via  355efadc6a1 CVE-2020-1472(ZeroLogon): s4:torture/rpc: make use of 
netlogon_creds_random_challenge()
       via  b813cdcac37 CVE-2020-1472(ZeroLogon): libcli/auth: add 
netlogon_creds_random_challenge()
      from  380938b00fb nt_printing_ads: add missing printShareName attribute 
when publishing printers

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 9945f3e3548657c33cc2e5ef97eedd1dfe2edf71
Author: Gary Lockyer <g...@catalyst.net.nz>
Date:   Fri Sep 18 15:57:34 2020 +1200

    CVE-2020-1472(ZeroLogon): s4 torture rpc: repeated bytes in client challenge
    
    Ensure that client challenges with the first 5 bytes identical are
    rejected.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
    
    Signed-off-by: Gary Lockyer <g...@catalyst.net.nz>
    Reviewed-by: Stefan Metzmacher <me...@samba.org>
    
    Autobuild-User(master): Stefan Metzmacher <me...@samba.org>
    Autobuild-Date(master): Fri Sep 18 14:13:17 UTC 2020 on sn-devel-184

commit 4b262b03e1e8285c399338895832a115953d3f23
Author: Gary Lockyer <g...@catalyst.net.nz>
Date:   Fri Sep 18 12:39:54 2020 +1200

    CVE-2020-1472(ZeroLogon): s4 torture rpc: Test empty machine acct pwd
    
    Ensure that an empty machine account password can't be set by
    netr_ServerPasswordSet2
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
    
    Signed-off-by: Gary Lockyer <g...@catalyst.net.nz>
    Reviewed-by: Stefan Metzmacher <me...@samba.org>

commit d1790a0b5ae7160f6707c6c4fbf2217b251584ea
Author: Stefan Metzmacher <me...@samba.org>
Date:   Thu Sep 17 17:27:54 2020 +0200

    CVE-2020-1472(ZeroLogon): docs-xml: document 'server require 
schannel:COMPUTERACCOUNT'
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Gary Lockyer <g...@catalyst.net.nz>

commit b8e4b0f4306e2d0b4b7c7c443d97abf46d7f9aca
Author: Günther Deschner <g...@samba.org>
Date:   Thu Sep 17 14:42:52 2020 +0200

    CVE-2020-1472(ZeroLogon): s3:rpc_server/netlogon: log warnings about 
unsecure configurations
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
    
    Pair-Programmed-With: Stefan Metzmacher <me...@samba.org>
    
    Signed-off-by: Günther Deschner <g...@samba.org>
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Gary Lockyer <g...@catalyst.net.nz>

commit b74017d2dd15006f4bec899aa38191a3b44800e4
Author: Günther Deschner <g...@samba.org>
Date:   Thu Sep 17 14:23:16 2020 +0200

    CVE-2020-1472(ZeroLogon): s3:rpc_server/netlogon: support "server require 
schannel:WORKSTATION$ = no"
    
    This allows to add expections for individual workstations, when using 
"server schannel = yes".
    "server schannel = auto" is very insecure and will be removed soon.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
    
    Pair-Programmed-With: Stefan Metzmacher <me...@samba.org>
    
    Signed-off-by: Günther Deschner <g...@samba.org>
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Gary Lockyer <g...@catalyst.net.nz>

commit 9ef5b63e7a169154401e58f7a29ed25443e5318f
Author: Günther Deschner <g...@samba.org>
Date:   Thu Sep 17 14:57:22 2020 +0200

    CVE-2020-1472(ZeroLogon): s3:rpc_server/netlogon: refactor 
dcesrv_netr_creds_server_step_check()
    
    We should debug more details about the failing request.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
    
    Pair-Programmed-With: Stefan Metzmacher <me...@samba.org>
    
    Signed-off-by: Günther Deschner <g...@samba.org>
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Gary Lockyer <g...@catalyst.net.nz>

commit ca8a0098ac207123a47b8b8f8602599d71d739db
Author: Stefan Metzmacher <me...@samba.org>
Date:   Thu Sep 17 13:37:26 2020 +0200

    CVE-2020-1472(ZeroLogon): s4:rpc_server/netlogon: log warnings about 
unsecure configurations
    
    This should give admins wawrnings until they have a secure
    configuration.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Ralph Boehme <s...@samba.org>
    Reviewed-by: Günther Deschner <g...@samba.org>
    Reviewed-by: Gary Lockyer <g...@catalyst.net.nz>

commit f9b772bf286b7bde6a29cb8d7bbd241638daf5e7
Author: Stefan Metzmacher <me...@samba.org>
Date:   Wed Sep 16 10:56:53 2020 +0200

    CVE-2020-1472(ZeroLogon): s4:rpc_server/netlogon: support "server require 
schannel:WORKSTATION$ = no"
    
    This allows to add expections for individual workstations, when using 
"server schannel = yes".
    "server schannel = auto" is very insecure and will be removed soon.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Gary Lockyer <g...@catalyst.net.nz>

commit be8e63949908d8c10d490c8cd0119df4fb917eeb
Author: Stefan Metzmacher <me...@samba.org>
Date:   Wed Sep 16 10:18:45 2020 +0200

    CVE-2020-1472(ZeroLogon): s4:rpc_server/netlogon: refactor 
dcesrv_netr_creds_server_step_check()
    
    We should debug more details about the failing request.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Gary Lockyer <g...@catalyst.net.nz>

commit 82d41977a8bef426396e3e00833d55711a55f372
Author: Jeremy Allison <j...@samba.org>
Date:   Wed Sep 16 12:53:50 2020 -0700

    CVE-2020-1472(ZeroLogon): s3:rpc_server/netlogon: protect 
netr_ServerPasswordSet2 against unencrypted passwords
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
    
    Pair-Programmed-With: Stefan Metzmacher <me...@samba.org>
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Gary Lockyer <g...@catalyst.net.nz>

commit 9ec8b59bdea19c99099a718ff9e04cd854563e11
Author: Jeremy Allison <j...@samba.org>
Date:   Wed Sep 16 12:48:21 2020 -0700

    CVE-2020-1472(ZeroLogon): s3:rpc_server/netlogon: Fix mem leak onto 
p->mem_ctx in error path of _netr_ServerPasswordSet2().
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
    
    Signed-off-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Gary Lockyer <g...@catalyst.net.nz>

commit d8a6e6549c185daa26852d6d85f475cddfb3083a
Author: Stefan Metzmacher <me...@samba.org>
Date:   Wed Sep 16 19:20:25 2020 +0200

    CVE-2020-1472(ZeroLogon): s4:rpc_server/netlogon: protect 
netr_ServerPasswordSet2 against unencrypted passwords
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Gary Lockyer <g...@catalyst.net.nz>

commit d3123858fb59046e826cf2c7ec2a3839e6508624
Author: Stefan Metzmacher <me...@samba.org>
Date:   Wed Sep 16 16:17:29 2020 +0200

    CVE-2020-1472(ZeroLogon): libcli/auth: reject weak client challenges in 
netlogon_creds_server_init()
    
    This implements the note from MS-NRPC 3.1.4.1 Session-Key Negotiation:
    
     7. If none of the first 5 bytes of the client challenge is unique, the
        server MUST fail session-key negotiation without further processing of
        the following steps.
    
    It lets ./zerologon_tester.py from
    https://github.com/SecuraBV/CVE-2020-1472.git
    report: "Attack failed. Target is probably patched."
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Gary Lockyer <g...@catalyst.net.nz>

commit 53528c71ffdb3377c4e73ac596c8507bc3898e83
Author: Stefan Metzmacher <me...@samba.org>
Date:   Wed Sep 16 16:15:26 2020 +0200

    CVE-2020-1472(ZeroLogon): libcli/auth: add 
netlogon_creds_is_random_challenge() to avoid weak values
    
    This is the check Windows is using, so we won't generate challenges,
    which are rejected by Windows DCs (and future Samba DCs).
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Gary Lockyer <g...@catalyst.net.nz>

commit 74eb448adf7fb638fe925eab87a2dbfe9c002cc0
Author: Stefan Metzmacher <me...@samba.org>
Date:   Wed Sep 16 16:10:53 2020 +0200

    CVE-2020-1472(ZeroLogon): s4:rpc_server:netlogon: make use of 
netlogon_creds_random_challenge()
    
    This is not strictly needed, but makes things more clear.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Gary Lockyer <g...@catalyst.net.nz>

commit caba2d8082d4b038aa59954b6e812612c2ecc0e1
Author: Stefan Metzmacher <me...@samba.org>
Date:   Wed Sep 16 16:10:53 2020 +0200

    CVE-2020-1472(ZeroLogon): s3:rpc_server:netlogon: make use of 
netlogon_creds_random_challenge()
    
    This is not strictly needed, but makes things more clear.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Gary Lockyer <g...@catalyst.net.nz>

commit 46642fd32d91b008615b859cfdf946f63b1ca0aa
Author: Stefan Metzmacher <me...@samba.org>
Date:   Wed Sep 16 16:08:38 2020 +0200

    CVE-2020-1472(ZeroLogon): libcli/auth: make use of 
netlogon_creds_random_challenge() in netlogon_creds_cli.c
    
    This will avoid getting rejected by the server if we generate
    a weak challenge.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Gary Lockyer <g...@catalyst.net.nz>

commit 355efadc6a18ffaaef2e4786e35e89780b10bccc
Author: Stefan Metzmacher <me...@samba.org>
Date:   Wed Sep 16 16:07:30 2020 +0200

    CVE-2020-1472(ZeroLogon): s4:torture/rpc: make use of 
netlogon_creds_random_challenge()
    
    This will avoid getting flakey tests once our server starts to
    reject weak challenges.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Gary Lockyer <g...@catalyst.net.nz>

commit b813cdcac377210c3ab18e0d0a0c1a76870b1d74
Author: Stefan Metzmacher <me...@samba.org>
Date:   Wed Sep 16 16:04:57 2020 +0200

    CVE-2020-1472(ZeroLogon): libcli/auth: add netlogon_creds_random_challenge()
    
    It's good to have just a single isolated function that will generate
    random challenges, in future we can add some logic in order to
    avoid weak values, which are likely to be rejected by a server.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Gary Lockyer <g...@catalyst.net.nz>

-----------------------------------------------------------------------

Summary of changes:
 docs-xml/smbdotconf/security/serverschannel.xml |  69 +++-
 libcli/auth/credentials.c                       |  44 ++-
 libcli/auth/netlogon_creds_cli.c                |   3 +-
 libcli/auth/proto.h                             |   3 +
 libcli/auth/wscript_build                       |   2 +-
 source3/rpc_server/netlogon/srv_netlog_nt.c     | 212 +++++++++++-
 source4/rpc_server/netlogon/dcerpc_netlogon.c   | 175 +++++++++-
 source4/torture/rpc/lsa.c                       |   2 +-
 source4/torture/rpc/netlogon.c                  | 434 ++++++++++++++++++++----
 9 files changed, 835 insertions(+), 109 deletions(-)


Changeset truncated at 500 lines:

diff --git a/docs-xml/smbdotconf/security/serverschannel.xml 
b/docs-xml/smbdotconf/security/serverschannel.xml
index 489492d79b1..b682d086f76 100644
--- a/docs-xml/smbdotconf/security/serverschannel.xml
+++ b/docs-xml/smbdotconf/security/serverschannel.xml
@@ -7,26 +7,65 @@
 <description>
 
     <para>
-       This option is deprecated with Samba 4.8 and will be removed in future.
-       At the same time the default changed to yes, which will be the
-       hardcoded behavior in future. If you have the need for the behavior of 
"auto"
-       to be kept, please file a bug at https://bugzilla.samba.org.
+       This option is deprecated and will be removed in future,
+       as it is a security problem if not set to "yes" (which will be
+       the hardcoded behavior in future).
     </para>
 
     <para>
-       This controls whether the server offers or even demands the use of the 
netlogon schannel.
-       <smbconfoption name="server schannel">no</smbconfoption> does not offer 
the schannel, <smbconfoption
-       name="server schannel">auto</smbconfoption> offers the schannel but 
does not enforce it, and <smbconfoption
-       name="server schannel">yes</smbconfoption> denies access if the client 
is not able to speak netlogon schannel.
-       This is only the case for Windows NT4 before SP4.
-       </para>
-
+       Samba will complain in the log files at log level 0,
+       about the security problem if the option is not set to "yes".
+    </para>
     <para>
-       Please note that with this set to <literal>no</literal>, you will have 
to apply the WindowsXP
-       <filename>WinXP_SignOrSeal.reg</filename> registry patch found in the 
docs/registry subdirectory of the Samba distribution tarball.
-       </para>
+       See CVE-2020-1472(ZeroLogon) 
https://bugzilla.samba.org/show_bug.cgi?id=14497
+    </para>
+
+    <para>If you still have legacy domain members use the <smbconfoption 
name="server require schannel:COMPUTERACCOUNT"/> option.
+    </para>
+
+    <para>This option yields precedence to the <smbconfoption name="server 
require schannel:COMPUTERACCOUNT"/> option.</para>
+
 </description>
 
 <value type="default">yes</value>
-<value type="example">auto</value>
+</samba:parameter>
+
+<samba:parameter name="server require schannel:COMPUTERACCOUNT"
+                 context="G"
+                 type="string"
+                 xmlns:samba="http://www.samba.org/samba/DTD/samba-doc";>
+<description>
+
+    <para>If you still have legacy domain members, which required "server 
schannel = auto" before,
+       it is possible to specify explicit expection per computer account
+       by using 'server require schannel:COMPUTERACCOUNT = no' as option.
+       Note that COMPUTERACCOUNT has to be the sAMAccountName value of
+       the computer account (including the trailing '$' sign).
+    </para>
+
+    <para>
+       Samba will complain in the log files at log level 0,
+       about the security problem if the option is not set to "no",
+       but the related computer is actually using the netlogon
+       secure channel (schannel) feature.
+    </para>
+
+    <para>
+       Samba will warn in the log files at log level 5,
+       if a setting is still needed for the specified computer account.
+    </para>
+
+    <para>
+       See CVE-2020-1472(ZeroLogon) 
https://bugzilla.samba.org/show_bug.cgi?id=14497
+    </para>
+
+    <para>This option takes precedence to the <smbconfoption name="server 
schannel"/> option.</para>
+
+    <programlisting>
+       server require schannel:LEGACYCOMPUTER1$ = no
+       server require schannel:NASBOX$ = no
+       server require schannel:LEGACYCOMPUTER2$ = no
+    </programlisting>
+</description>
+
 </samba:parameter>
diff --git a/libcli/auth/credentials.c b/libcli/auth/credentials.c
index c541eeff470..23339d98bfa 100644
--- a/libcli/auth/credentials.c
+++ b/libcli/auth/credentials.c
@@ -24,6 +24,7 @@
 #include "system/time.h"
 #include "libcli/auth/libcli_auth.h"
 #include "../libcli/security/dom_sid.h"
+#include "lib/util/util_str_escape.h"
 
 #ifndef HAVE_GNUTLS_AES_CFB8
 #include "lib/crypto/aes.h"
@@ -33,6 +34,33 @@
 #include <gnutls/gnutls.h>
 #include <gnutls/crypto.h>
 
+bool netlogon_creds_is_random_challenge(const struct netr_Credential 
*challenge)
+{
+       /*
+        * If none of the first 5 bytes of the client challenge is unique, the
+        * server MUST fail session-key negotiation without further processing
+        * of the following steps.
+        */
+
+       if (challenge->data[1] == challenge->data[0] &&
+           challenge->data[2] == challenge->data[0] &&
+           challenge->data[3] == challenge->data[0] &&
+           challenge->data[4] == challenge->data[0])
+       {
+               return false;
+       }
+
+       return true;
+}
+
+void netlogon_creds_random_challenge(struct netr_Credential *challenge)
+{
+       ZERO_STRUCTP(challenge);
+       while (!netlogon_creds_is_random_challenge(challenge)) {
+               generate_random_buffer(challenge->data, 
sizeof(challenge->data));
+       }
+}
+
 static NTSTATUS netlogon_creds_step_crypt(struct 
netlogon_creds_CredentialState *creds,
                                          const struct netr_Credential *in,
                                          struct netr_Credential *out)
@@ -677,7 +705,7 @@ struct netlogon_creds_CredentialState 
*netlogon_creds_server_init(TALLOC_CTX *me
 
        struct netlogon_creds_CredentialState *creds = talloc_zero(mem_ctx, 
struct netlogon_creds_CredentialState);
        NTSTATUS status;
-
+       bool ok;
 
        if (!creds) {
                return NULL;
@@ -690,6 +718,20 @@ struct netlogon_creds_CredentialState 
*netlogon_creds_server_init(TALLOC_CTX *me
        dump_data_pw("Server chall", server_challenge->data, 
sizeof(server_challenge->data));
        dump_data_pw("Machine Pass", machine_password->hash, 
sizeof(machine_password->hash));
 
+       ok = netlogon_creds_is_random_challenge(client_challenge);
+       if (!ok) {
+               DBG_WARNING("CVE-2020-1472(ZeroLogon): "
+                           "non-random client challenge rejected for "
+                           "client_account[%s] client_computer_name[%s]\n",
+                           log_escape(mem_ctx, client_account),
+                           log_escape(mem_ctx, client_computer_name));
+               dump_data(DBGLVL_WARNING,
+                         client_challenge->data,
+                         sizeof(client_challenge->data));
+               talloc_free(creds);
+               return NULL;
+       }
+
        creds->computer_name = talloc_strdup(creds, client_computer_name);
        if (!creds->computer_name) {
                talloc_free(creds);
diff --git a/libcli/auth/netlogon_creds_cli.c b/libcli/auth/netlogon_creds_cli.c
index 407cb471cbc..12cb3149ff6 100644
--- a/libcli/auth/netlogon_creds_cli.c
+++ b/libcli/auth/netlogon_creds_cli.c
@@ -1177,8 +1177,7 @@ static void 
netlogon_creds_cli_auth_challenge_start(struct tevent_req *req)
 
        TALLOC_FREE(state->creds);
 
-       generate_random_buffer(state->client_challenge.data,
-                              sizeof(state->client_challenge.data));
+       netlogon_creds_random_challenge(&state->client_challenge);
 
        subreq = dcerpc_netr_ServerReqChallenge_send(state, state->ev,
                                                state->binding_handle,
diff --git a/libcli/auth/proto.h b/libcli/auth/proto.h
index 88f4a7c6c50..a62668f088f 100644
--- a/libcli/auth/proto.h
+++ b/libcli/auth/proto.h
@@ -13,6 +13,9 @@
 
 /* The following definitions come from 
/home/jeremy/src/samba/git/master/source3/../source4/../libcli/auth/credentials.c
  */
 
+bool netlogon_creds_is_random_challenge(const struct netr_Credential 
*challenge);
+void netlogon_creds_random_challenge(struct netr_Credential *challenge);
+
 NTSTATUS netlogon_creds_des_encrypt_LMKey(struct 
netlogon_creds_CredentialState *creds,
                                          struct netr_LMSessionKey *key);
 NTSTATUS netlogon_creds_des_decrypt_LMKey(struct 
netlogon_creds_CredentialState *creds,
diff --git a/libcli/auth/wscript_build b/libcli/auth/wscript_build
index 41937623630..2a6a7468e45 100644
--- a/libcli/auth/wscript_build
+++ b/libcli/auth/wscript_build
@@ -18,7 +18,7 @@ bld.SAMBA_SUBSYSTEM('NTLM_CHECK',
 
 bld.SAMBA_SUBSYSTEM('LIBCLI_AUTH',
        source='credentials.c session.c smbencrypt.c smbdes.c',
-       public_deps='MSRPC_PARSE gnutls GNUTLS_HELPERS',
+       public_deps='MSRPC_PARSE gnutls GNUTLS_HELPERS util_str_escape',
        public_headers='credentials.h:domain_credentials.h'
        )
 
diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c 
b/source3/rpc_server/netlogon/srv_netlog_nt.c
index 2a2e2d0ac6e..c217fee9c43 100644
--- a/source3/rpc_server/netlogon/srv_netlog_nt.c
+++ b/source3/rpc_server/netlogon/srv_netlog_nt.c
@@ -48,6 +48,7 @@
 #include "../lib/tsocket/tsocket.h"
 #include "lib/param/param.h"
 #include "libsmb/dsgetdcname.h"
+#include "lib/util/util_str_escape.h"
 
 extern userdom_struct current_user_info;
 
@@ -841,8 +842,7 @@ NTSTATUS _netr_ServerReqChallenge(struct pipes_struct *p,
 
        pipe_state->client_challenge = *r->in.credentials;
 
-       generate_random_buffer(pipe_state->server_challenge.data,
-                              sizeof(pipe_state->server_challenge.data));
+       netlogon_creds_random_challenge(&pipe_state->server_challenge);
 
        *r->out.return_credentials = pipe_state->server_challenge;
 
@@ -1074,20 +1074,25 @@ static NTSTATUS netr_creds_server_step_check(struct 
pipes_struct *p,
 {
        NTSTATUS status;
        bool schannel_global_required = (lp_server_schannel() == true) ? 
true:false;
+       bool schannel_required = schannel_global_required;
+       const char *explicit_opt = NULL;
        struct loadparm_context *lp_ctx;
+       struct netlogon_creds_CredentialState *creds = NULL;
+       enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
+       uint16_t opnum = p->opnum;
+       const char *opname = "<unknown>";
+       static bool warned_global_once = false;
 
        if (creds_out != NULL) {
                *creds_out = NULL;
        }
 
-       if (schannel_global_required) {
-               if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
-                       DBG_ERR("[%s] is not using schannel\n",
-                               computer_name);
-                       return NT_STATUS_ACCESS_DENIED;
-               }
+       if (opnum < ndr_table_netlogon.num_calls) {
+               opname = ndr_table_netlogon.calls[opnum].name;
        }
 
+       auth_type = p->auth.auth_type;
+
        lp_ctx = loadparm_init_s3(mem_ctx, loadparm_s3_helpers());
        if (lp_ctx == NULL) {
                DEBUG(0, ("loadparm_init_s3 failed\n"));
@@ -1096,9 +1101,97 @@ static NTSTATUS netr_creds_server_step_check(struct 
pipes_struct *p,
 
        status = schannel_check_creds_state(mem_ctx, lp_ctx,
                                            computer_name, 
received_authenticator,
-                                           return_authenticator, creds_out);
+                                           return_authenticator, &creds);
        talloc_unlink(mem_ctx, lp_ctx);
-       return status;
+
+       if (!NT_STATUS_IS_OK(status)) {
+               ZERO_STRUCTP(return_authenticator);
+               return status;
+       }
+
+       /*
+        * We don't use lp_parm_bool(), as we
+        * need the explicit_opt pointer in order to
+        * adjust the debug messages.
+        */
+
+       explicit_opt = lp_parm_const_string(GLOBAL_SECTION_SNUM,
+                                           "server require schannel",
+                                           creds->account_name,
+                                           NULL);
+       if (explicit_opt != NULL) {
+               schannel_required = lp_bool(explicit_opt);
+       }
+
+       if (schannel_required) {
+               if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
+                       *creds_out = creds;
+                       return NT_STATUS_OK;
+               }
+
+               DBG_ERR("CVE-2020-1472(ZeroLogon): "
+                       "%s request (opnum[%u]) without schannel from "
+                       "client_account[%s] client_computer_name[%s]\n",
+                       opname, opnum,
+                       log_escape(mem_ctx, creds->account_name),
+                       log_escape(mem_ctx, creds->computer_name));
+               DBG_ERR("CVE-2020-1472(ZeroLogon): Check if option "
+                       "'server require schannel:%s = no' is needed! \n",
+                       log_escape(mem_ctx, creds->account_name));
+               TALLOC_FREE(creds);
+               ZERO_STRUCTP(return_authenticator);
+               return NT_STATUS_ACCESS_DENIED;
+       }
+
+       if (!schannel_global_required && !warned_global_once) {
+               /*
+                * We want admins to notice their misconfiguration!
+                */
+               DBG_ERR("CVE-2020-1472(ZeroLogon): "
+                       "Please configure 'server schannel = yes', "
+                       "See 
https://bugzilla.samba.org/show_bug.cgi?id=14497\n";);
+               warned_global_once = true;
+       }
+
+       if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
+               DBG_ERR("CVE-2020-1472(ZeroLogon): "
+                       "%s request (opnum[%u]) WITH schannel from "
+                       "client_account[%s] client_computer_name[%s]\n",
+                       opname, opnum,
+                       log_escape(mem_ctx, creds->account_name),
+                       log_escape(mem_ctx, creds->computer_name));
+               DBG_ERR("CVE-2020-1472(ZeroLogon): "
+                       "Option 'server require schannel:%s = no' not 
needed!?\n",
+                       log_escape(mem_ctx, creds->account_name));
+
+               *creds_out = creds;
+               return NT_STATUS_OK;
+       }
+
+       if (explicit_opt != NULL) {
+               DBG_INFO("CVE-2020-1472(ZeroLogon): "
+                        "%s request (opnum[%u]) without schannel from "
+                        "client_account[%s] client_computer_name[%s]\n",
+                        opname, opnum,
+                        log_escape(mem_ctx, creds->account_name),
+                        log_escape(mem_ctx, creds->computer_name));
+               DBG_INFO("CVE-2020-1472(ZeroLogon): "
+                        "Option 'server require schannel:%s = no' still 
needed!\n",
+                        log_escape(mem_ctx, creds->account_name));
+       } else {
+               DBG_ERR("CVE-2020-1472(ZeroLogon): "
+                       "%s request (opnum[%u]) without schannel from "
+                       "client_account[%s] client_computer_name[%s]\n",
+                       opname, opnum,
+                       log_escape(mem_ctx, creds->account_name),
+                       log_escape(mem_ctx, creds->computer_name));
+               DBG_ERR("CVE-2020-1472(ZeroLogon): Check if option "
+                       "'server require schannel:%s = no' might be needed!\n",
+                       log_escape(mem_ctx, creds->account_name));
+       }
+
+       *creds_out = creds;
+       return NT_STATUS_OK;
 }
 
 
@@ -1345,9 +1438,14 @@ NTSTATUS _netr_ServerPasswordSet2(struct pipes_struct *p,
 {
        NTSTATUS status;
        struct netlogon_creds_CredentialState *creds = NULL;
-       DATA_BLOB plaintext;
+       DATA_BLOB plaintext = data_blob_null;
+       DATA_BLOB new_password = data_blob_null;
+       size_t confounder_len;
+       DATA_BLOB dec_blob = data_blob_null;
+       DATA_BLOB enc_blob = data_blob_null;
        struct samr_CryptPassword password_buf;
        struct _samr_Credentials_t cr = { CRED_TYPE_PLAIN_TEXT, {0}};
+       bool ok;
 
        become_root();
        status = netr_creds_server_step_check(p, p->mem_ctx,
@@ -1387,21 +1485,103 @@ NTSTATUS _netr_ServerPasswordSet2(struct pipes_struct 
*p,
                                                      516);
        }
        if (!NT_STATUS_IS_OK(status)) {
+               TALLOC_FREE(creds);
                return status;
        }
 
-       if (!decode_pw_buffer(p->mem_ctx,
-                             password_buf.data,
-                             (char**) &plaintext.data,
-                             &plaintext.length,
-                             CH_UTF16)) {
+       if (!extract_pw_from_buffer(p->mem_ctx, password_buf.data, 
&new_password)) {
                DEBUG(2,("_netr_ServerPasswordSet2: unable to extract password "
                         "from a buffer. Rejecting auth request as a wrong 
password\n"));
                TALLOC_FREE(creds);
                return NT_STATUS_WRONG_PASSWORD;
        }
 
+       /*
+        * Make sure the length field was encrypted,
+        * otherwise we are under attack.
+        */
+       if (new_password.length == r->in.new_password->length) {
+               DBG_WARNING("Length[%zu] field not encrypted\n",
+                       new_password.length);
+               TALLOC_FREE(creds);
+               return NT_STATUS_WRONG_PASSWORD;
+       }
+
+       /*
+        * We don't allow empty passwords for machine accounts.
+        */
+       if (new_password.length < 2) {
+               DBG_WARNING("Empty password Length[%zu]\n",
+                       new_password.length);
+               TALLOC_FREE(creds);
+               return NT_STATUS_WRONG_PASSWORD;
+       }
+
+       /*
+        * Make sure the confounder part of CryptPassword
+        * buffer was encrypted, otherwise we are under attack.
+        */
+       confounder_len = 512 - new_password.length;
+       enc_blob = data_blob_const(r->in.new_password->data, confounder_len);
+       dec_blob = data_blob_const(password_buf.data, confounder_len);
+       if (data_blob_cmp(&dec_blob, &enc_blob) == 0) {
+               DBG_WARNING("Confounder buffer not encrypted Length[%zu]\n",
+                           confounder_len);
+               TALLOC_FREE(creds);
+               return NT_STATUS_WRONG_PASSWORD;
+       }
+
+       /*
+        * Check that the password part was actually encrypted,
+        * otherwise we are under attack.
+        */
+       enc_blob = data_blob_const(r->in.new_password->data + confounder_len,
+                                  new_password.length);
+       dec_blob = data_blob_const(password_buf.data + confounder_len,
+                                  new_password.length);
+       if (data_blob_cmp(&dec_blob, &enc_blob) == 0) {
+               DBG_WARNING("Password buffer not encrypted Length[%zu]\n",
+                           new_password.length);
+               TALLOC_FREE(creds);
+               return NT_STATUS_WRONG_PASSWORD;
+       }
+
+       /*
+        * don't allow zero buffers
+        */
+       if (all_zero(new_password.data, new_password.length)) {
+               DBG_WARNING("Password zero buffer Length[%zu]\n",
+                           new_password.length);
+               TALLOC_FREE(creds);
+               return NT_STATUS_WRONG_PASSWORD;
+       }
+
+       /* Convert from UTF16 -> plaintext. */
+       ok = convert_string_talloc(p->mem_ctx,
+                               CH_UTF16,
+                               CH_UNIX,
+                               new_password.data,
+                               new_password.length,
+                               (void *)&plaintext.data,
+                               &plaintext.length);
+       if (!ok) {
+               DBG_WARNING("unable to extract password from a buffer. "
+                           "Rejecting auth request as a wrong password\n");
+               TALLOC_FREE(creds);
+               return NT_STATUS_WRONG_PASSWORD;
+       }
+
+       /*
+        * We don't allow empty passwords for machine accounts.
+        */
+
        cr.creds.password = (const char*) plaintext.data;
+       if (strlen(cr.creds.password) == 0) {
+               DBG_WARNING("Empty plaintext password\n");
+               TALLOC_FREE(creds);
+               return NT_STATUS_WRONG_PASSWORD;
+       }
+
        status = netr_set_machine_account_password(p->mem_ctx,
                                                   p->session_info,
                                                   p->msg_ctx,
diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c 
b/source4/rpc_server/netlogon/dcerpc_netlogon.c
index 0351e2d286c..0c5ed1f0665 100644
--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
@@ -92,8 +92,7 @@ static NTSTATUS dcesrv_netr_ServerReqChallenge(struct 
dcesrv_call_state *dce_cal
 
        pipe_state->client_challenge = *r->in.credentials;
 
-       generate_random_buffer(pipe_state->server_challenge.data,
-                              sizeof(pipe_state->server_challenge.data));
+       netlogon_creds_random_challenge(&pipe_state->server_challenge);
 
        *r->out.return_credentials = pipe_state->server_challenge;
 
@@ -627,26 +626,114 @@ static NTSTATUS 
dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc
        NTSTATUS nt_status;
        int schannel = lpcfg_server_schannel(dce_call->conn->dce_ctx->lp_ctx);
        bool schannel_global_required = (schannel == true);
+       bool schannel_required = schannel_global_required;


-- 
Samba Shared Repository

Reply via email to