[cvs] [Wiki] changed: ImapSelect
Jan Schneider
jan at horde.org
Tue Aug 30 08:46:32 PDT 2005
jan Tue, 30 Aug 2005 08:46:32 -0700
Modified page: http://wiki.horde.org/ImapSelect
New Revision: 3.0
Change log: Better example
@@ -1,75 +1,57 @@
-+++ Introduction
++ 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
-
-
+++ 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:
<code>
---------------------------------------------------------
-| username | server.domain.com |
+| username | cyrus |
---------------------------------------------------------
</code>
-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 servername. Our example
-uses a table called 'host'.
-
-+++ Writing a hook
-
+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:
<code type="php">
-if (!function_exists('_imp_hook_imap')) {
- function _imp_hook_imap($userName)
- {
- global $conf;
- include_once 'DB.php';
- $_db = &DB::connect($conf['sql'], true);
- $query = sprintf('SELECT server FROM host WHERE user=%s', $_db->quote($userName));
- $result = $_db->getOne($query);
- if (!is_a($result, 'PEAR_Error')) {
- return $result;
- } else {
- return false;
- }
+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.');
}
-}
-</code>
+ // Set IMAP server values.
+ foreach (array('server', 'folders', 'namespace') as $key) {
+ $_SESSION['imp'][$key] = $servers[$server[0]][$key];
+ }
-+++ Placing the hook into the session
-
-
-
-The above hook returns a single line containing a server name. The results are injected into /horde/imp/lib/Session.php as follows:
-
-<code type="php">
-
- if (!empty($GLOBALS['conf']['hooks']['imap'])) {
- require_once HORDE_BASE . '/config/hooks.php';
- if (function_exists('_imp_hook_imap')) {
- $_SESSION['imp']['server'] = call_user_func('_imp_hook_imap', $_SESSION['imp']['user']);
- }
- }
+ return true;
+ }
+}
</code>
-On our setup, this is done right before authentication is attempted (right around line 223). As best I can tell, you're fine so long
-as you don't have $_SESSION['imp']['server'] overwritten by anything else before you get to the call to &Auth::singleton(array('imp', 'imp'));
-
-+++ Disclaimer
-
-
-
-This code works on our setup thus far. It could be wrong, uneccesary, foolish, or otherwise idiotic. In short, YMMV.
-
-Questions? Send them to mp at xmission.com
+All that's left to do, is to activate the preauthenticate hook in Horde's configuration.
More information about the cvs
mailing list