[Twisted-Python] LDAP binds appears to succeed with no password

Peter Westlake peter.westlake at pobox.com
Fri Jul 30 06:54:27 EDT 2010


I'm using LDAP to authenticate users, and when I give it an empty
password, it appears to succeed! Can anyone see what I'm doing wrong?
I've added comments by the log messages that appear in the output.

Peter.

from twisted.internet import reactor, defer
from ldaptor.protocols.ldap import ldapclient, ldapsyntax,
ldapconnector, ldaperrors
from ldaptor.protocols import pureldap as L

import log

class LDAPAuthenticationSource(object):
    def __init__(self, base_dn, hostname=None, attr='uid', bind_dn='',
                 bind_pw='', filter=L.LDAPFilter_present('cn')):
        self.hostname = hostname
        self.base_dn = base_dn
        self.attr = attr
        self.bind_dn = bind_dn
        self.bind_pw = bind_pw
        self.filter = filter
        self.cli = None

    @defer.inlineCallbacks
    def authenticate(self, username, password):
        if not password:
            log.info('Empty password!!!!')                  #######
            appears
        else:
            log.debug('Attempting to login as', username)

        c = ldapconnector.LDAPClientCreator(reactor,
        ldapclient.LDAPClient)
        self.client = yield c.connect(self.base_dn)

        yield ldapsyntax.LDAPEntry(self.client,
        self.bind_dn).bind(self.bind_pw)

        entries = []
        base = ldapsyntax.LDAPEntry(self.client, self.base_dn)

        yield base.search(
            filterObject=L.LDAPFilter_and(
                [L.LDAPFilter_equalityMatch(
                        attributeDesc=L.LDAPAttributeDescription(self.attr),
                        assertionValue=L.LDAPAssertionValue(username)
                    ),
                 self.filter,
                 ]),
            attributes = (self.attr,),  # No need to read the whole
            entry!
            callback=entries.append
        )
        n_entries = len(entries)
        if n_entries == 0:
            self.client.unbind()
            log.debug('Failed login for %s: no search results' %
            (username,))
            raise Exception('No search results!')
        elif n_entries > 1:
            self.client.unbind()
            log.debug('Failed login as %s: %d search results for unique
            entry!' % (username, n_entries))
            raise Exception('%d search results for unique entry!' %
            n_entries)
        else:
            # The password matches if we can bind as this DN with it.
            try:
                if not password:
                    log.info('Empty password')                          
                      ##### appears
                user_entry = yield entries[0].bind(password)
                if not password:
                    log.info('Succeeded with an empty password!')       
                      ##### appears
                    log.info('user_entry:')                             
                      ##### appears
                    log.info(user_entry)                                
                      ##### appears
                log.info('Login:', username)
            except ldaperrors.LDAPInvalidCredentials:
                log.info('Failed login for %s: invalid credentials' %
                username)
                raise
            except Exception, e:
                log.rep(e, 'Error while binding with user password')
                self.client.unbind()
                raise
            self.client.unbind()
            defer.returnValue(user_entry)



More information about the Twisted-Python mailing list