168 lines
5.4 KiB
Diff
168 lines
5.4 KiB
Diff
From b7bd51a393988883936048a0fd9d790d0e03481f Mon Sep 17 00:00:00 2001
|
|
From: Stefan Metzmacher <metze@samba.org>
|
|
Date: Fri, 25 Nov 2022 09:54:17 +0100
|
|
Subject: [PATCH 15/30] CVE-2022-38023 s4:rpc_server/netlogon: split out
|
|
dcesrv_netr_ServerAuthenticate3_check_downgrade()
|
|
|
|
We'll soon make it possible to use 'reject md5 servers:CLIENTACCOUNT$ = no',
|
|
which means we'll need the downgrade detection in more places.
|
|
|
|
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15240
|
|
|
|
Signed-off-by: Stefan Metzmacher <metze@samba.org>
|
|
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
|
Reviewed-by: Ralph Boehme <slow@samba.org>
|
|
(cherry picked from commit b6339fd1dcbe903e73efeea074ab0bd04ef83561)
|
|
|
|
Conflict: NA
|
|
Reference: https://attachments.samba.org/attachment.cgi?id=17692
|
|
---
|
|
source4/rpc_server/netlogon/dcerpc_netlogon.c | 114 ++++++++++--------
|
|
1 file changed, 67 insertions(+), 47 deletions(-)
|
|
|
|
diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
|
|
index ce01400ec88b..82e3df055e7f 100644
|
|
--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
|
|
+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
|
|
@@ -125,6 +125,67 @@ static NTSTATUS dcesrv_netr_ServerReqChallenge(struct dcesrv_call_state *dce_cal
|
|
return NT_STATUS_OK;
|
|
}
|
|
|
|
+static NTSTATUS dcesrv_netr_ServerAuthenticate3_check_downgrade(
|
|
+ struct dcesrv_call_state *dce_call,
|
|
+ struct netr_ServerAuthenticate3 *r,
|
|
+ struct netlogon_server_pipe_state *pipe_state,
|
|
+ uint32_t negotiate_flags,
|
|
+ NTSTATUS orig_status)
|
|
+{
|
|
+ struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
|
|
+ bool allow_nt4_crypto = lpcfg_allow_nt4_crypto(lp_ctx);
|
|
+ bool reject_des_client = !allow_nt4_crypto;
|
|
+ bool reject_md5_client = lpcfg_reject_md5_clients(lp_ctx);
|
|
+
|
|
+ if (negotiate_flags & NETLOGON_NEG_STRONG_KEYS) {
|
|
+ reject_des_client = false;
|
|
+ }
|
|
+
|
|
+ if (negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
|
|
+ reject_des_client = false;
|
|
+ reject_md5_client = false;
|
|
+ }
|
|
+
|
|
+ if (reject_des_client || reject_md5_client) {
|
|
+ /*
|
|
+ * Here we match Windows 2012 and return no flags.
|
|
+ */
|
|
+ *r->out.negotiate_flags = 0;
|
|
+ return NT_STATUS_DOWNGRADE_DETECTED;
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * This talloc_free is important to prevent re-use of the
|
|
+ * challenge. We have to delay it this far due to NETApp
|
|
+ * servers per:
|
|
+ * https://bugzilla.samba.org/show_bug.cgi?id=11291
|
|
+ */
|
|
+ TALLOC_FREE(pipe_state);
|
|
+
|
|
+ /*
|
|
+ * At this point we must also cleanup the TDB cache
|
|
+ * entry, if we fail the client needs to call
|
|
+ * netr_ServerReqChallenge again.
|
|
+ *
|
|
+ * Note: this handles a non existing record just fine,
|
|
+ * the r->in.computer_name might not be the one used
|
|
+ * in netr_ServerReqChallenge(), but we are trying to
|
|
+ * just tidy up the normal case to prevent re-use.
|
|
+ */
|
|
+ schannel_delete_challenge(dce_call->conn->dce_ctx->lp_ctx,
|
|
+ r->in.computer_name);
|
|
+
|
|
+ /*
|
|
+ * According to Microsoft (see bugid #6099)
|
|
+ * Windows 7 looks at the negotiate_flags
|
|
+ * returned in this structure *even if the
|
|
+ * call fails with access denied!
|
|
+ */
|
|
+ *r->out.negotiate_flags = negotiate_flags;
|
|
+
|
|
+ return orig_status;
|
|
+}
|
|
+
|
|
/*
|
|
* Do the actual processing of a netr_ServerAuthenticate3 message.
|
|
* called from dcesrv_netr_ServerAuthenticate3, which handles the logging.
|
|
@@ -152,11 +213,9 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
|
|
"objectSid", "samAccountName", NULL};
|
|
uint32_t server_flags = 0;
|
|
uint32_t negotiate_flags = 0;
|
|
- bool allow_nt4_crypto = lpcfg_allow_nt4_crypto(dce_call->conn->dce_ctx->lp_ctx);
|
|
- bool reject_des_client = !allow_nt4_crypto;
|
|
- bool reject_md5_client = lpcfg_reject_md5_clients(dce_call->conn->dce_ctx->lp_ctx);
|
|
|
|
ZERO_STRUCTP(r->out.return_credentials);
|
|
+ *r->out.negotiate_flags = 0;
|
|
*r->out.rid = 0;
|
|
|
|
pipe_state = dcesrv_iface_state_find_conn(dce_call,
|
|
@@ -243,52 +302,13 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
|
|
|
|
negotiate_flags = *r->in.negotiate_flags & server_flags;
|
|
|
|
- if (negotiate_flags & NETLOGON_NEG_STRONG_KEYS) {
|
|
- reject_des_client = false;
|
|
- }
|
|
-
|
|
- if (negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
|
|
- reject_des_client = false;
|
|
- reject_md5_client = false;
|
|
- }
|
|
-
|
|
- if (reject_des_client || reject_md5_client) {
|
|
- /*
|
|
- * Here we match Windows 2012 and return no flags.
|
|
- */
|
|
- *r->out.negotiate_flags = 0;
|
|
- return NT_STATUS_DOWNGRADE_DETECTED;
|
|
+ nt_status = dcesrv_netr_ServerAuthenticate3_check_downgrade(
|
|
+ dce_call, r, pipe_state, negotiate_flags,
|
|
+ NT_STATUS_OK);
|
|
+ if (!NT_STATUS_IS_OK(nt_status)) {
|
|
+ return nt_status;
|
|
}
|
|
|
|
- /*
|
|
- * This talloc_free is important to prevent re-use of the
|
|
- * challenge. We have to delay it this far due to NETApp
|
|
- * servers per:
|
|
- * https://bugzilla.samba.org/show_bug.cgi?id=11291
|
|
- */
|
|
- TALLOC_FREE(pipe_state);
|
|
-
|
|
- /*
|
|
- * At this point we must also cleanup the TDB cache
|
|
- * entry, if we fail the client needs to call
|
|
- * netr_ServerReqChallenge again.
|
|
- *
|
|
- * Note: this handles a non existing record just fine,
|
|
- * the r->in.computer_name might not be the one used
|
|
- * in netr_ServerReqChallenge(), but we are trying to
|
|
- * just tidy up the normal case to prevent re-use.
|
|
- */
|
|
- schannel_delete_challenge(dce_call->conn->dce_ctx->lp_ctx,
|
|
- r->in.computer_name);
|
|
-
|
|
- /*
|
|
- * According to Microsoft (see bugid #6099)
|
|
- * Windows 7 looks at the negotiate_flags
|
|
- * returned in this structure *even if the
|
|
- * call fails with access denied!
|
|
- */
|
|
- *r->out.negotiate_flags = negotiate_flags;
|
|
-
|
|
switch (r->in.secure_channel_type) {
|
|
case SEC_CHAN_WKSTA:
|
|
case SEC_CHAN_DNS_DOMAIN:
|
|
--
|
|
2.34.1
|