This is a read-only archive. Find the latest Linux articles, documentation, and answers at the new!


Using LDAP for mail contacts

By Nathan Willis on May 19, 2005 (8:00:00 AM)

Share    Print    Comments   

Chances are that your email program supports LDAP among its address book options. This article will show you how to set up a basic LDAP directory for use as an address book server in your home or small office.
Many corporate users use company-wide LDAP directories to free them from manually synchronizing and updating their contacts -- a convenience that even a two-PC household could benefit from. We will start by installing and configuring OpenLDAP, the free, open-source LDAP server. It is included with virtually all full-sized Linux distributions, but if you must you can download it from

A cautionary note: technically speaking, what we call an "LDAP server" is actually an X.500 directory server, but one that speaks LDAP: the Lightweight Directory Access Protocol. Defined in RFC 2251, LDAP is a simplified version of the older DAP (I'll let you figure out what that one stands for on your own; thank me later) used for talking to X.500 gateway systems. But DAP did not run over TCP/IP and used significantly higher overhead. An LDAP server can do much more than maintain contact info directories, notably network authentication but a host of other services too.

Both for this reason and due to its pre-TCP heritage, you will come face to face with extraneous configuration options and documentation geared at enterprise-level IT shops. Feel free to stop and exclaim "if this is the lightweight protocol, I'd hate to see what it replaced" as often as necessary. The syntax is not complicated, but it is highly abbreviated and not designed to be self-explanatory. But that's what this guide is for: trimming down the distractions and getting the job done.

OpenLDAP consists of two daemons: slapd (the stand-alone LDAP daemon) and slurpd (the stand-alone LDAP update replication daemon). You only need slapd; slurpd is used for coordinating multiple LDAP servers so they cooperate in a hierarchy, much like DNS servers. Configuring slapd for fun and profit --

Slapd reads in parameters from a config file, by default at /etc/openldap/slapd.conf. We will make minimal changes to the default supplied by OpenLDAP. The first few non-comment lines are includes pointing to the .schema files that dictate what type of information our directory will hold. The Fedora package I use includes core, COSINE, inetOrgPerson and NIS schema. I commented out the NIS schema since I know I'm not interested in it, but that is optional. inetOrgPerson and COSINE define the interesting address book data that we will use, and core contains fundamental definitions, so all three of these must stay.

And they have inheritance: inetOrgPerson inherits from COSINE, which inherits from core. If you want to define additional info to track in your address book, you can add a schema that inherits from inetOrgPerson and adds the interesting parts. Since I use Mozilla Thunderbird as my email client, I downloaded a copy of the MozillaOrgPerson schema and put it in the LDAP directory with the others. There are also schema defined for Outlook and other popular email clients, though they are all just icing on the cake. inetOrgPerson gives you the basic name, address, email and phone number information.

Skip to the end of the slapd.conf file, and you will find a section labeled database definitions. Here is my example definition:

database bdb
suffix "dc=glyphography,dc=com"
rootdn "cn=AddressManager,dc=glyphography,dc=com"
rootpw NotOnYourLife
directory /var/lib/ldap/local

For database you have two basic choices: ldbm and bdb -- ldbm stores its data in LDIF (LDAP Data Interchange Format) files, bdb in binary files. Using bdb is faster.

The next line is suffix and is our first encounter with some of that abbreviation-happy LDAP syntax. Here are a few of the common abbreviations we will see again and again:

  • dn: distinguished name, the unique identifier of an entry in the database. No duplicates are allowed, so a well-planned naming scheme is required.
  • cn: common name, the regular name of a person or entry -- it's okay for two people to have the same common name (since some people do), but not the same distinguished name.
  • o: organization, be it a company name or something generic like localnetwork
  • ou: organizational unit, for a subcategory of an organization, be it family, accounting department or whatever.
  • dc: domain component, part of an Internet domain name -- in the example, has two components.

The suffix you declare here denotes the scope of this database and is where all searches. We can define multiple databases in the slapd.conf file, but they must have different suffixes. It can be a compound of two or more parts, like the example. It can be anything syntactically valid, just remember what it is! Some people use their organization as their suffix, such as "o=newsforge" or "o=MyHouse" -- the convention of using your domain name (even though it must be split up as two DC's) comes from the hierarchical origins of LDAP. If I ever decided to link my LDAP directory up with another one, they might have chosen "o=MyDirectory" but they won't have chosen my domain name. Plus, if I ever need to run a second OpenLDAP server I can define it as a sub-domain such as "dc=maui,dc=glyphography,dc=com".

The rootdn line defines the DN of the superuser account for this database. Here it is composed of a descriptive CN and the suffix of the database itself -- it is unique like all good DNs, but clearly descriptive as well. The rootpw sets a password for simple authentication.

Last but not least, the directory line specifies where the actual bdb database will be created and stored. I chose to create a new directory, /var/lib/ldap/local, instead of the default /var/lib/ldap, just to make testing less hazardous.

With slapd.conf all configured and chomping at the bit, launch it with /etc/rc.d/init.d/ldap start. You are ready to pull a few addresses out of your existing, old-fashioned address book and add them to the LDAP directory. LDIF Autopsy --

In most email clients, you can export your existing address book as an LDIF file. Almost any such client export is going to require some tweaking, so whether it is faster to create a simple LDIF file or to fix the automatically-generated one depends on how many entries you have. I for one steadfastly refuse to do things by hand even when it is far easier, and as a result I've spent some time learning the ins and outs of Mozilla's LDIF export. As with the schema, my examples come from Thunderbird, but similar steps would work for other clients.

Take a deep breath and open the newly-minted LDIF file in your editor of choice. Each address book entry has been dumped into a block of text offset from its neighbors by blank lines. They look something like this:

dn: cn=Tom Delay,
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
objectclass: mozillaAbPersonObsolete
givenName: Tom
sn: Delay
cn: Tom Delay
xmozillanickname: tommy
modifytimestamp: 0Z

The first line is the DN of the entry, which as you recall must serve as its unique key in the database. Mozilla's LDIF export creates DN's by slapping together the CN and MAIL fields from elsewhere in the entry -- presumably reasoning that any two people could share an email address or coincidentally have the same name, but not both. Regrettably OpenLDAP runs afoul of these DNs. The reason it technical, but suffice it to say that concatenating random things is not the proper way to build DNs. At the very simplest, we can substitute our database's suffix from slapd.conf and all will be well.

So to make these entries readable to OpenLDAP and thus useful for our address book, we'll have to scrub every offending DN ... and a couple of other stray fields while we're at it. Say goodbye to the objectclass: mozillaAbPersonObsolete line, the xmozillanickname line and the modifytimestamp: 0Z as well; the former two are non-standard and undefined and the latter is supposed to be automatically-generated by the database -- importing one is just begging for trouble.

The other lines in each stanza hold either internal-structure LDAP fields (like objectclass) or our contact's data. Of particular note is the objectclass: inetOrgPerson line, which points OpenLDAP to the inetOrg schema we loaded in slapd.conf. Earlier I mentioned that I used the mozillaOrgPerson schema and loaded it in slapd.conf; here is where can we tell OpenLDAP to reference it.

Fix the LDIF file with a simple Perl script, like the example listed below. There are a variety of such scripts available on the Internet since Mozilla's LDIF problems are well-studied. This one strips out the useless modifytimestamp and mozillanickname entries, substitutes a domain-based suffix in each DN, and replaces mozillaAbPersonObsolete with mozillaOrgPerson. If you don't want to bother with mozillaOrgPerson, you should remove the mozillaAbPersonObsolete altogether.

#!/usr/bin/perl -pi
#; a space-age script for polishing up Mozilla LDIF export for OpenLDAP use
s/objectclass: mozillaAbPersonObsolete/objectclass: mozillaOrgPerson/;

The modern world is filled with people that know more about Perl than I do, and there is certainly more tweaking that could be done, but for me this was sufficient. Execute the script with mycontacts.ldif. It is now ready to load into the database. First, however, we will make another LDIF file that contains no contact info but just our directory definitions:

dn: dc=glyphography,dc=com
objectclass: top
objectclass: dcObject
objectclass: organization
dc: glyphography
o: Glyphography
dn: ou=personal,dc=glyphography,dc=com
objectclass: top
objectclass: organizationalUnit
ou: personal
description: Personal Addressbook

All that these entries do is define and describe the organization referenced in the DC elements of our slapd.conf file. Notice that the DN is the same as the suffix we assigned in slapd.conf -- it is what identifies our database. You could put this info at the beginning of the mycontacts.ldif file instead, but separating it makes it easier to update the contacts. Note also that I define an OU for personal contacts -- that is just in case I want to add a second OU for work contacts and maintain them separately. Load 'em up --

So now you have a running slapd server and a pair of LDIF files: one holding your contact information and one defining your directory. From a command line, load the directory definition file first:

ldapadd -xv -D 'cn=AddressManager,dc=glyphography,dc=com" -f directory_def.ldif -W

The x flag tells the server to use simple (password) authentication and the v flag generates verbose output. After the D flag we specify the DN under which we want to make a connection -- the same root DN that we defined in slapd.conf. The W flag prompts us for the password, also from slapd.conf.

If you see error messages, check your syntax and especially double-check the formats of your DN's, as misspelled words are the biggest pitfall. When you are ready to proceed, load the contact information file in the same manner:

ldapadd -xv -D 'cn=AddressManager,dc=glyphography,dc=com" -f mycontacts.ldif -W

Again, if all goes according to plan, you will see output reporting to you as each of your contacts is added. The ldapadd command will stop on any errors, so just look at the line of output that generated the error and fix the entry in your LDIF file. It's a good idea to stop slapd, delete the database files, and restart slapd when you have to do this -- I find it makes tracking down problematic LDIF entries easier.

Now you can connect to your OpenLDAP server with your email client! In Thunderbird, open the Address Book and select New LDAP Directory from the File menu. In the hostname field, type localhost, and in the Base DN field give the suffix you chose in slapd.conf (in my example, dc=glyphography,dc=com).

LDAP is based on search queries; by default you don't see any entries in the Address Book pane in Thunderbird. To find someone, just start typing in the search box, and your results will pop up in the list below. To see everyone (or at least everyone with an email address), type in an @ sign. There is an Offline tab suggesting that you can download a copy of the entire directory, but this has never worked in any Mozilla client, so just ignore it.

This next part may come as a surprise to people, but Mozilla Thunderbird does not let you edit LDAP entries directly. There is a feature request in Bugzilla to add this functionality, but since LDAP has not historically been a "home user" feature, it has been slow coming. Since you are running your OpenLDAP server locally, however, you can edit your entries with another tool such as Luma (a nice and straightforward GUI program) or phpLDAPadmin if you happen to be running a local web server too.

You can help advance Mozilla's LDAP functionality by cast votes for the appropriate Bugzilla entries. There are three that relate to what I have described here: 86405 is the LDAP editing feature and 231965 is the offline directory-download bug. 116692 is the mozillaOrgPerson schema, which is not a bug, but more of a feature tracker -- work is ongoing, and going well. Having a well-defined LDAP schema is important to using Mozilla in enterprise environments.

Enjoy your LDAP bliss, and don't be shy about lording it over friends and coworkers still struggling with their cluttered, unsynchronized contacts. Assuming they have your email address, they can always ask you for help.

Share    Print    Comments   


on Using LDAP for mail contacts

Note: Comments are owned by the poster. We are not responsible for their content.

Thank you but...

Posted by: Anonymous Coward on May 19, 2005 09:23 PM
Great article, and was planning on implimenting this very soon into my business and personal environment.

Could you fix the link to the Mozilla schema? When clicked, it hits a 404.


Re:Thank you but...

Posted by: Anonymous Coward on May 24, 2005 07:36 AM
Could you like to the real source of the schema please. You mention schemas for other clients, I would like to grab the evolution one if it exits.


Re:Thank you but...

Posted by: Anonymous Coward on May 24, 2005 07:38 AM


Re:Thank you but...

Posted by: Anonymous Coward on June 07, 2005 11:12 AM
Author here. It's in the next to last paragraph; the bugzilla link for the schema is its official home until it gets some kind of "public" release.

I had to separately include the version attached with the article copy, however, because the schema is undergoing revision, and I wanted to ensure that what was incorporated with the article actually worked with the examples given.


Re:Thank you but...

Posted by: Joe Barr on May 20, 2005 05:53 AM
Sorry about that, should be there now.


For Debian

Posted by: Anonymous Coward on May 24, 2005 08:15 AM
for debain you need to:

apt-get install slapd


apt-get install ldap-utils

for the ldapadd command

my Your comment has too few characters per line (currently 9.3). so i am cutting and pasting random garbage here so i can post my comment lets hope it works hu?


typo in ldapadd command

Posted by: Anonymous Coward on May 24, 2005 08:21 AM



Posted by: Anonymous Coward on May 26, 2005 09:44 PM
I saw some documentation on how to create groups, but am getting some errors when I try to add people to the groups. Think you could do a write up on that?<nobr> <wbr></nobr>:)


Connect Thunderbird to Active Directory LDAP

Posted by: Anonymous Coward on April 05, 2006 11:54 PM
I managed to connect thunderbird to our Active Directory at work and I wanted to share the tips.

Keywords: active directory thunderbird LDAP AD hang connect address book addressbook

First of all, you have to gather some information.

You need to locate what is your basedn. It's locatable with Samba's net command as follows:
$ net ads info
note down the "Bind Path" value as your basedn and the "LDAP server" as your dc name.
Mine is like "dc=EXAMPLE,dc=AD" for the basedn and
COMPANY_DC as my dc.
Next in line is your binddn, think of it as a username. In my company, it's set at "" (notice the connection between what's after the @ symbol and the basedn, but it may be a coincidence).

