diff --git a/lam/HISTORY b/lam/HISTORY index cf8e5e9b..2381fb86 100644 --- a/lam/HISTORY +++ b/lam/HISTORY @@ -5,6 +5,7 @@ March 2019 - LAM Pro: -> New self service fields: Mail routing (Local address) and Windows (Proxy-Addresses) -> Bind DLZ: support DNAME+XFR records and descriptions in records (requires latest LDAP schema) + -> Cron jobs: added Shadow account expiration notification jobs - Fixed bugs: -> Allow tree-only configurations without any other tab diff --git a/lam/docs/manual-sources/chapter-configuration.xml b/lam/docs/manual-sources/chapter-configuration.xml index b0aa378f..974cb3fb 100644 --- a/lam/docs/manual-sources/chapter-configuration.xml +++ b/lam/docs/manual-sources/chapter-configuration.xml @@ -969,6 +969,11 @@ mysql> GRANT ALL PRIVILEGES ON lam_cron.* TO 'lam_cron'@'localhost'; move expired accounts + + Shadow: + Notify users about account expiration + + Windows: Notify users about password expiration @@ -1364,6 +1369,90 @@ mysql> GRANT ALL PRIVILEGES ON lam_cron.* TO 'lam_cron'@'localhost'; +
+ Shadow: Notify users about account expiration + + This will send your users an email reminder before their whole + account expires. + + You need to activate the Shadow module for users to be able to + add this job. The job can be added multiple times (e.g. to send a + second warning at a later time). + + + + + + + Options + + + + + Option + + Description + + + + From address + + The email address to set as FROM. + + + + Reply-to address + + Optional Reply-to address for email. + + + + CC address + + Optional CC mail address. + + + + BCC address + + Optional BCC mail address. + + + + Subject + + The email subject line. Supports wildcards, see + below. + + + + Text + + The email body text. Supports wildcards, see + below. + + + + Notification period + + Number of days to notify before account + expires. + + + +
Wildcards:
+ + You can enter LDAP attributes as wildcards in the form + @@ATTRIBUTE_NAME@@. E.g. to add the user's common name use "@@cn@@". + For the common name it would be "@@cn@@". + + There are also two special wildcards for the expiration date. + @@EXPIRE_DATE_DDMMYYYY@@ will print the date as e.g. "31.12.2016". + @@EXPIRE_DATE_YYYYMMDD@@ will print the date as e.g. + "2016-12-31". +
+
Windows: Notify users about password expiration diff --git a/lam/docs/manual-sources/images/jobs_shadow3.png b/lam/docs/manual-sources/images/jobs_shadow3.png new file mode 100644 index 00000000..b256f12b Binary files /dev/null and b/lam/docs/manual-sources/images/jobs_shadow3.png differ diff --git a/lam/lib/modules/shadowAccount.inc b/lam/lib/modules/shadowAccount.inc index 939012a7..39aec47b 100644 --- a/lam/lib/modules/shadowAccount.inc +++ b/lam/lib/modules/shadowAccount.inc @@ -3,7 +3,7 @@ This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/) Copyright (C) 2003 - 2006 Tilo Lutz - Copyright (C) 2007 - 2018 Roland Gruber + Copyright (C) 2007 - 2019 Roland Gruber This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -762,7 +762,8 @@ class shadowAccount extends baseModule implements passwordService { public function getSupportedJobs(&$config) { return array( new ShadowAccountPasswordNotifyJob(), - new ShadowAccountExpirationCleanupJob() + new ShadowAccountExpirationCleanupJob(), + new ShadowAccountExpirationNotifyJob() ); } @@ -914,6 +915,100 @@ if (interface_exists('\LAM\JOB\Job', false)) { } + /** + * Job to notify users about account expiration. + * + * @package jobs + */ + class ShadowAccountExpirationNotifyJob extends \LAM\JOB\PasswordExpirationJob { + + /** + * Returns the alias name of the job. + * + * @return String name + */ + public function getAlias() { + return _('Shadow') . ': ' . _('Notify users about acoount expiration'); + } + + /** + * {@inheritDoc} + * @see \LAM\JOB\PasswordExpirationJob::getDescription() + */ + public function getDescription() { + return _('This job sends out emails to inform your users that their account will expire soon.'); + } + + /** + * Searches for users in LDAP. + * + * @param String $jobID unique job identifier + * @param array $options config options (name => value) + * @return array list of user attributes + */ + protected function findUsers($jobID, $options) { + // read users + $sysattrs = array('mail', 'shadowExpire'); + $attrs = $this->getAttrWildcards($jobID, $options); + $attrs = array_values(array_unique(array_merge($attrs, $sysattrs))); + return searchLDAPByFilter('(&(shadowExpire=*)(mail=*))', $attrs, array('user')); + } + + /** + * Checks if a user needs to change his password. + * + * @param integer $jobID job ID + * @param array $options job settings + * @param PDO $pdo PDO + * @param DateTime $now current time + * @param array $policyOptions list of max age values (policy DN => maxAge) + * @param array $user user attributes + * @param boolean $isDryRun just do a dry run, nothing is modified + */ + protected function checkSingleUser($jobID, $options, &$pdo, $now, $policyOptions, $user, $isDryRun) { + $dn = $user['dn']; + $expireTimeUnix = $user['shadowexpire'][0] * 3600 * 24; + $expireTime = new DateTime('@' . $expireTimeUnix, new DateTimeZone('UTC')); + $this->jobResultLog->logDebug("Expiration on " . $expireTime->format('Y-m-d')); + if ($expireTime <= $now) { + $this->jobResultLog->logDebug($dn . ' already expired'); + return; + } + $numDaysToWarn = 0; + if (!empty($options[$this->getConfigPrefix() . '_mailNotificationPeriod' . $jobID][0])) { + $numDaysToWarn = $options[$this->getConfigPrefix() . '_mailNotificationPeriod' . $jobID][0]; + } + $actionTime = clone $expireTime; + if ($numDaysToWarn != 0) { + $actionTime->sub(new DateInterval('P' . $numDaysToWarn . 'D')); + } + $actionTime->setTimeZone(getTimeZone()); + $this->jobResultLog->logDebug("Action time on " . $actionTime->format('Y-m-d')); + if ($actionTime > $now) { + $this->jobResultLog->logDebug($dn . ' does not need notification yet.'); + return; + } + $dbLastChange = $this->getDBLastPwdChangeTime($jobID, $pdo, $user['dn']); + // skip entries where mail was already sent + if ($dbLastChange == $user['shadowexpire'][0]) { + $this->jobResultLog->logDebug($dn . ' was already notified.'); + return; + } + if ($isDryRun) { + // no action for dry run + $this->jobResultLog->logInfo('Not sending email to ' . $dn . ' because of dry run.'); + return; + } + // send email + $success = $this->sendMail($options, $jobID, $user, $expireTime); + // update DB if mail was sent successfully + if ($success) { + $this->setDBLastPwdChangeTime($jobID, $pdo, $dn, $user['shadowexpire'][0]); + } + } + + } + /** * Job to delete or move users on account expiration. *