<< August 2013 | Home | October 2013 >>

Opening LDAP

This week's fun with LDAP

The mission: get LDAP running, and authenticate both system- and non-system users for a variety of services. A quick count gave:

  • SMTP auth (via SASL, I think)
  • IMAP auth
  • DAV, Davical & various SVNs
  • Owncloud
  • Pebble (blog server)
  • JIRA
  • Jenkins
  • Sonar
  • OpenVPN

Members should be in corresponding groups to gain access to a service. The box itself should still use PAM/passwd, and not authorize against LDAP. Passwords are stored as hashes in LDAP; ldappasswd can be used to (re)set it.

Installing OpenLDAP revealed that most of the slapd-config is now stored…in LDAP itself, so instead of `vi` for configuration you'll have to use LDIF; I'd recommend Apache Directory Studio.

Debian's "migrationtools"-package provides a handful of Perl scripts like "migrate_base.pl", which will chew through your passwd and generate a sensible LDIF script.

First catch: This script will give you entries of objectClasses account/posixAccount -- a day later we will find out that we actually want inetOrgPerson (which is incompatible with "account"): that's a class that will actually give you separate first name/last name (givenName & sn), and the mail-attribute for non-system-users. While my initial test with Sonar worked nicely (it just needs to lookup a uid, check the password, and render the full name from cn), JIRA has higher requirements.

I was hoping to get away with "account/posixAccount" for system users, and inetOrgPerson for the others, but either I need to "mix in" the additionally required attributes for JIRA, or change all "posixAccount"s to inetOrgPerson. Ick. Now although all system I looked at allow you to define a filter for authentication (which we can set up to look for uid in either account or inetOrgPerson), I don't see how to get the missing attributes into the "account"s.

For future reference, Redmine will be happy with posixAccount.

extensibleObject to the rescue! It seems you can just slap objectClass:extensibleObject onto an account and get all the missing required fields.

Specifically, we additionally require sn,givenName,mail.

Second catch: Using the memberof-filter for group access requires reconfiguring slapd with the additional module: Fortunately Serverfault provides the info already for the new-style slapd-configuration via cn=config! I haven't managed to install the overlay for groupOfUniqueNames yet, so we're stuck with groupOfNames -- I can't get ldapmodify to work on cn=config, and there's no slapmodify, only slapadd which now no longer works.


Now JIRA not only has a User Object Filter (defaults to "(objectclass=inetorgperson)", we'll use "(*(|(objectclass=inetorgperson)(objectclass=account))(memberof=cn=sonar,ou=Group,dc=foldr,dc=org))"), but also needs the "User Object Class". Since we expect different types, set it to "*".

JIRA's Create on First Login will nuke your group-settings, if you happened to have an internal account that now gets turned into an LDAP-account; you'll only get the default groups.

Do NOT lock yourself out of JIRA. Keep an internal JIRA user directory with a super-users who isn't also in LDAP, seriously. (Stop slapd if you have trouble authenticating against the internal directory.)


a2enmod authnz_ldap Limitation: You can't have auth_digest with LDAP, since the password is hashed. So SSL it is.

After that, I wasted good part of the afternoon in figuring out that for my use-case (proxy authentication) I need to send a Proxy-Authorization-header instead of the plain "Authorization: Basic" :-/ That was a painful waste of time, since neither my desktop nor my Android easily allowed me to try out CONNECT, and I had to resort to telnet.

Next problem: we don't serve SSL on svn.foldr.org. Which brings us back to RIPE allocations.