summaryrefslogtreecommitdiff
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
parent2dbc2d787a7d9acf85ac8b048d6a8a6c479ab428 (diff)
- Password plugin: implemented drivers
- removed password_sasl plugin
-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
-rw-r--r--plugins/sasl_password/README65
-rw-r--r--plugins/sasl_password/chgsaslpasswd.c27
-rw-r--r--plugins/sasl_password/locale/de_CH.inc16
-rw-r--r--plugins/sasl_password/locale/en_US.inc16
-rw-r--r--plugins/sasl_password/locale/pl_PL.inc16
-rw-r--r--plugins/sasl_password/sasl_password.js43
-rw-r--r--plugins/sasl_password/sasl_password.php146
17 files changed, 371 insertions, 465 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');
+ }
}
}
diff --git a/plugins/sasl_password/README b/plugins/sasl_password/README
deleted file mode 100644
index 3fbc448ff..000000000
--- a/plugins/sasl_password/README
+++ /dev/null
@@ -1,65 +0,0 @@
-+-------------------------------------------------------------------------+
-|
-| Author: Thomas Bruederli
-| Source: Squirrelmail Change SASL Password Plugin by Galen Johnson
-| Program: sasl_password
-| Version: 1.0
-| Purpose: Change Cyrus Account Passwords
-|
-+-------------------------------------------------------------------------+
-
-
-Purpose
--------
-Cyrus SASL database authentication allows your Cyrus+RoundCube
-installation to host mail users without requiring a Unix Shell account!
-
-This plugin 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 patch 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 plugin is based on the Squirrelmail Change SASL Password Plugin.
-See http://www.squirrelmail.org/plugin_view.php?id=107 for details.
-
-
-Installation
-------------
-Install just like any other plugin, just put it in the plugin directory
-and activate it by adding 'sasl_password' to the list of active plugins
-in config/main.inc.php
-
-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.
-
diff --git a/plugins/sasl_password/chgsaslpasswd.c b/plugins/sasl_password/chgsaslpasswd.c
deleted file mode 100644
index 17e20c67f..000000000
--- a/plugins/sasl_password/chgsaslpasswd.c
+++ /dev/null
@@ -1,27 +0,0 @@
-#include <stdio.h>
-#include <unistd.h>
-
-// set the UID this script will run as (cyrus user)
-#define UID 96
-// set the path to saslpasswd or saslpasswd2
-#define CMD "/usr/sbin/saslpasswd2"
-
-/* INSTALLING:
- gcc -o chgsaslpasswd chgsaslpasswd.c
- chown root.apache chgsaslpasswd
- strip chgsaslpasswd
- chmod 4550 chgsaslpasswd
-*/
-
-main(int argc, char *argv[])
-{
- int rc,cc;
-
- cc = setuid(UID);
- rc = execvp(CMD, argv);
- if ((rc != 0) || (cc != 0))
- {
- fprintf(stderr,"__ %s: failed %d %d\n",argv[0],rc,cc);
- exit(1);
- }
-}
diff --git a/plugins/sasl_password/locale/de_CH.inc b/plugins/sasl_password/locale/de_CH.inc
deleted file mode 100644
index 399efda84..000000000
--- a/plugins/sasl_password/locale/de_CH.inc
+++ /dev/null
@@ -1,16 +0,0 @@
-<?php
-
-$labels = array();
-$labels['changepasswd'] = 'Passwort ändern';
-$labels['curpasswd'] = 'Aktuelles Passwort';
-$labels['newpasswd'] = 'Neues Passwort';
-$labels['confpasswd'] = 'Passwort Wiederholung';
-
-$messages = array();
-$messages['nopassword'] = "Bitte geben Sie ein neues Passwort ein";
-$messages['nocurpassword'] = "Bitte geben Sie Ihr aktuelles Passwort an";
-$messages['passwordincorrect'] = "Das aktuelle Passwort ist nicht korrekt";
-$messages['passwordinconsistency'] = "Das neue Passwort und dessen Wiederholung stimmen nicht überein";
-$messages['successfullysaved'] = "Ihr Passwort wurde erfolgreich geändert";
-
-?> \ No newline at end of file
diff --git a/plugins/sasl_password/locale/en_US.inc b/plugins/sasl_password/locale/en_US.inc
deleted file mode 100644
index 42708b34f..000000000
--- a/plugins/sasl_password/locale/en_US.inc
+++ /dev/null
@@ -1,16 +0,0 @@
-<?php
-
-$labels = array();
-$labels['changepasswd'] = 'Change Password';
-$labels['curpasswd'] = 'Current Password:';
-$labels['newpasswd'] = 'New Password:';
-$labels['confpasswd'] = 'Confirm New Password:';
-
-$messages = array();
-$messages['nopassword'] = "Please enter the new password";
-$messages['nocurpassword'] = "Please enter your current password";
-$messages['passwordincorrect'] = "Current password is incorrect";
-$messages['passwordinconsistency'] = "The new password and it's confirmation do not match";
-$messages['successfullysaved'] = "Successfully changed password";
-
-?> \ No newline at end of file
diff --git a/plugins/sasl_password/locale/pl_PL.inc b/plugins/sasl_password/locale/pl_PL.inc
deleted file mode 100644
index 10cf51ad6..000000000
--- a/plugins/sasl_password/locale/pl_PL.inc
+++ /dev/null
@@ -1,16 +0,0 @@
-<?php
-
-$labels = array();
-$labels['changepasswd'] = 'Zmiana hasła';
-$labels['curpasswd'] = 'Aktualne hasło:';
-$labels['newpasswd'] = 'Nowe hasło:';
-$labels['confpasswd'] = 'Potwierdź hasło:';
-
-$messages = array();
-$messages['nopassword'] = "Wprowadź nowe hasło";
-$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['successfullysaved'] = "Zapisano.";
-
-?> \ No newline at end of file
diff --git a/plugins/sasl_password/sasl_password.js b/plugins/sasl_password/sasl_password.js
deleted file mode 100644
index 719dc8268..000000000
--- a/plugins/sasl_password/sasl_password.js
+++ /dev/null
@@ -1,43 +0,0 @@
-/* SASL pssword change interface (tab) */
-
-function sasl_password_save()
-{
- var input_curpasswd = $('#saslcurpasswd')[0];
- var input_newpasswd = $('#saslnewpasswd')[0];
- var input_confpasswd = $('#saslconfpasswd')[0];
-
- if (input_curpasswd && input_curpasswd.value=='') {
- alert(rcmail.gettext('nocurpassword', 'sasl_password'));
- input_curpasswd.focus();
- }
- else if (input_newpasswd && input_newpasswd.value=='') {
- alert(rcmail.gettext('nopassword', 'sasl_password'));
- input_newpasswd.focus();
- }
- else if (input_confpasswd && input_confpasswd.value=='') {
- alert(rcmail.gettext('nopassword', 'sasl_password'));
- input_confpasswd.focus();
- }
- else if ((input_newpasswd && input_confpasswd) && (input_newpasswd.value != input_confpasswd.value)) {
- alert(rcmail.gettext('passwordinconsistency', 'sasl_password'));
- input_newpasswd.focus();
- }
- else {
- rcmail.gui_objects.passform.submit();
- }
-}
-
-if (window.rcmail) {
- rcmail.addEventListener('init', function(evt) {
- // <span id="settingstabdefault" class="tablink"><roundcube:button command="preferences" type="link" label="preferences" title="editpreferences" /></span>
- var tab = $('<span>').attr('id', 'settingstabpluginsaslpassword').addClass('tablink');
-
- var button = $('<a>').attr('href', rcmail.env.comm_path+'&_action=plugin.saslpassword').html(rcmail.gettext('password')).appendTo(tab);
- button.bind('click', function(e){ return rcmail.command('plugin.saslpassword', this) });
-
- // add button and register commands
- rcmail.add_element(tab, 'tabs');
- rcmail.register_command('plugin.saslpassword', function() { rcmail.goto_url('plugin.saslpassword') }, true);
- rcmail.register_command('plugin.saslpassword-save', sasl_password_save, true);
- });
-}
diff --git a/plugins/sasl_password/sasl_password.php b/plugins/sasl_password/sasl_password.php
deleted file mode 100644
index 0152ec2ba..000000000
--- a/plugins/sasl_password/sasl_password.php
+++ /dev/null
@@ -1,146 +0,0 @@
-<?php
-
-/**
- * Change SASL Password
- *
- * Plugin that adds functionality ty 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
- */
-class sasl_password extends rcube_plugin
-{
- public $task = 'settings';
-
- function init()
- {
- $rcmail = rcmail::get_instance();
- // add Tab label
- $rcmail->output->add_label('password');
- $this->register_action('plugin.saslpassword', array($this, 'password_init'));
- $this->register_action('plugin.saslpassword-save', array($this, 'password_save'));
- $this->include_script('sasl_password.js');
- }
-
- function password_init()
- {
- $this->add_texts('locale/');
- $this->register_handler('plugin.body', array($this, 'password_form'));
-
- $rcmail = rcmail::get_instance();
- $rcmail->output->set_pagetitle($this->gettext('changepasswd'));
- $rcmail->output->send('plugin');
- }
-
- function password_save()
- {
- $rcmail = rcmail::get_instance();
-
- $this->add_texts('locale/');
- $this->register_handler('plugin.body', array($this, 'password_form'));
-
- if (!isset($_POST['_curpasswd']) || !isset($_POST['_newpasswd'])) {
- $rcmail->output->command('display_message', $this->gettext('nopassword'), 'error');
- }
- else {
- $curpwd = get_input_value('_curpasswd', RCUBE_INPUT_POST);
- $newpwd = get_input_value('_newpasswd', RCUBE_INPUT_POST);
-
- if ($rcmail->decrypt($_SESSION['password']) != $curpwd) {
- $rcmail->output->command('display_message', $this->gettext('passwordincorrect'), 'error');
- }
- else if ($this->_save($newpwd)) {
- $rcmail->output->command('display_message', $this->gettext('successfullysaved'), 'confirmation');
- $_SESSION['password'] = $rcmail->encrypt($newpwd);
- }
- else {
- $rcmail->output->command('display_message', $this->gettext('errorsaving'), 'error');
- }
- }
-
- rcmail_overwrite_action('plugin.saslpassword');
- rcmail::get_instance()->output->send('plugin');
- }
-
- function password_form()
- {
- $rcmail = rcmail::get_instance();
-
- // add some labels to client
- $rcmail->output->add_label(
- 'sasl_password.nopassword',
- 'sasl_password.nocurpassword',
- 'sasl_password.passwordinconsistency',
- 'sasl_password.changepasswd'
- );
-
- $table = new html_table(array('cols' => 2));
-
- // show current password selection
- $field_id = 'saslcurpasswd';
- $input_newpasswd = new html_passwordfield(array('name' => '_curpasswd', 'id' => $field_id, 'size' => 25));
-
- $table->add('title', html::label($field_id, Q($this->gettext('curpasswd'))));
- $table->add(null, $input_newpasswd->show());
-
- // show new password selection
- $field_id = 'saslnewpasswd';
- $input_newpasswd = new html_passwordfield(array('name' => '_newpasswd', 'id' => $field_id, 'size' => 25));
-
- $table->add('title', html::label($field_id, Q($this->gettext('newpasswd'))));
- $table->add(null, $input_newpasswd->show());
-
- // show confirm password selection
- $field_id = 'saslconfpasswd';
- $input_confpasswd = new html_passwordfield(array('name' => '_confpasswd', 'id' => $field_id, 'size' => 25));
-
- $table->add('title', html::label($field_id, Q($this->gettext('confpasswd'))));
- $table->add(null, $input_confpasswd->show());
-
- $out = html::div(array('class' => "settingsbox", 'style' => "margin:0"),
- html::div(array('id' => "userprefs-title"), $this->gettext('changepasswd')) .
- html::div(array('style' => "padding:15px"), $table->show() .
- html::p(null,
- $rcmail->output->button(array(
- 'command' => 'plugin.saslpassword-save',
- 'type' => 'input',
- 'class' => 'button mainaction',
- 'label' => 'save'
- )))
- )
- );
-
- $rcmail->output->add_gui_object('passform', 'password-form');
-
- return $rcmail->output->form_tag(array(
- 'id' => 'password-form',
- 'name' => 'password-form',
- 'method' => 'post',
- 'action' => './?_task=settings&_action=plugin.saslpassword-save',
- ), $out);
- }
-
- private function _save($passwd)
- {
- $curdir = realpath(dirname(__FILE__));
- $username = escapeshellcmd($_SESSION['username']);
- $code = 1;
-
- if ($fh = popen("$curdir/chgsaslpasswd -p $username", 'w')) {
- fwrite($fh, $passwd."\n");
- $code = pclose($fh);
- }
-
- return ($code == 0);
- }
-
-}
-
-?>