diff --git a/SOURCES/CVE-2022-38023-for-s3-v4-16.patch b/SOURCES/CVE-2022-38023-for-s3-v4-16.patch
new file mode 100644
index 0000000..904db99
--- /dev/null
+++ b/SOURCES/CVE-2022-38023-for-s3-v4-16.patch
@@ -0,0 +1,2413 @@
+From f7c26ead133ab9b67c6802a2303a22fd98e3c41a Mon Sep 17 00:00:00 2001
+From: Samuel Cabrero <scabrero@suse.de>
+Date: Wed, 21 Dec 2022 15:53:04 +0100
+Subject: [PATCH 1/9] CVE-2022-38023 s3:rpc_server/netlogon: 'server schannel
+ != yes' warning to dcesrv_interface_netlogon_bind
+
+Follow s4 netlogon server changes and move the checks to the RPC bind
+hook. Next commits will remove the s3 netr_creds_server_step_check()
+function.
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=15240
+
+Signed-off-by: Samuel Cabrero <scabrero@samba.org>
+Reviewed-by: Andreas Schneider <asn@samba.org>
+(cherry picked from commit 8141eae47aad849741beb138fae866c772e4ec4c)
+---
+ source3/rpc_server/netlogon/srv_netlog_nt.c | 39 +++++++++++++++------
+ 1 file changed, 28 insertions(+), 11 deletions(-)
+
+diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c
+index 5906464a9f3..a3853d482df 100644
+--- a/source3/rpc_server/netlogon/srv_netlog_nt.c
++++ b/source3/rpc_server/netlogon/srv_netlog_nt.c
+@@ -1081,7 +1081,6 @@ static NTSTATUS netr_creds_server_step_check(struct pipes_struct *p,
+ 	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 (creds_out != NULL) {
+ 		*creds_out = NULL;
+@@ -1143,16 +1142,6 @@ static NTSTATUS netr_creds_server_step_check(struct pipes_struct *p,
+ 		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 "
+@@ -2997,5 +2986,33 @@ NTSTATUS _netr_DsrUpdateReadOnlyServerDnsRecords(struct pipes_struct *p,
+ 	return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ 
++/*
++ * Define the bind function that will be used by ndr_netlogon_scompat.c,
++ * included at the bottom of this file.
++ */
++#define DCESRV_INTERFACE_NETLOGON_BIND(context, iface) \
++       dcesrv_interface_netlogon_bind(context, iface)
++
++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 NT_STATUS_OK;
++}
++
+ /* include the generated boilerplate */
+ #include "librpc/gen_ndr/ndr_netlogon_scompat.c"
+-- 
+2.39.0
+
+
+From 1790cc254c10dfc0deb5ff84ff18a5f24bfd3f44 Mon Sep 17 00:00:00 2001
+From: Samuel Cabrero <scabrero@suse.de>
+Date: Thu, 22 Dec 2022 16:46:15 +0100
+Subject: [PATCH 2/9] CVE-2022-38023 selftest:Samba3: 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: Samuel Cabrero <scabrero@samba.org>
+Reviewed-by: Andreas Schneider <asn@samba.org>
+(cherry picked from commit 3cd18690f83d2f85e847fc703ac127b4b04189fc)
+---
+ selftest/target/Samba3.pm | 16 +++++++++++++++-
+ 1 file changed, 15 insertions(+), 1 deletion(-)
+
+diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
+index 0b720a68927..b58f3d45118 100755
+--- a/selftest/target/Samba3.pm
++++ b/selftest/target/Samba3.pm
+@@ -271,9 +271,23 @@ sub setup_nt4_dc
+ 	lanman auth = yes
+ 	ntlm auth = yes
+ 	raw NTLMv2 auth = yes
+-	server schannel = auto
+ 	rpc start on demand helpers = false
+ 
++	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
++
+ 	fss: sequence timeout = 1
+ 	check parent directory delete on close = yes
+ ";
+-- 
+2.39.0
+
+
+From 0e7e7ddbf5524b8aec595227a04cb09599c61a81 Mon Sep 17 00:00:00 2001
+From: Samuel Cabrero <scabrero@samba.org>
+Date: Thu, 5 Jan 2023 18:13:09 +0100
+Subject: [PATCH 3/9] CVE-2022-38023 s4:rpc_server:wscript: Reformat following
+ pycodestyle
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=15240
+
+Signed-off-by: Samuel Cabrero <scabrero@samba.org>
+Reviewed-by: Andreas Schneider <asn@samba.org>
+(cherry picked from commit d9e6b490db3ead7e79bb3ff0c1f9ef8ab8bdc65b)
+---
+ source4/rpc_server/wscript_build | 290 ++++++++++++++++++-------------
+ 1 file changed, 168 insertions(+), 122 deletions(-)
+
+diff --git a/source4/rpc_server/wscript_build b/source4/rpc_server/wscript_build
+index 8c756721232..e7bb773d719 100644
+--- a/source4/rpc_server/wscript_build
++++ b/source4/rpc_server/wscript_build
+@@ -1,174 +1,220 @@
+ #!/usr/bin/env python
+ 
+ bld.SAMBA_SUBSYSTEM('DCERPC_SHARE',
+-	source='common/share_info.c',
+-	autoproto='common/share.h',
+-	deps='ldb share',
+-	enabled=bld.CONFIG_SET('WITH_NTVFS_FILESERVER'),
+-	)
++                    source='common/share_info.c',
++                    autoproto='common/share.h',
++                    deps='ldb share',
++                    enabled=bld.CONFIG_SET('WITH_NTVFS_FILESERVER'),
++                    )
+ 
+ bld.SAMBA_SUBSYSTEM('DCERPC_COMMON',
+-	source='common/server_info.c common/forward.c common/loadparm.c',
+-	autoproto='common/proto.h',
+-	deps='ldb DCERPC_SHARE',
+-	enabled=bld.AD_DC_BUILD_IS_ENABLED()
+-	)
++                    source='''
++                           common/server_info.c
++                           common/forward.c
++                           common/loadparm.c
++                           ''',
++                    autoproto='common/proto.h',
++                    deps='ldb DCERPC_SHARE',
++                    enabled=bld.AD_DC_BUILD_IS_ENABLED()
++                    )
+ 
+ bld.SAMBA_LIBRARY('dcerpc_server',
+-	source='dcerpc_server.c',
+-	pc_files='dcerpc_server.pc',
+-	deps='LIBCLI_AUTH ndr samba_server_gensec service auth',
+-	public_deps='dcerpc dcerpc-server-core',
+-	autoproto='dcerpc_server_proto.h',
+-	public_headers='dcerpc_server.h',
+-	vnum='0.0.1',
+-	enabled=bld.AD_DC_BUILD_IS_ENABLED()
+-	)
++                  source='dcerpc_server.c',
++                  pc_files='dcerpc_server.pc',
++                  deps='LIBCLI_AUTH ndr samba_server_gensec service auth',
++                  public_deps='dcerpc dcerpc-server-core',
++                  autoproto='dcerpc_server_proto.h',
++                  public_headers='dcerpc_server.h',
++                  vnum='0.0.1',
++                  enabled=bld.AD_DC_BUILD_IS_ENABLED()
++                  )
+ 
+ bld.SAMBA_MODULE('dcerpc_rpcecho',
+-	source='echo/rpc_echo.c',
+-	subsystem='dcerpc_server',
+-	init_function='dcerpc_server_rpcecho_init',
+-	deps='ndr-standard events'
+-	)
++                 source='echo/rpc_echo.c',
++                 subsystem='dcerpc_server',
++                 init_function='dcerpc_server_rpcecho_init',
++                 deps='ndr-standard events'
++                 )
+ 
+ 
+ bld.SAMBA_MODULE('dcerpc_epmapper',
+-	source='epmapper/rpc_epmapper.c',
+-	subsystem='dcerpc_server',
+-	init_function='dcerpc_server_epmapper_init',
+-	deps='NDR_EPMAPPER'
+-	)
++                 source='epmapper/rpc_epmapper.c',
++                 subsystem='dcerpc_server',
++                 init_function='dcerpc_server_epmapper_init',
++                 deps='NDR_EPMAPPER'
++                 )
+ 
+ 
+ bld.SAMBA_MODULE('dcerpc_remote',
+-	source='remote/dcesrv_remote.c',
+-	subsystem='dcerpc_server',
+-	init_function='dcerpc_server_remote_init',
+-	deps='LIBCLI_SMB ndr-table'
+-	)
++                 source='remote/dcesrv_remote.c',
++                 subsystem='dcerpc_server',
++                 init_function='dcerpc_server_remote_init',
++                 deps='LIBCLI_SMB ndr-table'
++                 )
+ 
+ 
+ bld.SAMBA_MODULE('dcerpc_srvsvc',
+-	source='srvsvc/dcesrv_srvsvc.c srvsvc/srvsvc_ntvfs.c',
+-	autoproto='srvsvc/proto.h',
+-	subsystem='dcerpc_server',
+-	init_function='dcerpc_server_srvsvc_init',
+-	deps='DCERPC_COMMON NDR_SRVSVC share ntvfs',
+-	enabled=bld.CONFIG_SET('WITH_NTVFS_FILESERVER')
+-	)
++                 source='srvsvc/dcesrv_srvsvc.c srvsvc/srvsvc_ntvfs.c',
++                 autoproto='srvsvc/proto.h',
++                 subsystem='dcerpc_server',
++                 init_function='dcerpc_server_srvsvc_init',
++                 deps='DCERPC_COMMON NDR_SRVSVC share ntvfs',
++                 enabled=bld.CONFIG_SET('WITH_NTVFS_FILESERVER')
++                 )
+ 
+ 
+ bld.SAMBA_MODULE('dcerpc_wkssvc',
+-	source='wkssvc/dcesrv_wkssvc.c',
+-	subsystem='dcerpc_server',
+-	init_function='dcerpc_server_wkssvc_init',
+-	deps='DCERPC_COMMON ndr-standard'
+-	)
++                 source='wkssvc/dcesrv_wkssvc.c',
++                 subsystem='dcerpc_server',
++                 init_function='dcerpc_server_wkssvc_init',
++                 deps='DCERPC_COMMON ndr-standard'
++                 )
+ 
+ 
+ bld.SAMBA_MODULE('dcerpc_unixinfo',
+-	source='unixinfo/dcesrv_unixinfo.c',
+-	subsystem='dcerpc_server',
+-	init_function='dcerpc_server_unixinfo_init',
+-	deps='DCERPC_COMMON samdb NDR_UNIXINFO LIBWBCLIENT_OLD'
+-	)
++                 source='unixinfo/dcesrv_unixinfo.c',
++                 subsystem='dcerpc_server',
++                 init_function='dcerpc_server_unixinfo_init',
++                 deps='DCERPC_COMMON samdb NDR_UNIXINFO LIBWBCLIENT_OLD'
++                 )
+ 
+ 
+ bld.SAMBA_MODULE('dcesrv_samr',
+-	source='samr/dcesrv_samr.c samr/samr_password.c',
+-	autoproto='samr/proto.h',
+-	subsystem='dcerpc_server',
+-	init_function='dcerpc_server_samr_init',
+-	deps='samdb DCERPC_COMMON ndr-standard auth4_sam GNUTLS_HELPERS DCERPC_HELPER'
+-	)
++                 source='samr/dcesrv_samr.c samr/samr_password.c',
++                 autoproto='samr/proto.h',
++                 subsystem='dcerpc_server',
++                 init_function='dcerpc_server_samr_init',
++                 deps='''
++                      samdb
++                      DCERPC_COMMON
++                      ndr-standard
++                      auth4_sam
++                      GNUTLS_HELPERS
++                      DCERPC_HELPER
++                      '''
++                 )
+ 
+ 
+ bld.SAMBA_MODULE('dcerpc_winreg',
+-	source='winreg/rpc_winreg.c',
+-	subsystem='dcerpc_server',
+-	init_function='dcerpc_server_winreg_init',
+-	deps='registry ndr-standard',
+-	internal_module=True,
+-	enabled=bld.CONFIG_SET('WITH_NTVFS_FILESERVER')
+-	)
++                 source='winreg/rpc_winreg.c',
++                 subsystem='dcerpc_server',
++                 init_function='dcerpc_server_winreg_init',
++                 deps='registry ndr-standard',
++                 internal_module=True,
++                 enabled=bld.CONFIG_SET('WITH_NTVFS_FILESERVER')
++                 )
+ 
+ 
+ bld.SAMBA_MODULE('dcerpc_netlogon',
+-	source='netlogon/dcerpc_netlogon.c',
+-	subsystem='dcerpc_server',
+-	init_function='dcerpc_server_netlogon_init',
+-	deps='''DCERPC_COMMON RPC_NDR_IRPC COMMON_SCHANNEL ndr-standard auth4_sam samba-hostconfig DSDB_MODULE_HELPERS
+-        util_str_escape'''
+-	)
++                 source='netlogon/dcerpc_netlogon.c',
++                 subsystem='dcerpc_server',
++                 init_function='dcerpc_server_netlogon_init',
++                 deps='''
++                      DCERPC_COMMON
++                      RPC_NDR_IRPC
++                      COMMON_SCHANNEL
++                      ndr-standard
++                      auth4_sam
++                      samba-hostconfig
++                      DSDB_MODULE_HELPERS
++                      util_str_escape
++                      '''
++                 )
+ 
+ 
+ bld.SAMBA_MODULE('dcerpc_lsarpc',
+-	source='lsa/dcesrv_lsa.c lsa/lsa_init.c lsa/lsa_lookup.c',
+-	autoproto='lsa/proto.h',
+-	subsystem='dcerpc_server',
+-	init_function='dcerpc_server_lsa_init',
+-	deps='samdb DCERPC_COMMON ndr-standard LIBCLI_AUTH NDR_DSSETUP com_err samba-security UTIL_LSARPC'
+-	)
++                 source='lsa/dcesrv_lsa.c lsa/lsa_init.c lsa/lsa_lookup.c',
++                 autoproto='lsa/proto.h',
++                 subsystem='dcerpc_server',
++                 init_function='dcerpc_server_lsa_init',
++                 deps='''
++                      samdb
++                      DCERPC_COMMON
++                      ndr-standard
++                      LIBCLI_AUTH
++                      NDR_DSSETUP
++                      com_err
++                      samba-security
++                      UTIL_LSARPC
++                      '''
++                 )
+ 
+ 
+ bld.SAMBA_MODULE('dcerpc_backupkey',
+-		 source='backupkey/dcesrv_backupkey.c ',
+-		 autoproto='backupkey/proto.h',
+-		 subsystem='dcerpc_server',
+-		 init_function='dcerpc_server_backupkey_init',
+-		 deps='samdb DCERPC_COMMON NDR_BACKUPKEY RPC_NDR_BACKUPKEY gnutls GNUTLS_HELPERS',
+-		 )
++                 source='backupkey/dcesrv_backupkey.c ',
++                 autoproto='backupkey/proto.h',
++                 subsystem='dcerpc_server',
++                 init_function='dcerpc_server_backupkey_init',
++                 deps='''
++                      samdb
++                      DCERPC_COMMON
++                      NDR_BACKUPKEY
++                      RPC_NDR_BACKUPKEY
++                      gnutls
++                      GNUTLS_HELPERS
++                      ''',
++                 )
+ 
+ 
+ bld.SAMBA_MODULE('dcerpc_drsuapi',
+-	source='drsuapi/dcesrv_drsuapi.c drsuapi/updaterefs.c drsuapi/getncchanges.c drsuapi/addentry.c drsuapi/writespn.c drsuapi/drsutil.c',
+-	subsystem='dcerpc_server',
+-	init_function='dcerpc_server_drsuapi_init',
+-	deps='samdb DCERPC_COMMON NDR_DRSUAPI samba-security'
+-	)
++                 source='''
++                        drsuapi/dcesrv_drsuapi.c
++                        drsuapi/updaterefs.c
++                        drsuapi/getncchanges.c
++                        drsuapi/addentry.c
++                        drsuapi/writespn.c
++                        drsuapi/drsutil.c
++                        ''',
++                 subsystem='dcerpc_server',
++                 init_function='dcerpc_server_drsuapi_init',
++                 deps='samdb DCERPC_COMMON NDR_DRSUAPI samba-security'
++                 )
+ 
+ 
+ bld.SAMBA_MODULE('dcerpc_browser',
+-	source='browser/dcesrv_browser.c',
+-	subsystem='dcerpc_server',
+-	init_function='dcerpc_server_browser_init',
+-	deps='DCERPC_COMMON NDR_BROWSER'
+-	)
++                 source='browser/dcesrv_browser.c',
++                 subsystem='dcerpc_server',
++                 init_function='dcerpc_server_browser_init',
++                 deps='DCERPC_COMMON NDR_BROWSER'
++                 )
+ 
+ bld.SAMBA_MODULE('dcerpc_eventlog',
+-	source='eventlog/dcesrv_eventlog6.c',
+-	subsystem='dcerpc_server',
+-	init_function='dcerpc_server_eventlog6_init',
+-	deps='DCERPC_COMMON'
+-	)
++                 source='eventlog/dcesrv_eventlog6.c',
++                 subsystem='dcerpc_server',
++                 init_function='dcerpc_server_eventlog6_init',
++                 deps='DCERPC_COMMON'
++                 )
+ 
+ bld.SAMBA_MODULE('dcerpc_dnsserver',
+-    source='dnsserver/dcerpc_dnsserver.c dnsserver/dnsutils.c dnsserver/dnsdata.c dnsserver/dnsdb.c',
+-    subsystem='dcerpc_server',
+-    init_function='dcerpc_server_dnsserver_init',
+-    deps='DCERPC_COMMON dnsserver_common netif'
+-    )
++                 source='''
++                        dnsserver/dcerpc_dnsserver.c
++                        dnsserver/dnsutils.c
++                        dnsserver/dnsdata.c
++                        dnsserver/dnsdb.c
++                        ''',
++                 subsystem='dcerpc_server',
++                 init_function='dcerpc_server_dnsserver_init',
++                 deps='DCERPC_COMMON dnsserver_common netif'
++                 )
+ 
+ 
+ bld.SAMBA_MODULE('service_dcerpc',
+-	source='service_rpc.c',
+-	autoproto='service_rpc.h',
+-	subsystem='service',
+-	init_function='server_service_rpc_init',
+-	internal_module=False,
+-	deps='dcerpc_server'
+-	)
+-
+-bld.SAMBA_BINARY(
+-    'test_rpc_dns_server_dnsutils',
+-    source='tests/rpc_dns_server_dnsutils_test.c',
+-    deps='''
+-            dnsserver_common
+-            dcerpc_server
+-            cmocka
+-            talloc
+-    ''',
+-    for_selftest=True,
+-    enabled=bld.AD_DC_BUILD_IS_ENABLED()
+-)
++                 source='service_rpc.c',
++                 autoproto='service_rpc.h',
++                 subsystem='service',
++                 init_function='server_service_rpc_init',
++                 internal_module=False,
++                 deps='dcerpc_server'
++                 )
++
++bld.SAMBA_BINARY('test_rpc_dns_server_dnsutils',
++                 source='tests/rpc_dns_server_dnsutils_test.c',
++                 deps='''
++                      dnsserver_common
++                      dcerpc_server
++                      cmocka
++                      talloc
++                      ''',
++                 for_selftest=True,
++                 enabled=bld.AD_DC_BUILD_IS_ENABLED()
++                 )
+-- 
+2.39.0
+
+
+From 740422fb6609dac3b0e2c1bb91d61b87e99c64aa Mon Sep 17 00:00:00 2001
+From: Samuel Cabrero <scabrero@suse.de>
+Date: Thu, 22 Dec 2022 14:03:23 +0100
+Subject: [PATCH 4/9] CVE-2022-38023 s4:rpc_server/netlogon: Move schannel and
+ credentials check functions to librpc
+
+Will be used later by s3 netlogon server.
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=15240
+
+Signed-off-by: Samuel Cabrero <scabrero@samba.org>
+Reviewed-by: Andreas Schneider <asn@samba.org>
+(cherry picked from commit 121e7b0e39478c5291100652ac92c263f406076b)
+---
+ librpc/rpc/server/netlogon/schannel_util.c    | 576 ++++++++++++++++++
+ librpc/rpc/server/netlogon/schannel_util.h    |  54 ++
+ librpc/wscript_build                          |  12 +
+ source4/rpc_server/netlogon/dcerpc_netlogon.c | 546 +----------------
+ source4/rpc_server/wscript_build              |   2 +-
+ 5 files changed, 644 insertions(+), 546 deletions(-)
+ create mode 100644 librpc/rpc/server/netlogon/schannel_util.c
+ create mode 100644 librpc/rpc/server/netlogon/schannel_util.h
+
+diff --git a/librpc/rpc/server/netlogon/schannel_util.c b/librpc/rpc/server/netlogon/schannel_util.c
+new file mode 100644
+index 00000000000..9b2a88a2628
+--- /dev/null
++++ b/librpc/rpc/server/netlogon/schannel_util.c
+@@ -0,0 +1,576 @@
++/*
++   Unix SMB/CIFS implementation.
++
++   netlogon schannel utility functions
++
++   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2008
++   Copyright (C) Stefan Metzmacher <metze@samba.org>  2005
++   Copyright (C) Matthias Dieter Wallnöfer            2009-2010
++
++   This program is free software; you can redistribute it and/or modify
++   it under the terms of the GNU General Public License as published by
++   the Free Software Foundation; either version 3 of the License, or
++   (at your option) any later version.
++
++   This program is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU General Public License for more details.
++
++   You should have received a copy of the GNU General Public License
++   along with this program.  If not, see <http://www.gnu.org/licenses/>.
++*/
++
++#include "includes.h"
++#include "schannel_util.h"
++#include "param/param.h"
++#include "libcli/security/dom_sid.h"
++#include "libcli/auth/schannel.h"
++#include "librpc/rpc/dcesrv_core.h"
++#include "librpc/gen_ndr/ndr_netlogon.h"
++#include "lib/util/util_str_escape.h"
++
++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;
++
++	bool seal_global_required;
++	bool seal_required;
++	bool seal_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;
++	int schannel = lpcfg_server_schannel(lp_ctx);
++	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;
++
++	*_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_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
++	 * 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;
++
++	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);
++	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);
++	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>";
++	const char *reason = "<unknown>";
++
++	if (opnum < ndr_table_netlogon.num_calls) {
++		opname = ndr_table_netlogon.calls[opnum].name;
++	}
++
++	if (s->auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
++		if (s->auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
++			reason = "WITH SEALED";
++		} else if (s->auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
++			reason = "WITH SIGNED";
++		} else {
++			reason = "WITH INVALID";
++			dbg_lvl = DBGLVL_ERR;
++			s->result = NT_STATUS_INTERNAL_ERROR;
++		}
++	} else {
++		reason = "WITHOUT";
++	}
++
++	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)/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) {
++			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, DBGLVL_INFO);
++		} else if (!s->seal_required) {
++			dbg_lvl = MIN(dbg_lvl, CVE_2022_38023_error_level);
++		}
++
++		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)));
++		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) {
++			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;
++	}
++
++	if (s->schannel_required) {
++		s->result = NT_STATUS_ACCESS_DENIED;
++
++		if (s->schannel_explicitly_set) {
++			dbg_lvl = MIN(dbg_lvl, DBGLVL_NOTICE);
++		} 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: "
++		      "%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) {
++			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)));
++		}
++		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 {
++		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(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' "
++		       "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)));
++	}
++
++	TALLOC_FREE(frame);
++	return s->result;
++}
++
++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;
++}
++
++/*
++ * 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.
++ */
++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;
++}
+diff --git a/librpc/rpc/server/netlogon/schannel_util.h b/librpc/rpc/server/netlogon/schannel_util.h
+new file mode 100644
+index 00000000000..561e2567e02
+--- /dev/null
++++ b/librpc/rpc/server/netlogon/schannel_util.h
+@@ -0,0 +1,54 @@
++/*
++   Unix SMB/CIFS implementation.
++
++   netlogon schannel utility functions
++
++   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2008
++   Copyright (C) Stefan Metzmacher <metze@samba.org>  2005
++   Copyright (C) Matthias Dieter Wallnöfer            2009-2010
++
++   This program is free software; you can redistribute it and/or modify
++   it under the terms of the GNU General Public License as published by
++   the Free Software Foundation; either version 3 of the License, or
++   (at your option) any later version.
++
++   This program is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU General Public License for more details.
++
++   You should have received a copy of the GNU General Public License
++   along with this program.  If not, see <http://www.gnu.org/licenses/>.
++*/
++
++#ifndef __LIBRPC_RPC_SERVER_NETLOGON_SCHANNEL_UTIL_H__
++#define __LIBRPC_RPC_SERVER_NETLOGON_SCHANNEL_UTIL_H__
++
++#include "replace.h"
++#include <talloc.h>
++#include "libcli/util/ntstatus.h"
++
++#define NETLOGON_SERVER_PIPE_STATE_MAGIC 0x4f555358
++
++struct dcesrv_call_state;
++struct netlogon_creds_CredentialState;
++struct netr_Authenticator;
++enum dcerpc_AuthType;
++enum dcerpc_AuthLevel;
++
++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);
++
++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);
++
++#endif /* __LIBRPC_RPC_SERVER_NETLOGON_SCHANNEL_UTIL_H__ */
+diff --git a/librpc/wscript_build b/librpc/wscript_build
+index b82209b4299..f22ab2eabae 100644
+--- a/librpc/wscript_build
++++ b/librpc/wscript_build
+@@ -678,6 +678,18 @@ bld.SAMBA_LIBRARY('dcerpc-pkt-auth',
+                    ''',
+                   deps='dcerpc-binding gensec')
+ 
++bld.SAMBA_SUBSYSTEM('DCERPC_SERVER_NETLOGON',
++                    source='''
++                           rpc/server/netlogon/schannel_util.c
++                           ''',
++                    deps='''
++                         talloc
++                         util_str_escape
++                         samba-hostconfig
++                         NDR_NETLOGON
++                         dcerpc-server-core
++                         ''')
++
+ bld.SAMBA_LIBRARY('dcerpc-server-core',
+     source='''
+            rpc/dcesrv_core.c
+diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
+index ddcb8487a56..6a3e044eb9d 100644
+--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
++++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
+@@ -42,6 +42,7 @@
+ #include "librpc/gen_ndr/ndr_irpc.h"
+ #include "librpc/gen_ndr/ndr_winbind.h"
+ #include "librpc/gen_ndr/ndr_winbind_c.h"
++#include "librpc/rpc/server/netlogon/schannel_util.h"
+ #include "lib/socket/netif.h"
+ #include "lib/util/util_str_escape.h"
+ #include "lib/param/loadparm.h"
+@@ -889,551 +890,6 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate2(struct dcesrv_call_state *dce_ca
+ 	return dcesrv_netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
+ }
+ 
+-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;
+-
+-	bool seal_global_required;
+-	bool seal_required;
+-	bool seal_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;
+-	int schannel = lpcfg_server_schannel(lp_ctx);
+-	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;
+-
+-	*_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_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
+-	 * 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;
+-
+-	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);
+-	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);
+-	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>";
+-	const char *reason = "<unknown>";
+-
+-	if (opnum < ndr_table_netlogon.num_calls) {
+-		opname = ndr_table_netlogon.calls[opnum].name;
+-	}
+-
+-	if (s->auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
+-		if (s->auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
+-			reason = "WITH SEALED";
+-		} else if (s->auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
+-			reason = "WITH SIGNED";
+-		} else {
+-			reason = "WITH INVALID";
+-			dbg_lvl = DBGLVL_ERR;
+-			s->result = NT_STATUS_INTERNAL_ERROR;
+-		}
+-	} else {
+-		reason = "WITHOUT";
+-	}
+-
+-	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)/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) {
+-			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, DBGLVL_INFO);
+-		} else if (!s->seal_required) {
+-			dbg_lvl = MIN(dbg_lvl, CVE_2022_38023_error_level);
+-		}
+-
+-		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)));
+-		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) {
+-			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;
+-	}
+-
+-	if (s->schannel_required) {
+-		s->result = NT_STATUS_ACCESS_DENIED;
+-
+-		if (s->schannel_explicitly_set) {
+-			dbg_lvl = MIN(dbg_lvl, DBGLVL_NOTICE);
+-		} 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: "
+-		      "%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) {
+-			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)));
+-		}
+-		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 {
+-		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(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' "
+-		       "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)));
+-	}
+-
+-	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;
+-}
+-
+-/*
+- * 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#.
+diff --git a/source4/rpc_server/wscript_build b/source4/rpc_server/wscript_build
+index e7bb773d719..0e44a3c2bae 100644
+--- a/source4/rpc_server/wscript_build
++++ b/source4/rpc_server/wscript_build
+@@ -118,10 +118,10 @@ bld.SAMBA_MODULE('dcerpc_netlogon',
+                       samba-hostconfig
+                       DSDB_MODULE_HELPERS
+                       util_str_escape
++                      DCERPC_SERVER_NETLOGON
+                       '''
+                  )
+ 
+-
+ bld.SAMBA_MODULE('dcerpc_lsarpc',
+                  source='lsa/dcesrv_lsa.c lsa/lsa_init.c lsa/lsa_lookup.c',
+                  autoproto='lsa/proto.h',
+-- 
+2.39.0
+
+
+From 1a1f5c53c217b5336464885a70e7eef94dd0ad5f Mon Sep 17 00:00:00 2001
+From: Samuel Cabrero <scabrero@suse.de>
+Date: Thu, 22 Dec 2022 16:30:26 +0100
+Subject: [PATCH 5/9] CVE-2022-38023 s3:rpc_server/netlogon: Use
+ dcesrv_netr_creds_server_step_check()
+
+After s3 and s4 rpc servers merge we can avoid duplicated code.
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=15240
+
+Signed-off-by: Samuel Cabrero <scabrero@samba.org>
+Reviewed-by: Andreas Schneider <asn@samba.org>
+(cherry picked from commit 25300d354c80995997d552581cd91dddaf4bbf48)
+---
+ librpc/rpc/server/netlogon/schannel_util.c  |   6 -
+ selftest/target/Samba3.pm                   |  14 ++
+ source3/rpc_server/netlogon/srv_netlog_nt.c | 201 +++++---------------
+ source3/rpc_server/wscript_build            |   2 +-
+ 4 files changed, 58 insertions(+), 165 deletions(-)
+
+diff --git a/librpc/rpc/server/netlogon/schannel_util.c b/librpc/rpc/server/netlogon/schannel_util.c
+index 9b2a88a2628..b14497b13ce 100644
+--- a/librpc/rpc/server/netlogon/schannel_util.c
++++ b/librpc/rpc/server/netlogon/schannel_util.c
+@@ -529,12 +529,6 @@ NTSTATUS dcesrv_netr_check_schannel(struct dcesrv_call_state *dce_call,
+ 	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.
+- */
+ NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dce_call,
+ 						    TALLOC_CTX *mem_ctx,
+ 						    const char *computer_name,
+diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
+index b58f3d45118..75256db675c 100755
+--- a/selftest/target/Samba3.pm
++++ b/selftest/target/Samba3.pm
+@@ -288,6 +288,20 @@ sub setup_nt4_dc
+ 	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
++
+ 	fss: sequence timeout = 1
+ 	check parent directory delete on close = yes
+ ";
+diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c
+index a3853d482df..8e0ea522b6d 100644
+--- a/source3/rpc_server/netlogon/srv_netlog_nt.c
++++ b/source3/rpc_server/netlogon/srv_netlog_nt.c
+@@ -51,6 +51,7 @@
+ #include "libsmb/dsgetdcname.h"
+ #include "lib/util/util_str_escape.h"
+ #include "source3/lib/substitute.h"
++#include "librpc/rpc/server/netlogon/schannel_util.h"
+ 
+ extern userdom_struct current_user_info;
+ 
+@@ -1061,129 +1062,6 @@ NTSTATUS _netr_ServerAuthenticate2(struct pipes_struct *p,
+ 	return _netr_ServerAuthenticate3(p, &a);
+ }
+ 
+-/*************************************************************************
+- *************************************************************************/
+-
+-static NTSTATUS netr_creds_server_step_check(struct pipes_struct *p,
+-					     TALLOC_CTX *mem_ctx,
+-					     const char *computer_name,
+-					     struct netr_Authenticator *received_authenticator,
+-					     struct netr_Authenticator *return_authenticator,
+-					     struct netlogon_creds_CredentialState **creds_out)
+-{
+-	struct dcesrv_call_state *dce_call = p->dce_call;
+-	NTSTATUS status;
+-	bool schannel_global_required = (lp_server_schannel() == true) ? true:false;
+-	bool schannel_required = schannel_global_required;
+-	const char *explicit_opt = NULL;
+-	struct loadparm_context *lp_ctx;
+-	struct netlogon_creds_CredentialState *creds = NULL;
+-	enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
+-	uint16_t opnum = dce_call->pkt.u.request.opnum;
+-	const char *opname = "<unknown>";
+-
+-	if (creds_out != NULL) {
+-		*creds_out = NULL;
+-	}
+-
+-	if (opnum < ndr_table_netlogon.num_calls) {
+-		opname = ndr_table_netlogon.calls[opnum].name;
+-	}
+-
+-	dcesrv_call_auth_info(dce_call, &auth_type, NULL);
+-
+-	lp_ctx = loadparm_init_s3(mem_ctx, loadparm_s3_helpers());
+-	if (lp_ctx == NULL) {
+-		DEBUG(0, ("loadparm_init_s3 failed\n"));
+-		return NT_STATUS_INTERNAL_ERROR;
+-	}
+-
+-	status = schannel_check_creds_state(mem_ctx, lp_ctx,
+-					    computer_name, received_authenticator,
+-					    return_authenticator, &creds);
+-	talloc_unlink(mem_ctx, lp_ctx);
+-
+-	if (!NT_STATUS_IS_OK(status)) {
+-		ZERO_STRUCTP(return_authenticator);
+-		return status;
+-	}
+-
+-	/*
+-	 * We don't use lp_parm_bool(), as we
+-	 * need the explicit_opt pointer in order to
+-	 * adjust the debug messages.
+-	 */
+-
+-	explicit_opt = lp_parm_const_string(GLOBAL_SECTION_SNUM,
+-					    "server require schannel",
+-					    creds->account_name,
+-					    NULL);
+-	if (explicit_opt != NULL) {
+-		schannel_required = lp_bool(explicit_opt);
+-	}
+-
+-	if (schannel_required) {
+-		if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
+-			*creds_out = creds;
+-			return NT_STATUS_OK;
+-		}
+-
+-		DBG_ERR("CVE-2020-1472(ZeroLogon): "
+-			"%s request (opnum[%u]) without schannel from "
+-			"client_account[%s] client_computer_name[%s]\n",
+-			opname, opnum,
+-			log_escape(mem_ctx, creds->account_name),
+-			log_escape(mem_ctx, creds->computer_name));
+-		DBG_ERR("CVE-2020-1472(ZeroLogon): Check if option "
+-			"'server require schannel:%s = no' is needed! \n",
+-			log_escape(mem_ctx, creds->account_name));
+-		TALLOC_FREE(creds);
+-		ZERO_STRUCTP(return_authenticator);
+-		return NT_STATUS_ACCESS_DENIED;
+-	}
+-
+-	if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
+-		DBG_ERR("CVE-2020-1472(ZeroLogon): "
+-			"%s request (opnum[%u]) WITH schannel from "
+-			"client_account[%s] client_computer_name[%s]\n",
+-			opname, opnum,
+-			log_escape(mem_ctx, creds->account_name),
+-			log_escape(mem_ctx, creds->computer_name));
+-		DBG_ERR("CVE-2020-1472(ZeroLogon): "
+-			"Option 'server require schannel:%s = no' not needed!?\n",
+-			log_escape(mem_ctx, creds->account_name));
+-
+-		*creds_out = creds;
+-		return NT_STATUS_OK;
+-	}
+-
+-	if (explicit_opt != NULL) {
+-		DBG_INFO("CVE-2020-1472(ZeroLogon): "
+-			 "%s request (opnum[%u]) without schannel from "
+-			 "client_account[%s] client_computer_name[%s]\n",
+-			 opname, opnum,
+-			 log_escape(mem_ctx, creds->account_name),
+-			 log_escape(mem_ctx, creds->computer_name));
+-		DBG_INFO("CVE-2020-1472(ZeroLogon): "
+-			 "Option 'server require schannel:%s = no' still needed!\n",
+-			 log_escape(mem_ctx, creds->account_name));
+-	} else {
+-		DBG_ERR("CVE-2020-1472(ZeroLogon): "
+-			"%s request (opnum[%u]) without schannel from "
+-			"client_account[%s] client_computer_name[%s]\n",
+-			opname, opnum,
+-			log_escape(mem_ctx, creds->account_name),
+-			log_escape(mem_ctx, creds->computer_name));
+-		DBG_ERR("CVE-2020-1472(ZeroLogon): Check if option "
+-			"'server require schannel:%s = no' might be needed!\n",
+-			log_escape(mem_ctx, creds->account_name));
+-	}
+-
+-	*creds_out = creds;
+-	return NT_STATUS_OK;
+-}
+-
+-
+ /*************************************************************************
+  *************************************************************************/
+ 
+@@ -1429,11 +1307,12 @@ NTSTATUS _netr_ServerPasswordSet(struct pipes_struct *p,
+ 	DEBUG(5,("_netr_ServerPasswordSet: %d\n", __LINE__));
+ 
+ 	become_root();
+-	status = netr_creds_server_step_check(p, p->mem_ctx,
+-					      r->in.computer_name,
+-					      r->in.credential,
+-					      r->out.return_authenticator,
+-					      &creds);
++	status = dcesrv_netr_creds_server_step_check(p->dce_call,
++						p->mem_ctx,
++						r->in.computer_name,
++						r->in.credential,
++						r->out.return_authenticator,
++						&creds);
+ 	unbecome_root();
+ 
+ 	if (!NT_STATUS_IS_OK(status)) {
+@@ -1493,11 +1372,12 @@ NTSTATUS _netr_ServerPasswordSet2(struct pipes_struct *p,
+ 	bool ok;
+ 
+ 	become_root();
+-	status = netr_creds_server_step_check(p, p->mem_ctx,
+-					      r->in.computer_name,
+-					      r->in.credential,
+-					      r->out.return_authenticator,
+-					      &creds);
++	status = dcesrv_netr_creds_server_step_check(p->dce_call,
++						p->mem_ctx,
++						r->in.computer_name,
++						r->in.credential,
++						r->out.return_authenticator,
++						&creds);
+ 	unbecome_root();
+ 
+ 	if (!NT_STATUS_IS_OK(status)) {
+@@ -1644,11 +1524,12 @@ NTSTATUS _netr_LogonSamLogoff(struct pipes_struct *p,
+ 	struct netlogon_creds_CredentialState *creds;
+ 
+ 	become_root();
+-	status = netr_creds_server_step_check(p, p->mem_ctx,
+-					      r->in.computer_name,
+-					      r->in.credential,
+-					      r->out.return_authenticator,
+-					      &creds);
++	status = dcesrv_netr_creds_server_step_check(p->dce_call,
++						p->mem_ctx,
++						r->in.computer_name,
++						r->in.credential,
++						r->out.return_authenticator,
++						&creds);
+ 	unbecome_root();
+ 
+ 	return status;
+@@ -2061,11 +1942,12 @@ NTSTATUS _netr_LogonSamLogonWithFlags(struct pipes_struct *p,
+ 	}
+ 
+ 	become_root();
+-	status = netr_creds_server_step_check(p, p->mem_ctx,
+-					      r->in.computer_name,
+-					      r->in.credential,
+-					      &return_authenticator,
+-					      &creds);
++	status = dcesrv_netr_creds_server_step_check(p->dce_call,
++						p->mem_ctx,
++						r->in.computer_name,
++						r->in.credential,
++						&return_authenticator,
++						&creds);
+ 	unbecome_root();
+ 	if (!NT_STATUS_IS_OK(status)) {
+ 		return status;
+@@ -2411,11 +2293,12 @@ NTSTATUS _netr_LogonGetCapabilities(struct pipes_struct *p,
+ 	NTSTATUS status;
+ 
+ 	become_root();
+-	status = netr_creds_server_step_check(p, p->mem_ctx,
+-					      r->in.computer_name,
+-					      r->in.credential,
+-					      r->out.return_authenticator,
+-					      &creds);
++	status = dcesrv_netr_creds_server_step_check(p->dce_call,
++						p->mem_ctx,
++						r->in.computer_name,
++						r->in.credential,
++						r->out.return_authenticator,
++						&creds);
+ 	unbecome_root();
+ 	if (!NT_STATUS_IS_OK(status)) {
+ 		return status;
+@@ -2775,11 +2658,12 @@ NTSTATUS _netr_GetForestTrustInformation(struct pipes_struct *p,
+ 	/* TODO: check server name */
+ 
+ 	become_root();
+-	status = netr_creds_server_step_check(p, p->mem_ctx,
+-					      r->in.computer_name,
+-					      r->in.credential,
+-					      r->out.return_authenticator,
+-					      &creds);
++	status = dcesrv_netr_creds_server_step_check(p->dce_call,
++						p->mem_ctx,
++						r->in.computer_name,
++						r->in.credential,
++						r->out.return_authenticator,
++						&creds);
+ 	unbecome_root();
+ 	if (!NT_STATUS_IS_OK(status)) {
+ 		return status;
+@@ -2878,11 +2762,12 @@ NTSTATUS _netr_ServerGetTrustInfo(struct pipes_struct *p,
+ 	/* TODO: check server name */
+ 
+ 	become_root();
+-	status = netr_creds_server_step_check(p, p->mem_ctx,
+-					      r->in.computer_name,
+-					      r->in.credential,
+-					      r->out.return_authenticator,
+-					      &creds);
++	status = dcesrv_netr_creds_server_step_check(p->dce_call,
++						p->mem_ctx,
++						r->in.computer_name,
++						r->in.credential,
++						r->out.return_authenticator,
++						&creds);
+ 	unbecome_root();
+ 	if (!NT_STATUS_IS_OK(status)) {
+ 		return status;
+diff --git a/source3/rpc_server/wscript_build b/source3/rpc_server/wscript_build
+index 83ceca2a45c..341df41a321 100644
+--- a/source3/rpc_server/wscript_build
++++ b/source3/rpc_server/wscript_build
+@@ -174,7 +174,7 @@ bld.SAMBA3_SUBSYSTEM('RPC_NETDFS',
+ 
+ bld.SAMBA3_SUBSYSTEM('RPC_NETLOGON',
+                      source='''netlogon/srv_netlog_nt.c''',
+-                    deps='LIBCLI_AUTH')
++                    deps='LIBCLI_AUTH DCERPC_SERVER_NETLOGON')
+ 
+ bld.SAMBA3_SUBSYSTEM('RPC_NTSVCS',
+                     source='''ntsvcs/srv_ntsvcs_nt.c''',
+-- 
+2.39.0
+
+
+From 5e8a9c85fe9cd28727c284a7fa5465db00a16cac Mon Sep 17 00:00:00 2001
+From: Samuel Cabrero <scabrero@suse.de>
+Date: Thu, 22 Dec 2022 09:29:04 +0100
+Subject: [PATCH 6/9] CVE-2022-38023 s3:rpc_server/netlogon: make sure all
+ _netr_LogonSamLogon*() calls go through dcesrv_netr_check_schannel()
+
+Some checks are also required for _netr_LogonSamLogonEx().
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=15240
+
+Signed-off-by: Samuel Cabrero <scabrero@samba.org>
+Reviewed-by: Andreas Schneider <asn@samba.org>
+(cherry picked from commit ca07f4340ce58a7e940a1123888b7409176412f7)
+---
+ source3/rpc_server/netlogon/srv_netlog_nt.c | 45 +++++++++++++--------
+ 1 file changed, 28 insertions(+), 17 deletions(-)
+
+diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c
+index 8e0ea522b6d..ba2680668ed 100644
+--- a/source3/rpc_server/netlogon/srv_netlog_nt.c
++++ b/source3/rpc_server/netlogon/srv_netlog_nt.c
+@@ -1632,6 +1632,11 @@ static NTSTATUS _netr_LogonSamLogon_base(struct pipes_struct *p,
+ 	struct auth_serversupplied_info *server_info = NULL;
+ 	struct auth_context *auth_context = NULL;
+ 	const char *fn;
++	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;
++
++	dcesrv_call_auth_info(dce_call, &auth_type, &auth_level);
+ 
+ #ifdef DEBUG_PASSWORD
+ 	logon = netlogon_creds_shallow_copy_logon(p->mem_ctx,
+@@ -1642,15 +1647,37 @@ static NTSTATUS _netr_LogonSamLogon_base(struct pipes_struct *p,
+ 	}
+ #endif
+ 
+-	switch (dce_call->pkt.u.request.opnum) {
++	switch (opnum) {
+ 		case NDR_NETR_LOGONSAMLOGON:
+ 			fn = "_netr_LogonSamLogon";
++			/*
++			 * Already called netr_check_schannel() via
++			 * netr_creds_server_step_check()
++			 */
+ 			break;
+ 		case NDR_NETR_LOGONSAMLOGONWITHFLAGS:
+ 			fn = "_netr_LogonSamLogonWithFlags";
++			/*
++			 * Already called netr_check_schannel() via
++			 * netr_creds_server_step_check()
++			 */
+ 			break;
+ 		case NDR_NETR_LOGONSAMLOGONEX:
+ 			fn = "_netr_LogonSamLogonEx";
++
++			if (auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
++				return NT_STATUS_ACCESS_DENIED;
++			}
++
++			status = dcesrv_netr_check_schannel(p->dce_call,
++							    creds,
++							    auth_type,
++							    auth_level,
++							    opnum);
++			if (NT_STATUS_IS_ERR(status)) {
++				return status;
++			}
++
+ 			break;
+ 		default:
+ 			return NT_STATUS_INTERNAL_ERROR;
+@@ -1881,10 +1908,6 @@ static NTSTATUS _netr_LogonSamLogon_base(struct pipes_struct *p,
+ 						r->out.validation->sam3);
+ 		break;
+ 	case 6: {
+-		enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
+-
+-		dcesrv_call_auth_info(dce_call, NULL, &auth_level);
+-
+ 		/* Only allow this if the pipe is protected. */
+ 		if (auth_level < DCERPC_AUTH_LEVEL_PRIVACY) {
+ 			DEBUG(0,("netr_Validation6: client %s not using privacy for netlogon\n",
+@@ -1997,8 +2020,6 @@ NTSTATUS _netr_LogonSamLogon(struct pipes_struct *p,
+ NTSTATUS _netr_LogonSamLogonEx(struct pipes_struct *p,
+ 			       struct netr_LogonSamLogonEx *r)
+ {
+-	struct dcesrv_call_state *dce_call = p->dce_call;
+-	enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
+ 	NTSTATUS status;
+ 	struct netlogon_creds_CredentialState *creds = NULL;
+ 	struct loadparm_context *lp_ctx;
+@@ -2010,16 +2031,6 @@ NTSTATUS _netr_LogonSamLogonEx(struct pipes_struct *p,
+ 		return status;
+ 	}
+ 
+-	/* Only allow this if the pipe is protected. */
+-
+-	dcesrv_call_auth_info(dce_call, &auth_type, NULL);
+-
+-	if (auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
+-		DEBUG(0,("_netr_LogonSamLogonEx: client %s not using schannel for netlogon\n",
+-			get_remote_machine_name() ));
+-		return NT_STATUS_INVALID_PARAMETER;
+-        }
+-
+ 	lp_ctx = loadparm_init_s3(p->mem_ctx, loadparm_s3_helpers());
+ 	if (lp_ctx == NULL) {
+ 		DEBUG(0, ("loadparm_init_s3 failed\n"));
+-- 
+2.39.0
+
+
+From f4682b16e9e5bdc4decf6c9d02388d540482b6a7 Mon Sep 17 00:00:00 2001
+From: Samuel Cabrero <scabrero@suse.de>
+Date: Thu, 22 Dec 2022 11:05:33 +0100
+Subject: [PATCH 7/9] CVE-2022-38023 s3:rpc_server/netlogon: Check for global
+ "server schannel require seal"
+
+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: Samuel Cabrero <scabrero@samba.org>
+Reviewed-by: Andreas Schneider <asn@samba.org>
+(cherry picked from commit a0b97e262318dc56fe663da89b0ee3172b2e7848)
+---
+ source3/rpc_server/netlogon/srv_netlog_nt.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c
+index ba2680668ed..a6f56a5ca21 100644
+--- a/source3/rpc_server/netlogon/srv_netlog_nt.c
++++ b/source3/rpc_server/netlogon/srv_netlog_nt.c
+@@ -2895,7 +2895,9 @@ static NTSTATUS dcesrv_interface_netlogon_bind(struct dcesrv_connection_context
+ 	struct loadparm_context *lp_ctx = context->conn->dce_ctx->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_schannel_once = false;
++	static bool warned_global_seal_once = false;
+ 
+ 	if (!schannel_global_required && !warned_global_schannel_once) {
+ 		/*
+@@ -2907,6 +2909,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 NT_STATUS_OK;
+ }
+ 
+-- 
+2.39.0
+
+
+From 5ddca0370de470bf1c532a6883e0b9fa0dedf6c4 Mon Sep 17 00:00:00 2001
+From: Samuel Cabrero <scabrero@samba.org>
+Date: Mon, 9 Jan 2023 12:17:48 +0100
+Subject: [PATCH 8/9] CVE-2022-38023 docs-xml/smbdotconf: The "server schannel
+ require seal[:COMPUTERACCOUNT]" options are also honoured by s3 netlogon
+ server.
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=15240
+
+Signed-off-by: Samuel Cabrero <scabrero@samba.org>
+Reviewed-by: Andreas Schneider <asn@samba.org>
+(cherry picked from commit 02fba22b8c9e9b33ab430555ef45500c45eaa9d1)
+---
+ docs-xml/smbdotconf/security/serverschannelrequireseal.xml | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/docs-xml/smbdotconf/security/serverschannelrequireseal.xml b/docs-xml/smbdotconf/security/serverschannelrequireseal.xml
+index d4620d1252d..0bec67d2519 100644
+--- a/docs-xml/smbdotconf/security/serverschannelrequireseal.xml
++++ b/docs-xml/smbdotconf/security/serverschannelrequireseal.xml
+@@ -12,9 +12,8 @@
+ 	</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.
++	This option controls whether the netlogon server, will reject the usage
++	of netlogon secure channel without privacy/enryption.
+ 	</para>
+ 
+ 	<para>
+-- 
+2.39.0
+
+
+From 2cb3ecb5c258fd23ca2f1fd2635be90336a0d7e0 Mon Sep 17 00:00:00 2001
+From: Samuel Cabrero <scabrero@suse.de>
+Date: Thu, 22 Dec 2022 16:32:40 +0100
+Subject: [PATCH 9/9] CVE-2022-38023 s3:rpc_server/netlogon: Avoid unnecessary
+ loadparm_context allocations
+
+After s3 and s4 rpc servers merge the loadparm_context is available in
+the dcesrv_context structure.
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=15240
+
+Signed-off-by: Samuel Cabrero <scabrero@samba.org>
+Reviewed-by: Andreas Schneider <asn@samba.org>
+
+Autobuild-User(master): Andreas Schneider <asn@cryptomilk.org>
+Autobuild-Date(master): Mon Jan  9 15:17:14 UTC 2023 on sn-devel-184
+
+(cherry picked from commit 56837f3d3169a02d0d92bd085d9c8250415ce29b)
+---
+ source3/rpc_server/netlogon/srv_netlog_nt.c | 21 ++-------------------
+ 1 file changed, 2 insertions(+), 19 deletions(-)
+
+diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c
+index a6f56a5ca21..7d17ab79f3d 100644
+--- a/source3/rpc_server/netlogon/srv_netlog_nt.c
++++ b/source3/rpc_server/netlogon/srv_netlog_nt.c
+@@ -880,7 +880,7 @@ NTSTATUS _netr_ServerAuthenticate3(struct pipes_struct *p,
+ 	 * so use a copy to avoid destroying the client values. */
+ 	uint32_t in_neg_flags = *r->in.negotiate_flags;
+ 	const char *fn;
+-	struct loadparm_context *lp_ctx;
++	struct loadparm_context *lp_ctx = p->dce_call->conn->dce_ctx->lp_ctx;
+ 	struct dom_sid sid;
+ 	struct samr_Password mach_pwd;
+ 	struct netlogon_creds_CredentialState *creds;
+@@ -1009,20 +1009,11 @@ NTSTATUS _netr_ServerAuthenticate3(struct pipes_struct *p,
+ 		goto out;
+ 	}
+ 
+-	lp_ctx = loadparm_init_s3(p->mem_ctx, loadparm_s3_helpers());
+-	if (lp_ctx == NULL) {
+-		DEBUG(10, ("loadparm_init_s3 failed\n"));
+-		status = NT_STATUS_INTERNAL_ERROR;
+-		goto out;
+-	}
+-
+ 	/* Store off the state so we can continue after client disconnect. */
+ 	become_root();
+ 	status = schannel_save_creds_state(p->mem_ctx, lp_ctx, creds);
+ 	unbecome_root();
+ 
+-	talloc_unlink(p->mem_ctx, lp_ctx);
+-
+ 	if (!NT_STATUS_IS_OK(status)) {
+ 		ZERO_STRUCTP(r->out.return_credentials);
+ 		goto out;
+@@ -2022,7 +2013,7 @@ NTSTATUS _netr_LogonSamLogonEx(struct pipes_struct *p,
+ {
+ 	NTSTATUS status;
+ 	struct netlogon_creds_CredentialState *creds = NULL;
+-	struct loadparm_context *lp_ctx;
++	struct loadparm_context *lp_ctx = p->dce_call->conn->dce_ctx->lp_ctx;
+ 
+ 	*r->out.authoritative = true;
+ 
+@@ -2031,18 +2022,10 @@ NTSTATUS _netr_LogonSamLogonEx(struct pipes_struct *p,
+ 		return status;
+ 	}
+ 
+-	lp_ctx = loadparm_init_s3(p->mem_ctx, loadparm_s3_helpers());
+-	if (lp_ctx == NULL) {
+-		DEBUG(0, ("loadparm_init_s3 failed\n"));
+-		return NT_STATUS_INTERNAL_ERROR;
+-	}
+-
+ 	become_root();
+ 	status = schannel_get_creds_state(p->mem_ctx, lp_ctx,
+ 					  r->in.computer_name, &creds);
+ 	unbecome_root();
+-	talloc_unlink(p->mem_ctx, lp_ctx);
+-
+ 	if (!NT_STATUS_IS_OK(status)) {
+ 		return status;
+ 	}
+-- 
+2.39.0
+
diff --git a/SOURCES/CVE-2022-38023-v4-16.patch b/SOURCES/CVE-2022-38023-v4-16.patch
new file mode 100644
index 0000000..54e0604
--- /dev/null
+++ b/SOURCES/CVE-2022-38023-v4-16.patch
@@ -0,0 +1,4417 @@
+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
+
diff --git a/SPECS/samba.spec b/SPECS/samba.spec
index 9d452c6..4bbf480 100644
--- a/SPECS/samba.spec
+++ b/SPECS/samba.spec
@@ -134,7 +134,7 @@
 
 %define samba_requires_eq()  %(LC_ALL="C" echo '%*' | xargs -r rpm -q --qf 'Requires: %%{name} = %%{epoch}:%%{version}\\n' | sed -e 's/ (none):/ /' -e 's/ 0:/ /' | grep -v "is not")
 
-%global baserelease 2
+%global baserelease 4
 
 %global samba_version 4.16.4
 %global talloc_version 2.3.3
@@ -207,6 +207,8 @@ Source201:      README.downgrade
 Patch0:         samba-s4u.patch
 # https://gitlab.com/samba-team/samba/-/merge_requests/2477
 Patch1:         samba-4.16-waf-crypto.patch
+Patch2:         CVE-2022-38023-v4-16.patch
+Patch3:         CVE-2022-38023-for-s3-v4-16.patch
 
 Requires(pre): /usr/sbin/groupadd
 Requires(post): systemd
@@ -4163,6 +4165,12 @@ fi
 %endif
 
 %changelog
+* Mon Jan 16 2023 Andreas Schneider <asn@redhat.com> - 4.16.4-4
+- related: rhbz#2154369 - Add additional patch for CVE-2022-38023
+
+* Tue Dec 20 2022 Andreas Schneider <asn@redhat.com> - 4.16.4-3
+- resolves: rhbz#2154369 - Fix CVE-2022-38023
+
 * Thu Aug 25 2022 Andreas Schneider <asn@redhat.com> - 4.16.4-2
 - resolves: rhbz#2120956 - Do not require samba package in python3-samba