|
|
d8cf22 |
From 7d93bda31ce0b4e0e22c6e464c9138800dcf8b1c Mon Sep 17 00:00:00 2001
|
|
|
d8cf22 |
From: Alexander Bokovoy <abokovoy@redhat.com>
|
|
|
d8cf22 |
Date: Fri, 26 Nov 2021 11:13:51 +0200
|
|
|
d8cf22 |
Subject: [PATCH] ipa-kdb: fix requester SID check according to MS-KILE and
|
|
|
d8cf22 |
MS-SFU updates
|
|
|
d8cf22 |
|
|
|
d8cf22 |
New versions of MS-KILE and MS-SFU after Windows Server November 2021
|
|
|
d8cf22 |
security updates add PAC_REQUESTER_SID buffer check behavior:
|
|
|
d8cf22 |
|
|
|
d8cf22 |
- PAC_REQUESTER_SID should only be added for TGT requests
|
|
|
d8cf22 |
|
|
|
d8cf22 |
- if PAC_REQUESTER_SID is present, KDC must verify that the cname on
|
|
|
d8cf22 |
the ticket resolves to the account with the same SID as the
|
|
|
d8cf22 |
PAC_REQUESTER_SID. If it doesn't KDC must respond with
|
|
|
d8cf22 |
KDC_ERR_TKT_REVOKED
|
|
|
d8cf22 |
|
|
|
d8cf22 |
Change requester SID check to skip exact check for non-local
|
|
|
d8cf22 |
PAC_REQUESTER_SID but harden to ensure it comes from the trusted domains
|
|
|
d8cf22 |
we know about.
|
|
|
d8cf22 |
|
|
|
d8cf22 |
If requester SID is the same as in PAC, we already do cname vs PAC SID
|
|
|
d8cf22 |
verification.
|
|
|
d8cf22 |
|
|
|
d8cf22 |
With these changes FreeIPA works against Windows Server 2019 with
|
|
|
d8cf22 |
November 2021 security fixes in cross-realm S4U2Self operations.
|
|
|
d8cf22 |
|
|
|
d8cf22 |
Fixes: https://pagure.io/freeipa/issue/9031
|
|
|
d8cf22 |
|
|
|
d8cf22 |
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
|
|
|
d8cf22 |
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
|
|
|
d8cf22 |
---
|
|
|
d8cf22 |
daemons/ipa-kdb/ipa_kdb_mspac.c | 47 ++++++++++++++++++++++++---------
|
|
|
d8cf22 |
1 file changed, 34 insertions(+), 13 deletions(-)
|
|
|
d8cf22 |
|
|
|
d8cf22 |
diff --git a/daemons/ipa-kdb/ipa_kdb_mspac.c b/daemons/ipa-kdb/ipa_kdb_mspac.c
|
|
|
d8cf22 |
index 538cfbba9..1b972c167 100644
|
|
|
d8cf22 |
--- a/daemons/ipa-kdb/ipa_kdb_mspac.c
|
|
|
d8cf22 |
+++ b/daemons/ipa-kdb/ipa_kdb_mspac.c
|
|
|
d8cf22 |
@@ -1697,7 +1697,7 @@ static krb5_error_code check_logon_info_consistent(krb5_context context,
|
|
|
d8cf22 |
"local [%s], PAC [%s]",
|
|
|
d8cf22 |
dom ? dom : "<failed to display>",
|
|
|
d8cf22 |
sid ? sid : "<failed to display>");
|
|
|
d8cf22 |
- return KRB5KDC_ERR_POLICY;
|
|
|
d8cf22 |
+ return KRB5KDC_ERR_TGT_REVOKED;
|
|
|
d8cf22 |
}
|
|
|
d8cf22 |
}
|
|
|
d8cf22 |
|
|
|
d8cf22 |
@@ -1709,7 +1709,7 @@ static krb5_error_code check_logon_info_consistent(krb5_context context,
|
|
|
d8cf22 |
kerr = ipadb_get_principal(context, client_princ, flags, &client_actual);
|
|
|
d8cf22 |
if (kerr != 0) {
|
|
|
d8cf22 |
krb5_klog_syslog(LOG_ERR, "PAC issue: ipadb_get_principal failed.");
|
|
|
d8cf22 |
- return KRB5KDC_ERR_POLICY;
|
|
|
d8cf22 |
+ return KRB5KDC_ERR_TGT_REVOKED;
|
|
|
d8cf22 |
}
|
|
|
d8cf22 |
|
|
|
d8cf22 |
ied = (struct ipadb_e_data *)client_actual->e_data;
|
|
|
d8cf22 |
@@ -1743,7 +1743,7 @@ static krb5_error_code check_logon_info_consistent(krb5_context context,
|
|
|
d8cf22 |
"local [%s] vs PAC [%s]",
|
|
|
d8cf22 |
local_sid ? local_sid : "<failed to display>",
|
|
|
d8cf22 |
pac_sid ? pac_sid : "<failed to display>");
|
|
|
d8cf22 |
- kerr = KRB5KDC_ERR_POLICY;
|
|
|
d8cf22 |
+ kerr = KRB5KDC_ERR_TGT_REVOKED;
|
|
|
d8cf22 |
goto done;
|
|
|
d8cf22 |
}
|
|
|
d8cf22 |
|
|
|
d8cf22 |
@@ -2005,22 +2005,43 @@ static krb5_error_code ipadb_check_logon_info(krb5_context context,
|
|
|
d8cf22 |
/* Check that requester SID is the same as in the PAC entry */
|
|
|
d8cf22 |
if (requester_sid != NULL) {
|
|
|
d8cf22 |
struct dom_sid client_sid;
|
|
|
d8cf22 |
+ bool is_from_trusted_domain = false;
|
|
|
d8cf22 |
kerr = ipadb_get_sid_from_pac(tmpctx, info.info, &client_sid);
|
|
|
d8cf22 |
if (kerr) {
|
|
|
d8cf22 |
goto done;
|
|
|
d8cf22 |
}
|
|
|
d8cf22 |
result = dom_sid_check(&client_sid, requester_sid, true);
|
|
|
d8cf22 |
if (!result) {
|
|
|
d8cf22 |
- /* memctx is freed by the caller */
|
|
|
d8cf22 |
- char *pac_sid = dom_sid_string(tmpctx, &client_sid);
|
|
|
d8cf22 |
- char *req_sid = dom_sid_string(tmpctx, requester_sid);
|
|
|
d8cf22 |
- krb5_klog_syslog(LOG_ERR, "PAC issue: PAC has a SID "
|
|
|
d8cf22 |
- "different from what PAC requester claims. "
|
|
|
d8cf22 |
- "PAC [%s] vs PAC requester [%s]",
|
|
|
d8cf22 |
- pac_sid ? pac_sid : "<failed to display>",
|
|
|
d8cf22 |
- req_sid ? req_sid : "<failed to display>");
|
|
|
d8cf22 |
- kerr = KRB5KDC_ERR_POLICY;
|
|
|
d8cf22 |
- goto done;
|
|
|
d8cf22 |
+ struct ipadb_context *ipactx = ipadb_get_context(context);
|
|
|
d8cf22 |
+ if (!ipactx || !ipactx->mspac) {
|
|
|
d8cf22 |
+ return KRB5_KDB_DBNOTINITED;
|
|
|
d8cf22 |
+ }
|
|
|
d8cf22 |
+ /* In S4U case we might be dealing with the PAC issued by the trusted domain */
|
|
|
d8cf22 |
+ if (is_s4u && (ipactx->mspac->trusts != NULL)) {
|
|
|
d8cf22 |
+ /* Iterate through list of trusts and check if this SID belongs to
|
|
|
d8cf22 |
+ * one of the domains we trust */
|
|
|
d8cf22 |
+ for(int i = 0 ; i < ipactx->mspac->num_trusts ; i++) {
|
|
|
d8cf22 |
+ result = dom_sid_check(&ipactx->mspac->trusts[i].domsid,
|
|
|
d8cf22 |
+ requester_sid, false);
|
|
|
d8cf22 |
+ if (result) {
|
|
|
d8cf22 |
+ is_from_trusted_domain = true;
|
|
|
d8cf22 |
+ break;
|
|
|
d8cf22 |
+ }
|
|
|
d8cf22 |
+ }
|
|
|
d8cf22 |
+ }
|
|
|
d8cf22 |
+
|
|
|
d8cf22 |
+ if (!is_from_trusted_domain) {
|
|
|
d8cf22 |
+ /* memctx is freed by the caller */
|
|
|
d8cf22 |
+ char *pac_sid = dom_sid_string(tmpctx, &client_sid);
|
|
|
d8cf22 |
+ char *req_sid = dom_sid_string(tmpctx, requester_sid);
|
|
|
d8cf22 |
+ krb5_klog_syslog(LOG_ERR, "PAC issue: PAC has a SID "
|
|
|
d8cf22 |
+ "different from what PAC requester claims. "
|
|
|
d8cf22 |
+ "PAC [%s] vs PAC requester [%s]",
|
|
|
d8cf22 |
+ pac_sid ? pac_sid : "<failed to display>",
|
|
|
d8cf22 |
+ req_sid ? req_sid : "<failed to display>");
|
|
|
d8cf22 |
+ kerr = KRB5KDC_ERR_TGT_REVOKED;
|
|
|
d8cf22 |
+ goto done;
|
|
|
d8cf22 |
+ }
|
|
|
d8cf22 |
}
|
|
|
d8cf22 |
}
|
|
|
d8cf22 |
|
|
|
d8cf22 |
--
|
|
|
d8cf22 |
2.31.1
|
|
|
d8cf22 |
|