From 8b6d1ab854387840f7526d6d59ddc7102231957f 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 --- 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 498bef7a7..dd29db190 100644 --- a/daemons/ipa-kdb/ipa_kdb_mspac.c +++ b/daemons/ipa-kdb/ipa_kdb_mspac.c @@ -2392,6 +2392,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); @@ -2602,6 +2603,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_blocklist_incoming); @@ -2971,6 +2990,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 d24cf1ffd..d23a14a0b 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);