You've already forked postfixadmin
mirror of
https://github.com/postfixadmin/postfixadmin.git
synced 2025-08-06 06:42:37 +03: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:
13
ADDITIONS/postfixadmin-mailbox-postpassword.sh
Normal file
13
ADDITIONS/postfixadmin-mailbox-postpassword.sh
Normal 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"
|
@@ -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']='sudo -u courier /usr/local/bin/postfixadmin-mailbox-postdeletion.sh';
|
||||||
$CONF['mailbox_postdeletion_script'] = '';
|
$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:
|
// Optional:
|
||||||
// Script to run after creation of domains.
|
// Script to run after creation of domains.
|
||||||
// Note that this may fail if PHP is run in "safe mode", or if
|
// Note that this may fail if PHP is run in "safe mode", or if
|
||||||
|
@@ -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_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_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_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['pAdminDelete_alias_domain_error'] = 'Unable to remove domain alias!';
|
||||||
$PALANG['domain_conflict_vacation_domain'] = 'You can\'t use the vacation domain as mail domain!';
|
$PALANG['domain_conflict_vacation_domain'] = 'You can\'t use the vacation domain as mail domain!';
|
||||||
|
|
||||||
|
@@ -103,6 +103,29 @@ class Login {
|
|||||||
}
|
}
|
||||||
|
|
||||||
db_log($domain, 'edit_password', $username);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -12,11 +12,15 @@ class MailboxHandler extends PFAHandler {
|
|||||||
|
|
||||||
# init $this->struct, $this->db_table and $this->id_field
|
# init $this->struct, $this->db_table and $this->id_field
|
||||||
protected function initStruct() {
|
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;
|
$reset_by_sms = 0;
|
||||||
if ($passwordReset && Config::read_string('sms_send_function')) {
|
if ($passwordReset && Config::read_string('sms_send_function')) {
|
||||||
$reset_by_sms = 1;
|
$reset_by_sms = 1;
|
||||||
}
|
}
|
||||||
|
$editPw = 1;
|
||||||
|
if (!$this->new && Config::read('mailbox_postpassword_script')) {
|
||||||
|
$editPw = 0;
|
||||||
|
}
|
||||||
|
|
||||||
$this->struct = array(
|
$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: 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?)
|
# 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', '' , '' , '' ),
|
'maildir' => pacol($this->new, 0, 1, 'text', '' , '' , '' ),
|
||||||
'password' => pacol(1, 1, 0, 'pass', 'password' , 'pCreate_mailbox_password_text' , '' ),
|
'password' => pacol($editPw, $editPw,0, 'pass', 'password' , 'pCreate_mailbox_password_text' , '' ),
|
||||||
'password2' => pacol(1, 1, 0, 'pass', 'password_again' , '' , '',
|
'password2' => pacol($editPw, $editPw,0, 'pass', 'password_again' , '' , '',
|
||||||
/*options*/ array(),
|
/*options*/ array(),
|
||||||
/*not_in_db*/ 0,
|
/*not_in_db*/ 0,
|
||||||
/*dont_write_to_db*/ 1,
|
/*dont_write_to_db*/ 1,
|
||||||
@@ -577,7 +581,12 @@ class MailboxHandler extends PFAHandler {
|
|||||||
$warnmsg = Config::Lang('mailbox_postedit_failed');
|
$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;
|
return true;
|
||||||
} # nothing to do
|
} # nothing to do
|
||||||
|
|
||||||
@@ -591,23 +600,42 @@ class MailboxHandler extends PFAHandler {
|
|||||||
|
|
||||||
$cmdarg1=escapeshellarg($this->id);
|
$cmdarg1=escapeshellarg($this->id);
|
||||||
$cmdarg2=escapeshellarg($domain);
|
$cmdarg2=escapeshellarg($domain);
|
||||||
$cmdarg3=escapeshellarg($this->values['maildir']);
|
$status = true;
|
||||||
if ($quota <= 0) {
|
|
||||||
$quota = 0;
|
if (!empty($cmd)) {
|
||||||
} # TODO: check if this is correct behaviour
|
$cmdarg3=escapeshellarg($this->values['maildir']);
|
||||||
$cmdarg4 = escapeshellarg("" . $quota);
|
if ($quota <= 0) {
|
||||||
$command= "$cmd $cmdarg1 $cmdarg2 $cmdarg3 $cmdarg4";
|
$quota = 0;
|
||||||
$retval=0;
|
} # TODO: check if this is correct behaviour
|
||||||
$output=array();
|
$cmdarg4 = escapeshellarg("" . $quota);
|
||||||
$firstline='';
|
$command= "$cmd $cmdarg1 $cmdarg2 $cmdarg3 $cmdarg4";
|
||||||
$firstline=exec($command, $output, $retval);
|
$retval=0;
|
||||||
if (0!=$retval) {
|
$output=array();
|
||||||
error_log("Running $command yielded return value=$retval, first line of output=$firstline");
|
$firstline='';
|
||||||
$this->errormsg[] = $warnmsg;
|
$firstline=exec($command, $output, $retval);
|
||||||
return false;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -71,7 +71,7 @@ $_SESSION['PFA_token'] = md5(uniqid('pfa' . rand(), true));
|
|||||||
$smarty->assign('language_selector', language_selector(), false);
|
$smarty->assign('language_selector', language_selector(), false);
|
||||||
$smarty->assign('smarty_template', 'login');
|
$smarty->assign('smarty_template', 'login');
|
||||||
$smarty->assign('logintype', 'user');
|
$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');
|
$smarty->display('index.tpl');
|
||||||
|
|
||||||
/* vim: set expandtab softtabstop=3 tabstop=3 shiftwidth=3: */
|
/* vim: set expandtab softtabstop=3 tabstop=3 shiftwidth=3: */
|
||||||
|
@@ -40,8 +40,8 @@ $CONF = Config::getInstance()->getAll();
|
|||||||
|
|
||||||
$smarty->configureTheme($rel_path);
|
$smarty->configureTheme($rel_path);
|
||||||
|
|
||||||
if ($context === 'admin' && !Config::read('forgotten_admin_password_reset') || $context === 'users' && !Config::read('forgotten_user_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');
|
die('Password reset is disabled by configuration option: forgotten_admin_password_reset or mailbox_postpassword_script');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||||
|
@@ -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')) {
|
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');
|
die('Password reset is disabled by configuration option: forgotten_admin_password_reset or mailbox_postpassword_script');
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendCodebyEmail($to, $username, $code) {
|
function sendCodebyEmail($to, $username, $code) {
|
||||||
|
Reference in New Issue
Block a user