Blob Blame History Raw
From e39dcc08705f0bf59a57ad835821cef41ec8b1e6 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow@samba.org>
Date: Tue, 6 Dec 2022 16:00:36 +0100
Subject: [PATCH 01/30] CVE-2022-38023 docs-xml: improve wording for several
 options: "takes precedence" -> "overrides"

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

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
(cherry picked from commit 8ec62694a94c346e6ba8f3144a417c9984a1c8b9)
---
 docs-xml/smbdotconf/logon/rejectmd5clients.xml   | 2 +-
 docs-xml/smbdotconf/security/serverschannel.xml  | 2 +-
 docs-xml/smbdotconf/winbind/rejectmd5servers.xml | 2 +-
 docs-xml/smbdotconf/winbind/requirestrongkey.xml | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/docs-xml/smbdotconf/logon/rejectmd5clients.xml b/docs-xml/smbdotconf/logon/rejectmd5clients.xml
index 41684ef10805..0bb9f6f6c8ec 100644
--- a/docs-xml/smbdotconf/logon/rejectmd5clients.xml
+++ b/docs-xml/smbdotconf/logon/rejectmd5clients.xml
@@ -10,7 +10,7 @@
 	<para>You can set this to yes if all domain members support aes.
 	This will prevent downgrade attacks.</para>
 
-	<para>This option takes precedence to the 'allow nt4 crypto' option.</para>
+	<para>This option overrides the 'allow nt4 crypto' option.</para>
 </description>
 
 <value type="default">no</value>
diff --git a/docs-xml/smbdotconf/security/serverschannel.xml b/docs-xml/smbdotconf/security/serverschannel.xml
index b682d086f76b..79e4e73a95c9 100644
--- a/docs-xml/smbdotconf/security/serverschannel.xml
+++ b/docs-xml/smbdotconf/security/serverschannel.xml
@@ -59,7 +59,7 @@
 	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>
+    <para>This option overrides the <smbconfoption name="server schannel"/> option.</para>
 
     <programlisting>
 	server require schannel:LEGACYCOMPUTER1$ = no
diff --git a/docs-xml/smbdotconf/winbind/rejectmd5servers.xml b/docs-xml/smbdotconf/winbind/rejectmd5servers.xml
index 37656293aa47..151b4676c57b 100644
--- a/docs-xml/smbdotconf/winbind/rejectmd5servers.xml
+++ b/docs-xml/smbdotconf/winbind/rejectmd5servers.xml
@@ -15,7 +15,7 @@
 	<para>The behavior can be controlled per netbios domain
 	by using 'reject md5 servers:NETBIOSDOMAIN = yes' as option.</para>
 
-	<para>This option takes precedence to the <smbconfoption name="require strong key"/> option.</para>
+	<para>This option overrides the <smbconfoption name="require strong key"/> option.</para>
 </description>
 
 <value type="default">no</value>
diff --git a/docs-xml/smbdotconf/winbind/requirestrongkey.xml b/docs-xml/smbdotconf/winbind/requirestrongkey.xml
index 4db62bfb02db..b17620ec8f1d 100644
--- a/docs-xml/smbdotconf/winbind/requirestrongkey.xml
+++ b/docs-xml/smbdotconf/winbind/requirestrongkey.xml
@@ -19,7 +19,7 @@
 
 	<para>This option yields precedence to the <smbconfoption name="reject md5 servers"/> option.</para>
 
-	<para>This option takes precedence to the <smbconfoption name="client schannel"/> option.</para>
+	<para>This option overrides the <smbconfoption name="client schannel"/> option.</para>
 </description>
 
 <value type="default">yes</value>
-- 
2.34.1


From 75fcaa4792afde7599d23316788ce8bbf780fe8a Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow@samba.org>
Date: Tue, 6 Dec 2022 16:05:26 +0100
Subject: [PATCH 02/30] CVE-2022-38023 docs-xml: improve wording for several
 options: "yields precedence" -> "is over-riden"

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

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
(cherry picked from commit 830e865ba5648f6520bc552ffd71b61f754b8251)
---
 docs-xml/smbdotconf/logon/allownt4crypto.xml                 | 2 +-
 docs-xml/smbdotconf/security/allowdcerpcauthlevelconnect.xml | 2 +-
 docs-xml/smbdotconf/security/clientschannel.xml              | 2 +-
 docs-xml/smbdotconf/security/serverschannel.xml              | 2 +-
 docs-xml/smbdotconf/winbind/requirestrongkey.xml             | 2 +-
 5 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/docs-xml/smbdotconf/logon/allownt4crypto.xml b/docs-xml/smbdotconf/logon/allownt4crypto.xml
index 03dc8fa93f72..06afcef73b1b 100644
--- a/docs-xml/smbdotconf/logon/allownt4crypto.xml
+++ b/docs-xml/smbdotconf/logon/allownt4crypto.xml
@@ -18,7 +18,7 @@
 
 	<para>"allow nt4 crypto = yes" allows weak crypto to be negotiated, maybe via downgrade attacks.</para>
 
-	<para>This option yields precedence to the 'reject md5 clients' option.</para>
+	<para>This option is over-ridden by the 'reject md5 clients' option.</para>
 </description>
 
 <value type="default">no</value>
diff --git a/docs-xml/smbdotconf/security/allowdcerpcauthlevelconnect.xml b/docs-xml/smbdotconf/security/allowdcerpcauthlevelconnect.xml
index 03531adbfb36..8bccab391cc2 100644
--- a/docs-xml/smbdotconf/security/allowdcerpcauthlevelconnect.xml
+++ b/docs-xml/smbdotconf/security/allowdcerpcauthlevelconnect.xml
@@ -15,7 +15,7 @@
 	<para>The behavior can be overwritten per interface name (e.g. lsarpc, netlogon, samr, srvsvc,
 	winreg, wkssvc ...) by using 'allow dcerpc auth level connect:interface = yes' as option.</para>
 
-	<para>This option yields precedence to the implementation specific restrictions.
+	<para>This option is over-ridden by the implementation specific restrictions.
 	E.g. the drsuapi and backupkey protocols require DCERPC_AUTH_LEVEL_PRIVACY.
 	The dnsserver protocol requires DCERPC_AUTH_LEVEL_INTEGRITY.
 	</para>
diff --git a/docs-xml/smbdotconf/security/clientschannel.xml b/docs-xml/smbdotconf/security/clientschannel.xml
index 5b07da95050c..d124ad481818 100644
--- a/docs-xml/smbdotconf/security/clientschannel.xml
+++ b/docs-xml/smbdotconf/security/clientschannel.xml
@@ -23,7 +23,7 @@
     <para>Note that for active directory domains this is hardcoded to
     <smbconfoption name="client schannel">yes</smbconfoption>.</para>
 
-    <para>This option yields precedence to the <smbconfoption name="require strong key"/> option.</para>
+    <para>This option is over-ridden by the <smbconfoption name="require strong key"/> option.</para>
 </description>
 <value type="default">yes</value>
 <value type="example">auto</value>
diff --git a/docs-xml/smbdotconf/security/serverschannel.xml b/docs-xml/smbdotconf/security/serverschannel.xml
index 79e4e73a95c9..3e66df1c2032 100644
--- a/docs-xml/smbdotconf/security/serverschannel.xml
+++ b/docs-xml/smbdotconf/security/serverschannel.xml
@@ -23,7 +23,7 @@
     <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>
+    <para>This option is over-ridden by the <smbconfoption name="server require schannel:COMPUTERACCOUNT"/> option.</para>
 
 </description>
 
diff --git a/docs-xml/smbdotconf/winbind/requirestrongkey.xml b/docs-xml/smbdotconf/winbind/requirestrongkey.xml
index b17620ec8f1d..9c1c1d7af148 100644
--- a/docs-xml/smbdotconf/winbind/requirestrongkey.xml
+++ b/docs-xml/smbdotconf/winbind/requirestrongkey.xml
@@ -17,7 +17,7 @@
 
 	<para>Note for active directory domain this option is hardcoded to 'yes'</para>
 
-	<para>This option yields precedence to the <smbconfoption name="reject md5 servers"/> option.</para>
+	<para>This option is over-ridden by the <smbconfoption name="reject md5 servers"/> option.</para>
 
 	<para>This option overrides the <smbconfoption name="client schannel"/> option.</para>
 </description>
-- 
2.34.1


From cbf7cf691860d92c1890009b639a1fd495cf1cf2 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze@samba.org>
Date: Wed, 30 Nov 2022 14:46:59 +0100
Subject: [PATCH 03/30] CVE-2022-38023 libcli/auth: pass lp_ctx to
 netlogon_creds_cli_set_global_db()

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 992f39a2c8a58301ceeb965f401e29cd64c5a209)
---
 libcli/auth/netlogon_creds_cli.c           | 3 ++-
 libcli/auth/netlogon_creds_cli.h           | 2 +-
 source3/rpc_client/cli_netlogon.c          | 2 +-
 source3/utils/destroy_netlogon_creds_cli.c | 2 +-
 4 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/libcli/auth/netlogon_creds_cli.c b/libcli/auth/netlogon_creds_cli.c
