Access a Remote IMAP Server with a Different Login HowTo

Written by Ole Wolf (ole [at] naturloven [dot] dk)

The following hook lets local users who sign on to Horde with SQL, LDAP, etc. access a remote IMAP server where they've been created with different usernames and passwords than their Horde logins.

Custom Database

Add a custom table named custom_mailusers to your Horde database using your favorite database manager. The table should contain three VARCHAR fields using the first one as a key:

This table contains the local usernames in username and their corresponding usernames and passwords on the remote IMAP server in imapusername and imappassword. Note that you'll have to somedhow manage this database table yourself.

IMAP Server ++

Setup the remote IMAP server as you would setup any IMAP server in IMP's backends file. Make a note of the $servers entry, as this will be used in the hook, below.

Hook

The following hook in IMP's hooks.local.php file reads from the database using the Horde database login and translates the local login username to the remote IMAP server's username and password:

    public function preauthenticate( $userId, $credentials )
    {
        global $conf;

        require dirname( __FILE__ ) . '/../config/conf.php';

        if( ! empty( $userId ) )
        {
            // Lookup IMAP username and password for the preferred username
            // in the custom table that is stored in the horde database.
            $dbhost   = $conf[ 'server' ][ 'name' ];
            $dbuser   = $conf[ 'sql' ][ 'username' ];
            $dbpasswd = $conf[ 'sql' ][ 'password' ];
            $dbname   = $conf[ 'sql' ][ 'database' ];
            $mysqli = new mysqli( $dbhost, $dbuser, $dbpasswd, $dbname );
            if( $mysqli->connect_error )
            {
                die( 'Cannot access username mapping database' );
            }
            $res = $mysqli->query( "SELECT imapusername, imappassword FROM custom_mailusers WHERE username='" . $mysqli->escape_string( $userId ) . "'" );
            if( ! $res )
            {
                Horde::logMessage( $mysqli->error, 'ERR' );
                die( 'Cannot query username mapping database' );
            }
            $newCred = $res->fetch_assoc( );
            if( $newCred === false )
            {
                die( 'Cannot read username from database' );
            }
            $imapUserId = $newCred[ 'imapusername' ];
            $imapPasswd = $newCred[ 'imappassword' ];

            Horde::logMessage( "Translating login $userId to $imapUserId", 'INF' );

            // Login with the IMAP credentials.
            $server      = 'imap';
            $credentials = array( 'server'      => $server,
                                  'transparent' => true,
                                  'password'    => $imapPasswd
                                  );
            return array( 'credentials' => $credentials,
                          'userId'      => $imapUserId );
        }

        return true;
    }

Replace the $server = imap'' content with that of your backends.php entry if necessary.

Security Issues

Since this hook assumes that Horde has authenticated the user, do not use this hook if you're using the IMP application to login with, as this will enable anyone who is registered as a user to login regardless of password!

Also, note that the user passwords are stored in plain text in the database.