Paranoid Penguin - Authenticate with LDAP, Part III
For the past couple of months in the Paranoid Penguin column, we've been building an LDAP server. We've installed OpenLDAP; configured slapd, the server dæmon; made TLS encryption work; and created our first LDAP record, a root organization entry. Now, it's time to add some users and start using our server for authenticating IMAP sessions.
The first step in creating an LDAP user database is to decide on a directory structure, including whether to group users and other entities or use a completely flat structure. If your LDAP database is strictly an on-line address book or authentication server, a flat database may suffice. In that case, your users' Distinguished Names (DNs) should look like this: dn=Mick Bauer,dc=wiremonkeys,dc=org.
If, however, your database contains information not only about individual users but also records for organizational subgroups or departments, for computers on your network and so on, you'll probably want to use a more sophisticated directory tree structure. There are a variety of ways to do this. One is by using domainComponent (dc) fields to create subdomains of your domain name, regardless of whether these actually exist in DNS. The method looks like dn=Bick Mauer,dc=engineering,dc=wiremonkeys,dc=org. Another is to use organizationalUnit objects in the same way, for example, dn=Dick Lauer,ou=engineering,dc=wiremonkeys,dc=org.
In order to keep this discussion simple, I use a flat database for the rest of the article; I leave it to you to determine whether and how to structure an LDAP database that best meets your particular LDAP needs. The documentation found at www.openldap.org and included with OpenLDAP software provides ample examples.
Another decision you need to make is which LDAP attributes you want to include for each record. Last month, I described how these are grouped and interrelated in schemas. You may recall that the schemas you specify, or include, in /etc/openldap/slapd.conf determine which attributes are available for you to use in records.
In addition to including schema in /etc/openldap/slapd.conf, in each record you create you need to use objectClass statements to associate the appropriate schemas with each user. Again, as discussed last time, the schema files in /etc/openldap/schema determine which schema support which attributes, and within a given schema, which object classes to which those attributes apply.
Suppose you intend to use your LDAP server to authenticate IMAP connections. The essential LDAP attributes for this purpose are uid and userPassword. This also holds true for any other application that authenticates to LDAP using the Bind method, in which the authenticating service simply attempts to bind to the LDAP server using the user name and password supplied by the user. If the bind succeeds, authentication is judged successful, and the LDAP connection is closed.
One way to determine which schema and object classes provide uid and userPassword is to grep the contents of /etc/openldap/schema for the strings uid and userPassword, note which files contain them and then manually parse those files to find the object classes that contain those attributes in MUST() or MAY() statements. If I do this for uid on a Red Hat 7.3 system running OpenLDAP 2.0, I find that the files core.schema, cosine.schema, inetorgperson.schema, nis.schema and openldap.schema contain references to the uid attribute.
Quick scans of these files (using less) tell me the following: core.schema's object uidObject requires uid; cosine.schema's only reference to the attribute uid is commented out and can be disregarded; inetorgperson.schema contains an object class, inetOrgPerson, that supports uid as an optional attribute; nis.schema contains two object classes, posixAccount and shadowAccount, both of which require uid; and openldap.schema's object class OpenLDAPperson also requires uid.
Luckily, there's a much faster way to determine the same information. The gq LDAP tool allows you to browse all supported attributes in all supported schema on your LDAP server. Figure 1 is a screenshot illustrating my LDAP server's support for uid, according to gq.
The Used in objectclasses box in Figure 1 tells us that the selected attribute, uid, appears in the object classes uidObject, posixAccount, shadowAccount and inetOrgPerson, all of which we identified earlier using grep. The object class OpenLDAPperson does not appear in the gq screen, because the LDAP server in question doesn't have an include statement in its /etc/openldap/slapd.conf file for the file openldap.schema. When in doubt, you should include schema you're not sure you need. After you settle on an LDAP record format, you can always un-include schema that don't contain object classes you need.
All this probably sounds like a lot of trouble and indeed it can be, but it's extremely important to be able to create records that contain the kinds of information pertinent to your LDAP needs. Because LDAP is so flexible, figuring out precisely how to assemble that information in the form of attributes can take some tinkering.
- August 2015 Issue of Linux Journal: Programming
- Django Models and Migrations
- Hacking a Safe with Bash
- Secure Server Deployments in Hostile Territory, Part II
- The Controversy Behind Canonical's Intellectual Property Policy
- Huge Package Overhaul for Debian and Ubuntu
- Shashlik - a Tasty New Android Simulator
- KDE Reveals Plasma Mobile
- Embed Linux in Monitoring and Control Systems
- diff -u: What's New in Kernel Development