index e92a042c0120..030191174dca 100644
--- a/libcli/auth/netlogon_creds_cli.c
+++ b/libcli/auth/netlogon_creds_cli.c
@@ -202,7 +202,8 @@ static NTSTATUS netlogon_creds_cli_context_common(
 
 static struct db_context *netlogon_creds_cli_global_db;
 
-NTSTATUS netlogon_creds_cli_set_global_db(struct db_context **db)
+NTSTATUS netlogon_creds_cli_set_global_db(struct loadparm_context *lp_ctx,
+					  struct db_context **db)
 {
 	if (netlogon_creds_cli_global_db != NULL) {
 		return NT_STATUS_INVALID_PARAMETER_MIX;
diff --git a/libcli/auth/netlogon_creds_cli.h b/libcli/auth/netlogon_creds_cli.h
index 6f40a46aa0a6..d10197c2d2af 100644
--- a/libcli/auth/netlogon_creds_cli.h
+++ b/libcli/auth/netlogon_creds_cli.h
@@ -31,7 +31,7 @@ struct messaging_context;
 struct dcerpc_binding_handle;
 struct db_context;
 
-NTSTATUS netlogon_creds_cli_set_global_db(struct db_context **db);
+NTSTATUS netlogon_creds_cli_set_global_db(struct loadparm_context *lp_ctx, struct db_context **db);
 NTSTATUS netlogon_creds_cli_open_global_db(struct loadparm_context *lp_ctx);
 void netlogon_creds_cli_close_global_db(void);
 
diff --git a/source3/rpc_client/cli_netlogon.c b/source3/rpc_client/cli_netlogon.c
index 50dae9d7f3eb..18664e8b91af 100644
--- a/source3/rpc_client/cli_netlogon.c
+++ b/source3/rpc_client/cli_netlogon.c
@@ -76,7 +76,7 @@ NTSTATUS rpccli_pre_open_netlogon_creds(void)
 		return NT_STATUS_NO_MEMORY;
 	}
 
-	status = netlogon_creds_cli_set_global_db(&global_db);
+	status = netlogon_creds_cli_set_global_db(lp_ctx, &global_db);
 	TALLOC_FREE(frame);
 	if (!NT_STATUS_IS_OK(status)) {
 		return status;
diff --git a/source3/utils/destroy_netlogon_creds_cli.c b/source3/utils/destroy_netlogon_creds_cli.c
index f28cad527dfb..a2e1952e434c 100644
--- a/source3/utils/destroy_netlogon_creds_cli.c
+++ b/source3/utils/destroy_netlogon_creds_cli.c
@@ -82,7 +82,7 @@ int main(int argc, const char *argv[])
 		goto done;
 	}
 
-	status = netlogon_creds_cli_set_global_db(&global_db);
+	status = netlogon_creds_cli_set_global_db(lp_ctx, &global_db);
 	if (!NT_STATUS_IS_OK(status)) {
 		fprintf(stderr,
 			"netlogon_creds_cli_set_global_db failed: %s\n",
-- 
2.34.1


From 2c4f9869b208cfd969607248420e36e3bd4aecfa Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze@samba.org>
Date: Wed, 30 Nov 2022 14:47:33 +0100
Subject: [PATCH 04/30] CVE-2022-38023 libcli/auth: add/use
 netlogon_creds_cli_warn_options()

This warns the admin about insecure options

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>

(similar to commit 7e7adf86e59e8a673fbe87de46cef0d62221e800)
[jsutton@samba.org Replaced call to tevent_cached_getpid() with one to
 getpid()]
---
 libcli/auth/netlogon_creds_cli.c | 66 ++++++++++++++++++++++++++++++++
 libcli/auth/netlogon_creds_cli.h |  2 +
 2 files changed, 68 insertions(+)

diff --git a/libcli/auth/netlogon_creds_cli.c b/libcli/auth/netlogon_creds_cli.c
index 030191174dca..3794d8b6b6ef 100644
--- a/libcli/auth/netlogon_creds_cli.c
+++ b/libcli/auth/netlogon_creds_cli.c
@@ -205,6 +205,8 @@ static struct db_context *netlogon_creds_cli_global_db;
 NTSTATUS netlogon_creds_cli_set_global_db(struct loadparm_context *lp_ctx,
 					  struct db_context **db)
 {
+	netlogon_creds_cli_warn_options(lp_ctx);
+
 	if (netlogon_creds_cli_global_db != NULL) {
 		return NT_STATUS_INVALID_PARAMETER_MIX;
 	}
@@ -219,6 +221,8 @@ NTSTATUS netlogon_creds_cli_open_global_db(struct loadparm_context *lp_ctx)
 	struct db_context *global_db;
 	int hash_size, tdb_flags;
 
+	netlogon_creds_cli_warn_options(lp_ctx);
+
 	if (netlogon_creds_cli_global_db != NULL) {
 		return NT_STATUS_OK;
 	}
@@ -259,6 +263,68 @@ void netlogon_creds_cli_close_global_db(void)
 	TALLOC_FREE(netlogon_creds_cli_global_db);
 }
 
+void netlogon_creds_cli_warn_options(struct loadparm_context *lp_ctx)
+{
+	bool global_reject_md5_servers = lpcfg_reject_md5_servers(lp_ctx);
+	bool global_require_strong_key = lpcfg_require_strong_key(lp_ctx);
+	int global_client_schannel = lpcfg_client_schannel(lp_ctx);
+	bool global_seal_secure_channel = lpcfg_winbind_sealed_pipes(lp_ctx);
+	static bool warned_global_reject_md5_servers = false;
+	static bool warned_global_require_strong_key = false;
+	static bool warned_global_client_schannel = false;
+	static bool warned_global_seal_secure_channel = false;
+	static int warned_global_pid = 0;
+	int current_pid = getpid();
+
+	if (warned_global_pid != current_pid) {
+		warned_global_reject_md5_servers = false;
+		warned_global_require_strong_key = false;
+		warned_global_client_schannel = false;
+		warned_global_seal_secure_channel = false;
+		warned_global_pid = current_pid;
+	}
+
+	if (!global_reject_md5_servers && !warned_global_reject_md5_servers) {
+		/*
+		 * We want admins to notice their misconfiguration!
+		 */
+		DBG_ERR("CVE-2022-38023 (and others): "
+			"Please configure 'reject md5 servers = yes' (the default), "
+			"See https://bugzilla.samba.org/show_bug.cgi?id=15240\n");
+		warned_global_reject_md5_servers = true;
+	}
+
+	if (!global_require_strong_key && !warned_global_require_strong_key) {
+		/*
+		 * We want admins to notice their misconfiguration!
+		 */
+		DBG_ERR("CVE-2022-38023 (and others): "
+			"Please configure 'require strong key = yes' (the default), "
+			"See https://bugzilla.samba.org/show_bug.cgi?id=15240\n");
+		warned_global_require_strong_key = true;
+	}
+
+	if (global_client_schannel != true && !warned_global_client_schannel) {
+		/*
+		 * We want admins to notice their misconfiguration!
+		 */
+		DBG_ERR("CVE-2022-38023 (and others): "
+			"Please configure 'client schannel = yes' (the default), "
+			"See https://bugzilla.samba.org/show_bug.cgi?id=15240\n");
+		warned_global_client_schannel = true;
+	}
+
+	if (!global_seal_secure_channel && !warned_global_seal_secure_channel) {
+		/*
+		 * We want admins to notice their misconfiguration!
+		 */
+		DBG_ERR("CVE-2022-38023 (and others): "
+			"Please configure 'winbind sealed pipes = yes' (the default), "
+			"See https://bugzilla.samba.org/show_bug.cgi?id=15240\n");
+		warned_global_seal_secure_channel = true;
+	}
+}
+
 NTSTATUS netlogon_creds_cli_context_global(struct loadparm_context *lp_ctx,
 				struct messaging_context *msg_ctx,
 				const char *client_account,
diff --git a/libcli/auth/netlogon_creds_cli.h b/libcli/auth/netlogon_creds_cli.h
index d10197c2d2af..600242e1aea7 100644
--- a/libcli/auth/netlogon_creds_cli.h
+++ b/libcli/auth/netlogon_creds_cli.h
@@ -35,6 +35,8 @@ NTSTATUS netlogon_creds_cli_set_global_db(struct loadparm_context *lp_ctx, struc
 NTSTATUS netlogon_creds_cli_open_global_db(struct loadparm_context *lp_ctx);
 void netlogon_creds_cli_close_global_db(void);
 
+void netlogon_creds_cli_warn_options(struct loadparm_context *lp_ctx);
+
 NTSTATUS netlogon_creds_cli_context_global(struct loadparm_context *lp_ctx,
 				struct messaging_context *msg_ctx,
 				const char *client_account,
-- 
2.34.1


From 558c68e0915885ed77b3d02e52d93f4c64a0e20e Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze@samba.org>
Date: Wed, 30 Nov 2022 16:16:05 +0100
Subject: [PATCH 05/30] CVE-2022-38023 s3:net: add and use
 net_warn_member_options() helper

This makes sure domain member related 'net' commands print warnings
about unsecure smb.conf options.

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 1fdf1d55a5dd550bdb16d037b5dc995c33c1a67a)
---
 source3/utils/net.c             |  6 ++++++
 source3/utils/net_ads.c         | 14 ++++++++++++++
 source3/utils/net_dom.c         |  2 ++
 source3/utils/net_join.c        |  2 ++
 source3/utils/net_offlinejoin.c |  2 ++
 source3/utils/net_proto.h       |  2 ++
 source3/utils/net_rpc.c         | 10 ++++++++++
 source3/utils/net_util.c        | 14 ++++++++++++++
 8 files changed, 52 insertions(+)

diff --git a/source3/utils/net.c b/source3/utils/net.c
index e1e14743c117..b96d7f5d9d48 100644
--- a/source3/utils/net.c
+++ b/source3/utils/net.c
@@ -85,6 +85,8 @@ enum netr_SchannelType get_sec_channel_type(const char *param)
 
 static int net_changetrustpw(struct net_context *c, int argc, const char **argv)
 {
+	net_warn_member_options();
+
 	if (net_ads_check_our_domain(c) == 0)
 		return net_ads_changetrustpw(c, argc, argv);
 
@@ -112,6 +114,8 @@ static int net_primarytrust_dumpinfo(struct net_context *c, int argc,
 		return 1;
 	}
 
+	net_warn_member_options();
+
 	if (c->opt_stdin) {
 		set_line_buffering(stdin);
 		set_line_buffering(stdout);
@@ -193,6 +197,8 @@ static int net_changesecretpw(struct net_context *c, int argc,
 		return 1;
 	}
 
+	net_warn_member_options();
+
 	if(c->opt_force) {
 		struct secrets_domain_info1 *info = NULL;
 		struct secrets_domain_info1_change *prev = NULL;
diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c
index d666f7fc3ec9..cc0d4a0d966c 100644
--- a/source3/utils/net_ads.c
+++ b/source3/utils/net_ads.c
@@ -1306,6 +1306,8 @@ static int net_ads_status(struct net_context *c, int argc, const char **argv)
 		return 0;
 	}
 
+	net_warn_member_options();
+
 	if (!ADS_ERR_OK(ads_startup(c, true, &ads))) {
 		return -1;
 	}
@@ -1447,6 +1449,8 @@ static NTSTATUS net_ads_join_ok(struct net_context *c)
 		return NT_STATUS_ACCESS_DENIED;
 	}
 
+	net_warn_member_options();
+
 	net_use_krb_machine_account(c);
 
 	get_dc_name(lp_workgroup(), lp_realm(), dc_name, &dcip);
@@ -1477,6 +1481,8 @@ int net_ads_testjoin(struct net_context *c, int argc, const char **argv)
 		return 0;
 	}
 
+	net_warn_member_options();
+
 	/* Display success or failure */
 	status = net_ads_join_ok(c);
 	if (!NT_STATUS_IS_OK(status)) {
@@ -1571,6 +1577,8 @@ int net_ads_join(struct net_context *c, int argc, const char **argv)
 	if (c->display_usage)
 		return net_ads_join_usage(c, argc, argv);
 
+	net_warn_member_options();
+
 	if (!modify_config) {
 
 		werr = check_ads_config();
@@ -2505,6 +2513,8 @@ int net_ads_changetrustpw(struct net_context *c, int argc, const char **argv)
 		return -1;
 	}
 
+	net_warn_member_options();
+
 	net_use_krb_machine_account(c);
 
 	use_in_memory_ccache();
@@ -2778,6 +2788,8 @@ static int net_ads_keytab_add(struct net_context *c,
 		return 0;
 	}
 
+	net_warn_member_options();
+
 	d_printf(_("Processing principals to add...\n"));
 
 	if (!c->opt_user_specified && c->opt_password == NULL) {
@@ -2822,6 +2834,8 @@ static int net_ads_keytab_create(struct net_context *c, int argc, const char **a
 		return 0;
 	}
 
+	net_warn_member_options();
+
 	if (!c->opt_user_specified && c->opt_password == NULL) {
 		net_use_krb_machine_account(c);
 	}
diff --git a/source3/utils/net_dom.c b/source3/utils/net_dom.c
index 13e65a933142..4b48e1566bc8 100644
--- a/source3/utils/net_dom.c
+++ b/source3/utils/net_dom.c
@@ -154,6 +154,8 @@ static int net_dom_join(struct net_context *c, int argc, const char **argv)
 		return net_dom_usage(c, argc, argv);
 	}
 
+	net_warn_member_options();
+
 	if (c->opt_host) {
 		server_name = c->opt_host;
 	}
diff --git a/source3/utils/net_join.c b/source3/utils/net_join.c
index 1493dff74d7b..f67f08f79a81 100644
--- a/source3/utils/net_join.c
+++ b/source3/utils/net_join.c
@@ -39,6 +39,8 @@ int net_join(struct net_context *c, int argc, const char **argv)
 		return 0;
 	}
 
+	net_warn_member_options();
+
 	if (net_ads_check_our_domain(c) == 0) {
 		if (net_ads_join(c, argc, argv) == 0)
 			return 0;
diff --git a/source3/utils/net_offlinejoin.c b/source3/utils/net_offlinejoin.c
index 03e5df0eace9..0cfd5fdfe235 100644
--- a/source3/utils/net_offlinejoin.c
+++ b/source3/utils/net_offlinejoin.c
@@ -49,6 +49,8 @@ int net_offlinejoin(struct net_context *c, int argc, const char **argv)
 		return -1;
 	}
 
+	net_warn_member_options();
+
 	status = libnetapi_net_init(&c->netapi_ctx);
 	if (status != 0) {
 		return -1;
diff --git a/source3/utils/net_proto.h b/source3/utils/net_proto.h
index b6ff639a0941..42096ba218d5 100644
--- a/source3/utils/net_proto.h
+++ b/source3/utils/net_proto.h
@@ -442,6 +442,8 @@ int net_run_function(struct net_context *c, int argc, const char **argv,
 		      const char *whoami, struct functable *table);
 void net_display_usage_from_functable(struct functable *table);
 
+void net_warn_member_options(void);
+
 const char *net_share_type_str(int num_type);
 
 NTSTATUS net_scan_dc(struct net_context *c,
diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c
index 97c0158d612f..16a541413d2e 100644
--- a/source3/utils/net_rpc.c
+++ b/source3/utils/net_rpc.c
@@ -371,6 +371,8 @@ static int net_rpc_oldjoin(struct net_context *c, int argc, const char **argv)
 		return 0;
 	}
 
+	net_warn_member_options();
+
 	mem_ctx = talloc_init("net_rpc_oldjoin");
 	if (!mem_ctx) {
 		return -1;
@@ -490,6 +492,8 @@ int net_rpc_testjoin(struct net_context *c, int argc, const char **argv)
 		return 0;
 	}
 
+	net_warn_member_options();
+
 	mem_ctx = talloc_init("net_rpc_testjoin");
 	if (!mem_ctx) {
 		return -1;
@@ -564,6 +568,8 @@ static int net_rpc_join_newstyle(struct net_context *c, int argc, const char **a
 		return 0;
 	}
 
+	net_warn_member_options();
+
 	mem_ctx = talloc_init("net_rpc_join_newstyle");
 	if (!mem_ctx) {
 		return -1;
@@ -685,6 +691,8 @@ int net_rpc_join(struct net_context *c, int argc, const char **argv)
 		return -1;
 	}
 
+	net_warn_member_options();
+
 	if (strlen(lp_netbios_name()) > 15) {
 		d_printf(_("Our netbios name can be at most 15 chars long, "
 			   "\"%s\" is %u chars long\n"),
@@ -815,6 +823,8 @@ int net_rpc_info(struct net_context *c, int argc, const char **argv)
 		return 0;
 	}
 
+	net_warn_member_options();
+
 	return run_rpc_command(c, NULL, &ndr_table_samr,
 			       NET_FLAGS_PDC, rpc_info_internals,
 			       argc, argv);
diff --git a/source3/utils/net_util.c b/source3/utils/net_util.c
index 298d9a64dc0c..f3b7755063bf 100644
--- a/source3/utils/net_util.c
+++ b/source3/utils/net_util.c
@@ -31,6 +31,7 @@
 #include "libsmb/libsmb.h"
 #include "lib/param/param.h"
 #include "auth/gensec/gensec.h"
+#include "libcli/auth/netlogon_creds_cli.h"
 #include "lib/cmdline/cmdline.h"
 
 NTSTATUS net_rpc_lookup_name(struct net_context *c,
@@ -478,6 +479,19 @@ void net_display_usage_from_functable(struct functable *table)
 	}
 }
 
+void net_warn_member_options(void)
+{
+	TALLOC_CTX *frame = talloc_stackframe();
+	struct loadparm_context *lp_ctx = NULL;
+
+	lp_ctx = loadparm_init_s3(frame, loadparm_s3_helpers());
+	if (lp_ctx != NULL) {
+		netlogon_creds_cli_warn_options(lp_ctx);
+	}
+
+	TALLOC_FREE(frame);
+}
+
 const char *net_share_type_str(int num_type)
 {
 	switch(num_type) {
-- 
2.34.1


From 9172fa1fe342a13c773d14c73ffcaa9f9561cdc7 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze@samba.org>
Date: Wed, 30 Nov 2022 14:59:36 +0100
Subject: [PATCH 06/30] CVE-2022-38023 s3:winbindd: also allow per domain
 "winbind sealed pipes:DOMAIN" and "require strong key:DOMAIN"

This avoids advising insecure defaults for the global options.

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 d60828f6391307a59abaa02b72b6a8acf66b2fef)
---
 source3/winbindd/winbindd_cm.c | 41 +++++++++++++++++++++++++++-------
 1 file changed, 33 insertions(+), 8 deletions(-)

diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c
index 6c6dd88a5aa4..5532e0cd0cc8 100644
--- a/source3/winbindd/winbindd_cm.c
+++ b/source3/winbindd/winbindd_cm.c
@@ -2431,6 +2431,8 @@ NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
 	bool retry = false; /* allow one retry attempt for expired session */
 	const char *remote_name = NULL;
 	const struct sockaddr_storage *remote_sockaddr = NULL;
+	bool sealed_pipes = true;
+	bool strong_key = true;
 
 	if (sid_check_is_our_sam(&domain->sid)) {
 		if (domain->rodc == false || need_rw_dc == false) {
@@ -2610,14 +2612,24 @@ retry:
 
  anonymous:
 
+	sealed_pipes = lp_winbind_sealed_pipes();
+	sealed_pipes = lp_parm_bool(-1, "winbind sealed pipes",
+				    domain->name,
+				    sealed_pipes);
+	strong_key = lp_require_strong_key();
+	strong_key = lp_parm_bool(-1, "require strong key",
+				  domain->name,
+				  strong_key);
+
 	/* Finally fall back to anonymous. */
-	if (lp_winbind_sealed_pipes() || lp_require_strong_key()) {
+	if (sealed_pipes || strong_key) {
 		status = NT_STATUS_DOWNGRADE_DETECTED;
 		DEBUG(1, ("Unwilling to make SAMR connection to domain %s "
 			  "without connection level security, "
-			  "must set 'winbind sealed pipes = false' and "
-			  "'require strong key = false' to proceed: %s\n",
-			  domain->name, nt_errstr(status)));
+			  "must set 'winbind sealed pipes:%s = false' and "
+			  "'require strong key:%s = false' to proceed: %s\n",
+			  domain->name, domain->name, domain->name,
+			  nt_errstr(status)));
 		goto done;
 	}
 	status = cli_rpc_pipe_open_noauth(conn->cli, &ndr_table_samr,
@@ -2774,6 +2786,8 @@ NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
 	bool retry = false; /* allow one retry attempt for expired session */
 	const char *remote_name = NULL;
 	const struct sockaddr_storage *remote_sockaddr = NULL;
+	bool sealed_pipes = true;
+	bool strong_key = true;
 
 retry:
 	result = init_dc_connection_rpc(domain, false);
@@ -2935,13 +2949,24 @@ retry:
 		goto done;
 	}
 
-	if (lp_winbind_sealed_pipes() || lp_require_strong_key()) {
+	sealed_pipes = lp_winbind_sealed_pipes();
+	sealed_pipes = lp_parm_bool(-1, "winbind sealed pipes",
+				    domain->name,
+				    sealed_pipes);
+	strong_key = lp_require_strong_key();
+	strong_key = lp_parm_bool(-1, "require strong key",
+				  domain->name,
+				  strong_key);
+
+	/* Finally fall back to anonymous. */
+	if (sealed_pipes || strong_key) {
 		result = NT_STATUS_DOWNGRADE_DETECTED;
 		DEBUG(1, ("Unwilling to make LSA connection to domain %s "
 			  "without connection level security, "
-			  "must set 'winbind sealed pipes = false' and "
-			  "'require strong key = false' to proceed: %s\n",
-			  domain->name, nt_errstr(result)));
+			  "must set 'winbind sealed pipes:%s = false' and "
+			  "'require strong key:%s = false' to proceed: %s\n",
+			  domain->name, domain->name, domain->name,
+			  nt_errstr(result)));
 		goto done;
 	}
 
-- 
2.34.1


From 434812f94ee12bdb55dbe8072702426f85610c02 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze@samba.org>
Date: Thu, 24 Nov 2022 18:22:23 +0100
Subject: [PATCH 07/30] CVE-2022-38023 docs-xml/smbdotconf: change 'reject md5
 servers' default to yes

AES is supported by Windows >= 2008R2 and Samba >= 4.0 so there's no
reason to allow md5 servers by default.

Note the change in netlogon_creds_cli_context_global() is only cosmetic,
but avoids confusion while reading the code. Check with:

 git show -U35 libcli/auth/netlogon_creds_cli.c

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 1c6c1129905d0c7a60018e7bf0f17a0fd198a584)
---
 docs-xml/smbdotconf/winbind/rejectmd5servers.xml | 7 +++++--
 lib/param/loadparm.c                             | 1 +
 libcli/auth/netlogon_creds_cli.c                 | 4 ++--
 source3/param/loadparm.c                         | 1 +
 4 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/docs-xml/smbdotconf/winbind/rejectmd5servers.xml b/docs-xml/smbdotconf/winbind/rejectmd5servers.xml
index 151b4676c57b..3bc4eaf7b02e 100644
--- a/docs-xml/smbdotconf/winbind/rejectmd5servers.xml
+++ b/docs-xml/smbdotconf/winbind/rejectmd5servers.xml
@@ -13,10 +13,13 @@
 	This will prevent downgrade attacks.</para>
 
 	<para>The behavior can be controlled per netbios domain
-	by using 'reject md5 servers:NETBIOSDOMAIN = yes' as option.</para>
+	by using 'reject md5 servers:NETBIOSDOMAIN = no' as option.</para>
+
+	<para>The default changed from 'no' to 'yes, with the patches for CVE-2022-38023,
+	see https://bugzilla.samba.org/show_bug.cgi?id=15240</para>
 
 	<para>This option overrides the <smbconfoption name="require strong key"/> option.</para>
 </description>
 
-<value type="default">no</value>
+<value type="default">yes</value>
 </samba:parameter>
diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c
index d6d845391e6f..e953499efba3 100644
--- a/lib/param/loadparm.c
+++ b/lib/param/loadparm.c
@@ -2666,6 +2666,7 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx)
 	lpcfg_do_global_parameter(lp_ctx, "winbind sealed pipes", "True");
 	lpcfg_do_global_parameter(lp_ctx, "winbind scan trusted domains", "False");
 	lpcfg_do_global_parameter(lp_ctx, "require strong key", "True");
+	lpcfg_do_global_parameter(lp_ctx, "reject md5 servers", "True");
 	lpcfg_do_global_parameter(lp_ctx, "winbindd socket directory", dyn_WINBINDD_SOCKET_DIR);
 	lpcfg_do_global_parameter(lp_ctx, "ntp signd socket directory", dyn_NTP_SIGND_SOCKET_DIR);
 	lpcfg_do_global_parameter_var(lp_ctx, "gpo update command", "%s/samba-gpupdate", dyn_SCRIPTSBINDIR);
diff --git a/libcli/auth/netlogon_creds_cli.c b/libcli/auth/netlogon_creds_cli.c
index 3794d8b6b6ef..ca5619d38703 100644
--- a/libcli/auth/netlogon_creds_cli.c
+++ b/libcli/auth/netlogon_creds_cli.c
@@ -341,8 +341,8 @@ NTSTATUS netlogon_creds_cli_context_global(struct loadparm_context *lp_ctx,
 	const char *client_computer;
 	uint32_t proposed_flags;
 	uint32_t required_flags = 0;
-	bool reject_md5_servers = false;
-	bool require_strong_key = false;
+	bool reject_md5_servers = true;
+	bool require_strong_key = true;
 	int require_sign_or_seal = true;
 	bool seal_secure_channel = true;
 	enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index 21e061939e3e..91747e09eccd 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -664,6 +664,7 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
 	Globals.client_schannel = true;
 	Globals.winbind_sealed_pipes = true;
 	Globals.require_strong_key = true;
+	Globals.reject_md5_servers = true;
 	Globals.server_schannel = true;
 	Globals.read_raw = true;
 	Globals.write_raw = true;
-- 
2.34.1


From 8ccaf7d47ad13313c7a80ac5f857425080d5fbab Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze@samba.org>
Date: Tue, 6 Dec 2022 10:56:29 +0100
Subject: [PATCH 08/30] CVE-2022-38023 s4:rpc_server/netlogon: 'server schannel
 != yes' warning to dcesrv_interface_netlogon_bind

This will simplify the following changes.

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 e060ea5b3edbe3cba492062c9605f88fae212ee0)
---
 source4/rpc_server/netlogon/dcerpc_netlogon.c | 26 +++++++++++--------
 1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
index cfd6d148b0a3..f63c3981f749 100644
--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
@@ -63,6 +63,21 @@
 static NTSTATUS dcesrv_interface_netlogon_bind(struct dcesrv_connection_context *context,
 					       const struct dcesrv_interface *iface)
 {
+	struct loadparm_context *lp_ctx = context->conn->dce_ctx->lp_ctx;
+	int schannel = lpcfg_server_schannel(lp_ctx);
+	bool schannel_global_required = (schannel == true);
+	static bool warned_global_schannel_once = false;
+
+	if (!schannel_global_required && !warned_global_schannel_once) {
+		/*
+		 * We want admins to notice their misconfiguration!
+		 */
+		D_ERR("CVE-2020-1472(ZeroLogon): "
+		      "Please configure 'server schannel = yes' (the default), "
+		      "See https://bugzilla.samba.org/show_bug.cgi?id=14497\n");
+		warned_global_schannel_once = true;
+	}
+
 	return dcesrv_interface_bind_reject_connect(context, iface);
 }
 
@@ -630,7 +645,6 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc
 	enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
 	uint16_t opnum = dce_call->pkt.u.request.opnum;
 	const char *opname = "<unknown>";
-	static bool warned_global_once = false;
 
 	if (opnum < ndr_table_netlogon.num_calls) {
 		opname = ndr_table_netlogon.calls[opnum].name;
@@ -682,16 +696,6 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc
 		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 "
-- 
2.34.1


From 268d1ac2f8ce3fb92a3433ada5e229d23c18c4f6 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze@samba.org>
Date: Mon, 12 Dec 2022 14:03:50 +0100
Subject: [PATCH 09/30] CVE-2022-38023 s4:rpc_server/netlogon: add a lp_ctx
 variable to dcesrv_netr_creds_server_step_check()

This will simplify the following changes.

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 7baabbe9819cd5a2714e7ea4e57a0c23062c0150)
---
 source4/rpc_server/netlogon/dcerpc_netlogon.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
index f63c3981f749..43dcd7271729 100644
--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
@@ -636,8 +636,9 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc
 						    struct netr_Authenticator *return_authenticator,
 						    struct netlogon_creds_CredentialState **creds_out)
 {
+	struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
 	NTSTATUS nt_status;
-	int schannel = lpcfg_server_schannel(dce_call->conn->dce_ctx->lp_ctx);
+	int schannel = lpcfg_server_schannel(lp_ctx);
 	bool schannel_global_required = (schannel == true);
 	bool schannel_required = schannel_global_required;
 	const char *explicit_opt = NULL;
@@ -653,7 +654,7 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc
 	dcesrv_call_auth_info(dce_call, &auth_type, NULL);
 
 	nt_status = schannel_check_creds_state(mem_ctx,
-					       dce_call->conn->dce_ctx->lp_ctx,
+					       lp_ctx,
 					       computer_name,
 					       received_authenticator,
 					       return_authenticator,
@@ -668,7 +669,7 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc
 	 * need the explicit_opt pointer in order to
 	 * adjust the debug messages.
 	 */
-	explicit_opt = lpcfg_get_parametric(dce_call->conn->dce_ctx->lp_ctx,
+	explicit_opt = lpcfg_get_parametric(lp_ctx,
 					    NULL,
 					    "server require schannel",
 					    creds->account_name);
-- 
2.34.1


From e4d8f31296ab5f2013585039a6e47c1a4b826ea8 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze@samba.org>
Date: Mon, 12 Dec 2022 14:03:50 +0100
Subject: [PATCH 10/30] CVE-2022-38023 s4:rpc_server/netlogon: add
 talloc_stackframe() to dcesrv_netr_creds_server_step_check()

This will simplify the following changes.

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 0e6a2ba83ef1be3c6a0f5514c21395121621a145)
---
 source4/rpc_server/netlogon/dcerpc_netlogon.c | 32 +++++++++++--------
 1 file changed, 19 insertions(+), 13 deletions(-)

diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
index 43dcd7271729..95fd1526d5a5 100644
--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
@@ -637,6 +637,7 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc
 						    struct netlogon_creds_CredentialState **creds_out)
 {
 	struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
+	TALLOC_CTX *frame = talloc_stackframe();
 	NTSTATUS nt_status;
 	int schannel = lpcfg_server_schannel(lp_ctx);
 	bool schannel_global_required = (schannel == true);
@@ -680,6 +681,7 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc
 	if (schannel_required) {
 		if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
 			*creds_out = creds;
+			TALLOC_FREE(frame);
 			return NT_STATUS_OK;
 		}
 
@@ -687,13 +689,15 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc
 			"%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));
+			log_escape(frame, creds->account_name),
+			log_escape(frame, 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));
+			"'server require schannel:%s = no' "
+			"might be needed for a legacy client.\n",
+			log_escape(frame, creds->account_name));
 		TALLOC_FREE(creds);
 		ZERO_STRUCTP(return_authenticator);
+		TALLOC_FREE(frame);
 		return NT_STATUS_ACCESS_DENIED;
 	}
 
@@ -702,13 +706,14 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc
 			"%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));
+			log_escape(frame, creds->account_name),
+			log_escape(frame, 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));
+			log_escape(frame, creds->account_name));
 
 		*creds_out = creds;
+		TALLOC_FREE(frame);
 		return NT_STATUS_OK;
 	}
 
@@ -718,24 +723,25 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc
 			 "%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));
+			 log_escape(frame, creds->account_name),
+			 log_escape(frame, 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));
+			 log_escape(frame, 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));
+			log_escape(frame, creds->account_name),
+			log_escape(frame, 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));
+			log_escape(frame, creds->account_name));
 	}
 
 	*creds_out = creds;
+	TALLOC_FREE(frame);
 	return NT_STATUS_OK;
 }
 
-- 
2.34.1


From 4e129119e3a2e1bfca623eb11d721329e53fba17 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze@samba.org>
Date: Wed, 30 Nov 2022 12:37:03 +0100
Subject: [PATCH 11/30] CVE-2022-38023 s4:rpc_server/netlogon: re-order
 checking in dcesrv_netr_creds_server_step_check()

This will simplify the following changes.

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 ec62151a2fb49ecbeaa3bf924f49a956832b735e)
---
 source4/rpc_server/netlogon/dcerpc_netlogon.c | 41 +++++++++----------
 1 file changed, 19 insertions(+), 22 deletions(-)

diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
index 95fd1526d5a5..33063942e161 100644
--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
@@ -678,13 +678,27 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc
 		schannel_required = lp_bool(explicit_opt);
 	}
 
-	if (schannel_required) {
-		if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
-			*creds_out = creds;
-			TALLOC_FREE(frame);
-			return NT_STATUS_OK;
+	if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
+		if (!schannel_required) {
+			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(frame, creds->account_name),
+				log_escape(frame, creds->computer_name));
+		}
+		if (explicit_opt != NULL && !schannel_required) {
+			DBG_ERR("CVE-2020-1472(ZeroLogon): "
+				"Option 'server require schannel:%s = no' not needed!?\n",
+				log_escape(frame, creds->account_name));
 		}
 
+		*creds_out = creds;
+		TALLOC_FREE(frame);
+		return NT_STATUS_OK;
+	}
+
+	if (schannel_required) {
 		DBG_ERR("CVE-2020-1472(ZeroLogon): "
 			"%s request (opnum[%u]) without schannel from "
 			"client_account[%s] client_computer_name[%s]\n",
@@ -701,23 +715,6 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc
 		return NT_STATUS_ACCESS_DENIED;
 	}
 
-	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(frame, creds->account_name),
-			log_escape(frame, creds->computer_name));
-		DBG_ERR("CVE-2020-1472(ZeroLogon): "
-			"Option 'server require schannel:%s = no' not needed!?\n",
-			log_escape(frame, creds->account_name));
-
-		*creds_out = creds;
-		TALLOC_FREE(frame);
-		return NT_STATUS_OK;
-	}
-
-
 	if (explicit_opt != NULL) {
 		DBG_INFO("CVE-2020-1472(ZeroLogon): "
 			 "%s request (opnum[%u]) without schannel from "
-- 
2.34.1


From 200da32d3573912098d68fd9b72f491317feb506 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze@samba.org>
Date: Wed, 30 Nov 2022 12:37:03 +0100
Subject: [PATCH 12/30] CVE-2022-38023 s4:rpc_server/netlogon: improve
 CVE-2020-1472(ZeroLogon) debug messages

In order to avoid generating useless debug messages during make test,
we will use 'CVE_2020_1472:warn_about_unused_debug_level = 3'
and 'CVE_2020_1472:error_debug_level = 2' in order to avoid schannel warnings.

Review with: git show -w

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 16ee03efc194d9c1c2c746f63236b977a419918d)
---
 source4/rpc_server/netlogon/dcerpc_netlogon.c | 147 +++++++++++++-----
 1 file changed, 106 insertions(+), 41 deletions(-)

diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
index 33063942e161..3c77d1302993 100644
--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
@@ -644,15 +644,34 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc
 	bool schannel_required = schannel_global_required;
 	const char *explicit_opt = NULL;
 	struct netlogon_creds_CredentialState *creds = NULL;
+	int CVE_2020_1472_warn_level = lpcfg_parm_int(lp_ctx, NULL,
+		"CVE_2020_1472", "warn_about_unused_debug_level", DBGLVL_ERR);
+	int CVE_2020_1472_error_level = lpcfg_parm_int(lp_ctx, NULL,
+		"CVE_2020_1472", "error_debug_level", DBGLVL_ERR);
+	unsigned int dbg_lvl = DBGLVL_DEBUG;
 	enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
+	enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
 	uint16_t opnum = dce_call->pkt.u.request.opnum;
 	const char *opname = "<unknown>";
+	const char *reason = "<unknown>";
 
 	if (opnum < ndr_table_netlogon.num_calls) {
 		opname = ndr_table_netlogon.calls[opnum].name;
 	}
 
-	dcesrv_call_auth_info(dce_call, &auth_type, NULL);
+	dcesrv_call_auth_info(dce_call, &auth_type, &auth_level);
+
+	if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
+		if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
+			reason = "WITH SEALED";
+		} else if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
+			reason = "WITH SIGNED";
+		} else {
+			smb_panic("Schannel without SIGN/SEAL");
+		}
+	} else {
+		reason = "WITHOUT";
+	}
 
 	nt_status = schannel_check_creds_state(mem_ctx,
 					       lp_ctx,
@@ -679,62 +698,108 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc
 	}
 
 	if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
-		if (!schannel_required) {
-			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(frame, creds->account_name),
-				log_escape(frame, creds->computer_name));
+		nt_status = NT_STATUS_OK;
+
+		if (explicit_opt != NULL && !schannel_required) {
+			dbg_lvl = MIN(dbg_lvl, CVE_2020_1472_warn_level);
+		} else if (!schannel_required) {
+			dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
 		}
+
+		DEBUG(dbg_lvl, (
+		      "CVE-2020-1472(ZeroLogon): "
+		      "%s request (opnum[%u]) %s schannel from "
+		      "client_account[%s] client_computer_name[%s] %s\n",
+		      opname, opnum, reason,
+		      log_escape(frame, creds->account_name),
+		      log_escape(frame, creds->computer_name),
+		      nt_errstr(nt_status)));
+
 		if (explicit_opt != NULL && !schannel_required) {
-			DBG_ERR("CVE-2020-1472(ZeroLogon): "
-				"Option 'server require schannel:%s = no' not needed!?\n",
-				log_escape(frame, creds->account_name));
+			DEBUG(CVE_2020_1472_warn_level, (
+			      "CVE-2020-1472(ZeroLogon): "
+			      "Option 'server require schannel:%s = no' not needed for '%s'!\n",
+			      log_escape(frame, creds->account_name),
+			      log_escape(frame, creds->computer_name)));
 		}
 
 		*creds_out = creds;
 		TALLOC_FREE(frame);
-		return NT_STATUS_OK;
+		return nt_status;
 	}
 
 	if (schannel_required) {
-		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(frame, creds->account_name),
-			log_escape(frame, creds->computer_name));
-		DBG_ERR("CVE-2020-1472(ZeroLogon): Check if option "
-			"'server require schannel:%s = no' "
-			"might be needed for a legacy client.\n",
-			log_escape(frame, creds->account_name));
+		nt_status = NT_STATUS_ACCESS_DENIED;
+
+		if (explicit_opt != NULL) {
+			dbg_lvl = MIN(dbg_lvl, DBGLVL_NOTICE);
+		} else {
+			dbg_lvl = MIN(dbg_lvl, CVE_2020_1472_error_level);
+		}
+
+		DEBUG(dbg_lvl, (
+		      "CVE-2020-1472(ZeroLogon)/CVE-2022-38023: "
+		      "%s request (opnum[%u]) %s schannel from "
+		      "client_account[%s] client_computer_name[%s] %s\n",
+		      opname, opnum, reason,
+		      log_escape(frame, creds->account_name),
+		      log_escape(frame, creds->computer_name),
+		      nt_errstr(nt_status)));
+		if (explicit_opt != NULL) {
+			D_NOTICE("CVE-2020-1472(ZeroLogon): Option "
+				"'server require schannel:%s = yes' "
+				"rejects access for client.\n",
+				log_escape(frame, creds->account_name));
+		} else {
+			DEBUG(CVE_2020_1472_error_level, (
+			      "CVE-2020-1472(ZeroLogon): Check if option "
+			      "'server require schannel:%s = no' "
+			      "might be needed for a legacy client.\n",
+			      log_escape(frame, creds->account_name)));
+		}
 		TALLOC_FREE(creds);
 		ZERO_STRUCTP(return_authenticator);
 		TALLOC_FREE(frame);
-		return NT_STATUS_ACCESS_DENIED;
+		return nt_status;
 	}
 
+	nt_status = 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(frame, creds->account_name),
-			 log_escape(frame, creds->computer_name));
-		DBG_INFO("CVE-2020-1472(ZeroLogon): "
-			 "Option 'server require schannel:%s = no' still needed!\n",
-			 log_escape(frame, creds->account_name));
+		dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
 	} 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(frame, creds->account_name),
-			log_escape(frame, creds->computer_name));
-		DBG_ERR("CVE-2020-1472(ZeroLogon): Check if option "
-			"'server require schannel:%s = no' might be needed!\n",
-			log_escape(frame, creds->account_name));
+		dbg_lvl = MIN(dbg_lvl, CVE_2020_1472_error_level);
+	}
+
+	DEBUG(dbg_lvl, (
+	      "CVE-2020-1472(ZeroLogon)/CVE-2022-38023: "
+	      "%s request (opnum[%u]) %s schannel from "
+	      "client_account[%s] client_computer_name[%s] %s\n",
+	      opname, opnum, reason,
+	      log_escape(frame, creds->account_name),
+	      log_escape(frame, creds->computer_name),
+	      nt_errstr(nt_status)));
+
+	if (explicit_opt != NULL) {
+		D_INFO("CVE-2020-1472(ZeroLogon): Option "
+		       "'server require schannel:%s = no' "
+		       "still needed for '%s'!\n",
+		       log_escape(frame, creds->account_name),
+		       log_escape(frame, creds->computer_name));
+	} else {
+		/*
+		 * admins should set
+		 * server require schannel:COMPUTER$ = no
+		 * in order to avoid the level 0 messages.
+		 * Over time they can switch the global value
+		 * to be strict.
+		 */
+		DEBUG(CVE_2020_1472_error_level, (
+		      "CVE-2020-1472(ZeroLogon): "
+		      "Please use 'server require schannel:%s = no' "
+		      "for '%s' to avoid this warning!\n",
+		      log_escape(frame, creds->account_name),
+		      log_escape(frame, creds->computer_name)));
 	}
 
 	*creds_out = creds;
-- 
2.34.1


From 0038d0302c807bc76b073de3aeed13a29c1fc458 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze@samba.org>
Date: Wed, 30 Nov 2022 12:26:01 +0100
Subject: [PATCH 13/30] CVE-2022-38023 selftest:Samba4: avoid global 'server
 schannel = auto'

Instead of using the generic deprecated option use the specific
server require schannel:COMPUTERACCOUNT = no in order to allow
legacy tests for pass.

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 63c96ea6c02981795e67336401143f2a8836992c)
---
 selftest/target/Samba4.pm | 40 ++++++++++++++++++++++++++++++++++++---
 1 file changed, 37 insertions(+), 3 deletions(-)

diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm
index b004042738a7..d26022466c66 100755
--- a/selftest/target/Samba4.pm
+++ b/selftest/target/Samba4.pm
@@ -1616,10 +1616,27 @@ sub provision_ad_dc_ntvfs($$$)
 	dsdb event notification = true
 	dsdb password event notification = true
 	dsdb group change notification = true
-	server schannel = auto
 	# override the new SMB2 only default
 	client min protocol = CORE
 	server min protocol = LANMAN1
+
+	CVE_2020_1472:warn_about_unused_debug_level = 3
+	server require schannel:schannel0\$ = no
+	server require schannel:schannel1\$ = no
+	server require schannel:schannel2\$ = no
+	server require schannel:schannel3\$ = no
+	server require schannel:schannel4\$ = no
+	server require schannel:schannel5\$ = no
+	server require schannel:schannel6\$ = no
+	server require schannel:schannel7\$ = no
+	server require schannel:schannel8\$ = no
+	server require schannel:schannel9\$ = no
+	server require schannel:schannel10\$ = no
+	server require schannel:schannel11\$ = no
+	server require schannel:torturetest\$ = no
+
+	# needed for 'samba.tests.auth_log' tests
+	server require schannel:LOCALDC\$ = no
 	";
 	push (@{$extra_provision_options}, "--use-ntvfs");
 	my $ret = $self->provision($prefix,
@@ -1968,8 +1985,22 @@ sub provision_ad_dc($$$$$$$)
 	lpq cache time = 0
 	print notify backchannel = yes
 
-	server schannel = auto
-        auth event notification = true
+	CVE_2020_1472:warn_about_unused_debug_level = 3
+	server require schannel:schannel0\$ = no
+	server require schannel:schannel1\$ = no
+	server require schannel:schannel2\$ = no
+	server require schannel:schannel3\$ = no
+	server require schannel:schannel4\$ = no
+	server require schannel:schannel5\$ = no
+	server require schannel:schannel6\$ = no
+	server require schannel:schannel7\$ = no
+	server require schannel:schannel8\$ = no
+	server require schannel:schannel9\$ = no
+	server require schannel:schannel10\$ = no
+	server require schannel:schannel11\$ = no
+	server require schannel:torturetest\$ = no
+
+	auth event notification = true
 	dsdb event notification = true
 	dsdb password event notification = true
 	dsdb group change notification = true
@@ -2658,6 +2689,9 @@ sub setup_ad_dc_smb1
 [global]
 	client min protocol = CORE
 	server min protocol = LANMAN1
+
+	# needed for 'samba.tests.auth_log' tests
+	server require schannel:ADDCSMB1\$ = no
 ";
 	return _setup_ad_dc($self, $path, $conf_opts, "addcsmb1", "addom2.samba.example.com");
 }
-- 
2.34.1


From 76855044472bf75f75a204e0fe411b457478363c Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze@samba.org>
Date: Mon, 28 Nov 2022 15:02:13 +0100
Subject: [PATCH 14/30] CVE-2022-38023 s4:torture: use
 NETLOGON_NEG_SUPPORTS_AES by default

For generic tests we should use the best available features.

And AES will be required by default soon.

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 cfd55a22cda113fbb2bfa373b54091dde1ea6e66)
---
 source4/torture/ntp/ntp_signd.c |  2 +-
 source4/torture/rpc/lsa.c       |  4 ++--
 source4/torture/rpc/netlogon.c  | 24 ++++++++++++------------
 source4/torture/rpc/samba3rpc.c | 15 ++++++++++++---
 4 files changed, 27 insertions(+), 18 deletions(-)

