Setup an LDAP Address Book

Posted: July 9, 2007. Tags: LDAP

The goal of this exercise was to create an LDAP address book that the Gnome Evolution mail client would read and write. It took 3 days to get to the bottom of this. Getting some trivial functionality working was easy. Getting (nearly) all the Evolution contact fields to work, with security enabled on the LDAP server was much harder.

Here is the setup:

First the facts, then the details...

Used

Setup

  1. Copied evolutionperson.schema from /usr/share/evolution-data-server-1.10/ to my LDAP server /etc/openldap/schema
  2. Wrote the following slapd.conf (original comments/examples ommitted for brevity):
#
# See slapd.conf(5) for details on configuration options.
# This file should NOT be world readable.
#
include     /etc/openldap/schema/core.schema
include     /etc/openldap/schema/cosine.schema
include     /etc/openldap/schema/inetorgperson.schema
include     /etc/openldap/schema/nis.schema
include     /etc/openldap/schema/evolutionperson.schema

# 128=ALCs 256=OpStats
#loglevel   384
pidfile     /var/run/slapd.pid
argsfile    /var/run/slapd.args

#######################################################################
# Database for ombwa.org
#######################################################################

database    bdb
suffix      "dc=ombwa,dc=org"
rootdn      "cn=Manager,dc=ombwa,dc=org"
rootpw

directory   /var/lib/ldap/ombwa.org
mode        0600

#################### Access controls ####################
# Evolution queries the rootDSE and Subschema while anonymous.
access to dn=""
by * read
access to dn.exact="cn=Subschema"
by * read
# Allow auth access to users subtree.
access to dn.subtree="ou=users,dc=ombwa,dc=org"
by * auth
# Allow sam access to Sam's address book.
access to dn.subtree="ou=Sams,ou=address books,dc=ombwa,dc=org"
by dn="uid=sam,ou=users,dc=ombwa,dc=org" write
# No soup for you.
access to *
by * none

# Indices to maintain for this database
index objectClass                       eq,pres
index ou,cn,mail,surname,givenname      eq,pres,sub
index uidNumber,gidNumber,loginShell    eq,pres
index uid,memberUid                     eq,pres,sub
index nisMapName,nisMapEntry            eq,pres,sub
  1. Restarted LDAP server
  2. Setup the tree by running the following LDIF file through
ldapadd -x -D "cn=Manager,dc=ombwa,dc=org" -w -a -f ''

To be honest I did half of it with PhpLdapAdmin - you can tell those entries because of the vestigial ''top'' objectClass:

dn: dc=ombwa,dc=org
objectClass: dcObject
objectClass: organization
dc: ombwa
o: ombwa.org

dn: ou=users,dc=ombwa,dc=org
objectClass: organizationalUnit
ou: users

dn: uid=sam,ou=users,dc=ombwa,dc=org
uid: sam
userPassword::
objectClass: account
objectClass: simpleSecurityObject

dn: ou=address books,dc=ombwa,dc=org
objectClass: organizationalUnit
objectClass: top
ou: address books

dn: ou=Sams,ou=address books,dc=ombwa,dc=org
ou: Sams
objectClass: organizationalUnit
objectClass: top

Explanation

Initially whenever I started locking down the ACLs at all, Evo would grey out most or all of the fields in the contact form. Clearly it wasn't happy with the schemas that it could find on the LDAP server. Googling led me to discover the evolutionPerson objectclass, but the picture got clearer when I downloaded and examined the source:

sudo apt-get source evolutuion
sudo apt-get source evolutuion-data-server

In evolution-data-server-1.10.1/addressbook/backends/ldap/e-book-backend-ldap.c it says:

/* the objectClasses we need */
#define TOP                  "top"
#define PERSON               "person"
#define ORGANIZATIONALPERSON "organizationalPerson"
#define INETORGPERSON        "inetOrgPerson"
#define CALENTRY             "calEntry"
#define EVOLUTIONPERSON      "evolutionPerson"
#define GROUPOFNAMES         "groupOfNames"

I'm not doing calendaring yet, so I ignored calEntry. Everything but evolutionPerson was installed by default. After much Googling it turns out evolutionPerson schema is installed at with Evolution, at /usr/share/evolution-data-server-1.10/evolutionperson.schema. I copied this to my LDAP server /etc/openldap/schema and added a line for it to slapd.conf.

This still didn't help, however with the ACLs issue. After reading most of LDAP for Rocket Scientists I figured out what is going on. There is an "uber-object" called the RootDSE that contains meta-information about what the LDAP server serves. It has an object under it called Subschema that allows the caller to see all the classes the LDAP server supports. Evolution attempts to access these before authenticating, so you must have ACLs to support that. Ironically the example ACLs in the top of the slapd.conf set this up.