1
|
<?php
|
2
|
|
3
|
/**
|
4
|
* @file
|
5
|
* cron relate functions
|
6
|
*
|
7
|
*/
|
8
|
|
9
|
/**
|
10
|
* function to respond to ldap associated drupal accounts which no
|
11
|
* longer have a related LDAP entry
|
12
|
*
|
13
|
* @param LdapUserConf $ldap_user_conf
|
14
|
*
|
15
|
* @return boolean FALSE on error or incompletion or TRUE otherwise
|
16
|
*
|
17
|
* @todo need to avoid sending repeated emails
|
18
|
*
|
19
|
*
|
20
|
*/
|
21
|
|
22
|
function _ldap_user_orphans($ldap_user_conf) {
|
23
|
|
24
|
// return TRUE; // this is untested code
|
25
|
|
26
|
if (!$ldap_user_conf->orphanedDrupalAcctBehavior ||
|
27
|
$ldap_user_conf->orphanedDrupalAcctBehavior == 'ldap_user_orphan_do_not_check') {
|
28
|
return TRUE;
|
29
|
}
|
30
|
|
31
|
/**
|
32
|
* query drupal accounts
|
33
|
* - ldap associated drupal accounts
|
34
|
* - where (ldap_user_current_dn not null)
|
35
|
* - ordered by ldap_user_last_checked
|
36
|
* - order by uid asc (get oldest first)
|
37
|
*/
|
38
|
|
39
|
$last_uid_checked = variable_get('ldap_user_cron_last_uid_checked', 1);
|
40
|
|
41
|
$query = new EntityFieldQuery();
|
42
|
$query->entityCondition('entity_type', 'user')
|
43
|
->fieldCondition('ldap_user_current_dn', 'value', 'NULL', '!=')
|
44
|
->propertyCondition('uid', $last_uid_checked, '>')
|
45
|
->propertyOrderBy('uid', 'ASC')
|
46
|
->range(0, $ldap_user_conf->orphanedCheckQty)
|
47
|
->addMetaData('account', user_load(1)); // run the query as user 1
|
48
|
$result = $query->execute();
|
49
|
|
50
|
$drupal_users = array();
|
51
|
$email_list = array();
|
52
|
$ldap_servers = ldap_servers_get_servers(NULL, 'enabled');
|
53
|
$watchdogs_sids_missing_watchdogged = array();
|
54
|
/**
|
55
|
* first produce array of form:
|
56
|
* $drupal_users[$sid][$puid_attr][$puid]['exists'] = FALSE | TRUE;
|
57
|
* signifying if corresponding LDAP Entry exists
|
58
|
*/
|
59
|
if (!(isset($result['user']) && count($result['user']) > 0)) {
|
60
|
return TRUE;
|
61
|
}
|
62
|
|
63
|
$uids = array_keys($result['user']);
|
64
|
$user_count = count($uids);
|
65
|
|
66
|
// if maxed out reset uid check counter
|
67
|
if ($user_count < $ldap_user_conf->orphanedCheckQty) {
|
68
|
variable_set('ldap_user_cron_last_uid_checked', 1);
|
69
|
}
|
70
|
else {
|
71
|
variable_set('ldap_user_cron_last_uid_checked', $uids[count($uids) - 1]);
|
72
|
}
|
73
|
|
74
|
$batches = floor($user_count / LDAP_SERVERS_MAXFILTER_ORS) + 1;
|
75
|
// e.g. 175 users and 50 max ldap query ors will yield 4 batches
|
76
|
for ($batch=1; $batch <= $batches; $batch++) { // e.g. 1,2,3,4
|
77
|
$filters = array();
|
78
|
$drupal_users = array();
|
79
|
/**
|
80
|
* 1. populate $drupal_users[$sid][$puid_attr][$puid]['exists'] = TRUE
|
81
|
*
|
82
|
* e.g. first batch $i=0; $i<50; $i++
|
83
|
* 2nd batch $i=50; $i<100; $i++
|
84
|
* 4th batch $i=150; $i<175; $i++
|
85
|
*/
|
86
|
$start = ($batch - 1)* LDAP_SERVERS_MAXFILTER_ORS; // e.g 0, 50, 100
|
87
|
$end_plus_1 = min(($batch)* LDAP_SERVERS_MAXFILTER_ORS, $user_count); // e.g. 50, 100, 150
|
88
|
$batch_uids = array_slice($uids, $start, ($end_plus_1 - $start)); // e.g. 50, 50; 100, 50
|
89
|
$accounts = entity_load('user', $batch_uids);
|
90
|
|
91
|
foreach ($accounts as $uid => $user) {
|
92
|
$sid = @$user->ldap_user_puid_sid['und'][0]['value'];
|
93
|
$puid = @$user->ldap_user_puid['und'][0]['value'];
|
94
|
$puid_attr = @$user->ldap_user_puid_property['und'][0]['value'];
|
95
|
if ($sid && $puid && $puid_attr) {
|
96
|
if ($ldap_servers[$sid]->unique_persistent_attr_binary) {
|
97
|
$filters[$sid][$puid_attr][] = "($puid_attr=" . ldap_servers_binary_filter($puid) . ")";
|
98
|
}
|
99
|
else {
|
100
|
$filters[$sid][$puid_attr][] = "($puid_attr=$puid)";
|
101
|
}
|
102
|
$drupal_users[$sid][$puid_attr][$puid]['uid'] = $uid;
|
103
|
$drupal_users[$sid][$puid_attr][$puid]['exists'] = FALSE;
|
104
|
}
|
105
|
else {
|
106
|
// user with missing ldap data fields
|
107
|
// perhaps should be watchdogged?
|
108
|
}
|
109
|
}
|
110
|
|
111
|
//2. set $drupal_users[$sid][$puid_attr][$puid]['exists'] to FALSE
|
112
|
// if entry doesn't exist
|
113
|
foreach ($filters as $sid => $puid_attrs) {
|
114
|
if (!isset($ldap_servers[$sid])) {
|
115
|
if (!isset($watchdogs_sids_missing_watchdogged[$sid])) {
|
116
|
watchdog(
|
117
|
'ldap_user',
|
118
|
'Server %sid not enabled, but needed to remove orphaned ldap users',
|
119
|
array('%sid' => $sid),
|
120
|
WATCHDOG_ERROR
|
121
|
);
|
122
|
$watchdogs_sids_missing_watchdogged[$sid] = TRUE;
|
123
|
}
|
124
|
continue;
|
125
|
}
|
126
|
foreach ($puid_attrs as $puid_attr => $ors) {
|
127
|
// query should look like (|(guid=3243243)(guid=3243243)(guid=3243243))
|
128
|
$ldap_filter = '(|' . join("", $ors) . ')';
|
129
|
$ldap_entries = $ldap_servers[$sid]->searchAllBaseDns($ldap_filter, array($puid_attr));
|
130
|
if ($ldap_entries === FALSE) {
|
131
|
unset($drupal_users[$sid]); // if query has error, don't remove ldap entries!
|
132
|
watchdog(
|
133
|
'ldap_user',
|
134
|
'ldap server %sid had error while querying to
|
135
|
deal with orphaned ldap user entries. Please check that the ldap
|
136
|
server is configured correctly. Query; %query',
|
137
|
array('%sid' => $sid, '%query' => $query),
|
138
|
WATCHDOG_ERROR);
|
139
|
continue;
|
140
|
}
|
141
|
|
142
|
unset($ldap_entries['count']);
|
143
|
|
144
|
foreach ($ldap_entries as $i => $ldap_entry) {
|
145
|
$puid = $ldap_servers[$sid]->userPuidFromLdapEntry($ldap_entry);
|
146
|
$drupal_users[$sid][$puid_attr][$puid]['exists'] = TRUE;
|
147
|
}
|
148
|
}
|
149
|
}
|
150
|
//3. we now have $drupal_users[$sid][$puid_attr][$puid]['exists'] = FALSE | TRUE;
|
151
|
if ($ldap_user_conf->orphanedDrupalAcctBehavior == 'ldap_user_orphan_email') {
|
152
|
global $base_url;
|
153
|
}
|
154
|
$check_time = time();
|
155
|
foreach ($drupal_users as $sid => $puid_x_puid_attrs) {
|
156
|
foreach ($puid_x_puid_attrs as $puid_attr => $puids) {
|
157
|
foreach ($puids as $puid => $user_data) {
|
158
|
|
159
|
$account = $accounts[$user_data['uid']];
|
160
|
$user_edit['ldap_user_last_checked'][LANGUAGE_NONE][0]['value'] = $check_time;
|
161
|
$account = user_save($account, $user_edit, 'ldap_user');
|
162
|
if (!$user_data['exists']) {
|
163
|
/**
|
164
|
* $ldap_user_conf->orphanedDrupalAcctBehavior will either be
|
165
|
* 'ldap_user_orphan_email' or one of the user module options:
|
166
|
* user_cancel_block, user_cancel_block_unpublish,
|
167
|
* user_cancel_reassign, user_cancel_delete
|
168
|
*/
|
169
|
if ($ldap_user_conf->orphanedDrupalAcctBehavior == 'ldap_user_orphan_email') {
|
170
|
$email_list[] = $account->name . "," . $account->mail . "," . $base_url . "/user/$uid/edit";
|
171
|
}
|
172
|
else {
|
173
|
_user_cancel(array(), $account, $ldap_user_conf->orphanedDrupalAcctBehavior);
|
174
|
}
|
175
|
}
|
176
|
}
|
177
|
}
|
178
|
}
|
179
|
}
|
180
|
|
181
|
if (count($email_list) > 0) {
|
182
|
$site_email = variable_get('site_mail', FALSE);
|
183
|
$params = array('accounts' => $email_list);
|
184
|
if ($site_email) {
|
185
|
drupal_mail(
|
186
|
'ldap_user',
|
187
|
'orphaned_accounts',
|
188
|
$site_email,
|
189
|
language_default(),
|
190
|
$params
|
191
|
);
|
192
|
}
|
193
|
}
|
194
|
|
195
|
return TRUE;
|
196
|
}
|