From a14ebbea895a20f5a68052e32ba65c4fd7fdf670 Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Aug 22 2016 12:03:00 +0000 Subject: ipa-kdb: simplify trusted domain parent search In terms of cross-forest trust parent domain is the root domain of the forest because we only have trust established with the forest root. In FreeIPA LDAP store all sub-domains stored in cn=, cn=ad,cn=trusts,... subtree. Thus, a first RDN after cn=ad is the forest root domain. This allows us to simplify logic of finding the parent domain. For complex hierachical forests with more than two levels of sub-domains, this will still be true because of the forest trust: as forest trust is established to the forest root domain, any communication to any sub-domain must traverse forest root domain's domain controller. Note that SSSD also generated incorrectly CA paths information for forests with non-hierarchical tree-roots. In such cases IPA KDC got confused and mistakenly assumed direct trust to the non-hierarchical tree-root instead of going through the forest root domain. See https://fedorahosted.org/sssd/ticket/3103 for details. Resolves: https://fedorahosted.org/freeipa/ticket/5738 Reviewed-By: Martin Babinsky --- diff --git a/daemons/ipa-kdb/ipa_kdb_mspac.c b/daemons/ipa-kdb/ipa_kdb_mspac.c index 65cc035..cf1bd5b 100644 --- a/daemons/ipa-kdb/ipa_kdb_mspac.c +++ b/daemons/ipa-kdb/ipa_kdb_mspac.c @@ -2429,6 +2429,7 @@ krb5_error_code ipadb_mspac_get_trusted_domains(struct ipadb_context *ipactx) char *base = NULL; char *dnstr = NULL; char *dnl = NULL; + LDAPDN dn = NULL; char **sid_blacklist_incoming = NULL; char **sid_blacklist_outgoing = NULL; int ret, n, i; @@ -2556,26 +2557,26 @@ krb5_error_code ipadb_mspac_get_trusted_domains(struct ipadb_context *ipactx) goto done; } - /* Note that after ldap_str2rdn() call dnl will point to end of one RDN - * which would be '\0' for trust root domain and ',' for subdomain */ dnl--; dnl[0] = '\0'; - ret = ldap_str2rdn(dnstr, &rdn, &dnl, LDAP_DN_FORMAT_LDAPV3); + /* Create a DN, which is now everything before the base, + * to get list of rdn values -- the last one would be a root domain. + * Since with cross-forest trust we have to route everything via root + * domain, that is enough for us to assign parentship. */ + ret = ldap_str2dn(dnstr, &dn, LDAP_DN_FORMAT_LDAPV3); if (ret) { goto done; } - ldap_rdnfree(rdn); - - if (dnl[0] != '\0') { - dnl++; - ret = ldap_str2rdn(dnl, &rdn, &dnl, LDAP_DN_FORMAT_LDAPV3); - if (ret) { - goto done; - } - t[n].parent_name = strndup(rdn[0]->la_value.bv_val, rdn[0]->la_value.bv_len); - ldap_rdnfree(rdn); + rdn = NULL; + for (i = 0; dn[i] != NULL; i++) { + rdn = dn[i]; } + /* We should have a single AVA in the domain RDN */ + t[n].parent_name = strndup(rdn[0]->la_value.bv_val, rdn[0]->la_value.bv_len); + + ldap_dnfree(dn); + free(dnstr); dnstr = NULL; }