phpLDAPadmin

We have configured Apache to use its built-in LDAP modules to perform authentication with the help of a directory server. Now we are going to turn to a more complex web-based application, phpLDAPadmin. phpLDAPadmin is an application, written in PHP, designed to help manage a directory server. While it is known to work on other directory servers, it was developed against OpenLDAP.

Before we can install phpLDAPadmin, we will need to install a few other packages. In the first part of this chapter we looked at Apache. This (or some other web server) is required to run phpLDAPadmin. Additionally, some recent version of PHP (we will use PHP 5) is needed, along with the PHP LDAP module.

For example, to install PHP 5, we would run the following command:

  $ sudo apt-get install libapache2-mod-php5 php5-ldap

Installing PHP may require the satisfaction of several other dependencies, but apt-get will take care of the heavy lifting for you.

Once PHP is installed, you can restart Apache, and then move on to installing phpLDAPadmin.

The easiest way to install phpLDAPadmin is to use the package in the Ubuntu repository.

phpLDAPadmin is included in the universe repository in Ubuntu. This means that as long as you have the universe repository enabled in your sources (see /etc/apt/sources.list), you can install it with a simple apt-get command:

  $ sudo apt-get install phpldapadmin

phpLDAPadmin will be installed on the file system at /usr/share/phpldapadmin, and Apache is configured to direct requests for http://hostname/phpldapadmin to the phpLDAPadmin application. The Apache configuration is located at /etc/phpldapadmin/apache.conf.

Note

It is also easy to install phpLDAPadmin from the source distribution available at http://phpldapadmin.sourceforge.net. Once the web server and PHP are installed, it is simply a matter of unpacking the source code into a folder under the web server's web root directory (for example /var/www/). For complete instructions, see the installation guide on the official phpLDAPadmin documentation wiki: http://wiki.phpldapadmin.info/tiki-index.php?page_ref_id=6.

Once phpLDAPadmin is installed, we can move on to configuration.

The phpLDAPadmin configuration file is at /etc/phpldapadmin/config.php. phpLDAPadmin uses a config file format that, while common in PHP and Perl applications, may seem daunting to one who is used to editing the typical name/value parameter files that most UNIX applications use.

There are two major ways in which this configuration file differs from the standard type:

  • The way default configuration options are handled
  • The form of a configuration parameter

Regarding the first, phpLDAPadmin has two configuration files, one that stores all of the default settings (/usr/share/phpldapadmin/lib/config_default.php), and one intended for administrators to edit (/etc/phpldapadmin/config.php). Administrators should only change this second config file. The config_default.php file should not be altered.

When phpLDAPadmin attempts to access a setting, it will first check to see if there is a custom setting in the custom settings file (config.php). If one is found, that setting will be used. If one is not found, the value of the default setting is used.

The advantage of this technique is that upgrades to phpLDAPadmin need not make any changes to the custom configuration file. Only the default file is modified. The downside is that sometimes new parameters are added, but go unnoticed, since the administrator's configuration file remains unchanged.

The second difference, the form of the configuration parameter, is based in part on the first. Instead of using a simple text file to store parameters, phpLDAPadmin uses PHP variables to store information. In this sense, the config.php configuration file is actually a piece of code.

There are some clear advantages in doing this:

  • All of the built-in PHP features can be used in the configuration file (including dynamically evaluated scripts)
  • No special configuration file parser is needed, making code size smaller and run time faster

But there are definitely some drawbacks to this method, and the main one is that readability of the file can be greatly diminished. The default configuration file, for example, is almost 400 lines long and contains code (though only a smattering) mixed with configuration parameters.

Another drawback is that straightforward configuration of the application will still require some knowledge of the PHP language.

As we look at the configuration file, I will not assume working knowledge of PHP, and will explain some of the constructs in the configuration file.

The configuration parameters in phpLDAPadmin can look daunting at first. In this section, I will explain the format of each type of configuration parameter. Each section gives a very brief example of what the parameter form looks like, followed by a more lengthy description of what is going on.

If you are not a programmer, don't get discouraged if not all of this makes sense. The important thing is that you understand the structure of each of the configuration directives.

Configuration parameters in phpLDAPadmin's config.php file take one of three forms: a variable setting, a function call, or an array setting.

The second form of a configuration parameter in phpLDAPadmin's configuration file uses a function call. Briefly, a function call looks like this:

$object->function('parameter one', 'parameter 2');

A function may have zero or more parameters, and the number is determined by the programmer.

Functions can be attached to objects. An object, roughly speaking, is a container for data and functions. phpLDAPadmin is an object-oriented program, meaning that it makes frequent use of objects to organize the functional units of the source code.

