From 77d1b6c2e768b6307daed7eba23137a2daada125 Mon Sep 17 00:00:00 2001 From: David Goodwin Date: Tue, 28 Aug 2018 21:19:56 +0100 Subject: [PATCH] rename sql fields to just have mailbox.password_expiry and domain.password_expiry --- README.password_expiration | 14 ++++++++++++-- functions.inc.php | 38 +++++++++++++++++--------------------- model/DomainHandler.php | 2 +- model/MailboxHandler.php | 2 +- password_expiration.sql | 6 +++--- public/list-virtual.php | 2 +- 6 files changed, 35 insertions(+), 29 deletions(-) diff --git a/README.password_expiration b/README.password_expiration index 57ddd89f..9baca32b 100644 --- a/README.password_expiration +++ b/README.password_expiration @@ -1,4 +1,5 @@ *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 @@ -6,33 +7,42 @@ 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(),pw_expires_on=now() + interval 90 day'; + +$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: -user_query = SELECT concat('/var/vmail/', m.maildir) as home, concat('maildir:/var/vmail/', m.maildir) as mail, 20001 AS uid, 20001 AS gid, concat('dirsize:storage=', m.quota) AS quota, m.domain FROM mailbox m ,domain d WHERE d.domain = m.domain and m.username = 'tutu@eyetech-software.com' AND m.active = '1' and (m.pw_expires_on > now() or d.password_expiration_value = 0) + +user_query = SELECT concat('/var/vmail/', m.maildir) as home, concat('maildir:/var/vmail/', m.maildir) as mail, 20001 AS uid, 20001 AS gid, concat('dirsize:storage=', m.quota) AS quota, m.domain FROM mailbox m ,domain d WHERE d.domain = m.domain and m.username = 'tutu@eyetech-software.com' AND m.active = '1' and (m.password_expiry > now() or d.password_expiry = 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). diff --git a/functions.inc.php b/functions.inc.php index b70e146d..67b9f110 100644 --- a/functions.inc.php +++ b/functions.inc.php @@ -261,15 +261,13 @@ function check_domain($domain) { } /** - * get_password_expiration_value * Get password expiration value for a domain - * @param String $domain - a string that may be a domain - * @return password expiration value for this domain - * TODO: return specific value for invalid (not existing) 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_expiration_value FROM $table_domain WHERE domain='$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]; @@ -1879,7 +1877,7 @@ function db_delete($table, $where, $delete, $additionalwhere='') { * @param array (optional) - array of fields to set to now() - default: array('created', 'modified') * @return int - number of inserted rows */ -function db_insert ($table, $values, $timestamp = array('created', 'modified'), $timestamp_expiration = array('pw_expires_on') ) { +function db_insert ($table, $values, $timestamp = array('created', 'modified'), $timestamp_expiration = array('password_expiry') ) { $table = table_by_key($table); foreach (array_keys($values) as $key) { @@ -1898,7 +1896,8 @@ function db_insert ($table, $values, $timestamp = array('created', 'modified'), if ($CONF['password_expiration_enabled'] == 'YES') { if ($table == 'mailbox') { $domain_dirty = $values['domain']; - $domain = substr($domain_dirty, 1, -1); + $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"; @@ -1962,8 +1961,8 @@ function db_update_q($table, $where, $values, $timestamp = array('modified')) { $domain = substr($domain_dirty, 0, -1); if ($table == 'mailbox') { $password_expiration_value = get_password_expiration_value($domain); - $key = 'pw_expires_on'; - $sql_values[$key] = escape_string($key) . "=now() + interval " . $password_expiration_value . " day"; + $key = 'password_expiry'; + $sql_values[$key] = $key . " = now() + interval " . $password_expiration_value . " day"; } } @@ -2219,10 +2218,9 @@ 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 .= "" . $CONF['show_status_text'] . " "; + $stat_result = db_query ("SELECT * FROM ". $CONF['database_tables']['vacation'] ." WHERE email = '" . $show_alias . "' AND active = 1"); + if ($stat_result['rows'] == 1) { + $stat_string .= "" . $CONF['show_status_text'] . " "; } else { $stat_string .= $CONF['show_status_text'] . " "; } @@ -2230,10 +2228,9 @@ function gen_show_status($show_alias) { // 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 .= "" . $CONF['show_status_text'] . " "; + $stat_result = db_query ("SELECT * FROM ". $CONF['database_tables']['mailbox'] ." WHERE username = '" . $show_alias . "' AND active = 0"); + if ($stat_result['rows'] == 1) { + $stat_string .= "" . $CONF['show_status_text'] . " "; } else { $stat_string .= $CONF['show_status_text'] . " "; } @@ -2241,10 +2238,9 @@ function gen_show_status($show_alias) { // Expired CHECK if ( $CONF['show_expired'] == 'YES' ) { - $stat_result = db_query ("SELECT * FROM ". $CONF['database_tables']['mailbox'] ." WHERE username = '" . $show_alias . "' AND pw_expires_on <= now()"); - if ($stat_result['rows'] == 1) { - $stat_string .= "" . $CONF['show_status_text'] . " "; + $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 .= "" . $CONF['show_status_text'] . " "; } else { $stat_string .= $CONF['show_status_text'] . " "; } diff --git a/model/DomainHandler.php b/model/DomainHandler.php index a347e06b..b140f0d1 100644 --- a/model/DomainHandler.php +++ b/model/DomainHandler.php @@ -94,7 +94,7 @@ class DomainHandler extends PFAHandler { 'default_aliases' => pacol($this->new, $this->new, 0, 'bool', 'pAdminCreate_domain_defaultaliases', '' , 1,'', /*not in db*/ 1 ), 'created' => pacol(0, 0, 0, 'ts', 'created' , '' ), 'modified' => pacol(0, 0, $super, 'ts', 'last_modified' , '' ), - 'password_expiration_value' => pacol($super,$super,$super,'num','password_expiration', 'password_expiration_desc', ''), + 'password_expiry' => pacol($super, $super, $super, 'num', 'password_expiration' , 'password_expiration_desc', ''), '_can_edit' => pacol(0, 0, 1, 'int', '' , '' , 0 , /*options*/ '', /*not_in_db*/ 0, diff --git a/model/MailboxHandler.php b/model/MailboxHandler.php index 32d9dde8..d8fe2368 100644 --- a/model/MailboxHandler.php +++ b/model/MailboxHandler.php @@ -49,7 +49,7 @@ class MailboxHandler extends PFAHandler { 'token_validity' => pacol(1, 0, 0, 'ts', '' , '', date("Y-m-d H:i:s",time())), 'created' => pacol(0, 0, 1, 'ts', 'created' , '' ), 'modified' => pacol(0, 0, 1, 'ts', 'last_modified' , '' ), - 'pw_expires_on' => pacol( 0, 0, 1, 'ts', 'password_expiration' , '' ), + 'password_expiry' => pacol(0, 0, 1, 'ts', 'password_expiration' , '' ), # TODO: add virtual 'notified' column and allow to display who received a vacation response? ); diff --git a/password_expiration.sql b/password_expiration.sql index 0966ae90..a272c3de 100644 --- a/password_expiration.sql +++ b/password_expiration.sql @@ -1,3 +1,3 @@ -ALTER TABLE mailbox ADD COLUMN pw_expires_on TIMESTAMP DEFAULT now() not null; -UPDATE mailbox set pw_expires_on = now() + interval 90 day; -ALTER TABLE domain ADD COLUMN password_expiration_value int DEFAULT 0; +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; diff --git a/public/list-virtual.php b/public/list-virtual.php index 9860580f..cffc62e8 100644 --- a/public/list-virtual.php +++ b/public/list-virtual.php @@ -192,7 +192,7 @@ if ($display_mailbox_aliases) { } if ($password_expiration) { - $sql_select .= ", $table_mailbox.pw_expires_on as password_expiration "; + $sql_select .= ", $table_mailbox.password_expiry as password_expiration "; } if (Config::bool('vacation_control_admin')) {