0
0
mirror of https://github.com/postfixadmin/postfixadmin.git synced 2024-09-19 19:22:14 +02:00

Suport for dovecot mail-crypt-plugin via new mailbox_postpassword_script hook.

Uses doveadm mailbox cryptokey on create user / password change to adjust user encryption key.
https://doc.dovecot.org/configuration_manual/mail_crypt_plugin/
This commit is contained in:
BotoX 2021-01-11 20:25:30 +01:00
parent 6b2fa8e607
commit c6ae3ea2f3
8 changed files with 99 additions and 24 deletions

View File

@ -0,0 +1,13 @@
#!/bin/bash
# Example script for dovecot mail-crypt-plugin
# https://doc.dovecot.org/configuration_manual/mail_crypt_plugin/
# New user
if [ -z "$3" ]; then
doveadm -o plugin/mail_crypt_private_password="$4" mailbox cryptokey generate -u "$1" -U
exit 0
fi
# Password change
doveadm mailbox cryptokey password -u "$1" -o "$3" -n "$4"

View File

@ -589,6 +589,16 @@ $CONF['mailbox_postedit_script'] = '';
// $CONF['mailbox_postdeletion_script']='sudo -u courier /usr/local/bin/postfixadmin-mailbox-postdeletion.sh';
$CONF['mailbox_postdeletion_script'] = '';
// Optional:
// Script to run after setting a mailbox password. (New mailbox [$4 = empty] or change existing password)
// Disables changing password without entering old password.
// Note that this may fail if PHP is run in "safe mode", or if
// operating system features (such as SELinux) or limitations
// prevent the web-server from executing external scripts.
// Parameters: (1) username (2) domain (3) old password (4) new password
// $CONF['mailbox_postpassword_script']='/usr/local/bin/postfixadmin-mailbox-postpassword.sh';
$CONF['mailbox_postpassword_script'] = '';
// Optional:
// Script to run after creation of domains.
// Note that this may fail if PHP is run in "safe mode", or if

View File

@ -279,6 +279,7 @@ $PALANG['domain_postcreate_failed'] = 'The domain postcreate script failed, chec
$PALANG['mailbox_postdel_failed'] = 'The mailbox postdeletion script failed, check the error log for details!';
$PALANG['mailbox_postedit_failed'] = 'The mailbox postedit script failed, check the error log for details!';
$PALANG['mailbox_postcreate_failed'] = 'The mailbox postcreate script failed, check the error log for details!';
$PALANG['mailbox_postpassword_failed'] = 'The mailbox postpassword script failed, check the error log for details!';
$PALANG['pAdminDelete_alias_domain_error'] = 'Unable to remove domain alias!';
$PALANG['domain_conflict_vacation_domain'] = 'You can\'t use the vacation domain as mail domain!';

View File

@ -103,6 +103,29 @@ class Login {
}
db_log($domain, 'edit_password', $username);
$cmd_pw = Config::read('mailbox_postpassword_script');
$warnmsg_pw = Config::Lang('mailbox_postpassword_failed');
if (empty($cmd_pw)) {
return true;
} # nothing to do
$cmdarg1=escapeshellarg($this->id);
$cmdarg2=escapeshellarg($domain);
$cmdarg3=escapeshellarg($old_password);
$cmdarg4=escapeshellarg($new_password);
$command= "$cmd_pw $cmdarg1 $cmdarg2 $cmdarg3 $cmdarg4";
$retval=0;
$output=array();
$firstline='';
$firstline=exec($command, $output, $retval);
if (0!=$retval) {
error_log("Running $command yielded return value=$retval, first line of output=$firstline");
$this->errormsg[] = $warnmsg_pw;
return false;
}
return true;
}
}

View File

