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

  1. 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
    
  2. Attempt to log in, randomly, user wont be logged in and traceback is thrown to apache's error logs.

Example

Component selection

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

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...

Plan


CategoryMoinMoinBugFixed

MoinMoin: MoinMoinBugs/LdapTlsNoCertificate (last edited 2009-04-13 12:33:24 by ThomasWaldmann)