An Open Access Peon

29 March 2010

slapd configuration hints

I run an OpenLDAP instance to provide common login credentials for Subversion and Trac.

OpenLDAP is one of those tools that can be nightmarish to get working. LDAP may be 'lightweight' but when put in a stack of browser-web server-LDAP it can be very tricky to work out what's going wrong and where. I spent a weekend fruitlessly trying to debug Apache auth when what I needed to do was stop/start rather than restart (stupid I know).

In OpenLDAP 2.4 the configuration is now moved from a standard "slapd.conf" to LDIF configuration files (in Ubuntu under /etc/ldap/slapd.d/). These can be changed directly or updated via a ldapmodify/ldapadd.

You can add configuration files via the ldapi interface:

sudo ldapmodify -c -Y EXTERNAL -H ldapi:/// -f FILENAME.LDIF

Beware that if you add a configuration that breaks slapd it will shut down right after you add the configuration. So it's a good idea to backup /etc/ldap/slapd.d/ before making any untested changes (restore/start slapd).

A quick example for querying the LDAP server (note: -ZZ requires TLS, omit this for unsecured connections):

ldapsearch -ZZ -b dc=eprints,dc=org -h localhost -v -D cn=USERNAME,ou=people,dc=eprints,dc=org -w PASSWORD

To start slapd in debugging/console mode do (see the OpenLDAP documentation for values for the -d argument):

slapd -h 'ldap:/// ldaps:/// ldapi:///' -F /etc/ldap/slapd.d/ -d 16383

If you start slapd as root it will write its configuration files as root, so be careful to restore permissions on /etc/ldap/slapd.d/ back to openldap:openldap. If slapd starts as root but not from init.d it may be due to permissions problems (e.g. can't read a certificate file).

I found it difficult to find a working example of creating a slapd database. Here's what I used to create an HDB-based database (paths are Ubuntu):

# Load modules for database type
dn: cn=module{0},cn=config
objectClass: olcModuleList
cn: module{0}
olcModulePath: /usr/lib/ldap
olcModuleLoad: {0}back_hdb

# Create directory database
dn: olcDatabase={1}hdb,cn=config
objectClass: olcDatabaseConfig
objectClass: olcHdbConfig
olcDatabase: {1}hdb
olcDbDirectory: /var/lib/ldap
olcSuffix: dc=eprints,dc=org
olcRootDN: cn=admin,dc=eprints,dc=org
## FIXME below!
olcRootPW: xxx
olcLastMod: TRUE
olcDbCheckpoint: 512 30
olcDbConfig: {0}set_cachesize 0 4194304 0
olcDbConfig: {1}set_lk_max_objects 2048
olcDbConfig: {2}set_lk_max_locks 2048
olcDbConfig: {3}set_lk_max_lockers 2048
olcDbIndex: uid pres,eq
olcDbIndex: cn,sn,mail pres,eq,approx,sub
olcDbIndex: objectClass eq

Translating permissions from slapd.conf to LDIF is relatively easy. If, like me, you need a few tries at getting this write use this as a template (ldapmodify as above will replace *all* existing olcAccess lines):

# Set up permissions on dc=eprints,dc=org
dn: olcDatabase={1}hdb,cn=config
changetype: modify
replace: olcAccess
olcAccess: {0}to dn.base=""
by * read
olcAccess: {1}to dn.base="cn=Subschema"
by * read
olcAccess: {2}to dn.subtree="ou=people,dc=eprints,dc=org"
by group/groupOfUniqueNames/uniqueMember="cn=superusers,ou=groups,dc=eprints,dc=org" write
by self write
by users auth
by anonymous auth
olcAccess: {3}to *
by * none

Your permissions will likely need to be very different to those given here (which I've abbreviated anyway). Because I'm using apache mod_authz_ldap I have to provide a two-stage authentication, which requires having a 'superuser' account that can search for the relevant cn entry before performing the user authentication.

I hope this saves somebody a headache!