Python-ldap not able to bind successfully

Based on what @Cas said above, I only had to add:

connection.set_option(ldap.OPT_REFERRALS,0)

It looks like this is such a common problem that it was added to the python-ldap FAQ:

Q: My script bound to MS Active Directory but a a search operation results in an exception ldap.OPERATIONS_ERROR with the diagnostic messages text "In order to perform this operation a successful bind must be completed on the connection.". What's happening here?

A: When searching from the domain level MS AD returns referrals (search continuations) for some objects to indicate to the client where to look for these objects. Client-chasing of referrals is a broken concept since LDAPv3 does not specify which credentials to use when chasing the referral. Windows clients are supposed to simply use their Windows credentials but this does not work in general when chasing referrals received from and pointing to arbitrary LDAP servers. Therefore per default libldap automatically chases the referrals internally with an anonymous access which fails with MS AD. So best thing is to switch this behaviour off:

l = ldap.initialize('ldap://foobar')

l.set_option(ldap.OPT_REFERRALS,0)


Try:

import ldap

connect = ldap.initialize("ldap://example.com")
connect.set_option(ldap.OPT_REFERRALS, 0)
try:
    connect.simple_bind_s(login, password)
    connect.search_s("dc=example,dc=com",
                     ldap.SCOPE_SUBTREE,
                     'userPrincipalName={}'.format(login),
                     ['cn'])
except (ldap.INVALID_CREDENTIALS, ldap.OPERATIONS_ERROR):
    return False
retrurn True

So here we binding LDAP with our credentials, and if no error was raised, we try to perform search for our user’s CN in LDAP. And if there was an empty password and this is not correct, here will be raised OPERATIONS_ERROR, because no actual bind with credentials was performed.


I was getting the exact same error as you, what I did was adding this line (as suggested by Christopher), l.set_option(ldap.OPT_REFERRALS, 0) before doing the binding, e.g.

conn.protocol_version = ldap.VERSION3
conn.set_option(ldap.OPT_REFERRALS, 0)
conn.simple_bind_s(user, pw)

And after that my connection to LDAP worked fine.