function password_policy_cron in Password Policy 6
Same name and namespace in other branches
- 8.3 password_policy.module \password_policy_cron()
- 5 password_policy.module \password_policy_cron()
- 7.2 password_policy.module \password_policy_cron()
- 7 password_policy.module \password_policy_cron()
Implements hook_cron().
File
- ./
password_policy.module, line 517 - The password policy module allows you to enforce a specific level of password complexity for the user passwords on the system.
Code
function password_policy_cron() {
// Short circuit if no policies are active that use expiration.
if (!db_result(db_query("SELECT COUNT(*) FROM {password_policy} WHERE enabled = 1 AND expiration > 0"))) {
return;
}
// Get all users' last password change time. Don't touch blocked accounts
$result = db_query("SELECT u.uid AS uid, u.created AS created_u, p.created AS created_p, e.pid AS pid, e.warning AS warning, e.unblocked AS unblocked FROM {users} u LEFT JOIN {password_policy_history} p ON u.uid = p.uid LEFT JOIN {password_policy_expiration} e ON u.uid = e.uid WHERE u.uid > 0 AND u.status = 1 ORDER BY p.created ASC");
while ($row = db_fetch_object($result)) {
if ($row->uid == 1 && !variable_get('password_policy_admin', 0)) {
continue;
}
// Use account creation timestamp if there is no entry in password history
// table.
$accounts[$row->uid] = empty($row->created_p) ? $row->created_u : $row->created_p;
// Last time a warning was mailed out (if was). We need it because we send
// warnings only once a day, not on all cron runs.
$warns[$row->uid] = $row->warning;
// The user was last time unblocked (if was). We don't block this account
// again for some period of time.
$unblocks[$row->uid] = $row->unblocked;
// The user was last time unblocked (if was). We don't block this account
// again for some period of time.
$pids[$row->uid] = $row->pid;
}
if ($accounts) {
foreach ($accounts as $uid => $last_change) {
/* Alternative: $result = db_query("SELECT p.* FROM {password_policy} p INNER JOIN {password_policy_role} r ON p.pid = r.pid INNER JOIN {users_roles} u ON r.rid = u.rid WHERE p.enabled = 1 AND u.uid = %d ORDER BY p.weight LIMIT 1", $uid); */
$roles = array(
DRUPAL_AUTHENTICATED_RID,
);
$result = db_query("SELECT rid FROM {users_roles} WHERE uid = %d ORDER BY rid", $uid);
while ($row = db_fetch_object($result)) {
$roles[] = $row->rid;
}
$policy = _password_policy_load_active_policy($roles);
if ($policy) {
$expiration = $policy['expiration'];
$warnings = !empty($policy['warning']) ? explode(',', $policy['warning']) : array();
if (!empty($expiration)) {
// Calculate expiration time.
$expiration_seconds = $expiration * 60 * 60 * 24;
$policy_start = $policy['created'];
if (variable_get('password_policy_begin', 0) == 1) {
$policy_start -= $expiration_seconds;
}
rsort($warnings, SORT_NUMERIC);
$time = time();
// Check expiration and warning days for each account.
if (!empty($warnings)) {
foreach ($warnings as $warning) {
// Loop through all configured warning send out days. If today is
// the day we send out the warning.
$warning_seconds = $warning * 60 * 60 * 24;
// Warning start time.
$start_period = max($policy_start, $last_change) + $expiration_seconds - $warning_seconds;
// Warning end time. We create a one day window for cron to run.
$end_period = $start_period + 60 * 60 * 24;
if ($warns[$uid] && $warns[$uid] > $start_period && $warns[$uid] < $end_period) {
// A warning was already mailed out
continue;
}
if ($time > $start_period && $time < $end_period) {
// A warning falls in the one day window, so we send out the
// warning.
$account = user_load(array(
'uid' => $uid,
));
$message = drupal_mail('password_policy', 'warning', $account->mail, user_preferred_language($account), array(
'account' => $account,
'days_left' => $warning,
));
if ($message['result']) {
// The mail was sent out successfully.
watchdog('password_policy', 'Password expiration warning mailed to %username at %email.', array(
'%username' => $account->name,
'%email' => $account->mail,
));
}
if ($pids[$uid]) {
db_query("UPDATE {password_policy_expiration} SET warning = %d WHERE uid = %d", $time, $uid);
}
else {
db_query("INSERT INTO {password_policy_expiration} (uid, warning) VALUES (%d, %d)", $uid, $time);
}
}
}
}
if ($time > max($policy_start, $last_change) + $expiration_seconds && $time > $unblocks[$uid] + 60 * 60 * 24 && variable_get('password_policy_block', 0) == 0) {
// Block expired accounts. Unblocked accounts are not blocked for
// 24h. One time login lasts for a 24h.
db_query("UPDATE {users} SET status = 0 WHERE uid = %d", $uid);
if ($pids[$uid]) {
db_query("UPDATE {password_policy_expiration} SET blocked = %d WHERE uid = %d", $time, $uid);
}
else {
db_query("INSERT INTO {password_policy_expiration} (uid, blocked) VALUES (%d, %d)", $uid, $time);
}
$account = user_load(array(
'uid' => $uid,
));
watchdog('password_policy', 'Password for user %name has expired.', array(
'%name' => $account->name,
), WATCHDOG_NOTICE, l(t('edit'), 'user/' . $account->uid . '/edit'));
}
}
}
}
}
}