|
|
403b09 |
From 79bcdeb76d51fec5e8eab08f7642e7910e925bb4 Mon Sep 17 00:00:00 2001
|
|
|
403b09 |
From: Alexander Bokovoy <abokovoy@redhat.com>
|
|
|
403b09 |
Date: Mon, 15 Aug 2016 18:14:00 +0300
|
|
|
403b09 |
Subject: [PATCH] trust: automatically resolve DNS trust conflicts for triangle
|
|
|
403b09 |
trusts
|
|
|
403b09 |
|
|
|
403b09 |
For configuration where:
|
|
|
403b09 |
- AD example.com trusts IPA at ipa.example.com
|
|
|
403b09 |
- AD example.org trusts AD example.com
|
|
|
403b09 |
- a trust is tried to be established between ipa.example.com and
|
|
|
403b09 |
example.org,
|
|
|
403b09 |
|
|
|
403b09 |
there will be a trust topology conflict detected by example.org domain
|
|
|
403b09 |
controller because ipa.example.com DNS namespace overlaps with
|
|
|
403b09 |
example.com DNS namespace.
|
|
|
403b09 |
|
|
|
403b09 |
This type of trust topology conflict is documented in MS-ADTS 6.1.6.9.3.2
|
|
|
403b09 |
"Building Well-Formed msDS-TrustForestTrustInfo Message". A similar
|
|
|
403b09 |
conflict can arise for SID and NetBIOS namespaces. However, unlike SID
|
|
|
403b09 |
and NetBIOS namespaces, we can solve DNS namespace conflict
|
|
|
403b09 |
automatically if there are administrative credentials for example.org
|
|
|
403b09 |
available.
|
|
|
403b09 |
|
|
|
403b09 |
A manual sequence to solve the DNS namespace conflict is described in
|
|
|
403b09 |
https://msdn.microsoft.com/it-it/library/cc786254%28v=ws.10%29.aspx.
|
|
|
403b09 |
This sequence boils down to the following steps:
|
|
|
403b09 |
|
|
|
403b09 |
1. As an administrator of the example.org, you need to add an
|
|
|
403b09 |
exclusion entry for ipa.example.com in the properties of the trust to
|
|
|
403b09 |
example.com
|
|
|
403b09 |
2. Establish trust between ipa.example.com and example.org
|
|
|
403b09 |
|
|
|
403b09 |
It is important to add the exclusion entry before step 4 or there will
|
|
|
403b09 |
be conflict recorded which cannot be cleared easily right now due to a
|
|
|
403b09 |
combination of bugs in both IPA and Active Directory.
|
|
|
403b09 |
|
|
|
403b09 |
This patchset implements automated solution for the case when we have
|
|
|
403b09 |
access to the example.org's administrator credentials:
|
|
|
403b09 |
|
|
|
403b09 |
1. Attempt to establish trust and update trust topology information.
|
|
|
403b09 |
2. If trust topology conflict is detected as result of (1):
|
|
|
403b09 |
2.1. Fetch trust topology infromation for the conflicting forest
|
|
|
403b09 |
trust
|
|
|
403b09 |
2.2. Add exclusion entry to our domain to the trust topology obtained
|
|
|
403b09 |
in (2.1)
|
|
|
403b09 |
2.3. Update trust topology for the conflicting forest trust
|
|
|
403b09 |
3. Re-establish trust between ipa.example.com and example.org
|
|
|
403b09 |
|
|
|
403b09 |
We cannot do the same for shared secret trust and for external trust,
|
|
|
403b09 |
though:
|
|
|
403b09 |
|
|
|
403b09 |
1. For shared secret trust we don't have administrative credentials
|
|
|
403b09 |
in the forest reporting the conflict
|
|
|
403b09 |
|
|
|
403b09 |
2. For the external trust we cannot set topology information due to
|
|
|
403b09 |
MS-LSAD 3.1.4.7.16 because external trust is non-transitive by
|
|
|
403b09 |
definition and thus setting topology information will fail.
|
|
|
403b09 |
|
|
|
403b09 |
To test this logic one can use two Samba AD forests with FreeIPA
|
|
|
403b09 |
using a sub-domain of one of them.
|
|
|
403b09 |
|
|
|
403b09 |
Fixes: https://fedorahosted.org/freeipa/ticket/6076
|
|
|
403b09 |
Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
|
|
|
403b09 |
---
|
|
|
403b09 |
ipalib/errors.py | 29 ++++++-
|
|
|
403b09 |
ipaserver/dcerpc.py | 220 +++++++++++++++++++++++++++++++++++++++++++++-------
|
|
|
403b09 |
2 files changed, 220 insertions(+), 29 deletions(-)
|
|
|
403b09 |
|
|
|
403b09 |
diff --git a/ipalib/errors.py b/ipalib/errors.py
|
|
|
403b09 |
index 7b4f15dd60ee80719195ba1b9b85d075b10bdf4f..4cc4455b0abf7d2b1366e1ce6dbb3762bc551cc6 100644
|
|
|
403b09 |
--- a/ipalib/errors.py
|
|
|
403b09 |
+++ b/ipalib/errors.py
|
|
|
403b09 |
@@ -866,7 +866,6 @@ class NotAForestRootError(InvocationError):
|
|
|
403b09 |
errno = 3016
|
|
|
403b09 |
format = _("Domain '%(domain)s' is not a root domain for forest '%(forest)s'")
|
|
|
403b09 |
|
|
|
403b09 |
-
|
|
|
403b09 |
##############################################################################
|
|
|
403b09 |
# 4000 - 4999: Execution errors
|
|
|
403b09 |
|
|
|
403b09 |
@@ -1908,6 +1907,34 @@ class DNSResolverError(DNSError):
|
|
|
403b09 |
errno = 4401
|
|
|
403b09 |
format = _('%(exception)s')
|
|
|
403b09 |
|
|
|
403b09 |
+class TrustError(ExecutionError):
|
|
|
403b09 |
+ """
|
|
|
403b09 |
+ **4500** Base class for trust execution errors (*4500 - 4599*).
|
|
|
403b09 |
+ These are typically instantiated when there is an error in establishing or
|
|
|
403b09 |
+ modifying a trust to another forest.
|
|
|
403b09 |
+ """
|
|
|
403b09 |
+
|
|
|
403b09 |
+ errno = 4500
|
|
|
403b09 |
+
|
|
|
403b09 |
+class TrustTopologyConflictError(TrustError):
|
|
|
403b09 |
+ """
|
|
|
403b09 |
+ **4501** Raised when an attempt to establish trust fails with a topology
|
|
|
403b09 |
+ conflict against another forest the target forest trusts
|
|
|
403b09 |
+
|
|
|
403b09 |
+ For example:
|
|
|
403b09 |
+
|
|
|
403b09 |
+ >>> raise TrustTopologyConflictError(forest='example.test',
|
|
|
403b09 |
+ conflict='my.ad.test',
|
|
|
403b09 |
+ domains=['ad.test'])
|
|
|
403b09 |
+ Traceback (most recent call last):
|
|
|
403b09 |
+ ...
|
|
|
403b09 |
+ TrustTopologyConflictError: Forest 'example.test' has existing trust to forest(s) ['ad.test'] which prevents a trust to 'my.ad.test'
|
|
|
403b09 |
+ """
|
|
|
403b09 |
+
|
|
|
403b09 |
+ errno = 4501
|
|
|
403b09 |
+ format = _("Forest '%(forest)s' has existing trust to forest(s) "
|
|
|
403b09 |
+ "%(domains)s which prevents a trust to '%(conflict)s'")
|
|
|
403b09 |
+
|
|
|
403b09 |
|
|
|
403b09 |
##############################################################################
|
|
|
403b09 |
# 5000 - 5999: Generic errors
|
|
|
403b09 |
diff --git a/ipaserver/dcerpc.py b/ipaserver/dcerpc.py
|
|
|
403b09 |
index 19be6bf7a3617a3b867d51a9358c9926e91049a7..a1c12f16a655493808d50e6adb95e618a664a98c 100644
|
|
|
403b09 |
--- a/ipaserver/dcerpc.py
|
|
|
403b09 |
+++ b/ipaserver/dcerpc.py
|
|
|
403b09 |
@@ -1,7 +1,7 @@
|
|
|
403b09 |
# Authors:
|
|
|
403b09 |
# Alexander Bokovoy <abokovoy@redhat.com>
|
|
|
403b09 |
#
|
|
|
403b09 |
-# Copyright (C) 2011 Red Hat
|
|
|
403b09 |
+# Copyright (C) 2011-2016 Red Hat
|
|
|
403b09 |
# see file 'COPYING' for use and warranty information
|
|
|
403b09 |
#
|
|
|
403b09 |
# Portions (C) Andrew Tridgell, Andrew Bartlett
|
|
|
403b09 |
@@ -140,6 +140,15 @@ pysss_type_key_translation_dict = {
|
|
|
403b09 |
pysss_nss_idmap.ID_BOTH: 'both',
|
|
|
403b09 |
}
|
|
|
403b09 |
|
|
|
403b09 |
+class TrustTopologyConflictSolved(Exception):
|
|
|
403b09 |
+ """
|
|
|
403b09 |
+ Internal trust error: raised when previously detected
|
|
|
403b09 |
+ trust topology conflict is automatically solved.
|
|
|
403b09 |
+
|
|
|
403b09 |
+ No separate errno is assigned as this error should
|
|
|
403b09 |
+ not be visible outside the dcerpc.py code.
|
|
|
403b09 |
+ """
|
|
|
403b09 |
+ pass
|
|
|
403b09 |
|
|
|
403b09 |
def assess_dcerpc_exception(num=None, message=None):
|
|
|
403b09 |
"""
|
|
|
403b09 |
@@ -1087,34 +1096,165 @@ class TrustDomainInstance(object):
|
|
|
403b09 |
info.entries = ftinfo_records
|
|
|
403b09 |
return info
|
|
|
403b09 |
|
|
|
403b09 |
+ def clear_ftinfo_conflict(self, another_domain, cinfo):
|
|
|
403b09 |
+ """
|
|
|
403b09 |
+ Attempt to clean up the forest trust collisions
|
|
|
403b09 |
+
|
|
|
403b09 |
+ :param self: the forest we establish trust to
|
|
|
403b09 |
+ :param another_domain: a forest that establishes trust to 'self'
|
|
|
403b09 |
+ :param cinfo: lsa_ForestTrustCollisionInfo structure that contain
|
|
|
403b09 |
+ set of of lsa_ForestTrustCollisionRecord structures
|
|
|
403b09 |
+ :raises: TrustTopologyConflictSolved, TrustTopologyConflictError
|
|
|
403b09 |
+
|
|
|
403b09 |
+ This code tries to perform intelligent job of going
|
|
|
403b09 |
+ over individual collisions and making exclusion entries
|
|
|
403b09 |
+ for affected IPA namespaces.
|
|
|
403b09 |
+
|
|
|
403b09 |
+ There are three possible conflict configurations:
|
|
|
403b09 |
+ - conflict of DNS namespace (TLN conflict, LSA_TLN_DISABLED_CONFLICT)
|
|
|
403b09 |
+ - conflict of SID namespace (LSA_SID_DISABLED_CONFLICT)
|
|
|
403b09 |
+ - conflict of NetBIOS namespace (LSA_NB_DISABLED_CONFLICT)
|
|
|
403b09 |
+
|
|
|
403b09 |
+ we only can handle TLN conflicts because (a) excluding SID namespace
|
|
|
403b09 |
+ is not possible and (b) excluding NetBIOS namespace not possible.
|
|
|
403b09 |
+ These two types of conflicts should result in trust-add CLI error
|
|
|
403b09 |
+
|
|
|
403b09 |
+ These conflicts can come from external source (another forest) or
|
|
|
403b09 |
+ from internal source (another domain in the same forest). We only
|
|
|
403b09 |
+ can fix the problems with another forest.
|
|
|
403b09 |
+
|
|
|
403b09 |
+ To resolve TLN conflict we need to do following:
|
|
|
403b09 |
+ 1. Retrieve forest trust information for the forest we conflict on
|
|
|
403b09 |
+ 2. Add an exclusion entry for IPA DNS namespace to it
|
|
|
403b09 |
+ 3. Set forest trust information for the forest we conflict on
|
|
|
403b09 |
+ 4. Re-try establishing trust to the original forest
|
|
|
403b09 |
+
|
|
|
403b09 |
+ This all can only be done under privileges of Active Directory admin
|
|
|
403b09 |
+ that can change forest trusts. If we cannot have those privileges,
|
|
|
403b09 |
+ the work has to be done manually in the Windows UI for
|
|
|
403b09 |
+ 'Active Directory Domains and Trusts' by the administrator of the
|
|
|
403b09 |
+ original forest.
|
|
|
403b09 |
+ """
|
|
|
403b09 |
+
|
|
|
403b09 |
+ # List of entries for unsolved conflicts
|
|
|
403b09 |
+ result = []
|
|
|
403b09 |
+
|
|
|
403b09 |
+ trust_timestamp = long(time.time()*1e7+116444736000000000)
|
|
|
403b09 |
+
|
|
|
403b09 |
+ # Collision information contains entries for specific trusted domains
|
|
|
403b09 |
+ # we collide with. Look into TLN collisions and add a TLN exclusion
|
|
|
403b09 |
+ # entry to the specific domain trust.
|
|
|
403b09 |
+ root_logger.error("Attempt to solve forest trust topology conflicts")
|
|
|
403b09 |
+ for rec in cinfo.entries:
|
|
|
403b09 |
+ if rec.type == lsa.LSA_FOREST_TRUST_COLLISION_TDO:
|
|
|
403b09 |
+ dominfo = self._pipe.lsaRQueryForestTrustInformation(
|
|
|
403b09 |
+ self._policy_handle,
|
|
|
403b09 |
+ rec.name,
|
|
|
403b09 |
+ lsa.LSA_FOREST_TRUST_DOMAIN_INFO)
|
|
|
403b09 |
+
|
|
|
403b09 |
+ # Oops, we were unable to retrieve trust topology for this
|
|
|
403b09 |
+ # trusted domain (forest).
|
|
|
403b09 |
+ if not dominfo:
|
|
|
403b09 |
+ result.append(rec)
|
|
|
403b09 |
+ root_logger.error("Unable to resolve conflict for "
|
|
|
403b09 |
+ "DNS domain %s in the forest %s "
|
|
|
403b09 |
+ "for domain trust %s. Trust cannot "
|
|
|
403b09 |
+ "be established unless this conflict "
|
|
|
403b09 |
+ "is fixed manually."
|
|
|
403b09 |
+ % (another_domain.info['dns_domain'],
|
|
|
403b09 |
+ self.info['dns_domain'],
|
|
|
403b09 |
+ rec.name.string))
|
|
|
403b09 |
+ continue
|
|
|
403b09 |
+
|
|
|
403b09 |
+ # Copy over the entries, extend with TLN exclusion
|
|
|
403b09 |
+ entries = []
|
|
|
403b09 |
+ for e in dominfo.entries:
|
|
|
403b09 |
+ e1 = lsa.ForestTrustRecord()
|
|
|
403b09 |
+ e1.type = e.type
|
|
|
403b09 |
+ e1.flags = e.flags
|
|
|
403b09 |
+ e1.time = e.time
|
|
|
403b09 |
+ e1.forest_trust_data = e.forest_trust_data
|
|
|
403b09 |
+ entries.append(e1)
|
|
|
403b09 |
+
|
|
|
403b09 |
+ # Create TLN exclusion record
|
|
|
403b09 |
+ record = lsa.ForestTrustRecord()
|
|
|
403b09 |
+ record.type = lsa.LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX
|
|
|
403b09 |
+ record.flags = 0
|
|
|
403b09 |
+ record.time = trust_timestamp
|
|
|
403b09 |
+ record.forest_trust_data.string = \
|
|
|
403b09 |
+ another_domain.info['dns_domain']
|
|
|
403b09 |
+ entries.append(record)
|
|
|
403b09 |
+
|
|
|
403b09 |
+ fti = lsa.ForestTrustInformation()
|
|
|
403b09 |
+ fti.count = len(entries)
|
|
|
403b09 |
+ fti.entries = entries
|
|
|
403b09 |
+
|
|
|
403b09 |
+ # Update the forest trust information now
|
|
|
403b09 |
+ ldname = lsa.StringLarge()
|
|
|
403b09 |
+ ldname.string = rec.name.string
|
|
|
403b09 |
+ cninfo = self._pipe.lsaRSetForestTrustInformation(
|
|
|
403b09 |
+ self._policy_handle,
|
|
|
403b09 |
+ ldname,
|
|
|
403b09 |
+ lsa.LSA_FOREST_TRUST_DOMAIN_INFO,
|
|
|
403b09 |
+ fti, 0)
|
|
|
403b09 |
+ if cninfo:
|
|
|
403b09 |
+ result.append(rec)
|
|
|
403b09 |
+ root_logger.error("When defining exception for DNS "
|
|
|
403b09 |
+ "domain %s in forest %s for "
|
|
|
403b09 |
+ "trusted forest %s, "
|
|
|
403b09 |
+ "got collision info back:\n%s"
|
|
|
403b09 |
+ % (another_domain.info['dns_domain'],
|
|
|
403b09 |
+ self.info['dns_domain'],
|
|
|
403b09 |
+ rec.name.string,
|
|
|
403b09 |
+ ndr_print(cninfo)))
|
|
|
403b09 |
+ else:
|
|
|
403b09 |
+ result.append(rec)
|
|
|
403b09 |
+ root_logger.error("Unable to resolve conflict for "
|
|
|
403b09 |
+ "DNS domain %s in the forest %s "
|
|
|
403b09 |
+ "for in-forest domain %s. Trust cannot "
|
|
|
403b09 |
+ "be established unless this conflict "
|
|
|
403b09 |
+ "is fixed manually."
|
|
|
403b09 |
+ % (another_domain.info['dns_domain'],
|
|
|
403b09 |
+ self.info['dns_domain'],
|
|
|
403b09 |
+ rec.name.string))
|
|
|
403b09 |
+
|
|
|
403b09 |
+ if len(result) == 0:
|
|
|
403b09 |
+ root_logger.error("Successfully solved all conflicts")
|
|
|
403b09 |
+ raise TrustTopologyConflictSolved()
|
|
|
403b09 |
+
|
|
|
403b09 |
+ # Otherwise, raise TrustTopologyConflictError() exception
|
|
|
403b09 |
+ domains = [x.name.string for x in result]
|
|
|
403b09 |
+ raise errors.TrustTopologyConflictError(
|
|
|
403b09 |
+ target=self.info['dns_domain'],
|
|
|
403b09 |
+ conflict=another_domain.info['dns_domain'],
|
|
|
403b09 |
+ domains=domains)
|
|
|
403b09 |
+
|
|
|
403b09 |
+
|
|
|
403b09 |
+
|
|
|
403b09 |
def update_ftinfo(self, another_domain):
|
|
|
403b09 |
"""
|
|
|
403b09 |
Updates forest trust information in this forest corresponding
|
|
|
403b09 |
to the another domain's information.
|
|
|
403b09 |
"""
|
|
|
403b09 |
- try:
|
|
|
403b09 |
- if another_domain.ftinfo_records:
|
|
|
403b09 |
- ftinfo = self.generate_ftinfo(another_domain)
|
|
|
403b09 |
- # Set forest trust information -- we do it only against AD DC as
|
|
|
403b09 |
- # smbd already has the information about itself
|
|
|
403b09 |
- ldname = lsa.StringLarge()
|
|
|
403b09 |
- ldname.string = another_domain.info['dns_domain']
|
|
|
403b09 |
- ftlevel = lsa.LSA_FOREST_TRUST_DOMAIN_INFO
|
|
|
403b09 |
- # RSetForestTrustInformation returns collision information
|
|
|
403b09 |
- # for trust topology
|
|
|
403b09 |
- cinfo = self._pipe.lsaRSetForestTrustInformation(
|
|
|
403b09 |
- self._policy_handle,
|
|
|
403b09 |
- ldname,
|
|
|
403b09 |
- ftlevel,
|
|
|
403b09 |
- ftinfo, 0)
|
|
|
403b09 |
- if cinfo:
|
|
|
403b09 |
- root_logger.error("When setting forest trust information, "
|
|
|
403b09 |
- "got collision info back:\n%s"
|
|
|
403b09 |
- % (ndr_print(cinfo)))
|
|
|
403b09 |
- except RuntimeError as e:
|
|
|
403b09 |
- # We can ignore the error here --
|
|
|
403b09 |
- # setting up name suffix routes may fail
|
|
|
403b09 |
- pass
|
|
|
403b09 |
+ if another_domain.ftinfo_records:
|
|
|
403b09 |
+ ftinfo = self.generate_ftinfo(another_domain)
|
|
|
403b09 |
+ # Set forest trust information -- we do it only against AD DC as
|
|
|
403b09 |
+ # smbd already has the information about itself
|
|
|
403b09 |
+ ldname = lsa.StringLarge()
|
|
|
403b09 |
+ ldname.string = another_domain.info['dns_domain']
|
|
|
403b09 |
+ ftlevel = lsa.LSA_FOREST_TRUST_DOMAIN_INFO
|
|
|
403b09 |
+ # RSetForestTrustInformation returns collision information
|
|
|
403b09 |
+ # for trust topology
|
|
|
403b09 |
+ cinfo = self._pipe.lsaRSetForestTrustInformation(
|
|
|
403b09 |
+ self._policy_handle,
|
|
|
403b09 |
+ ldname,
|
|
|
403b09 |
+ ftlevel,
|
|
|
403b09 |
+ ftinfo, 0)
|
|
|
403b09 |
+ if cinfo:
|
|
|
403b09 |
+ root_logger.error("When setting forest trust information, "
|
|
|
403b09 |
+ "got collision info back:\n%s"
|
|
|
403b09 |
+ % (ndr_print(cinfo)))
|
|
|
403b09 |
+ self.clear_ftinfo_conflict(another_domain, cinfo)
|
|
|
403b09 |
|
|
|
403b09 |
def establish_trust(self, another_domain, trustdom_secret,
|
|
|
403b09 |
trust_type='bidirectional', trust_external=False):
|
|
|
403b09 |
@@ -1207,7 +1347,19 @@ class TrustDomainInstance(object):
|
|
|
403b09 |
root_logger.error(
|
|
|
403b09 |
'unable to set trust transitivity status: %s' % (str(e)))
|
|
|
403b09 |
|
|
|
403b09 |
- if self.info['is_pdc'] or trust_external:
|
|
|
403b09 |
+ # Updating forest trust info may fail
|
|
|
403b09 |
+ # If it failed due to topology conflict, it may be fixed automatically
|
|
|
403b09 |
+ # update_ftinfo() will through exceptions in that case
|
|
|
403b09 |
+ # Note that MS-LSAD 3.1.4.7.16 says:
|
|
|
403b09 |
+ # -------------------------
|
|
|
403b09 |
+ # The server MUST also make sure that the trust attributes associated
|
|
|
403b09 |
+ # with the trusted domain object referenced by the TrustedDomainName
|
|
|
403b09 |
+ # parameter has the TRUST_ATTRIBUTE_FOREST_TRANSITIVE set.
|
|
|
403b09 |
+ # If the attribute is not present, the server MUST return
|
|
|
403b09 |
+ # STATUS_INVALID_PARAMETER.
|
|
|
403b09 |
+ # -------------------------
|
|
|
403b09 |
+ # Thus, we must not update forest trust info for the external trust
|
|
|
403b09 |
+ if self.info['is_pdc'] and not trust_external:
|
|
|
403b09 |
self.update_ftinfo(another_domain)
|
|
|
403b09 |
|
|
|
403b09 |
def verify_trust(self, another_domain):
|
|
|
403b09 |
@@ -1509,9 +1661,21 @@ class TrustDomainJoins(object):
|
|
|
403b09 |
if not self.remote_domain.read_only:
|
|
|
403b09 |
trustdom_pass = samba.generate_random_password(128, 128)
|
|
|
403b09 |
self.get_realmdomains()
|
|
|
403b09 |
- self.remote_domain.establish_trust(self.local_domain,
|
|
|
403b09 |
- trustdom_pass,
|
|
|
403b09 |
- trust_type, trust_external)
|
|
|
403b09 |
+
|
|
|
403b09 |
+ # Establishing trust may throw an exception for topology
|
|
|
403b09 |
+ # conflict. If it was solved, re-establish the trust again
|
|
|
403b09 |
+ # Otherwise let the CLI to display a message about the conflict
|
|
|
403b09 |
+ try:
|
|
|
403b09 |
+ self.remote_domain.establish_trust(self.local_domain,
|
|
|
403b09 |
+ trustdom_pass,
|
|
|
403b09 |
+ trust_type, trust_external)
|
|
|
403b09 |
+ except TrustTopologyConflictSolved as e:
|
|
|
403b09 |
+ # we solved topology conflict, retry again
|
|
|
403b09 |
+ self.remote_domain.establish_trust(self.local_domain,
|
|
|
403b09 |
+ trustdom_pass,
|
|
|
403b09 |
+ trust_type, trust_external)
|
|
|
403b09 |
+
|
|
|
403b09 |
+ # For local domain we don't set topology information
|
|
|
403b09 |
self.local_domain.establish_trust(self.remote_domain,
|
|
|
403b09 |
trustdom_pass,
|
|
|
403b09 |
trust_type, trust_external)
|
|
|
403b09 |
--
|
|
|
403b09 |
2.7.4
|
|
|
403b09 |
|