From ba1482a18a807a5db4d1bd84640a0d5d83fcd9c3 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze@samba.org>
Date: Fri, 25 Nov 2022 13:13:36 +0100
Subject: [PATCH 21/29] CVE-2022-38023 s4:rpc_server/netlogon: debug 'reject
 md5 servers' and 'allow nt4 crypto' misconfigurations

This allows the admin to notice what's wrong in order to adjust the
configuration if required.

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

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
(cherry picked from commit 43df4be35950f491864ae8ada05d51b42a556381)

[metze@samba.org remove lpcfg_weak_crypto() check for 4.15]

Conflict: NA
Reference: https://attachments.samba.org/attachment.cgi?id=17698
---
 source4/rpc_server/netlogon/dcerpc_netlogon.c | 121 ++++++++++++++++++
 1 file changed, 121 insertions(+)

diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
index 301a5c8144f5..d23cf48c6409 100644
--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
@@ -63,10 +63,34 @@ static NTSTATUS dcesrv_interface_netlogon_bind(struct dcesrv_connection_context
 					       const struct dcesrv_interface *iface)
 {
 	struct loadparm_context *lp_ctx = context->conn->dce_ctx->lp_ctx;
+	bool global_allow_nt4_crypto = lpcfg_allow_nt4_crypto(lp_ctx);
+	bool global_reject_md5_client = lpcfg_reject_md5_clients(lp_ctx);
 	int schannel = lpcfg_server_schannel(lp_ctx);
 	bool schannel_global_required = (schannel == true);
+	static bool warned_global_nt4_once = false;
+	static bool warned_global_md5_once = false;
 	static bool warned_global_schannel_once = false;
 
+	if (global_allow_nt4_crypto && !warned_global_nt4_once) {
+		/*
+		 * We want admins to notice their misconfiguration!
+		 */
+		D_ERR("CVE-2022-38023 (and others): "
+		      "Please configure 'allow nt4 crypto = no' (the default), "
+		      "See https://bugzilla.samba.org/show_bug.cgi?id=15240\n");
+		warned_global_nt4_once = true;
+	}
+
+	if (!global_reject_md5_client && !warned_global_md5_once) {
+		/*
+		 * We want admins to notice their misconfiguration!
+		 */
+		D_ERR("CVE-2022-38023: "
+		      "Please configure 'reject md5 clients = yes' (the default), "
+		      "See https://bugzilla.samba.org/show_bug.cgi?id=15240\n");
+		warned_global_md5_once = true;
+	}
+
 	if (!schannel_global_required && !warned_global_schannel_once) {
 		/*
 		 * We want admins to notice their misconfiguration!
@@ -148,6 +172,12 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_check_downgrade(
 	bool reject_des_client;
 	bool allow_nt4_crypto;
 	bool reject_md5_client;
+	bool need_des = true;
+	bool need_md5 = true;
+	int CVE_2022_38023_warn_level = lpcfg_parm_int(lp_ctx, NULL,
+			"CVE_2022_38023", "warn_about_unused_debug_level", DBGLVL_ERR);
+	int CVE_2022_38023_error_level = lpcfg_parm_int(lp_ctx, NULL,
+			"CVE_2022_38023", "error_debug_level", DBGLVL_ERR);
 
 	/*
 	 * We don't use lpcfg_parm_bool(), as we
@@ -179,19 +209,62 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_check_downgrade(
 	reject_des_client = !allow_nt4_crypto;
 
 	if (negotiate_flags & NETLOGON_NEG_STRONG_KEYS) {
+		need_des = false;
 		reject_des_client = false;
 	}
 
 	if (negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
+		need_des = false;
+		need_md5 = false;
 		reject_des_client = false;
 		reject_md5_client = false;
 	}
 
 	if (reject_des_client || reject_md5_client) {
+		TALLOC_CTX *frame = talloc_stackframe();
+
+		DEBUG(CVE_2022_38023_error_level, (
+		      "CVE-2022-38023: "
+		      "client_account[%s] computer_name[%s] "
+		      "schannel_type[%u] "
+		      "client_negotiate_flags[0x%x] "
+		      "%s%s%s "
+		      "NT_STATUS_DOWNGRADE_DETECTED "
+		      "reject_des[%u] reject_md5[%u]\n",
+		      log_escape(frame, r->in.account_name),
+		      log_escape(frame, r->in.computer_name),
+		      r->in.secure_channel_type,
+		      (unsigned)*r->in.negotiate_flags,
+		      trust_account_in_db ? "real_account[" : "",
+		      trust_account_in_db ? trust_account_in_db : "",
+		      trust_account_in_db ? "]" : "",
+		      reject_des_client,
+		      reject_md5_client));
+		if (trust_account_in_db == NULL) {
+			goto return_downgrade;
+		}
+
+		if (reject_md5_client && explicit_md5_opt == NULL) {
+			DEBUG(CVE_2022_38023_error_level, (
+			      "CVE-2022-38023: Check if option "
+			      "'server reject md5 schannel:%s = no' "
+			      "might be needed for a legacy client.\n",
+			      trust_account_in_db));
+		}
+		if (reject_des_client && explicit_nt4_opt == NULL) {
+			DEBUG(CVE_2022_38023_error_level, (
+			      "CVE-2022-38023: Check if option "
+			      "'allow nt4 crypto:%s = yes' "
+			      "might be needed for a legacy client.\n",
+			      trust_account_in_db));
+		}
+
+return_downgrade:
 		/*
 		 * Here we match Windows 2012 and return no flags.
 		 */
 		*r->out.negotiate_flags = 0;
+		TALLOC_FREE(frame);
 		return NT_STATUS_DOWNGRADE_DETECTED;
 	}
 
@@ -224,6 +297,54 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_check_downgrade(
 	 */
 	*r->out.negotiate_flags = negotiate_flags;
 
+	if (!NT_STATUS_IS_OK(orig_status) || trust_account_in_db == NULL) {
+		return orig_status;
+	}
+
+	if (global_reject_md5_client && account_reject_md5_client && explicit_md5_opt) {
+		D_INFO("CVE-2022-38023: Check if option "
+		       "'server reject md5 schannel:%s = yes' not needed!?\n",
+		       trust_account_in_db);
+	} else if (need_md5 && !account_reject_md5_client && explicit_md5_opt) {
+		D_INFO("CVE-2022-38023: Check if option "
+			 "'server reject md5 schannel:%s = no' "
+			 "still needed for a legacy client.\n",
+			 trust_account_in_db);
+	} else if (need_md5 && explicit_md5_opt == NULL) {
+		DEBUG(CVE_2022_38023_error_level, (
+		      "CVE-2022-38023: Check if option "
+		      "'server reject md5 schannel:%s = no' "
+		      "might be needed for a legacy client.\n",
+		      trust_account_in_db));
+	} else if (!account_reject_md5_client && explicit_md5_opt) {
+		DEBUG(CVE_2022_38023_warn_level, (
+		      "CVE-2022-38023: Check if option "
+		      "'server reject md5 schannel:%s = no' not needed!?\n",
+		      trust_account_in_db));
+	}
+
+	if (!global_allow_nt4_crypto && !account_allow_nt4_crypto && explicit_nt4_opt) {
+		D_INFO("CVE-2022-38023: Check if option "
+		       "'allow nt4 crypto:%s = no' not needed!?\n",
+		       trust_account_in_db);
+	} else if (need_des && account_allow_nt4_crypto && explicit_nt4_opt) {
+		D_INFO("CVE-2022-38023: Check if option "
+			 "'allow nt4 crypto:%s = yes' "
+			 "still needed for a legacy client.\n",
+			 trust_account_in_db);
+	} else if (need_des && explicit_nt4_opt == NULL) {
+		DEBUG(CVE_2022_38023_error_level, (
+		      "CVE-2022-38023: Check if option "
+		      "'allow nt4 crypto:%s = yes' "
+		      "might be needed for a legacy client.\n",
+		      trust_account_in_db));
+	} else if (account_allow_nt4_crypto && explicit_nt4_opt) {
+		DEBUG(CVE_2022_38023_warn_level, (
+		      "CVE-2022-38023: Check if option "
+		      "'allow nt4 crypto:%s = yes' not needed!?\n",
+		      trust_account_in_db));
+	}
+
 	return orig_status;
 }
 
-- 
2.34.1
