6.0.0-git
2024-03-29
Last Modified 2005-05-02 by ben

Using Horde with a New LDAP Directory

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 will be adding a new branch to it. Please feel free to fill in any gaps or to 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.


Document Standards

We will be using the following standards and assumptions throughout this document. Please adjust accordingly to your situation.

  • The LDAP directory is on the same machine we are installing Horde on.
    • LDAP directory security accounts are stored in ou=DSA,dc=example,dc=com, which already exists.
    • The LDAP directory does not allow anonymous binding.
    • The LDAP administrative account is cn=root,dc=example,dc=com.
    • OpenLDAP 2.1.29-1 running on a Fedora Core 2 machine is used for this example.

LDAP Directory Configuration

Required Schemas

There are a few schema files that need to be included in the slapd config file. These files are located in horde/scripts/ldap/horde.schema, and turba/scripts/ldap/rfc2739.schema. Copy these files to /etc/openldap/schema, and add these lines to the global section in /etc/openldap/slapd.conf:


include /etc/openldap/schema/horde.schema

include /etc/openldap/schema/rfc2739.schema

Then, restart slapd for these changes to take effect.

Import LDAP Entries

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: 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: uid=admin,ou=horde,dc=example,dc=com

objectclass: top

objectclass: uidobject

objectclass: person

objectclass: hordePerson

objectclass: calentry

uid: admin

cn: Administrator

sn: Administrator

userpassword: supersecretpassword

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

Set Passwords for New Accounts

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=horde,dc=example,dc=com:


ldappasswd -x -h localhost -D "cn=root,dc=example,dc=com" -s secretpassword -W uid=admin,ou=horde,dc=example,dc=com

Directory Permissions

These are the minimum directory permissions required for horde to work properly.


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


Horde Configuration

Authentication

ldap_horde_config.png

  • The hostname of the LDAP server - This is the address of your LDAP server.
    • The base DN for the LDAP server - This is the subtree that horde will search through to find user information.
    • The DN used to bind to the LDAP server - Because our LDAP directory does not allow anonymous binding, we must provide the binding account here. If your LDAP directory allows anonymous binding, this can be left blank.
    • The password used to bind to the LDAP server - The password associated with the binding account. Leave this blank if binding anonymously.
    • LDAP Protocol Version - This should almost always be LDAPv3.
    • The username search key - This is the field that stores the username.
    • How to specify a filter for the user lists - Unless you have to use some fancy filters to find users, One or more objectclass filters should work fine here.
    • The objectclass filter used to search for users. Can be a single objectclass or a list - This is simply a list of objectClass values that represent valid users.

User Management

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.

hook_authldap.png

Preferences

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 Hord preferences, s et the preference system to use LDAP as its backend. The field values here are very simular to the Horde configuration.

ldap_pref_config.png

  • The hostname of the LDAP server - This is the address of your LDAP server.
    • The port of the LDAP server - This is the port that your LDAP server is listening on. Most commonly, this will be 389.
    • LDAP Protocol Version - This should almost always be LDAPv3.
    • The base DN for the LDAP server - This is the subtree that horde will search through to find user preference information.
    • The DN of the root (administrative) account to bind for write operations - This is not actually asking for the LDAP root account, this is just the DN that horde uses to bind to the LDAP directory. This account should have write priveleges, which we configured above. If your LDAP directory allows anonymous binding, this can be left blank.
    • The password of the root DN for bind authentication - The password associated with the binding account. Leave this blank if binding anonymously.
    • The username search key - This is the field that stores the username.