zPanel Webmail Password Change

Issue:

zPanel is using RoundCube as the webmail frontend. It’s clean and user-friendly. However, if it is going to be used by ordinary mailbox users without zPanel admin access, users cannot change their own password through RoundCube. Deploying the Password plugin is not easy for zPanel as RoundCube is an open source webmail software, and it is not dedicated for zPanel.

Solution:

  1. Open /etc/zpanel/configs/roundcube/main.inc.php
  2. Deploy password plugin by modifying: $rcmail_config[‘plugins’] = array() -> $rcmail_config[‘plugins’] = array(‘password’)
  3. change dir to /etc/zpanel/panel/etc/apps/webmail/plugins/password/
  4. Copy config.inc.php.dist to config.inc.php
  5. Change the line: $rcmail_config[‘password_driver’] = ‘sql’ -> $rcmail_config[‘password_driver’] = ‘zpmail’
  6. Add the following driver contributed by setris.
  7. Name it as zpmail.php and put it under directory ../plugins/password/drivers/:

<?php

/**
 * ZpanelX SQL Password Driver
 *
 * Driver for passwords stored in SQL database
 *
 * @version 1.1
 * @author
 *
*/
class rcube_zpmail_password
{
    function save($curpass, $passwd)
    {
        $rcmail = rcmail::get_instance();
        $local_part  = $rcmail->user->get_username(‘local’);
        $domain_part = $rcmail->user->get_username(‘domain’);
        $username    = $_SESSION[‘username’];
        $host        = $_SESSION[‘imap_host’];
        // convert domains to/from punnycode
        if ($rcmail->config->get(‘password_idn_ascii’)) {
            $domain_part = rcube_idn_to_ascii($domain_part);
            $username    = rcube_idn_to_ascii($username);
            $host        = rcube_idn_to_ascii($host);
        }
        else {
            $domain_part = rcube_idn_to_utf8($domain_part);
            $username    = rcube_idn_to_utf8($username);
            $host        = rcube_idn_to_utf8($host);
        }
        $sql = ‘SELECT password FROM mailbox WHERE username=”‘.$username.'”‘;
        $host = “DBHOST”; // Usually localhost
        $dbName = “zpanel_postfix”; // your ZPanelX postfix database. Default value here
        $dbUser = “DBUSERNAME”;
        $dbPass = “DBPASSWORD”;
        try {
            $db = new PDO(“mysql:host={$host};dbname={$dbName}”, $dbUser, $dbPass);
            $db->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING );
        } catch (PDOException $e) {
            //echo ‘Database error: ‘. $e->getMessage() . ”;
            return PASSWORD_CONNECT_ERROR;
        }
        $res = $db->query($sql);
        $result = $res->fetch();$pass = $result[“password”];
        $hash = str_replace(“{PLAIN-MD5}”, “”, $pass);
        if (md5($curpass) != $hash)
        {
            // echo “Password mismatch error”;
            return PASSWORD_ERROR;
        }
        $pass = “{PLAIN-MD5}”.md5($passwd);
        $sql = ‘UPDATE mailbox SET password=”‘.$pass.'” WHERE username=”‘.$username.'”‘;
        $res = $db->query($sql);
        if ($res) {
                return PASSWORD_SUCCESS;
        }
        return PASSWORD_ERROR;
    }
}
Don’t forget to change parameters: $host, $db_User, $db_Pass above appropriately.
Config:
  • zPanel   10.1.1
  • RoundCube   0.9.5
  • Password plugin  3.2
Tricks:
There are many drivers in Password plugin inlcuding the default: sql, but none of them works with zPanel. That is the reason why we need to create new driver for the plugin.