summaryrefslogtreecommitdiff
path: root/plugins/password
diff options
context:
space:
mode:
authoralecpl <alec@alec.pl>2009-06-20 07:28:33 +0000
committeralecpl <alec@alec.pl>2009-06-20 07:28:33 +0000
commit6bd74d8d51045923698f958fc917918411c6ca13 (patch)
treee4fb532d6de60be50eef00136fb520e1f177d62f /plugins/password
parent2dbc2d787a7d9acf85ac8b048d6a8a6c479ab428 (diff)
- Password plugin: implemented drivers
- removed password_sasl plugin
Diffstat (limited to 'plugins/password')
-rw-r--r--plugins/password/README159
-rw-r--r--plugins/password/config.inc.php31
-rw-r--r--plugins/password/drivers/sasl.php41
-rw-r--r--plugins/password/drivers/sql.php66
-rw-r--r--plugins/password/localization/en_US.inc5
-rw-r--r--plugins/password/localization/et_EE.inc5
-rw-r--r--plugins/password/localization/hu_HU.inc1
-rw-r--r--plugins/password/localization/nl_NL.inc5
-rw-r--r--plugins/password/localization/pl_PL.inc3
-rw-r--r--plugins/password/password.php191
10 files changed, 371 insertions, 136 deletions
diff --git a/plugins/password/README b/plugins/password/README
new file mode 100644
index 000000000..ca53116ee
--- /dev/null
+++ b/plugins/password/README
@@ -0,0 +1,159 @@
+ -----------------------------------------------------------------------
+ Password Plugin for Roundcube
+ -----------------------------------------------------------------------
+
+ Plugin that adds a possibility to change user password using many
+ methods (drivers) via Settings/Password tab.
+
+ -----------------------------------------------------------------------
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License version 2
+ as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ @version 1.2
+ @author Aleksander 'A.L.E.C' Machniak <alec@alec.pl>
+ @author <see driver files for driver authors>
+ -----------------------------------------------------------------------
+
+ 1. Configuration
+ 2. Drivers
+ 2.1. Database (sql)
+ 2.2. Cyrus/SASL (sasl)
+ 3. Driver API
+
+
+ 1. Configuration
+ ----------------
+
+ * See config.inc.php file.
+
+
+ 2. Drivers
+ ----------
+
+ Password plugin supports many password change mechanisms which are
+ handled by included drivers. Just pass driver name in 'password_driver' option.
+
+
+ 2.1. Database (sql)
+ -------------------
+
+ You can specify which database to connect by 'password_db_dsn' option and
+ what SQL query to execute by 'password_query'. See main.inc.php file for
+ more info.
+
+ Example implementations of an update_passwd function:
+
+ - This is for use with LMS (http://lms.org.pl) database and postgres:
+
+ CREATE OR REPLACE FUNCTION update_passwd(hash text, account text) RETURNS integer AS $$
+ DECLARE
+ res integer;
+ BEGIN
+ UPDATE passwd SET password = hash
+ WHERE login = split_part(account, '@', 1)
+ AND domainid = (SELECT id FROM domains WHERE name = split_part(account, '@', 2))
+ RETURNING id INTO res;
+ RETURN res;
+ END;
+ $$ LANGUAGE plpgsql SECURITY DEFINER;
+
+ - This is for use with a SELECT update_passwd(%o,%c,%u) query
+ Updates the password only when the old password matches the MD5 password
+ in the database
+
+ CREATE FUNCTION update_password (oldpass text, cryptpass text, user text) RETURNS text
+ MODIFIES SQL DATA
+ BEGIN
+ DECLARE currentsalt varchar(20);
+ DECLARE error text;
+ SET error = 'incorrect current password';
+ SELECT substring_index(substr(user.password,4),_latin1'$',1) INTO currentsalt FROM users WHERE username=user;
+ SELECT '' INTO error FROM users WHERE username=user AND password=ENCRYPT(oldpass,currentsalt);
+ UPDATE users SET password=cryptpass WHERE username=user AND password=ENCRYPT(oldpass,currentsalt);
+ RETURN error;
+ END
+
+ Example SQL UPDATEs:
+
+ - Plain text passwords:
+ UPDATE users SET password=%p WHERE username=%u AND password=%o AND domain=%h LIMIT 1
+
+ - Crypt text passwords:
+ UPDATE users SET password=%c WHERE username=%u LIMIT 1
+
+ - Use a MYSQL crypt function (*nix only) with random 8 character salt
+ UPDATE users SET password=ENCRYPT(%p,concat(_utf8'$1$',right(md5(rand()),8),_utf8'$')) WHERE username=%u LIMIT 1
+
+ - MD5 stored passwords:
+ UPDATE users SET password=MD5(%p) WHERE username=%u AND password=MD5(%o) LIMIT 1
+
+
+ 2.2. Cyrus/SASL (sasl)
+ ----------------------
+
+ Cyrus SASL database authentication allows your Cyrus+RoundCube
+ installation to host mail users without requiring a Unix Shell account!
+
+ This driver only covers the "sasldb" case when using Cyrus SASL. Kerberos
+ and PAM authentication mechanisms will require other techniques to enable
+ user password manipulations.
+
+ Cyrus SASL includes a shell utility called "saslpasswd" for manipulating
+ user passwords in the "sasldb" database. This plugin attempts to use
+ this utility to perform password manipulations required by your webmail
+ users without any administrative interaction. Unfortunately, this
+ scheme requires that the "saslpasswd" utility be run as the "cyrus"
+ user - kind of a security problem since we have chosen to SUID a small
+ script which will allow this to happen.
+
+ This driver is based on the Squirrelmail Change SASL Password Plugin.
+ See http://www.squirrelmail.org/plugin_view.php?id=107 for details.
+
+ Installation:
+
+ Edit the chgsaslpasswd.c and chgsaslpasswd.sh files as is documented
+ within them.
+
+ Compile the wrapper program:
+ gcc -o chgsaslpasswd chgsaslpasswd.c
+
+ Chown the chgsaslpasswd and chgsaslpasswd.sh to the cyrus user and group
+ that your browser runs as, then chmod them to 4550.
+
+ For example, if your cyrus user is 'cyrus' and the apache server group is
+ 'nobody' (I've been told Redhat runs Apache as user 'apache'):
+
+ chown cyrus:nobody chgsaslpasswd
+ chmod 4550 chgsaslpasswd
+
+ Stephen Carr has suggested users should try to run the scripts on a test
+ account as the cyrus user eg;
+
+ su cyrus -c "./chgsaslpasswd -p test_account"
+
+ This will allow you to make sure that the script will work for your setup.
+ Should the script not work, make sure that:
+ 1) the user the script runs as has access to the saslpasswd|saslpasswd2
+ file and proper permissions
+ 2) make sure the user in the chgsaslpasswd.c file is set correctly.
+ This could save you some headaches if you are the paranoid type.
+
+
+ 3. Driver API
+ -------------
+
+ Driver file (<driver_name>.php) must define 'password_save' function with
+ two arguments. First - current password, second - new password. Function
+ may return PASSWORD_SUCCESS on success or PASSWORD_ERROR on any error.
+ See existing drivers in drivers/ directory for examples.
+ \ No newline at end of file
diff --git a/plugins/password/config.inc.php b/plugins/password/config.inc.php
new file mode 100644
index 000000000..8fa329204
--- /dev/null
+++ b/plugins/password/config.inc.php
@@ -0,0 +1,31 @@
+<?php
+
+// Password Plugin options
+// -----------------------
+// A driver to use for password change. Default: "sql".
+$rcmail_config['password_driver'] = 'sql';
+
+// Determine whether current password is required to change password.
+// Default: false.
+$rcmail_config['password_confirm_current'] = false;
+
+
+// SQL Driver options
+// ------------------
+// PEAR database DSN for performing the query. By default
+// Roundcube DB settings are used.
+$rcmail_config['password_db_dsn'] = '';
+
+// The SQL query used to change the password.
+// The query can contain the following macros that will be expanded as follows:
+// %p is replaced with the plaintext new password
+// %c is replaced with the crypt version of the new password, MD5 if available
+// otherwise DES.
+// %u is replaced with the username (from the session info)
+// %o is replaced with the password before the change
+// %h is replaced with the imap host (from the session info)
+// Escaping of macros is handled by this module.
+// Default: "SELECT update_passwd(%c, %u)"
+$rcmail_config['password_query'] = 'SELECT update_passwd(%c, %u)';
+
+?>
diff --git a/plugins/password/drivers/sasl.php b/plugins/password/drivers/sasl.php
new file mode 100644
index 000000000..361333403
--- /dev/null
+++ b/plugins/password/drivers/sasl.php
@@ -0,0 +1,41 @@
+<?php
+
+/**
+ * SASL Password Driver
+ *
+ * Driver that adds functionality to change the users Cyrus/SASL password.
+ * The code is derrived from the Squirrelmail "Change SASL Password" Plugin
+ * by Galen Johnson.
+ *
+ * It only works with saslpasswd2 on the same host where RoundCube runs
+ * and requires shell access and gcc in order to compile the binary.
+ *
+ * For installation instructions please read the README file.
+ *
+ * @version 1.0
+ * @author Thomas Bruederli
+ */
+
+function password_save($currpass, $newpass)
+{
+ $curdir = realpath(dirname(__FILE__));
+ $username = escapeshellcmd($_SESSION['username']);
+
+ if ($fh = popen("$curdir/chgsaslpasswd -p $username", 'w')) {
+ fwrite($fh, $newpass."\n");
+ $code = pclose($fh);
+
+ if($code == 0)
+ return PASSWORD_SUCCESS;
+ } else
+ raise_error(array(
+ 'code' => 600,
+ 'type' => 'php',
+ 'file' = __FILE__,
+ 'message' => "Password plugin: Unable to execute $curdir/chgsaslpasswd"
+ ), true, false);
+
+ return PASSWORD_ERROR;
+}
+
+?>
diff --git a/plugins/password/drivers/sql.php b/plugins/password/drivers/sql.php
new file mode 100644
index 000000000..3cac8d4dc
--- /dev/null
+++ b/plugins/password/drivers/sql.php
@@ -0,0 +1,66 @@
+<?php
+
+/**
+ * SQL Password Driver
+ *
+ * Driver for passwords stored in SQL database
+ *
+ * @version 1.0
+ * @author Aleksander 'A.L.E.C' Machniak <alec@alec.pl>
+ *
+ */
+
+function password_save($curpass, $passwd)
+{
+ $rcmail = rcmail::get_instance();
+
+ if (!($sql = $rcmail->config->get('password_query')))
+ $sql = 'SELECT update_passwd(%c, %u)';
+
+ if ($dsn = $rcmail->config->get('password_db_dsn')) {
+ $db = new rcube_mdb2($dsn, '', FALSE);
+ $db->set_debug((bool)$rcmail->config->get('sql_debug'));
+ $db->db_connect('w');
+ } else {
+ $db = $rcmail->get_dbh();
+ }
+
+ if ($err = $db->is_error())
+ return PASSWORD_ERROR;
+
+ if (strpos($sql, '%c') !== FALSE) {
+ $salt = '';
+ if (CRYPT_MD5) {
+ $len = rand(3, CRYPT_SALT_LENGTH);
+ } else if (CRYPT_STD_DES) {
+ $len = 2;
+ } else {
+ return PASSWORD_CRYPT_ERROR;
+ }
+ for ($i = 0; $i < $len ; $i++) {
+ $salt .= chr(rand(ord('.'), ord('z')));
+ }
+ $sql = str_replace('%c', $db->quote(crypt($passwd, CRYPT_MD5 ? '$1$'.$salt.'$' : $salt)), $sql);
+ }
+
+ $sql = str_replace('%u', $db->quote($_SESSION['username'],'text'), $sql);
+ $sql = str_replace('%p', $db->quote($passwd,'text'), $sql);
+ $sql = str_replace('%o', $db->quote($curpass,'text'), $sql);
+ $sql = str_replace('%h', $db->quote($_SESSION['imap_host'],'text'), $sql);
+
+ $res = $db->query($sql);
+
+ if (!$db->is_error()) {
+ if (strtolower(substr(trim($query),0,6))=='select') {
+ if ($result = $db->fetch_array($res))
+ return PASSWORD_SUCCESS;
+ } else {
+ if ($db->affected_rows($res) == 1)
+ return PASSWORD_SUCCESS; // This is the good case: 1 row updated
+ }
+ }
+
+ return PASSWORD_ERROR;
+}
+
+?>
diff --git a/plugins/password/localization/en_US.inc b/plugins/password/localization/en_US.inc
index 9e25214cd..80bf1ccc3 100644
--- a/plugins/password/localization/en_US.inc
+++ b/plugins/password/localization/en_US.inc
@@ -11,8 +11,7 @@ $messages['nopassword'] = 'Please input new password.';
$messages['nocurpassword'] = 'Please input current password.';
$messages['passwordincorrect'] = 'Current password incorrect.';
$messages['passwordinconsistency'] = 'Passwords do not match, please try again.';
-$messages['nocryptfunction'] = 'The server is missing a function to encrypt your password - contact your system adminstrator.';
-$messages['internalerror'] = 'The server is updated more than one row in the database. This could be bad for all users. Contact your system adminstrator.';
-$messages['errorsaving'] = 'Could not save your new password to the database. Contact your system adminstrator.';
+$messages['nocryptfunction'] = 'The server is missing a function to encrypt your password. Contact your system adminstrator.';
+$messages['internalerror'] = 'Could not save new password. Contact your system adminstrator.';
?>
diff --git a/plugins/password/localization/et_EE.inc b/plugins/password/localization/et_EE.inc
index 9ddc0b3d4..61546e83e 100644
--- a/plugins/password/localization/et_EE.inc
+++ b/plugins/password/localization/et_EE.inc
@@ -11,8 +11,7 @@ $messages['nopassword'] = 'Palun sisesta uus parool.';
$messages['nocurpassword'] = 'Palun sisesta vana parool.';
$messages['passwordincorrect'] = 'Vana parool on vale.';
$messages['passwordinconsistency'] = 'Paroolid ei kattu, palun proovi uuesti.';
-$messages['nocryptfunction'] = 'Serveris ei ole parooli krüpteerimiseks vajalikku funktsiooni - palun võta oma süsteemi administraatoriga ühendust.';
-$messages['internalerror'] = 'Server uuendas andmebaasis liiga palju ridu. See võib olla halb kõigile kasutajatele. Palun võta oma süsteemi administraatoriga ühendust.';
-$messages['errorsaving'] = 'Uue parooli andmebaasi salvestamine nurjus. Palun võta oma süsteemi administraatoriga ühendust.';
+$messages['nocryptfunction'] = 'Serveris ei ole parooli krüpteerimiseks vajalikku funktsiooni. Palun võta oma süsteemi administraatoriga ühendust.';
+$messages['internalerror'] = 'Uue parooli andmebaasi salvestamine nurjus. Palun võta oma süsteemi administraatoriga ühendust.';
?>
diff --git a/plugins/password/localization/hu_HU.inc b/plugins/password/localization/hu_HU.inc
index 8a4e5d678..9b5acb8c6 100644
--- a/plugins/password/localization/hu_HU.inc
+++ b/plugins/password/localization/hu_HU.inc
@@ -13,6 +13,5 @@ $messages['passwordincorrect'] = 'Érvénytelen a jelenlegi jelszó.';
$messages['passwordinconsistency'] = 'A két új jelszó nem egyezik.';
$messages['nocryptfunction'] = 'Hiba történt a kérés feldolgozása során.';
$messages['internalerror'] = 'Hiba történt a kérés feldolgozása során.';
-$messages['errorsaving'] = 'Hiba történt a kérés feldolgozása során.';
?>
diff --git a/plugins/password/localization/nl_NL.inc b/plugins/password/localization/nl_NL.inc
index 61d4e366d..c289ee30e 100644
--- a/plugins/password/localization/nl_NL.inc
+++ b/plugins/password/localization/nl_NL.inc
@@ -11,8 +11,7 @@ $messages['nopassword'] = 'Vul een wachtwoord in.';
$messages['nocurpassword'] = 'vul het huidige wachtwoord in.';
$messages['passwordincorrect'] = 'Huidig wachtwoord is onjuist.';
$messages['passwordinconsistency'] = 'Wachtwoorden komen niet overeen, probeer het opnieuw.';
-$messages['nocryptfunction'] = 'De server mist een functie om uw wachtwoord et beveiligen - neem contact op met uw systeembeheerder.';
-$messages['internalerror'] = 'De server heeft meer dan 1 regel in de database gewijzigd. Dit kan een probleem opleveren voor alle gebruikers. Neem contact op met uw systeembeheerder.';
-$messages['errorsaving'] = 'Uw wachtwoord kan niet worden opgeslagen in de database. Neem contact op met uw systeembeheerder.';
+$messages['nocryptfunction'] = 'De server mist een functie om uw wachtwoord et beveiligen. Neem contact op met uw systeembeheerder.';
+$messages['internalerror'] = 'Uw wachtwoord kan niet worden opgeslagen. Neem contact op met uw systeembeheerder.';
?>
diff --git a/plugins/password/localization/pl_PL.inc b/plugins/password/localization/pl_PL.inc
index 3c4acb3d1..e26770b14 100644
--- a/plugins/password/localization/pl_PL.inc
+++ b/plugins/password/localization/pl_PL.inc
@@ -12,7 +12,6 @@ $messages['nocurpassword'] = 'Wprowadź aktualne hasło.';
$messages['passwordincorrect'] = 'Błędne aktualne hasło, spróbuj ponownie.';
$messages['passwordinconsistency'] = 'Hasła nie pasują, spróbuj ponownie.';
$messages['nocryptfunction'] = 'Brak funkcji kodującej hasło. Skontaktuj się z administratorem.';
-$messages['internalerror'] = 'Serwer zaktualizował więcej niż jeden wpis w bazie. To może być złe dla innych użytkowników. Skontaktuj się z administratorem.';
-$messages['errorsaving'] = 'Nie udało się zapisać nowego hasła. Skontaktuj się z administratorem.';
+$messages['internalerror'] = 'Nie udało się zapisać nowego hasła. Skontaktuj się z administratorem.';
?>
diff --git a/plugins/password/password.php b/plugins/password/password.php
index 767ddab82..050053981 100644
--- a/plugins/password/password.php
+++ b/plugins/password/password.php
@@ -1,84 +1,37 @@
<?php
-/**
- * Change Password
- *
- * Plugin that adds a possibility to change password using a database
- * (Settings -> Password tab)
- *
- * @version 1.1
- * @author Aleksander 'A.L.E.C' Machniak <alec@alec.pl>
- * @editor Daniel Black
- *
- * Configuration Items (config/main.inc.php):
- * password_confirm_current - boolean to determine whether current password
- * is required to change password. Defaults to FALSE.
- * password_db_dsn - is the PEAR database DSN for performing the query. Defaults
- * to the default databse setting in config/db.inc.php
- * password_query - the SQL query used to change the password.
- * If the SQL query is a SELECT it will return an error message in a row if unsuccessful
- * If the SQL query is a UPDATE it will update a single row only.
- * An UPDATE where zero rows changed will be inteperated to be a wrong username/password
- * More than one row changed will be inteperated as an internal error
- * The query can contain the following macros that will be expanded as follows:
- * %p is replaced with the plaintext new password
- * %c is replaced with the crypt version of the new password, MD5 if available
- * otherwise DES.
- * %u is replaced with the username (from the session info)
- * %o is replaced with the password before the change
- * %h is replaced with the imap host (from the session info)
- * Escaping of macros is handled by this module.
- * Defaults to "SELECT update_passwd(%c, %u)"
- * To use this you need to define the update_passwd function in your
- * database.
- *
- * Example SQL queries:
- * These will typically need to define a function to change the password:
- *
- * Example implementations of an update_passwd function:
- *
- * This is for use with LMS (http://lms.org.pl) database and postgres:
- * CREATE OR REPLACE FUNCTION update_passwd(hash text, account text) RETURNS integer AS $$
- * DECLARE
- * res integer;
- * BEGIN
- * UPDATE passwd SET password = hash
- * WHERE login = split_part(account, '@', 1)
- * AND domainid = (SELECT id FROM domains WHERE name = split_part(account, '@', 2))
- * RETURNING id INTO res;
- * RETURN res;
- * END;
- * $$ LANGUAGE plpgsql SECURITY DEFINER;
- *
- * This is for use with a SELECT update_passwd(%o,%c,%u) query
- * Uupdates the password only when the old password matches the MD5 password in the database
- * CREATE FUNCTION update_password (oldpass text, cryptpass text, user text) RETURNS text
- * MODIFIES SQL DATA
- * BEGIN
- * DECLARE currentsalt varchar(20);
- * DECLARE error text;
- * SET error = 'incorrect current password';
- * SELECT substring_index(substr(user.password,4),_latin1'$',1) INTO currentsalt FROM users WHERE username=user;
- * SELECT '' INTO error FROM users WHERE username=user AND password=ENCRYPT(oldpass,currentsalt);
- * UPDATE users SET password=cryptpass WHERE username=user AND password=ENCRYPT(oldpass,currentsalt);
- * RETURN error;
- * END
- *
- * Example SQL UPDATEs:
- *
- * Plain text passwords:
- * UPDATE users SET password=%p WHERE username=%u AND password=%o AND domain=%h LIMIT 1
- *
- * Crypt text passwords:
- * UPDATE users SET password=%c WHERE username=%u LIMIT 1
- *
- * Use a MYSQL crypt function (*nix only) with random 8 character salt
- * UPDATE users SET password=ENCRYPT(%p,concat(_utf8'$1$',right(md5(rand()),8),_utf8'$')) WHERE username=%u LIMIT 1
- *
- * MD5 stored passwords:
- * UPDATE users SET password=MD5(%p) WHERE username=%u AND password=MD5(%o) LIMIT 1
- *
- */
+/*
+ +-------------------------------------------------------------------------+
+ | Password Plugin for Roundcube |
+ | Version 1.2 |
+ | |
+ | Copyright (C) 2009, RoundCube Dev. - Switzerland |
+ | |
+ | This program is free software; you can redistribute it and/or modify |
+ | it under the terms of the GNU General Public License version 2 |
+ | as published by the Free Software Foundation. |
+ | |
+ | This program is distributed in the hope that it will be useful, |
+ | but WITHOUT ANY WARRANTY; without even the implied warranty of |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
+ | GNU General Public License for more details. |
+ | |
+ | You should have received a copy of the GNU General Public License along |
+ | with this program; if not, write to the Free Software Foundation, Inc., |
+ | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
+ | |
+ +-------------------------------------------------------------------------+
+ | Author: Aleksander Machniak <alec@alec.pl> |
+ +-------------------------------------------------------------------------+
+
+ $Id: index.php 2645 2009-06-15 07:01:36Z alec $
+
+*/
+
+define('PASSWORD_CRYPT_ERROR', 1);
+define('PASSWORD_ERROR', 2);
+define('PASSWORD_SUCCESS', 0);
+
class password extends rcube_plugin
{
public $task = 'settings';
@@ -106,6 +59,7 @@ class password extends rcube_plugin
function password_save()
{
$rcmail = rcmail::get_instance();
+ $this->load_config();
$this->add_texts('localization/');
$this->register_handler('plugin.body', array($this, 'password_form'));
@@ -135,8 +89,8 @@ class password extends rcube_plugin
function password_form()
{
$rcmail = rcmail::get_instance();
+ $this->load_config();
- $confirm = $rcmail->config->get('password_confirm_current');
// add some labels to client
$rcmail->output->add_label(
'password.nopassword',
@@ -152,7 +106,7 @@ class password extends rcube_plugin
// return the complete edit form as table
$out = '<table' . $attrib_str . ">\n\n";
- if ($confirm) {
+ if ($rcmail->config->get('password_confirm_current')) {
// show current password selection
$field_id = 'curpasswd';
$input_newpasswd = new html_passwordfield(array('name' => '_curpasswd', 'id' => $field_id,
@@ -205,55 +159,44 @@ class password extends rcube_plugin
), $out);
}
- private function _save($curpass,$passwd)
+ private function _save($curpass, $passwd)
{
- $cfg = rcmail::get_instance()->config;
-
- if (!($sql = $cfg->get('password_query')))
- $sql = "SELECT update_passwd(%c, %u)";
-
- if ($dsn = $cfg->get('password_db_dsn')) {
- $db = new rcube_mdb2($dsn, '', FALSE);
- $db->set_debug((bool)$cfg->get('sql_debug'));
- $db->db_connect('w');
- } else {
- $db = rcmail::get_instance()->get_dbh();
- }
-
- if ($err = $db->is_error())
- return $err;
+ $config = rcmail::get_instance()->config;
+ $driver = $this->home.'/drivers/'.$config->get('password_driver', 'sql').'.php';
- if (strpos($sql,'%c') !== FALSE) {
- $salt = '';
- if (CRYPT_MD5) {
- $len = rand(3,CRYPT_SALT_LENGTH);
- } else if (CRYPT_STD_DES) {
- $len = 2;
- } else {
- return $this->gettext('nocryptfunction');
- }
- for ($i = 0; $i < $len ; $i++) {
- $salt .= chr(rand(ord('.'),ord('z')));
- }
- $sql = str_replace('%c', $db->quote(crypt($passwd, CRYPT_MD5 ? '$1$'.$salt.'$' : $salt)), $sql);
+ if (!is_readable($driver)) {
+ raise_error(array(
+ 'code' => 600,
+ 'type' => 'php',
+ 'file' => __FILE__,
+ 'message' => "Password plugin: Unable to open driver file $driver"
+ ), true, false);
+ return $this->gettext('internalerror');
}
- $sql = str_replace('%u', $db->quote($_SESSION['username'],'text'), $sql);
- $sql = str_replace('%p', $db->quote($passwd,'text'), $sql);
- $sql = str_replace('%o', $db->quote($curpass,'text'), $sql);
- $sql = str_replace('%h', $db->quote($_SESSION['imap_host'],'text'), $sql);
-
- $res = $db->query($sql);
- if ($err = $db->is_error())
- return $err;
- if (strtolower(substr(trim($query),0,6))=='select') {
- return $db->fetch_array($res);
- } else {
- $res = $db->affected_rows($res);
- if ($res == 0) return $this->gettext('errorsaving');
- if ($res == 1) return FALSE; // THis is the good case - 1 row updated
+
+ include($driver);
+
+ if (!function_exists('password_save')) {
+ raise_error(array(
+ 'code' => 600,
+ 'type' => 'php',
+ 'file' => __FILE__,
+ 'message' => "Password plugin: Broken driver: $driver"
+ ), true, false);
return $this->gettext('internalerror');
}
+ $result = password_save($curpass, $passwd);
+
+ switch ($result) {
+ case PASSWORD_SUCCESS:
+ return;
+ case PASSWORD_CRYPT_ERROR;
+ return $this->gettext('nocryptfunction');
+ case PASSWORD_ERROR:
+ default:
+ return $this->gettext('internalerror');
+ }
}
}