I set up an LDAP server to manage my email login password. I then promptly forgot how I set it up. This is the story of how I recovered it, mostly for my personal future use.
The best reference for this is the OpenLDAP administration guide.
An LDAP directory is structured as a tree of entries. Each entry includes:
- A “distinguished name,” or DN, that uniquely identifies the entry, as described in greater detail below
- One or more attributes, each of which is a key-value pair
- An objectClass, identified in one of the attributes, which specifies the structure of the entry (e.g., what attributes are required and permitted)
- A parent entry (unless it is the top-level entry in the tree)
The distinguished name (DN) is structured as a list of key-value pairs, joined by an equals sign, the list being joined by commas (e.g., ou=people,dc=sbf5,dc=com). The first key=value pair is the “relative distinguished name” (RDN) and must be unique among all sibling entries (that is, children of the parent entry). The rest of the DN is simply the DN of the parent entry. The RDN must correspond to an attribute of the entry itself.
Generally, there are two main trees in an OpenLDAP server: the cn=config tree and the main data tree (dc=sbf5,dc=com for me). The config tree maintains data specifying the structure of the directory and various options.
- dn: Distinguished name
- dc: Domain component (part of a domain name)
- ou: Organizational unit
Authenticating to the Directory
In order to perform any commands, I need to properly authenticate to the LDAP directory.
The system root account has privileges to read and modify the cn=config tree. Authentication to this tree is through the SASL EXTERNAL mechanism, which grants authorization equal to the calling Unix account. This mechanism can only be used with the Unix IPC (ldapi://) protocol. The relevant options for this are -Y EXTERNAL -H ldapi:///.
The root account for the main data tree has privileges to modify the data tree. It is identified under the DN of the attribute olcRootDN of the relevant olcDatabase. The easy way to find it is:
ldapsearch -Y EXTERNAL -H ldapi:/// -b cn=config '(olcRootDN=*)'
The password is identified by the olcRootPW attribute. Since I will probably forget the password every time I need it again, it’s easiest to just change it:
% slappasswd # Generate a password hash % ldapmodify -Y EXTERNAL -H ldapi:/// # Now type the following lines on STDIN dn: [whatever the DN of the olcDatabase is] changetype: modify replace: olcRootPW olcRootPW: [the generated hash] -
To authenticate as a user using the LDAP simple authentication method, pass the -x option. Alone, this will log in anonymously. To log in as a user, pass the -D [user-dn] and -W options.
Reading the Database
The ldapsearch command searches the LDAP directory for matching entries. The form of the command is ldapsearch [auth-options] -b [search-base] [query] [fields-to-return] where:
- [auth-options] are the authentication options described in the authentication section
- [search-base] is the DN of the entry to begin searching from (i.e., the sub-entries will be searched)
- [query] is a search query, generally formatted as ([attribute-name]=[desired-value]), the desired value being a glob-like match using asterisks
- [fields-to-return] are optional arguments specifying attributes to include in the results; omitting them means all attributes are returned
More on the Search Query Format
The search query for ldapsearch is based on RFC 4515. In short, it is composed of a series of search terms, each looking like ([attribute-name]=[desired-value]), that is, an attribute to match, an equals sign, and a match pattern (that can include asterisks), all surrounded by parentheses.
The boolean operators are all done by prefix. The AND operator is expressed as (&[search-terms]*), that is, an ampersand followed by several (also parenthesized) search terms, all surrounded by parentheses. The OR and NOT operators are similar, but with the ampersand changed to a pipe symbol or exclamation point (and, for NOT, only one search term may be listed).
There are also these search extension functions, but I don’t think I’ll be using any of those for now.
Changing a User Password
The ldappasswd command can be used to change a user’s password. To do so, the user must authenticate to the database as described above (with the -x and other options). The -S option may be used so that the user is prompted for the new password. Otherwise, the server will randomly generate one.
Modifying an Entry
To modify an entry, it is necessary to first have the proper authorization credentials. This will probably be the root account for the data tree, as described above.
Next, make an LDIF file having the form:
dn: [the DN of the entry being modified] changetype: modify [replace, add, or delete]: [attribute-name] [attribute-name]: [new value] - [Repeat the last three lines for all modifications]
The [new value] may be omitted for deletions, or specified if there are multiple instances of the attribute and only one is to be deleted.
Then enter the command ldapmodify [auth-options] < [ldif-file] to execute the command.