A SASL password changing plugin inspired by the Squirrelmail Change SASL Password Plugin
parent
3db528bd5c
commit
652a7f0ed2
@ -0,0 +1,65 @@
|
||||
+-------------------------------------------------------------------------+
|
||||
|
|
||||
| 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.
|
||||
|
@ -0,0 +1,27 @@
|
||||
#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);
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
<?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";
|
||||
|
||||
?>
|
@ -0,0 +1,16 @@
|
||||
<?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";
|
||||
|
||||
?>
|
@ -0,0 +1,43 @@
|
||||
/* 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);
|
||||
});
|
||||
}
|
@ -0,0 +1,144 @@
|
||||
<?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->register_handler('plugin.body', array($this, 'password_form'));
|
||||
$this->include_script('sasl_password.js');
|
||||
}
|
||||
|
||||
function password_init()
|
||||
{
|
||||
$this->add_texts('locale/');
|
||||
$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/');
|
||||
|
||||
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 ($_SESSION['password'] != $rcmail->encrypt_passwd($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_passwd($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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
Loading…
Reference in New Issue