@ -12,11 +12,15 @@ class MailboxHandler extends PFAHandler {
# init $this->struct, $this->db_table and $this->id_field
protected function initStruct() {
$passwordReset = (int) Config::bool('forgotten_user_password_reset');
$passwordReset = (int) Config::bool('forgotten_user_password_reset') && !Config::read('mailbox_postpassword_script');
$reset_by_sms = 0;
if ($passwordReset && Config::read_string('sms_send_function')) {
$reset_by_sms = 1;
}
$editPw = 1;
if (!$this->new && Config::read('mailbox_postpassword_script')) {
$editPw = 0;
}
$this->struct = array(
@ -29,8 +33,8 @@ class MailboxHandler extends PFAHandler {
# TODO: maildir: display in list is needed to include maildir in SQL result (for post_edit hook)
# TODO: (not a perfect solution, but works for now - maybe we need a separate "include in SELECT query" field?)
'maildir' => pacol($this->new, 0, 1, 'text', '' , '' , '' ),
'password' => pacol(1, 1, 0, 'pass', 'password' , 'pCreate_mailbox_password_text' , '' ),
'password2' => pacol(1, 1, 0, 'pass', 'password_again' , '' , '',
'password' => pacol($editPw, $editPw,0, 'pass', 'password' , 'pCreate_mailbox_password_text' , '' ),
'password2' => pacol($editPw, $editPw,0, 'pass', 'password_again' , '' , '',
/*options*/ array(),
/*not_in_db*/ 0,
/*dont_write_to_db*/ 1,
@ -577,7 +581,12 @@ class MailboxHandler extends PFAHandler {
$warnmsg = Config::Lang('mailbox_postedit_failed');
}
if (empty($cmd)) {
if ($this->new) {
$cmd_pw = Config::read('mailbox_postpassword_script');
$warnmsg_pw = Config::Lang('mailbox_postpassword_failed');
}
if (empty($cmd) && empty($cmd_pw)) {
return true;
} # nothing to do
@ -591,23 +600,42 @@ class MailboxHandler extends PFAHandler {
$cmdarg1=escapeshellarg($this->id);
$cmdarg2=escapeshellarg($domain);
$cmdarg3=escapeshellarg($this->values['maildir']);
if ($quota <= 0) {
$quota = 0;
} # TODO: check if this is correct behaviour
$cmdarg4 = escapeshellarg("" . $quota);
$command= "$cmd $cmdarg1 $cmdarg2 $cmdarg3 $cmdarg4";
$retval=0;
$output=array();
$firstline='';
$firstline=exec($command, $output, $retval);
if (0!=$retval) {
error_log("Running $command yielded return value=$retval, first line of output=$firstline");
$this->errormsg[] = $warnmsg;
return false;
$status = true;
if (!empty($cmd)) {
$cmdarg3=escapeshellarg($this->values['maildir']);
if ($quota <= 0) {
$quota = 0;
} # TODO: check if this is correct behaviour
$cmdarg4 = escapeshellarg("" . $quota);
$command= "$cmd $cmdarg1 $cmdarg2 $cmdarg3 $cmdarg4";
$retval=0;
$output=array();
$firstline='';
$firstline=exec($command, $output, $retval);
if (0!=$retval) {
error_log("Running $command yielded return value=$retval, first line of output=$firstline");
$this->errormsg[] .= $warnmsg;
$status = false;
}
}
return true;
if (!empty($cmd_pw)) {
$cmdarg3='""';
$cmdarg4=escapeshellarg($this->values['password']);
$command= "$cmd_pw $cmdarg1 $cmdarg2 $cmdarg3 $cmdarg4";
$retval=0;
$output=array();
$firstline='';
$firstline=exec($command, $output, $retval);
if (0!=$retval) {
error_log("Running $command yielded return value=$retval, first line of output=$firstline");
$this->errormsg[] .= $warnmsg_pw;
$status = false;
}
}
return $status;
}
/**

View File

@ -71,7 +71,7 @@ $_SESSION['PFA_token'] = md5(uniqid('pfa' . rand(), true));
$smarty->assign('language_selector', language_selector(), false);
$smarty->assign('smarty_template', 'login');
$smarty->assign('logintype', 'user');
$smarty->assign('forgotten_password_reset', Config::read('forgotten_user_password_reset'));
$smarty->assign('forgotten_password_reset', Config::read('forgotten_user_password_reset') && !Config::read('mailbox_postpassword_script'));
$smarty->display('index.tpl');
/* vim: set expandtab softtabstop=3 tabstop=3 shiftwidth=3: */

View File

@ -40,8 +40,8 @@ $CONF = Config::getInstance()->getAll();
$smarty->configureTheme($rel_path);
if ($context === 'admin' && !Config::read('forgotten_admin_password_reset') || $context === 'users' && !Config::read('forgotten_user_password_reset')) {
die('Password reset is disabled by configuration option: forgotten_admin_password_reset');
if ($context === 'admin' && !Config::read('forgotten_admin_password_reset') || $context === 'users' && (!Config::read('forgotten_user_password_reset') || Config::read('mailbox_postpassword_script')) {
die('Password reset is disabled by configuration option: forgotten_admin_password_reset or mailbox_postpassword_script');
}
if ($_SERVER['REQUEST_METHOD'] === 'GET') {

View File

@ -39,8 +39,8 @@ require_once($rel_path . 'common.php');
if ($context === 'admin' && !Config::read('forgotten_admin_password_reset') || $context === 'users' && !Config::read('forgotten_user_password_reset')) {
die('Password reset is disabled by configuration option: forgotten_admin_password_reset');
if ($context === 'admin' && !Config::read('forgotten_admin_password_reset') || $context === 'users' && (!Config::read('forgotten_user_password_reset') || Config::read('mailbox_postpassword_script'))) {
die('Password reset is disabled by configuration option: forgotten_admin_password_reset or mailbox_postpassword_script');
}
function sendCodebyEmail($to, $username, $code) {