6.0.0-git
2024-05-06
Last Modified 2005-08-30 by Jan Schneider

Dynamically selecting an IMAP server for authentication

Introduction

During a migration from one IMAP server to another, the need arose to run both the old and the new IMAP servers in paralell. By default,

Horde only allows a single primary server to be enabled in servers.php. Of course, we could have allowed our users to simply select

their server by enabling IMAP server selection, but there is a better way. What follows are instructions on using a MySQL backend to

select an IMAP server for authentication, given a username:

The SQL table

There are many ways to do this of course. In this example, we'll just be using a table with two rows:


---------------------------------------------------------

|   username        |     cyrus                         |

---------------------------------------------------------

Your table can be constructed however you like. It can even be a part of your existing Horde DB. The important point is that you need the table to be constructed in such a way as to be able to query a username and have the lookup return a server name from imp/config/servers.php.

Writing a hook

Here's some sample code for a hook placed inside horde/config/hooks.php:


if (!function_exists('_horde_hook_preauthenticate')) {

    function _horde_hook_preauthenticate($userID, $credential, $realm)

    {

        require dirname(__FILE__) . '/../imp/config/servers.php';

        // Strip domain part from user.

        $userID = substr($userID, 0, strpos($userID, '@'));

        // Connect to database server.

        $db = mysql_connect('hostname', 'dbuser', 'dbpasswd') or die('Can not connect to database.');

        // Select database.

        mysql_select_db('dbname') or die('Can not select database.');

        // Execute the query

        $sth = mysql_query('SELECT server_name FROM users WHERE user=\'' . mysql_real_escape_string($userID) . '\'') or die ('Can not query database.');

        // Fetch the server name.

        $server = mysql_fetch_row($sth);

        if ($server === false) {

            die('Can not read user from database.');

        }

        // Set IMAP server values.

        foreach (array('server', 'folders', 'namespace') as $key) {

            $_SESSION['imp'][$key] = $servers[$server[0]][$key];

        }

        return true;

    }

}

All that's left to do, is to activate the preauthenticate hook in Horde's configuration.