Modify ↓
Opened 15 years ago
Last modified 6 years ago
#5996 new defect
LdapPlugin should cascade group memberships
Reported by: | Owned by: | Emmanuel Blot | |
---|---|---|---|
Priority: | high | Component: | LdapPlugin |
Severity: | normal | Keywords: | |
Cc: | Trac Release: | 0.11 |
Description
Groups can be defined either through its direct members (which can be users or other groups), or through the memberOf attribute of users or other groups. LdapPlugin should support both methods. Also, LdapPlugin should support indirect membership of a group (where a user is a member of a group that is in its turn member of another group). Where supported matching syntax 0.113556.1.4.1941 should be used.
Typically, the LDAP query could look something like:
(&(objectClass=user)(memberOf:1.2.840.113556.1.4.1941:=CN=groupName))
Attachments (0)
Change History (2)
comment:1 Changed 6 years ago by
comment:2 Changed 6 years ago by
Ok, so turns out my previous patch does not work. Based on the code provided in ticket #7339, I made recursive groups in a more efficient way:
-
0.12/ldapplugin/api.py
diff --git a/0.12/ldapplugin/api.py b/0.12/ldapplugin/api.py index 4d6f6e2..3642517 100644
a b class LdapPermissionGroupProvider(Component): 145 145 del self._cache[username] 146 146 147 147 # Private API 148 149 148 def _get_user_groups(self, username): 150 149 """Returns a list of all groups a user belongs to""" 151 ldap_groups = self._ldap.get_groups()152 150 groups = [] 153 for group in ldap_groups: 154 if self._ldap.is_in_group(self.util.user_attrdn(username), group): 155 m = DN_RE.search(group) 156 if m: 157 groupname = GROUP_PREFIX + m.group('rdn') 158 if groupname not in groups: 159 groups.append(groupname) 160 return groups 151 grouprdns = [] 152 srfilter = "(&(objectclass=%s)(%s=%s))" % (self._ldap.groupname, self._ldap.groupmember, self.util.user_attrdn(username)) 153 srresult = self._ldap.get_dn(self._ldap.basedn, srfilter) 154 if srresult: 155 groups.extend(srresult) 156 for group in srresult: 157 groups = groups + self._get_group_parents(group) 158 159 # Return only the RDN 160 for group in groups: 161 m = DN_RE.search(group) 162 if m: 163 grouprdn = GROUP_PREFIX + m.group('rdn') 164 if grouprdn not in grouprdns: 165 grouprdns.append(grouprdn) 166 return grouprdns 167 168 def _get_group_parents(self, groupdn): 169 parents = [] 170 srfilter = "(&(objectclass=%s)(%s=%s))" % (self._ldap.groupname, self._ldap.groupmember, groupdn) 171 srresult = self._ldap.get_dn(self._ldap.basedn, srfilter) 172 if srresult: 173 parents.extend(srresult) 174 for groupdn in srresult: 175 parents = parents + self._get_group_parents(groupdn) 176 return parents 177
Note: See
TracTickets for help on using
tickets.
Directive 1.2.840.113556.1.4.1941 is only handled by Active Directory and Samba4. OpenLDAP does not support it as of 2019 (Even though I can find requests for this function dating 2002).
I have a quick patch that enables recursive LDAP search. It is not optimized in terms of performance, but it works: