What is LDAP?

“The Lightweight Directory Access Protocol (LDAP) is an open, vendor-neutral, industry standard application protocol for accessing and maintaining distributed directory information services over an Internet Protocol (IP) network."

This is a guide for a common integration of syncing users and groups between LDAP and Drupal 7.

What We Need:

* An LDAP server for testing.
Note: Best practices dictate that your Drupal instance’s user credentials come from and are managed by the LDAP server.
If you don’t have your own LDAP server, here’s a working public server (Open LDAP) you can use to test your configuration:

  • Server: ldap.forumsys.com
  • Port: 389
  • Bind DN: cn=read-only-admin,dc=example,dc=com
  • Bind Password: password
  • Individual users are represented with: uid
  • Groups are represented with: ou
  • All accounts except nogroup and test have an email address associated with them: @username@ldap.forumsys.com

*A running Drupal instance with the following modules enabled:

*Apache Directory Studio - if you’re operating off of your own server, you will likely need some method of navigating through the LDAP directory and dialing down to specific information, such as organization and labeling parameters.

Getting Started:

Before we hop into our Drupal instance and start the LDAP configuration, let’s take a look at the LDAP server and make sure that we can connect to it and identify some essential pieces of information - I’ll be using Apache Directory Studio. We need to enter the hostname, port, bind DN, and bind password (use simple authentication). Depending on your server's configuration, you'll want to make note of how groups (ou) and users (uid) are categorized. On the test server, we have three primary groups (chemists, mathematicians and scientists) and fouteen users. Take a look at the screenshots below to see how our test server is configured.

 


Now it’s time to enable the new modules we committed, so let’s head over to our Drupal instance make our way to Modules.

Once all that's done, we’re ready to start configuring the LDAP module. Let’s navigate over to: /admin/config/people/ldap (example: dev-your-site-name.com/admin/config/people/ldap or, from within Drupal, click Configuration at the top of the navigation bar, and then, in the upper-left section, People, select LDAP Configuration. We'll continue the configuration in our next post, please stay tuned.

LDAP Module Configuration - /admin/config/people/ldap

There are seven sections in the LDAP module, let’s walk through the settings for each one (based on the LDAP settings we looked at earlier):

  1. Settings (no settings need to be changed)
  2. Servers
  3. User
  4. Authentication
  5. Authorization
  6. Queries
  7. Help

Servers - let's start by selecting Add LDAP Server Configuration, and here we'll define our various Connection Settings - note, these are based on the attributes that we obtained from the LDAP server earlier. If you're using the test server provided, just follow along. Name your server, define the LDAP Server Type as Open LDAP, the LDAP Server will contain the server address (we're using ldap.forumsys.com) and the Port is 389.

Our Binding Method is Service Account Bind, and our DN is cn=read-only-admin,dc=example,dc=com. Our password is...well, password.

Within Base DNs for LDAP users, groups, and other entries, we're going to use the high-level dc=example,dc=com - that way we get all of the groups and their users. Next we have to define some basic attributes, the AuthName attribute is uid and the Email attribute is mail.

Within LDAP Group Configuration we need to define the Name of Group Object Class, which is ou. Because we're using nested groups, select the checkbox for Nested groups are used in my LDAP. For LDAP Group Entry Attribute Holding User's DN, CN, etc. we will once again use uid, and for User attribute held in "LDAP Group Entry Attribute Holding..." we're going to use cn.

Save the settings for Servers and we'll move on to User momentarily - let's run the test function and make sure that our Drupal instance can communicate with our LDAP server.

Looks good. Make sure to enable the server before moving on.

 

For How to resolve LDAP conflicts with manually created Drupal accounts (e.g. admin on Drupal + admin on the LDAP server), select Reject manual creation of Drupal accounts that conflict with LDAP Accounts... and be sure to select the server settings for LDAP that we created within the module earlier, in our case it's myldap. Within Drupal Account Provisioning Events I prefer to select both Create or Synch... settings in order to keep user changes consistent on both systems (i.e. Jane Doe changes her password in one place instead of several).

Existing Drupal User Account Conflict - select Associate Drupal account with the LDAP entry..., and for Application of Drupal Account settings to LDAP Authenticated Users select Account creation settings...do not affect "LDAP Associated" Drupal accounts. Please note that I prefer to avoid deleting accounts whenever possible, so under Action to perform on Drupal account that no longer have a corresponding LDAP entry, I select Perform no action, but email list of orphaned accounts. It would make plenty of sense for others to select Disable the account and keep its content.

In our example, I select None under LDAP Servers to Provision LDAP Entries on because I don't want our Drupal instance committing changes to the LDAP server.

On to the Authentication section of the module - the settings here are pretty straightforward and it's mostly the defaults. Be sure to select Mixed mode in the Allowable Authentications and that our server is selected within Authentication LDAP Server Configurations.

