[Freeipa-devel] [PATCH] 885 optimize indirect member calculation

Alexander Bokovoy abokovoy at redhat.com
Thu Oct 6 11:08:30 UTC 2011


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
-------------- next part --------------
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', 'automember',
+                      '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
                 try:
                     (result, truncated) = self.find_entries(searchfilter,
                         attr_list, member, time_limit=time_limit,


More information about the Freeipa-devel mailing list