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