355 lines
12 KiB
Diff
355 lines
12 KiB
Diff
From fba17d9f8e6437fc675608c0507d6a00f830aaea Mon Sep 17 00:00:00 2001
|
|
From: Samuel Cabrero <scabrero@suse.de>
|
|
Date: Wed, 4 Jan 2023 17:50:04 +0100
|
|
Subject: [PATCH 40/40] CVE-2022-38023 s3:rpc_server/netlogon: implement
|
|
"server schannel require seal[:COMPUTERACCOUNT]"
|
|
|
|
By default we'll now require schannel connections with
|
|
privacy/sealing/encryption.
|
|
|
|
But we allow exceptions for specific computer/trust accounts.
|
|
|
|
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15240
|
|
|
|
Signed-off-by: Samuel Cabrero <scabrero@suse.de>
|
|
|
|
Conflict: remove selftest/target/Samba3.pm
|
|
Reference: https://attachments.samba.org/attachment.cgi?id=17736
|
|
---
|
|
selftest/target/Samba3.pm | 14 ++
|
|
source3/rpc_server/netlogon/srv_netlog_nt.c | 237 +++++++++++++++++++-
|
|
2 files changed, 249 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c
|
|
index f238d7ce42b..df305e94479 100644
|
|
--- a/source3/rpc_server/netlogon/srv_netlog_nt.c
|
|
+++ b/source3/rpc_server/netlogon/srv_netlog_nt.c
|
|
@@ -1075,14 +1075,22 @@ static NTSTATUS netr_check_schannel(struct pipes_struct *p,
|
|
bool schannel_global_required = (lp_server_schannel() == true) ? true:false;
|
|
bool schannel_required = schannel_global_required;
|
|
bool schannel_explicitly_set = false;
|
|
+ bool seal_global_required = (lp_server_schannel_require_seal() == true) ? true:false;
|
|
+ bool seal_required = seal_global_required;
|
|
+ bool seal_explicitly_set = false;
|
|
int CVE_2020_1472_warn_level = lp_parm_int(GLOBAL_SECTION_SNUM,
|
|
"CVE_2020_1472", "warn_about_unused_debug_level", DBGLVL_ERR);
|
|
int CVE_2020_1472_error_level = lp_parm_int(GLOBAL_SECTION_SNUM,
|
|
"CVE_2020_1472", "error_debug_level", DBGLVL_ERR);
|
|
+ int CVE_2022_38023_warn_level = lp_parm_int(GLOBAL_SECTION_SNUM,
|
|
+ "CVE_2022_38023", "warn_about_unused_debug_level", DBGLVL_ERR);
|
|
+ int CVE_2022_38023_error_level = lp_parm_int(GLOBAL_SECTION_SNUM,
|
|
+ "CVE_2022_38023", "error_debug_level", DBGLVL_ERR);
|
|
unsigned int dbg_lvl = DBGLVL_DEBUG;
|
|
const char *opname = "<unknown>";
|
|
const char *reason = "<unknown>";
|
|
static bool warned_global_schannel_once = false;
|
|
+ static bool warned_global_seal_once = false;
|
|
|
|
if (opnum < ndr_table_netlogon.num_calls) {
|
|
opname = ndr_table_netlogon.calls[opnum].name;
|
|
@@ -1119,6 +1127,20 @@ static NTSTATUS netr_check_schannel(struct pipes_struct *p,
|
|
return status;
|
|
}
|
|
|
|
+ /*
|
|
+ * We don't use lp_parm_bool(), as we
|
|
+ * need the explicit_opt pointer in order to
|
|
+ * adjust the debug messages.
|
|
+ */
|
|
+ explicit_opt = lp_parm_const_string(GLOBAL_SECTION_SNUM,
|
|
+ "server schannel require seal",
|
|
+ creds->account_name,
|
|
+ NULL);
|
|
+ if (explicit_opt != NULL) {
|
|
+ seal_required = lp_bool(explicit_opt);
|
|
+ }
|
|
+ seal_explicitly_set = explicit_opt != NULL;
|
|
+
|
|
/*
|
|
* We don't use lp_parm_bool(), as we
|
|
* need the explicit_opt pointer in order to
|
|
@@ -1134,7 +1156,96 @@ static NTSTATUS netr_check_schannel(struct pipes_struct *p,
|
|
}
|
|
schannel_explicitly_set = explicit_opt != NULL;
|
|
|
|
+ if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL &&
|
|
+ auth_level == DCERPC_AUTH_LEVEL_PRIVACY)
|
|
+ {
|
|
+ status = NT_STATUS_OK;
|
|
+
|
|
+ if (schannel_explicitly_set && !schannel_required) {
|
|
+ dbg_lvl = MIN(dbg_lvl, CVE_2020_1472_warn_level);
|
|
+ } else if (!schannel_required) {
|
|
+ dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
|
|
+ }
|
|
+ if (seal_explicitly_set && !seal_required) {
|
|
+ dbg_lvl = MIN(dbg_lvl, CVE_2022_38023_warn_level);
|
|
+ } else if (!seal_required) {
|
|
+ dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
|
|
+ }
|
|
+
|
|
+ DEBUG(dbg_lvl, (
|
|
+ "CVE-2020-1472(ZeroLogon)/CVE-2022-38023: "
|
|
+ "%s request (opnum[%u]) %s schannel from "
|
|
+ "client_account[%s] client_computer_name[%s] %s\n",
|
|
+ opname, opnum, reason,
|
|
+ log_escape(frame, creds->account_name),
|
|
+ log_escape(frame, creds->computer_name),
|
|
+ nt_errstr(status)));
|
|
+
|
|
+ if (schannel_explicitly_set && !schannel_required) {
|
|
+ DEBUG(CVE_2020_1472_warn_level, (
|
|
+ "CVE-2020-1472(ZeroLogon): "
|
|
+ "Option 'server require schannel:%s = no' not needed for '%s'!\n",
|
|
+ log_escape(frame, creds->account_name),
|
|
+ log_escape(frame, creds->computer_name)));
|
|
+ }
|
|
+
|
|
+ if (seal_explicitly_set && !seal_required) {
|
|
+ DEBUG(CVE_2022_38023_warn_level, (
|
|
+ "CVE-2022-38023: "
|
|
+ "Option 'server schannel require seal:%s = no' not needed for '%s'!\n",
|
|
+ log_escape(frame, creds->account_name),
|
|
+ log_escape(frame, creds->computer_name)));
|
|
+ }
|
|
+
|
|
+ TALLOC_FREE(frame);
|
|
+ return status;
|
|
+ }
|
|
+
|
|
if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
|
|
+ if (seal_required) {
|
|
+ status = NT_STATUS_ACCESS_DENIED;
|
|
+
|
|
+ if (seal_explicitly_set) {
|
|
+ dbg_lvl = DBGLVL_NOTICE;
|
|
+ } else {
|
|
+ dbg_lvl = MIN(dbg_lvl, CVE_2022_38023_error_level);
|
|
+ }
|
|
+ if (schannel_explicitly_set && !schannel_required) {
|
|
+ dbg_lvl = MIN(dbg_lvl, CVE_2022_38023_warn_level);
|
|
+ }
|
|
+
|
|
+ DEBUG(dbg_lvl, (
|
|
+ "CVE-2022-38023: "
|
|
+ "%s request (opnum[%u]) %s schannel from "
|
|
+ "from client_account[%s] client_computer_name[%s] %s\n",
|
|
+ opname, opnum, reason,
|
|
+ log_escape(frame, creds->account_name),
|
|
+ log_escape(frame, creds->computer_name),
|
|
+ nt_errstr(status)));
|
|
+ if (seal_explicitly_set) {
|
|
+ D_NOTICE("CVE-2022-38023: Option "
|
|
+ "'server schannel require seal:%s = yes' "
|
|
+ "rejects access for client.\n",
|
|
+ log_escape(frame, creds->account_name));
|
|
+ } else {
|
|
+ DEBUG(CVE_2020_1472_error_level, (
|
|
+ "CVE-2022-38023: Check if option "
|
|
+ "'server schannel require seal:%s = no' "
|
|
+ "might be needed for a legacy client.\n",
|
|
+ log_escape(frame, creds->account_name)));
|
|
+ }
|
|
+ if (schannel_explicitly_set && !schannel_required) {
|
|
+ DEBUG(CVE_2020_1472_warn_level, (
|
|
+ "CVE-2020-1472(ZeroLogon): Option "
|
|
+ "'server require schannel:%s = no' "
|
|
+ "not needed for '%s'!\n",
|
|
+ log_escape(frame, creds->account_name),
|
|
+ log_escape(frame, creds->computer_name)));
|
|
+ }
|
|
+ TALLOC_FREE(frame);
|
|
+ return status;
|
|
+ }
|
|
+
|
|
status = NT_STATUS_OK;
|
|
|
|
if (schannel_explicitly_set && !schannel_required) {
|
|
@@ -1142,6 +1253,11 @@ static NTSTATUS netr_check_schannel(struct pipes_struct *p,
|
|
} else if (!schannel_required) {
|
|
dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
|
|
}
|
|
+ if (seal_explicitly_set && !seal_required) {
|
|
+ dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
|
|
+ } else if (!seal_required) {
|
|
+ dbg_lvl = MIN(dbg_lvl, CVE_2022_38023_error_level);
|
|
+ }
|
|
|
|
DEBUG(dbg_lvl, (
|
|
"CVE-2020-1472(ZeroLogon): "
|
|
@@ -1151,7 +1267,6 @@ static NTSTATUS netr_check_schannel(struct pipes_struct *p,
|
|
log_escape(frame, creds->account_name),
|
|
log_escape(frame, creds->computer_name),
|
|
nt_errstr(status)));
|
|
-
|
|
if (schannel_explicitly_set && !schannel_required) {
|
|
DEBUG(CVE_2020_1472_warn_level, (
|
|
"CVE-2020-1472(ZeroLogon): "
|
|
@@ -1159,7 +1274,77 @@ static NTSTATUS netr_check_schannel(struct pipes_struct *p,
|
|
log_escape(frame, creds->account_name),
|
|
log_escape(frame, creds->computer_name)));
|
|
}
|
|
+ if (seal_explicitly_set && !seal_required) {
|
|
+ D_INFO("CVE-2022-38023: "
|
|
+ "Option 'server schannel require seal:%s = no' still needed for '%s'!\n",
|
|
+ log_escape(frame, creds->account_name),
|
|
+ log_escape(frame, creds->computer_name));
|
|
+ } else if (!seal_required) {
|
|
+ /*
|
|
+ * admins should set
|
|
+ * server schannel require seal:COMPUTER$ = no
|
|
+ * in order to avoid the level 0 messages.
|
|
+ * Over time they can switch the global value
|
|
+ * to be strict.
|
|
+ */
|
|
+ DEBUG(CVE_2022_38023_error_level, (
|
|
+ "CVE-2022-38023: "
|
|
+ "Please use 'server schannel require seal:%s = no' "
|
|
+ "for '%s' to avoid this warning!\n",
|
|
+ log_escape(frame, creds->account_name),
|
|
+ log_escape(frame, creds->computer_name)));
|
|
+ }
|
|
+
|
|
+ TALLOC_FREE(frame);
|
|
+ return status;
|
|
+ }
|
|
+
|
|
+ if (seal_required) {
|
|
+ status = NT_STATUS_ACCESS_DENIED;
|
|
|
|
+ if (seal_explicitly_set) {
|
|
+ dbg_lvl = MIN(dbg_lvl, DBGLVL_NOTICE);
|
|
+ } else {
|
|
+ dbg_lvl = MIN(dbg_lvl, CVE_2022_38023_error_level);
|
|
+ }
|
|
+ if (!schannel_explicitly_set) {
|
|
+ dbg_lvl = MIN(dbg_lvl, CVE_2020_1472_error_level);
|
|
+ } else if (schannel_required) {
|
|
+ dbg_lvl = MIN(dbg_lvl, DBGLVL_NOTICE);
|
|
+ }
|
|
+
|
|
+ DEBUG(dbg_lvl, (
|
|
+ "CVE-2020-1472(ZeroLogon)/CVE-2022-38023: "
|
|
+ "%s request (opnum[%u]) %s schannel from "
|
|
+ "from client_account[%s] client_computer_name[%s] %s\n",
|
|
+ opname, opnum, reason,
|
|
+ log_escape(frame, creds->account_name),
|
|
+ log_escape(frame, creds->computer_name),
|
|
+ nt_errstr(status)));
|
|
+ if (seal_explicitly_set) {
|
|
+ D_NOTICE("CVE-2022-38023: Option "
|
|
+ "'server schannel require seal:%s = yes' "
|
|
+ "rejects access for client.\n",
|
|
+ log_escape(frame, creds->account_name));
|
|
+ } else {
|
|
+ DEBUG(CVE_2022_38023_error_level, (
|
|
+ "CVE-2022-38023: Check if option "
|
|
+ "'server schannel require seal:%s = no' "
|
|
+ "might be needed for a legacy client.\n",
|
|
+ log_escape(frame, creds->account_name)));
|
|
+ }
|
|
+ if (!schannel_explicitly_set) {
|
|
+ DEBUG(CVE_2020_1472_error_level, (
|
|
+ "CVE-2020-1472(ZeroLogon): Check if option "
|
|
+ "'server require schannel:%s = no' "
|
|
+ "might be needed for a legacy client.\n",
|
|
+ log_escape(frame, creds->account_name)));
|
|
+ } else if (schannel_required) {
|
|
+ D_NOTICE("CVE-2022-38023: Option "
|
|
+ "'server require schannel:%s = yes' "
|
|
+ "also rejects access for client.\n",
|
|
+ log_escape(frame, creds->account_name));
|
|
+ }
|
|
TALLOC_FREE(frame);
|
|
return status;
|
|
}
|
|
@@ -1172,6 +1357,9 @@ static NTSTATUS netr_check_schannel(struct pipes_struct *p,
|
|
} else {
|
|
dbg_lvl = MIN(dbg_lvl, CVE_2020_1472_error_level);
|
|
}
|
|
+ if (!seal_explicitly_set) {
|
|
+ dbg_lvl = MIN(dbg_lvl, CVE_2022_38023_error_level);
|
|
+ }
|
|
|
|
DEBUG(dbg_lvl, (
|
|
"CVE-2020-1472(ZeroLogon)/CVE-2022-38023: "
|
|
@@ -1193,6 +1381,13 @@ static NTSTATUS netr_check_schannel(struct pipes_struct *p,
|
|
"might be needed for a legacy client.\n",
|
|
log_escape(frame, creds->account_name)));
|
|
}
|
|
+ if (!seal_explicitly_set) {
|
|
+ DEBUG(CVE_2022_38023_error_level, (
|
|
+ "CVE-2022-38023: Check if option "
|
|
+ "'server schannel require seal:%s = no' "
|
|
+ "might be needed for a legacy client.\n",
|
|
+ log_escape(frame, creds->account_name)));
|
|
+ }
|
|
TALLOC_FREE(frame);
|
|
return status;
|
|
}
|
|
@@ -1207,8 +1402,24 @@ static NTSTATUS netr_check_schannel(struct pipes_struct *p,
|
|
warned_global_schannel_once = true;
|
|
}
|
|
|
|
+ if (!seal_global_required && !warned_global_seal_once) {
|
|
+ /*
|
|
+ * We want admins to notice their misconfiguration!
|
|
+ */
|
|
+ DBG_ERR("CVE-2022-38023 (and others): "
|
|
+ "Please configure 'server schannel require seal = yes' (the default), "
|
|
+ "See https://bugzilla.samba.org/show_bug.cgi?id=15240\n");
|
|
+ warned_global_seal_once = true;
|
|
+ }
|
|
+
|
|
status = NT_STATUS_OK;
|
|
|
|
+ if (seal_explicitly_set) {
|
|
+ dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
|
|
+ } else {
|
|
+ dbg_lvl = MIN(dbg_lvl, CVE_2022_38023_error_level);
|
|
+ }
|
|
+
|
|
if (schannel_explicitly_set) {
|
|
dbg_lvl = MIN(dbg_lvl, DBGLVL_INFO);
|
|
} else {
|
|
@@ -1224,6 +1435,28 @@ static NTSTATUS netr_check_schannel(struct pipes_struct *p,
|
|
log_escape(frame, creds->computer_name),
|
|
nt_errstr(status)));
|
|
|
|
+ if (seal_explicitly_set) {
|
|
+ D_INFO("CVE-2022-38023: Option "
|
|
+ "'server schannel require seal:%s = no' "
|
|
+ "still needed for '%s'!\n",
|
|
+ log_escape(frame, creds->account_name),
|
|
+ log_escape(frame, creds->computer_name));
|
|
+ } else {
|
|
+ /*
|
|
+ * admins should set
|
|
+ * server schannel require seal:COMPUTER$ = no
|
|
+ * in order to avoid the level 0 messages.
|
|
+ * Over time they can switch the global value
|
|
+ * to be strict.
|
|
+ */
|
|
+ DEBUG(CVE_2022_38023_error_level, (
|
|
+ "CVE-2022-38023: Please use "
|
|
+ "'server schannel require seal:%s = no' "
|
|
+ "for '%s' to avoid this warning!\n",
|
|
+ log_escape(frame, creds->account_name),
|
|
+ log_escape(frame, creds->computer_name)));
|
|
+ }
|
|
+
|
|
if (schannel_explicitly_set) {
|
|
D_INFO("CVE-2020-1472(ZeroLogon): Option "
|
|
"'server require schannel:%s = no' "
|
|
@@ -1247,7 +1480,7 @@ static NTSTATUS netr_check_schannel(struct pipes_struct *p,
|
|
}
|
|
|
|
TALLOC_FREE(frame);
|
|
- return NT_STATUS_OK;
|
|
+ return status;
|
|
}
|
|
|
|
static NTSTATUS netr_creds_server_step_check(struct pipes_struct *p,
|
|
--
|
|
2.39.0
|