Python Ldap: Ldapobject. Search_S() Works, but Ldapobject. Search() Doesn't

I am trying to implement a basic LDAP authentication script in Python, and I am trying to just perform a simple LDAP search and see if it works. I believe I have correctly created and set up my LDAP object and connection.

After binding, I try to perform a search. Using the LDAPObject.search_s() method successfully returns a list of strings with user information. When I use the LDAPObject.search() method, though, the method returns result code 2, which is a protocol error. The reason I want to use the search() method is because it returns an int and not a list. From what I understand according to the Python LDAP documentation, the two methods can take in the same arguments, so I don't understand why one method is returning an error and not the other.

Here is my code:

import ldap
import getpass

# get login info

username = raw_input("Enter your username: ")
password = getpass.getpass("Enter your password: ")

ldap_server = "LDAP://ipaddress:port"
base_dn = "OU=Domain Users,DC=dummyname,DC=com"
user_dn = username + "@dummyname.com"
search_filter = "(&(objectClass=user)(sAMAccountName=" + username + "))"

ld = ldap.initialize(ldap_server);
ld = ldap.open(ldap_server)
ld.protocol_version = 3
ld.set_option(ldap.OPT_REFERRALS, 0)

# bind user information to ldap connection

try:
    print ld.simple_bind_s(user_dn, password)
    results = ld.search(base_dn, ldap.SCOPE_SUBTREE, search_filter)
    print results
    ld.unbind_s()
except ldap.INVALID_CREDENTIALS:
    print "Your username or password is invalid."
except Exception as e:
    print("Connection unsuccessful: " + str(e.message))
    ld.unbind_s()

Full output of this code is:

Enter your username: myusername
Enter your password:
(97, [], 1, [])
2

Any help would be greatly appreciated. Thanks.

1 Answer

The following command is using an async search which does not block to wait for a return value. The int it returns is actually the MSGID of the LDAPObject which you need to get the return value when it is returned.

msgid = ld.search(base_dn, ldap.SCOPE_SUBTREE, search_filter)  # Returns int of msgid without blocking

To get the actual results you need to call

actual_results = ld.result(msgid)   # Blocks until search is done and returns [(dn,attrs)]

Using the following commands causes the LDAPObject to search in "sequential order" thus blocking the program.

results = ld.search_s(base_dn, ldap.SCOPE_SUBTREE, search_filter)  # blocks until all results are received   [(dn,attrs)]

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Elena Rostova

Elena Rostova

Lead Health, Wellness & Medical Journalist

Elena Rostova holds a Master's degree in Public Health Journalism. She covers groundbreaking medical research, holistic wellness trends, mental health awareness, and nutritional science.

Share this article
Twitter Facebook Pinterest