diff --git a/lam/graphics/trashBig.png b/lam/graphics/trashBig.png new file mode 100644 index 00000000..a069fcb8 Binary files /dev/null and b/lam/graphics/trashBig.png differ diff --git a/lam/help/help.inc b/lam/help/help.inc index dee0e630..15051ba7 100644 --- a/lam/help/help.inc +++ b/lam/help/help.inc @@ -333,6 +333,18 @@ $helpArray = array ( "Headline" => _('BCC address'), "Text" => _('This email address will be set as BCC address of all mails.') ), + '807' => array( + "Headline" => _('Delay'), + "Text" => _('Delay this action by a number of days after account expiry.') + ), + '808' => array( + "Headline" => _('Action'), + "Text" => _('You can delete or move expired accounts.') + ), + '809' => array( + "Headline" => _('Target DN'), + "Text" => _('The expired accounts will be moved to this DN.') + ), ); /* This is a sample help entry. Just copy this line an modify the values between the [] brackets. diff --git a/lam/lib/account.inc b/lam/lib/account.inc index 5923c650..b0a73eea 100644 --- a/lam/lib/account.inc +++ b/lam/lib/account.inc @@ -802,6 +802,49 @@ function ldapGetDN($dn, $attributes = array('dn'), $handle = null) { return $return; } +/** +* Deletes a DN and all child entries. +* +* @param string $dn DN to delete +* @param boolean $recursive recursive delete also child entries +* @return array error messages +*/ +function deleteDN($dn, $recursive) { + $errors = array(); + if (($dn == null) || ($dn == '')) { + $errors[] = array('ERROR', _('Entry does not exist')); + return $errors; + } + if ($recursive) { + $sr = @ldap_list($_SESSION['ldap']->server(), $dn, 'objectClass=*', array('dn'), 0, 0, 0, LDAP_DEREF_NEVER); + if ($sr) { + $entries = ldap_get_entries($_SESSION['ldap']->server(), $sr); + cleanLDAPResult($entries); + for ($i = 0; $i < sizeof($entries); $i++) { + // delete recursively + $subErrors = deleteDN($entries[$i]['dn'], $recursive); + for ($e = 0; $e < sizeof($subErrors); $e++) $errors[] = $subErrors[$e]; + } + } + else { + $errors[] = array ('ERROR', sprintf(_('Was unable to delete DN: %s.'), $dn), getDefaultLDAPErrorString($_SESSION['ldap']->server())); + return $errors; + } + } + // delete parent DN + $success = @ldap_delete($_SESSION['ldap']->server(), $dn); + $ldapUser = $_SESSION['ldap']->decrypt_login(); + $ldapUser = $ldapUser[0]; + if (!$success) { + logNewMessage(LOG_ERR, '[' . $ldapUser .'] Unable to delete DN: ' . $dn . ' (' . ldap_error($_SESSION['ldap']->server()) . ').'); + $errors[] = array ('ERROR', sprintf(_('Was unable to delete DN: %s.'), $dn), getDefaultLDAPErrorString($_SESSION['ldap']->server())); + } + else { + logNewMessage(LOG_NOTICE, '[' . $ldapUser .'] Deleted DN: ' . $dn); + } + return $errors; +} + /** * Returns the parameters for a StatusMessage of the last LDAP search. * diff --git a/lam/lib/modules/shadowAccount.inc b/lam/lib/modules/shadowAccount.inc index db79d58a..8c157105 100644 --- a/lam/lib/modules/shadowAccount.inc +++ b/lam/lib/modules/shadowAccount.inc @@ -772,7 +772,8 @@ class shadowAccount extends baseModule implements passwordService { */ public function getSupportedJobs(&$config) { return array( - new ShadowAccountPasswordNotifyJob() + new ShadowAccountPasswordNotifyJob(), + new ShadowAccountExpirationCleanupJob() ); } @@ -894,6 +895,80 @@ if (interface_exists('\LAM\JOB\Job', false)) { } + /** + * Job to delete or move users on account expiration. + * + * @package jobs + */ + class ShadowAccountExpirationCleanupJob extends \LAM\JOB\AccountExpirationCleanupJob { + + /** + * Returns the alias name of the job. + * + * @return String name + */ + public function getAlias() { + return _('Shadow') . ': ' . _('Cleanup expired user accounts'); + } + + /** + * Returns the description of the job. + * + * @return String description + */ + public function getDescription() { + return _('This job deletes or moves user accounts when they expire.'); + } + + /** + * 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 + $attrs = array('shadowExpire'); + $userResults = searchLDAPByFilter('(shadowExpire=*)', $attrs, array('user')); + return $userResults; + } + + /** + * 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 policy options by getPolicyOptions() + * @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) { + $expireTimeUnix = $user['shadowexpire'][0] * 3600 * 24; + $expireTime = new DateTime('@' . $expireTimeUnix, new DateTimeZone('UTC')); + logNewMessage(LOG_DEBUG, "Expiration on " . $expireTime->format('Y-m-d')); + $delay = 0; + if (!empty($options[$this->getConfigPrefix() . '_delay' . $jobID][0])) { + $delay = $options[$this->getConfigPrefix() . '_delay' . $jobID][0]; + } + if (!empty($user['shadowwarning'][0]) && ($user['shadowwarning'][0] > 0)) { + $numDaysToWarn += $user['shadowwarning'][0]; + } + $actionTime = clone $expireTime; + if ($delay != 0) { + $actionTime->add(new DateInterval('P' . $delay . 'D')); + } + $actionTime->setTimeZone(getTimeZone()); + logNewMessage(LOG_DEBUG, "Action time on " . $actionTime->format('Y-m-d')); + if ($actionTime <= $now) { + $this->performAction($jobID, $options, $user, $isDryRun); + } + } + + } + } ?> diff --git a/lam/templates/delete.php b/lam/templates/delete.php index 3bda6ad7..b6efe474 100644 --- a/lam/templates/delete.php +++ b/lam/templates/delete.php @@ -328,47 +328,4 @@ function getChildCount($dn) { return (sizeof($entries) - 1); } -/** -* Deletes a DN and all child entries. -* -* @param string $dn DN to delete -* @param boolean $recursive recursive delete also child entries -* @return array error messages -*/ -function deleteDN($dn, $recursive) { - $errors = array(); - if (($dn == null) || ($dn == '')) { - $errors[] = array('ERROR', _('Entry does not exist')); - return $errors; - } - if ($recursive) { - $sr = @ldap_list($_SESSION['ldap']->server(), $dn, 'objectClass=*', array('dn'), 0, 0, 0, LDAP_DEREF_NEVER); - if ($sr) { - $entries = ldap_get_entries($_SESSION['ldap']->server(), $sr); - cleanLDAPResult($entries); - for ($i = 0; $i < sizeof($entries); $i++) { - // delete recursively - $subErrors = deleteDN($entries[$i]['dn'], $recursive); - for ($e = 0; $e < sizeof($subErrors); $e++) $errors[] = $subErrors[$e]; - } - } - else { - $errors[] = array ('ERROR', sprintf(_('Was unable to delete DN: %s.'), $dn), getDefaultLDAPErrorString($_SESSION['ldap']->server())); - return $errors; - } - } - // delete parent DN - $success = @ldap_delete($_SESSION['ldap']->server(), $dn); - $ldapUser = $_SESSION['ldap']->decrypt_login(); - $ldapUser = $ldapUser[0]; - if (!$success) { - logNewMessage(LOG_ERR, '[' . $ldapUser .'] Unable to delete DN: ' . $dn . ' (' . ldap_error($_SESSION['ldap']->server()) . ').'); - $errors[] = array ('ERROR', sprintf(_('Was unable to delete DN: %s.'), $dn), getDefaultLDAPErrorString($_SESSION['ldap']->server())); - } - else { - logNewMessage(LOG_NOTICE, '[' . $ldapUser .'] Deleted DN: ' . $dn); - } - return $errors; -} - ?>