For the entire Email section, I'd only suggest the following alterations: Email Template Handling - select Use the template if no email address was provided by the LDAP server, and beneath that, the template is: @username@ldap.forumsys.com, you'll want this for any users on the LDAP server that don't have an associated email address. Best practices require that users have an email address associated with an account in any content management system, so configuring the module to implement a correctly structured email address based on the username and proper domain name (@ldap.forumsys.com, for example) is likely appropriate.

 

Authorization, Queries & Help are the last sections of the LDAP module, but we won't be using Authorization or Help. We'll most definitely need Queries later on - the next part of this guide, actually.

Writing an LDAP Query - /admin/config/people/ldap/query/add

For configuration purposes we're going to pull all users from the LDAP server and as long as they have a valid username and email address, they’ll populate in the system (using the test server I provided earlier, two will be ignored).

  • For our base DN’s to query we’re going to enter the following:  dc=example,dc=com
  • Our filter is going to be any user (no groups) that are designated a user:  (objectClass=person)
  • Because the LDAP server we’re using isn’t particularly intricate in its configuration, I’m going to opt to pull all attributes, so I don’t need to enter anything in the section Attributes to return.
     

Please note that Base DN's to search in query and Filter are what drive our query and are crucial in this configuration to adequately pull the data we need from our LDAP server (DN's, uid's, email addresses, etc.) As I indicated earlier - we're using an open-ended, generic query for our test server because we're simply pulling all users and their attributes from the LDAP test server to our Drupal instance.

Now it's time to test our query.

Success! As you can see, our query returns all of the users from the LDAP server - from their DNs to their email addresses.

Advanced LDAP Queries

For a more comprehensive guide on writing your own queries please see the following link:  https://www.google.com/support/enterprise/static/gapps/docs/admin/en/gads/admin/ldap.5.4.html

Adding Fields to User Settings - /admin/config/people/accounts/fields

This section is pretty straight-forward, we’re going to add some fields for use in our LDAP Feed - this part 1 of where we link fields in Drupal to the ID’s we obtained from the LDAP server earlier.

We’re going to make two new fields based on our LDAP server’s configuration: Full Name and DN Field (Distinguished Name Field). Both are Field Type = Text and the Widget’s = Text Area. You don't need to make any specific changes to the field itself during the creation process, we just need two text fields that we'll refer to during the creation of our feed in the next part of the walkthrough. Take a look below if you're unfamiliar with creating new fields within Drupal.

 

That's all for now - our next and final entry will detail the creation & automation of a feed (this is how we'll set Drupal to execute our query and pull in new users and updated user passwords automatically.)

Creating an LDAP Feed - /admin/structure/feeds/create

To begin, name your feed and click Create to continue. There are four sections to complete:

  1. Basic Settings (leave Periodic Import OFF until you’ve successfully imported your LDAP server’s users using the query we created earlier - this is detailed in the next section, LDAP Import)
  2. Fetcher (we will be using LDAP Query Fetcher instead of the Drupal User LDAP Entry Fetcher)
  3. Parser
  4. Processor

There’s actually very well-written Drupal community documentation for this section, please see the following link for a generic setup - our setup is slightly different:  https://www.drupal.org/node/1300812/
 

Let's begin with Basic settings - we need to name our feed, set Attach to content type to Use standalone form, and again - leave Periodic import OFF.

Next, we're going to change Fetcher and select LDAP Query Fetcher.

Now, withing Fetcher settings you'll want to select the LDAP Query we created earlier ("pull ldap users").

In the change section of Parser select LDAP Entry Parser for Feeds.

Within the Processor section we need to select User processor (after all, our intent is to pull users and their attributes from the LDAP server.)

In the Settings for User processor section, we're going to select Update existing users, Plain text for formatting, and set the users to Active. Of course this all depends on your setup's specific needs - some of you may want to Replace existing users, or you'll want the users imported and updated but blocked in order to avoid giving them access to the system during testing.

Last but not least, in Mapping for User processor we need to define the elements/attributes that we're using, as these will define the Drupal users that we create based on the LDAP server's users. In our example we want to bring over the Full Name (cn) that we defined earlier, the User Name (sn), and the Email address (mail). We also want to make sure that we mark these as Unique. Now it's time to test our feed!

 

LDAP Import - /import

From the Import page we’re going to select the feed we created earlier (it should be the first availabe option in the list) and it will take us to a page where we can test our LDAP query - simply select the query we created earlier ("ldap feed") and hit import. As long as the accounts in question have valid usernames and email addresses they should all import without issue. If there’s a problem during the import Drupal will note success/failure and there are sections to assist you in troubleshooting - the Log tab identifies what failed and why, and the Delete Items tab allows you to remove all users generated via the import (in case you need to try again - which is likely if you have a more intricate query executing).

 


Import Automation - /admin/structure/feeds

Let’s head back to the feed we created earlier, select Edit and under the Basic Settings section on the left, select Settings. Simply set Periodic Import to Every 15 minutes and Save, thereby setting your feed to import any users created within the LDAP server automatically.
 

Congratulations! You've written a query that recurringly executes via feed and further changes to your LDAP user and group base will be affected in Drupal.