diff --git a/source4/torture/ntp/ntp_signd.c b/source4/torture/ntp/ntp_signd.c
index 124c9604871b..6d482bfdee16 100644
--- a/source4/torture/ntp/ntp_signd.c
+++ b/source4/torture/ntp/ntp_signd.c
@@ -70,7 +70,7 @@ static bool test_ntp_signd(struct torture_context *tctx,
 	uint32_t rid;
 	const char *machine_name;
 	const struct samr_Password *pwhash = cli_credentials_get_nt_hash(credentials, mem_ctx);
-	uint32_t negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
+	uint32_t negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
 
 	struct sign_request sign_req;
 	struct signed_reply signed_reply;
diff --git a/source4/torture/rpc/lsa.c b/source4/torture/rpc/lsa.c
index d430ee571081..d22546862d5b 100644
--- a/source4/torture/rpc/lsa.c
+++ b/source4/torture/rpc/lsa.c
@@ -4408,7 +4408,7 @@ static bool check_dom_trust_pw(struct dcerpc_pipe *p,
 	torture_assert_ntstatus_ok(tctx, status, "dcerpc_pipe_connect_b");
 
 	ok = check_pw_with_ServerAuthenticate3(p1, tctx,
-					       NETLOGON_NEG_AUTH2_ADS_FLAGS,
+					       NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES,
 					       server_name,
 					       incoming_creds, &creds);
 	torture_assert_int_equal(tctx, ok, expected_result,
@@ -4505,7 +4505,7 @@ static bool check_dom_trust_pw(struct dcerpc_pipe *p,
 	torture_assert_ntstatus_ok(tctx, status, "dcerpc_pipe_connect_b");
 
 	ok = check_pw_with_ServerAuthenticate3(p2, tctx,
-					       NETLOGON_NEG_AUTH2_ADS_FLAGS,
+					       NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES,
 					       server_name,
 					       incoming_creds, &creds);
 	torture_assert(tctx, ok, "check_pw_with_ServerAuthenticate3 with changed password");
diff --git a/source4/torture/rpc/netlogon.c b/source4/torture/rpc/netlogon.c
index 11f950d3aab4..2803dd13b467 100644
--- a/source4/torture/rpc/netlogon.c
+++ b/source4/torture/rpc/netlogon.c
@@ -191,7 +191,7 @@ bool test_SetupCredentials(struct dcerpc_pipe *p, struct torture_context *tctx,
 
 	/* This allows the tests to continue against the more fussy windows 2008 */
 	if (NT_STATUS_EQUAL(a.out.result, NT_STATUS_DOWNGRADE_DETECTED)) {
-		return test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
+		return test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES,
 					      credentials,
 					      cli_credentials_get_secure_channel_type(credentials),
 					      creds_out);
@@ -431,7 +431,7 @@ bool test_SetupCredentialsDowngrade(struct torture_context *tctx,
 		"ServerAuthenticate3 failed");
 	torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_DOWNGRADE_DETECTED, "ServerAuthenticate3 should have failed");
 
-	negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
+	negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
 	creds = netlogon_creds_client_init(tctx, a.in.account_name,
 					   a.in.computer_name,
 					   a.in.secure_channel_type,
@@ -498,7 +498,7 @@ static bool test_ServerReqChallenge(
 	const char *machine_name;
 	struct dcerpc_binding_handle *b = p->binding_handle;
 	struct netr_ServerAuthenticate2 a;
-	uint32_t in_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
+	uint32_t in_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
 	uint32_t out_negotiate_flags = 0;
 	const struct samr_Password *mach_password = NULL;
 	enum netr_SchannelType sec_chan_type = 0;
@@ -570,7 +570,7 @@ static bool test_ServerReqChallenge_zero_challenge(
 	const char *machine_name;
 	struct dcerpc_binding_handle *b = p->binding_handle;
 	struct netr_ServerAuthenticate2 a;
-	uint32_t in_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
+	uint32_t in_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
 	uint32_t out_negotiate_flags = 0;
 	const struct samr_Password *mach_password = NULL;
 	enum netr_SchannelType sec_chan_type = 0;
@@ -647,7 +647,7 @@ static bool test_ServerReqChallenge_5_repeats(
 	const char *machine_name;
 	struct dcerpc_binding_handle *b = p->binding_handle;
 	struct netr_ServerAuthenticate2 a;
-	uint32_t in_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
+	uint32_t in_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
 	uint32_t out_negotiate_flags = 0;
 	const struct samr_Password *mach_password = NULL;
 	enum netr_SchannelType sec_chan_type = 0;
@@ -731,7 +731,7 @@ static bool test_ServerReqChallenge_4_repeats(
 	const char *machine_name;
 	struct dcerpc_binding_handle *b = p->binding_handle;
 	struct netr_ServerAuthenticate2 a;
-	uint32_t in_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
+	uint32_t in_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
 	uint32_t out_negotiate_flags = 0;
 	const struct samr_Password *mach_password = NULL;
 	enum netr_SchannelType sec_chan_type = 0;
@@ -1527,7 +1527,7 @@ static bool test_SetPassword2_all_zeros(
 	struct netr_CryptPassword new_password;
 	struct dcerpc_pipe *p = NULL;
 	struct dcerpc_binding_handle *b = NULL;
-	uint32_t flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
+	uint32_t flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; /* no AES desired here */
 
 	if (!test_SetupCredentials2(
 		p1,
@@ -1603,7 +1603,7 @@ static bool test_SetPassword2_maximum_length_password(
 	struct netr_CryptPassword new_password;
 	struct dcerpc_pipe *p = NULL;
 	struct dcerpc_binding_handle *b = NULL;
-	uint32_t flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
+	uint32_t flags = NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
 	DATA_BLOB new_random_pass = data_blob_null;
 
 	if (!test_SetupCredentials2(
@@ -1686,7 +1686,7 @@ static bool test_SetPassword2_all_zero_password(
 	struct netr_CryptPassword new_password;
 	struct dcerpc_pipe *p = NULL;
 	struct dcerpc_binding_handle *b = NULL;
-	uint32_t flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
+	uint32_t flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; /* no AES desired here */
 
 	if (!test_SetupCredentials2(
 		p1,
@@ -4046,7 +4046,7 @@ static bool test_netr_GetForestTrustInformation(struct torture_context *tctx,
 	struct dcerpc_pipe *p = NULL;
 	struct dcerpc_binding_handle *b = NULL;
 
-	if (!test_SetupCredentials3(p1, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
+	if (!test_SetupCredentials3(p1, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES,
 				    machine_credentials, &creds)) {
 		return false;
 	}
@@ -4985,7 +4985,7 @@ static bool test_GetDomainInfo(struct torture_context *tctx,
 
 	torture_comment(tctx, "Testing netr_LogonGetDomainInfo\n");
 
-	if (!test_SetupCredentials3(p1, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
+	if (!test_SetupCredentials3(p1, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES,
 				    machine_credentials, &creds)) {
 		return false;
 	}
@@ -5560,7 +5560,7 @@ static bool test_GetDomainInfo_async(struct torture_context *tctx,
 
 	torture_comment(tctx, "Testing netr_LogonGetDomainInfo - async count %d\n", ASYNC_COUNT);
 
-	if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
+	if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES,
 				    machine_credentials, &creds)) {
 		return false;
 	}
diff --git a/source4/torture/rpc/samba3rpc.c b/source4/torture/rpc/samba3rpc.c
index ff5dc1d68003..ee8dac67dfa8 100644
--- a/source4/torture/rpc/samba3rpc.c
+++ b/source4/torture/rpc/samba3rpc.c
@@ -1071,7 +1071,7 @@ static bool auth2(struct torture_context *tctx,
 		goto done;
 	}
 
-	negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
+	negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
 	E_md4hash(cli_credentials_get_password(wks_cred), mach_pw.hash);
 
 	a.in.server_name = talloc_asprintf(
@@ -1260,10 +1260,19 @@ static bool schan(struct torture_context *tctx,
 		E_md4hash(cli_credentials_get_password(user_creds),
 			  pinfo.ntpassword.hash);
 
-		netlogon_creds_arcfour_crypt(creds_state, pinfo.ntpassword.hash, 16);
-
 		logon.password = &pinfo;
 
+		/*
+		 * We don't use this here:
+		 *
+		 * netlogon_creds_encrypt_samlogon_logon(creds_state,
+		 *                                       NetlogonInteractiveInformation,
+		 *                                       &logon);
+		 *
+		 * in order to detect bugs
+		 */
+		netlogon_creds_aes_encrypt(creds_state, pinfo.ntpassword.hash, 16);
+
 		r.in.logon_level = NetlogonInteractiveInformation;
 		r.in.logon = &logon;
 		r.out.return_authenticator = &return_authenticator;
-- 
2.34.1


From 5a6eba6e6bf3cd87a5875634d82335b216bf1069 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze@samba.org>
Date: Fri, 25 Nov 2022 09:54:17 +0100
Subject: [PATCH 15/30] CVE-2022-38023 s4:rpc_server/netlogon: split out
 dcesrv_netr_ServerAuthenticate3_check_downgrade()

We'll soon make it possible to use 'reject md5 servers:CLIENTACCOUNT$ = no',
which means we'll need the downgrade detection in more places.

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 b6339fd1dcbe903e73efeea074ab0bd04ef83561)
---
 source4/rpc_server/netlogon/dcerpc_netlogon.c | 114 ++++++++++--------
 1 file changed, 67 insertions(+), 47 deletions(-)

diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
index 3c77d1302993..87e4bbe00f2d 100644
--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
@@ -125,6 +125,67 @@ static NTSTATUS dcesrv_netr_ServerReqChallenge(struct dcesrv_call_state *dce_cal
 	return NT_STATUS_OK;
 }
 
+static NTSTATUS dcesrv_netr_ServerAuthenticate3_check_downgrade(
+	struct dcesrv_call_state *dce_call,
+	struct netr_ServerAuthenticate3 *r,
+	struct netlogon_server_pipe_state *pipe_state,
+	uint32_t negotiate_flags,
+	NTSTATUS orig_status)
+{
+	struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
+	bool allow_nt4_crypto = lpcfg_allow_nt4_crypto(lp_ctx);
+	bool reject_des_client = !allow_nt4_crypto;
+	bool reject_md5_client = lpcfg_reject_md5_clients(lp_ctx);
+
+	if (negotiate_flags & NETLOGON_NEG_STRONG_KEYS) {
+		reject_des_client = false;
+	}
+
+	if (negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
+		reject_des_client = false;
+		reject_md5_client = false;
+	}
+
+	if (reject_des_client || reject_md5_client) {
+		/*
+		 * Here we match Windows 2012 and return no flags.
+		 */
+		*r->out.negotiate_flags = 0;
+		return NT_STATUS_DOWNGRADE_DETECTED;
+	}
+
+	/*
+	 * This talloc_free is important to prevent re-use of the
+	 * challenge.  We have to delay it this far due to NETApp
+	 * servers per:
+	 * https://bugzilla.samba.org/show_bug.cgi?id=11291
+	 */
+	TALLOC_FREE(pipe_state);
+
+	/*
+	 * At this point we must also cleanup the TDB cache
+	 * entry, if we fail the client needs to call
+	 * netr_ServerReqChallenge again.
+	 *
+	 * Note: this handles a non existing record just fine,
+	 * the r->in.computer_name might not be the one used
+	 * in netr_ServerReqChallenge(), but we are trying to
+	 * just tidy up the normal case to prevent re-use.
+	 */
+	schannel_delete_challenge(dce_call->conn->dce_ctx->lp_ctx,
+				  r->in.computer_name);
+
+	/*
+	 * According to Microsoft (see bugid #6099)
+	 * Windows 7 looks at the negotiate_flags
+	 * returned in this structure *even if the
+	 * call fails with access denied!
+	 */
+	*r->out.negotiate_flags = negotiate_flags;
+
+	return orig_status;
+}
+
 /*
  * Do the actual processing of a netr_ServerAuthenticate3 message.
  * called from dcesrv_netr_ServerAuthenticate3, which handles the logging.
@@ -152,11 +213,9 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
 			       "objectSid", "samAccountName", NULL};
 	uint32_t server_flags = 0;
 	uint32_t negotiate_flags = 0;
-	bool allow_nt4_crypto = lpcfg_allow_nt4_crypto(dce_call->conn->dce_ctx->lp_ctx);
-	bool reject_des_client = !allow_nt4_crypto;
-	bool reject_md5_client = lpcfg_reject_md5_clients(dce_call->conn->dce_ctx->lp_ctx);
 
 	ZERO_STRUCTP(r->out.return_credentials);
+	*r->out.negotiate_flags = 0;
 	*r->out.rid = 0;
 
 	pipe_state = dcesrv_iface_state_find_conn(dce_call,
@@ -243,52 +302,13 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
 
 	negotiate_flags = *r->in.negotiate_flags & server_flags;
 
-	if (negotiate_flags & NETLOGON_NEG_STRONG_KEYS) {
-		reject_des_client = false;
-	}
-
-	if (negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
-		reject_des_client = false;
-		reject_md5_client = false;
-	}
-
-	if (reject_des_client || reject_md5_client) {
-		/*
-		 * Here we match Windows 2012 and return no flags.
-		 */
-		*r->out.negotiate_flags = 0;
-		return NT_STATUS_DOWNGRADE_DETECTED;
+	nt_status = dcesrv_netr_ServerAuthenticate3_check_downgrade(
+			dce_call, r, pipe_state, negotiate_flags,
+			NT_STATUS_OK);
+	if (!NT_STATUS_IS_OK(nt_status)) {
+		return nt_status;
 	}
 
-	/*
-	 * This talloc_free is important to prevent re-use of the
-	 * challenge.  We have to delay it this far due to NETApp
-	 * servers per:
-	 * https://bugzilla.samba.org/show_bug.cgi?id=11291
-	 */
-	TALLOC_FREE(pipe_state);
-
-	/*
-	 * At this point we must also cleanup the TDB cache
-	 * entry, if we fail the client needs to call
-	 * netr_ServerReqChallenge again.
-	 *
-	 * Note: this handles a non existing record just fine,
-	 * the r->in.computer_name might not be the one used
-	 * in netr_ServerReqChallenge(), but we are trying to
-	 * just tidy up the normal case to prevent re-use.
-	 */
-	schannel_delete_challenge(dce_call->conn->dce_ctx->lp_ctx,
-				  r->in.computer_name);
-
-	/*
-	 * According to Microsoft (see bugid #6099)
-	 * Windows 7 looks at the negotiate_flags
-	 * returned in this structure *even if the
-	 * call fails with access denied!
-	 */
-	*r->out.negotiate_flags = negotiate_flags;
-
 	switch (r->in.secure_channel_type) {
 	case SEC_CHAN_WKSTA:
 	case SEC_CHAN_DNS_DOMAIN:
-- 
2.34.1


From 267a886bcdf3b502d83a3470e9d5b51191210153 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze@samba.org>
Date: Fri, 25 Nov 2022 10:10:33 +0100
Subject: [PATCH 16/30] CVE-2022-38023 s4:rpc_server/netlogon: require aes if
 weak crypto is disabled

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 4c7f84798acd1e3218209d66d1a92e9f42954d51)
---
 source4/rpc_server/netlogon/dcerpc_netlogon.c | 9 +++++++++
 source4/torture/rpc/netlogon_crypto.c         | 2 +-
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
index 87e4bbe00f2d..4141cc40687f 100644
--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
@@ -137,6 +137,15 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_check_downgrade(
 	bool reject_des_client = !allow_nt4_crypto;
 	bool reject_md5_client = lpcfg_reject_md5_clients(lp_ctx);
 
+	/*
+	 * If weak cryto is disabled, do not announce that we support RC4.
+	 */
+	if (lpcfg_weak_crypto(lp_ctx) == SAMBA_WEAK_CRYPTO_DISALLOWED) {
+		/* Without RC4 and DES we require AES */
+		reject_des_client = true;
+		reject_md5_client = true;
+	}
+
 	if (negotiate_flags & NETLOGON_NEG_STRONG_KEYS) {
 		reject_des_client = false;
 	}
diff --git a/source4/torture/rpc/netlogon_crypto.c b/source4/torture/rpc/netlogon_crypto.c
index 05beb2b77b3b..85844604ee27 100644
--- a/source4/torture/rpc/netlogon_crypto.c
+++ b/source4/torture/rpc/netlogon_crypto.c
@@ -150,7 +150,7 @@ static bool test_ServerAuth3Crypto(struct dcerpc_pipe *p,
 	    force_client_rc4) {
 		torture_assert_ntstatus_equal(tctx,
 					      a.out.result,
-					      NT_STATUS_ACCESS_DENIED,
+					      NT_STATUS_DOWNGRADE_DETECTED,
 					      "Unexpected status code");
 		return false;
 	}
-- 
2.34.1


From 2b4abfc0bf48e89cd93f97f9afcff23e932f427b Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze@samba.org>
Date: Thu, 24 Nov 2022 18:26:18 +0100
Subject: [PATCH 17/30] CVE-2022-38023 docs-xml/smbdotconf: change 'reject md5
 clients' default to yes

AES is supported by Windows Server >= 2008R2, Windows (Client) >= 7 and Samba >= 4.0,
so there's no reason to allow md5 clients by default.
However some third party domain members may need it.

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 c8e53394b98b128ed460a6111faf05dfbad980d1)
---
 docs-xml/smbdotconf/logon/rejectmd5clients.xml | 11 ++++++++---
 lib/param/loadparm.c                           |  1 +
 selftest/target/Samba4.pm                      |  4 ++++
 source3/param/loadparm.c                       |  1 +
 4 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/docs-xml/smbdotconf/logon/rejectmd5clients.xml b/docs-xml/smbdotconf/logon/rejectmd5clients.xml
index 0bb9f6f6c8ec..edcbe02e99a3 100644
--- a/docs-xml/smbdotconf/logon/rejectmd5clients.xml
+++ b/docs-xml/smbdotconf/logon/rejectmd5clients.xml
@@ -7,11 +7,16 @@
 	only in 'active directory domain controller' mode), will
 	reject clients which does not support NETLOGON_NEG_SUPPORTS_AES.</para>
 
-	<para>You can set this to yes if all domain members support aes.
-	This will prevent downgrade attacks.</para>
+	<para>Support for NETLOGON_NEG_SUPPORTS_AES was added in Windows
+	starting with Server 2008R2 and Windows 7, it's available in Samba
+	starting with 4.0, however third party domain members like NetApp ONTAP
+	still uses RC4 (HMAC-MD5), see https://www.samba.org/samba/security/CVE-2022-38023.html for more details.</para>
+
+	<para>The default changed from 'no' to 'yes', with the patches for CVE-2022-38023,
+	see https://bugzilla.samba.org/show_bug.cgi?id=15240</para>
 
 	<para>This option overrides the 'allow nt4 crypto' option.</para>
 </description>
 
-<value type="default">no</value>
+<value type="default">yes</value>
 </samba:parameter>
diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c
index e953499efba3..2b644ee97c02 100644
--- a/lib/param/loadparm.c
+++ b/lib/param/loadparm.c
@@ -2725,6 +2725,7 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx)
 	lpcfg_do_global_parameter(lp_ctx, "winbind nss info", "template");
 
 	lpcfg_do_global_parameter(lp_ctx, "server schannel", "True");
+	lpcfg_do_global_parameter(lp_ctx, "reject md5 clients", "True");
 
 	lpcfg_do_global_parameter(lp_ctx, "short preserve case", "True");
 
diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm
index d26022466c66..fb63bbeff059 100755
--- a/selftest/target/Samba4.pm
+++ b/selftest/target/Samba4.pm
@@ -1620,6 +1620,8 @@ sub provision_ad_dc_ntvfs($$$)
 	client min protocol = CORE
 	server min protocol = LANMAN1
 
+	reject md5 clients = no
+
 	CVE_2020_1472:warn_about_unused_debug_level = 3
 	server require schannel:schannel0\$ = no
 	server require schannel:schannel1\$ = no
@@ -1985,6 +1987,8 @@ sub provision_ad_dc($$$$$$$)
 	lpq cache time = 0
 	print notify backchannel = yes
 
+	reject md5 clients = no
+
 	CVE_2020_1472:warn_about_unused_debug_level = 3
 	server require schannel:schannel0\$ = no
 	server require schannel:schannel1\$ = no
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index 91747e09eccd..28ce4de6dd67 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -666,6 +666,7 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
 	Globals.require_strong_key = true;
 	Globals.reject_md5_servers = true;
 	Globals.server_schannel = true;
+	Globals.reject_md5_clients = true;
 	Globals.read_raw = true;
 	Globals.write_raw = true;
 	Globals.null_passwords = false;
-- 
2.34.1


From d05bde2dfe40483b9f31a94a8d475f628f7aa1e3 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze@samba.org>
Date: Fri, 25 Nov 2022 10:31:08 +0100
Subject: [PATCH 18/30] CVE-2022-38023 s4:rpc_server/netlogon: defer downgrade
 check until we found the account in our SAM

We'll soon make it possible to use 'reject md5 servers:CLIENTACCOUNT$ = no',
which means we'll need use the account name from our SAM.

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 b09f51eefc311bbb1525efd1dc7b9a837f7ec3c2)
---
 source4/rpc_server/netlogon/dcerpc_netlogon.c | 76 +++++++++++++------
 1 file changed, 53 insertions(+), 23 deletions(-)

diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
index 4141cc40687f..e39a530fd7f5 100644
--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
@@ -311,13 +311,6 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
 
 	negotiate_flags = *r->in.negotiate_flags & server_flags;
 
-	nt_status = dcesrv_netr_ServerAuthenticate3_check_downgrade(
-			dce_call, r, pipe_state, negotiate_flags,
-			NT_STATUS_OK);
-	if (!NT_STATUS_IS_OK(nt_status)) {
-		return nt_status;
-	}
-
 	switch (r->in.secure_channel_type) {
 	case SEC_CHAN_WKSTA:
 	case SEC_CHAN_DNS_DOMAIN:
@@ -326,16 +319,22 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
 	case SEC_CHAN_RODC:
 		break;
 	case SEC_CHAN_NULL:
-		return NT_STATUS_INVALID_PARAMETER;
+		return dcesrv_netr_ServerAuthenticate3_check_downgrade(
+				dce_call, r, pipe_state, negotiate_flags,
+				NT_STATUS_INVALID_PARAMETER);
 	default:
 		DEBUG(1, ("Client asked for an invalid secure channel type: %d\n",
 			  r->in.secure_channel_type));
-		return NT_STATUS_INVALID_PARAMETER;
+		return dcesrv_netr_ServerAuthenticate3_check_downgrade(
+				dce_call, r, pipe_state, negotiate_flags,
+				NT_STATUS_INVALID_PARAMETER);
 	}
 
 	sam_ctx = dcesrv_samdb_connect_as_system(mem_ctx, dce_call);
 	if (sam_ctx == NULL) {
-		return NT_STATUS_INVALID_SYSTEM_SERVICE;
+		return dcesrv_netr_ServerAuthenticate3_check_downgrade(
+				dce_call, r, pipe_state, negotiate_flags,
+				NT_STATUS_INVALID_SYSTEM_SERVICE);
 	}
 
 	if (r->in.secure_channel_type == SEC_CHAN_DOMAIN ||
@@ -364,16 +363,22 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
 		encoded_name = ldb_binary_encode_string(mem_ctx,
 							r->in.account_name);
 		if (encoded_name == NULL) {
-			return NT_STATUS_NO_MEMORY;
+			return dcesrv_netr_ServerAuthenticate3_check_downgrade(
+				dce_call, r, pipe_state, negotiate_flags,
+				NT_STATUS_NO_MEMORY);
 		}
 
 		len = strlen(encoded_name);
 		if (len < 2) {
-			return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
+			return dcesrv_netr_ServerAuthenticate3_check_downgrade(
+				dce_call, r, pipe_state, negotiate_flags,
+				NT_STATUS_NO_TRUST_SAM_ACCOUNT);
 		}
 
 		if (require_trailer && encoded_name[len - 1] != trailer) {
-			return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
+			return dcesrv_netr_ServerAuthenticate3_check_downgrade(
+				dce_call, r, pipe_state, negotiate_flags,
+				NT_STATUS_NO_TRUST_SAM_ACCOUNT);
 		}
 		encoded_name[len - 1] = '\0';
 
@@ -391,30 +396,42 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
 				  "but there's no tdo for [%s] => [%s] \n",
 				  log_escape(mem_ctx, r->in.account_name),
 				  encoded_name));
-			return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
+			return dcesrv_netr_ServerAuthenticate3_check_downgrade(
+				dce_call, r, pipe_state, negotiate_flags,
+				NT_STATUS_NO_TRUST_SAM_ACCOUNT);
 		}
 		if (!NT_STATUS_IS_OK(nt_status)) {
-			return nt_status;
+			return dcesrv_netr_ServerAuthenticate3_check_downgrade(
+				dce_call, r, pipe_state, negotiate_flags,
+				nt_status);
 		}
 
 		nt_status = dsdb_trust_get_incoming_passwords(tdo_msg, mem_ctx,
 							      &curNtHash,
 							      &prevNtHash);
 		if (NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCOUNT_DISABLED)) {
-			return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
+			return dcesrv_netr_ServerAuthenticate3_check_downgrade(
+				dce_call, r, pipe_state, negotiate_flags,
+				NT_STATUS_NO_TRUST_SAM_ACCOUNT);
 		}
 		if (!NT_STATUS_IS_OK(nt_status)) {
-			return nt_status;
+			return dcesrv_netr_ServerAuthenticate3_check_downgrade(
+				dce_call, r, pipe_state, negotiate_flags,
+				nt_status);
 		}
 
 		flatname = ldb_msg_find_attr_as_string(tdo_msg, "flatName", NULL);
 		if (flatname == NULL) {
-			return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
+			return dcesrv_netr_ServerAuthenticate3_check_downgrade(
+				dce_call, r, pipe_state, negotiate_flags,
+				NT_STATUS_NO_TRUST_SAM_ACCOUNT);
 		}
 
 		*trust_account_for_search = talloc_asprintf(mem_ctx, "%s$", flatname);
 		if (*trust_account_for_search == NULL) {
-			return NT_STATUS_NO_MEMORY;
+			return dcesrv_netr_ServerAuthenticate3_check_downgrade(
+				dce_call, r, pipe_state, negotiate_flags,
+				NT_STATUS_NO_MEMORY);
 		}
 	} else {
 		*trust_account_for_search = r->in.account_name;
@@ -429,14 +446,18 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
 	if (num_records == 0) {
 		DEBUG(3,("Couldn't find user [%s] in samdb.\n",
 			 log_escape(mem_ctx, r->in.account_name)));
-		return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
+		return dcesrv_netr_ServerAuthenticate3_check_downgrade(
+				dce_call, r, pipe_state, negotiate_flags,
+				NT_STATUS_NO_TRUST_SAM_ACCOUNT);
 	}
 
 	if (num_records > 1) {
 		DEBUG(0,("Found %d records matching user [%s]\n",
 			 num_records,
 			 log_escape(mem_ctx, r->in.account_name)));
-		return NT_STATUS_INTERNAL_DB_CORRUPTION;
+		return dcesrv_netr_ServerAuthenticate3_check_downgrade(
+				dce_call, r, pipe_state, negotiate_flags,
+				NT_STATUS_INTERNAL_DB_CORRUPTION);
 	}
 
 	*trust_account_in_db = ldb_msg_find_attr_as_string(msgs[0],
@@ -445,9 +466,18 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
 	if (*trust_account_in_db == NULL) {
 		DEBUG(0,("No samAccountName returned in record matching user [%s]\n",
 			 r->in.account_name));
-		return NT_STATUS_INTERNAL_DB_CORRUPTION;
+		return dcesrv_netr_ServerAuthenticate3_check_downgrade(
+				dce_call, r, pipe_state, negotiate_flags,
+				NT_STATUS_INTERNAL_DB_CORRUPTION);
 	}
-	
+
+	nt_status = dcesrv_netr_ServerAuthenticate3_check_downgrade(
+			dce_call, r, pipe_state, negotiate_flags,
+			NT_STATUS_OK);
+	if (!NT_STATUS_IS_OK(nt_status)) {
+		return nt_status;
+	}
+
 	user_account_control = ldb_msg_find_attr_as_uint(msgs[0], "userAccountControl", 0);
 
 	if (user_account_control & UF_ACCOUNTDISABLE) {
-- 
2.34.1


From 88c10a23f06376605a29fc9ddb7737868ffad916 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze@samba.org>
Date: Fri, 25 Nov 2022 13:13:36 +0100
Subject: [PATCH 19/30] CVE-2022-38023 s4:rpc_server/netlogon: add 'server
 reject md5 schannel:COMPUTERACCOUNT = no' and 'allow nt4
 crypto:COMPUTERACCOUNT = yes'

This makes it more flexible when we change the global default to
'reject md5 servers = yes'.

'allow nt4 crypto = no' is already the default.

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 69b36541606d7064de9648cd54b35adfdf8f0e8f)
---
 source4/rpc_server/netlogon/dcerpc_netlogon.c | 58 ++++++++++++++++++-
 1 file changed, 55 insertions(+), 3 deletions(-)

diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
index e39a530fd7f5..f303dc00ada2 100644
--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
@@ -130,12 +130,48 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_check_downgrade(
 	struct netr_ServerAuthenticate3 *r,
 	struct netlogon_server_pipe_state *pipe_state,
 	uint32_t negotiate_flags,
+	const char *trust_account_in_db,
 	NTSTATUS orig_status)
 {
 	struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
-	bool allow_nt4_crypto = lpcfg_allow_nt4_crypto(lp_ctx);
-	bool reject_des_client = !allow_nt4_crypto;
-	bool reject_md5_client = lpcfg_reject_md5_clients(lp_ctx);
+	bool global_allow_nt4_crypto = lpcfg_allow_nt4_crypto(lp_ctx);
+	bool account_allow_nt4_crypto = global_allow_nt4_crypto;
+	const char *explicit_nt4_opt = NULL;
+	bool global_reject_md5_client = lpcfg_reject_md5_clients(lp_ctx);
+	bool account_reject_md5_client = global_reject_md5_client;
+	const char *explicit_md5_opt = NULL;
+	bool reject_des_client;
+	bool allow_nt4_crypto;
+	bool reject_md5_client;
+
+	/*
+	 * We don't use lpcfg_parm_bool(), as we
+	 * need the explicit_opt pointer in order to
+	 * adjust the debug messages.
+	 */
+
+	if (trust_account_in_db != NULL) {
+		explicit_nt4_opt = lpcfg_get_parametric(lp_ctx,
+							NULL,
+							"allow nt4 crypto",
+							trust_account_in_db);
+	}
+	if (explicit_nt4_opt != NULL) {
+		account_allow_nt4_crypto = lp_bool(explicit_nt4_opt);
+	}
+	allow_nt4_crypto = account_allow_nt4_crypto;
+	if (trust_account_in_db != NULL) {
+		explicit_md5_opt = lpcfg_get_parametric(lp_ctx,
+							NULL,
+							"server reject md5 schannel",
+							trust_account_in_db);
+	}
+	if (explicit_md5_opt != NULL) {
+		account_reject_md5_client = lp_bool(explicit_md5_opt);
+	}
+	reject_md5_client = account_reject_md5_client;
+
+	reject_des_client = !allow_nt4_crypto;
 
 	/*
 	 * If weak cryto is disabled, do not announce that we support RC4.
@@ -321,12 +357,14 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
 	case SEC_CHAN_NULL:
 		return dcesrv_netr_ServerAuthenticate3_check_downgrade(
 				dce_call, r, pipe_state, negotiate_flags,
+				NULL, /* trust_account_in_db */
 				NT_STATUS_INVALID_PARAMETER);
 	default:
 		DEBUG(1, ("Client asked for an invalid secure channel type: %d\n",
 			  r->in.secure_channel_type));
 		return dcesrv_netr_ServerAuthenticate3_check_downgrade(
 				dce_call, r, pipe_state, negotiate_flags,
+				NULL, /* trust_account_in_db */
 				NT_STATUS_INVALID_PARAMETER);
 	}
 
@@ -334,6 +372,7 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
 	if (sam_ctx == NULL) {
 		return dcesrv_netr_ServerAuthenticate3_check_downgrade(
 				dce_call, r, pipe_state, negotiate_flags,
+				NULL, /* trust_account_in_db */
 				NT_STATUS_INVALID_SYSTEM_SERVICE);
 	}
 
@@ -365,6 +404,7 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
 		if (encoded_name == NULL) {
 			return dcesrv_netr_ServerAuthenticate3_check_downgrade(
 				dce_call, r, pipe_state, negotiate_flags,
+				NULL, /* trust_account_in_db */
 				NT_STATUS_NO_MEMORY);
 		}
 
@@ -372,12 +412,14 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
 		if (len < 2) {
 			return dcesrv_netr_ServerAuthenticate3_check_downgrade(
 				dce_call, r, pipe_state, negotiate_flags,
+				NULL, /* trust_account_in_db */
 				NT_STATUS_NO_TRUST_SAM_ACCOUNT);
 		}
 
 		if (require_trailer && encoded_name[len - 1] != trailer) {
 			return dcesrv_netr_ServerAuthenticate3_check_downgrade(
 				dce_call, r, pipe_state, negotiate_flags,
+				NULL, /* trust_account_in_db */
 				NT_STATUS_NO_TRUST_SAM_ACCOUNT);
 		}
 		encoded_name[len - 1] = '\0';
@@ -398,11 +440,13 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
 				  encoded_name));
 			return dcesrv_netr_ServerAuthenticate3_check_downgrade(
 				dce_call, r, pipe_state, negotiate_flags,
+				NULL, /* trust_account_in_db */
 				NT_STATUS_NO_TRUST_SAM_ACCOUNT);
 		}
 		if (!NT_STATUS_IS_OK(nt_status)) {
 			return dcesrv_netr_ServerAuthenticate3_check_downgrade(
 				dce_call, r, pipe_state, negotiate_flags,
+				NULL, /* trust_account_in_db */
 				nt_status);
 		}
 
@@ -412,11 +456,13 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
 		if (NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCOUNT_DISABLED)) {
 			return dcesrv_netr_ServerAuthenticate3_check_downgrade(
 				dce_call, r, pipe_state, negotiate_flags,
+				NULL, /* trust_account_in_db */
 				NT_STATUS_NO_TRUST_SAM_ACCOUNT);
 		}
 		if (!NT_STATUS_IS_OK(nt_status)) {
 			return dcesrv_netr_ServerAuthenticate3_check_downgrade(
 				dce_call, r, pipe_state, negotiate_flags,
+				NULL, /* trust_account_in_db */
 				nt_status);
 		}
 
@@ -424,6 +470,7 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
 		if (flatname == NULL) {
 			return dcesrv_netr_ServerAuthenticate3_check_downgrade(
 				dce_call, r, pipe_state, negotiate_flags,
+				NULL, /* trust_account_in_db */
 				NT_STATUS_NO_TRUST_SAM_ACCOUNT);
 		}
 
@@ -431,6 +478,7 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
 		if (*trust_account_for_search == NULL) {
 			return dcesrv_netr_ServerAuthenticate3_check_downgrade(
 				dce_call, r, pipe_state, negotiate_flags,
+				NULL, /* trust_account_in_db */
 				NT_STATUS_NO_MEMORY);
 		}
 	} else {
@@ -448,6 +496,7 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
 			 log_escape(mem_ctx, r->in.account_name)));
 		return dcesrv_netr_ServerAuthenticate3_check_downgrade(
 				dce_call, r, pipe_state, negotiate_flags,
+				NULL, /* trust_account_in_db */
 				NT_STATUS_NO_TRUST_SAM_ACCOUNT);
 	}
 
@@ -457,6 +506,7 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
 			 log_escape(mem_ctx, r->in.account_name)));
 		return dcesrv_netr_ServerAuthenticate3_check_downgrade(
 				dce_call, r, pipe_state, negotiate_flags,
+				NULL, /* trust_account_in_db */
 				NT_STATUS_INTERNAL_DB_CORRUPTION);
 	}
 
@@ -468,11 +518,13 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
 			 r->in.account_name));
 		return dcesrv_netr_ServerAuthenticate3_check_downgrade(
 				dce_call, r, pipe_state, negotiate_flags,
+				NULL, /* trust_account_in_db */
 				NT_STATUS_INTERNAL_DB_CORRUPTION);
 	}
 
 	nt_status = dcesrv_netr_ServerAuthenticate3_check_downgrade(
 			dce_call, r, pipe_state, negotiate_flags,
+			*trust_account_in_db,
 			NT_STATUS_OK);
 	if (!NT_STATUS_IS_OK(nt_status)) {
 		return nt_status;
-- 
2.34.1


From b8f6e9fa3e218add0b2ca4fb14bcb9b5167ab8f5 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze@samba.org>
Date: Fri, 25 Nov 2022 13:31:14 +0100
Subject: [PATCH 20/30] CVE-2022-38023 docs-xml/smbdotconf: document "allow nt4
 crypto:COMPUTERACCOUNT = no"

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 bd429d025981b445bf63935063e8e302bfab3f9b)
---
 docs-xml/smbdotconf/logon/allownt4crypto.xml | 76 +++++++++++++++++++-
 1 file changed, 74 insertions(+), 2 deletions(-)

diff --git a/docs-xml/smbdotconf/logon/allownt4crypto.xml b/docs-xml/smbdotconf/logon/allownt4crypto.xml
index 06afcef73b1b..bbd03a42db74 100644
--- a/docs-xml/smbdotconf/logon/allownt4crypto.xml
+++ b/docs-xml/smbdotconf/logon/allownt4crypto.xml
@@ -1,11 +1,18 @@
 <samba:parameter name="allow nt4 crypto"
                  context="G"
                  type="boolean"
+                 deprecated="1"
                  xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
 <description>
+	<para>
+	This option is deprecated and will be removed in future,
+	as it is a security problem if not set to "no" (which will be
+	the hardcoded behavior in future).
+	</para>
+
 	<para>This option controls whether the netlogon server (currently
 	only in 'active directory domain controller' mode), will
-	reject clients which does not support NETLOGON_NEG_STRONG_KEYS
+	reject clients which do not support NETLOGON_NEG_STRONG_KEYS
 	nor NETLOGON_NEG_SUPPORTS_AES.</para>
 
 	<para>This option was added with Samba 4.2.0. It may lock out clients
@@ -18,8 +25,73 @@
 
 	<para>"allow nt4 crypto = yes" allows weak crypto to be negotiated, maybe via downgrade attacks.</para>
 
-	<para>This option is over-ridden by the 'reject md5 clients' option.</para>
+	<para><emphasis>Avoid using this option!</emphasis> Use explicit '<smbconfoption name="allow nt4 crypto:COMPUTERACCOUNT">yes</smbconfoption>' instead!
+	Which is available with the patches for
+	<ulink url="https://www.samba.org/samba/security/CVE-2022-38023.html">CVE-2022-38023</ulink>
+	see <ulink url="https://bugzilla.samba.org/show_bug.cgi?id=15240">https://bugzilla.samba.org/show_bug.cgi?id=15240</ulink></para>
+
+	<para>
+	Samba will log an error in the log files at log level 0
+	if legacy a client is rejected or allowed without an explicit,
+	'<smbconfoption name="allow nt4 crypto:COMPUTERACCOUNT">yes</smbconfoption>' option
+	for the client. The message will indicate
+	the explicit '<smbconfoption name="allow nt4 crypto:COMPUTERACCOUNT">yes</smbconfoption>'
+	line to be added, if the legacy client software requires it. (The log level can be adjusted with
+	'<smbconfoption name="CVE_2022_38023:error_debug_level">1</smbconfoption>'
+	in order to complain only at a higher log level).
+	</para>
+
+	<para>This allows admins to use "yes" only for a short grace period,
+	in order to collect the explicit
+	'<smbconfoption name="allow nt4 crypto:COMPUTERACCOUNT">yes</smbconfoption>' options.</para>
+
+	<para>This option is over-ridden by the '<smbconfoption name="reject md5 clients">yes</smbconfoption>' option.</para>
 </description>
 
 <value type="default">no</value>
 </samba:parameter>
+
+<samba:parameter name="allow nt4 crypto: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 'allow nt4 crypto = yes',
+	it is possible to specify an explicit exception per computer account
+	by using 'allow nt4 crypto:COMPUTERACCOUNT = yes' as option.
+	Note that COMPUTERACCOUNT has to be the sAMAccountName value of
+	the computer account (including the trailing '$' sign).
+    </para>
+
+    <para>
+	Samba will log a complaint in the log files at log level 0
+	about the security problem if the option is set to "yes",
+	but the related computer does not require it.
+	(The log level can be adjusted with
+	'<smbconfoption name="CVE_2022_38023:warn_about_unused_debug_level">1</smbconfoption>'
+	in order to complain only at a higher log level).
+    </para>
+
+    <para>
+	Samba will log a warning in the log files at log level 5,
+	if a setting is still needed for the specified computer account.
+    </para>
+
+    <para>
+	See <ulink url="https://www.samba.org/samba/security/CVE-2022-38023.html">CVE-2022-38023</ulink>,
+	<ulink url="https://bugzilla.samba.org/show_bug.cgi?id=15240">https://bugzilla.samba.org/show_bug.cgi?id=15240</ulink>.
+    </para>
+
+    <para>This option overrides the <smbconfoption name="allow nt4 crypto"/> option.</para>
+
+    <para>This option is over-ridden by the '<smbconfoption name="reject md5 clients">yes</smbconfoption>' option.</para>
+
+    <programlisting>
+	allow nt4 crypto:LEGACYCOMPUTER1$ = yes
+	allow nt4 crypto:NASBOX$ = yes
+	allow nt4 crypto:LEGACYCOMPUTER2$ = yes
+    </programlisting>
+</description>
+
+</samba:parameter>
-- 
2.34.1


From 16895f56b2f35dda0df54b1b416d7fac05965fcc Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze@samba.org>
Date: Fri, 25 Nov 2022 14:02:11 +0100
Subject: [PATCH 21/30] CVE-2022-38023 docs-xml/smbdotconf: document "server
 reject md5 schannel:COMPUTERACCOUNT"

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 2ad302b42254e3c2800aaf11669fe2e6d55fa8a1)
---
 docs-xml/smbdotconf/logon/allownt4crypto.xml  | 13 ++-
 .../smbdotconf/logon/rejectmd5clients.xml     | 96 ++++++++++++++++++-
 2 files changed, 103 insertions(+), 6 deletions(-)

diff --git a/docs-xml/smbdotconf/logon/allownt4crypto.xml b/docs-xml/smbdotconf/logon/allownt4crypto.xml
index bbd03a42db74..ee63e6cc2453 100644
--- a/docs-xml/smbdotconf/logon/allownt4crypto.xml
+++ b/docs-xml/smbdotconf/logon/allownt4crypto.xml
@@ -45,7 +45,9 @@
 	in order to collect the explicit
 	'<smbconfoption name="allow nt4 crypto:COMPUTERACCOUNT">yes</smbconfoption>' options.</para>
 
-	<para>This option is over-ridden by the '<smbconfoption name="reject md5 clients">yes</smbconfoption>' option.</para>
+	<para>This option is over-ridden by the effective value of 'yes' from
+	the '<smbconfoption name="server reject md5 schannel:COMPUTERACCOUNT"/>'
+	and/or '<smbconfoption name="reject md5 clients"/>' options.</para>
 </description>
 
 <value type="default">no</value>
@@ -85,12 +87,19 @@
 
     <para>This option overrides the <smbconfoption name="allow nt4 crypto"/> option.</para>
 
-    <para>This option is over-ridden by the '<smbconfoption name="reject md5 clients">yes</smbconfoption>' option.</para>
+    <para>This option is over-ridden by the effective value of 'yes' from
+    the '<smbconfoption name="server reject md5 schannel:COMPUTERACCOUNT"/>'
+    and/or '<smbconfoption name="reject md5 clients"/>' options.</para>
+    <para>Which means '<smbconfoption name="allow nt4 crypto:COMPUTERACCOUNT">yes</smbconfoption>'
+    is only useful in combination with '<smbconfoption name="server reject md5 schannel:COMPUTERACCOUNT">no</smbconfoption>'</para>
 
     <programlisting>
 	allow nt4 crypto:LEGACYCOMPUTER1$ = yes
+	server reject md5 schannel:LEGACYCOMPUTER1$ = no
 	allow nt4 crypto:NASBOX$ = yes
+	server reject md5 schannel:NASBOX$ = no
 	allow nt4 crypto:LEGACYCOMPUTER2$ = yes
+	server reject md5 schannel:LEGACYCOMPUTER2$ = no
     </programlisting>
 </description>
 
diff --git a/docs-xml/smbdotconf/logon/rejectmd5clients.xml b/docs-xml/smbdotconf/logon/rejectmd5clients.xml
index edcbe02e99a3..fe7701d92772 100644
--- a/docs-xml/smbdotconf/logon/rejectmd5clients.xml
+++ b/docs-xml/smbdotconf/logon/rejectmd5clients.xml
@@ -1,8 +1,15 @@
 <samba:parameter name="reject md5 clients"
                  context="G"
                  type="boolean"
+                 deprecated="1"
                  xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
 <description>
+	<para>
+	This option is deprecated and will be removed in a future release,
+	as it is a security problem if not set to "yes" (which will be
+	the hardcoded behavior in the future).
+	</para>
+
 	<para>This option controls whether the netlogon server (currently
 	only in 'active directory domain controller' mode), will
 	reject clients which does not support NETLOGON_NEG_SUPPORTS_AES.</para>
@@ -10,13 +17,94 @@
 	<para>Support for NETLOGON_NEG_SUPPORTS_AES was added in Windows
 	starting with Server 2008R2 and Windows 7, it's available in Samba
 	starting with 4.0, however third party domain members like NetApp ONTAP
-	still uses RC4 (HMAC-MD5), see https://www.samba.org/samba/security/CVE-2022-38023.html for more details.</para>
+	still uses RC4 (HMAC-MD5), see
+	<ulink url="https://www.samba.org/samba/security/CVE-2022-38023.html">https://www.samba.org/samba/security/CVE-2022-38023.html</ulink>
+	for more details.
+	</para>
+
+	<para>The default changed from 'no' to 'yes', with the patches for
+	<ulink url="https://www.samba.org/samba/security/CVE-2022-38023.html">CVE-2022-38023</ulink>
+	see <ulink url="https://bugzilla.samba.org/show_bug.cgi?id=15240">https://bugzilla.samba.org/show_bug.cgi?id=15240</ulink>.
+	</para>
+
+	<para><emphasis>Avoid using this option!</emphasis> Use an explicit per machine account
+	'<smbconfoption name="server reject md5 schannel:COMPUTERACCOUNT"/>' instead!
+	Which is available with the patches for
+	<ulink url="https://www.samba.org/samba/security/CVE-2022-38023.html">CVE-2022-38023</ulink>
+	see <ulink url="https://bugzilla.samba.org/show_bug.cgi?id=15240">https://bugzilla.samba.org/show_bug.cgi?id=15240</ulink>.
+	</para>
 
-	<para>The default changed from 'no' to 'yes', with the patches for CVE-2022-38023,
-	see https://bugzilla.samba.org/show_bug.cgi?id=15240</para>
+	<para>
+	Samba will log an error in the log files at log level 0
+	if legacy a client is rejected or allowed without an explicit,
+	'<smbconfoption name="server reject md5 schannel:COMPUTERACCOUNT">no</smbconfoption>' option
+	for the client. The message will indicate
+	the explicit '<smbconfoption name="server reject md5 schannel:COMPUTERACCOUNT">no</smbconfoption>'
+	line to be added, if the legacy client software requires it. (The log level can be adjusted with
+	'<smbconfoption name="CVE_2022_38023:error_debug_level">1</smbconfoption>'
+	in order to complain only at a higher log level).
+	</para>
 
-	<para>This option overrides the 'allow nt4 crypto' option.</para>
+	<para>This allows admins to use "no" only for a short grace period,
+	in order to collect the explicit
+	'<smbconfoption name="server reject md5 schannel:COMPUTERACCOUNT">no</smbconfoption>' options.</para>
+
+	<para>When set to 'yes' this option overrides the
+	'<smbconfoption name="allow nt4 crypto:COMPUTERACCOUNT"/>' and
+	'<smbconfoption name="allow nt4 crypto"/>' options and implies
+	'<smbconfoption name="allow nt4 crypto:COMPUTERACCOUNT">no</smbconfoption>'.
+	</para>
 </description>
 
 <value type="default">yes</value>
 </samba:parameter>
+
+<samba:parameter name="server reject md5 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 or trusted domains,
+	which required "reject md5 clients = no" before,
+	it is possible to specify an explicit exception per computer account
+	by setting 'server reject md5 schannel:COMPUTERACCOUNT = no'.
+	Note that COMPUTERACCOUNT has to be the sAMAccountName value of
+	the computer account (including the trailing '$' sign).
+    </para>
+
+    <para>
+	Samba will log a complaint in the log files at log level 0
+	about the security problem if the option is set to "no",
+	but the related computer does not require it.
+	(The log level can be adjusted with
+	'<smbconfoption name="CVE_2022_38023:warn_about_unused_debug_level">1</smbconfoption>'
+	in order to complain only at a higher log level).
+    </para>
+
+    <para>
+	Samba will log a warning in the log files at log level 5
+	if a setting is still needed for the specified computer account.
+    </para>
+
+    <para>
+	See <ulink url="https://www.samba.org/samba/security/CVE-2022-38023.html">CVE-2022-38023</ulink>,
+	<ulink url="https://bugzilla.samba.org/show_bug.cgi?id=15240">https://bugzilla.samba.org/show_bug.cgi?id=15240</ulink>.
+    </para>
+
+    <para>This option overrides the <smbconfoption name="reject md5 clients"/> option.</para>
+
+    <para>When set to 'yes' this option overrides the
+    '<smbconfoption name="allow nt4 crypto:COMPUTERACCOUNT"/>' and
+    '<smbconfoption name="allow nt4 crypto"/>' options and implies
+    '<smbconfoption name="allow nt4 crypto:COMPUTERACCOUNT">no</smbconfoption>'.
+    </para>
+
+    <programlisting>
+	server reject md5 schannel:LEGACYCOMPUTER1$ = no
+	server reject md5 schannel:NASBOX$ = no
+	server reject md5 schannel:LEGACYCOMPUTER2$ = no
+    </programlisting>
+</description>
+
+</samba:parameter>
-- 
2.34.1


From 71283bb55feb027a94c3795bd1b94217be93c1a6 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze@samba.org>
Date: Fri, 25 Nov 2022 13:13:36 +0100
Subject: [PATCH 22/30] 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)
---
 source4/rpc_server/netlogon/dcerpc_netlogon.c | 143 ++++++++++++++++++
 1 file changed, 143 insertions(+)

diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
index f303dc00ada2..5f2f765abe5b 100644
--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
@@ -64,10 +64,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!
@@ -143,6 +167,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
@@ -183,19 +213,84 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_check_downgrade(
 	}
 
 	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();
+
+		if (lpcfg_weak_crypto(lp_ctx) == SAMBA_WEAK_CRYPTO_DISALLOWED) {
+			if (CVE_2022_38023_error_level < DBGLVL_NOTICE) {
+				CVE_2022_38023_error_level = DBGLVL_NOTICE;
+			}
+			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 "
+			      "WEAK_CRYPTO_DISALLOWED\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 ? "]" : ""));
+			goto return_downgrade;
+		}
+
+		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;
 	}
 
@@ -228,6 +323,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


From ab3062a57e170f90bca2d88771559d7c5ea38837 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze@samba.org>
Date: Wed, 30 Nov 2022 14:57:20 +0100
Subject: [PATCH 23/30] CVE-2022-38023 selftest:Samba4: avoid global 'allow nt4
 crypto = yes' and 'reject md5 clients = no'

Instead of using the generic deprecated option use the specific
allow nt4 crypto:COMPUTERACCOUNT = yes and
server reject md5 schannel:COMPUTERACCOUNT = no
in order to allow legacy tests for pass.

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 7ae3735810c2db32fa50f309f8af3c76ffa29768)
---
 selftest/target/Samba4.pm | 60 ++++++++++++++++++++++++++++++++++-----
 1 file changed, 53 insertions(+), 7 deletions(-)

diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm
index fb63bbeff059..b61acbf8e57b 100755
--- a/selftest/target/Samba4.pm
+++ b/selftest/target/Samba4.pm
@@ -1608,7 +1608,6 @@ sub provision_ad_dc_ntvfs($$$)
         my $extra_conf_options = "netbios aliases = localDC1-a
         server services = +winbind -winbindd
 	ldap server require strong auth = allow_sasl_over_tls
-	allow nt4 crypto = yes
 	raw NTLMv2 auth = yes
 	lsa over netlogon = yes
         rpc server port = 1027
@@ -1620,9 +1619,19 @@ sub provision_ad_dc_ntvfs($$$)
 	client min protocol = CORE
 	server min protocol = LANMAN1
 
-	reject md5 clients = no
-
 	CVE_2020_1472:warn_about_unused_debug_level = 3
+	CVE_2022_38023:warn_about_unused_debug_level = 3
+	allow nt4 crypto:torturetest\$ = yes
+	server reject md5 schannel:schannel2\$ = no
+	server reject md5 schannel:schannel3\$ = no
+	server reject md5 schannel:schannel8\$ = no
+	server reject md5 schannel:schannel9\$ = no
+	server reject md5 schannel:torturetest\$ = no
+	server reject md5 schannel:tests4u2proxywk\$ = no
+	server reject md5 schannel:tests4u2selfbdc\$ = no
+	server reject md5 schannel:tests4u2selfwk\$ = no
+	server reject md5 schannel:torturepacbdc\$ = no
+	server reject md5 schannel:torturepacwksta\$ = no
 	server require schannel:schannel0\$ = no
 	server require schannel:schannel1\$ = no
 	server require schannel:schannel2\$ = no
