LDAP Programming in Python

July 8th, 2003 by Ryan Kulla in

An introduction to the python-ldap package for writing applications.
Your rating: None Average: 3.1 (11 votes)

You've heard about the next generation directory protocol called LDAP (lightweight directory access protocol), and you're wondering if it's possible to write programs that can interact with it. Maybe you've even set up an LDAP server of your own, and now you want to write programs for it. To these ends, this article gets you ready to write your own programs to automate the querying process of LDAP servers. Hopefully, it also provides you with a solid foundation for extending your knowledge to write configuration scripts and whatever else you want to do with LDAP.

Most major programming languages have an LDAP API, but I chose to use Python because it is perhaps the easiest and clearest language with which to demonstrate. If you do not already understand the basics of the Python programming language and LDAP, you probably should come back to this tutorial after you have become better acquainted with them.

Meet python-ldap

Writing programs that access LDAP servers is easy to do using Python and python-ldap. The python-ldap package contains a module that wraps the OpenLDAP C API and provides an object-oriented client API to interact with LDAP directory servers. The package also contains modules to do other tasks related to LDAP, such as processing LDIF, LDAPURLs and LDAPv3 schemes and more.

Currently, standard implementations of Python do not come with python-ldap, but you can download it as a third-party package from SourceForge.

A Simple python-ldap Application

The best way to learn is to write an example program, so let's write a small and complete program to fetch some specific contact information from an LDAP server. Because indentation matters in Python, all the code given below is indented, so copy it as you see it.

The first thing we need to do is import the ldap module. So open your favorite text editor and type import ldap. For this program, we need to create two simple functions:

  • a main() function that binds the program to an LDAP server and calls a search function

  • a function called my_search() that is used to retrieve/display data from the server.

Let's create our main function and set up variables to authenticate with the LDAP server by using def main():.

If you are using a public server, you can leave the values for the who and cred blank. You can get a list of some public LDAP servers here

. It looks something like this:

   server = "ldap.somewhere.edu"
    who = ""
    cred = ""

Now we need to make a keyword set to what we want our search string to be. I use my first name for this sample program:

   keyword = "ryan"

Next, we need to bind to the LDAP server. Doing so creates an object named "l" that is then used throughout the program.

   try:
        l = ldap.open(server)
        l.simple_bind_s(who, cred)
        print "Successfully bound to server.\n"

We're now ready to query the server. We also now catch any possible errors if there is a problem authenticating:

       print "Searching..\n"
        my_search(l, keyword)
    except ldap.LDAPError, error_message:
        print "Couldn't Connect. %s " % error_message

Having written our main function, we now can create our search function:

   def my_search(l, keyword):

In a moment we will be calling python-ldap's built-in search method on our l object. Four variables--base, scope, filter and retrieve_attributes--are the parameters of that search method. Base is used for the DN (distinguished name) of the entry where the search should start. You can leave it blank for this example:

   base = ""

For scope we use SCOPE_SUBTREE to search the object and all its descendants:

   scope = ldap.SCOPE_SUBTREE

Our search filter consists of a cn (common name) and our keyword. Putting asterisks around our keyword (ryan) will match anything with the string ryan, such as Bryant.

   filter = "cn=" + "*" + keyword + "*"

The last argument we pass to the search method is used to return all the attributes of each entry:

   retrieve_attributes = None

Now, let's setup a few more variables, including a counter to keep track of the number of results returned:

   count = 0

a list to append the results to:

   result_set = []

and a variable to specify the length, in seconds, we're willing to wait for a response from the server:

   timeout = 0

Now we can begin our search by calling python-ldap's search method on our l object:

   try:
        result_id = l.search(base, scope, filter, retrieve_attributes)

Store any results in the result_set list

       while 1:
            result_type, result_data = l.result(result_id, timeout)
            if (result_data == []):
                break
            else:
                if result_type == ldap.RES_SEARCH_ENTRY:
                    result_set.append(result_data)

If we were to print result_set now, it might look like a big list of tuples and dicts. Instead, step through it and select only the data we want to see

       if len(result_set) == 0:
            print "No Results."
            return 
        for i in range(len(result_set)):
            for entry in result_set[i]:                 
                try:
                    name = entry[1]['cn'][0]
                    email = entry[1]['mail'][0]
                    phone = entry[1]['telephonenumber'][0]
                    desc = entry[1]['description'][0]
                    count = count + 1