To call a function that is attached to the object, you will need to use the arrow (access) operator (->), which is composed of a dash (-) and a greater-than sign (>). This indicates that the function is a member of the object. Here's an example taken from the phpLDAPadmin configuration file:

$i = 0;
$ldapservers = new LDAPServers;
$ldapservers->SetValue($i,'server','name','My LDAP Server');

The first line takes the variable named $i, and assigns it the value 0.

The second line creates a new LDAPServers object, and assigns it to the variable $ldapservers. Now, anytime we work with the variable $ldapservers we are actually working with an object that has all of the member functions and variables defined in the LDAPServers class. The LDAPServers class describes the servers that phpLDAPadmin will connect to.

You can think of a class as defining all of the parts of a machine, and the object as an instance of that machine. Once we have our copy of our LDAPServers machine, we can access the data stored in the machine, and also use the machine's functions to perform certain tasks.

According to the class definition for this object, it has a handful of member functions, including the SetValue() function. This function stores data in the $ldapservers object. So the third line in the given example sets some information about the LDAP server:

$ldapservers->SetValue($i,'server','name','My LDAP Server');

This line uses the SetValue() function of $ldapservers. The SetValue() function takes four different pieces of information:

  • The number for the server (the value of $i, in this case)
  • A string representing what sort of setting this is ('server')
  • A string that names the property being set ('name')
  • A string representing the value of the property ('My LDAP Server')

Later we will talk about what each one of these does. For the time being, though, the important thing is to understand the general form of the function: $object->function( param_1, param_2);. A function can have as many parameters as the programmer decides upon.

For the most part, the comments in the configuration file will guide us as to what sorts of parameters each function will need. You should not need to look at any other piece of code to figure out what to put in an object.

Now let's take a look at the list kind of directive.

The last sort of configuration parameter in phpLDAPadmin is the array. There are two basic forms of setting an array value:

$my_array[0] = 'My Value';
$my_map['Key Name'] = 'Value';

An array is an organized collection of information. PHP has two different kinds of arrays: an indexed array (where things are stored in a numbered sequence) and a map (where things are stored in name/value pairs).

An indexed array can be created like this:

$my_array = array( 'a', 'b', 'c');

This creates an array with three items, 'a', 'b', and 'c'. The first one, 'a', is stored in the first slot of the array and can be accessed by index number:

$my_array[0];

Note that the first index number is zero, not one. This would return the value 'a'. The second one can be accessed using the index number of the second item:

$my_array[1];

This would return 'b'.

In a map-type array, instead of using a number for an index, some string (or other object) can be used. For example, we can create an map this way:

$my_map = array( 'First Name' => 'Matt', 'Last Name' = 'Butcher' );

This creates an array with two items, one named First Name and one named Last Name. Now, instead of accessing them by index, I can access them by name:

$my_array['First Name'];

This would return 'Matt'.

Once an array is created using the array() function, you can add elements to an array by assigning a value to an array slot. For an indexed array, this might look like the following:

$my_array[3] = 'd';

This would put 'd' at the fourth position (0, 1, 2, 3) in the array.

Likewise, adding a value to a map is similar, except in place of the index number, you use a key name:

This adds the name 'Dave' to the array item with the key name 'First Name'.

Finally, arrays can be nested inside of each other. Again, here is an example from the phpLDAPadmin config file:

In this example the $queries array is an indexed array where each value is a mapped array. So $queries[0]['name'] and $queries[1]['name'] represent two different name values. Each name value is stored in a different slot in the indexed array. Think of the array as being structured like this bit of pseudo-code:

Now we have two different queries (both stored in the same indexed array): Query 0 and Query 1. Each query has its own name and base.

These are the basic features of arrays—the features that we will be using to configure phpLDAPadmin. Now we are ready to move on to the actual configuration of phpLDAPadmin.

The first thing we need to do is configure phpLDAPadmin to connect to our LDAP server. This is done using the $ldapservers object.

In my installation, Apache and OpenLDAP are running on the same server, so I will configure phpLDAPadmin to connect to the local instance.

To begin this part of the configuration we need to locate the $ldapservers object in the configuration file. The line we are concerned with looks like this:

$ldapservers = new LDAPServers;

It is located on line 63 of our default configuration file.

This defines the $ldapservers object. The rest of our configuration directives for our LDAP server need to go below this line.

The first thing to do is set up the information about our LDAP connection. We want to giver our LDAP server a name, host and port info, and information on whether we want this connection to be encrypted with TLS:

$ldapservers->SetValue($i,'server','name','Example.Com');
$ldapservers->SetValue($i,'server','host','localhost');
$ldapservers->SetValue($i,'server','port','389');
$ldapservers->SetValue($i,'server','tls',false);

This names our server Example.Com, and sets it up to connect to localhost on the default LDAP port 389 without any SSL/TLS encryption.

The $i in the given functions indicates the number of the LDAP server that we are configuring. $i is set to 0, indicating that this is the first LDAP server we are configuring. Where we would have to configure a second LDAP server, we would change $i to 1 and then continue with a second batch of the same sorts of directives.

The second parameter, 'server', indicates that we are setting server parameters. The third parameter ('name', 'host', 'port', and 'tls') indicates the exact server parameter we are setting, and the fourth parameter contains the value to be assigned to the parameter.

Note that the TLS setting is for turning on and off StartTLS (see Chapter 4). If you want to use LDAPS (SSL-based LDAP), then use an LDAP URL, 'ldaps://example.com', in the host setting and set the port to the correct LDAPS port (636 by default).

Next, we need to tell phpLDAPadmin where to store login information. This information is stored in the auth_type parameter:

$ldapservers->SetValue($i,'server','auth_type','session');

When a user logs into phpLDAPadmin, information used for binding to LDAP gets stored. There are three places where this information can be stored:

  • A cookie in the web browser ('cookie')
  • A server session variable ('session')
  • (The information can be added by hand to) the configuration file ('config')

In general, we should store the information in a session variable (as the given example does). If you should choose cookie-based storage make sure you also set $config->custom->session['blowfish'] to a string of random characters. The string is used as a key for the Blowfish cipher and it must be at least 32-characters long. A longer key is better.

The next parameter sets the list of naming contexts (base DNs) that phpLDAPadmin should display:

This sets up only one context DN: dc=example,dc=com. While this setting is necessary on some LDAP servers, OpenLDAP should not need it. OpenLDAP publishes a list of contexts in the Root DSE record, and phpLDAPadmin can get the information from there. In fact, that is the default configuration for phpLDAPadmin, so the setting can be left off or set to this:

This creates an empty list of contexts (array()), and causes phpLDAPadmin to look up the supported contexts in the Root DSE.

There are just two parameters left to look at:

Let's see these two settings:

While there are many other configurable parameters in the phpLDAPadmin configuration file, we have the basics configured. We can now test out the phpLDAPadmin tool with our web browser.

With PHP installed, Apache restarted, and phpLDAPadmin configured, we are now ready to connect to phpLDAPadmin. Ubuntu installs phpLDAPadmin so that it is available at the URL http://<hostname or IP address>/phpldapadmin/. In this case I am running the web browser on the same machine as the Apache server, so http://localhost/phpldapadmin points to the phpLDAPadmin tool.

When phpLDAPadmin first loads, it will look something like this:

A First Look at phpLDAPadmin

The left-hand frame is the navigation frame for phpLDAPadmin. The computer icon accompanied by the text Example.Com indicates the server that we configured. If phpLDAPadmin has been configured with multiple hosts, then the left frame will list them all.

Here is the screenshot:

A First Look at phpLDAPadmin

At the top section, just below the version banner (phpLDAPadmin – 0.9.8.3), there are six links. The Home link points to this page. Request feature, Donate, and Report a bug all point to various places on the external phpLDAPadmin website. Help loads an internal page that in turn points back to the phpLDAPadmin forum website.

Finally, the Purge caches link can be used to purge the internal caches of copies of LDAP data that phpLDAPadmin uses to optimize performance. This may be necessary if phpLDAPadmin displays an old copy of some piece of data when it should display a more recent update.

To log in to our server, click on the Login... link beneath the Example.Com icon. This will load the login screen in the main frame on the right side.

A First Look at phpLDAPadmin

Note that unlike Apache by default, phpLDAPadmin by default requires that you enter your entire DN to log in. It then binds directly as that DN.

If the anon_bind parameter in the phpLDAPadmin conf.php file is set to true instead of false, users will also be able to check a box to log in as the Anonymous user:

$ldapservers->SetValue($i,'login','anon_bind',true);

In that case they will not need to enter either a DN or a password, but phpLDAPadmin will allow them to browse the directory information tree to the extent allowed by the ACLs.

Once you have logged in, the navigation frame will display a list of directory information trees hosted on this directory server, as shown in the screenshot:

Navigating phpLDAPadmin

Beneath Example.Com, there is now a list of seven links:

Underneath this list of links are the base entries for the two directory information trees currently hosted on this server, the cn=log tree,which holds the accesslog, and the dc=example,dc=com tree which holds the directory entries we have been creating throughout this book.

Clicking on a plus (+) icon expands that part of the tree, and shows the subordinate entries:

Navigating phpLDAPadmin

Navigating the directory information tree then, can be done quickly and efficiently through the left-pane navigation.

Each entry in the tree has only the RDN portion of the DN displayed. Through viewing the hierarchy one can build the full DN, but if you wish to display the full DN by default you can set the following parameter in the config.php file:

Conversely, if you want to show just the value of the RDN, without the attr= part, you can set it to %rdnValue in the given parameter instead.

To view an entire record, simply click on the desired entry in the hierarchy view in the left-hand navigation frame. For example, if we click on cn=Admins the full record will be displayed in the main frame:

Viewing and Modifying a Record

This screen provides a number of tools for manipulating a record, as well as a full display of all of the record's attributes. The tools are as follows:

Beneath this selection of tools is a display of all of the attributes for the current record:

Viewing and Modifying a Record

The cn=Admins group record has the following (non-operational) attributes: cn, member, objectclass, and ou. phpLDAPadmin analyzes the record and presents options that are fitting for the record.

First, cn cannot be modified since it is used in the RDN (as is noted on the far right-hand side). Also, it is labeled as required. Clicking on the rename link will do the same thing as the rename option in the list of tools: it will prompt me to perform a modrdn operation.

Under the member attribute, which is also required, there are two values: the DNs of the users who are members of this group.

The arrows (Viewing and Modifying a Record)to the left of the DNs are links pointing to the records of those users. If you click on the link it will load a page similar to this one that allows you to edit the record for that DN.

On the other side of the member DN fields are icons that look like a directory with a magnifying class (Viewing and Modifying a Record). Clicking on this will allow you to navigate the directory tree to find another DN to place in this field.

We will look at that dialog in just a moment. But first, we will look into adding a new group member to our group by adding a new attribute value.

Looking at the member section of the record display, we can add a new member by clicking on the add value link. This will bring up an attribute editing screen:

Viewing and Modifying a Record

The attribute editing screen is used to add a new attribute to an existing record. At the top of the screen, we can see some basic information about what attribute (member) we are adding to which record (cn=Admins).

Next, the attribute editor lists the existing values of the attribute (since this group already has two members). Finally, there is a single-text input box to allow us to enter a new member.

phpLDAPadmin examines the schema for this attribute and displays the schema description as well as a human-readable description of the syntax.

Also, since the value of this field is a DN, the find icon (the folder image with the magnifying glass) appears on the right side. We can click that icon to bring up the find dialog, and in that window we can navigate the directory information tree in search of the DN we want to add. This is what it will look like:

Viewing and Modifying a Record

Clicking on a plus sign (+) icon will expand that branch of the tree, while clicking on the DN itself will insert that DN into the field on the attribute editing screen.

Now we have the desired value in the new member field:

Viewing and Modifying a Record

Clicking the Add New Value button will provisionally add this attribute to our cn=Admin group, and return us to the record view. Our new addition is shwon on the main record view:

Viewing and Modifying a Record

Now we have three members. At the bottom of this page is a button labeled save changes. This button saves any changes made directly to fields on this page, but it is not needed to save the new group member—the user uid=barbara has already been added to the group.

Notice that the objectClass field does not allow modification of structural object classes. That is because LDAP does not allow changing an entry's structural object class. However, new object classes (auxiliary ones) can be added using the add value link.

Also, next to each object class is an information icon (Viewing and Modifying a Record)—a blue circle with a white letter i.

Clicking on this icon will load the schema viewer for that object class, which displays helpful information about an object class:

Viewing and Modifying a Record

The schema viewer shows all of the information stored in the LDAP schema, but in a much more human-friendly way than the schema files we looked at in Chapter 6. The schema viewer provides an interface to view object classes, attribute definitions, matching rules, and syntax information. In this case it is showing the groupOfNames object class. Attributes and superior object classes are linked which makes it much easier to navigate through the schemas. Additionally, there is a Jump to an objectClass drop-down list that provides a fast way to look at some of the other object classes.

New records can be added from many points in phpLDAPadmin. Anywhere there is a star icon (Adding a New Record), it denotes a position where a new subordinate record can be added.

Let's add a simple user account. To do this we will use the tree view in the left-hand navigation pane to locate the ou=Users branch:

Adding a New Record

Clicking on the star icon (Create new entry here) will load the record creation view into the main frame. From here we can begin defining our new user's entry.

