Hi! Attached two patches attempt to fix some of the issues we see with child domains.
SSSD only 'sees' users from child domains if there is an ID range for each of them. However, after refactoring of trust code when external trust was introduced, part of the range creation had wrong assumption that if a trusted domain exists, its range also exists. This is now fixed to try to create range even if the domain exists. In fact, because the older code was not going to the range creation for trusted domains which already existed, adding ranges was done incorrectly: ID ranges use full domain name and don't need <parent>-<child> hierarchy, but the code was passing both parent and the child names. As result, an attempt to create an ID range for parent was done instead of the child. Parent ID range already existed so we never got to create child ID ranges at all in that case. Finally, there is a fix in SSSD to properly generate CA paths so that libkrb5 can calculate correct trust path via forest root (parent) domain. While looking at that, I also decided to simplify logic in ipa-kdb driver because for cross-forest trust we never can transit to the child domain directly, we always have to use the forest root domain. However, old code could actually set a immediate domain's parent instead of the forest root for deep level trust relationship within the forest we trust. As we still cannot get to second level or beyond directly or via their actual parent domain, we always have to go through the forest root domain. The simplified code enforces this logic. -- / Alexander Bokovoy
From 37e4ab4786aec94bfb057fa3146d4e18e30df391 Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy <[email protected]> Date: Sat, 6 Aug 2016 11:12:13 +0300 Subject: [PATCH 4/5] trust: make sure ID range is created for the child domain even if it exists ID ranges for child domains of a forest trust were created incorrectly in FreeIPA 4.4.0 due to refactoring of -- if the domain was already existing, we never attempted to create the ID range for it. At the same time, when domain was missing, we attempted to add ID range and passed both forest root and the child domain names to add_range(). However, add_range() only looks at the first positional argument which was the forest root name. That ID range always exists (it is created before child domains are processed). Modify the code to make sure child domain name is passed as the first positional argument. In addition, the oddjob helper should explicitly set context='server' so that idrange code will be able to see and use ipaserver/dcerpc.py helpers. Resolves: https://fedorahosted.org/freeipa/ticket/5738 --- install/oddjob/com.redhat.idm.trust-fetch-domains | 2 +- ipaserver/plugins/trust.py | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/install/oddjob/com.redhat.idm.trust-fetch-domains b/install/oddjob/com.redhat.idm.trust-fetch-domains index 7c948fd..bffa021 100755 --- a/install/oddjob/com.redhat.idm.trust-fetch-domains +++ b/install/oddjob/com.redhat.idm.trust-fetch-domains @@ -76,7 +76,7 @@ env._bootstrap(debug=options.debug, log=None) env._finalize_core(**dict(DEFAULT_CONFIG)) # Initialize the API with the proper debug level -api.bootstrap(in_server=True, debug=env.debug, log=None) +api.bootstrap(in_server=True, debug=env.debug, log=None, context='server') api.finalize() # Only import trust plugin after api is initialized or internal imports diff --git a/ipaserver/plugins/trust.py b/ipaserver/plugins/trust.py index f2e0b1e..f90d9c1 100644 --- a/ipaserver/plugins/trust.py +++ b/ipaserver/plugins/trust.py @@ -1673,15 +1673,19 @@ def add_new_domains_from_trust(myapi, trustinstance, trust_entry, domains, **opt if 'raw' in options: dom['raw'] = options['raw'] - res = myapi.Command.trustdomain_add(trust_name, name, **dom) - result.append(res['result']) + try: + res = myapi.Command.trustdomain_add(trust_name, name, **dom) + result.append(res['result']) + except errors.DuplicateEntry: + # Ignore updating duplicate entries + pass if idrange_type != u'ipa-ad-trust-posix': range_name = name.upper() + '_id_range' dom['range_type'] = u'ipa-ad-trust' add_range(myapi, trustinstance, range_name, dom['ipanttrusteddomainsid'], - trust_name, name, **dom) + name, **dom) except errors.DuplicateEntry: # Ignore updating duplicate entries pass -- 2.7.4
From 767458d1532feb7029ff9a52e67e931fd87869ec Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy <[email protected]> Date: Sun, 7 Aug 2016 21:42:14 +0300 Subject: [PATCH 5/5] 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=<forest root>, 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 --- daemons/ipa-kdb/ipa_kdb_mspac.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/daemons/ipa-kdb/ipa_kdb_mspac.c b/daemons/ipa-kdb/ipa_kdb_mspac.c index 80e7055..76e9e99 100644 --- a/daemons/ipa-kdb/ipa_kdb_mspac.c +++ b/daemons/ipa-kdb/ipa_kdb_mspac.c @@ -2420,6 +2420,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; @@ -2547,26 +2548,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; } -- 2.7.4
-- Manage your subscription for the Freeipa-devel mailing list: https://www.redhat.com/mailman/listinfo/freeipa-devel Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code
