Python-ldap not able to bind successfully

13,826

Solution 1

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.

Solution 2

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)

Solution 3

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.

Share:
13,826

Related videos on Youtube

Titus P
Author by

Titus P

Updated on July 25, 2022

Comments

  • Titus P
    Titus P almost 2 years

    I am not having any luck finding answers on this, so here it goes.

    When I attemtp to connect to an AD server using python-ldap, it appears to work successfully for some functions, and not for others. My connection:

    >>>import sys
    >>>import ldap
    
    >>>l = ldap.initialize("ldap://company.com:389")
    >>>l.set_option(ldap.OPT_PROTOCOL_VERSION, 3)
    >>>l.simple_bind_s("[email protected]","password")
    (97, [], 1, [])
    

    Some simple google searching indicated that the 97 meant success, although the level of success is a bit wonky. But, for some reason, I cant find anything on the status code 1. If I run some ldap functions on the connection, some of them work and some do not.

    >>>l.whoami_s()
    'u:COMPANY.COM\\user'
    

    Seems to return fine, but

    >>> base_dn = 'dc=company,dc=com'
    >>> retrieveAttributes = ["uniquemember"]
    >>> searchFilter = "cn=user"
    >>> l.search_s(base_dn, ldap.SCOPE_SUBTREE,searchFilter,retrieveAttributes)
    Traceback (most recent call last):
      File "<console>", line 1, in <module>
      File "/home/user/.envs/scoring/local/lib/python2.7/site-packages/ldap/ldapobject.py", line 552, in search_s
        return self.search_ext_s(base,scope,filterstr,attrlist,attrsonly,None,None,timeout=self.timeout)
      File "/home/user/.envs/scoring/local/lib/python2.7/site-packages/ldap/ldapobject.py", line 546, in search_ext_s
        return self.result(msgid,all=1,timeout=timeout)[1]
      File "/home/user/.envs/scoring/local/lib/python2.7/site-packages/ldap/ldapobject.py", line 458, in result
        resp_type, resp_data, resp_msgid = self.result2(msgid,all,timeout)
      File "/home/user/.envs/scoring/local/lib/python2.7/site-packages/ldap/ldapobject.py", line 462, in result2
        resp_type, resp_data, resp_msgid, resp_ctrls = self.result3(msgid,all,timeout)
      File "/home/user/.envs/scoring/local/lib/python2.7/site-packages/ldap/ldapobject.py", line 469, in result3
        resp_ctrl_classes=resp_ctrl_classes
      File "/home/user/.envs/scoring/local/lib/python2.7/site-packages/ldap/ldapobject.py", line 476, in result4
        ldap_result = self._ldap_call(self._l.result4,msgid,all,timeout,add_ctrls,add_intermediates,add_extop)
      File "/home/user/.envs/scoring/local/lib/python2.7/site-packages/ldap/ldapobject.py", line 99, in _ldap_call
        result = func(*args,**kwargs)
    OPERATIONS_ERROR: {'info': '000004DC: LdapErr: DSID-0C0906E8, comment: In order to perform this operation a successful bind must be completed on the connection., data 0, v1db1', 'desc': 'Operations error'}
    

    I am stumped to why the whoami would work but the search would not. I am using a domain admin for the user, so it shouldn't have anything to do with permissions to the directory. Can anyone shed some light?

    • Lucas Meijer
      Lucas Meijer over 10 years
      I have this line in my python code that accesses ldap, and I put it there last year but I don't recall why: l.set_option(ldap.OPT_REFERRALS, 0)

Related