Display the data, if any was found, in the following format:

    1.    Name:    Description:    E-mail:    Phone:    2.    Name:    Description:    E-mail:    Phone:    etc..

                   print "%d.\nName: %s\nDescription: %s\nE-mail: %s\nPhone: %s\n" %\
                           (count, name, desc, email, phone)
                except:
                    pass
    except ldap.LDAPError, error_message:
        print error_message

Running the Program

You probably are anxious now to run the program and see it in action. But first, you need to append the following code to call the main() function. It should go at the end of your script before you run it.

if __name__=='__main__':
    main()

Now that you have inputted everything you need to run the Python program, save the source code in your editor and name the file ldap-test.py. Give it a run and test it out. If you don't see any output, it is probably because you didn't enter a valid LDAP server and/or who and cred, or because there simply is no existing search field on the server that matches the one we're using (in this case *ryan*).

Next Steps

We have only gotten our feet wet with how to use Python to write LDAP applications; you can do a lot more with python-ldap. You can find more python-ldap programming examples here.

For more information, check out the python-ldap documentation. A complete list of LDAP-related RFCs also are freely available on-line. If you are looking for a good book, consider LDAP Programming, Management, and Integration by Clayton Donely and LDAP: Programming Directory-Enabled Applications With Lightweight Directory Access Protocol by Tim Howes. These books use programming languages such as C/C++, Perl and Java for their code examples, but they still can be helpful for those who wish to code LDAP applications in Python. For an open-source implementation of LDAP, visit OpenLDAP's web site. There's also a developer's mailing list.

__________________________


Special Magazine Offer -- Free Gift with Subscription
Receive a free digital copy of Linux Journal's System Administration Special Edition as well as instant online access to current and past issues. CLICK HERE for offer

Linux Journal: delivering readers the advice and inspiration they need to get the most out of their Linux systems since 1994.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
KOMTET's picture

Translation

On October 9th, 2009 KOMTET (not verified) says:

Great!
Thanks.
We have translated your article in russian. If you have no objection - posted it on our website.
http://www.komtet.ru/info/python/ldap-v-python

Anonymous's picture

Quite poorly written. The

On July 31st, 2009 Anonymous (not verified) says:

Quite poorly written. The following is a much more practical explanation of getting started with python & ldap.

http://www.grotan.com/ldap/python-ldap-samples.html

Anonymous's picture

It was good for the time

On August 4th, 2009 Anonymous (not verified) says:

Keep in mind that in 2003, when this article was written, there were no other articles on LDAP programming in Python. So I think it was quite good for the time.

Anonymous's picture

Bad code

On April 20th, 2007 Anonymous (not verified) says:

I was able to pick out the basics from this example, but the python code is terrible...

Anonymous's picture

Re: LDAP Programming in Python

On October 22nd, 2004 Anonymous says:

The code, for the most part, works for me. But I'm having trouble slicing the data portions out of the search result.

When grabbing 'description' (or any other attribute), I'm getting back:

string indices must be integers " entry[1]['description'][0] "

Anonymous's picture

Re: LDAP Programming in Python

On October 23rd, 2004 Anonymous says:

try this:
entyr[0][1]['description']

look for Python's Manual about List, Tuple and Dictionary!

Post new comment

Please note that comments may not appear immediately, so there is no need to repost your comment.
The content of this field is kept private and will not be shown publicly.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <pre> <ul> <ol> <li> <dl> <dt> <dd> <i> <b>
  • Lines and paragraphs break automatically.

More information about formatting options

Newsletter

Each week Linux Journal editors will tell you what's hot in the world of Linux. You will receive late breaking news, technical tips and tricks, and links to in-depth stories featured on www.linuxjournal.com.
Sign up for our Email Newsletter

Tech Tip Videos

From the Magazine

December 2009, #188

If last month's Infrastrucuture issue was too "big" for you then try on this month's Embedded issue. Find out how to use Player for programming mobile robots, build a humidity controller for your root cellar, find out how to reduce the boot time of your embedded system, and if you're new to embedded systems find out the basics that go into one. You can also read about the Beagle Board, the Mesh Potato and a spate of other interestingly named items. And along with our regular columns don't miss our new monthly column: Economy Size Geek.


Read this issue