The first thing to do is select a structural object class for our new user. phpLDAPadmin gives us a list to choose from:

Adding a New Record

The phpLDAPadmin system has a number of pre-defined templates for adding new entries but our LDAP server is not configured with all of the object classes that phpLDAPadmin supports. (Many of these schemas are defined, though, in the /etc/ldap/schemas/ directory.)

Attempting to add a User Account (which uses the posixUser object class, as defined in nis.schema) will cause problems when you try to create the user.

Those that are defined in phpLDAPadmin but are disabled in the template definition are marked with a white arrow on a black circle; they cannot be selected.

We want to create a new inetOrgPerson object. Since there is no pre-defined template for an inetOrgPerson, we will use the Custom template.

The first thing to do is create the DN and decide on a structural object class:

Adding a New Record

Our new user's UID will be mary and, as always, we will be using uid as the attribute in the RDN. The user will be in the ou=Users organizational unit. And we want to select inetOrgPerson (and person and organizationalPerson) from the list of object classes. Clicking Proceed >> will bring us to the next screen, where we can fill out a number of attribute values. Here is the next screen:

Adding a New Record

The required attributes are at the top of the form. After that, there is a section for selecting multiple optional attributes and giving them values. If you add a userPassword value here, it will be properly encrypted and stored on the directory server.

Scrolling to the bottom of this page there is a button labeled Create Object. Clicking that will perform an LDAP add operation on the directory server.

Once the new user is created phpLDAPadmin will display the entry.

Other templates streamline this process by automatically selecting the correct object classes and narrowing down the available attributes to just those used most often.

The last task we are going to look at with phpLDAPadmin is searching. phpLDAPadmin comes with a set of searching utilities that can be used to find information in the directory information tree.

To get to the search screen, click on search in the left-hand navigation frame. This will take you to the basic search screen:

Searching with phpLDAPadmin

Here, we will search for any entries whose UID starts with the string ma. Pressing the Search button will execute the search, which, for our directory, returns four records:

Searching with phpLDAPadmin

This returned all of the users who had a UID that starts with ma. Note that, by default, the search will check all available directory contexts. That might mean that one directory information tree will have zero search results and another may have a host of matches.

Sometimes it is nice to have more control over the LDAP search though. Clicking the Advanced Search Form link at the top of the simple search screen will load a search screen with more options:

Searching with phpLDAPadmin

This allows us to explicitly set the base DN, the scope, and the search filter, as well as specify a list of attributes that we want returned. In short, this search form contains the fields we are accustomed to seeing in other LDAP applications, like the ldapsearch command-line client.

This too will return a list of items matching our specification.

The third search option is Predefined Searches. This tool is especially helpful for running searches with the same parameters time after time.

The searches are predefined at the bottom of the config.php file in the /etc/phpldapadmin/ directory. The predefined search section begins like this:

The first line sets up a query counter and the second line creates a new array of queries. We are going to add configuration directives to the $queries array.

A search definition looks like this:

Each line adds a new name/value pair to the first slot in the $queries array (remember, $q is 0, which indicates the first slot of the array). By now, the format of such a filter ought to look pretty familiar:

If we were to create a second filter, we would first increment the $q variable, and then define a new set of parameters:

The line $q++ changes the value of $q from 0 to 1, putting the next five parameters in the next indexed slot of the $queries array.

Once we have defined the filters and saved the file, we are ready to test them out. There is no need to restart Apache or SLAPD; phpLDAPadmin reads its configuration file with every new request, and will pick up our changes immediately.

Here is the screen for Predefined Searches:

Searching with phpLDAPadmin

With the predefined search, all we must do to run it is select the desired search from the drop down list at the top of the page and press the Search button. Since the filter is stored in the configuration file, phpLDAPadmin doesn't need any additional information from us.

We've now looked at the main features of phpLDAPadmin, a well-developed tool for managing an LDAP directory through a web interface.

phpLDAPadmin is not the only Open Source program for managing directory servers. There are standard desktop tools like GQ (http://gq-project.org), and dozens of other web-based LDAP tools. There are also plugins to bring LDAP support to other popular web-based applications (like Squirrelmail, Joomla, and OpenCms).

There are also tools available to bring LDAP services to other authentication tools. For example, the libpam-ldap package provides PAM (Pluggable Authentication Modules) with the capabilities for performing LDAP lookups. And saslauthd, an SASL daemon that provides authentication services, can also be configured to connect to an LDAP server for authentication purposes.

Finally, there are a whole host of DNS servers, mail servers, file servers, and other packages that can be configured to use LDAP to store and retrieve information, particularly authentication information.