Finally, you need to know that the port is not the normal port (eg: 389) but 3268.

Hence, in thunderbird's addressbook, do a File->New->LDAP Directory

Hostname: COMPANY_DC
Base DN: dc=example,dc=ad
Port Number: 3268
Bind DN:

And you're done! That setting also worked somewhat with the regular Port but it would hang if I modified the search query after it had already returned data.
You can also configure Thunderbird mail client to use the "global LDAP server preference for this account" to autofill the address fields when creating a new email.

Any questions should be directed at artaxerxes2 at iname dot com with the words "Thunderbird Active Directory" in the subject line.


You don't have to setup your own

Posted by: Anonymous Coward on March 05, 2007 09:17 AM
You could skip all this and use <a href="" title=""></a> for LDAP address book lookups



Posted by: Administrator on July 05, 2005 07:29 AM
Notice, that in the examples above, the entries will be added to the root of the tree, when the text seems to imply that they were meant to go in the 'personal' grouping. If that is the case, the following line in the perl script:


should be changed to:



re: using LDAP for mail contacts

Posted by: Anonymous [ip:] on December 06, 2007 05:05 AM
Your posting was a tremendous help in getting LDAP set up for me...thank you. One question though about something you touched on, and no other sites really seem to address. In an Outlook+Exchange environment, you always see the list of entries in the GAB without running a query. You noted that in Thunderbird you have to run a query to see anything. I need that list to show up without a query. Any ideas? I don't think it is happening on the client side, because I opened up an Outlook client and connected it up to my shiny new LDAP implementation, and the address book is still blank. In fact, that one doesn't even populate with a search, but I know it works because I can start typing a name on the To: line and hit Ctrl-K and it will autofill. Thanks for any assistance.


This story has been archived. Comments can no longer be posted.

Tableless layout Validate XHTML 1.0 Strict Validate CSS Powered by Xaraya