From 57c169e7004a9696792747778ae9fb8b30f92ce8 Mon Sep 17 00:00:00 2001 From: Roland Gruber Date: Sun, 29 Oct 2017 11:33:07 +0100 Subject: [PATCH 1/4] added isDebugLoggingEnabled() --- lam/lib/security.inc | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/lam/lib/security.inc b/lam/lib/security.inc index 0aff6d63..5e745d5e 100644 --- a/lam/lib/security.inc +++ b/lam/lib/security.inc @@ -208,6 +208,17 @@ function logoffAndBackToLoginPage() { die(); } +/** + * Returns if debug messages are to be logged. + * + * @return boolean debug enabled + */ +function isDebugLoggingEnabled() { + if (isset($_SESSION['cfgMain'])) $cfg = $_SESSION['cfgMain']; + else $cfg = new LAMCfgMain(); + return $cfg->logLevel >= LOG_DEBUG; +} + /** * Puts a new message in the log file. * From ea302937241ccb5c33bdee2848c64328285b9202 Mon Sep 17 00:00:00 2001 From: Roland Gruber Date: Sun, 29 Oct 2017 15:55:00 +0100 Subject: [PATCH 2/4] new job logging --- lam/lib/modules/shadowAccount.inc | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/lam/lib/modules/shadowAccount.inc b/lam/lib/modules/shadowAccount.inc index a9e7b1ce..9d323fb6 100644 --- a/lam/lib/modules/shadowAccount.inc +++ b/lam/lib/modules/shadowAccount.inc @@ -862,11 +862,11 @@ if (interface_exists('\LAM\JOB\Job', false)) { protected function checkSingleUser($jobID, $options, &$pdo, $now, $policyOptions, $user, $isDryRun) { // skip if user is locked if (!empty($user['userpassword'][0]) && !pwd_is_enabled($user['userpassword'][0])) { - logNewMessage(LOG_DEBUG, $user['dn'] . ' is locked.'); + $this->jobResultLog->logDebug($user['dn'] . ' is locked.'); return; } if ($user['shadowmax'][0] < 1) { - logNewMessage(LOG_DEBUG, $user['dn'] . ' does not expire.'); + $this->jobResultLog->logDebug($user['dn'] . ' does not expire.'); return; } @@ -874,39 +874,39 @@ if (interface_exists('\LAM\JOB\Job', false)) { // calculate time when password expires $lastPwdTimeUnix = $user['shadowlastchange'][0] * 3600 * 24; $lastPwdTime = new DateTime('@' . $lastPwdTimeUnix, new DateTimeZone('UTC')); - logNewMessage(LOG_DEBUG, "Last password change on " . $lastPwdTime->format('Y-m-d')); + $this->jobResultLog->logDebug("Last password change on " . $lastPwdTime->format('Y-m-d')); $numDaysToWarn = $options[$this->getConfigPrefix() . '_mailNotificationPeriod' . $jobID][0]; if (!empty($user['shadowwarning'][0]) && ($user['shadowwarning'][0] > 0)) { $numDaysToWarn += $user['shadowwarning'][0]; } - logNewMessage(LOG_DEBUG, "Number of days before warning " . $numDaysToWarn); + $this->jobResultLog->logDebug("Number of days before warning " . $numDaysToWarn); $numDaysToExpire = $user['shadowmax'][0]; $expireTime = $lastPwdTime->add(new DateInterval('P' . $numDaysToExpire . 'D')); - logNewMessage(LOG_DEBUG, "Password expires on " . $expireTime->format('Y-m-d')); + $this->jobResultLog->logDebug("Password expires on " . $expireTime->format('Y-m-d')); // skip already expired accounts if ($expireTime <= $now) { - logNewMessage(LOG_DEBUG, $user['dn'] . ' already expired'); + $this->jobResultLog->logDebug($user['dn'] . ' already expired'); return; } // calculate time of notification $notifyTime = clone $expireTime; $notifyTime->sub(new DateInterval('P' . $numDaysToWarn . 'D')); $notifyTime->setTimeZone(getTimeZone()); - logNewMessage(LOG_DEBUG, "Password notification on " . $notifyTime->format('Y-m-d H:i')); + $this->jobResultLog->logDebug("Password notification on " . $notifyTime->format('Y-m-d H:i')); // skip if notification is in the future if ($notifyTime > $now) { - logNewMessage(LOG_DEBUG, $user['dn'] . ' does not need notification yet.'); + $this->jobResultLog->logDebug($user['dn'] . ' does not need notification yet.'); return; } $dbLastChange = $this->getDBLastPwdChangeTime($jobID, $pdo, $user['dn']); // skip entries where mail was already sent if ($dbLastChange == $user['shadowlastchange'][0]) { - logNewMessage(LOG_DEBUG, $user['dn'] . ' was already notified.'); + $this->jobResultLog->logDebug($user['dn'] . ' was already notified.'); return; } if ($isDryRun) { // no action for dry run - logNewMessage(LOG_NOTICE, 'Not sending email to ' . $user['dn'] . ' because of dry run.'); + $this->jobResultLog->logInfo('Not sending email to ' . $user['dn'] . ' because of dry run.'); return; } // send email @@ -972,7 +972,7 @@ if (interface_exists('\LAM\JOB\Job', false)) { 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')); + $this->jobResultLog->logDebug("Expiration on " . $expireTime->format('Y-m-d')); $delay = 0; if (!empty($options[$this->getConfigPrefix() . '_delay' . $jobID][0])) { $delay = $options[$this->getConfigPrefix() . '_delay' . $jobID][0]; @@ -982,7 +982,7 @@ if (interface_exists('\LAM\JOB\Job', false)) { $actionTime->add(new DateInterval('P' . $delay . 'D')); } $actionTime->setTimeZone(getTimeZone()); - logNewMessage(LOG_DEBUG, "Action time on " . $actionTime->format('Y-m-d')); + $this->jobResultLog->logDebug("Action time on " . $actionTime->format('Y-m-d')); if ($actionTime <= $now) { $this->performAction($jobID, $options, $user, $isDryRun); } From faac345f53d6f6f2ab5a9527e5559f398c7c27a2 Mon Sep 17 00:00:00 2001 From: Roland Gruber Date: Sun, 29 Oct 2017 16:26:25 +0100 Subject: [PATCH 3/4] new job logger --- lam/lib/modules/freeRadius.inc | 4 ++-- lam/lib/modules/windowsUser.inc | 28 ++++++++++++++-------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/lam/lib/modules/freeRadius.inc b/lam/lib/modules/freeRadius.inc index 0ac6d38b..6c1d7a6e 100644 --- a/lam/lib/modules/freeRadius.inc +++ b/lam/lib/modules/freeRadius.inc @@ -850,7 +850,7 @@ if (interface_exists('\LAM\JOB\Job', false)) { */ protected function checkSingleUser($jobID, $options, &$pdo, $now, $policyOptions, $user, $isDryRun) { $expireTime = DateTime::createFromFormat('d M Y H:i', $user['radiusexpiration'][0], new DateTimeZone('UTC')); - logNewMessage(LOG_DEBUG, "Expiration on " . $expireTime->format('Y-m-d')); + $this->jobResultLog->logDebug("Expiration on " . $expireTime->format('Y-m-d')); $delay = 0; if (!empty($options[$this->getConfigPrefix() . '_delay' . $jobID][0])) { $delay = $options[$this->getConfigPrefix() . '_delay' . $jobID][0]; @@ -860,7 +860,7 @@ if (interface_exists('\LAM\JOB\Job', false)) { $actionTime->add(new DateInterval('P' . $delay . 'D')); } $actionTime->setTimeZone(getTimeZone()); - logNewMessage(LOG_DEBUG, "Action time on " . $actionTime->format('Y-m-d')); + $this->jobResultLog->logDebug("Action time on " . $actionTime->format('Y-m-d')); if ($actionTime <= $now) { $this->performAction($jobID, $options, $user, $isDryRun); } diff --git a/lam/lib/modules/windowsUser.inc b/lam/lib/modules/windowsUser.inc index f9fb5947..09160971 100644 --- a/lam/lib/modules/windowsUser.inc +++ b/lam/lib/modules/windowsUser.inc @@ -3484,60 +3484,60 @@ if (interface_exists('\LAM\JOB\Job', false)) { $domainRoot = strtolower(substr($dn, stripos($dn, 'dc='))); // skip if password does not expire at all if (windowsUser::isNeverExpiring($user)) { - logNewMessage(LOG_DEBUG, $dn . ' does not expire.'); + $this->jobResultLog->logDebug($dn . ' does not expire.'); return; } // skip if no information about last password change if (empty($user['pwdlastset'][0]) || ($user['pwdlastset'][0] < 1)) { - logNewMessage(LOG_DEBUG, $dn . ' has no valid "pwdLastSet".'); + $this->jobResultLog->logDebug($dn . ' has no valid "pwdLastSet".'); return; } // skip if account itself is expired if (!empty($user['accountexpires'][0])) { $accountExpiration = windowsUser::getFileTime($user['accountexpires'][0]); if ($accountExpiration <= $now) { - logNewMessage(LOG_DEBUG, $dn . ' already expired'); + $this->jobResultLog->logDebug($dn . ' already expired'); return; } } // skip if account is deactivated if (windowsUser::isDeactivated($user)) { - logNewMessage(LOG_DEBUG, $dn . ' is deactivated.'); + $this->jobResultLog->logDebug($dn . ' is deactivated.'); return; } $maxPwdAge = $policyOptions['maxpwdage'][$domainRoot]; // calculate time when password expires $lastPwdTime = windowsUser::getFileTime($user['pwdlastset'][0]); - logNewMessage(LOG_DEBUG, "Last password change on " . $lastPwdTime->format('Y-m-d')); + $this->jobResultLog->logDebug("Last password change on " . $lastPwdTime->format('Y-m-d')); $numDaysToWarn = $options[$this->getConfigPrefix() . '_mailNotificationPeriod' . $jobID][0]; - logNewMessage(LOG_DEBUG, "Number of days before warning " . $numDaysToWarn); + $this->jobResultLog->logDebug("Number of days before warning " . $numDaysToWarn); // expiration date = pwdLastSet - maxpwdage $expireTime = windowsUser::getFileTime($user['pwdlastset'][0] - $maxPwdAge); - logNewMessage(LOG_DEBUG, "Password expires on " . $expireTime->format('Y-m-d')); + $this->jobResultLog->logDebug("Password expires on " . $expireTime->format('Y-m-d')); // skip already expired accounts if ($expireTime <= $now) { - logNewMessage(LOG_DEBUG, $dn . ' already expired'); + $this->jobResultLog->logDebug($dn . ' already expired'); return; } // calculate time of notification $notifyTime = clone $expireTime; $notifyTime->sub(new DateInterval('P' . $numDaysToWarn . 'D')); $notifyTime->setTimeZone(getTimeZone()); - logNewMessage(LOG_DEBUG, "Password notification on " . $notifyTime->format('Y-m-d H:i')); + $this->jobResultLog->logDebug("Password notification on " . $notifyTime->format('Y-m-d H:i')); // skip if notification is in the future if ($notifyTime > $now) { - logNewMessage(LOG_DEBUG, $dn . ' does not need notification yet.'); + $this->jobResultLog->logDebug($dn . ' does not need notification yet.'); return; } $dbLastChange = $this->getDBLastPwdChangeTime($jobID, $pdo, $dn); // skip entries where mail was already sent if ($dbLastChange == $user['pwdlastset'][0]) { - logNewMessage(LOG_DEBUG, $dn . ' was already notified.'); + $this->jobResultLog->logDebug($dn . ' was already notified.'); return; } if ($isDryRun) { // no action for dry run - logNewMessage(LOG_NOTICE, 'Not sending email to ' . $dn . ' because of dry run.'); + $this->jobResultLog->logInfo('Not sending email to ' . $dn . ' because of dry run.'); return; } // send email @@ -3605,7 +3605,7 @@ if (interface_exists('\LAM\JOB\Job', false)) { $expireTime = new DateTime('1601-01-01', new DateTimeZone('UTC')); $expireTime->add(new DateInterval('PT' . $seconds . 'S')); $expireTime->setTimezone(getTimeZone()); - logNewMessage(LOG_DEBUG, "Expiration on " . $expireTime->format('Y-m-d')); + $this->jobResultLog->logDebug("Expiration on " . $expireTime->format('Y-m-d')); $delay = 0; if (!empty($options[$this->getConfigPrefix() . '_delay' . $jobID][0])) { $delay = $options[$this->getConfigPrefix() . '_delay' . $jobID][0]; @@ -3615,7 +3615,7 @@ if (interface_exists('\LAM\JOB\Job', false)) { $actionTime->add(new DateInterval('P' . $delay . 'D')); } $actionTime->setTimeZone(getTimeZone()); - logNewMessage(LOG_DEBUG, "Action time on " . $actionTime->format('Y-m-d')); + $this->jobResultLog->logDebug("Action time on " . $actionTime->format('Y-m-d')); if ($actionTime <= $now) { $this->performAction($jobID, $options, $user, $isDryRun); } From a7f1166ede430c6e3c6a317ba42b752c1f909c30 Mon Sep 17 00:00:00 2001 From: Roland Gruber Date: Sun, 29 Oct 2017 16:35:22 +0100 Subject: [PATCH 4/4] job dry-run --- lam/HISTORY | 2 + .../manual-sources/chapter-configuration.xml | 99 ++++++++++--------- 2 files changed, 56 insertions(+), 45 deletions(-) diff --git a/lam/HISTORY b/lam/HISTORY index ae27179a..16a29fec 100644 --- a/lam/HISTORY +++ b/lam/HISTORY @@ -3,6 +3,8 @@ December 2017 - PHP 5.6 and Internet Explorer 11 or later required - Account status also shows expired accounts - Quota: support k/m/g/t/K/M/G/T to specify values in e.g. kB + - LAM Pro: + -> Cron jobs include better logging and support dry-run 19.09.2017 6.1 diff --git a/lam/docs/manual-sources/chapter-configuration.xml b/lam/docs/manual-sources/chapter-configuration.xml index 5a20dd61..d92fbfa9 100644 --- a/lam/docs/manual-sources/chapter-configuration.xml +++ b/lam/docs/manual-sources/chapter-configuration.xml @@ -15,7 +15,7 @@ - + @@ -30,7 +30,7 @@ - + @@ -63,7 +63,7 @@ - + @@ -84,15 +84,16 @@ Session encryption will encrypt sensitive data like passwords in your session files. This is only available when - PHP OpenSSL is active. This - adds extra security but also costs performance. If you manage a large - directory you might want to disable this and take other actions to - secure your LAM server. + PHP OpenSSL is + active. This adds extra security but also costs performance. If you + manage a large directory you might want to disable this and take other + actions to secure your LAM server. - + @@ -126,7 +127,7 @@ - + @@ -143,7 +144,7 @@ - + @@ -168,7 +169,7 @@ - + @@ -190,7 +191,7 @@ - + @@ -205,7 +206,7 @@ - + @@ -230,7 +231,7 @@ - + @@ -275,7 +276,7 @@ - + @@ -294,7 +295,7 @@ - + @@ -336,7 +337,7 @@ - + @@ -391,7 +392,7 @@ - + @@ -426,7 +427,7 @@ - + @@ -438,7 +439,7 @@ - + @@ -453,7 +454,7 @@ - + @@ -473,7 +474,7 @@ - + @@ -512,7 +513,7 @@ - + @@ -542,7 +543,7 @@ - + @@ -554,7 +555,7 @@ - + @@ -567,7 +568,7 @@ - + @@ -583,7 +584,7 @@ - + @@ -656,7 +657,7 @@ - + @@ -675,7 +676,7 @@ - + @@ -702,7 +703,7 @@ - + @@ -738,7 +739,7 @@ - + @@ -769,7 +770,7 @@ mysql> GRANT ALL PRIVILEGES ON lam_cron.* TO 'lam_cron'@'localhost'; - + @@ -786,6 +787,14 @@ mysql> GRANT ALL PRIVILEGES ON lam_cron.* TO 'lam_cron'@'localhost'; configured jobs on a daily basis. The command must be run as the same user as your webserver is running. You are free to change the starting time of the script or run it more often. + + Dry-run: You can perform a dry-run of the job. This will not + perform any actions but only print what would be done. For this please + put "--dryRun" at the end of the command. E.g.: + + /usr/share/ldap-account-manager/lib/cron.sh lam 123456789 --dryRun + +
@@ -803,7 +812,7 @@ mysql> GRANT ALL PRIVILEGES ON lam_cron.* TO 'lam_cron'@'localhost'; - + @@ -839,7 +848,7 @@ mysql> GRANT ALL PRIVILEGES ON lam_cron.* TO 'lam_cron'@'localhost'; - + @@ -938,7 +947,7 @@ mysql> GRANT ALL PRIVILEGES ON lam_cron.* TO 'lam_cron'@'localhost'; - + @@ -1040,7 +1049,7 @@ mysql> GRANT ALL PRIVILEGES ON lam_cron.* TO 'lam_cron'@'localhost'; - + @@ -1126,7 +1135,7 @@ mysql> GRANT ALL PRIVILEGES ON lam_cron.* TO 'lam_cron'@'localhost'; - + @@ -1182,7 +1191,7 @@ mysql> GRANT ALL PRIVILEGES ON lam_cron.* TO 'lam_cron'@'localhost'; - + @@ -1266,7 +1275,7 @@ mysql> GRANT ALL PRIVILEGES ON lam_cron.* TO 'lam_cron'@'localhost'; - + @@ -1314,7 +1323,7 @@ mysql> GRANT ALL PRIVILEGES ON lam_cron.* TO 'lam_cron'@'localhost'; - + @@ -1363,7 +1372,7 @@ mysql> GRANT ALL PRIVILEGES ON lam_cron.* TO 'lam_cron'@'localhost'; - + @@ -1413,7 +1422,7 @@ mysql> GRANT ALL PRIVILEGES ON lam_cron.* TO 'lam_cron'@'localhost'; - + @@ -1439,7 +1448,7 @@ mysql> GRANT ALL PRIVILEGES ON lam_cron.* TO 'lam_cron'@'localhost'; - + @@ -1458,7 +1467,7 @@ mysql> GRANT ALL PRIVILEGES ON lam_cron.* TO 'lam_cron'@'localhost'; - + @@ -1491,7 +1500,7 @@ mysql> GRANT ALL PRIVILEGES ON lam_cron.* TO 'lam_cron'@'localhost'; - +