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';
-
+
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/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);
}
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);
}
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.
*