Projet

Général

Profil

Paste
Télécharger (7,19 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / ldap / ldap_user / ldap_user.cron.inc @ 91af538d

1
<?php
2

    
3
/**
4
 * @file
5
 * Cron relate functions.
6
 */
7

    
8
/**
9
 * Function to respond to ldap associated drupal accounts which no
10
 * longer have a related LDAP entry.
11
 *
12
 * @param LdapUserConf $ldap_user_conf
13
 *
14
 * @return boolean FALSE on error or incompletion or TRUE otherwise
15
 */
16
function _ldap_user_orphans($ldap_user_conf) {
17
  if (!$ldap_user_conf->orphanedDrupalAcctBehavior ||
18
    $ldap_user_conf->orphanedDrupalAcctBehavior == 'ldap_user_orphan_do_not_check') {
19
    return TRUE;
20
  }
21

    
22
  /**
23
   * query drupal accounts
24
   *   - ldap associated drupal accounts
25
   *   - where (ldap_user_current_dn not null)
26
   *   - ordered by ldap_user_last_checked
27
   *   - order by uid asc (get oldest first)
28
   */
29

    
30
  $last_uid_checked = variable_get('ldap_user_cron_last_uid_checked', 1);
31

    
32
  $query = new EntityFieldQuery();
33
  $query->entityCondition('entity_type', 'user')
34
    ->fieldCondition('ldap_user_puid_sid', 'value', 'NULL', '!=')
35
    ->fieldCondition('ldap_user_puid_property', 'value', 'NULL', '!=')
36
    ->fieldCondition('ldap_user_puid', 'value', 'NULL', '!=')
37
    ->fieldCondition('ldap_user_current_dn', 'value', 'NULL', '!=')
38
    ->propertyCondition('uid', $last_uid_checked, '>')
39
    ->propertyCondition('status', 1)
40
    ->propertyOrderBy('uid', 'ASC')
41
    ->range(0, $ldap_user_conf->orphanedCheckQty)
42
  // Run the query as user 1.
43
    ->addMetaData('account', user_load(1));
44
  $result = $query->execute();
45

    
46
  $email_list = [];
47
  $ldap_servers = ldap_servers_get_servers(NULL, 'enabled');
48
  $watchdogs_sids_missing_watchdogged = [];
49
  /**
50
   * First produce array of form:
51
   *  $drupal_users[$sid][$puid_attr][$puid]['exists'] = bool
52
   *  signifying if corresponding LDAP Entry exists.
53
   */
54
  if (!(isset($result['user']) && count($result['user']) > 0)) {
55
    variable_set('ldap_user_cron_last_uid_checked', 1);
56
    return TRUE;
57
  }
58

    
59
  $uids = array_keys($result['user']);
60
  $user_count = count($uids);
61

    
62
  // If maxed out reset uid check counter.
63
  if ($user_count < $ldap_user_conf->orphanedCheckQty) {
64
    variable_set('ldap_user_cron_last_uid_checked', 1);
65
  }
66
  else {
67
    variable_set('ldap_user_cron_last_uid_checked', $uids[count($uids) - 1]);
68
  }
69

    
70
  $batches = floor($user_count / LDAP_SERVERS_MAXFILTER_ORS) + 1;
71
  // e.g. 175 users and  50 max ldap query ors will yield 4 batches.
72
  for ($batch = 1; $batch <= $batches; $batch++) {
73
    $email_list = _ldap_user_orphan_process_batch($ldap_user_conf, $batch, $user_count, $uids, $ldap_servers, $watchdogs_sids_missing_watchdogged, $query, $email_list);
74
  }
75

    
76
  if (count($email_list) > 0) {
77
    $site_email = variable_get('site_mail', FALSE);
78
    $params = ['accounts' => $email_list];
79
    if ($site_email) {
80
      drupal_mail(
81
        'ldap_user',
82
        'orphaned_accounts',
83
        $site_email,
84
        language_default(),
85
        $params
86
      );
87
    }
88
  }
89

    
90
  return TRUE;
91
}
92

    
93
/**
94
 * @param $ldap_user_conf
95
 * @param $batch
96
 * @param $user_count
97
 * @param $uids
98
 * @param $ldap_servers
99
 * @param $watchdogs_sids_missing_watchdogged
100
 * @param $query
101
 * @param $email_list
102
 *
103
 * @return array
104
 * @throws \Exception
105
 */
106
function _ldap_user_orphan_process_batch($ldap_user_conf, $batch, $user_count, $uids, $ldap_servers, $watchdogs_sids_missing_watchdogged, $query, $email_list) {
107
  $filters = [];
108
  $drupal_users = [];
109
  /**
110
   * 1. populate $drupal_users[$sid][$puid_attr][$puid]['exists']  = TRUE
111
   *
112
   * e.g.  first batch $i=0; $i<50; $i++
113
   *       2nd batch   $i=50; $i<100; $i++
114
   *       4th batch   $i=150; $i<175; $i++
115
   */
116
  // e.g 0, 50, 100.
117
  $start = ($batch - 1) * LDAP_SERVERS_MAXFILTER_ORS;
118
  // e.g. 50, 100, 150.
119
  $end_plus_1 = min(($batch) * LDAP_SERVERS_MAXFILTER_ORS, $user_count);
120
  // e.g. 50, 50; 100, 50.
121
  $batch_uids = array_slice($uids, $start, ($end_plus_1 - $start));
122
  $accounts = entity_load('user', $batch_uids);
123

    
124
  foreach ($accounts as $uid => $user) {
125
    $sid = @$user->ldap_user_puid_sid[LANGUAGE_NONE][0]['value'];
126
    $puid = @$user->ldap_user_puid[LANGUAGE_NONE][0]['value'];
127
    $puid_attr = @$user->ldap_user_puid_property[LANGUAGE_NONE][0]['value'];
128
    if ($sid && $puid && $puid_attr) {
129
      if ($ldap_servers[$sid]->unique_persistent_attr_binary) {
130
        $filters[$sid][$puid_attr][] = "($puid_attr=" . ldap_servers_binary_filter($puid) . ")";
131
      }
132
      else {
133
        $filters[$sid][$puid_attr][] = "($puid_attr=$puid)";
134
      }
135
      $drupal_users[$sid][$puid_attr][$puid]['uid'] = $uid;
136
      $drupal_users[$sid][$puid_attr][$puid]['exists'] = FALSE;
137
    }
138
    else {
139
      // User with missing ldap data fields
140
      // perhaps should be watchdogged?
141
    }
142
  }
143

    
144
  // 2. set $drupal_users[$sid][$puid_attr][$puid]['exists'] to FALSE
145
  // if entry doesn't exist.
146
  foreach ($filters as $sid => $puid_attrs) {
147
    if (!isset($ldap_servers[$sid])) {
148
      if (!isset($watchdogs_sids_missing_watchdogged[$sid])) {
149
        watchdog(
150
          'ldap_user',
151
          'Server %sid not enabled, but needed to remove orphaned ldap users',
152
          ['%sid' => $sid],
153
          WATCHDOG_ERROR
154
        );
155
        $watchdogs_sids_missing_watchdogged[$sid] = TRUE;
156
      }
157
      continue;
158
    }
159
    foreach ($puid_attrs as $puid_attr => $ors) {
160
      // Query should look like (|(guid=3243243)(guid=3243243)(guid=3243243))
161
      $ldap_filter = '(|' . join("", $ors) . ')';
162
      $ldap_entries = $ldap_servers[$sid]->searchAllBaseDns($ldap_filter, [$puid_attr]);
163
      if ($ldap_entries === FALSE) {
164
        // If query has error, don't remove ldap entries!
165
        unset($drupal_users[$sid]);
166
        watchdog(
167
          'ldap_user',
168
          'ldap server %sid had error while querying to
169
            deal with orphaned ldap user entries.  Please check that the ldap
170
            server is configured correctly.  Query; %query',
171
          ['%sid' => $sid, '%query' => serialize($query)],
172
          WATCHDOG_ERROR);
173
        continue;
174
      }
175

    
176
      unset($ldap_entries['count']);
177

    
178
      foreach ($ldap_entries as $i => $ldap_entry) {
179
        $puid = $ldap_servers[$sid]->userPuidFromLdapEntry($ldap_entry);
180
        $drupal_users[$sid][$puid_attr][$puid]['exists'] = TRUE;
181
      }
182
    }
183
  }
184
  // 3. we now have $drupal_users[$sid][$puid_attr][$puid]['exists'] = bool.
185
  global $base_url;
186
  foreach ($drupal_users as $sid => $puid_x_puid_attrs) {
187
    foreach ($puid_x_puid_attrs as $puid_attr => $puids) {
188
      foreach ($puids as $puid => $user_data) {
189

    
190
        if ($account = $accounts[$user_data['uid']]) {
191
          $user_edit = [];
192
          $user_edit['ldap_user_last_checked'][LANGUAGE_NONE][0]['value'] = time();
193
          $account = user_save($account, $user_edit, 'ldap_user');
194
          if (!$user_data['exists']) {
195
            /**
196
             * $ldap_user_conf->orphanedDrupalAcctBehavior will either be
197
             *  'ldap_user_orphan_email' or one of the user module options:
198
             *     user_cancel_block, user_cancel_block_unpublish,
199
             *     user_cancel_reassign, user_cancel_delete
200
             */
201
            if ($ldap_user_conf->orphanedDrupalAcctBehavior == 'ldap_user_orphan_email') {
202
              $email_list[] = $account->name . "," . $account->mail . "," . $base_url . "/user/" . $account->uid . "/edit";
203
            }
204
            else {
205
              _user_cancel([], $account, $ldap_user_conf->orphanedDrupalAcctBehavior);
206
            }
207
          }
208
        }
209
      }
210
    }
211
  }
212
  return $email_list;
213
}