@@ -1677,6 +1686,13 @@ sub provision_fl2000dc($$)
 	kdc enable fast = no
 	spnego:simulate_w2k=yes
 	ntlmssp_server:force_old_spnego=yes
+
+	CVE_2022_38023:warn_about_unused_debug_level = 3
+	server reject md5 schannel:tests4u2proxywk\$ = no
+	server reject md5 schannel:tests4u2selfbdc\$ = no
+	server reject md5 schannel:tests4u2selfwk\$ = no
+	server reject md5 schannel:torturepacbdc\$ = no
+	server reject md5 schannel:torturepacwksta\$ = no
 ";
 	my $extra_provision_options = ["--base-schema=2008_R2"];
 	# This environment uses plain text secrets
@@ -1717,11 +1733,23 @@ sub provision_fl2003dc($$$)
 	my $ip_addr2 = Samba::get_ipv6_addr("fakednsforwarder2");
 
 	print "PROVISIONING DC WITH FOREST LEVEL 2003...\n";
-	my $extra_conf_options = "allow dns updates = nonsecure and secure
+	my $extra_conf_options = "
+	allow dns updates = nonsecure and secure
+
 	kdc enable fast = no
 	dcesrv:header signing = no
 	dcesrv:max auth states = 0
-	dns forwarder = $ip_addr1 [$ip_addr2]:54";
+
+	dns forwarder = $ip_addr1 [$ip_addr2]:54
+
+	CVE_2022_38023:warn_about_unused_debug_level = 3
+	server reject md5 schannel:tests4u2proxywk\$ = no
+	server reject md5 schannel:tests4u2selfbdc\$ = no
+	server reject md5 schannel:tests4u2selfwk\$ = no
+	server reject md5 schannel:torturepacbdc\$ = no
+	server reject md5 schannel:torturepacwksta\$ = no
+";
+
 	my $extra_provision_options = ["--base-schema=2008_R2"];
 	my $ret = $self->provision($prefix,
 				   "domain controller",
@@ -1776,6 +1804,13 @@ sub provision_fl2008r2dc($$$)
 	ldap server require strong auth = no
         # delay by 10 seconds, 10^7 usecs
 	ldap_server:delay_expire_disconnect = 10000
+
+	CVE_2022_38023:warn_about_unused_debug_level = 3
+	server reject md5 schannel:tests4u2proxywk\$ = no
+	server reject md5 schannel:tests4u2selfbdc\$ = no
+	server reject md5 schannel:tests4u2selfwk\$ = no
+	server reject md5 schannel:torturepacbdc\$ = no
+	server reject md5 schannel:torturepacwksta\$ = no
 ";
 	my $extra_provision_options = ["--base-schema=2008_R2"];
 	my $ret = $self->provision($prefix,
@@ -1987,9 +2022,20 @@ sub provision_ad_dc($$$$$$$)
 	lpq cache time = 0
 	print notify backchannel = yes
 
-	reject md5 clients = no
-
 	CVE_2020_1472:warn_about_unused_debug_level = 3
+	CVE_2022_38023:warn_about_unused_debug_level = 3
+	CVE_2022_38023:error_debug_level = 2
+	server reject md5 schannel:schannel2\$ = no
+	server reject md5 schannel:schannel3\$ = no
+	server reject md5 schannel:schannel8\$ = no
+	server reject md5 schannel:schannel9\$ = no
+	server reject md5 schannel:torturetest\$ = no
+	server reject md5 schannel:tests4u2proxywk\$ = no
+	server reject md5 schannel:tests4u2selfbdc\$ = no
+	server reject md5 schannel:tests4u2selfwk\$ = no
+	server reject md5 schannel:torturepacbdc\$ = no
+	server reject md5 schannel:torturepacwksta\$ = no
+	server reject md5 schannel:samlogontest\$ = no
 	server require schannel:schannel0\$ = no
 	server require schannel:schannel1\$ = no
 	server require schannel:schannel2\$ = no
-- 
2.34.1


From 8ab5154b071bc02c540da963cf1c7e15cbf6c63b Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze@samba.org>
Date: Wed, 30 Nov 2022 16:57:24 +0100
Subject: [PATCH 24/30] CVE-2022-38023 s4:rpc_server/netlogon: split out
 dcesrv_netr_check_schannel() function

This will allow us to reuse the function in other places.
As it will also get some additional checks soon.

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 f43dc4f0bd60d4e127b714565147f82435aa4f07)
---
 source4/rpc_server/netlogon/dcerpc_netlogon.c | 84 +++++++++++--------
 1 file changed, 51 insertions(+), 33 deletions(-)

diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
index 5f2f765abe5b..8e952ec2e0c7 100644
--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
@@ -877,18 +877,11 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate2(struct dcesrv_call_state *dce_ca
 	return dcesrv_netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
 }
 
-/*
- * NOTE: The following functions are nearly identical to the ones available in
- * source3/rpc_server/srv_nelog_nt.c
- * The reason we keep 2 copies is that they use different structures to
- * represent the auth_info and the decrpc pipes.
- */
-static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dce_call,
-						    TALLOC_CTX *mem_ctx,
-						    const char *computer_name,
-						    struct netr_Authenticator *received_authenticator,
-						    struct netr_Authenticator *return_authenticator,
-						    struct netlogon_creds_CredentialState **creds_out)
+static NTSTATUS dcesrv_netr_check_schannel(struct dcesrv_call_state *dce_call,
+					   const struct netlogon_creds_CredentialState *creds,
+					   enum dcerpc_AuthType auth_type,
+					   enum dcerpc_AuthLevel auth_level,
+					   uint16_t opnum)
 {
 	struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
 	TALLOC_CTX *frame = talloc_stackframe();
@@ -897,15 +890,11 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc
 	bool schannel_global_required = (schannel == true);
 	bool schannel_required = schannel_global_required;
 	const char *explicit_opt = NULL;
-	struct netlogon_creds_CredentialState *creds = NULL;
 	int CVE_2020_1472_warn_level = lpcfg_parm_int(lp_ctx, NULL,
 		"CVE_2020_1472", "warn_about_unused_debug_level", DBGLVL_ERR);
 	int CVE_2020_1472_error_level = lpcfg_parm_int(lp_ctx, NULL,
 		"CVE_2020_1472", "error_debug_level", DBGLVL_ERR);
 	unsigned int dbg_lvl = DBGLVL_DEBUG;
-	enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
-	enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
-	uint16_t opnum = dce_call->pkt.u.request.opnum;
 	const char *opname = "<unknown>";
 	const char *reason = "<unknown>";
 
@@ -913,8 +902,6 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc
 		opname = ndr_table_netlogon.calls[opnum].name;
 	}
 
-	dcesrv_call_auth_info(dce_call, &auth_type, &auth_level);
-
 	if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
 		if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
 			reason = "WITH SEALED";
@@ -927,17 +914,6 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc
 		reason = "WITHOUT";
 	}
 
-	nt_status = schannel_check_creds_state(mem_ctx,
-					       lp_ctx,
-					       computer_name,
-					       received_authenticator,
-					       return_authenticator,
-					       &creds);
-	if (!NT_STATUS_IS_OK(nt_status)) {
-		ZERO_STRUCTP(return_authenticator);
-		return nt_status;
-	}
-
 	/*
 	 * We don't use lpcfg_parm_bool(), as we
 	 * need the explicit_opt pointer in order to
@@ -977,7 +953,6 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc
 			      log_escape(frame, creds->computer_name)));
 		}
 
-		*creds_out = creds;
 		TALLOC_FREE(frame);
 		return nt_status;
 	}
@@ -1011,8 +986,6 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc
 			      "might be needed for a legacy client.\n",
 			      log_escape(frame, creds->account_name)));
 		}
-		TALLOC_FREE(creds);
-		ZERO_STRUCTP(return_authenticator);
 		TALLOC_FREE(frame);
 		return nt_status;
 	}
@@ -1056,11 +1029,56 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc
 		      log_escape(frame, creds->computer_name)));
 	}
 
-	*creds_out = creds;
 	TALLOC_FREE(frame);
 	return NT_STATUS_OK;
 }
 
+/*
+ * NOTE: The following functions are nearly identical to the ones available in
+ * source3/rpc_server/srv_nelog_nt.c
+ * The reason we keep 2 copies is that they use different structures to
+ * represent the auth_info and the decrpc pipes.
+ */
+static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dce_call,
+						    TALLOC_CTX *mem_ctx,
+						    const char *computer_name,
+						    struct netr_Authenticator *received_authenticator,
+						    struct netr_Authenticator *return_authenticator,
+						    struct netlogon_creds_CredentialState **creds_out)
+{
+	NTSTATUS nt_status;
+	struct netlogon_creds_CredentialState *creds = NULL;
+	enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
+	enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
+
+	dcesrv_call_auth_info(dce_call, &auth_type, &auth_level);
+
+	nt_status = schannel_check_creds_state(mem_ctx,
+					       dce_call->conn->dce_ctx->lp_ctx,
+					       computer_name,
+					       received_authenticator,
+					       return_authenticator,
+					       &creds);
+	if (!NT_STATUS_IS_OK(nt_status)) {
+		ZERO_STRUCTP(return_authenticator);
+		return nt_status;
+	}
+
+	nt_status = dcesrv_netr_check_schannel(dce_call,
+					       creds,
+					       auth_type,
+					       auth_level,
+					       dce_call->pkt.u.request.opnum);
+	if (!NT_STATUS_IS_OK(nt_status)) {
+		TALLOC_FREE(creds);
+		ZERO_STRUCTP(return_authenticator);
+		return nt_status;
+	}
+
+	*creds_out = creds;
+	return NT_STATUS_OK;
+}
+
 /*
   Change the machine account password for the currently connected
   client.  Supplies only the NT#.
-- 
2.34.1


From 875734d5294ff48950a24d6a89be52c916307bc2 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze@samba.org>
Date: Wed, 30 Nov 2022 17:15:36 +0100
Subject: [PATCH 25/30] CVE-2022-38023 s4:rpc_server/netlogon: make sure all
 dcesrv_netr_LogonSamLogon*() calls go through dcesrv_netr_check_schannel()

We'll soon add some additional contraints in dcesrv_netr_check_schannel(),
which are also required for dcesrv_netr_LogonSamLogonEx().

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 689507457f5e6666488732f91a355a2183fb1662)
---
 source4/rpc_server/netlogon/dcerpc_netlogon.c | 36 +++++++++++++++----
 1 file changed, 29 insertions(+), 7 deletions(-)

diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
index 8e952ec2e0c7..d5bca620b0d4 100644
--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
@@ -1441,6 +1441,35 @@ static NTSTATUS dcesrv_netr_LogonSamLogon_base_call(struct dcesrv_netr_LogonSamL
 	struct auth_usersupplied_info *user_info = NULL;
 	NTSTATUS nt_status;
 	struct tevent_req *subreq = NULL;
+	enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
+	enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
+
+	dcesrv_call_auth_info(dce_call, &auth_type, &auth_level);
+
+	switch (dce_call->pkt.u.request.opnum) {
+	case NDR_NETR_LOGONSAMLOGON:
+	case NDR_NETR_LOGONSAMLOGONWITHFLAGS:
+		/*
+		 * These already called dcesrv_netr_check_schannel()
+		 * via dcesrv_netr_creds_server_step_check()
+		 */
+		break;
+	case NDR_NETR_LOGONSAMLOGONEX:
+	default:
+		if (auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
+			return NT_STATUS_ACCESS_DENIED;
+		}
+
+		nt_status = dcesrv_netr_check_schannel(dce_call,
+						       creds,
+						       auth_type,
+						       auth_level,
+						       dce_call->pkt.u.request.opnum);
+		if (!NT_STATUS_IS_OK(nt_status)) {
+			return nt_status;
+		}
+		break;
+	}
 
 	*r->out.authoritative = 1;
 
@@ -1789,7 +1818,6 @@ static void dcesrv_netr_LogonSamLogon_base_reply(
 static NTSTATUS dcesrv_netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
 				     struct netr_LogonSamLogonEx *r)
 {
-	enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
 	struct dcesrv_netr_LogonSamLogon_base_state *state;
 	NTSTATUS nt_status;
 
@@ -1827,12 +1855,6 @@ static NTSTATUS dcesrv_netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call,
 		return nt_status;
 	}
 
-	dcesrv_call_auth_info(dce_call, &auth_type, NULL);
-
-	if (auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
-		return NT_STATUS_ACCESS_DENIED;
-	}
-
 	nt_status = dcesrv_netr_LogonSamLogon_base_call(state);
 
 	if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
-- 
2.34.1


From 9c294a19374d15f04649c62f4e5f8df6a59610a5 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze@samba.org>
Date: Fri, 25 Nov 2022 16:53:35 +0100
Subject: [PATCH 26/30] CVE-2022-38023 docs-xml/smbdotconf: add "server
 schannel require seal[:COMPUTERACCOUNT]" options

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 7732a4b0bde1d9f98a0371f17d22648495329470)
---
 .../smbdotconf/security/serverschannel.xml    |  43 ++++++-
 .../security/serverschannelrequireseal.xml    | 118 ++++++++++++++++++
 lib/param/loadparm.c                          |   1 +
 source3/param/loadparm.c                      |   1 +
 4 files changed, 157 insertions(+), 6 deletions(-)
 create mode 100644 docs-xml/smbdotconf/security/serverschannelrequireseal.xml

diff --git a/docs-xml/smbdotconf/security/serverschannel.xml b/docs-xml/smbdotconf/security/serverschannel.xml
index 3e66df1c2032..42a657912cac 100644
--- a/docs-xml/smbdotconf/security/serverschannel.xml
+++ b/docs-xml/smbdotconf/security/serverschannel.xml
@@ -12,19 +12,37 @@
 	the hardcoded behavior in future).
     </para>
 
-    <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><emphasis>Avoid using this option!</emphasis> Use explicit '<smbconfoption name="server require schannel:COMPUTERACCOUNT">no</smbconfoption>' instead!
     </para>
+
+    <para>
+	Samba will log an error in the log files at log level 0
+	if legacy a client is rejected or allowed without an explicit,
+	'<smbconfoption name="server require schannel:COMPUTERACCOUNT">no</smbconfoption>' option
+	for the client. The message will indicate
+	the explicit '<smbconfoption name="server require schannel:COMPUTERACCOUNT">no</smbconfoption>'
+	line to be added, if the legacy client software requires it. (The log level can be adjusted with
+	'<smbconfoption name="CVE_2020_1472:error_debug_level">1</smbconfoption>'
+	in order to complain only at a higher log level).
+	</para>
+
     <para>
-	See CVE-2020-1472(ZeroLogon) https://bugzilla.samba.org/show_bug.cgi?id=14497
+	This allows admins to use "auto" only for a short grace period,
+	in order to collect the explicit
+	'<smbconfoption name="server require schannel:COMPUTERACCOUNT">no</smbconfoption>' options.
     </para>
 
-    <para>If you still have legacy domain members use the <smbconfoption name="server require schannel:COMPUTERACCOUNT"/> option.
+    <para>
+	See <ulink url="https://www.samba.org/samba/security/CVE-2020-1472.html">CVE-2020-1472(ZeroLogon)</ulink>,
+	<ulink url="https://bugzilla.samba.org/show_bug.cgi?id=14497">https://bugzilla.samba.org/show_bug.cgi?id=14497</ulink>.
     </para>
 
     <para>This option is over-ridden by the <smbconfoption name="server require schannel:COMPUTERACCOUNT"/> option.</para>
 
+    <para>This option is over-ridden by the effective value of 'yes' from
+    the '<smbconfoption name="server schannel require seal:COMPUTERACCOUNT"/>'
+    and/or '<smbconfoption name="server schannel require seal"/>' options.</para>
+
 </description>
 
 <value type="default">yes</value>
@@ -48,6 +66,9 @@
 	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.
+	(The log level can be adjusted with
+	'<smbconfoption name="CVE_2020_1472:warn_about_unused_debug_level">1</smbconfoption>'
+	in order to complain only at a higher log level).
     </para>
 
     <para>
@@ -56,15 +77,25 @@
     </para>
 
     <para>
