|
|
|
BROWSE
All Titles WordPress Web Services SOA BPEL Web Graphics & Video Web Development RAW Portugues, Espanol, Italiano, French PHP/MySQL Oracle Open Source Networking & Telephony Moodle Microsoft & .NET Linux Servers jQuery Joomla! JBoss Java e-Learning e-Commerce Dynamics Drupal CRM Cookbook Content Management Beginner Guides Architecture and Analysis AJAX Future Titles Recently Published Titles Among other merits, Python is an ideal language for writing server-side scripts, allowing you to integrate interactive behavior with HTML. Persisting dynamic content to an underlying database is fairly straightforward. By installing an appropriate Python DB module, you get the ability to interact with the database of choice from within Python code, moving your application data in and out of the underlying persistent store. This article by Yuli Vasiliev will walk you through the process of building a simple Python application that interacts with a MySQL database. In a nutshell, the application picks up some live data from a web site and then persists it to an underlying MySQL database. See More This is the second article in the article mini-series on Python LDAP applications by Matt Butcher. For first part please visit this link. In this article we will see some of the LDAP operations such as compare operation, search operation. We will also see how to change an LDAP password. See More |
Python LDAP Applications: Part 1 - Installing and Configuring the Python-LDAP Library and Binding to an LDAP Directory
Installing Python-LDAPThere are a couple of LDAP libraries available for Python, but the most popular is the Python-LDAP module, which (as with the PHP API) uses the OpenLDAP C library as a base for providing network access to an LDAP server. Like OpenLDAP, the Python-LDAP API is Open Source. It works on Linux, Windows, Mac OS X, BSD, and probably other UNIX operating systems as well (platforms that have both Python and OpenLDAP available). The source code is available at the official Python-LDAP website: Before installing Python-LDAP, you will need to have the Python scripting language installed. Typically, this is installed by default on Ubuntu (and on most flavors of Linux). Installing Python-LDAP requires only one command:
This will choose the module or modules that match the installed Python version. That is, if you are running Python 2.4 (the stable version, at the time of writing), this will install the The library, which consists of several Python packages, will be installed into In Ubuntu, there is no need to run further configuration in order to make use of the Python-LDAP library. We are ready to dive into the API. If you install by hand, either from source or from the binary packages, you may need to add the Python-LDAP library to your Python path. See the Python documentation for details. The Python-LDAP API is well documented. The documentation is available online at the official Python-LDAP website: In previous versions of Ubuntu Python-LDAP documentation was available in the package python-ldap-doc, which could be installed with apt-get. Also, many of the Python-LDAP functions and objects have documentation strings that can be accessed from the Python interpreter like this: >>> print ldap.initialize.__doc__ The documentation string usually contains a brief description of the function or object, and is a useful quick reference. A Quick Overview of the Python LDAP APINow that the package is installed, let's take a quick look at what was installed. The Python-LDAP package comes with nine different modules:
Most of the commonly used LDAP features are in the A Note on the Python ExamplesThe Python interpreter (python) can be run interactively. Running Python in an interactive mode can be very useful for discovery and debugging. Further, since it prints useful information directly to the console, it can be useful for demonstration purposes. In many of the examples below, the code is shown as it would be entered in the interactive shell. Here is an example: >>> h = "Hello World" Lines that begin with h = “Hello World” Most of the time, features are introduced using the interpreter, but lengthier examples are done in the form of a Python script. Where it might be confusing, I will explicitly say in the text which of the two methods I am using. Connecting and Binding to the DirectoryNow that we have the library installed, we are ready to use the API. The Python-LDAP API connects and binds in two stages. Initializing the LDAP system is done with the >>> import ldap The first line of this example imports the The second line initializes the LDAP code, and returns an Sometimes, you may prefer to pass in simply host and port information. This can be done with the >>> con.get_option(ldap.OPT_X_TLS_DEMAND) A Safe ConnectionIn most production environments, security is a major concern. As we have seen in previous chapters, one major component of security in network-based LDAP services is the use of SSL/TLS-based connections. There are two ways to get transport-layer security with the Python-LDAP module. The first is to connect to the LDAPS (LDAP over SSL) port. This is done by passing the correct parameter to the Or, instead of using LDAPS, you can perform a Start TLS operation before binding to the server: >>> import ldap Note that while the call to ExceptionsConnecting to an LDAP server may result in the raising of an exception, so in production code, it is best to wrap the connection attempt inside of a try/except block. Here is a fragment of a script: #!/usr/bin/env python In the case above, if the There are a few dozen exceptions that the Python-LDAP library might raise, but all of them are subclasses of the except ldap.LDAPError, e: Within an In general, it is best to use try/except blocks around LDAP operations in order to catch any errors that might occur during processing. Mastering OpenLDAP: Configuring, Securing and Integrating Directory Services
For more information, please visit: www.PacktPub.com/OpenLDAP-Developers-Server-Open-Source-Linux/book BindingOnce we have an
First, for many Python LDAP functions, including almost all of the LDAP operations, there are both synchronous and asynchronous versions. Synchronous versions, which will block until the server returns a result, have method names that end with The other operations – those that do not end with Since they wait to return any results until the operation has been completed, synchronous methods will often have different return values than their asynchronous counterparts. Synchronized methods may return the results obtained from the server, or they may have void returns. Asynchronous methods, on the other hand, will always return a message identifier. This identifier can be used to access the results of the operation. Here's an example of the different results for the two different forms of simple bind. First, the synchronous bind: >>> dn = "uid=matt,ou=users,dc=example,dc=com" Notice that this method returns a tuple. Now, look at the asynchronous version: >>> con.simple_bind( dn, pw ) In this case, the Notes on Getting Results Later in this chapter, we will see more sophisticated uses of synchronous and asynchronous methods, but for now we will continue looking at methods of binding. The bind() and bind_s() methods work the same way, but they require a third parameter, specifying which sort of authentication mechanism to use. Unfortunately, at the time of this writing, only the AUTH_SIMPLE form of binding (plain old simple bind) is supported by this mechanism: >>> con.bind_s( dn, pw, ldap.AUTH_SIMPLE ) This performs a simple bind to the server. ExceptionsA bind can fail for a number of reasons, the most common being that the connection failed (the CONNECT_ERROR exception) or authentication failed (INVALID_CREDENTIALS). In production code, it is a good idea to check for these exceptions using try/except blocks. By checking for them separately, you can distinguish between, say, authentication failures and other, more serious failures: l = ldap.initialize(server) In this case, if the failure is due to the user entering the wrong DN or password, a message to that effect is printed. Otherwise, the error description provided by the LDAP library is printed. SASL Interactive BindsSASL is a robust authentication mechanism, but the flexibility and adaptability of SASL comes at the cost of additional complexity. This additional complexity is evident in the Python-LDAP module. SASL binding is implemented differently than the other bind methods. First, there is no asynchronous version of the SASL bind method (not all thread safety issues have been worked out in this module, yet). Since the SASL code is not as stable as the rest of the API, you may want to stick to simple binding (with SSL/TLS protection) rather than rely upon SASL support. There is only one SASL binding method, sasl_interactive_bind_s(). This method takes two arguments. The first is a DN string. It is almost always left blank, since with SASL, we usually authenticate with some other identifier. The second argument is an sasl object (or a subclass of an sasl object). The sasl object contains a dictionary of information that the SASL subsystem uses to perform authentication. Each different SASL mechanism is implemented as a class that is a subclass of the sasl object. There are a handful of different subclasses that come with the Python-LDAP module, though you can create your own if you need support for a different mechanism.
Our LDAP server is configured to allow DIGEST-MD5 SASL connections, so we will walk through an example of performing this sort of SASL authentication. >>> import ldap To begin with, we import the ldap and ldap.sasl packages, and we store the user name and password information in a couple of variables. After initializing a connection, we need to create a new sasl object – on that will contain the information necessary to perform DIGEST-MD5 authentication. We do this by constructing a new digest_md5 object: >>> auth_tokens = ldap.sasl.digest_md5( user_name, pw ) Now, auth_tokens points to our new SASL object. Next, we need to bind. This is done with the sasl_interactive_bind_s() method of the LDAPObject: >>> con.sasl_interactive_bind_s( "", auth_tokens ) If a SASL interactive bind is successful, then this method will return an integer. Otherwise, an INVALID_CREDENTIALS exception will be raised: >>> auth_tokens = ldap.sasl.digest_md5( "foo", pw ) In this case, the user foo was not found in the SASL DB, and the SASL subsystem returned an error. Mastering OpenLDAP: Configuring, Securing and Integrating Directory Services
For more information, please visit: www.PacktPub.com/OpenLDAP-Developers-Server-Open-Source-Linux/book UnbindingThe unbind() method of the LDAPObject class unbinds and closes the connection to the LDAP server. While there is an unbind_s() method, it doesn't matter which one you use – both are synchronous. >>> con.unbind() The server receives an unbind operation, and then the client closes the connection. But what if you want to switch users, while using the same connection? In most cases, another call to one of the binding methods will work. But with the sasl_interactive_bind_s() method, you will need to close the connection, and then reconnect in order to rebind. As a matter of practice, you should always unbind from the server when you are done using it. This can be done conveniently using a try/finally clause. Here's a snippet of a larger script exemplifying the use of a try/finally block (with try/except blocks nested inside). try: In this case, the finally block makes sure that regardless of what happens – whether the operations succeed or fail – an LDAP unbind() is always called at the end. A Practical Example: get_sasl_dn.pyWe now have enough information to create a small program. One issue, when binding with SASL, is to know what DN you are using. This is a result of the fact that most forms of SASL bind do not use DNs to authenticate. They use other forms of user identification, and OpenLDAP maps those to a DN based on rules in the slapd.conf configuration. We will create a simple script, using the commands introduced above, plus the simple whoami_s() method, to do a SASL bind, and then report the DN of the user once the bind is complete. Who Am I? The simple version of the script we do here will only try the SASL DIGEST-MD5 mechanism, but such a script could be easily extended to work with other SASL mechanisms. Here is our script, called get_sasl_dn.py #!/usr/bin/env python The beginning is just a boilerplate Python script. We need to import the ldap and ldap.sasl libraries for the LDAP work. We will need sys to get access to the standard error output, and we will use the getpass library to get user and password information. Next, we declare a few variables and write some usage information, which the user can see by running:
The next thing to do is get the user name and password information. This is done in the following bit of code: if len(sys.argv) > 1: First, we check to see if the argument list passed in from the command line (sys.argv) has any information. Since the program name is the first item, we need to know if the list has more than one item. If it does, then we check to see if either the -h or --help flags were set, in which case we just want to print usage information and exit. But if neither of those are set, we assume the second argument (sys.argv[1]) is the user name. If no arguments were specified on the command line, we use getpass.getuser() to get user information from the underlying environment. On a UNIX or Linux system, this returns the name of the shell user. After we have the user name, we get the password by getpass.getpass(), which prompts the user to enter a password. Now we have the information we need to perform a SASL bind to the LDAP server. The next step is to connect to LDAP. We want to wrap all of this in a try/finally block: try: A few lines were removed from the above. We will get back to those in a moment. The first few lines of the section above (after the try: ) initialize the LDAPObject, and then create the digest_md5 class. With this try/finally block, we know that an unbind() will be done whether the program succeeds or encounters an error. Note that the nested try/except block in the finally clause just ensures that if the unbind raises an exception, the user won't have to see an ugly stack trace. Now for the lines that were missing in the example above: try: This try/except block does the hard work. First, it does a synchronous bind to the server, using the digest_md5 object (named auth_tokens) that was created on the lines above. If the bind fails, an exception will be thrown (which will be caught by the except clause below). But if it succeeds, then the script will write out the DN of the connected user: sys.stdout.write( con.whoami_s() ) The con.whoami_s() method performs the LDAP Who Am I extended operation, and then returns the DN as a string. This is then written to the standard output for the program. Again, any errors in the LDAP Who Am I operation will be caught by the except clause. Here's an example of what the output looks like for a successful run of the program: $ ./get_sasl_dn.py matt On the command line, the program has one parameter (matt). This will be stored as sys.argv[1], and assigned by the script to the user_name variable. Then, getpass.getpass() prompts for the password (Password for matt:). The password is not echoed back to the terminal. Finally, once the SASL authentication and the whoami_s() method are run, the DN is printed to the standard output: dn:uid=matt,ou=users,dc=example,dc=com. Now we are comfortable binding and unbinding from the directory, and have looked at some basic strategies for handling connections and exceptions. We are ready to move on to other LDAP operations. Matplotlib for Python Developers
About The AuthorMatt Butcher is the principal consultant for Aleph-Null, Inc., a systems integrator that specializes in Free and Open Source solutions.Matt has worked on a wide variety of projects, including embedding Linux in set-top boxes and developing advanced search engines based on artificial intelligence and medical informatics technologies. Matt is involved in several Open Source communities. He is also a member of the Emerging Technologies Lab at Loyola University Chicago, where he is currently finishing a Ph.D. in philosophy. Matt has written two other books for Packt: Managing and Customizing OpenCms 6, and Building Websites with OpenCms. Matt has also contributed articles to Newsforge.com, TheServerSide.com, and LinuxDevices.com.Books from Packt
Tuesday, December 18, 2007 | Open Source
This is the third article in the article mini-series on Python LDAP applications by Matt Butcher. The first part deals with the installation and configuration of Python-LDAP library, and the binding-unbinding operations, and changing of the LDAP password. The second article takes a look at some of LDAP operations. In this article we will see some more LDAP operations such as add operation, delete operation etc. Then we will take a look at LDAP URL Library. See More |
TOP TITLES ![]()
|
| ||||||||