Howto password change in webmail
This howto describes how to enable a password change for mail accounts directly in the ispcp webmail (squirrel mail)
Version from 2007-10-15 - better sql formula...
IMPORTANT: This does not work with RC7 and higher due to encrypted passwords (new feature). Hopefully someone can write a new version…
Step 1 - the plugin itself
We need the plugin change_sqlpass for squirrelmail - here
http://www.squirrelmail.org/plugin_view.php?id=25 is the description and here
http://www.squirrelmail.org/plugin_download.php?id=25&rev=1226 the download...
Requires: SquirrelMail 1.2.8, Compatibility 2.0.4, Pear DB library SquirrelMail and Compatibility is ok by ispcp - PEAR DB should be separately installed...
We unpack the file in /var/www/ispcp/gui/tools/webmail/plugins/ so that the files come into /var/www/ispcp/gui/tools/webmail/plugins/change_sqlpass. Set ownership and permissions like the other plugins... (vu2000:www-data, -r--r--r--, dr-xr-xr-x).
Then we have to activate the plugin by adding a line to /var/www/ispcp/gui/tools/webmail/config/config_local.php:
$plugins[26] = 'change_sqlpass';
(the index number should be higher than the ones from the already activated plugins...)
Step 2, a user for the database
We need to create a user in mysql which is used for the password change. Use a sql console (in the shell, in pma, whatever - as mysql-root).
(I adopted the statements from the old vhcs2 documentation)
GRANT USAGE ON ispcp.* TO 'ispcp-mail-user'@'localhost' IDENTIFIED BY '###greatpassword###' WITH MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0; GRANT SELECT (`domain_id`, `domain_name` ) ON `ispcp`.`domain` TO 'ispcp-mail-user'@'localhost'; GRANT SELECT (`domain_id`, `alias_id`, `alias_name` ) ON `ispcp`.`domain_aliasses` TO 'ispcp-mail-user'@'localhost'; GRANT SELECT (`domain_id`, `subdomain_id`, `subdomain_name` ) ON `ispcp`.`subdomain` TO 'ispcp-mail-user'@'localhost'; GRANT SELECT ( `mail_id`, `mail_acc`, `domain_id`, `sub_id`, `mail_type`, `status`, `mail_pass`), UPDATE (`mail_pass` , `status`) ON `ispcp`.`mail_users` TO 'ispcp-mail-user'@'localhost';
Step 3, configuration of the plugin
Go into the plugin folder /var/www/ispcp/gui/tools/webmail/plugins/change_sqlpass, make a copy of the sample config:
cp config.php.sample config.php
and open config.php for editing, we need to changes some lines: make the beginning of the file (global ...) looks like this (add two globals and set one with null):
global $csp_dsn, $password_update_queries, $lookup_password_query,
$force_change_password_check_query, $password_encryption,
$csp_salt_query, $csp_salt_static, $csp_secure_port,
$csp_non_standard_http_port, $csp_delimiter, $csp_debug,
$min_password_length, $max_password_length, $include_digit_in_password,
$include_uppercase_letter_in_password, $include_lowercase_letter_in_password,
$include_nonalphanumeric_in_password,
$lookup_password_query_get_id, $mail_id;
$mail_id = null;
now we set 4 variables:
$csp_dsn = 'mysql://ispcp-mail-user:###greatpassword###@localhost/ispcp';
$lookup_password_query = "SELECT COUNT(DISTINCT t1.`mail_id`) = 1
FROM `mail_users` t1
LEFT JOIN `domain` t2 USING ( `domain_id` )
LEFT JOIN `domain_aliasses` t3 USING ( `domain_id` )
LEFT JOIN `subdomain` t4 USING ( `domain_id` )
WHERE t1.`mail_acc` = '%2' AND t1.`mail_pass` = '%5'
AND (
( t1.`mail_type` = 'normal_mail' AND t2.`domain_name` = '%3' )
OR ( t1.`mail_type` = 'alias_mail' AND t3.`alias_name` = '%3' AND t3.`alias_id` = t1.`sub_id` )
OR ( t1.`mail_type` = 'subdom_mail'AND CONCAT( t4.`subdomain_name` , '.', t2.`domain_name` ) = '%3' AND t4.`subdomain_id` = t1.`sub_id` )
)";
$lookup_password_query_get_id = "SELECT DISTINCT t1.`mail_id`
FROM `mail_users` t1
LEFT JOIN `domain` t2 USING ( `domain_id` )
LEFT JOIN `domain_aliasses` t3 USING ( `domain_id` )
LEFT JOIN `subdomain` t4 USING ( `domain_id` )
WHERE t1.`mail_acc` = '%2' AND t1.`mail_pass` = '%5'
AND (
( t1.`mail_type` = 'normal_mail' AND t2.`domain_name` = '%3' )
OR ( t1.`mail_type` = 'alias_mail' AND t3.`alias_name` = '%3' AND t3.`alias_id` = t1.`sub_id` )
OR ( t1.`mail_type` = 'subdom_mail' AND CONCAT( t4.`subdomain_name`, '.', t2.`domain_name` ) = '%3' AND t4.`subdomain_id` = t1.`sub_id` )
)";
$password_update_queries = array(
"UPDATE `mail_users` SET `mail_pass` = '%5', status = 'change' WHERE mail_id = %6",
);
$csp_salt_query = '';
I needed to add the $mail_id variable, otherwise it'd be to tricky with the sql statements - therefore we need some changes also in functions.php (same folder). The diff -u looks like this:
--- functions.php_org 2005-11-12 07:48:24.000000000 +0100
+++ functions.php 2007-09-30 01:46:15.000000000 +0200
@@ -694,7 +694,7 @@
global $lookup_password_query, $csp_debug, $min_password_length,
$max_password_length, $include_digit_in_password,
$include_uppercase_letter_in_password, $include_lowercase_letter_in_password,
- $include_nonalphanumeric_in_password;
+ $include_nonalphanumeric_in_password, $lookup_password_query_get_id, $mail_id;
load_config('change_sqlpass', array('config.php'));
@@ -742,6 +742,14 @@
$sql);
$db_password = $db->getAll($sql);
+ $sql = $lookup_password_query_get_id;
+ $sql = str_replace(array('%1', '%2', '%3', '%4', '%5'),
+ array($full_username, $user, $dom, $encrypted_pwd, $db->escapeSimple($cp_oldpass)),
+ $sql);
+ $mail_id = $db->getAll($sql); // we need the id of the mail account, otherwise it's to hard to create a good pw update sql statement
+ if (count($mail_id) != 1) {
+ array_push($messages, _("Problem detected: ".count($mail_id)." accounts found"));
+ }
// check for database errors
//
@@ -826,7 +834,7 @@
function change_password($password)
{
- global $password_update_queries, $csp_debug, $base_uri;
+ global $password_update_queries, $csp_debug, $base_uri, $mail_id;
load_config('change_sqlpass', array('config.php'));
@@ -846,8 +854,8 @@
{
$sql = $query;
- $sql = str_replace(array('%1', '%2', '%3', '%4', '%5'),
- array($full_username, $user, $dom, $encrypted_pwd, $db->escapeSimple($password)),
+ $sql = str_replace(array('%1', '%2', '%3', '%4', '%5', '%6'),
+ array($full_username, $user, $dom, $encrypted_pwd, $db->escapeSimple($password), $mail_id[0][0]),
$sql);
@@ -872,6 +880,9 @@
}
+ // send a signal to the ispcp request manager:
+ require_once('../../../../include/ispcp-functions.php');
+ send_request();
// Write new cookies for the password
//
That's it.
I think it should be safe (not setting the password to the wrong account) but maybe we need some testing... [feedback is welcome].
Maybe we get this into ispcp - after 1.0 :-)
A small drawback: users have to logoff and login again after password change - maybe we can fix that later...
