On Wed, 05 Oct 2011, Rob Crittenden wrote:
> When calculating indirect membership of a group all members are
> examined and if those have members, those are added as well. This
> does not need to be done when the member in question is a user or a
> host as they cannot have members.
> For large groups this is a significant performance improvement (as
> well as reducing unnecessary load on 389-ds).
Works for me. However, shouldn't we expand this to all terminal 
objects rather than users and hosts?

Something like attached patch? The containers list should be sorted by 
probability of encountering the container in real life, with users and 
hosts to be at the beginning.
/ Alexander Bokovoy
diff --git a/ipaserver/plugins/ldap2.py b/ipaserver/plugins/ldap2.py
index b12403b..f9d1d14 100644
--- a/ipaserver/plugins/ldap2.py
+++ b/ipaserver/plugins/ldap2.py
@@ -42,6 +42,7 @@ import ldap.sasl as _ldap_sasl
 from ldap.controls import LDAPControl
 # for backward compatibility
 from ldap.functions import explode_dn
+from ipalib.dn import DN
 import krbV
@@ -960,6 +961,26 @@ class ldap2(CrudBackend, Encoder):
         # update group entry
         self.update_entry(group_dn, group_entry_attrs)
+    def is_terminal(self, dn):
+        """Check if the DN cannot have nested members
+           Returns True if DN corresponds to terminal element, False otherwise
+        """
+        containers = ('user', 'host', 'hbac', 'hbacservice', 'automount', 
+                      'service', 'sudocmd', 'sudorule')
+        for container in containers:
+            key = "container_%s" % (container)
+            try:
+                if dn.endswith(DN(api.env[key], api.env.basedn)):
+                    return True
+            except KeyError:
+                # Protect against cases when the plugin for the container is
+                # not loaded and accessing container dn causes an exception.
+                # Simply skip such containers.
+                pass
+        return False
     def get_members(self, group_dn, members, attr_list=[], 
membertype=MEMBERS_ALL, time_limit=None, size_limit=None, normalize=True):
         """Do a memberOf search of groupdn and return the attributes in
            attr_list (an empty list returns all attributes).
@@ -987,6 +1008,11 @@ class ldap2(CrudBackend, Encoder):
         if membertype == MEMBERS_ALL or membertype == MEMBERS_INDIRECT:
             checkmembers = copy.deepcopy(members)
             for member in checkmembers:
+                # No need to check entry types that are not nested for
+                # additional members
+                if self.is_terminal(DN(member)):
+                    results.append([member, {}])
+                    continue
                     (result, truncated) = self.find_entries(searchfilter,
                         attr_list, member, time_limit=time_limit,
Freeipa-devel mailing list

Reply via email to