Hi,

attached patch implements missing idranges when new child domains
discovered through 'ipa trust-fetch-domains'. This functionality existed
in 'ipa trust-add' but was not exposed in the 'ipa trust-fetch-domains'.

Additionally, error message is shown in case trust name is incorrect.

https://fedorahosted.org/freeipa/ticket/4104
https://fedorahosted.org/freeipa/ticket/4111
--
/ Alexander Bokovoy
>From 4c5cc55deb4e346169ead3ebaac52e847adde424 Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <[email protected]>
Date: Tue, 14 Jan 2014 13:55:56 +0200
Subject: [PATCH] trust-fetch-domains: create ranges for new child domains

When trust is added, we do create ranges for discovered child domains.
However, this functionality was not available through
'trust-fetch-domains' command.

Additionally, make sure non-existing trust will report proper error in
trust-fetch-domains.

https://fedorahosted.org/freeipa/ticket/4111
https://fedorahosted.org/freeipa/ticket/4104
---
 ipalib/plugins/trust.py | 246 ++++++++++++++++++++++++++----------------------
 1 file changed, 134 insertions(+), 112 deletions(-)

diff --git a/ipalib/plugins/trust.py b/ipalib/plugins/trust.py
index 76d609f..6466f28 100644
--- a/ipalib/plugins/trust.py
+++ b/ipalib/plugins/trust.py
@@ -188,6 +188,114 @@ def make_trust_dn(env, trust_type, dn):
         return DN(dn, container_dn)
     return dn
 
