auth: Allow NTLMv1 if MSV1_0_ALLOW_MSVCHAPV2 is given and re-factor 'ntlm auth ='
authorAndrew Bartlett <abartlet@samba.org>
Mon, 3 Jul 2017 00:11:51 +0000 (12:11 +1200)
committerAndrew Bartlett <abartlet@samba.org>
Tue, 4 Jul 2017 04:57:20 +0000 (06:57 +0200)
The ntlm auth parameter is expanded to more clearly describe the
role of each option, and to allow the new mode that permits MSCHAPv2
(as declared by the client over the NETLOGON protocol) while
still banning NTLMv1.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=12252
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Based on a patch by Mantas Mikulėnas <mantas@utenos-kolegija.lt>:

Commit 0b500d413c5b ("Added MSV1_0_ALLOW_MSVCHAPV2 flag to ntlm_auth")
added the --allow-mschapv2 option, but didn't implement checking for it
server-side. This implements such checking.

Additionally, Samba now disables NTLMv1 authentication by default for
security reasons. To avoid having to re-enable it globally, 'ntlm auth'
becomes an enum and a new setting is added to allow only MSCHAPv2.

Signed-off-by: Mantas Mikulėnas <mantas@utenos-kolegija.lt>
Reviewed-by: Garming Sam <garming@catalyst.net.nz>
docs-xml/smbdotconf/security/ntlmauth.xml
lib/param/loadparm.c
lib/param/param_table.c
libcli/auth/ntlm_check.c
libcli/auth/ntlm_check.h
source3/param/loadparm.c

index 884ee9dbf1a0b73c03a91448f168e1b0a01e3a2e..891da2807602d2c5c979d690a58699930a2c8e21 100644 (file)
@@ -1,6 +1,7 @@
 <samba:parameter name="ntlm auth"
                  context="G"
-                 type="boolean"
+                 type="enum"
+                 enumlist="enum_ntlm_auth"
                  xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
 <description>
     <para>This parameter determines whether or not <citerefentry><refentrytitle>smbd</refentrytitle>
     If disabled, either the lanman password hash or an NTLMv2 response
     will need to be sent by the client.</para>
 
-    <para>If this option, and <command moreinfo="none">lanman
-    auth</command> are both disabled, then only NTLMv2 logins will be
-    permited.  Not all clients support NTLMv2, and most will require
-    special configuration to use it.</para>
+    <para>By default with <command moreinfo="none">lanman
+    auth</command> set to <constant>no</constant> and
+    <command moreinfo="none">ntlm auth</command> set to
+    <constant>ntlmv2-only</constant> only NTLMv2 logins will be
+    permited.  Most clients support NTLMv2 by default, but some older
+    clients will require special configuration to use it.</para>
 
     <para>The primary user of NTLMv1 is MSCHAPv2 for VPNs and 802.1x.</para>
 
-    <para>The default changed from "yes" to "no" with Samba 4.5.</para>
+    <para>The available settings are:</para>
+
+    <itemizedlist>
+        <listitem>
+          <para><constant>ntlmv1-permitted</constant>
+         (alias <constant>yes</constant>) - Allow NTLMv1 and above for all clients.</para>
+
+        </listitem>
+
+        <listitem>
+          <para><constant>ntlmv2-only</constant>
+         (alias <constant>no</constant>) - Do not allow NTLMv1 to be used,
+         but permit NTLMv2.</para>
+        </listitem>
+
+        <listitem>
+            <para><constant>mschapv2-and-ntlmv2-only</constant> - Only
+            allow NTLMv1 when the client promises that it is providing
+            MSCHAPv2 authentication (such as the <command
+            moreinfo="none">ntlm_auth</command> tool).</para>
+        </listitem>
+
+    </itemizedlist>
+
+    <para>The default changed from <constant>yes</constant> to
+    <constant>no</constant> with Samba 4.5.  The default chagned again
+    to <constant>ntlmv2-only</constant> with Samba 4.7, however the
+    behaviour is unchanged.</para>
 </description>
 
 <related>lanman auth</related>
 <related>raw NTLMv2 auth</related>
-<value type="default">no</value>
+<value type="default">ntlmv2-only</value>
 </samba:parameter>
index 3ceea50b279a22e34376ffc140c9916518533896..9c93277c35e58a868a4b198c5b2a8ea7a21ae25f 100644 (file)
@@ -70,6 +70,7 @@
 #include "librpc/gen_ndr/nbt.h"
 #include "libds/common/roles.h"
 #include "lib/util/samba_util.h"
+#include "libcli/auth/ntlm_check.h"
 
 #ifdef HAVE_HTTPCONNECTENCRYPT
 #include <cups/http.h>
@@ -2709,7 +2710,7 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx)
        lpcfg_do_global_parameter(lp_ctx, "ClientLanManAuth", "False");
        lpcfg_do_global_parameter(lp_ctx, "ClientNTLMv2Auth", "True");
        lpcfg_do_global_parameter(lp_ctx, "LanmanAuth", "False");
-       lpcfg_do_global_parameter(lp_ctx, "NTLMAuth", "False");
+       lpcfg_do_global_parameter(lp_ctx, "NTLMAuth", "ntlmv2-only");
        lpcfg_do_global_parameter(lp_ctx, "RawNTLMv2Auth", "False");
        lpcfg_do_global_parameter(lp_ctx, "client use spnego principal", "False");
 
