From 521a28fd446a64c4fa5895e1aa768512249652f6 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Tue, 17 Mar 2015 20:22:25 -0400 Subject: Fix fetching infoldap plugin groups Signed-off-by: Simo Sorce Reviewed-by: Patrick Uiterwijk --- ipsilon/info/infoldap.py | 36 +++++++++++++++++++++++++++++------- ipsilon/login/authldap.py | 16 +++++++++++++++- 2 files changed, 44 insertions(+), 8 deletions(-) diff --git a/ipsilon/info/infoldap.py b/ipsilon/info/infoldap.py index 3edd0dd..e56a6a0 100644 --- a/ipsilon/info/infoldap.py +++ b/ipsilon/info/infoldap.py @@ -56,6 +56,10 @@ Info plugin that uses LDAP to retrieve user data. """ pconfig.String( 'bind password', 'Password to use for bind operation'), + pconfig.String( + 'base dn', + 'The base dn to look for users and groups', + 'dc=example,dc=com'), ) @property @@ -78,6 +82,10 @@ Info plugin that uses LDAP to retrieve user data. """ def user_dn_tmpl(self): return self.get_config_value('user dn template') + @property + def base_dn(self): + return self.get_config_value('base dn') + def _ldap_bind(self): tls = self.tls.lower() @@ -116,19 +124,26 @@ Info plugin that uses LDAP to retrieve user data. """ data[name] = value return data - def _get_user_groups(self, conn, dn, ldapattrs): + def _get_user_groups(self, conn, base, username): # TODO: fixme to support RFC2307bis schemas - if 'memberuid' in ldapattrs: - return ldapattrs['memberuid'] - else: + results = conn.search_s(base, ldap.SCOPE_SUBTREE, + filterstr='memberuid=%s' % username) + if results is None or results == []: + self.debug('No groups for %s' % username) return [] + groups = [] + for r in results: + if 'cn' in r[1]: + groups.append(r[1]['cn'][0]) + return groups - def get_user_data_from_conn(self, conn, dn): + def get_user_data_from_conn(self, conn, dn, base, username): reply = dict() try: ldapattrs = self._get_user_data(conn, dn) + self.debug(ldapattrs) userattrs, extras = self.mapper.map_attributes(ldapattrs) - groups = self._get_user_groups(conn, dn, ldapattrs) + groups = self._get_user_groups(conn, base, username) reply = userattrs reply['_groups'] = groups reply['_extras'] = {'ldap': extras} @@ -141,7 +156,8 @@ Info plugin that uses LDAP to retrieve user data. """ try: conn = self._ldap_bind() dn = self.user_dn_tmpl % {'username': user} - return self.get_user_data_from_conn(conn, dn) + base = self.base_dn + return self.get_user_data_from_conn(conn, dn, base, user) except Exception, e: # pylint: disable=broad-except self.error(e) return {} @@ -165,6 +181,8 @@ class Installer(InfoProviderInstaller): help='LDAP Bind Password') group.add_argument('--info-ldap-user-dn-template', action='store', help='LDAP User DN Template') + group.add_argument('--info-ldap-base-dn', action='store', + help='LDAP Base DN') def configure(self, opts): if opts['info_ldap'] != 'yes': @@ -192,6 +210,10 @@ class Installer(InfoProviderInstaller): elif 'ldap_bind_dn_template' in opts: config['user dn template'] = opts['ldap_bind_dn_template'] config['tls'] = 'Demand' + if 'info_ldap_base_dn' in opts and opts['info_ldap_base_dn']: + config['base dn'] = opts['info_ldap_base_dn'] + elif 'ldap_base_dn' in opts and opts['ldap_base_dn']: + config['base dn'] = opts['ldap_base_dn'] po.save_plugin_config(config) # Update global config to add info plugin diff --git a/ipsilon/login/authldap.py b/ipsilon/login/authldap.py index 1f6c3dc..db58360 100644 --- a/ipsilon/login/authldap.py +++ b/ipsilon/login/authldap.py @@ -51,7 +51,9 @@ class LDAP(LoginFormBase, Log): if not self.ldap_info: self.ldap_info = LDAPInfo(self._site) - return self.ldap_info.get_user_data_from_conn(conn, dn) + base = self.lm.base_dn + return self.ldap_info.get_user_data_from_conn(conn, dn, base, + username) return None @@ -110,6 +112,10 @@ authentication. """ 'bind dn template', 'Template to turn username into DN.', 'uid=%(username)s,ou=People,dc=example,dc=com'), + pconfig.String( + 'base dn', + 'The base dn to look for users and groups', + 'dc=example,dc=com'), pconfig.Condition( 'get user info', 'Get user info via ldap using user credentials', @@ -161,6 +167,10 @@ authentication. """ def bind_dn_tmpl(self): return self.get_config_value('bind dn template') + @property + def base_dn(self): + return self.get_config_value('base dn') + def get_tree(self, site): self.page = LDAP(site, self, 'login/ldap') return self.page @@ -180,6 +190,8 @@ class Installer(LoginManagerInstaller): help='LDAP Server Url') group.add_argument('--ldap-bind-dn-template', action='store', help='LDAP Bind DN Template') + group.add_argument('--ldap-base-dn', action='store', + help='LDAP Base DN') def configure(self, opts): if opts['ldap'] != 'yes': @@ -197,6 +209,8 @@ class Installer(LoginManagerInstaller): if 'ldap_bind_dn_template' in opts: config['bind dn template'] = opts['ldap_bind_dn_template'] config['tls'] = 'Demand' + if 'ldap_base_dn' in opts and opts['ldap_base_dn'] is not None: + config['base dn'] = opts['ldap_base_dn'] po.save_plugin_config(config) # Update global config to add login plugin -- cgit