From 886153da7dd1ca1f5d37dd9c1e2141850b7177b2 Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Tue, 17 Nov 2020 20:37:52 -0500 Subject: [PATCH] Use trust-find and trustdomain-find to identify all AD trusts Not all AD domains are visible to trust-find. For each trust iterate over trustdomain-find to find the complete list of domains. Signed-off-by: Rob Crittenden --- src/ipahealthcheck/ipa/trust.py | 20 +++-- tests/test_ipa_trust.py | 155 ++++++++++++++++++++------------ 2 files changed, 108 insertions(+), 67 deletions(-) diff --git a/src/ipahealthcheck/ipa/trust.py b/src/ipahealthcheck/ipa/trust.py index 0abe5cd..00971c4 100644 --- a/src/ipahealthcheck/ipa/trust.py +++ b/src/ipahealthcheck/ipa/trust.py @@ -42,16 +42,18 @@ def get_trust_domains(): Each entry is a dictionary representating an AD domain. """ - result = api.Command.trust_find() - results = result['result'] trust_domains = [] - for result in results: - if result.get('trusttype')[0] == 'Active Directory domain': - domain = dict() - domain['domain'] = result.get('cn')[0] - domain['domainsid'] = result.get('ipanttrusteddomainsid')[0] - domain['netbios'] = result.get('ipantflatname')[0] - trust_domains.append(domain) + trusts = api.Command.trust_find(pkey_only=True, raw=True) + for trust in trusts['result']: + for cn in trust.get('cn'): + trustdomains = api.Command.trustdomain_find(cn, raw=True) + for trustdomain in trustdomains['result']: + domain = dict() + domain['domain'] = trustdomain.get('cn')[0] + domain['domainsid'] = trustdomain.get( + 'ipanttrusteddomainsid')[0] + domain['netbios'] = trustdomain.get('ipantflatname')[0] + trust_domains.append(domain) return trust_domains diff --git a/tests/test_ipa_trust.py b/tests/test_ipa_trust.py index 3c4b947..f3a9f27 100644 --- a/tests/test_ipa_trust.py +++ b/tests/test_ipa_trust.py @@ -72,6 +72,56 @@ class mock_ldap_conn: return tuple() +# +# Construct a setup with two direct trusts and one sub domain +# +def trust_find(): + return [{ + 'result': [ + { + 'cn': ['ad.example'], + }, + { + 'cn': ['child.example'], + }, + ] + }] + + +def trustdomain_find(): + return [ + { + "result": [ + { + "cn": ["ad.example"], + "ipantflatname": ["ADROOT"], + "ipanttrusteddomainsid": ["S-1-5-21-abc"], + "ipanttrusttype": ["2"], + "ipanttrustattributes": ["8"], + }, + { + "cn": ["child.ad.example"], + "ipantflatname": ["CHILD.ADROOT"], + "ipanttrusteddomainsid": ["S-1-5-22-def"], + "ipanttrusttype": ["2"], + "ipanttrustattributes": ["1"], + }, + ], + }, + { + "result": [ + { + "cn": ["child.example"], + "ipantflatname": ["CHILD"], + "ipanttrusteddomainsid": ["S-1-5-21-ghi"], + "ipanttrusttype": ["2"], + "ipanttrustattributes": ["8"], + }, + ], + }, + ] + + class SSSDDomain: def __init__(self, return_ipa_server_mode=True, provider='ipa'): self.return_ipa_server_mode = return_ipa_server_mode @@ -246,31 +296,17 @@ class TestTrustDomains(BaseTest): dlresult.returncode = 0 dlresult.error_log = '' dlresult.output = 'implicit_files\nipa.example\nad.example\n' \ - 'child.example\n' + 'child.ad.example\nchild.example\n' olresult = namedtuple('run', ['returncode', 'error_log']) olresult.returncode = 0 olresult.error_log = '' olresult.output = 'Online status: Online\n\n' - mock_run.side_effect = [dlresult, olresult, olresult] + mock_run.side_effect = [dlresult, olresult, olresult, olresult] # get_trust_domains() - m_api.Command.trust_find.side_effect = [{ - 'result': [ - { - 'cn': ['ad.example'], - 'ipantflatname': ['ADROOT'], - 'ipanttrusteddomainsid': ['S-1-5-21-abc'], - 'trusttype': ['Active Directory domain'], - }, - { - 'cn': ['child.example'], - 'ipantflatname': ['ADROOT'], - 'ipanttrusteddomainsid': ['S-1-5-21-def'], - 'trusttype': ['Active Directory domain'], - }, - ] - }] + m_api.Command.trust_find.side_effect = trust_find() + m_api.Command.trustdomain_find.side_effect = trustdomain_find() framework = object() registry.initialize(framework, config.Config) @@ -279,15 +315,17 @@ class TestTrustDomains(BaseTest): self.results = capture_results(f) - assert len(self.results) == 3 + assert len(self.results) == 4 result = self.results.results[0] assert result.result == constants.SUCCESS assert result.source == 'ipahealthcheck.ipa.trust' assert result.check == 'IPATrustDomainsCheck' assert result.kw.get('key') == 'domain-list' - assert result.kw.get('trust_domains') == 'ad.example, child.example' - assert result.kw.get('sssd_domains') == 'ad.example, child.example' + assert result.kw.get('trust_domains') == \ + 'ad.example, child.ad.example, child.example' + assert result.kw.get('sssd_domains') == \ + 'ad.example, child.ad.example, child.example' result = self.results.results[1] assert result.result == constants.SUCCESS @@ -301,6 +339,13 @@ class TestTrustDomains(BaseTest): assert result.source == 'ipahealthcheck.ipa.trust' assert result.check == 'IPATrustDomainsCheck' assert result.kw.get('key') == 'domain-status' + assert result.kw.get('domain') == 'child.ad.example' + + result = self.results.results[3] + assert result.result == constants.SUCCESS + assert result.source == 'ipahealthcheck.ipa.trust' + assert result.check == 'IPATrustDomainsCheck' + assert result.kw.get('key') == 'domain-status' assert result.kw.get('domain') == 'child.example' @patch('ipapython.ipautil.run') @@ -319,22 +364,8 @@ class TestTrustDomains(BaseTest): mock_run.side_effect = [dlresult, olresult, olresult] # get_trust_domains() - m_api.Command.trust_find.side_effect = [{ - 'result': [ - { - 'cn': ['ad.example'], - 'ipantflatname': ['ADROOT'], - 'ipanttrusteddomainsid': ['S-1-5-21-abc'], - 'trusttype': ['Active Directory domain'], - }, - { - 'cn': ['child.example'], - 'ipantflatname': ['ADROOT'], - 'ipanttrusteddomainsid': ['S-1-5-21-def'], - 'trusttype': ['Active Directory domain'], - }, - ] - }] + m_api.Command.trust_find.side_effect = trust_find() + m_api.Command.trustdomain_find.side_effect = trustdomain_find() framework = object() registry.initialize(framework, config.Config) @@ -350,7 +381,8 @@ class TestTrustDomains(BaseTest): assert result.source == 'ipahealthcheck.ipa.trust' assert result.check == 'IPATrustDomainsCheck' assert result.kw.get('key') == 'domain-list' - assert result.kw.get('trust_domains') == 'ad.example, child.example' + assert result.kw.get('trust_domains') == \ + 'ad.example, child.ad.example, child.example' assert result.kw.get('sssd_domains') == 'child.example' result = self.results.results[1] @@ -428,29 +460,16 @@ class TestTrustCatalog(BaseTest): ds2result.output = 'Active servers:\nAD Global Catalog: ' \ 'root-dc.ad.vm\nAD Domain Controller: root-dc.ad.vm\n' \ - mock_run.side_effect = [dsresult, ds2result] + mock_run.side_effect = [dsresult, ds2result, ds2result] mock_getnamebysid.side_effect = [ {'S-1-5-21-abc-500': {'name': 'admin@ad.example', 'type': 3}}, + {'S-1-5-21-ghi-500': {'name': 'admin@child.ad.example', 'type': 3}}, {'S-1-5-21-def-500': {'name': 'admin@child.example', 'type': 3}} ] # get_trust_domains() - m_api.Command.trust_find.side_effect = [{ - 'result': [ - { - 'cn': ['ad.example'], - 'ipantflatname': ['ADROOT'], - 'ipanttrusteddomainsid': ['S-1-5-21-abc'], - 'trusttype': ['Active Directory domain'], - }, - { - 'cn': ['child.example'], - 'ipantflatname': ['ADROOT'], - 'ipanttrusteddomainsid': ['S-1-5-21-def'], - 'trusttype': ['Active Directory domain'], - }, - ] - }] + m_api.Command.trust_find.side_effect = trust_find() + m_api.Command.trustdomain_find.side_effect = trustdomain_find() framework = object() registry.initialize(framework, config.Config) @@ -459,7 +478,7 @@ class TestTrustCatalog(BaseTest): self.results = capture_results(f) - assert len(self.results) == 6 + assert len(self.results) == 9 result = self.results.results[0] assert result.result == constants.SUCCESS @@ -487,20 +506,40 @@ class TestTrustCatalog(BaseTest): assert result.source == 'ipahealthcheck.ipa.trust' assert result.check == 'IPATrustCatalogCheck' assert result.kw.get('key') == 'Domain Security Identifier' - assert result.kw.get('sid') == 'S-1-5-21-def' + assert result.kw.get('sid') == 'S-1-5-22-def' result = self.results.results[4] assert result.result == constants.SUCCESS assert result.source == 'ipahealthcheck.ipa.trust' assert result.check == 'IPATrustCatalogCheck' assert result.kw.get('key') == 'AD Global Catalog' - assert result.kw.get('domain') == 'child.example' + assert result.kw.get('domain') == 'child.ad.example' result = self.results.results[5] assert result.result == constants.SUCCESS assert result.source == 'ipahealthcheck.ipa.trust' assert result.check == 'IPATrustCatalogCheck' assert result.kw.get('key') == 'AD Domain Controller' + + result = self.results.results[6] + assert result.result == constants.SUCCESS + assert result.source == 'ipahealthcheck.ipa.trust' + assert result.check == 'IPATrustCatalogCheck' + assert result.kw.get('key') == 'Domain Security Identifier' + assert result.kw.get('sid') == 'S-1-5-21-ghi' + + result = self.results.results[7] + assert result.result == constants.SUCCESS + assert result.source == 'ipahealthcheck.ipa.trust' + assert result.check == 'IPATrustCatalogCheck' + assert result.kw.get('key') == 'AD Global Catalog' + assert result.kw.get('domain') == 'child.example' + + result = self.results.results[8] + assert result.result == constants.SUCCESS + assert result.source == 'ipahealthcheck.ipa.trust' + assert result.check == 'IPATrustCatalogCheck' + assert result.kw.get('key') == 'AD Domain Controller' assert result.kw.get('domain') == 'child.example' -- 2.25.4