index 21cac107647b9efeb6136f87fa94c6f591d90002..4e9910dd083e49a520d7c22b612b6ce21e42f4af 100644 (file)
@@ -31,6 +31,7 @@
 #include "lib/param/param.h"
 #include "lib/param/loadparm.h"
 #include "lib/param/param_global.h"
+#include "libcli/auth/ntlm_check.h"
 #include "libcli/smb/smb_constants.h"
 #include "libds/common/roles.h"
 #include "source4/lib/tls/tls.h"
@@ -330,6 +331,19 @@ static const struct enum_list enum_mangled_names[] = {
        {-1, NULL}
 };
 
+static const struct enum_list enum_ntlm_auth[] = {
+       {NTLM_AUTH_NTLMV2_ONLY, "ntlmv2-only"},
+       {NTLM_AUTH_NTLMV2_ONLY, "no"},
+       {NTLM_AUTH_NTLMV2_ONLY, "false"},
+       {NTLM_AUTH_NTLMV2_ONLY, "0"},
+       {NTLM_AUTH_ON, "ntlmv1-permitted"},
+       {NTLM_AUTH_ON, "yes"},
+       {NTLM_AUTH_ON, "true"},
+       {NTLM_AUTH_ON, "1"},
+       {NTLM_AUTH_MSCHAPv2_NTLMV2_ONLY, "mschapv2-and-ntlmv2-only"},
+       {-1, NULL}
+};
+
 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
  *
  * NOTE: Handling of duplicated (synonym) parameters:
index d7fba34cdba6ad934f591b6d9510528491bf7739..8e8d100075a60456535a4622596d8c3c83e4de0f 100644 (file)
@@ -280,7 +280,7 @@ NTSTATUS hash_password_check(TALLOC_CTX *mem_ctx,
 
 NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx,
                             bool lanman_auth,
-                            bool ntlm_auth,
+                            enum ntlm_auth_level ntlm_auth,
                             uint32_t logon_parameters,
                             const DATA_BLOB *challenge,
                             const DATA_BLOB *lm_response,
@@ -397,7 +397,8 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx,
                        DEBUG(3,("ntlm_password_check: NTLMv2 password check failed\n"));
                }
        } else if (nt_response->length == 24 && stored_nt) {
-               if (ntlm_auth) {                
+               if (ntlm_auth == NTLM_AUTH_ON
+                   || (ntlm_auth == NTLM_AUTH_MSCHAPv2_NTLMV2_ONLY && (logon_parameters & MSV1_0_ALLOW_MSVCHAPV2))) {
                        /* We have the NT MD4 hash challenge available - see if we can
                           use it (ie. does it exist in the smbpasswd file).
                        */
index df11f7d7a2659c62be1fbe42f2b1dc14c2522d06..f1dc54a48474887a2673be9ad173a2b1ec708e01 100644 (file)
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
+#ifndef __LIBCLI_AUTH_NTLM_CHECK_H__
+#define __LIBCLI_AUTH_NTLM_CHECK_H__
 
+/* mangled names options */
+enum ntlm_auth_level {NTLM_AUTH_ON,
+                     NTLM_AUTH_NTLMV2_ONLY,
+                     NTLM_AUTH_MSCHAPv2_NTLMV2_ONLY};
+
+struct samr_Password;
 
 /**
  * Compare password hashes against those from the SAM
@@ -62,7 +70,7 @@ NTSTATUS hash_password_check(TALLOC_CTX *mem_ctx,
 
 NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx,
                                 bool lanman_auth,
-                                bool ntlm_auth,
+                                enum ntlm_auth_level ntlm_auth,
                             uint32_t logon_parameters,
                             const DATA_BLOB *challenge,
                             const DATA_BLOB *lm_response,
@@ -74,3 +82,5 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx,
                             const struct samr_Password *stored_nt, 
                             DATA_BLOB *user_sess_key, 
                             DATA_BLOB *lm_sess_key);
+
+#endif /* __LIBCLI_AUTH_NTLM_CHECK_H__ */
index 8f0cf5e6e0311b47af6b66103e174423994f6a6c..ba3763e97d136e9ed5c7ab743abbb8a8d5c6add3 100644 (file)
@@ -71,6 +71,7 @@
 #include "../lib/util/bitmap.h"
 #include "librpc/gen_ndr/nbt.h"
 #include "source4/lib/tls/tls.h"
+#include "libcli/auth/ntlm_check.h"
 
 #ifdef HAVE_SYS_SYSCTL_H
 #include <sys/sysctl.h>
@@ -693,7 +694,7 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
        Globals.client_lanman_auth = false;     /* Do NOT use the LanMan hash if it is available */
        Globals.client_plaintext_auth = false;  /* Do NOT use a plaintext password even if is requested by the server */
        Globals.lanman_auth = false;    /* Do NOT use the LanMan hash, even if it is supplied */
-       Globals.ntlm_auth = false;      /* Do NOT use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
+       Globals.ntlm_auth = NTLM_AUTH_NTLMV2_ONLY;      /* Do NOT use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
        Globals.raw_ntlmv2_auth = false; /* Reject NTLMv2 without NTLMSSP */
        Globals.client_ntlmv2_auth = true; /* Client should always use use NTLMv2, as we can't tell that the server supports it, but most modern servers do */
        /* Note, that we will also use NTLM2 session security (which is different), if it is available */