cf659d
From 34a9663509fe12778cca621e765b027e26ed1e34 Mon Sep 17 00:00:00 2001
cf659d
From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
cf659d
Date: Thu, 22 Feb 2018 11:54:45 +1300
cf659d
Subject: [PATCH 1/6] selftest/tests.py: remove always-needed, never-set
cf659d
 with_cmocka flag
cf659d
cf659d
We have cmocka in third_party, so we are never without it.
cf659d
cf659d
Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
cf659d
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
cf659d
cf659d
(Backported from commit 33ef0e57a4f08eae5ea06f482374fbc0a1014de6
cf659d
by Andrew Bartlett)
cf659d
---
cf659d
 selftest/tests.py | 18 ++++++++----------
cf659d
 1 file changed, 8 insertions(+), 10 deletions(-)
cf659d
cf659d
diff --git a/selftest/tests.py b/selftest/tests.py
cf659d
index 126e1184230..3f5097b680c 100644
cf659d
--- a/selftest/tests.py
cf659d
+++ b/selftest/tests.py
cf659d
@@ -38,7 +38,6 @@ finally:
cf659d
     f.close()
cf659d
 
cf659d
 have_man_pages_support = ("XSLTPROC_MANPAGES" in config_hash)
cf659d
-with_cmocka = ("HAVE_CMOCKA" in config_hash)
cf659d
 with_pam = ("WITH_PAM" in config_hash)
cf659d
 pam_wrapper_so_path=config_hash["LIBPAM_WRAPPER_SO_PATH"]
cf659d
 
cf659d
@@ -168,13 +167,12 @@ if with_pam:
cf659d
                    valgrindify(python), pam_wrapper_so_path,
cf659d
                    "$DOMAIN", "alice", "Secret007"])
cf659d
 
cf659d
-if with_cmocka:
cf659d
-    plantestsuite("samba.unittests.krb5samba", "none",
cf659d
-                  [os.path.join(bindir(), "default/testsuite/unittests/test_krb5samba")])
cf659d
-    plantestsuite("samba.unittests.sambafs_srv_pipe", "none",
cf659d
-                  [os.path.join(bindir(), "default/testsuite/unittests/test_sambafs_srv_pipe")])
cf659d
-    plantestsuite("samba.unittests.lib_util_modules", "none",
cf659d
-                  [os.path.join(bindir(), "default/testsuite/unittests/test_lib_util_modules")])
cf659d
+plantestsuite("samba.unittests.krb5samba", "none",
cf659d
+              [os.path.join(bindir(), "default/testsuite/unittests/test_krb5samba")])
cf659d
+plantestsuite("samba.unittests.sambafs_srv_pipe", "none",
cf659d
+              [os.path.join(bindir(), "default/testsuite/unittests/test_sambafs_srv_pipe")])
cf659d
+plantestsuite("samba.unittests.lib_util_modules", "none",
cf659d
+              [os.path.join(bindir(), "default/testsuite/unittests/test_lib_util_modules")])
cf659d
 
cf659d
-    plantestsuite("samba.unittests.smb1cli_session", "none",
cf659d
-                  [os.path.join(bindir(), "default/libcli/smb/test_smb1cli_session")])
cf659d
+plantestsuite("samba.unittests.smb1cli_session", "none",
cf659d
+              [os.path.join(bindir(), "default/libcli/smb/test_smb1cli_session")])
cf659d
-- 
cf659d
2.14.4
cf659d
cf659d
cf659d
From e99322edcf4c39614d596fd1be636fd8dd610abc Mon Sep 17 00:00:00 2001
cf659d
From: Andrew Bartlett <abartlet@samba.org>
cf659d
Date: Fri, 27 Jul 2018 08:44:24 +1200
cf659d
Subject: [PATCH 2/6] CVE-2018-1139 libcli/auth: Add initial tests for
cf659d
 ntlm_password_check()
cf659d
cf659d
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13360
cf659d
cf659d
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
cf659d
---
cf659d
 libcli/auth/tests/ntlm_check.c | 413 +++++++++++++++++++++++++++++++++++++++++
cf659d
 libcli/auth/wscript_build      |  13 ++
cf659d
 selftest/knownfail.d/ntlm      |   2 +
cf659d
 selftest/tests.py              |   2 +
cf659d
 4 files changed, 430 insertions(+)
cf659d
 create mode 100644 libcli/auth/tests/ntlm_check.c
cf659d
 create mode 100644 selftest/knownfail.d/ntlm
