Getting started with LDAP can be quite daunting. In the space of a weekend, I took myself on a bit of a crash course to learn about LDAP so that I could work on a project that needed LDAP to access an address book. Here are some of the things I learned along the way:
Some LDAP Terminology
- LDAP – Lightweight Directory Access Protocol. It’s a system for accessing a “directory” of information in a structured way
- DN – Distinguished Name. It identifies a specific entry by either a series of RDNs, or a search string, to locate that particular entry.
- RDN – Relative Distinguished Name. Basically a portion of a DN.
- CN – Common Name. This is the general purpose “name” of an entry, and is usually used as part of the DN for an entry.
- DC – Domain Component. This is also part of a DN/RDN, and is often used to define the name of your service/directory/top-level-domain.
- directory – your collection of entries that you want to access via LDAP (it’s the D in LDAP!)
- schema – the “design” of your directory. Refers to the hierarchy of entries within your directory.
- top – the “root” level entry of your schema.
- objectClass – a group of attributes, commonly used to describe a particular type of information. For example the inetOrgPerson objectClass contains a group of attributes for describing a person, with common internet-based communication methods.
- attribute – a single piece of information belonging to an entry in your directory
- LDIF – LDAP Data Interchange Format. This is a simple, text-based format used to read/write LDAP entries. It is in “attributeName: value” format, with one entry per line, so it’s very easy to read/handle on the command line or via code.
Setting Up an LDAP Server
- OpenLDAP is easy to install/configure, and is available via package managers for most common *NIX OSes.
- You need to set up your DC correctly in the slapd configuration files so that you have something to connect to.
- Run slapd in debug mode so that you can get some useful information and see what is and isn’t working while you’re figuring things out.
Custom objectClass Creation
In our case, we needed some attributes that weren’t available in any of the objectClasses that were being loaded by OpenLDAP, so we decided to create our own. OpenLDAP was loading the config files for a lot of attributes, but until they’re included in an objectClass, and that objectClass is referenced in your entry, you can’t use those attributes. Here’s what we came up with:
objectclass ( 1.1.1.1.1.1.1.1.1.1.1.1.1 NAME 'vCardPerson' SUP inetOrgPerson STRUCTURAL MAY ( additionalName $ personalTitle $ honorificSuffix $ bday $ tz $ sourceURI ) )
Basically we just created an objectClass called “vCardPerson” which inherited everything (SUP) from inetOrgPerson, then added a few optional (MAY) attributes. The 1.1.1….. is a garbage number that we made up. You’re supposed to register and get a unique number to identify every objectClass from IANA, but, well, we were working on an experimental project so we didn’t bother 🙂
Working with LDAP via PHP
- If you get an error message: “Object Class violation”, then you’re probably trying to set an attribute which isn’t available. You might need to include another objectClass (or define your own) so that you have access to that attribute.
- Connecting and Binding to an LDAP server is pretty easy once you have things set up. You will probably use something similar to this:
$ldap = ldap_connect( 'ldap://ldaphostname.com/' ); if ( $ldap ) { $bind = ldap_bind( $ldap, 'cn=admin,dc=nodomain', 'password' ); if ( !$bind ) { echo 'Failed to connect to LDAP server!'; exit; } }
- A DN should probably include a unique identifier to make life easier, ours ended up looking something like this (where uid changed for each entry):
uid=123,dc=1234,dc=nodomain
- Creating an entry (and saving it in LDAP) is as easy as creating an array and then calling a PHP function. Each of the array elements matches up to an LDAP attribute, and you just need to be sure to include an objectClass entry to define which attributes you’re using. Here’s an example (assuming you’re connected to an LDAP server via $ldap and have defined a new, unique DN via $dn):
$entry = array(); $entry['objectClass'] = array( 'top', 'person', 'organizationalPerson', 'inetOrgPerson', 'hCard' ); $entry['cn'] = array( 'Billy Bob' ); // Common Name $entry['sn'] = array( 'Bob' ); // Surname/Family Name $entry['gn'] = array( 'Billy' ); // Given Name $entry['displayName'] = array( 'BillyBob' ); // Nickname $entry['mail'] = array( 'billy@bob.com' ); // Email $entry['labeledURI'] = array( 'http://billybob.com' ); $entry['mobile'] = array( '+12345678912' ); // Mobile number if ( !ldap_add( $ldap, $dn, $entry ) ) { echo ldap_error( $ldap ); } else { echo 'Successfully added entry'; }
Hopefully I’ll be able to add to this over time as I learn some more bits and pieces with LDAP. Do you have any good pointers or explanations for how LDAP works? Please add them in the comments!
I always thought LDAP looked funny, must be all that X.500 influence 🙂
It's definitely not something I'd describe as \”elegant\” 🙂