22 | | |
23 | | |
24 | | |
25 | | Replying to [comment:2 Jun Omae]: |
26 | | > I think that it should add an option to specify LDAP field to match the username and authenticate rather than a part of LDAP filter. |
27 | | > |
28 | | > Also, the username to use in LDAP filter should be escaped using [http://www.python-ldap.org/en/latest/reference/ldap-filter.html#ldap.filter.filter_format ldap.filter.filter_format()]. |
29 | | > |
30 | | > Untested patch: |
31 | | > |
32 | | > {{{#!diff |
33 | | > y/ldapstore.py |
34 | | > index 2ee361972..6d119eac3 100644 |
35 | | > --- a/ldapacctmngrplugin/trunk/ldapacctmngrplugin/security/ldapstore.py |
36 | | > +++ b/ldapacctmngrplugin/trunk/ldapacctmngrplugin/security/ldapstore.py |
37 | | > @@ -11,7 +11,8 @@ class LDAPStore (Component): |
38 | | > bind_passwd = Option('ldap', 'bind_passwd', '', doc='For server not accepting anonymous bind, specify a bind_dn and password.') |
39 | | > user_searchbase = Option('ldap', 'user_searchbase', 'dc=company,dc=com', doc='Where to look for users. It is usually "dc=your_company_name,dc=com". Please consult the structure of your LDAP tree.') |
40 | | > user_searchfilter = Option('ldap', 'user_searchfilter', 'objectClass=inetOrgPerson', doc='Filter for listing valid users. The default ("objectClass=inetOrgPerson") should work for most of the cases.') |
41 | | > - user_matchfilter = Option('ldap', 'user_matchfilter', 'uid=%s', doc='The LDAP field for matching username when authenticating. The query is almost always "uid=%s".') |
42 | | > + user_field = Option('ldap', 'user_field', 'uid', |
43 | | > + doc="""The LDAP field to match the username and authenticate.""") |
44 | | > |
45 | | > implements(IPasswordStore) |
46 | | > |
47 | | > @@ -19,13 +20,14 @@ class LDAPStore (Component): |
48 | | > # Authenticate a user by checking password |
49 | | > con = None |
50 | | > base = self.user_searchbase |
51 | | > - filter = self.user_matchfilter % user |
52 | | > + user_field = self.user_field |
53 | | > + filter_ = ldap.filter.filter_format('%s=%s', [user_field, user]) |
54 | | > |
55 | | > # nested "try:" for python2.4 |
56 | | > try: |
57 | | > try: |
58 | | > con = self.init_connection() |
59 | | > - resp = con.search_s(base, ldap.SCOPE_SUBTREE, filter, ['dn']) |
60 | | > + resp = con.search_s(base, ldap.SCOPE_SUBTREE, filter_, ['dn']) |
61 | | > |
62 | | > # Added to prevent empty password authentication (some server allows that) |
63 | | > if not len(resp) : |
64 | | > @@ -44,20 +46,23 @@ class LDAPStore (Component): |
65 | | > # Get list of users from LDAP server |
66 | | > con = None |
67 | | > base = self.user_searchbase |
68 | | > + user_field = self.user_field |
69 | | > filter = self.user_searchfilter |
70 | | > resp = None |
71 | | > |
72 | | > try: |
73 | | > con = self.init_connection() |
74 | | > - resp = con.search_s(base, ldap.SCOPE_SUBTREE, filter, ['dn','uid']) |
75 | | > + resp = con.search_s(base, ldap.SCOPE_SUBTREE, filter, |
76 | | > + ['dn', user_field]) |
77 | | > finally: |
78 | | > if con != None: |
79 | | > con.unbind() |
80 | | > |
81 | | > self.log.debug('List users: get %d users' % (len(resp))) |
82 | | > for entry in resp: |
83 | | > - if entry[1]['uid'][0]: |
84 | | > - yield entry[1]['uid'][0] |
85 | | > + value = entry[1][user_field][0] |
86 | | > + if value: |
87 | | > + yield value |
88 | | > |
89 | | > def init_connection(self): |
90 | | > # Initialize LDAP connection |
91 | | > }}} |