What's the best way to write an LDAP client

Question:

First of all I have to say that I don’t know LDAP so in this question I’ll try to explain what are my thoughts about the task that I have to perform.

I need to develop an application, essentially a LDAP client, for authentication on an LDAP Server.
My first problem is to try authentication on the LDAP server available in the company where I work.

Use ldapsearch to test authentication

I know the program ldapsearch. This link explains that is it possible to use it for LDAP authentication.
So ldapsearch can be used to test the authentication on an LDAP server

One way to use of ldapsearch by command line is:

ldapsearch -H ldap://ldap.example.com -D "cn=admin,dc=example,dc=com" -W -b "cn=admin,dc=example,dc=com"

Previous command uses the following options:

  • -H ldapURI: Specify URI referring to the LDAP server
  • -D bindDN: Use the Distinguished Name bindDN to bind to the LDAP directory
  • -W: Prompt for simple authentication
  • -b searchbase: Use searchbase as the starting point for the search instead of the default.

The command execution queries the LDAP server ldap.example.com and asks the insertion of the password for the user with Common Name admin (cn=admin). If the password of admin is not correct the result is the error message:

ldap_bind: Invalid credentials (49)

If the inserted password is correct the output contains the following 0 Success message:

...
# search result
search: 2
result: 0 Success
...

Integrate ldapsearch inside an application?

By ldapsearch I have tested with success the LDAP authentication on my company LDAP Server. Now I have a question: is ldapsearch suited for direct used inside a LDAP client? And in this case:

  • Is it correct to use the different ldapsearch output (described above) to know if a user has inserted the correct password?
  • The LDAP client have to call the external program ldapsearch?

How to write a client to direct authenticate on a LDAP server?

For example in this post ldapsearch is used in a shell script to verified which users of a list are present on a LDAP Server but I suspect that it isn’t suited for direct use inside a program write in Python or C.

If I exclude the use of ldapsearch I have to direct implement the LDAP authentication in a Client application (may be in Python language).

Without ldapsearch how can I implement the protocol LDAP in Python or in other language?

Thank you

Asked By: frankfalse

||

Answers:

About the question I think that the direct use of ldapsearch for authentication on LDAP server is not a good idea, in fact, after read carefully the link indicated in the question I have understood that the author has cited the use of ldapsearch only as an experiment, and this is clear when he says:

That may be summarized as (as experiment in command line):

$ ldapsearch -x -h ldap.company.com -s sub -b 'dc=europe,dc=com' "uid=XYZ"

It is better use API provided by various programming languages. In particular I’ve decided to write a Python application.
I suppose that ldapsearch can be use for authentication in a bash script.

Python application for authentication on LDAP Server

To authenticate on a LDAP Server by a Python application is possible to use the python-ldap module; this is a wrapper of OpenLDAP library and provides a Python API to interact with a LDAP Server.

Useful link:

  • The documentation of python-ldap can be found here.

  • An useful example code which uses python-ldap can be found at this link.

The example program allows the authentication on a LDAP Server by insertion of the credentials of an existent account (domain,username,password) and after the authentication, it executes a query on LDAP database (as ldapsearch).
The code defines the function query_activedirectory() which can be used to query the LDAP Server.
To call the function is used the code below:

# the function returns a generator, so it won't fetch anything yet
response = query_activedirectory(
  uri="ldap://yourserver.domain.local:389",
  bindDN="cn=yourname,OU=folder,OU=folder,DC=domain,DC=local",
  bindPW="your_password",
  baseDN="OU=folder,OU=folder,DC=domain,DC=local",
  filterstr="&(objectClass=user)(!(objectClass=computer))(memberOf:1.2.840.113556.1.4.1941:=CN=cool_group,OU=folder,OU=folder,DC=domain,DC=local)",
  attrlist=["userPrincipalName", "givenName"],  # None to fetch all attributes
  timeout=-1,    # wait indefinitely
  pagesize=1000
)

To execute the example code with the Server LDAP present in my company I have adapted the content of the following variable to be compliant to my company settings:

  • uri –> in the example its value is "ldap://yourserver.domain.local:389" while for example in my company the TCP port is 3268 and obviously the rest of URI is different
  • bindDN (stands for bind Distinguish Name) –> in the example its value is "cn=yourname,OU=folder,OU=folder,DC=domain,DC=local"
  • bindPW (stands for bind Password) –> in the example its value is "your_password"
  • baseDN (stands for base Distinguish Name) –> in the example its value is "OU=folder,OU=folder,DC=domain,DC=local"
  • filterstr (correspond to the searchbase passed to -b argument of ldapsearch) –> check the example code for the value of filter
  • attrlist –> in the example its value is ["userPrincipalName", "givenName"]

This is the best way that I have found for authentication on a LDAP server by a python application.
I have followed the hint of @larsks (see above comments).

Answered By: frankfalse
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.