+def add_range(self, range_name, dom_sid, *keys, **options):
+    """
+    First, we try to derive the parameters of the ID range based on the
+    information contained in the Active Directory.
+
+    If that was not successful, we go for our usual defaults (random base,
+    range size 200 000, ipa-ad-trust range type).
+
+    Any of these can be overriden by passing appropriate CLI options
+    to the trust-add command.
+    """
+
+    range_size = None
+    range_type = None
+    base_id = None
+
+    # First, get information about ID space from AD
+    # However, we skip this step if other than ipa-ad-trust-posix
+    # range type is enforced
+
+    if options.get('range_type', None) in (None, u'ipa-ad-trust-posix'):
+
+        # Get the base dn
+        domain = keys[-1]
+        basedn = realm_to_suffix(domain)
+
+        # Search for information contained in
+        # CN=ypservers,CN=ypServ30,CN=RpcServices,CN=System
+        info_filter = '(objectClass=msSFU30DomainInfo)'
+        info_dn = DN('CN=ypservers,CN=ypServ30,CN=RpcServices,CN=System')\
+                  + basedn
+
+        # Get the domain validator
+        domain_validator = ipaserver.dcerpc.DomainValidator(self.api)
+        if not domain_validator.is_configured():
+            raise errors.NotFound(
+                reason=_('Cannot search in trusted domains without own '
+                         'domain configured. Make sure you have run '
+                         'ipa-adtrust-install on the IPA server first'))
+
+        # KDC might not get refreshed data at the first time,
+        # retry several times
+        for retry in range(10):
+            info_list = domain_validator.search_in_dc(domain,
+                                                      info_filter,
+                                                      None,
+                                                      SCOPE_SUBTREE,
+                                                      basedn=info_dn,
+                                                      quiet=True)
+
+            if info_list:
+                info = info_list[0]
+                break
+            else:
+                sleep(2)
+
+        required_msSFU_attrs = ['msSFU30MaxUidNumber', 'msSFU30OrderNumber']
+
+        if not info_list:
+            # We were unable to gain UNIX specific info from the AD
+            self.log.debug("Unable to gain POSIX info from the AD")
+        else:
+            if all(attr in info for attr in required_msSFU_attrs):
+                self.log.debug("Able to gain POSIX info from the AD")
+                range_type = u'ipa-ad-trust-posix'
+
+                max_uid = info.get('msSFU30MaxUidNumber')
+                max_gid = info.get('msSFU30MaxGidNumber', None)
+                max_id = int(max(max_uid, max_gid)[0])
+
+                base_id = int(info.get('msSFU30OrderNumber')[0])
+                range_size = (1 + (max_id - base_id) / DEFAULT_RANGE_SIZE)\
+                             * DEFAULT_RANGE_SIZE
+
+    # Second, options given via the CLI options take precedence to discovery
+    if options.get('range_type', None):
+        range_type = options.get('range_type', None)
+    elif not range_type:
+        range_type = u'ipa-ad-trust'
+
+    if options.get('range_size', None):
+        range_size = options.get('range_size', None)
+    elif not range_size:
+        range_size = DEFAULT_RANGE_SIZE
+
+    if options.get('base_id', None):
+        base_id = options.get('base_id', None)
+    elif not base_id:
+        # Generate random base_id if not discovered nor given via CLI
+        base_id = DEFAULT_RANGE_SIZE + (
+            pysss_murmur.murmurhash3(
+                dom_sid,
+                len(dom_sid), 0xdeadbeefL
+            ) % 10000
+        ) * DEFAULT_RANGE_SIZE
+
+    # Finally, add new ID range
+    self.api.Command['idrange_add'](range_name,
+                                    ipabaseid=base_id,
+                                    ipaidrangesize=range_size,
+                                    ipabaserid=0,
+                                    iparangetype=range_type,
+                                    ipanttrusteddomainsid=dom_sid)
+
+    # Return the values that were generated inside this function
+    return range_type, range_size, base_id
+
+
 class trust(LDAPObject):
     """
     Trust object.
@@ -341,8 +449,8 @@ sides.
             # Store the created range type, since for POSIX trusts no
             # ranges for the subdomains should be added, POSIX attributes
             # provide a global mapping across all subdomains
-            (created_range_type, _, _) = self.add_range(range_name, dom_sid,
-                                                        *keys, **options)
+            (created_range_type, _, _) = add_range(self, range_name, dom_sid,
+                                                   *keys, **options)
         else:
             created_range_type = old_range['result']['iparangetype'][0]
 
@@ -382,8 +490,8 @@ sides.
 
                     # Try to add the range for each subdomain
                     try:
-                        self.add_range(range_name, dom_sid, *keys,
-                                       **passed_options)
+                        add_range(self, range_name, dom_sid, *keys,
+                                  **passed_options)
                     except errors.DuplicateEntry:
                         pass
 
@@ -549,113 +657,6 @@ sides.
 
         return old_range, range_name, dom_sid
 
-    def add_range(self, range_name, dom_sid, *keys, **options):
-        """
-        First, we try to derive the parameters of the ID range based on the
-        information contained in the Active Directory.
-
-        If that was not successful, we go for our usual defaults (random base,
-        range size 200 000, ipa-ad-trust range type).
-
-        Any of these can be overriden by passing appropriate CLI options
-        to the trust-add command.
-        """
-
-        range_size = None
-        range_type = None
-        base_id = None
-
-        # First, get information about ID space from AD
-        # However, we skip this step if other than ipa-ad-trust-posix
-        # range type is enforced
-
-        if options.get('range_type', None) in (None, u'ipa-ad-trust-posix'):
-
-            # Get the base dn
-            domain = keys[-1]
-            basedn = realm_to_suffix(domain)
-
-            # Search for information contained in
-            # CN=ypservers,CN=ypServ30,CN=RpcServices,CN=System
-            info_filter = '(objectClass=msSFU30DomainInfo)'
-            info_dn = DN('CN=ypservers,CN=ypServ30,CN=RpcServices,CN=System')\
-                      + basedn
-
-            # Get the domain validator
-            domain_validator = ipaserver.dcerpc.DomainValidator(self.api)
-            if not domain_validator.is_configured():
-                raise errors.NotFound(
-                    reason=_('Cannot search in trusted domains without own '
-                             'domain configured. Make sure you have run '
-                             'ipa-adtrust-install on the IPA server first'))
-
-            # KDC might not get refreshed data at the first time,
-            # retry several times
-            for retry in range(10):
-                info_list = domain_validator.search_in_dc(domain,
-                                                          info_filter,
-                                                          None,
-                                                          SCOPE_SUBTREE,
-                                                          basedn=info_dn,
-                                                          quiet=True)
-
-                if info_list:
-                    info = info_list[0]
-                    break
-                else:
-                    sleep(2)
-
-            required_msSFU_attrs = ['msSFU30MaxUidNumber', 
'msSFU30OrderNumber']
-
-            if not info_list:
-                # We were unable to gain UNIX specific info from the AD
-                self.log.debug("Unable to gain POSIX info from the AD")
-            else:
-                if all(attr in info for attr in required_msSFU_attrs):
-                    self.log.debug("Able to gain POSIX info from the AD")
-                    range_type = u'ipa-ad-trust-posix'
-
-                    max_uid = info.get('msSFU30MaxUidNumber')
-                    max_gid = info.get('msSFU30MaxGidNumber', None)
-                    max_id = int(max(max_uid, max_gid)[0])
-
-                    base_id = int(info.get('msSFU30OrderNumber')[0])
-                    range_size = (1 + (max_id - base_id) / DEFAULT_RANGE_SIZE)\
-                                 * DEFAULT_RANGE_SIZE
-
-        # Second, options given via the CLI options take precedence to 
discovery
-        if options.get('range_type', None):
-            range_type = options.get('range_type', None)
-        elif not range_type:
-            range_type = u'ipa-ad-trust'
-
-        if options.get('range_size', None):
-            range_size = options.get('range_size', None)
-        elif not range_size:
-            range_size = DEFAULT_RANGE_SIZE
-
-        if options.get('base_id', None):
-            base_id = options.get('base_id', None)
-        elif not base_id:
-            # Generate random base_id if not discovered nor given via CLI
-            base_id = DEFAULT_RANGE_SIZE + (
-                pysss_murmur.murmurhash3(
-                    dom_sid,
-                    len(dom_sid), 0xdeadbeefL
-                ) % 10000
-            ) * DEFAULT_RANGE_SIZE
-
-        # Finally, add new ID range
-        api.Command['idrange_add'](range_name,
-                                   ipabaseid=base_id,
-                                   ipaidrangesize=range_size,
-                                   ipabaserid=0,
-                                   iparangetype=range_type,
-                                   ipanttrusteddomainsid=dom_sid)
-
-        # Return the values that were generated inside this function
-        return range_type, range_size, base_id
-
     def execute_ad(self, full_join, *keys, **options):
         # Join domain using full credentials and with random trustdom
         # secret (will be generated by the join method)
@@ -1246,6 +1247,11 @@ def fetch_domains_from_trust(self, trustinstance, 
trust_entry, **options):
     if not domains:
         return result
 
+    # trust range must exist by the time fetch_domains_from_trust is called
+    range_name = trust_name.upper() + '_id_range'
+    old_range = api.Command.idrange_show(range_name, raw=True)['result']
+    idrange_type = old_range['iparangetype']
+
     for dom in domains:
         dom['trust_type'] = u'ad'
         try:
@@ -1255,8 +1261,15 @@ def fetch_domains_from_trust(self, trustinstance, 
trust_entry, **options):
                 dom['all'] = options['all']
             if 'raw' in options:
                 dom['raw'] = options['raw']
+
             res = self.api.Command.trustdomain_add(trust_name, name, **dom)
             result.append(res['result'])
+
+            if idrange_type != u'ipa-ad-trust-posix':
+                range_name = name.upper() + '_id_range'
+                dom['range_type'] = u'ipa-ad-trust'
+                add_range(self, range_name, dom['ipanttrusteddomainsid'],
+                          trust_name, name, **dom)
         except errors.DuplicateEntry:
             # Ignore updating duplicate entries
             pass
@@ -1277,7 +1290,16 @@ class trust_fetch_domains(LDAPRetrieve):
                     'sub-package of IPA'
                 )
             )
-        trust = self.api.Command.trust_show(keys[0], raw=True)['result']
+        try:
+            trust = self.api.Command.trust_show(keys[0], raw=True)['result']
+        except AssertionError:
+            raise errors.NotFound(
+                name=_('AD Trust setup'),
+                reason=_(
+                    'Cannot refresh list of the trusted forest domains '
+                    'because there is no trust to the forest with this name'
+                )
+            )
 
         trustinstance = ipaserver.dcerpc.TrustDomainJoins(self.api)
         if not trustinstance.configured:
-- 
1.8.4.2

_______________________________________________
Freeipa-devel mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/freeipa-devel

Reply via email to