-	See CVE-2020-1472(ZeroLogon) https://bugzilla.samba.org/show_bug.cgi?id=14497
+	See <ulink url="https://www.samba.org/samba/security/CVE-2020-1472.html">CVE-2020-1472(ZeroLogon)</ulink>,
+	<ulink url="https://bugzilla.samba.org/show_bug.cgi?id=14497">https://bugzilla.samba.org/show_bug.cgi?id=14497</ulink>.
     </para>
 
     <para>This option overrides the <smbconfoption name="server schannel"/> option.</para>
 
+    <para>This option is over-ridden by the effective value of 'yes' from
+    the '<smbconfoption name="server schannel require seal:COMPUTERACCOUNT"/>'
+    and/or '<smbconfoption name="server schannel require seal"/>' options.</para>
+    <para>Which means '<smbconfoption name="server require schannel:COMPUTERACCOUNT">no</smbconfoption>'
+    is only useful in combination with '<smbconfoption name="server schannel require seal:COMPUTERACCOUNT">no</smbconfoption>'</para>
+
     <programlisting>
 	server require schannel:LEGACYCOMPUTER1$ = no
+	server require schannel seal:LEGACYCOMPUTER1$ = no
 	server require schannel:NASBOX$ = no
+	server require schannel seal:NASBOX$ = no
 	server require schannel:LEGACYCOMPUTER2$ = no
+	server require schannel seal:LEGACYCOMPUTER2$ = no
     </programlisting>
 </description>
 
diff --git a/docs-xml/smbdotconf/security/serverschannelrequireseal.xml b/docs-xml/smbdotconf/security/serverschannelrequireseal.xml
new file mode 100644
index 000000000000..d4620d1252dd
--- /dev/null
+++ b/docs-xml/smbdotconf/security/serverschannelrequireseal.xml
@@ -0,0 +1,118 @@
+<samba:parameter name="server schannel require seal"
+                 context="G"
+                 type="boolean"
+                 deprecated="1"
+                 xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
+<description>
+
+	<para>
+	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 option controls whether the netlogon server (currently
+	only in 'active directory domain controller' mode), will
+	reject the usage of netlogon secure channel without privacy/enryption.
+	</para>
+
+	<para>
+	The option is modelled after the registry key available on Windows.
+	</para>
+
+	<programlisting>
+	HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters\RequireSeal=2
+	</programlisting>
+
+	<para>
+	<emphasis>Avoid using this option!</emphasis> Use the per computer account specific option
+	'<smbconfoption name="server schannel require seal:COMPUTERACCOUNT"/>' instead!
+	Which is available with the patches for
+	<ulink url="https://www.samba.org/samba/security/CVE-2022-38023.html">CVE-2022-38023</ulink>
+	see <ulink url="https://bugzilla.samba.org/show_bug.cgi?id=15240">https://bugzilla.samba.org/show_bug.cgi?id=15240</ulink>.
+	</para>
+
+	<para>
+	Samba will log an error in the log files at log level 0
+	if legacy a client is rejected or allowed without an explicit,
+	'<smbconfoption name="server schannel require seal:COMPUTERACCOUNT">no</smbconfoption>' option
+	for the client. The message will indicate
+	the explicit '<smbconfoption name="server schannel require seal:COMPUTERACCOUNT">no</smbconfoption>'
+	line to be added, if the legacy client software requires it. (The log level can be adjusted with
+	'<smbconfoption name="CVE_2022_38023:error_debug_level">1</smbconfoption>'
+	in order to complain only at a higher log level).
+	</para>
+
+	<para>This allows admins to use "no" only for a short grace period,
+	in order to collect the explicit
+	'<smbconfoption name="server schannel require seal:COMPUTERACCOUNT">no</smbconfoption>' options.</para>
+
+	<para>
+	When set to 'yes' this option overrides the
+	'<smbconfoption name="server require schannel:COMPUTERACCOUNT"/>' and
+	'<smbconfoption name="server schannel"/>' options and implies
+	'<smbconfoption name="server require schannel:COMPUTERACCOUNT">yes</smbconfoption>'.
+	</para>
+
+	<para>
+	This option is over-ridden by the <smbconfoption name="server schannel require seal:COMPUTERACCOUNT"/> option.
+	</para>
+
+</description>
+
+<value type="default">yes</value>
+</samba:parameter>
+
+<samba:parameter name="server schannel require seal: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 require seal = no" before,
+	it is possible to specify explicit exception per computer account
+	by using 'server schannel require seal: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 log a complaint in the log files at log level 0
+	about the security problem if the option is set to "no",
+	but the related computer does not require it.
+	(The log level can be adjusted with
+	'<smbconfoption name="CVE_2022_38023:warn_about_unused_debug_level">1</smbconfoption>'
+	in order to complain only at a higher log level).
+	</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 <ulink url="https://www.samba.org/samba/security/CVE-2022-38023.html">CVE-2022-38023</ulink>,
+	<ulink url="https://bugzilla.samba.org/show_bug.cgi?id=15240">https://bugzilla.samba.org/show_bug.cgi?id=15240</ulink>.
+	</para>
+
+	<para>
+	This option overrides the '<smbconfoption name="server schannel require seal"/>' option.
+	</para>
+
+	<para>
+	When set to 'yes' this option overrides the
+	'<smbconfoption name="server require schannel:COMPUTERACCOUNT"/>' and
+	'<smbconfoption name="server schannel"/>' options and implies
+	'<smbconfoption name="server require schannel:COMPUTERACCOUNT">yes</smbconfoption>'.
+	</para>
+
+	<programlisting>
+	server require schannel seal:LEGACYCOMPUTER1$ = no
+	server require schannel seal:NASBOX$ = no
+	server require schannel seal:LEGACYCOMPUTER2$ = no
+	</programlisting>
+</description>
+
+</samba:parameter>
diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c
index 2b644ee97c02..2b1eec5c4a12 100644
--- a/lib/param/loadparm.c
+++ b/lib/param/loadparm.c
@@ -2725,6 +2725,7 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx)
 	lpcfg_do_global_parameter(lp_ctx, "winbind nss info", "template");
 
 	lpcfg_do_global_parameter(lp_ctx, "server schannel", "True");
+	lpcfg_do_global_parameter(lp_ctx, "server schannel require seal", "True");
 	lpcfg_do_global_parameter(lp_ctx, "reject md5 clients", "True");
 
 	lpcfg_do_global_parameter(lp_ctx, "short preserve case", "True");
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index 28ce4de6dd67..443b63a1cf46 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -666,6 +666,7 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
 	Globals.require_strong_key = true;
 	Globals.reject_md5_servers = true;
 	Globals.server_schannel = true;
+	Globals.server_schannel_require_seal = true;
 	Globals.reject_md5_clients = true;
 	Globals.read_raw = true;
 	Globals.write_raw = true;
-- 
2.34.1


From 422a2c9adcc39edb4a9ea3da435a7b53822f6ccc Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze@samba.org>
Date: Fri, 2 Dec 2022 14:31:26 +0100
Subject: [PATCH 27/30] CVE-2022-38023 s4:rpc_server/netlogon: add a per
 connection cache to dcesrv_netr_check_schannel()

It's enough to warn the admin once per connection.

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 3c57608e1109c1d6e8bb8fbad2ef0b5d79d00e1a)
---
 source4/rpc_server/netlogon/dcerpc_netlogon.c | 193 ++++++++++++++----
 1 file changed, 153 insertions(+), 40 deletions(-)

diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
index d5bca620b0d4..624c8d407242 100644
--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
@@ -877,23 +877,105 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate2(struct dcesrv_call_state *dce_ca
 	return dcesrv_netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
 }
 
