Description
When Moin is set to use ldap with start_tls, the class LDAPAuth (auth/ldap_login.py) randomly fails to log user in.
Steps to reproduce
- configure farmconfig as follow (basically, start_tls and no certificates/keys):
1 from MoinMoin.auth.ldap_login import LDAPAuth 2 ldap_authenticator1 = LDAPAuth( 3 # the values shown below are the DEFAULT values (you may remove them if you are happy with them), 4 # the examples shown in the comments are typical for Active Directory (AD) or OpenLDAP. 5 server_uri='ldap://myldapserver', # ldap / active directory server URI 6 # use ldaps://server:636 url for ldaps, 7 # use ldap://server for ldap without tls (and set start_tls to 0), 8 # use ldap://server for ldap with tls (and set start_tls to 1 or 2). 9 bind_dn='', # We can either use some fixed user and password for binding to LDAP. 10 # Be careful if you need a % char in those strings - as they are used as 11 # a format string, you have to write %% to get a single % in the end. 12 #bind_dn = 'binduser@example.org' # (AD) 13 #bind_dn = 'cn=admin,dc=example,dc=org' # (OpenLDAP) 14 #bind_pw = 'secret' 15 # or we can use the username and password we got from the user: 16 #bind_dn = '%(username)s@example.org' # DN we use for first bind (AD) 17 #bind_pw = '%(password)s' # password we use for first bind 18 # or we can bind anonymously (if that is supported by your directory). 19 # In any case, bind_dn and bind_pw must be defined. 20 bind_pw='', 21 base_dn='dc=domain,dc=com', # base DN we use for searching 22 #base_dn = 'ou=SOMEUNIT,dc=example,dc=org' 23 scope=2, # scope of the search we do (2 == ldap.SCOPE_SUBTREE) 24 referrals=0, # LDAP REFERRALS (0 needed for AD) 25 search_filter='(uid=%(username)s)', # ldap filter used for searching: 26 #search_filter = '(sAMAccountName=%(username)s)' # (AD) 27 #search_filter = '(uid=%(username)s)' # (OpenLDAP) 28 # you can also do more complex filtering like: 29 # "(&(cn=%(username)s)(memberOf=CN=WikiUsers,OU=Groups,DC=example,DC=org))" 30 # some attribute names we use to extract information from LDAP (if not None, 31 # if None, the attribute won't be extracted from LDAP): 32 givenname_attribute='givenName', # often 'givenName' - ldap attribute we get the first name from 33 surname_attribute='sn', # often 'sn' - ldap attribute we get the family name from 34 aliasname_attribute=None, # often 'displayName' - ldap attribute we get the aliasname from 35 email_attribute='mail', # often 'mail' - ldap attribute we get the email address from 36 email_callback=None, # callback function called to make up email address 37 coding='utf-8', # coding used for ldap queries and result values 38 timeout=10, # how long we wait for the ldap server [s] 39 start_tls=2, # usage of Transport Layer Security 0 = No, 1 = Try, 2 = Required 40 tls_cacertdir='', 41 tls_cacertfile='', 42 tls_certfile='', 43 tls_keyfile='', 44 tls_require_cert=0, # 0 == ldap.OPT_X_TLS_NEVER (needed for self-signed certs) 45 bind_once=False, # set to True to only do one bind - useful if configured to bind as the user on the first attempt 46 autocreate=True, # set to True to automatically create/update user profiles 47 ) 48 49 auth = [ldap_authenticator1, ] # this is a list, you may have multiple ldap authenticators 50 # as well as other authenticators
- Attempt to log in, randomly, user wont be logged in and traceback is thrown to apache's error logs.
Example
Component selection
- auth
Details
Traceback in apache error logs:
2009-04-01 16:10:15,425 WARNING MoinMoin.log:1072 using logging configuration read from built-in fallback in MoinMoin.log module! 2009-04-01 16:10:15,531 INFO MoinMoin.config.multiconfig:1072 using farm config: /etc/moin/farmconfig.py 2009-04-01 16:10:15,537 INFO MoinMoin.config.multiconfig:1072 using wiki config: /etc/moin/mywiki.py 2009-04-01 16:10:15,707 WARNING MoinMoin.auth.ldap_login:1072 Couldn't establish TLS to 'ldap://myldapserver' (err: {'info': '', 'desc': 'Connect error'}). 2009-04-01 16:10:15,707 ERROR MoinMoin.auth.ldap_login:1072 caught an exception, traceback follows... Traceback (most recent call last): File "/var/lib/python-support/python2.4/MoinMoin/auth/ldap_login.py", line 155, in login l.start_tls_s() File "/usr/lib/python2.4/site-packages/ldap/ldapobject.py", line 505, in start_tls_s return self._ldap_call(self._l.start_tls_s) File "/usr/lib/python2.4/site-packages/ldap/ldapobject.py", line 94, in _ldap_call result = func(*args,**kwargs) CONNECT_ERROR: {'info': '', 'desc': 'Connect error'}
MoinMoin Version |
1.8.0 |
OS and Version |
Debian Etch |
Python Version |
2.4.4 |
Python Ldap Version |
2.2.0 |
Server Setup |
|
Server Details |
|
Language you are using the wiki in (set in the browser/UserPreferences) |
|
LDAP server |
openldap 2.4.11 on Debian Lenny |
Workaround
Until issue is fixed, one can change the default value of:
tls_cacertdir='', tls_cacertfile='', tls_certfile='', tls_keyfile='',
to
tls_cacertdir=None, tls_cacertfile=None, tls_certfile=None, tls_keyfile=None,
Discussion
Issue is due to the fact that empty certificates filenames are set. This can be fixed by the following patch: LdapTlsNoCertificate.diff
Can you please just test with the workaround? Using None to prevent setting the file/dirnames seems cleaner than dealing with the empty strings.
The workaround was already tested by myself . I am using it myself. The idea behind changing the e=handling of empty string is to make earlier version of Class LDAPAuth will work properly, but to be honest, I am happy with just changing LDAPAuth template.
Still, LDAPAuth default parameters values have to be changed to None...
- Thomas, please also modify wiki/config/more_samples/ldap_wikiconfig_snippet as it is the file that I actually used to set up my LDAP config, guess other people will also use it as a default template.
- Fixed. Thanks for the hint.
Plan
- Priority:
- Assigned to:
- Status: applied =None fix in moin 1.7, 1.8 and 1.9 repos, also fixed the sample configs