You've already forked postfixadmin
mirror of
https://github.com/postfixadmin/postfixadmin.git
synced 2025-08-07 17:42:53 +03:00
Merge pull request #200 from doktoil-makresh/master
Support for password expiration, managed in PostFix Admin
This commit is contained in:
48
README.password_expiration
Normal file
48
README.password_expiration
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
*Description
|
||||||
|
|
||||||
|
This extension adds support for password expiration.
|
||||||
|
It is designed to have expiration on users passwords. An email is sent when the password is expiring in 30 days, then 14 days, then 7 days.
|
||||||
|
It is strongly inspired by https://abridge2devnull.com/posts/2014/09/29/dovecot-user-password-expiration-notifications-updated-4122015/, and adapted to fit with Postfix Admin & Roundcube's password plugin
|
||||||
|
Expiration unit is day
|
||||||
|
Expiration value for domain is set through Postfix Admin GUI
|
||||||
|
|
||||||
|
*Installation
|
||||||
|
|
||||||
|
Perform the following changes:
|
||||||
|
|
||||||
|
**Changes in MySQL/MariaDB mailbox table (as defined in $CONF['database_tables'] from config.inc.php):
|
||||||
|
|
||||||
|
You are invited to backup your DB first, and ensure the table name is correct.
|
||||||
|
|
||||||
|
Execute the attached SQL script (password_expiration.sql) that will add the required columns. The expiration value for existing users will be set to 90 days. If you want a different value, edit line 2 in the script and replace 90 by the required value.
|
||||||
|
|
||||||
|
**Changes in Postfix Admin :
|
||||||
|
|
||||||
|
To enable password expiration, add the following to your config.inc.php file:
|
||||||
|
$CONF['password_expiration_enabled'] = 'YES';
|
||||||
|
|
||||||
|
All my tests are performed using $CONF['encrypt'] = 'md5crypt';
|
||||||
|
|
||||||
|
**If you are using Roundcube's password plugin, you should also adapt the $config['password_query'] value.
|
||||||
|
|
||||||
|
I recommend to use:
|
||||||
|
|
||||||
|
$config['password_query'] = 'UPDATE mailbox SET password=%c, modified = now(), password_expiry = now() + interval 90 day';
|
||||||
|
|
||||||
|
of cource you may adapt to the expected expiration value
|
||||||
|
|
||||||
|
All my tests are performed using $config['password_algorithm'] = 'md5-crypt';
|
||||||
|
|
||||||
|
**Changes in Dovecot (adapt if you use another LDA)
|
||||||
|
|
||||||
|
Edit dovecot-mysql.conf file, and replace the user_query (and only this one) by this query:
|
||||||
|
|
||||||
|
password_query = SELECT username as user, password, concat('/var/vmail/', maildir) as userdb_var, concat('maildir:/var/vmail/', maildir) as userdb_mail, 20001 as userdb_uid, 20001 as userdb_gid, m.domain FROM mailbox m, domain d where d.domain = m.domain and m.username = '%u' AND m.active = '1' AND (m.pw_expires_on > now() or d.password_expiration_value = 0)
|
||||||
|
|
||||||
|
Of course you may require to adapt the uid, gid, maildir and table to your setup
|
||||||
|
|
||||||
|
**Changes in system
|
||||||
|
|
||||||
|
You need to have a script running on a daily basis to check password expiration and send emails 30, 14 and 7 days before password expiration (script attached: check_mailpass_expiration.sh).
|
||||||
|
Edit the script to adapt the variables to your setup.
|
||||||
|
This script is using postfixadmin.my.cnf to read credentials. Edit this file to enter a DB user that is allowed to access (read-write) your database. This file should be protected from any user (chmod 400).
|
20
check_mailpass_expiration.sh
Normal file
20
check_mailpass_expiration.sh
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#Adapt to your setup
|
||||||
|
|
||||||
|
POSTFIX_DB="postfix_test"
|
||||||
|
MYSQL_CREDENTIALS_FILE="postfixadmin.my.cnf"
|
||||||
|
|
||||||
|
REPLY_ADDRESS=noreply@example.com
|
||||||
|
|
||||||
|
# Change this list to change notification times and when ...
|
||||||
|
for INTERVAL in 30 14 7
|
||||||
|
do
|
||||||
|
LOWER=$(( $INTERVAL - 1 ))
|
||||||
|
|
||||||
|
QUERY="SELECT username,password_expiry FROM mailbox WHERE password_expiry > now() + interval $LOWER DAY AND password_expiry < NOW() + interval $INTERVAL DAY"
|
||||||
|
|
||||||
|
mysql --defaults-extra-file="$MYSQL_CREDENTIALS_FILE" "$POSTFIX_DB" -B -e "$QUERY" | while read -a RESULT ; do
|
||||||
|
echo -e "Dear User, \n Your password will expire on ${RESULT[1]}" | mail -s "Password 30 days before expiration notication" -r $REPLY_ADDRESS ${RESULT[0]}
|
||||||
|
done
|
||||||
|
|
||||||
|
done
|
@@ -516,6 +516,16 @@ $CONF['show_undeliverable']='YES';
|
|||||||
$CONF['show_undeliverable_color']='tomato';
|
$CONF['show_undeliverable_color']='tomato';
|
||||||
// mails to these domains will never be flagged as undeliverable
|
// mails to these domains will never be flagged as undeliverable
|
||||||
$CONF['show_undeliverable_exceptions']=array("unixmail.domain.ext","exchangeserver.domain.ext");
|
$CONF['show_undeliverable_exceptions']=array("unixmail.domain.ext","exchangeserver.domain.ext");
|
||||||
|
// show mailboxes with expired password
|
||||||
|
$CONF['show_expired']='YES';
|
||||||
|
$CONF['show_expired_color']='orange';
|
||||||
|
// show vacation enabled mailboxes
|
||||||
|
$CONF['show_vacation']='YES';
|
||||||
|
$CONF['show_vacation_color']='turquoise';
|
||||||
|
// show disabled accounts
|
||||||
|
$CONF['show_disabled']='YES';
|
||||||
|
$CONF['show_disabled_color']='grey';
|
||||||
|
// show POP/IMAP mailboxes
|
||||||
$CONF['show_popimap']='YES';
|
$CONF['show_popimap']='YES';
|
||||||
$CONF['show_popimap_color']='darkgrey';
|
$CONF['show_popimap_color']='darkgrey';
|
||||||
// you can assign special colors to some domains. To do this,
|
// you can assign special colors to some domains. To do this,
|
||||||
@@ -661,6 +671,11 @@ $CONF['theme_custom_css'] = '';
|
|||||||
// change to boolean true to enable xmlrpc
|
// change to boolean true to enable xmlrpc
|
||||||
$CONF['xmlrpc_enabled'] = false;
|
$CONF['xmlrpc_enabled'] = false;
|
||||||
|
|
||||||
|
//Account expiration info
|
||||||
|
//If you want to display the password expiracy status of the accounts (read-only)
|
||||||
|
//More details in README.password_expiration
|
||||||
|
$CONF['password_expiration_enable'] = 'YES';
|
||||||
|
|
||||||
// If you want to keep most settings at default values and/or want to ensure
|
// If you want to keep most settings at default values and/or want to ensure
|
||||||
// that future updates work without problems, you can use a separate config
|
// that future updates work without problems, you can use a separate config
|
||||||
// file (config.local.php) instead of editing this file and override some
|
// file (config.local.php) instead of editing this file and override some
|
||||||
|
@@ -260,6 +260,18 @@ function check_domain($domain) {
|
|||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get password expiration value for a domain
|
||||||
|
* @param string $domain - a string that may be a domain
|
||||||
|
* @return int password expiration value for this domain (DAYS, or zero if not enabled)
|
||||||
|
*/
|
||||||
|
function get_password_expiration_value ($domain) {
|
||||||
|
$table_domain = table_by_key('domain');
|
||||||
|
$query = "SELECT password_expiry FROM $table_domain WHERE domain='$domain'";
|
||||||
|
$result = db_query ($query);
|
||||||
|
$password_expiration_value = db_array ($result['result']);
|
||||||
|
return $password_expiration_value[0];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* check_email
|
* check_email
|
||||||
@@ -1871,7 +1883,7 @@ function db_delete($table, $where, $delete, $additionalwhere='') {
|
|||||||
* @param array $timestamp (optional) - array of fields to set to now() - default: array('created', 'modified')
|
* @param array $timestamp (optional) - array of fields to set to now() - default: array('created', 'modified')
|
||||||
* @return int - number of inserted rows
|
* @return int - number of inserted rows
|
||||||
*/
|
*/
|
||||||
function db_insert($table, $values, $timestamp = array('created', 'modified')) {
|
function db_insert ($table, $values, $timestamp = array('created', 'modified'), $timestamp_expiration = array('password_expiry') ) {
|
||||||
$table = table_by_key($table);
|
$table = table_by_key($table);
|
||||||
|
|
||||||
foreach (array_keys($values) as $key) {
|
foreach (array_keys($values) as $key) {
|
||||||
@@ -1886,6 +1898,19 @@ function db_insert($table, $values, $timestamp = array('created', 'modified')) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
global $CONF;
|
||||||
|
if ($CONF['password_expiration_enabled'] == 'YES') {
|
||||||
|
if ($table == 'mailbox') {
|
||||||
|
$domain_dirty = $values['domain'];
|
||||||
|
$domain = substr($domain_dirty, 1, -1); // really the update to the mailbox password_expiry should be based on a trigger, or a query like :
|
||||||
|
// .... NOW() + INTERVAL domain.password_expiry DAY
|
||||||
|
$password_expiration_value = get_password_expiration_value($domain);
|
||||||
|
foreach($timestamp_expiration as $key) {
|
||||||
|
$values[$key] = "now() + interval " . $password_expiration_value . " day";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$sql_values = "(" . implode(",", escape_string(array_keys($values))).") VALUES (".implode(",", $values).")";
|
$sql_values = "(" . implode(",", escape_string(array_keys($values))).") VALUES (".implode(",", $values).")";
|
||||||
|
|
||||||
$result = db_query("INSERT INTO $table $sql_values");
|
$result = db_query("INSERT INTO $table $sql_values");
|
||||||
@@ -1934,6 +1959,19 @@ function db_update_q($table, $where, $values, $timestamp = array('modified')) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
global $CONF;
|
||||||
|
if ($CONF['password_expiration_enabled'] == 'YES') {
|
||||||
|
$where_type = explode('=',$where);
|
||||||
|
$email = ($where_type[1]);
|
||||||
|
$domain_dirty = explode('@',$email)[1];
|
||||||
|
$domain = substr($domain_dirty, 0, -1);
|
||||||
|
if ($table == 'mailbox') {
|
||||||
|
$password_expiration_value = get_password_expiration_value($domain);
|
||||||
|
$key = 'password_expiry';
|
||||||
|
$sql_values[$key] = $key . " = now() + interval " . $password_expiration_value . " day";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$sql="UPDATE $table SET " . implode(",", $sql_values) . " WHERE $where";
|
$sql="UPDATE $table SET " . implode(",", $sql_values) . " WHERE $where";
|
||||||
|
|
||||||
$result = db_query($sql);
|
$result = db_query($sql);
|
||||||
@@ -2190,6 +2228,36 @@ function gen_show_status($show_alias) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Vacation CHECK
|
||||||
|
if ( $CONF['show_vacation'] == 'YES' ) {
|
||||||
|
$stat_result = db_query ("SELECT * FROM ". $CONF['database_tables']['vacation'] ." WHERE email = '" . $show_alias . "' AND active = 1");
|
||||||
|
if ($stat_result['rows'] == 1) {
|
||||||
|
$stat_string .= "<span style='background-color:" . $CONF['show_vacation_color'] . "'>" . $CONF['show_status_text'] . "</span> ";
|
||||||
|
} else {
|
||||||
|
$stat_string .= $CONF['show_status_text'] . " ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disabled CHECK
|
||||||
|
if ( $CONF['show_disabled'] == 'YES' ) {
|
||||||
|
$stat_result = db_query ("SELECT * FROM ". $CONF['database_tables']['mailbox'] ." WHERE username = '" . $show_alias . "' AND active = 0");
|
||||||
|
if ($stat_result['rows'] == 1) {
|
||||||
|
$stat_string .= "<span style='background-color:" . $CONF['show_disabled_color'] . "'>" . $CONF['show_status_text'] . "</span> ";
|
||||||
|
} else {
|
||||||
|
$stat_string .= $CONF['show_status_text'] . " ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Expired CHECK
|
||||||
|
if ( $CONF['show_expired'] == 'YES' ) {
|
||||||
|
$stat_result = db_query ("SELECT * FROM ". $CONF['database_tables']['mailbox'] ." WHERE username = '" . $show_alias . "' AND password_expiry <= now()");
|
||||||
|
if ($stat_result['rows'] == 1) {
|
||||||
|
$stat_string .= "<span style='background-color:" . $CONF['show_expired_color'] . "'>" . $CONF['show_status_text'] . "</span> ";
|
||||||
|
} else {
|
||||||
|
$stat_string .= $CONF['show_status_text'] . " ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// POP/IMAP CHECK
|
// POP/IMAP CHECK
|
||||||
if ($CONF['show_popimap'] == 'YES') {
|
if ($CONF['show_popimap'] == 'YES') {
|
||||||
$stat_delimiter = "";
|
$stat_delimiter = "";
|
||||||
|
@@ -348,6 +348,10 @@ $PALANG['broadcast_mailboxes_only'] = 'Only send to mailboxes';
|
|||||||
$PALANG['broadcast_to_domains'] = 'Send to domains:';
|
$PALANG['broadcast_to_domains'] = 'Send to domains:';
|
||||||
|
|
||||||
$PALANG['pStatus_undeliverable'] = 'maybe UNDELIVERABLE ';
|
$PALANG['pStatus_undeliverable'] = 'maybe UNDELIVERABLE ';
|
||||||
|
$PALANG['pStatus_disabled'] = 'Account disabled ';
|
||||||
|
$PALANG['pStatus_expired'] = 'Password expired ';
|
||||||
|
$PALANG['pStatus_vacation'] = 'Vacation enabled ';
|
||||||
|
|
||||||
$PALANG['pStatus_custom'] = 'Delivers to ';
|
$PALANG['pStatus_custom'] = 'Delivers to ';
|
||||||
$PALANG['pStatus_popimap'] = 'POP/IMAP ';
|
$PALANG['pStatus_popimap'] = 'POP/IMAP ';
|
||||||
|
|
||||||
@@ -407,6 +411,7 @@ $PALANG['pFetchmail_desc_returned_text'] = 'Text message from last polling';
|
|||||||
|
|
||||||
$PALANG['dateformat_pgsql'] = 'YYYY-mm-dd'; # translators: rearrange to your local date format, but make sure it's a valid PostgreSQL date format
|
$PALANG['dateformat_pgsql'] = 'YYYY-mm-dd'; # translators: rearrange to your local date format, but make sure it's a valid PostgreSQL date format
|
||||||
$PALANG['dateformat_mysql'] = '%Y-%m-%d'; # translators: rearrange to your local date format, but make sure it's a valid MySQL date format
|
$PALANG['dateformat_mysql'] = '%Y-%m-%d'; # translators: rearrange to your local date format, but make sure it's a valid MySQL date format
|
||||||
|
$PALANG['password_expiration'] = 'Pass expires';
|
||||||
|
|
||||||
$PALANG['please_keep_this_as_last_entry'] = ''; # needed for language-check.sh
|
$PALANG['please_keep_this_as_last_entry'] = ''; # needed for language-check.sh
|
||||||
/* vim: set expandtab ft=php softtabstop=3 tabstop=3 shiftwidth=3: */
|
/* vim: set expandtab ft=php softtabstop=3 tabstop=3 shiftwidth=3: */
|
||||||
|
@@ -342,6 +342,9 @@ $PALANG['pBroadcast_error_empty'] = 'Les champs "Nom", "Sujet" et "Message" ne p
|
|||||||
$PALANG['broadcast_mailboxes_only'] = 'Only send to mailboxes'; # XXX
|
$PALANG['broadcast_mailboxes_only'] = 'Only send to mailboxes'; # XXX
|
||||||
$PALANG['broadcast_to_domains'] = 'Send to domains:'; # XXX
|
$PALANG['broadcast_to_domains'] = 'Send to domains:'; # XXX
|
||||||
$PALANG['pStatus_undeliverable'] = 'Non délivrable ';
|
$PALANG['pStatus_undeliverable'] = 'Non délivrable ';
|
||||||
|
$PALANG['pStatus_vacation'] = 'Répondeur activé ';
|
||||||
|
$PALANG['pStatus_disabled'] = 'Compte désactivé ';
|
||||||
|
$PALANG['pStatus_expired'] = 'Mot de passe expiré ';
|
||||||
$PALANG['pStatus_custom'] = 'Délivré à ';
|
$PALANG['pStatus_custom'] = 'Délivré à ';
|
||||||
$PALANG['pStatus_popimap'] = 'POP/IMAP ';
|
$PALANG['pStatus_popimap'] = 'POP/IMAP ';
|
||||||
$PALANG['password_too_short'] = 'Mot de passe trop court. - %s caractères minimum';
|
$PALANG['password_too_short'] = 'Mot de passe trop court. - %s caractères minimum';
|
||||||
@@ -398,6 +401,7 @@ $PALANG['pFetchmail_desc_date'] = 'Date de la dernière vérification/changement
|
|||||||
$PALANG['pFetchmail_desc_returned_text'] = 'Message de la dernière vérification';
|
$PALANG['pFetchmail_desc_returned_text'] = 'Message de la dernière vérification';
|
||||||
$PALANG['dateformat_pgsql'] = 'dd-mm-YYYY';
|
$PALANG['dateformat_pgsql'] = 'dd-mm-YYYY';
|
||||||
$PALANG['dateformat_mysql'] = '%d-%m-%Y';
|
$PALANG['dateformat_mysql'] = '%d-%m-%Y';
|
||||||
|
$PALANG['password_expiration'] = 'Expiration du mot de passe';
|
||||||
|
|
||||||
$PALANG['please_keep_this_as_last_entry'] = ''; # needed for language-check.sh
|
$PALANG['please_keep_this_as_last_entry'] = ''; # needed for language-check.sh
|
||||||
/* vim: set expandtab ft=php softtabstop=3 tabstop=3 shiftwidth=3: */
|
/* vim: set expandtab ft=php softtabstop=3 tabstop=3 shiftwidth=3: */
|
||||||
|
@@ -94,6 +94,7 @@ class DomainHandler extends PFAHandler {
|
|||||||
'default_aliases' => pacol($this->new, $this->new, 0, 'bool', 'pAdminCreate_domain_defaultaliases', '' , 1,'', /*not in db*/ 1 ),
|
'default_aliases' => pacol($this->new, $this->new, 0, 'bool', 'pAdminCreate_domain_defaultaliases', '' , 1,'', /*not in db*/ 1 ),
|
||||||
'created' => pacol(0, 0, 0, 'ts', 'created' , '' ),
|
'created' => pacol(0, 0, 0, 'ts', 'created' , '' ),
|
||||||
'modified' => pacol(0, 0, $super, 'ts', 'last_modified' , '' ),
|
'modified' => pacol(0, 0, $super, 'ts', 'last_modified' , '' ),
|
||||||
|
'password_expiry' => pacol($super, $super, $super, 'num', 'password_expiration' , 'password_expiration_desc', ''),
|
||||||
'_can_edit' => pacol(0, 0, 1, 'int', '' , '' , 0 ,
|
'_can_edit' => pacol(0, 0, 1, 'int', '' , '' , 0 ,
|
||||||
/*options*/ '',
|
/*options*/ '',
|
||||||
/*not_in_db*/ 0,
|
/*not_in_db*/ 0,
|
||||||
|
@@ -49,6 +49,7 @@ class MailboxHandler extends PFAHandler {
|
|||||||
'token_validity' => pacol(1, 0, 0, 'ts', '' , '', date("Y-m-d H:i:s",time())),
|
'token_validity' => pacol(1, 0, 0, 'ts', '' , '', date("Y-m-d H:i:s",time())),
|
||||||
'created' => pacol(0, 0, 1, 'ts', 'created' , '' ),
|
'created' => pacol(0, 0, 1, 'ts', 'created' , '' ),
|
||||||
'modified' => pacol(0, 0, 1, 'ts', 'last_modified' , '' ),
|
'modified' => pacol(0, 0, 1, 'ts', 'last_modified' , '' ),
|
||||||
|
'password_expiry' => pacol(0, 0, 1, 'ts', 'password_expiration' , '' ),
|
||||||
# TODO: add virtual 'notified' column and allow to display who received a vacation response?
|
# TODO: add virtual 'notified' column and allow to display who received a vacation response?
|
||||||
);
|
);
|
||||||
|
|
||||||
|
3
password_expiration.sql
Normal file
3
password_expiration.sql
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
ALTER TABLE mailbox ADD COLUMN password_expiry TIMESTAMP DEFAULT now() not null;
|
||||||
|
UPDATE mailbox set password_expiry = now() + interval 90 day;
|
||||||
|
ALTER TABLE domain ADD COLUMN password_expiry int DEFAULT 0;
|
3
postfixadmin.my.cnf
Normal file
3
postfixadmin.my.cnf
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
[client]
|
||||||
|
user=postfix_read_write_account
|
||||||
|
password=strong_password
|
@@ -165,6 +165,7 @@ $tAlias = $handler->result();
|
|||||||
#
|
#
|
||||||
|
|
||||||
$display_mailbox_aliases = Config::bool('alias_control_admin');
|
$display_mailbox_aliases = Config::bool('alias_control_admin');
|
||||||
|
$password_expiration = Config::bool('password_expiration');
|
||||||
|
|
||||||
# build the sql query
|
# build the sql query
|
||||||
$sql_select = "SELECT $table_mailbox.* ";
|
$sql_select = "SELECT $table_mailbox.* ";
|
||||||
@@ -190,6 +191,10 @@ if ($display_mailbox_aliases) {
|
|||||||
$sql_join .= " LEFT JOIN $table_alias ON $table_mailbox.username=$table_alias.address ";
|
$sql_join .= " LEFT JOIN $table_alias ON $table_mailbox.username=$table_alias.address ";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($password_expiration) {
|
||||||
|
$sql_select .= ", $table_mailbox.password_expiry as password_expiration ";
|
||||||
|
}
|
||||||
|
|
||||||
if (Config::bool('vacation_control_admin')) {
|
if (Config::bool('vacation_control_admin')) {
|
||||||
$table_vacation = table_by_key('vacation');
|
$table_vacation = table_by_key('vacation');
|
||||||
$sql_select .= ", $table_vacation.active AS v_active ";
|
$sql_select .= ", $table_vacation.active AS v_active ";
|
||||||
|
@@ -88,11 +88,11 @@ function _upgrade_filter_function($name) {
|
|||||||
return preg_match('/upgrade_[\d]+(_mysql|_pgsql|_sqlite|_mysql_pgsql)?$/', $name) == 1;
|
return preg_match('/upgrade_[\d]+(_mysql|_pgsql|_sqlite|_mysql_pgsql)?$/', $name) == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function _db_add_field($table, $field, $fieldtype, $after) {
|
function _db_add_field($table, $field, $fieldtype, $after = '') {
|
||||||
global $CONF;
|
global $CONF;
|
||||||
|
|
||||||
$query = "ALTER TABLE " . table_by_key($table) . " ADD COLUMN $field $fieldtype";
|
$query = "ALTER TABLE " . table_by_key($table) . " ADD COLUMN $field $fieldtype";
|
||||||
if ($CONF['database_type'] == 'mysql') {
|
if ($CONF['database_type'] == 'mysql' && !empty($after)) {
|
||||||
$query .= " AFTER $after "; # PgSQL does not support to specify where to add the column, MySQL does
|
$query .= " AFTER $after "; # PgSQL does not support to specify where to add the column, MySQL does
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1760,3 +1760,8 @@ function upgrade_1841_sqlite() {
|
|||||||
_db_add_field($table, 'token_validity', '{DATETIME}', 'token');
|
_db_add_field($table, 'token_validity', '{DATETIME}', 'token');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function upgrade_1842() {
|
||||||
|
_db_add_field('mailbox', 'password_expiry', "{DATETIME}"); // when a specific mailbox password expires
|
||||||
|
_db_add_field('domain', 'password_expiry', 'int DEFAULT 0'); // expiry applied to mailboxes within that domain
|
||||||
|
}
|
||||||
|
@@ -71,6 +71,16 @@
|
|||||||
{if $CONF.show_undeliverable===YES}
|
{if $CONF.show_undeliverable===YES}
|
||||||
<span style='background-color:{$CONF.show_undeliverable_color};'>{$CONF.show_status_text}</span>={$PALANG.pStatus_undeliverable}
|
<span style='background-color:{$CONF.show_undeliverable_color};'>{$CONF.show_status_text}</span>={$PALANG.pStatus_undeliverable}
|
||||||
{/if}
|
{/if}
|
||||||
|
{if $CONF.show_vacation===YES}
|
||||||
|
<span style='background-color:{$CONF.show_vacation_color};'>{$CONF.show_status_text}</span>={$PALANG.pStatus_vacation}
|
||||||
|
{/if}
|
||||||
|
{if $CONF.show_disabled===YES}
|
||||||
|
<span style='background-color:{$CONF.show_disabled_color};'>{$CONF.show_status_text}</span>={$PALANG.pStatus_disabled}
|
||||||
|
{/if}
|
||||||
|
{if $CONF.show_expired===YES}
|
||||||
|
<span style='background-color:{$CONF.show_expired_color};'>{$CONF.show_status_text}</span>={$PALANG.pStatus_expired}
|
||||||
|
{/if}
|
||||||
|
|
||||||
{if $CONF.show_popimap===YES}
|
{if $CONF.show_popimap===YES}
|
||||||
<span style='background-color:{$CONF.show_popimap_color};'>{$CONF.show_status_text}</span>={$PALANG.pStatus_popimap}
|
<span style='background-color:{$CONF.show_popimap_color};'>{$CONF.show_status_text}</span>={$PALANG.pStatus_popimap}
|
||||||
{/if}
|
{/if}
|
||||||
|
@@ -13,6 +13,9 @@
|
|||||||
<td>{$PALANG.name}</td>
|
<td>{$PALANG.name}</td>
|
||||||
{if $CONF.quota===YES}<td>{$PALANG.pOverview_mailbox_quota}</td>{/if}
|
{if $CONF.quota===YES}<td>{$PALANG.pOverview_mailbox_quota}</td>{/if}
|
||||||
<td>{$PALANG.last_modified}</td>
|
<td>{$PALANG.last_modified}</td>
|
||||||
|
{if $CONF.password_expiration===YES}
|
||||||
|
<td>{$PALANG.password_expiration}</td>
|
||||||
|
{/if}
|
||||||
<td>{$PALANG.active}</td>
|
<td>{$PALANG.active}</td>
|
||||||
{assign var="colspan" value="`$colspan-6`"}
|
{assign var="colspan" value="`$colspan-6`"}
|
||||||
<td colspan="{$colspan}"> </td>
|
<td colspan="{$colspan}"> </td>
|
||||||
@@ -74,6 +77,9 @@
|
|||||||
</td>
|
</td>
|
||||||
{/if}
|
{/if}
|
||||||
<td>{$item.modified}</td>
|
<td>{$item.modified}</td>
|
||||||
|
{if $CONF.password_expiration===YES}
|
||||||
|
<td>{$item.password_expiration}</td>
|
||||||
|
{/if}
|
||||||
<td><a href="{#url_editactive#}mailbox&id={$item.username|escape:"url"}&active={if ($item.active==0)}1{else}0{/if}&token={$smarty.session.PFA_token|escape:"url"}"
|
<td><a href="{#url_editactive#}mailbox&id={$item.username|escape:"url"}&active={if ($item.active==0)}1{else}0{/if}&token={$smarty.session.PFA_token|escape:"url"}"
|
||||||
>{if $item.active==1}{$PALANG.YES}{else}{$PALANG.NO}{/if}</a></td>
|
>{if $item.active==1}{$PALANG.YES}{else}{$PALANG.NO}{/if}</a></td>
|
||||||
{if $CONF.vacation_control_admin===YES && $CONF.vacation===YES}
|
{if $CONF.vacation_control_admin===YES && $CONF.vacation===YES}
|
||||||
|
Reference in New Issue
Block a user