-static NTSTATUS dcesrv_netr_check_schannel(struct dcesrv_call_state *dce_call,
-					   const struct netlogon_creds_CredentialState *creds,
-					   enum dcerpc_AuthType auth_type,
-					   enum dcerpc_AuthLevel auth_level,
-					   uint16_t opnum)
+struct dcesrv_netr_check_schannel_state {
+	struct dom_sid account_sid;
+	enum dcerpc_AuthType auth_type;
+	enum dcerpc_AuthLevel auth_level;
+
+	bool schannel_global_required;
+	bool schannel_required;
+	bool schannel_explicitly_set;
+
+	NTSTATUS result;
+};
+
+static NTSTATUS dcesrv_netr_check_schannel_get_state(struct dcesrv_call_state *dce_call,
+						     const struct netlogon_creds_CredentialState *creds,
+						     enum dcerpc_AuthType auth_type,
+						     enum dcerpc_AuthLevel auth_level,
+						     struct dcesrv_netr_check_schannel_state **_s)
 {
 	struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
-	TALLOC_CTX *frame = talloc_stackframe();
-	NTSTATUS nt_status;
 	int schannel = lpcfg_server_schannel(lp_ctx);
 	bool schannel_global_required = (schannel == true);
 	bool schannel_required = schannel_global_required;
 	const char *explicit_opt = NULL;
+#define DCESRV_NETR_CHECK_SCHANNEL_STATE_MAGIC (NETLOGON_SERVER_PIPE_STATE_MAGIC+1)
+	struct dcesrv_netr_check_schannel_state *s = NULL;
+	NTSTATUS status;
+
+	*_s = NULL;
+
+	s = dcesrv_iface_state_find_conn(dce_call,
+			DCESRV_NETR_CHECK_SCHANNEL_STATE_MAGIC,
+			struct dcesrv_netr_check_schannel_state);
+	if (s != NULL) {
+		if (!dom_sid_equal(&s->account_sid, creds->sid)) {
+			goto new_state;
+		}
+		if (s->auth_type != auth_type) {
+			goto new_state;
+		}
+		if (s->auth_level != auth_level) {
+			goto new_state;
+		}
+
+		*_s = s;
+		return NT_STATUS_OK;
+	}
+
+new_state:
+	TALLOC_FREE(s);
+	s = talloc_zero(dce_call,
+			struct dcesrv_netr_check_schannel_state);
+	if (s == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	s->account_sid = *creds->sid;
+	s->auth_type = auth_type;
+	s->auth_level = auth_level;
+	s->result = NT_STATUS_MORE_PROCESSING_REQUIRED;
+
+	/*
+	 * We don't use lpcfg_parm_bool(), as we
+	 * need the explicit_opt pointer in order to
+	 * adjust the debug messages.
+	 */
+	explicit_opt = lpcfg_get_parametric(lp_ctx,
+					    NULL,
+					    "server require schannel",
+					    creds->account_name);
+	if (explicit_opt != NULL) {
+		schannel_required = lp_bool(explicit_opt);
+	}
+
+	s->schannel_global_required = schannel_global_required;
+	s->schannel_required = schannel_required;
+	s->schannel_explicitly_set = explicit_opt != NULL;
+
+	status = dcesrv_iface_state_store_conn(dce_call,
+			DCESRV_NETR_CHECK_SCHANNEL_STATE_MAGIC,
+			s);
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+
+	*_s = s;
+	return NT_STATUS_OK;
+}
+
+static NTSTATUS dcesrv_netr_check_schannel_once(struct dcesrv_call_state *dce_call,
+						struct dcesrv_netr_check_schannel_state *s,
+						const struct netlogon_creds_CredentialState *creds,
+						uint16_t opnum)
+{
+	struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
 	int CVE_2020_1472_warn_level = lpcfg_parm_int(lp_ctx, NULL,
 		"CVE_2020_1472", "warn_about_unused_debug_level", DBGLVL_ERR);
 	int CVE_2020_1472_error_level = lpcfg_parm_int(lp_ctx, NULL,
 		"CVE_2020_1472", "error_debug_level", DBGLVL_ERR);
+	TALLOC_CTX *frame = talloc_stackframe();
 	unsigned int dbg_lvl = DBGLVL_DEBUG;
 	const char *opname = "<unknown>";
 	const char *reason = "<unknown>";
@@ -902,37 +984,43 @@ static NTSTATUS dcesrv_netr_check_schannel(struct dcesrv_call_state *dce_call,
 		opname = ndr_table_netlogon.calls[opnum].name;
 	}
 
-	if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
-		if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
+	if (s->auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
+		if (s->auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
 			reason = "WITH SEALED";
-		} else if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
+		} else if (s->auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
 			reason = "WITH SIGNED";
 		} else {
-			smb_panic("Schannel without SIGN/SEAL");
+			reason = "WITH INVALID";
+			dbg_lvl = DBGLVL_ERR;
+			s->result = NT_STATUS_INTERNAL_ERROR;
 		}
 	} else {
 		reason = "WITHOUT";
 	}
 
-	/*
-	 * We don't use lpcfg_parm_bool(), as we
-	 * need the explicit_opt pointer in order to
-	 * adjust the debug messages.
-	 */
-	explicit_opt = lpcfg_get_parametric(lp_ctx,
-					    NULL,
-					    "server require schannel",
-					    creds->account_name);
-	if (explicit_opt != NULL) {
-		schannel_required = lp_bool(explicit_opt);
+	if (!NT_STATUS_EQUAL(s->result, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
+		if (!NT_STATUS_IS_OK(s->result)) {
+			dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
+		}
+
+		DEBUG(dbg_lvl, (
+		      "CVE-2020-1472(ZeroLogon): "
+		      "%s request (opnum[%u]) %s schannel from "
+		      "client_account[%s] client_computer_name[%s] %s\n",
+		      opname, opnum, reason,
+		      log_escape(frame, creds->account_name),
+		      log_escape(frame, creds->computer_name),
+		      nt_errstr(s->result)));
+		TALLOC_FREE(frame);
+		return s->result;
 	}
 
-	if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
-		nt_status = NT_STATUS_OK;
+	if (s->auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
+		s->result = NT_STATUS_OK;
 
-		if (explicit_opt != NULL && !schannel_required) {
+		if (s->schannel_explicitly_set && !s->schannel_required) {
 			dbg_lvl = MIN(dbg_lvl, CVE_2020_1472_warn_level);
-		} else if (!schannel_required) {
+		} else if (!s->schannel_required) {
 			dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
 		}
 
@@ -943,9 +1031,8 @@ static NTSTATUS dcesrv_netr_check_schannel(struct dcesrv_call_state *dce_call,
 		      opname, opnum, reason,
 		      log_escape(frame, creds->account_name),
 		      log_escape(frame, creds->computer_name),
-		      nt_errstr(nt_status)));
-
-		if (explicit_opt != NULL && !schannel_required) {
+		      nt_errstr(s->result)));
+		if (s->schannel_explicitly_set && !s->schannel_required) {
 			DEBUG(CVE_2020_1472_warn_level, (
 			      "CVE-2020-1472(ZeroLogon): "
 			      "Option 'server require schannel:%s = no' not needed for '%s'!\n",
@@ -954,13 +1041,13 @@ static NTSTATUS dcesrv_netr_check_schannel(struct dcesrv_call_state *dce_call,
 		}
 
 		TALLOC_FREE(frame);
-		return nt_status;
+		return s->result;
 	}
 
-	if (schannel_required) {
-		nt_status = NT_STATUS_ACCESS_DENIED;
+	if (s->schannel_required) {
+		s->result = NT_STATUS_ACCESS_DENIED;
 
-		if (explicit_opt != NULL) {
+		if (s->schannel_explicitly_set) {
 			dbg_lvl = MIN(dbg_lvl, DBGLVL_NOTICE);
 		} else {
 			dbg_lvl = MIN(dbg_lvl, CVE_2020_1472_error_level);
@@ -973,8 +1060,8 @@ static NTSTATUS dcesrv_netr_check_schannel(struct dcesrv_call_state *dce_call,
 		      opname, opnum, reason,
 		      log_escape(frame, creds->account_name),
 		      log_escape(frame, creds->computer_name),
-		      nt_errstr(nt_status)));
-		if (explicit_opt != NULL) {
+		      nt_errstr(s->result)));
+		if (s->schannel_explicitly_set) {
 			D_NOTICE("CVE-2020-1472(ZeroLogon): Option "
 				"'server require schannel:%s = yes' "
 				"rejects access for client.\n",
@@ -987,12 +1074,12 @@ static NTSTATUS dcesrv_netr_check_schannel(struct dcesrv_call_state *dce_call,
 			      log_escape(frame, creds->account_name)));
 		}
 		TALLOC_FREE(frame);
-		return nt_status;
+		return s->result;
 	}
 
-	nt_status = NT_STATUS_OK;
+	s->result = NT_STATUS_OK;
 
-	if (explicit_opt != NULL) {
+	if (s->schannel_explicitly_set) {
 		dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
 	} else {
 		dbg_lvl = MIN(dbg_lvl, CVE_2020_1472_error_level);
@@ -1005,9 +1092,9 @@ static NTSTATUS dcesrv_netr_check_schannel(struct dcesrv_call_state *dce_call,
 	      opname, opnum, reason,
 	      log_escape(frame, creds->account_name),
 	      log_escape(frame, creds->computer_name),
-	      nt_errstr(nt_status)));
+	      nt_errstr(s->result)));
 
-	if (explicit_opt != NULL) {
+	if (s->schannel_explicitly_set) {
 		D_INFO("CVE-2020-1472(ZeroLogon): Option "
 		       "'server require schannel:%s = no' "
 		       "still needed for '%s'!\n",
@@ -1030,6 +1117,32 @@ static NTSTATUS dcesrv_netr_check_schannel(struct dcesrv_call_state *dce_call,
 	}
 
 	TALLOC_FREE(frame);
+	return s->result;
+}
+
+static NTSTATUS dcesrv_netr_check_schannel(struct dcesrv_call_state *dce_call,
+					   const struct netlogon_creds_CredentialState *creds,
+					   enum dcerpc_AuthType auth_type,
+					   enum dcerpc_AuthLevel auth_level,
+					   uint16_t opnum)
+{
+	struct dcesrv_netr_check_schannel_state *s = NULL;
+	NTSTATUS status;
+
+	status = dcesrv_netr_check_schannel_get_state(dce_call,
+						      creds,
+						      auth_type,
+						      auth_level,
+						      &s);
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+
+	status = dcesrv_netr_check_schannel_once(dce_call, s, creds, opnum);
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+
 	return NT_STATUS_OK;
 }
 
-- 
2.34.1


From 78d79aade1f07776266e22829a53a594bb2968b8 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze@samba.org>
Date: Fri, 25 Nov 2022 14:05:30 +0100
Subject: [PATCH 28/30] CVE-2022-38023 s4:rpc_server/netlogon: implement
 "server schannel require seal[:COMPUTERACCOUNT]"

By default we'll now require schannel connections with
privacy/sealing/encryption.

But we allow exceptions for specific computer/trust accounts.

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 b3ed90a0541a271a7c6d4bee1201fa47adc3c0c1)
---
 selftest/target/Samba4.pm                     |  28 ++
 source4/rpc_server/netlogon/dcerpc_netlogon.c | 244 +++++++++++++++++-
 2 files changed, 271 insertions(+), 1 deletion(-)

diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm
index b61acbf8e57b..087860b9ebdd 100755
--- a/selftest/target/Samba4.pm
+++ b/selftest/target/Samba4.pm
@@ -1645,9 +1645,23 @@ sub provision_ad_dc_ntvfs($$$)
 	server require schannel:schannel10\$ = no
 	server require schannel:schannel11\$ = no
 	server require schannel:torturetest\$ = no
+	server schannel require seal:schannel0\$ = no
+	server schannel require seal:schannel1\$ = no
+	server schannel require seal:schannel2\$ = no
+	server schannel require seal:schannel3\$ = no
+	server schannel require seal:schannel4\$ = no
+	server schannel require seal:schannel5\$ = no
+	server schannel require seal:schannel6\$ = no
+	server schannel require seal:schannel7\$ = no
+	server schannel require seal:schannel8\$ = no
+	server schannel require seal:schannel9\$ = no
+	server schannel require seal:schannel10\$ = no
+	server schannel require seal:schannel11\$ = no
+	server schannel require seal:torturetest\$ = no
 
 	# needed for 'samba.tests.auth_log' tests
 	server require schannel:LOCALDC\$ = no
+	server schannel require seal:LOCALDC\$ = no
 	";
 	push (@{$extra_provision_options}, "--use-ntvfs");
 	my $ret = $self->provision($prefix,
@@ -2049,6 +2063,19 @@ sub provision_ad_dc($$$$$$$)
 	server require schannel:schannel10\$ = no
 	server require schannel:schannel11\$ = no
 	server require schannel:torturetest\$ = no
+	server schannel require seal:schannel0\$ = no
+	server schannel require seal:schannel1\$ = no
+	server schannel require seal:schannel2\$ = no
+	server schannel require seal:schannel3\$ = no
+	server schannel require seal:schannel4\$ = no
+	server schannel require seal:schannel5\$ = no
+	server schannel require seal:schannel6\$ = no
+	server schannel require seal:schannel7\$ = no
+	server schannel require seal:schannel8\$ = no
+	server schannel require seal:schannel9\$ = no
+	server schannel require seal:schannel10\$ = no
+	server schannel require seal:schannel11\$ = no
+	server schannel require seal:torturetest\$ = no
 
 	auth event notification = true
 	dsdb event notification = true
@@ -2742,6 +2769,7 @@ sub setup_ad_dc_smb1
 
 	# needed for 'samba.tests.auth_log' tests
 	server require schannel:ADDCSMB1\$ = no
+	server schannel require seal:ADDCSMB1\$ = no
 ";
 	return _setup_ad_dc($self, $path, $conf_opts, "addcsmb1", "addom2.samba.example.com");
 }
diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
index 624c8d407242..ddcb8487a56d 100644
--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
@@ -68,9 +68,11 @@ static NTSTATUS dcesrv_interface_netlogon_bind(struct dcesrv_connection_context
 	bool global_reject_md5_client = lpcfg_reject_md5_clients(lp_ctx);
 	int schannel = lpcfg_server_schannel(lp_ctx);
 	bool schannel_global_required = (schannel == true);
+	bool global_require_seal = lpcfg_server_schannel_require_seal(lp_ctx);
 	static bool warned_global_nt4_once = false;
 	static bool warned_global_md5_once = false;
 	static bool warned_global_schannel_once = false;
+	static bool warned_global_seal_once = false;
 
 	if (global_allow_nt4_crypto && !warned_global_nt4_once) {
 		/*
@@ -102,6 +104,16 @@ static NTSTATUS dcesrv_interface_netlogon_bind(struct dcesrv_connection_context
 		warned_global_schannel_once = true;
 	}
 
+	if (!global_require_seal && !warned_global_seal_once) {
+		/*
+		 * We want admins to notice their misconfiguration!
+		 */
+		D_ERR("CVE-2022-38023 (and others): "
+		      "Please configure 'server schannel require seal = yes' (the default), "
+		      "See https://bugzilla.samba.org/show_bug.cgi?id=15240\n");
+		warned_global_seal_once = true;
+	}
+
 	return dcesrv_interface_bind_reject_connect(context, iface);
 }
 
@@ -886,6 +898,10 @@ struct dcesrv_netr_check_schannel_state {
 	bool schannel_required;
 	bool schannel_explicitly_set;
 
+	bool seal_global_required;
+	bool seal_required;
+	bool seal_explicitly_set;
+
 	NTSTATUS result;
 };
 
@@ -900,6 +916,9 @@ static NTSTATUS dcesrv_netr_check_schannel_get_state(struct dcesrv_call_state *d
 	bool schannel_global_required = (schannel == true);
 	bool schannel_required = schannel_global_required;
 	const char *explicit_opt = NULL;
+	bool global_require_seal = lpcfg_server_schannel_require_seal(lp_ctx);
+	bool require_seal = global_require_seal;
+	const char *explicit_seal_opt = NULL;
 #define DCESRV_NETR_CHECK_SCHANNEL_STATE_MAGIC (NETLOGON_SERVER_PIPE_STATE_MAGIC+1)
 	struct dcesrv_netr_check_schannel_state *s = NULL;
 	NTSTATUS status;
@@ -937,6 +956,19 @@ new_state:
 	s->auth_level = auth_level;
 	s->result = NT_STATUS_MORE_PROCESSING_REQUIRED;
 
+	/*
+	 * We don't use lpcfg_parm_bool(), as we
+	 * need the explicit_opt pointer in order to
+	 * adjust the debug messages.
+	 */
+	explicit_seal_opt = lpcfg_get_parametric(lp_ctx,
+						 NULL,
+						 "server schannel require seal",
+						 creds->account_name);
+	if (explicit_seal_opt != NULL) {
+		require_seal = lp_bool(explicit_seal_opt);
+	}
+
 	/*
 	 * We don't use lpcfg_parm_bool(), as we
 	 * need the explicit_opt pointer in order to
@@ -954,6 +986,10 @@ new_state:
 	s->schannel_required = schannel_required;
 	s->schannel_explicitly_set = explicit_opt != NULL;
 
+	s->seal_global_required = global_require_seal;
+	s->seal_required = require_seal;
+	s->seal_explicitly_set = explicit_seal_opt != NULL;
+
 	status = dcesrv_iface_state_store_conn(dce_call,
 			DCESRV_NETR_CHECK_SCHANNEL_STATE_MAGIC,
 			s);
@@ -975,6 +1011,10 @@ static NTSTATUS dcesrv_netr_check_schannel_once(struct dcesrv_call_state *dce_ca
 		"CVE_2020_1472", "warn_about_unused_debug_level", DBGLVL_ERR);
 	int CVE_2020_1472_error_level = lpcfg_parm_int(lp_ctx, NULL,
 		"CVE_2020_1472", "error_debug_level", DBGLVL_ERR);
+	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);
 	TALLOC_CTX *frame = talloc_stackframe();
 	unsigned int dbg_lvl = DBGLVL_DEBUG;
 	const char *opname = "<unknown>";
@@ -1004,18 +1044,107 @@ static NTSTATUS dcesrv_netr_check_schannel_once(struct dcesrv_call_state *dce_ca
 		}
 
 		DEBUG(dbg_lvl, (
-		      "CVE-2020-1472(ZeroLogon): "
+		      "CVE-2020-1472(ZeroLogon)/CVE-2022-38023: "
+		      "%s request (opnum[%u]) %s schannel from "
+		      "client_account[%s] client_computer_name[%s] %s\n",
+		      opname, opnum, reason,
+		      log_escape(frame, creds->account_name),
+		      log_escape(frame, creds->computer_name),
+		      nt_errstr(s->result)));
+		TALLOC_FREE(frame);
+		return s->result;
+	}
+
+	if (s->auth_type == DCERPC_AUTH_TYPE_SCHANNEL &&
+	    s->auth_level == DCERPC_AUTH_LEVEL_PRIVACY)
+	{
+		s->result = NT_STATUS_OK;
+
+		if (s->schannel_explicitly_set && !s->schannel_required) {
+			dbg_lvl = MIN(dbg_lvl, CVE_2020_1472_warn_level);
+		} else if (!s->schannel_required) {
+			dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
+		}
+		if (s->seal_explicitly_set && !s->seal_required) {
+			dbg_lvl = MIN(dbg_lvl, CVE_2022_38023_warn_level);
+		} else if (!s->seal_required) {
+			dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
+		}
+
+		DEBUG(dbg_lvl, (
+		      "CVE-2020-1472(ZeroLogon)/CVE-2022-38023: "
 		      "%s request (opnum[%u]) %s schannel from "
 		      "client_account[%s] client_computer_name[%s] %s\n",
 		      opname, opnum, reason,
 		      log_escape(frame, creds->account_name),
 		      log_escape(frame, creds->computer_name),
 		      nt_errstr(s->result)));
+
+		if (s->schannel_explicitly_set && !s->schannel_required) {
+			DEBUG(CVE_2020_1472_warn_level, (
+			      "CVE-2020-1472(ZeroLogon): "
+			      "Option 'server require schannel:%s = no' not needed for '%s'!\n",
+			      log_escape(frame, creds->account_name),
+			      log_escape(frame, creds->computer_name)));
+		}
+
+		if (s->seal_explicitly_set && !s->seal_required) {
+			DEBUG(CVE_2022_38023_warn_level, (
+			      "CVE-2022-38023: "
+			      "Option 'server schannel require seal:%s = no' not needed for '%s'!\n",
+			      log_escape(frame, creds->account_name),
+			      log_escape(frame, creds->computer_name)));
+		}
+
 		TALLOC_FREE(frame);
 		return s->result;
 	}
 
 	if (s->auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
+		if (s->seal_required) {
+			s->result = NT_STATUS_ACCESS_DENIED;
+
+			if (s->seal_explicitly_set) {
+				dbg_lvl = DBGLVL_NOTICE;
+			} else {
+				dbg_lvl = MIN(dbg_lvl, CVE_2022_38023_error_level);
+			}
+			if (s->schannel_explicitly_set && !s->schannel_required) {
+				dbg_lvl = MIN(dbg_lvl, CVE_2022_38023_warn_level);
+			}
+
+			DEBUG(dbg_lvl, (
+			      "CVE-2022-38023: "
+			      "%s request (opnum[%u]) %s schannel from "
+			      "from client_account[%s] client_computer_name[%s] %s\n",
+			      opname, opnum, reason,
+			      log_escape(frame, creds->account_name),
+			      log_escape(frame, creds->computer_name),
+			      nt_errstr(s->result)));
+			if (s->seal_explicitly_set) {
+				D_NOTICE("CVE-2022-38023: Option "
+					 "'server schannel require seal:%s = yes' "
+					 "rejects access for client.\n",
+					 log_escape(frame, creds->account_name));
+			} else {
+				DEBUG(CVE_2020_1472_error_level, (
+				      "CVE-2022-38023: Check if option "
+				      "'server schannel require seal:%s = no' "
+				      "might be needed for a legacy client.\n",
+				      log_escape(frame, creds->account_name)));
+			}
+			if (s->schannel_explicitly_set && !s->schannel_required) {
+				DEBUG(CVE_2020_1472_warn_level, (
+				      "CVE-2020-1472(ZeroLogon): Option "
+				      "'server require schannel:%s = no' "
+				      "not needed for '%s'!\n",
+				      log_escape(frame, creds->account_name),
+				      log_escape(frame, creds->computer_name)));
+			}
+			TALLOC_FREE(frame);
+			return s->result;
+		}
+
 		s->result = NT_STATUS_OK;
 
 		if (s->schannel_explicitly_set && !s->schannel_required) {
@@ -1023,6 +1152,11 @@ static NTSTATUS dcesrv_netr_check_schannel_once(struct dcesrv_call_state *dce_ca
 		} else if (!s->schannel_required) {
 			dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
 		}
+		if (s->seal_explicitly_set && !s->seal_required) {
+			dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
+		} else if (!s->seal_required) {
+			dbg_lvl = MIN(dbg_lvl, CVE_2022_38023_error_level);
+		}
 
 		DEBUG(dbg_lvl, (
 		      "CVE-2020-1472(ZeroLogon): "
@@ -1039,7 +1173,77 @@ static NTSTATUS dcesrv_netr_check_schannel_once(struct dcesrv_call_state *dce_ca
 			      log_escape(frame, creds->account_name),
 			      log_escape(frame, creds->computer_name)));
 		}
+		if (s->seal_explicitly_set && !s->seal_required) {
+			D_INFO("CVE-2022-38023: "
+			       "Option 'server schannel require seal:%s = no' still needed for '%s'!\n",
+			       log_escape(frame, creds->account_name),
+			       log_escape(frame, creds->computer_name));
+		} else if (!s->seal_required) {
+			/*
+			 * admins should set
+			 * server schannel require seal:COMPUTER$ = no
+			 * in order to avoid the level 0 messages.
+			 * Over time they can switch the global value
+			 * to be strict.
+			 */
+			DEBUG(CVE_2022_38023_error_level, (
+			      "CVE-2022-38023: "
+			      "Please use 'server schannel require seal:%s = no' "
+			      "for '%s' to avoid this warning!\n",
+			      log_escape(frame, creds->account_name),
+			      log_escape(frame, creds->computer_name)));
+		}
+
+		TALLOC_FREE(frame);
+		return s->result;
+	}
+
+	if (s->seal_required) {
+		s->result = NT_STATUS_ACCESS_DENIED;
+
+		if (s->seal_explicitly_set) {
+			dbg_lvl = MIN(dbg_lvl, DBGLVL_NOTICE);
+		} else {
+			dbg_lvl = MIN(dbg_lvl, CVE_2022_38023_error_level);
+		}
+		if (!s->schannel_explicitly_set) {
+			dbg_lvl = MIN(dbg_lvl, CVE_2020_1472_error_level);
+		} else if (s->schannel_required) {
+			dbg_lvl = MIN(dbg_lvl, DBGLVL_NOTICE);
+		}
 
+		DEBUG(dbg_lvl, (
+		      "CVE-2020-1472(ZeroLogon)/CVE-2022-38023: "
+		      "%s request (opnum[%u]) %s schannel from "
+		      "from client_account[%s] client_computer_name[%s] %s\n",
+		      opname, opnum, reason,
+		      log_escape(frame, creds->account_name),
+		      log_escape(frame, creds->computer_name),
+		      nt_errstr(s->result)));
+		if (s->seal_explicitly_set) {
+			D_NOTICE("CVE-2022-38023: Option "
+			         "'server schannel require seal:%s = yes' "
+			         "rejects access for client.\n",
+			         log_escape(frame, creds->account_name));
+		} else {
+			DEBUG(CVE_2022_38023_error_level, (
+			      "CVE-2022-38023: Check if option "
+			      "'server schannel require seal:%s = no' "
+			      "might be needed for a legacy client.\n",
+			      log_escape(frame, creds->account_name)));
+		}
+		if (!s->schannel_explicitly_set) {
+			DEBUG(CVE_2020_1472_error_level, (
+			      "CVE-2020-1472(ZeroLogon): Check if option "
+			      "'server require schannel:%s = no' "
+			      "might be needed for a legacy client.\n",
+			      log_escape(frame, creds->account_name)));
+		} else if (s->schannel_required) {
+			D_NOTICE("CVE-2022-38023: Option "
+			         "'server require schannel:%s = yes' "
+			         "also rejects access for client.\n",
+			         log_escape(frame, creds->account_name));
+		}
 		TALLOC_FREE(frame);
 		return s->result;
 	}
@@ -1052,6 +1256,9 @@ static NTSTATUS dcesrv_netr_check_schannel_once(struct dcesrv_call_state *dce_ca
 		} else {
 			dbg_lvl = MIN(dbg_lvl, CVE_2020_1472_error_level);
 		}
+		if (!s->seal_explicitly_set) {
+			dbg_lvl = MIN(dbg_lvl, CVE_2022_38023_error_level);
+		}
 
 		DEBUG(dbg_lvl, (
 		      "CVE-2020-1472(ZeroLogon)/CVE-2022-38023: "
@@ -1073,12 +1280,25 @@ static NTSTATUS dcesrv_netr_check_schannel_once(struct dcesrv_call_state *dce_ca
 			      "might be needed for a legacy client.\n",
 			      log_escape(frame, creds->account_name)));
 		}
+		if (!s->seal_explicitly_set) {
+			DEBUG(CVE_2022_38023_error_level, (
+			      "CVE-2022-38023: Check if option "
+			      "'server schannel require seal:%s = no' "
+			      "might be needed for a legacy client.\n",
+			      log_escape(frame, creds->account_name)));
+		}
 		TALLOC_FREE(frame);
 		return s->result;
 	}
 
 	s->result = NT_STATUS_OK;
 
+	if (s->seal_explicitly_set) {
+		dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
+	} else {
+		dbg_lvl = MIN(dbg_lvl, CVE_2022_38023_error_level);
+	}
+
 	if (s->schannel_explicitly_set) {
 		dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
 	} else {
@@ -1094,6 +1314,28 @@ static NTSTATUS dcesrv_netr_check_schannel_once(struct dcesrv_call_state *dce_ca
 	      log_escape(frame, creds->computer_name),
 	      nt_errstr(s->result)));
 
+	if (s->seal_explicitly_set) {
+		D_INFO("CVE-2022-38023: Option "
+		       "'server schannel require seal:%s = no' "
+		       "still needed for '%s'!\n",
+		       log_escape(frame, creds->account_name),
+		       log_escape(frame, creds->computer_name));
+	} else {
+		/*
+		 * admins should set
+		 * server schannel require seal:COMPUTER$ = no
+		 * in order to avoid the level 0 messages.
+		 * Over time they can switch the global value
+		 * to be strict.
+		 */
+		DEBUG(CVE_2022_38023_error_level, (
+		      "CVE-2022-38023: Please use "
+		       "'server schannel require seal:%s = no' "
+		      "for '%s' to avoid this warning!\n",
+		      log_escape(frame, creds->account_name),
+		      log_escape(frame, creds->computer_name)));
+	}
+
 	if (s->schannel_explicitly_set) {
 		D_INFO("CVE-2020-1472(ZeroLogon): Option "
 		       "'server require schannel:%s = no' "
-- 
2.34.1


From 8a9aed5d0dab28a20004ed6cc73f2472b11fbd41 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze@samba.org>
Date: Wed, 30 Nov 2022 15:13:47 +0100
Subject: [PATCH 29/30] CVE-2022-38023 testparm: warn about server/client
 schannel != yes

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 f964c0c357214637f80d0089723b9b11d1b38f7e)
---
 source3/utils/testparm.c | 20 +++++++++++++++++---
 1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/source3/utils/testparm.c b/source3/utils/testparm.c
index 27a8bc1fb8e8..b3ddd48b3f1d 100644
--- a/source3/utils/testparm.c
+++ b/source3/utils/testparm.c
@@ -598,11 +598,25 @@ static int do_global_checks(void)
 		ret = 1;
 	}
 
-	if (!lp_server_schannel()) {
+	if (lp_server_schannel() != true) { /* can be 'auto' */
 		fprintf(stderr,
-			"WARNING: You have configured 'server schannel = no'. "
+			"WARNING: You have not configured "
+			"'server schannel = yes' (the default). "
 			"Your server is vulernable to \"ZeroLogon\" "
-			"(CVE-2020-1472)\n\n");
+			"(CVE-2020-1472)\n"
+			"If required use individual "
+			"'server require schannel:COMPUTERACCOUNT$ = no' "
+			"options\n\n");
+	}
+	if (lp_client_schannel() != true) { /* can be 'auto' */
+		fprintf(stderr,
+			"WARNING: You have not configured "
+			"'client schannel = yes' (the default). "
+			"Your server is vulernable to \"ZeroLogon\" "
+			"(CVE-2020-1472)\n"
+			"If required use individual "
+			"'client schannel:NETBIOSDOMAIN = no' "
+			"options\n\n");
 	}
 
 	return ret;
-- 
2.34.1


From a3e10bf4b8fc328167e7219337742bf12eb41111 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze@samba.org>
Date: Tue, 6 Dec 2022 13:36:17 +0100
Subject: [PATCH 30/30] CVE-2022-38023 testparm: warn about unsecure schannel
 related options

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 4d540473c3d43d048a30dd63efaeae9ff87b2aeb)
---
 source3/utils/testparm.c | 61 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 61 insertions(+)

diff --git a/source3/utils/testparm.c b/source3/utils/testparm.c
index b3ddd48b3f1d..02ef3de83ae5 100644
--- a/source3/utils/testparm.c
+++ b/source3/utils/testparm.c
@@ -608,6 +608,37 @@ static int do_global_checks(void)
 			"'server require schannel:COMPUTERACCOUNT$ = no' "
 			"options\n\n");
 	}
+	if (lp_allow_nt4_crypto()) {
+		fprintf(stderr,
+			"WARNING: You have not configured "
+			"'allow nt4 crypto = no' (the default). "
+			"Your server is vulernable to "
+			"CVE-2022-38023 and others!\n"
+			"If required use individual "
+			"'allow nt4 crypto:COMPUTERACCOUNT$ = yes' "
+			"options\n\n");
+	}
+	if (!lp_reject_md5_clients()) {
+		fprintf(stderr,
+			"WARNING: You have not configured "
+			"'reject md5 clients = yes' (the default). "
+			"Your server is vulernable to "
+			"CVE-2022-38023!\n"
+			"If required use individual "
+			"'server reject md5 schannel:COMPUTERACCOUNT$ = yes' "
+			"options\n\n");
+	}
+	if (!lp_server_schannel_require_seal()) {
+		fprintf(stderr,
+			"WARNING: You have not configured "
+			"'server schannel require seal = yes' (the default). "
+			"Your server is vulernable to "
+			"CVE-2022-38023!\n"
+			"If required use individual "
+			"'server schannel require seal:COMPUTERACCOUNT$ = no' "
+			"options\n\n");
+	}
+
 	if (lp_client_schannel() != true) { /* can be 'auto' */
 		fprintf(stderr,
 			"WARNING: You have not configured "
@@ -618,6 +649,36 @@ static int do_global_checks(void)
 			"'client schannel:NETBIOSDOMAIN = no' "
 			"options\n\n");
 	}
+	if (!lp_reject_md5_servers()) {
+		fprintf(stderr,
+			"WARNING: You have not configured "
+			"'reject md5 servers = yes' (the default). "
+			"Your server is vulernable to "
+			"CVE-2022-38023\n"
+			"If required use individual "
+			"'reject md5 servers:NETBIOSDOMAIN = no' "
+			"options\n\n");
+	}
+	if (!lp_require_strong_key()) {
+		fprintf(stderr,
+			"WARNING: You have not configured "
+			"'require strong key = yes' (the default). "
+			"Your server is vulernable to "
+			"CVE-2022-38023\n"
+			"If required use individual "
+			"'require strong key:NETBIOSDOMAIN = no' "
+			"options\n\n");
+	}
+	if (!lp_winbind_sealed_pipes()) {
+		fprintf(stderr,
+			"WARNING: You have not configured "
+			"'winbind sealed pipes = yes' (the default). "
+			"Your server is vulernable to "
+			"CVE-2022-38023\n"
+			"If required use individual "
+			"'winbind sealed pipes:NETBIOSDOMAIN = no' "
+			"options\n\n");
+	}
 
 	return ret;
 }
-- 
2.34.1