function _ldap_user_orphans in Lightweight Directory Access Protocol (LDAP) 8.2
Same name and namespace in other branches
- 7.2 ldap_user/ldap_user.cron.inc \_ldap_user_orphans()
function to respond to ldap associated drupal accounts which no longer have a related LDAP entry
Parameters
LdapUserConf $ldap_user_conf:
Return value
boolean FALSE on error or incompletion or TRUE otherwise
@todo need to avoid sending repeated emails
1 call to _ldap_user_orphans()
- ldap_user_cron in ldap_user/
ldap_user.module - Implements hook_cron().
File
- ldap_user/
ldap_user.cron.inc, line 22 - cron relate functions
Code
function _ldap_user_orphans($ldap_user_conf) {
// return TRUE; // this is untested code
if (!$ldap_user_conf->orphanedDrupalAcctBehavior || $ldap_user_conf->orphanedDrupalAcctBehavior == 'ldap_user_orphan_do_not_check') {
return TRUE;
}
/**
* query drupal accounts
* - ldap associated drupal accounts
* - where (ldap_user_current_dn not null)
* - ordered by ldap_user_last_checked
* - order by uid asc (get oldest first)
*/
$last_uid_checked = config('ldap_user.settings')
->get('cron_last_uid_checked');
$query = new EntityFieldQuery();
$query
->entityCondition('entity_type', 'user')
->fieldCondition('ldap_user_current_dn', 'value', 'NULL', '!=')
->propertyCondition('uid', $last_uid_checked, '>')
->propertyOrderBy('uid', 'ASC')
->range(0, $ldap_user_conf->orphanedCheckQty - 1)
->addMetaData('account', user_load(1));
// run the query as user 1
$result = $query
->execute();
$drupal_users = array();
$ldap_servers = ldap_servers_get_servers(NULL, 'enabled');
$watchdogs_sids_missing_watchdogged = array();
/**
* first produce array of form:
* $drupal_users[$sid][$puid_attr][$puid]['exists'] = FALSE | TRUE;
* signifying if corresponding LDAP Entry exists
*/
if (!(isset($result['user']) && count($result['user']) > 0)) {
return TRUE;
}
$uids = array_keys($result['user']);
$user_count = count($uids);
// if maxed out reset uid check counter
if ($user_count < $ldap_user_conf->orphanedCheckQty) {
variable_set('ldap_user_cron_last_uid_checked', 1);
}
else {
variable_set('ldap_user_cron_last_uid_checked', $uids[count($uids) - 1]);
}
$batches = floor($user_count / LDAP_SERVERS_MAXFILTER_ORS) + 1;
// e.g. 175 users and 50 max ldap query ors will yield 4 batches
for ($batch = 1; $batch <= $batches; $batch++) {
// e.g. 1,2,3,4
$filters = array();
/**
* 1. populate $drupal_users[$sid][$puid_attr][$puid]['exists'] = TRUE
*
* e.g. first batch $i=0; $i<50; $i++
* 2nd batch $i=50; $i<100; $i++
* 4th batch $i=150; $i<175; $i++
*/
$start = ($batch - 1) * LDAP_SERVERS_MAXFILTER_ORS;
// e.g 0, 50, 100
$end_plus_1 = min($batch * LDAP_SERVERS_MAXFILTER_ORS, $user_count);
// e.g. 50, 100, 150
$batch_uids = array_slice($uids, $start, $end_plus_1 - $start);
// e.g. 50, 50; 100, 50
$accounts = entity_load('user', $batch_uids);
foreach ($accounts as $uid => $user) {
$sid = @$user->ldap_user_puid_sid['und'][0]['value'];
$puid = @$user->ldap_user_puid['und'][0]['value'];
$puid_attr = @$user->ldap_user_puid_property['und'][0]['value'];
if ($sid && $puid && $puid_attr) {
if ($ldap_servers[$sid]->unique_persistent_attr_binary) {
$filters[$sid][$puid_attr][] = "({$puid_attr}=" . ldap_servers_binary_filter($puid) . ")";
}
else {
$filters[$sid][$puid_attr][] = "({$puid_attr}={$puid})";
}
$drupal_users[$sid][$puid_attr][$puid]['uid'] = $uid;
$drupal_users[$sid][$puid_attr][$puid]['exists'] = FALSE;
}
else {
// user with missing ldap data fields
// perhaps should be watchdogged?
}
}
//2. set $drupal_users[$sid][$puid_attr][$puid]['exists'] to FALSE
// if entry doesn't exist
foreach ($filters as $sid => $puid_attrs) {
if (!isset($ldap_servers[$sid])) {
if (!isset($watchdogs_sids_missing_watchdogged[$sid])) {
watchdog('ldap_user', 'Server %sid not enabled, but needed to remove orphaned ldap users', array(
'%sid' => $sid,
), WATCHDOG_ERROR);
$watchdogs_sids_missing_watchdogged[$sid] = TRUE;
}
continue;
}
foreach ($puid_attrs as $puid_attr => $ors) {
// query should look like (|(guid=3243243)(guid=3243243)(guid=3243243))
$ldap_filter = '(|' . join("", $ors) . ')';
$ldap_entries = $ldap_servers[$sid]
->searchAllBaseDns($ldap_filter, array(
$puid_attr,
));
if ($ldap_entries === FALSE) {
unset($drupal_users[$sid]);
// if query has error, don't remove ldap entries!
watchdog('ldap_user', 'ldap server %sid had error while querying to
deal with orphaned ldap user entries. Please check that the ldap
server is configured correctly. Query; %query', array(
'%sid' => $sid,
'%query' => $query,
), WATCHDOG_ERROR);
continue;
}
unset($ldap_entries['count']);
foreach ($ldap_entries as $i => $ldap_entry) {
$puid = $ldap_servers[$sid]
->userPuidFromLdapEntry($ldap_entry);
$drupal_users[$sid][$puid_attr][$puid]['exists'] = TRUE;
}
}
}
}
//3. we now have $drupal_users[$sid][$puid_attr][$puid]['exists'] = FALSE | TRUE;
if ($ldap_user_conf->orphanedDrupalAcctBehavior == 'ldap_user_orphan_email') {
$email_list = array();
global $base_url;
}
$check_time = time();
$email_list = array();
foreach ($drupal_users as $sid => $puid_x_puid_attrs) {
foreach ($puid_x_puid_attrs as $puid_attr => $puids) {
foreach ($puids as $puid => $user_data) {
$account = $accounts[$user_data['uid']];
$user_edit['ldap_user_last_checked'][LANGUAGE_NONE][0]['value'] = $check_time;
$account = user_save($account, $user_edit, 'ldap_user');
if (!$user_data['exists']) {
/**
* $ldap_user_conf->orphanedDrupalAcctBehavior will either be
* 'ldap_user_orphan_email' or one of the user module options:
* user_cancel_block, user_cancel_block_unpublish,
* user_cancel_reassign, user_cancel_delete
*/
if ($ldap_user_conf->orphanedDrupalAcctBehavior == 'ldap_user_orphan_email') {
$email_list[] = $account->name . "," . $account->mail . "," . $base_url . "/user/{$uid}/edit";
}
else {
_user_cancel(array(), $account, $ldap_user_conf->orphanedDrupalAcctBehavior);
}
}
}
}
}
if (count($email_list) > 0) {
$site_email = config('system.site')
->get('mail');
$params = array(
'accounts' => $email_list,
);
if ($site_email) {
drupal_mail('ldap_user', 'orphaned_accounts', $site_email, language_default(), $params);
}
}
return TRUE;
}