From 1f0702bf9231a4898a2d58325fc51c71fea25047 Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Fri, 23 Oct 2020 18:45:09 +0300 Subject: [PATCH] ipa-kdb: support subordinate/superior UPN suffixes [MS-ADTS] 6.1.6.9.3.2 requires msDS-TrustForestTrustInfo attribute of trusted domain information in Active Directory to conform certain rules. One side-effect of those rules is that list of UPN suffixes reported through the netr_DsRGetForestTrustInformation function is dynamically filtered to deduplicate subordinate suffixes. It means that if list of UPN suffixes contains the following top level names (TLNs): fabrikam.com sub.fabrikam.com then netr_DsRGetForestTrustInformation would only return 'fabrikam.com' as the TLN, fully filtering 'sub.fabrikam.com'. IPA KDB driver used exact comparison of the UPN suffixes so any subordinate had to be specified exactly. Modify logic so that if exact check does not succeed, we validate a realm to test being a subordinate of the known UPN suffixes. The subordinate check is done by making sure UPN suffix is at the end of the test realm and is immediately preceded with a dot. Because the function to check suffixes potentially called for every Kerberos principal, precalculate and cache length for each UPN suffix at the time we retrieve the list of them. Fixes: https://pagure.io/freeipa/issue/8554 Signed-off-by: Alexander Bokovoy Reviewed-By: Rob Crittenden Reviewed-By: Robbie Harwood Reviewed-By: Rob Crittenden Reviewed-By: Robbie Harwood --- daemons/ipa-kdb/ipa_kdb_mspac.c | 30 +++++++++++++++++++++++++ daemons/ipa-kdb/ipa_kdb_mspac_private.h | 1 + 2 files changed, 31 insertions(+) diff --git a/daemons/ipa-kdb/ipa_kdb_mspac.c b/daemons/ipa-kdb/ipa_kdb_mspac.c index 29dadc183..692f542c9 100644 --- a/daemons/ipa-kdb/ipa_kdb_mspac.c +++ b/daemons/ipa-kdb/ipa_kdb_mspac.c @@ -2393,6 +2393,7 @@ void ipadb_mspac_struct_free(struct ipadb_mspac **mspac) free((*mspac)->trusts[i].upn_suffixes[j]); } free((*mspac)->trusts[i].upn_suffixes); + free((*mspac)->trusts[i].upn_suffixes_len); } } free((*mspac)->trusts); @@ -2603,6 +2604,24 @@ krb5_error_code ipadb_mspac_get_trusted_domains(struct ipadb_context *ipactx) } } + t[n].upn_suffixes_len = NULL; + if (t[n].upn_suffixes != NULL) { + size_t len = 0; + + for (; t[n].upn_suffixes[len] != NULL; len++); + + if (len != 0) { + t[n].upn_suffixes_len = calloc(n, sizeof(size_t)); + if (t[n].upn_suffixes_len == NULL) { + ret = ENOMEM; + goto done; + } + for (i = 0; i < len; i++) { + t[n].upn_suffixes_len[i] = strlen(t[n].upn_suffixes[i]); + } + } + } + ret = ipadb_ldap_attr_to_strlist(lc, le, "ipaNTSIDBlacklistIncoming", &sid_blacklist_incoming); @@ -2972,6 +2991,17 @@ krb5_error_code ipadb_is_princ_from_trusted_realm(krb5_context kcontext, result = strncasecmp(test_realm, ipactx->mspac->trusts[i].upn_suffixes[j], size) == 0; + if (!result) { + /* if UPN suffix did not match exactly, find if it is + * superior to the test_realm, e.g. if test_realm ends + * with the UPN suffix prefixed with dot*/ + size_t len = ipactx->mspac->trusts[i].upn_suffixes_len[j]; + if ((size > len) && (test_realm[size - len - 1] == '.')) { + result = strncasecmp(test_realm + (size - len), + ipactx->mspac->trusts[i].upn_suffixes[j], + len) == 0; + } + } if (result) break; } diff --git a/daemons/ipa-kdb/ipa_kdb_mspac_private.h b/daemons/ipa-kdb/ipa_kdb_mspac_private.h index 30382d2ee..b21aa163f 100644 --- a/daemons/ipa-kdb/ipa_kdb_mspac_private.h +++ b/daemons/ipa-kdb/ipa_kdb_mspac_private.h @@ -48,6 +48,7 @@ struct ipadb_adtrusts { struct ipadb_adtrusts *parent; char *parent_name; char **upn_suffixes; + size_t *upn_suffixes_len; }; int string_to_sid(const char *str, struct dom_sid *sid); -- 2.29.2