cf659d
cf659d
diff --git a/libcli/auth/tests/ntlm_check.c b/libcli/auth/tests/ntlm_check.c
cf659d
new file mode 100644
cf659d
index 00000000000..e87a0a276d4
cf659d
--- /dev/null
cf659d
+++ b/libcli/auth/tests/ntlm_check.c
cf659d
@@ -0,0 +1,413 @@
cf659d
+/*
cf659d
+ * Unit tests for the ntlm_check password hash check library.
cf659d
+ *
cf659d
+ *  Copyright (C) Andrew Bartlett <abartlet@samba.org> 2018
cf659d
+ *
cf659d
+ * This program is free software; you can redistribute it and/or modify
cf659d
+ * it under the terms of the GNU General Public License as published by
cf659d
+ * the Free Software Foundation; either version 3 of the License, or
cf659d
+ * (at your option) any later version.
cf659d
+ *
cf659d
+ * This program is distributed in the hope that it will be useful,
cf659d
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
cf659d
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
cf659d
+ * GNU General Public License for more details.
cf659d
+ *
cf659d
+ * You should have received a copy of the GNU General Public License
cf659d
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
cf659d
+ *
cf659d
+ */
cf659d
+
cf659d
+/*
cf659d
+ * from cmocka.c:
cf659d
+ * These headers or their equivalents should be included prior to
cf659d
+ * including
cf659d
+ * this header file.
cf659d
+ *
cf659d
+ * #include <stdarg.h>
cf659d
+ * #include <stddef.h>
cf659d
+ * #include <setjmp.h>
cf659d
+ *
cf659d
+ * This allows test applications to use custom definitions of C standard
cf659d
+ * library functions and types.
cf659d
+ *
cf659d
+ */
cf659d
+
cf659d
+/*
cf659d
+ * Note that the messaging routines (audit_message_send and get_event_server)
cf659d
+ * are not tested by these unit tests.  Currently they are for integration
cf659d
+ * test support, and as such are exercised by the integration tests.
cf659d
+ */
cf659d
+#include <stdarg.h>
cf659d
+#include <stddef.h>
cf659d
+#include <setjmp.h>
cf659d
+#include <cmocka.h>
cf659d
+
cf659d
+#include "includes.h"
cf659d
+#include "../lib/crypto/crypto.h"
cf659d
+#include "librpc/gen_ndr/netlogon.h"
cf659d
+#include "libcli/auth/libcli_auth.h"
cf659d
+#include "auth/credentials/credentials.h"
cf659d
+
cf659d
+struct ntlm_state {
cf659d
+	const char *username;
cf659d
+	const char *domain;
cf659d
+	DATA_BLOB challenge;
cf659d
+	DATA_BLOB ntlm;
cf659d
+	DATA_BLOB lm;
cf659d
+	DATA_BLOB ntlm_key;
cf659d
+	DATA_BLOB lm_key;
cf659d
+	const struct samr_Password *nt_hash;
cf659d
+};
cf659d
+
cf659d
+static int test_ntlm_setup_with_options(void **state,
cf659d
+					int flags, bool upn)
cf659d
+{
cf659d
+	NTSTATUS status;
cf659d
+	DATA_BLOB challenge = {
cf659d
+		.data = discard_const_p(uint8_t, "I am a teapot"),
cf659d
+		.length = 8
cf659d
+	};
cf659d
+	struct ntlm_state *ntlm_state = talloc(NULL, struct ntlm_state);
cf659d
+	DATA_BLOB target_info = NTLMv2_generate_names_blob(ntlm_state,
cf659d
+							   NULL,
cf659d
+							   "serverdom");
cf659d
+	struct cli_credentials *creds = cli_credentials_init(ntlm_state);
cf659d
+	cli_credentials_set_username(creds,
cf659d
+				     "testuser",
cf659d
+				     CRED_SPECIFIED);
cf659d
+	cli_credentials_set_domain(creds,
cf659d
+				   "testdom",
cf659d
+				   CRED_SPECIFIED);
cf659d
+	cli_credentials_set_workstation(creds,
cf659d
+					"testwksta",
cf659d
+					CRED_SPECIFIED);
cf659d
+	cli_credentials_set_password(creds,
cf659d
+				     "testpass",
cf659d
+				     CRED_SPECIFIED);
cf659d
+
cf659d
+	if (upn) {
cf659d
+		cli_credentials_set_principal(creds,
cf659d
+					      "testuser@samba.org",
cf659d
+					      CRED_SPECIFIED);
cf659d
+	}
cf659d
+
cf659d
+	cli_credentials_get_ntlm_username_domain(creds,
cf659d
+						 ntlm_state,
cf659d
+						 &ntlm_state->username,
cf659d
+						 &ntlm_state->domain);
cf659d
+
cf659d
+	status = cli_credentials_get_ntlm_response(creds,
cf659d
+						   ntlm_state,
cf659d
+						   &flags,
cf659d
+						   challenge,
cf659d
+						   NULL,
cf659d
+						   target_info,
cf659d
+						   &ntlm_state->lm,
cf659d
+						   &ntlm_state->ntlm,
cf659d
+						   &ntlm_state->lm_key,
cf659d
+						   &ntlm_state->ntlm_key);
cf659d
+	ntlm_state->challenge = challenge;
cf659d
+
cf659d
+	ntlm_state->nt_hash = cli_credentials_get_nt_hash(creds,
cf659d
+							  ntlm_state);
cf659d
+
cf659d
+	if (!NT_STATUS_IS_OK(status)) {
cf659d
+		return -1;
cf659d
+	}
cf659d
+
cf659d
+	*state = ntlm_state;
cf659d
+	return 0;
cf659d
+}
cf659d
+
cf659d
+static int test_ntlm_setup(void **state) {
cf659d
+	return test_ntlm_setup_with_options(state, 0, false);
cf659d
+}
cf659d
+
cf659d
+static int test_ntlm_and_lm_setup(void **state) {
cf659d
+	return test_ntlm_setup_with_options(state,
cf659d
+					    CLI_CRED_LANMAN_AUTH,
cf659d
+					    false);
cf659d
+}
cf659d
+
cf659d
+static int test_ntlm2_setup(void **state) {
cf659d
+	return test_ntlm_setup_with_options(state,
cf659d
+					    CLI_CRED_NTLM2,
cf659d
+					    false);
cf659d
+}
cf659d
+
cf659d
+static int test_ntlmv2_setup(void **state) {
cf659d
+	return test_ntlm_setup_with_options(state,
cf659d
+					    CLI_CRED_NTLMv2_AUTH,
cf659d
+					    false);
cf659d
+}
cf659d
+
cf659d
+static int test_ntlm_teardown(void **state)
cf659d
+{
cf659d
+	struct ntlm_state *ntlm_state
cf659d
+		= talloc_get_type_abort(*state,
cf659d
+					struct ntlm_state);
cf659d
+	TALLOC_FREE(ntlm_state);
cf659d
+	*state = NULL;
cf659d
+	return 0;
cf659d
+}
cf659d
+
cf659d
+static void test_ntlm_allowed(void **state)
cf659d
+{
cf659d
+	DATA_BLOB user_sess_key, lm_sess_key;
cf659d
+	struct ntlm_state *ntlm_state
cf659d
+		= talloc_get_type_abort(*state,
cf659d
+					struct ntlm_state);
cf659d
+	NTSTATUS status;
cf659d
+	status = ntlm_password_check(ntlm_state,
cf659d
+				     false,
cf659d
+				     NTLM_AUTH_ON,
cf659d
+				     0,
cf659d
+				     &ntlm_state->challenge,
cf659d
+				     &ntlm_state->lm,
cf659d
+				     &ntlm_state->ntlm,
cf659d
+				     ntlm_state->username,
cf659d
+				     ntlm_state->username,
cf659d
+				     ntlm_state->domain,
cf659d
+				     NULL,
cf659d
+				     ntlm_state->nt_hash,
cf659d
+				     &user_sess_key,
cf659d
+				     &lm_sess_key);
cf659d
+
cf659d
+	assert_int_equal(NT_STATUS_V(status), NT_STATUS_V(NT_STATUS_OK));
cf659d
+}
cf659d
+
cf659d
+static void test_ntlm_allowed_lm_supplied(void **state)
cf659d
+{
cf659d
+	return test_ntlm_allowed(state);
cf659d
+}
cf659d
+
cf659d
+static void test_ntlm_disabled(void **state)
cf659d
+{
cf659d
+	DATA_BLOB user_sess_key, lm_sess_key;
cf659d
+	struct ntlm_state *ntlm_state
cf659d
+		= talloc_get_type_abort(*state,
cf659d
+					struct ntlm_state);
cf659d
+	NTSTATUS status;
cf659d
+	status = ntlm_password_check(ntlm_state,
cf659d
+				     false,
cf659d
+				     NTLM_AUTH_DISABLED,
cf659d
+				     0,
cf659d
+				     &ntlm_state->challenge,
cf659d
+				     &ntlm_state->lm,
cf659d
+				     &ntlm_state->ntlm,
cf659d
+				     ntlm_state->username,
cf659d
+				     ntlm_state->username,
cf659d
+				     ntlm_state->domain,
cf659d
+				     NULL,
cf659d
+				     ntlm_state->nt_hash,
cf659d
+				     &user_sess_key,
cf659d
+				     &lm_sess_key);
cf659d
+
cf659d
+	assert_int_equal(NT_STATUS_V(status), NT_STATUS_V(NT_STATUS_NTLM_BLOCKED));
cf659d
+}
cf659d
+
cf659d
+static void test_ntlm2(void **state)
cf659d
+{
cf659d
+	DATA_BLOB user_sess_key, lm_sess_key;
cf659d
+	struct ntlm_state *ntlm_state
cf659d
+		= talloc_get_type_abort(*state,
cf659d
+					struct ntlm_state);
cf659d
+	NTSTATUS status;
cf659d
+	status = ntlm_password_check(ntlm_state,
cf659d
+				     false,
cf659d
+				     NTLM_AUTH_ON,
cf659d
+				     0,
cf659d
+				     &ntlm_state->challenge,
cf659d
+				     &ntlm_state->lm,
cf659d
+				     &ntlm_state->ntlm,
cf659d
+				     ntlm_state->username,
cf659d
+				     ntlm_state->username,
cf659d
+				     ntlm_state->domain,
cf659d
+				     NULL,
cf659d
+				     ntlm_state->nt_hash,
cf659d
+				     &user_sess_key,
cf659d
+				     &lm_sess_key);
cf659d
+
cf659d
+	/*
cf659d
+	 * NTLM2 session security (where the real challenge is the
cf659d
+	 * MD5(challenge, client-challenge) (in the first 8 bytes of
cf659d
+	 * the lm) isn't decoded by ntlm_password_check(), it must
cf659d
+	 * first be converted back into normal NTLM by the NTLMSSP
cf659d
+	 * layer
cf659d
+	 */
cf659d
+	assert_int_equal(NT_STATUS_V(status),
cf659d
+			 NT_STATUS_V(NT_STATUS_WRONG_PASSWORD));
cf659d
+}
cf659d
+
cf659d
+static void test_ntlm_mschapv2_only_allowed(void **state)
cf659d
+{
cf659d
+	DATA_BLOB user_sess_key, lm_sess_key;
cf659d
+	struct ntlm_state *ntlm_state
cf659d
+		= talloc_get_type_abort(*state,
cf659d
+					struct ntlm_state);
cf659d
+	NTSTATUS status;
cf659d
+	status = ntlm_password_check(ntlm_state,
cf659d
+				     false,
cf659d
+				     NTLM_AUTH_MSCHAPv2_NTLMV2_ONLY,
cf659d
+				     MSV1_0_ALLOW_MSVCHAPV2,
cf659d
+				     &ntlm_state->challenge,
cf659d
+				     &ntlm_state->lm,
cf659d
+				     &ntlm_state->ntlm,
cf659d
+				     ntlm_state->username,
cf659d
+				     ntlm_state->username,
cf659d
+				     ntlm_state->domain,
cf659d
+				     NULL,
cf659d
+				     ntlm_state->nt_hash,
cf659d
+				     &user_sess_key,
cf659d
+				     &lm_sess_key);
cf659d
+
cf659d
+	assert_int_equal(NT_STATUS_V(status), NT_STATUS_V(NT_STATUS_OK));
cf659d
+}
cf659d
+
cf659d
+static void test_ntlm_mschapv2_only_denied(void **state)
cf659d
+{
cf659d
+	DATA_BLOB user_sess_key, lm_sess_key;
cf659d
+	struct ntlm_state *ntlm_state
cf659d
+		= talloc_get_type_abort(*state,
cf659d
+					struct ntlm_state);
cf659d
+	NTSTATUS status;
cf659d
+	status = ntlm_password_check(ntlm_state,
cf659d
+				     false,
cf659d
+				     NTLM_AUTH_MSCHAPv2_NTLMV2_ONLY,
cf659d
+				     0,
cf659d
+				     &ntlm_state->challenge,
cf659d
+				     &ntlm_state->lm,
cf659d
+				     &ntlm_state->ntlm,
cf659d
+				     ntlm_state->username,
cf659d
+				     ntlm_state->username,
cf659d
+				     ntlm_state->domain,
cf659d
+				     NULL,
cf659d
+				     ntlm_state->nt_hash,
cf659d
+				     &user_sess_key,
cf659d
+				     &lm_sess_key);
cf659d
+
cf659d
+	assert_int_equal(NT_STATUS_V(status),
cf659d
+			 NT_STATUS_V(NT_STATUS_WRONG_PASSWORD));
cf659d
+}
cf659d
+
cf659d
+static void test_ntlmv2_only_ntlmv2(void **state)
cf659d
+{
cf659d
+	DATA_BLOB user_sess_key, lm_sess_key;
cf659d
+	struct ntlm_state *ntlm_state
cf659d
+		= talloc_get_type_abort(*state,
cf659d
+					struct ntlm_state);
cf659d
+	NTSTATUS status;
cf659d
+	status = ntlm_password_check(ntlm_state,
cf659d
+				     false,
cf659d
+				     NTLM_AUTH_NTLMV2_ONLY,
cf659d
+				     0,
cf659d
+				     &ntlm_state->challenge,
cf659d
+				     &ntlm_state->lm,
cf659d
+				     &ntlm_state->ntlm,
cf659d
+				     ntlm_state->username,
cf659d
+				     ntlm_state->username,
cf659d
+				     ntlm_state->domain,
cf659d
+				     NULL,
cf659d
+				     ntlm_state->nt_hash,
cf659d
+				     &user_sess_key,
cf659d
+				     &lm_sess_key);
cf659d
+
cf659d
+	assert_int_equal(NT_STATUS_V(status), NT_STATUS_V(NT_STATUS_OK));
cf659d
+}
cf659d
+
cf659d
+static void test_ntlmv2_only_ntlm(void **state)
cf659d
+{
cf659d
+	DATA_BLOB user_sess_key, lm_sess_key;
cf659d
+	struct ntlm_state *ntlm_state
cf659d
+		= talloc_get_type_abort(*state,
cf659d
+					struct ntlm_state);
cf659d
+	NTSTATUS status;
cf659d
+	status = ntlm_password_check(ntlm_state,
cf659d
+				     false,
cf659d
+				     NTLM_AUTH_NTLMV2_ONLY,
cf659d
+				     0,
cf659d
+				     &ntlm_state->challenge,
cf659d
+				     &ntlm_state->lm,
cf659d
+				     &ntlm_state->ntlm,
cf659d
+				     ntlm_state->username,
cf659d
+				     ntlm_state->username,
cf659d
+				     ntlm_state->domain,
cf659d
+				     NULL,
cf659d
+				     ntlm_state->nt_hash,
cf659d
+				     &user_sess_key,
cf659d
+				     &lm_sess_key);
cf659d
+
cf659d
+	assert_int_equal(NT_STATUS_V(status),
cf659d
+			 NT_STATUS_V(NT_STATUS_WRONG_PASSWORD));
cf659d
+}
cf659d
+
cf659d
+static void test_ntlmv2_only_ntlm_and_lanman(void **state)
cf659d
+{
cf659d
+	return test_ntlmv2_only_ntlm(state);
cf659d
+}
cf659d
+
cf659d
+static void test_ntlmv2_only_ntlm_once(void **state)
cf659d
+{
cf659d
+	DATA_BLOB user_sess_key, lm_sess_key;
cf659d
+	struct ntlm_state *ntlm_state
cf659d
+		= talloc_get_type_abort(*state,
cf659d
+					struct ntlm_state);
cf659d
+	NTSTATUS status;
cf659d
+	status = ntlm_password_check(ntlm_state,
cf659d
+				     false,
cf659d
+				     NTLM_AUTH_NTLMV2_ONLY,
cf659d
+				     0,
cf659d
+				     &ntlm_state->challenge,
cf659d
+				     &data_blob_null,
cf659d
+				     &ntlm_state->ntlm,
cf659d
+				     ntlm_state->username,
cf659d
+				     ntlm_state->username,
cf659d
+				     ntlm_state->domain,
cf659d
+				     NULL,
cf659d
+				     ntlm_state->nt_hash,
cf659d
+				     &user_sess_key,
cf659d
+				     &lm_sess_key);
cf659d
+
cf659d
+	assert_int_equal(NT_STATUS_V(status),
cf659d
+			 NT_STATUS_V(NT_STATUS_WRONG_PASSWORD));
cf659d
+}
cf659d
+
cf659d
+int main(int argc, const char **argv)
cf659d
+{
cf659d
+	const struct CMUnitTest tests[] = {
cf659d
+		cmocka_unit_test_setup_teardown(test_ntlm_allowed,
cf659d
+						test_ntlm_setup,
cf659d
+						test_ntlm_teardown),
cf659d
+		cmocka_unit_test_setup_teardown(test_ntlm_allowed_lm_supplied,
cf659d
+						test_ntlm_and_lm_setup,
cf659d
+						test_ntlm_teardown),
cf659d
+		cmocka_unit_test_setup_teardown(test_ntlm_disabled,
cf659d
+						test_ntlm_setup,
cf659d
+						test_ntlm_teardown),
cf659d
+		cmocka_unit_test_setup_teardown(test_ntlm2,
cf659d
+						test_ntlm2_setup,
cf659d
+						test_ntlm_teardown),
cf659d
+		cmocka_unit_test_setup_teardown(test_ntlm_mschapv2_only_allowed,
cf659d
+						test_ntlm_setup,
cf659d
+						test_ntlm_teardown),
cf659d
+		cmocka_unit_test_setup_teardown(test_ntlm_mschapv2_only_denied,
cf659d
+						test_ntlm_setup,
cf659d
+						test_ntlm_teardown),
cf659d
+		cmocka_unit_test_setup_teardown(test_ntlmv2_only_ntlm,
cf659d
+						test_ntlm_setup,
cf659d
+						test_ntlm_teardown),
cf659d
+		cmocka_unit_test_setup_teardown(test_ntlmv2_only_ntlm_and_lanman,
cf659d
+						test_ntlm_and_lm_setup,
cf659d
+						test_ntlm_teardown),
cf659d
+		cmocka_unit_test_setup_teardown(test_ntlmv2_only_ntlm_once,
cf659d
+						test_ntlm_setup,
cf659d
+						test_ntlm_teardown),
cf659d
+		cmocka_unit_test_setup_teardown(test_ntlmv2_only_ntlmv2,
cf659d
+						test_ntlmv2_setup,
cf659d
+						test_ntlm_teardown)
cf659d
+	};
cf659d
+
cf659d
+	cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
cf659d
+	return cmocka_run_group_tests(tests, NULL, NULL);
cf659d
+}
cf659d
diff --git a/libcli/auth/wscript_build b/libcli/auth/wscript_build
cf659d
index 475b7d69406..d319d9b879e 100644
cf659d
--- a/libcli/auth/wscript_build
cf659d
+++ b/libcli/auth/wscript_build
cf659d
@@ -41,3 +41,16 @@ bld.SAMBA_SUBSYSTEM('PAM_ERRORS',
cf659d
 bld.SAMBA_SUBSYSTEM('SPNEGO_PARSE',
cf659d
                     source='spnego_parse.c',
cf659d
                     deps='asn1util')
cf659d
+
cf659d
+bld.SAMBA_BINARY(
cf659d
+        'test_ntlm_check',
cf659d
+        source='tests/ntlm_check.c',
cf659d
+        deps='''
cf659d
+             NTLM_CHECK
cf659d
+             CREDENTIALS_NTLM
cf659d
+             samba-credentials
cf659d
+             cmocka
cf659d
+             talloc
cf659d
+        ''',
cf659d
+        install=False
cf659d
+    )
cf659d
diff --git a/selftest/knownfail.d/ntlm b/selftest/knownfail.d/ntlm
cf659d
new file mode 100644
cf659d
index 00000000000..c6e6a3739ba
cf659d
--- /dev/null
cf659d
+++ b/selftest/knownfail.d/ntlm
cf659d
@@ -0,0 +1,2 @@
cf659d
+^samba.unittests.ntlm_check.test_ntlm_mschapv2_only_denied
cf659d
+^samba.unittests.ntlm_check.test_ntlmv2_only_ntlm\(
cf659d
diff --git a/selftest/tests.py b/selftest/tests.py
cf659d
index 3f5097b680c..dc6486c13f8 100644
cf659d
--- a/selftest/tests.py
cf659d
+++ b/selftest/tests.py
cf659d
@@ -176,3 +176,5 @@ plantestsuite("samba.unittests.lib_util_modules", "none",
cf659d
 
cf659d
 plantestsuite("samba.unittests.smb1cli_session", "none",
cf659d
               [os.path.join(bindir(), "default/libcli/smb/test_smb1cli_session")])
cf659d
+plantestsuite("samba.unittests.ntlm_check", "none",
cf659d
+              [os.path.join(bindir(), "default/libcli/auth/test_ntlm_check")])
cf659d
-- 
cf659d
2.14.4
cf659d
cf659d
cf659d
From 7a23af4b344ab3c9e9ba65bba5655f51a485c3b7 Mon Sep 17 00:00:00 2001
cf659d
From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd@samba.org>
cf659d
Date: Wed, 14 Mar 2018 15:36:05 +0100
cf659d
Subject: [PATCH 3/6] CVE-2018-1139 libcli/auth: fix debug messages in
cf659d
 hash_password_check()
cf659d
cf659d
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13360
cf659d
cf659d
CVE-2018-1139: Weak authentication protocol allowed.
cf659d
cf659d
Guenther
cf659d
cf659d
Signed-off-by: Guenther Deschner <gd@samba.org>
cf659d
Reviewed-by: Andreas Schneider <asn@samba.org>
cf659d
---
cf659d
 libcli/auth/ntlm_check.c | 8 ++++----
cf659d
 1 file changed, 4 insertions(+), 4 deletions(-)
cf659d
cf659d
diff --git a/libcli/auth/ntlm_check.c b/libcli/auth/ntlm_check.c
cf659d
index 3b02adc1d48..1c6499bd210 100644
cf659d
--- a/libcli/auth/ntlm_check.c
cf659d
+++ b/libcli/auth/ntlm_check.c
cf659d
@@ -224,7 +224,7 @@ NTSTATUS hash_password_check(TALLOC_CTX *mem_ctx,
cf659d
 			     const struct samr_Password *stored_nt)
cf659d
 {
cf659d
 	if (stored_nt == NULL) {
cf659d
-		DEBUG(3,("ntlm_password_check: NO NT password stored for user %s.\n", 
cf659d
+		DEBUG(3,("hash_password_check: NO NT password stored for user %s.\n",
cf659d
 			 username));
cf659d
 	}
cf659d
 
cf659d
@@ -232,14 +232,14 @@ NTSTATUS hash_password_check(TALLOC_CTX *mem_ctx,
cf659d
 		if (memcmp(client_nt->hash, stored_nt->hash, sizeof(stored_nt->hash)) == 0) {
cf659d
 			return NT_STATUS_OK;
cf659d
 		} else {
cf659d
-			DEBUG(3,("ntlm_password_check: Interactive logon: NT password check failed for user %s\n",
cf659d
+			DEBUG(3,("hash_password_check: Interactive logon: NT password check failed for user %s\n",
cf659d
 				 username));
cf659d
 			return NT_STATUS_WRONG_PASSWORD;
cf659d
 		}
cf659d
 
cf659d
 	} else if (client_lanman && stored_lanman) {
cf659d
 		if (!lanman_auth) {
cf659d
-			DEBUG(3,("ntlm_password_check: Interactive logon: only LANMAN password supplied for user %s, and LM passwords are disabled!\n",
cf659d
+			DEBUG(3,("hash_password_check: Interactive logon: only LANMAN password supplied for user %s, and LM passwords are disabled!\n",
cf659d
 				 username));
cf659d
 			return NT_STATUS_WRONG_PASSWORD;
cf659d
 		}
cf659d
@@ -250,7 +250,7 @@ NTSTATUS hash_password_check(TALLOC_CTX *mem_ctx,
cf659d
 		if (memcmp(client_lanman->hash, stored_lanman->hash, sizeof(stored_lanman->hash)) == 0) {
cf659d
 			return NT_STATUS_OK;
cf659d
 		} else {
cf659d
-			DEBUG(3,("ntlm_password_check: Interactive logon: LANMAN password check failed for user %s\n",
cf659d
+			DEBUG(3,("hash_password_check: Interactive logon: LANMAN password check failed for user %s\n",
cf659d
 				 username));
cf659d
 			return NT_STATUS_WRONG_PASSWORD;
cf659d
 		}
cf659d
-- 
cf659d
2.14.4
cf659d
cf659d
cf659d
From fdb383c02e26305f4f312beae70bc5b8d4997a52 Mon Sep 17 00:00:00 2001
cf659d
From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd@samba.org>
cf659d
Date: Wed, 14 Mar 2018 15:35:01 +0100
cf659d
Subject: [PATCH 4/6] CVE-2018-1139 s3-utils: use enum ntlm_auth_level in
cf659d
 ntlm_password_check().
cf659d
cf659d
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13360
cf659d
cf659d
CVE-2018-1139: Weak authentication protocol allowed.
cf659d
cf659d
Guenther
cf659d
cf659d
Signed-off-by: Guenther Deschner <gd@samba.org>
cf659d
Reviewed-by: Andreas Schneider <asn@samba.org>
cf659d
---
cf659d
 source3/utils/ntlm_auth.c | 6 ++++--
cf659d
 1 file changed, 4 insertions(+), 2 deletions(-)
cf659d
cf659d
diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c
cf659d
index 3f544902a24..8f77680416f 100644
cf659d
--- a/source3/utils/ntlm_auth.c
cf659d
+++ b/source3/utils/ntlm_auth.c
cf659d
@@ -1010,7 +1010,7 @@ static NTSTATUS local_pw_check(struct auth4_context *auth4_context,
cf659d
 	*pauthoritative = 1;
cf659d
 
cf659d
 	nt_status = ntlm_password_check(mem_ctx,
cf659d
-					true, true, 0,
cf659d
+					true, NTLM_AUTH_ON, 0,
cf659d
 					&auth4_context->challenge.data,
cf659d
 					&user_info->password.response.lanman,
cf659d
 					&user_info->password.response.nt,
cf659d
@@ -1719,7 +1719,9 @@ static void manage_ntlm_server_1_request(enum stdio_helper_mode stdio_helper_mod
cf659d
 
cf659d
 				nt_lm_owf_gen (opt_password, nt_pw.hash, lm_pw.hash);
cf659d
 				nt_status = ntlm_password_check(mem_ctx,
cf659d
-								true, true, 0,
cf659d
+								true,
cf659d
+								NTLM_AUTH_ON,
cf659d
+								0,
cf659d
 								&challenge,
cf659d
 								&lm_response,
cf659d
 								&nt_response,
cf659d
-- 
cf659d
2.14.4
cf659d
cf659d
cf659d
From 69662890219c8ff58619b47b24d2a7a4bdb08de8 Mon Sep 17 00:00:00 2001
cf659d
From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd@samba.org>
cf659d
Date: Fri, 16 Mar 2018 17:25:12 +0100
cf659d
Subject: [PATCH 5/6] CVE-2018-1139 selftest: verify whether ntlmv1 can be used
cf659d
 via SMB1 when it is disabled.
cf659d
cf659d
Right now, this test will succeed.
cf659d
cf659d
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13360
cf659d
cf659d
CVE-2018-1139: Weak authentication protocol allowed.
cf659d
cf659d
Guenther
cf659d
cf659d
Signed-off-by: Guenther Deschner <gd@samba.org>
cf659d
Reviewed-by: Andreas Schneider <asn@samba.org>
cf659d
---
cf659d
 source3/selftest/tests.py | 2 +-
cf659d
 1 file changed, 1 insertion(+), 1 deletion(-)
cf659d
cf659d
diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py
cf659d
index 9092c1776c8..034c014e5b8 100755
cf659d
--- a/source3/selftest/tests.py
cf659d
+++ b/source3/selftest/tests.py
cf659d
@@ -187,7 +187,7 @@ for env in ["nt4_dc", "nt4_member", "ad_member", "ad_dc", "ad_dc_ntvfs", "s4memb
cf659d
     plantestsuite("samba3.blackbox.smbclient_machine_auth.plain (%s:local)" % env, "%s:local" % env, [os.path.join(samba3srcdir, "script/tests/test_smbclient_machine_auth.sh"), '$SERVER', smbclient3, configuration])
cf659d
     plantestsuite("samba3.blackbox.smbclient_ntlm.plain (%s)" % env, env, [os.path.join(samba3srcdir, "script/tests/test_smbclient_ntlm.sh"), '$SERVER', '$DC_USERNAME', '$DC_PASSWORD', "never", smbclient3, configuration])
cf659d
 
cf659d
-for options in ["--option=clientntlmv2auth=no", "--option=clientusespnego=no --option=clientntlmv2auth=no", ""]:
cf659d
+for options in ["--option=clientntlmv2auth=no", "--option=clientusespnego=no --option=clientntlmv2auth=no", "--option=clientusespnego=no --option=clientntlmv2auth=no -mNT1", ""]:
cf659d
     for env in ["nt4_member", "ad_member"]:
cf659d
         plantestsuite("samba3.blackbox.smbclient_auth.plain (%s) %s" % (env, options), env, [os.path.join(samba3srcdir, "script/tests/test_smbclient_auth.sh"), '$SERVER', '$SERVER_IP', '$DC_USERNAME', '$DC_PASSWORD', smbclient3, configuration, options])
cf659d
         plantestsuite("samba3.blackbox.smbclient_auth.plain (%s) %s member creds" % (env, options), env, [os.path.join(samba3srcdir, "script/tests/test_smbclient_auth.sh"), '$SERVER', '$SERVER_IP', '$SERVER/$USERNAME', '$PASSWORD', smbclient3, configuration, options])
cf659d
-- 
cf659d
2.14.4
cf659d
cf659d
cf659d
From 9511ba41455865104c3c06f834dd44787a3044bd Mon Sep 17 00:00:00 2001
cf659d
From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd@samba.org>
cf659d
Date: Tue, 13 Mar 2018 16:56:20 +0100
cf659d
Subject: [PATCH 6/6] CVE-2018-1139 libcli/auth: Do not allow ntlmv1 over SMB1
cf659d
 when it is disabled via "ntlm auth".
cf659d
cf659d
This fixes a regression that came in via 00db3aba6cf9ebaafdf39ee2f9c7ba5ec2281ea0.
cf659d
cf659d
Found by Vivek Das <vdas@redhat.com> (Red Hat QE).
cf659d
cf659d
In order to demonstrate simply run:
cf659d
cf659d
smbclient //server/share -U user%password -mNT1 -c quit \
cf659d
--option="client ntlmv2 auth"=no \
cf659d
--option="client use spnego"=no
cf659d
cf659d
against a server that uses "ntlm auth = ntlmv2-only" (our default
cf659d
setting).
cf659d
cf659d
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13360
cf659d
cf659d
CVE-2018-1139: Weak authentication protocol allowed.
cf659d
cf659d
Guenther
cf659d
cf659d
Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>
cf659d
Signed-off-by: Guenther Deschner <gd@samba.org>
cf659d
Reviewed-by: Andreas Schneider <asn@samba.org>
cf659d
---
cf659d
 libcli/auth/ntlm_check.c  | 2 +-
cf659d
 selftest/knownfail        | 3 ++-
cf659d
 selftest/knownfail.d/ntlm | 2 --
cf659d
 3 files changed, 3 insertions(+), 4 deletions(-)
cf659d
 delete mode 100644 selftest/knownfail.d/ntlm
cf659d
cf659d
diff --git a/libcli/auth/ntlm_check.c b/libcli/auth/ntlm_check.c
cf659d
index 1c6499bd210..b68e9c87888 100644
cf659d
--- a/libcli/auth/ntlm_check.c
cf659d
+++ b/libcli/auth/ntlm_check.c
cf659d
@@ -572,7 +572,7 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx,
cf659d
 	   - I think this is related to Win9X pass-though authentication
cf659d
 	*/
cf659d
 	DEBUG(4,("ntlm_password_check: Checking NT MD4 password in LM field\n"));
cf659d
-	if (ntlm_auth) {
cf659d
+	if (ntlm_auth == NTLM_AUTH_ON) {
cf659d
 		if (smb_pwd_check_ntlmv1(mem_ctx, 
cf659d
 					 lm_response, 
cf659d
 					 stored_nt->hash, challenge,
cf659d
diff --git a/selftest/knownfail b/selftest/knownfail
cf659d
index ba16fd72290..84776d4f35d 100644
cf659d
--- a/selftest/knownfail
cf659d
+++ b/selftest/knownfail
cf659d
@@ -303,8 +303,9 @@
cf659d
 ^samba4.smb.signing.*disabled.*signing=off.*\(ad_dc\)
cf659d
 # fl2000dc doesn't support AES
cf659d
 ^samba4.krb5.kdc.*as-req-aes.*fl2000dc
cf659d
-# nt4_member and ad_member don't support ntlmv1
cf659d
+# nt4_member and ad_member don't support ntlmv1 (not even over SMB1)
cf659d
 ^samba3.blackbox.smbclient_auth.plain.*_member.*option=clientntlmv2auth=no.member.creds.*as.user
cf659d
+^samba3.blackbox.smbclient_auth.plain.*_member.*option=clientntlmv2auth=no.*mNT1.member.creds.*as.user
cf659d
 #nt-vfs server blocks read with execute access
cf659d
 ^samba4.smb2.read.access
cf659d
 #ntvfs server blocks copychunk with execute access on read handle
cf659d
diff --git a/selftest/knownfail.d/ntlm b/selftest/knownfail.d/ntlm
cf659d
deleted file mode 100644
cf659d
index c6e6a3739ba..00000000000
cf659d
--- a/selftest/knownfail.d/ntlm
cf659d
+++ /dev/null
cf659d
@@ -1,2 +0,0 @@
cf659d
-^samba.unittests.ntlm_check.test_ntlm_mschapv2_only_denied
cf659d
-^samba.unittests.ntlm_check.test_ntlmv2_only_ntlm\(
cf659d
-- 
cf659d
2.14.4
cf659d