From ce60b9fa59e9c911711739252a9f94e49a584262 Mon Sep 17 00:00:00 2001 From: Damien Martins Date: Mon, 20 Aug 2018 15:32:53 +0200 Subject: [PATCH] Now password expiration is managed through Postfix Admin GUI --- README.password_expiration | 12 +++++----- functions.inc.php | 48 +++++++++++++++++++++++++------------- model/DomainHandler.php | 1 + password_expiration.sql | 2 +- 4 files changed, 40 insertions(+), 23 deletions(-) diff --git a/README.password_expiration b/README.password_expiration index 66a5f2b1..57ddd89f 100644 --- a/README.password_expiration +++ b/README.password_expiration @@ -2,6 +2,8 @@ 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: @@ -9,15 +11,12 @@ 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 the last line in the script and replace 90 by the required value. +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'; -Do not forget to set the expiration value (in days) -$CONF['password_expiration_value'] = '90'; - 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. @@ -29,8 +28,9 @@ 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/', maildir) as home, concat('maildir:/var/vmail/', maildir) as mail, 20001 AS uid, 20001 AS gid, concat('dirsize:storage=', quota) AS quota FROM mailbox WHERE username = '%u' AND active = '1' AND pw_expires_on > now() -if course you may require to adapt the uid, gid, maildir and table to your setup +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) + +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). diff --git a/functions.inc.php b/functions.inc.php index b57c87af..de730640 100644 --- a/functions.inc.php +++ b/functions.inc.php @@ -260,6 +260,20 @@ function check_domain($domain) { return ''; } +/** + * 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 + */ +function get_password_expiration_value ($domain) { + $table_domain = table_by_key('domain'); + $query = "SELECT password_expiration_value FROM $table_domain WHERE domain='$domain'"; + $result = db_query ($query); + $password_expiration_value = db_array ($result['result']); + return $password_expiration_value[0]; +} /** * check_email @@ -1879,15 +1893,15 @@ function db_insert ($table, $values, $timestamp = array('created', 'modified'), $values[$key] = "now()"; } } - if ($table == 'mailbox') { - global $CONF; - if ($CONF['password_expiration_enabled'] == 'YES') { - $expires_warning_values = array('thirty', 'fourteen', 'seven'); - foreach($expires_warning_values as $key) { - $values[$key] = escape_string($key) . "=0"; - } + + global $CONF; + if ($CONF['password_expiration_enabled'] == 'YES') { + if ($table == 'mailbox') { + $domain_dirty = $values['domain']; + $domain = substr($domain_dirty, 1, -1); + $password_expiration_value = get_password_expiration_value($domain); foreach($timestamp_expiration as $key) { - $values[$key] = "now() + interval " . $CONF['password_expiration_value'] . " day"; + $values[$key] = "now() + interval " . $password_expiration_value . " day"; } } } @@ -1939,15 +1953,17 @@ function db_update_q($table, $where, $values, $timestamp = array('modified')) { $sql_values[$key] = escape_string($key) . "=now()"; } } - if ($table == 'mailbox') { - global $CONF; - if ($CONF['password_expiration_enabled'] == 'YES') { + + global $CONF; + if ($CONF['password_expiration_enabled'] == 'YES') { + $where_type = explode('=',$where); + $email = ($where_type[1]); + $domain_dirty = explode('@',$email)[1]; //Please do it nicer + $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 " . $CONF['password_expiration_value'] . " day"; - $expires_warning_values = array('thirty', 'fourteen', 'seven'); - foreach($expires_warning_values as $key) { - $sql_values[$key] = escape_string($key) . "=0"; - } + $sql_values[$key] = escape_string($key) . "=now() + interval " . $password_expiration_value . " day"; } } diff --git a/model/DomainHandler.php b/model/DomainHandler.php index 57a70e0f..a347e06b 100644 --- a/model/DomainHandler.php +++ b/model/DomainHandler.php @@ -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 ), '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', ''), '_can_edit' => pacol(0, 0, 1, 'int', '' , '' , 0 , /*options*/ '', /*not_in_db*/ 0, diff --git a/password_expiration.sql b/password_expiration.sql index de99c24c..0966ae90 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 null; +ALTER TABLE domain ADD COLUMN password_expiration_value int DEFAULT 0;