Written by Ben Chavet (ben [at] horde [dot] org)
This document is intended to help administrators set up a new Horde 3 installation using a new LDAP directory. Installing and configuring an LDAP directory is outside the scope of this document. It is assumed that you have a working LDAP directory, and that we are adding a new branch to it.
Please feel free to fill in any gaps or clarify any existing information presented here.
For starters, this will be a running progress of what I am doing to set up a working Horde installation using LDAP wherever possible.
The following standards and assumptions are used throughout this document. Please adjust accordingly to your situation.
The following shows the LDAP directory structure we are using.
dc=example,dc=com |-- ou=DSA | `-- cn=horde `-- ou=horde |-- ou=users | `--cn=admin `-- ou=groups
This is certainly not the only, or even necessarily the "correct", directory structure to use. Horde is not picky, and can be configured to use any structure you choose. We chose this particular structure in order to leave our LDAP directory open for non-horde use in the future. If you choose not to use this structure, be sure to modify the examples to fit your directory structure.
The following schemas must be included in your LDAP configuration.
include /etc/openldap/schema/core.schema include /etc/openldap/schema/inetorgperson.schema include /etc/openldap/schema/nis.schema
And the following schemas are optional.
include /etc/openldap/schema/rfc2739.schema include /etc/openldap/schema/horde.schema
rfc2739.schema is used by turba to store calendar information, and can be found in horde/turba/scripts/ldap/rfc2739.schema. horde.schema is used by horde to store user preferences, and can be found in horde/scripts/ldap/horde.schema. If you intend to use either of these features, copy the respective schema file to /etc/openldap/schema.
Put the following in a file named horde.ldif. Don't worry about the password values just yet, we'll be changing them in a minute. Also, make sure to adjust the dn values for your directory.
dn: ou=DSA,dc=example,dc=com objectclass: organizationalUnit ou: DSA dn: cn=horde,ou=DSA,dc=example,dc=com objectclass: organizationalRole objectClass: top objectClass: simpleSecurityObject userPassword: superSecretPassword cn: horde dn: ou=horde,dc=example,dc=com objectclass: organizationalUnit ou: horde dn: ou=users,ou=horde,dc=example,dc=com objectclass: organizationalUnit ou: horde dn: uid=admin,ou=users,ou=horde,dc=example,dc=com objectclass: shadowaccount objectclass: inetorgperson uid: admin cn: Administrator sn: Administrator userpassword: supersecretpassword dn: ou=groups,ou=horde,dc=example,dc=com objectclass: organizationalUnit ou: horde
Then, run the following command to import the entries into the LDAP directory. You will be prompted for the LDAP root password.
ldapadd -x -h localhost -D "cn=root,dc=example,dc=com" -f horde.ldif -W
The new accounts that we just created have generic passwords, so we need to set them to something reasonable. Run the following two commands to set the passwords. Be sure to replace secretpassword with the real passwords you want to have set.
Set the password for cn=horde,ou=DSA,dc=example,dc=com:
ldappasswd -x -h localhost -D "cn=root,dc=example,dc=com" -s secretpassword -W cn=horde,ou=DSA,dc=example,dc=com
Set the password for uid=admin,ou=users,ou=horde,dc=example,dc=com:
ldappasswd -x -h localhost -D "cn=root,dc=example,dc=com" -s secretpassword -W uid=admin,ou=users,ou=horde,dc=example,dc=com
These are the minimum directory permissions required for horde to work properly.
### ou=DSA Permissions ### access to dn.children="ou=DSA,dc=example,dc=com" attrs=userPassword by self write by anonymous auth by * none access to dn.children="ou=DSA,dc=example,dc=com" by self read by * none ### ou=horde Permissions ### access to dn.children="ou=horde,dc=example,dc=com" attrs=userPassword by dn="cn=horde,ou=DSA,dc=example,dc=com" write by self write by anonymous auth by * none access to dn="ou=horde,dc=example,dc=com" by dn="cn=horde,ou=DSA,dc=example,dc=com" write by self read by * none
In order to ensure proper user management, we have to put a _horde_hook_authldap function in horde/config/hooks.php. There is an example function in horde/config/hooks.php.dist which we will use as a base for our function.
if (!function_exists('_horde_hook_authldap')) { function _horde_hook_authldap($userID, $credentials = null) { $entry['dn'] = 'uid=' . $userID . ',ou=horde,dc=example,dc=com'; if (isset($credentials) && isset($credentials['user_fullname'])) { $entry['cn'] = $credentials['user_fullname']; } else { $entry['cn'] = $userID; } $entry['sn'] = $userID; $entry['objectclass'][0] = 'top'; $entry['objectclass'][1] = 'uidobject'; $entry['objectclass'][2] = 'person'; $entry['objectclass'][3] = 'hordeperson'; $entry['uid'] = $userID; // need to check for new users (password) and edited users (user_pass_2) if (isset($credentials) && isset($credentials['password'])) { $entry['userPassword'] = '{MD5}' . base64_encode(mHash(MHASH_MD5, $credentials['password'])); } else if (isset($credentials) && isset($credentials['user_pass_2'])) { $entry['userPassword'] = '{MD5}' . base64_encode(mHash(MHASH_MD5, $credentials['user_pass_2'])); } return $entry; } }
This hook function also needs to be enabled in the horde configuration.
Storing Horde preferences in the LDAP directory adds a large number of attribute entries to every user DN. If this is something you do not want, you should look into using some other preference backend.
To use LDAP to store Horde preferences, set the preference system to use LDAP as its backend. The field values here are very simular to the Horde configuration.