Projet

Général

Profil

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

root / drupal7 / sites / all / modules / ldap / ldap_user / ldap_user.module @ 32700c57

1 85ad3d82 Assos Assos
<?php
2
3
/**
4
 * @file
5 32700c57 Assos Assos
 * Module for the LDAP User Entity.
6 85ad3d82 Assos Assos
 */
7
8
define('LDAP_USER_DRUPAL_HELP_URL', 'http://drupal.org/node/997082');
9
10 32700c57 Assos Assos
// Configurable drupal acct provision triggers.
11 85ad3d82 Assos Assos
define('LDAP_USER_DRUPAL_USER_PROV_ON_USER_UPDATE_CREATE', 1);
12
define('LDAP_USER_DRUPAL_USER_PROV_ON_AUTHENTICATE', 2);
13
define('LDAP_USER_DRUPAL_USER_PROV_ON_ALLOW_MANUAL_CREATE', 3);
14
15 32700c57 Assos Assos
// Configurable ldap entry provision triggers.
16 85ad3d82 Assos Assos
define('LDAP_USER_LDAP_ENTRY_PROV_ON_USER_UPDATE_CREATE', 6);
17
define('LDAP_USER_LDAP_ENTRY_PROV_ON_AUTHENTICATE', 7);
18
define('LDAP_USER_LDAP_ENTRY_DELETE_ON_USER_DELETE', 8);
19
20 32700c57 Assos Assos
// Provisioning events (events are triggered by triggers)
21 85ad3d82 Assos Assos
define('LDAP_USER_EVENT_SYNCH_TO_DRUPAL_USER', 1);
22
define('LDAP_USER_EVENT_CREATE_DRUPAL_USER', 2);
23
define('LDAP_USER_EVENT_SYNCH_TO_LDAP_ENTRY', 3);
24
define('LDAP_USER_EVENT_CREATE_LDAP_ENTRY', 4);
25
define('LDAP_USER_EVENT_LDAP_ASSOCIATE_DRUPAL_ACCT', 5);
26
27 32700c57 Assos Assos
// Results of ldap entry provisioning.
28 85ad3d82 Assos Assos
define('LDAP_USER_PROVISION_LDAP_ENTRY_EXISTS', 1);
29
define('LDAP_USER_PROVISION_LDAP_ENTRY_CREATE_FAILED', 2);
30
define('LDAP_USER_PROVISION_LDAP_ENTRY_SYNCH_FAILED', 3);
31
32 32700c57 Assos Assos
// Options for what to do when existing non ldap associated Drupal account conflicts with ldap account.
33 85ad3d82 Assos Assos
define('LDAP_USER_CONFLICT_LOG', 1);
34
define('LDAP_USER_CONFLICT_RESOLVE', 2);
35
define('LDAP_USER_CONFLICT_RESOLVE_DEFAULT', 2);
36
37 32700c57 Assos Assos
// Options for what to do if another Drupal account has the same email address.
38 b42754b9 Assos Assos
define('LDAP_USER_ACCOUNTS_WITH_SAME_EMAIL_DISABLED', 0);
39
define('LDAP_USER_ACCOUNTS_WITH_SAME_EMAIL_ENABLED', 1);
40
41 32700c57 Assos Assos
// Options for dealing with manual account creation that conflict with ldap entries.
42 85ad3d82 Assos Assos
define('LDAP_USER_MANUAL_ACCT_CONFLICT_REJECT', 1);
43
define('LDAP_USER_MANUAL_ACCT_CONFLICT_LDAP_ASSOCIATE', 2);
44
define('LDAP_USER_MANUAL_ACCT_CONFLICT_SHOW_OPTION_ON_FORM', 3);
45
define('LDAP_USER_MANUAL_ACCT_CONFLICT_NO_LDAP_ASSOCIATE', 4);
46
47 32700c57 Assos Assos
// Options for account creation behavior.
48 85ad3d82 Assos Assos
define('LDAP_USER_ACCT_CREATION_LDAP_BEHAVIOR', 4);
49
define('LDAP_USER_ACCT_CREATION_USER_SETTINGS_FOR_LDAP', 1);
50
define('LDAP_USER_ACCT_CREATION_LDAP_BEHAVIOR_DEFAULT', 4);
51
52 32700c57 Assos Assos
// Provision directions.
53 85ad3d82 Assos Assos
define('LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER', 1);
54
define('LDAP_USER_PROV_DIRECTION_TO_LDAP_ENTRY', 2);
55
define('LDAP_USER_PROV_DIRECTION_NONE', 3);
56
define('LDAP_USER_PROV_DIRECTION_ALL', 4);
57
58
define('LDAP_USER_PROV_RESULT_NO_ERROR', 0);
59
define('LDAP_USER_PROV_RESULT_NO_PWD', 1);
60
define('LDAP_USER_PROV_RESULT_BAD_PARAMS', 2);
61
62 32700c57 Assos Assos
// Need to avoid conflicting with server ids.
63
define('LDAP_USER_NO_SERVER_SID', 0);
64 85ad3d82 Assos Assos
define('LDAP_USER_TEST_FORM_PATH', 'admin/config/people/ldap/user/test');
65
define('LDAP_USER_WS_USER_PATH', 'ldap/user/ws');
66
67
// Machine name for the setting to provision from last authentication server.
68
define('LDAP_USER_AUTH_SERVER_SID', 'ldap_last_authserv');
69
define('LDAP_USER_SESSION_PROV_SID', 'ldap_user_session_prov_sid');
70
71
/**
72
 * Implements hook_menu().
73
 */
74
function ldap_user_menu() {
75 32700c57 Assos Assos
  $items = [];
76 85ad3d82 Assos Assos
77 32700c57 Assos Assos
  $items['admin/config/people/ldap/user'] = [
78 85ad3d82 Assos Assos
    'title' => '3. User',
79
    'description' => 'Settings related to user provisioning and data synching between ldap and drupal users.',
80
    'page callback' => 'drupal_get_form',
81 32700c57 Assos Assos
    'page arguments' => ['ldap_user_admin_form'],
82
    'access arguments' => ['administer site configuration'],
83 85ad3d82 Assos Assos
    'type' => MENU_LOCAL_TASK,
84
    'weight' => 2,
85
    'file' => 'ldap_user.admin.inc',
86 32700c57 Assos Assos
  ];
87 85ad3d82 Assos Assos
88 32700c57 Assos Assos
  $items[LDAP_USER_TEST_FORM_PATH] = [
89 85ad3d82 Assos Assos
    'title' => 'Test LDAP User Functionality for a given user.',
90
    'description' => '',
91
    'page callback' => 'drupal_get_form',
92 32700c57 Assos Assos
    'page arguments' => ['ldap_user_test_form'],
93
    'access arguments' => ['administer site configuration'],
94 85ad3d82 Assos Assos
    'file' => 'ldap_user.test_form.inc',
95
    'type' => MENU_LOCAL_ACTION,
96 32700c57 Assos Assos
  ];
97 85ad3d82 Assos Assos
  return $items;
98
}
99
100
/**
101
 * Implements hook_init().
102
 */
103
function ldap_user_init() {
104 32700c57 Assos Assos
  // Reset for simpletest page load behavior.
105
  ldap_user_ldap_provision_semaphore(NULL, NULL, NULL, TRUE);
106 85ad3d82 Assos Assos
}
107
108
/**
109
 * Implements hook_theme().
110
 */
111
function ldap_user_theme() {
112 32700c57 Assos Assos
  return [
113
    'ldap_user_conf_form' => [
114
      'render element' => 'form',
115
      'file' => 'ldap_user.theme.inc',
116
    ],
117
  ];
118 85ad3d82 Assos Assos
}
119
120
/**
121
 * Implements hook_cron().
122
 */
123
function ldap_user_cron() {
124
  $ldap_user_conf = ldap_user_conf();
125
  if ($ldap_user_conf->orphanedDrupalAcctBehavior != 'ldap_user_orphan_do_not_check') {
126
    module_load_include('inc', 'ldap_user', 'ldap_user.cron');
127
    $result = _ldap_user_orphans($ldap_user_conf);
128
    if ($result !== TRUE) {
129 32700c57 Assos Assos
      watchdog('ldap_user', 'LDAP User check for orphaned ldap provisioned Drupal accounts failed', [], WATCHDOG_ERROR);
130 85ad3d82 Assos Assos
    }
131
  }
132
}
133
134
/**
135
 * Implements hook_mail().
136
 */
137
function ldap_user_mail($key, &$message, $params) {
138
  switch ($key) {
139
    case 'orphaned_accounts':
140 bc175c27 Assos Assos
      $message['subject'] = variable_get('site_name') . ' ' . t('Orphaned LDAP Users');
141
      $message['body'][] = t('The following !count Drupal users no longer have
142 85ad3d82 Assos Assos
        corresponding LDAP Entries.  Perhaps they have been removed from the LDAP
143 32700c57 Assos Assos
        and should be removed:', ['!count' => count($params['accounts'])])
144 85ad3d82 Assos Assos
        . "\n\n" . t('username,mail,edit url') . "\n" .
145
        join("\n", $params['accounts']);
146
      break;
147
  }
148
}
149
150
/**
151
 * Implements hook_ldap_derived_user_name_alter().
152
 */
153
function ldap_user_ldap_derived_user_name_alter(&$name, $ldap_user) {
154 32700c57 Assos Assos
  // Alter $name in some way here.
155 85ad3d82 Assos Assos
}
156
157 32700c57 Assos Assos
/**
158
 *
159
 */
160 85ad3d82 Assos Assos
function ldap_user_conf_cache_clear() {
161
  $discard = ldap_user_conf('admin', TRUE);
162
  $discard = ldap_user_conf(NULL, TRUE);
163
  ldap_user_ldap_provision_semaphore(NULL, NULL, NULL, TRUE);
164
}
165
166
/**
167 32700c57 Assos Assos
 * Get ldapUserConf or ldapUserConfAdmin object.
168 85ad3d82 Assos Assos
 *
169 32700c57 Assos Assos
 * @param enum $type
170
 *   is 'admin' for ldapUserConfAdmin object or NULL for ldapUserConf object.
171
 * @param bool $resect
172
 *   clear static cache of object.
173 85ad3d82 Assos Assos
 *
174 32700c57 Assos Assos
 * @return \LdapUserConf|\LdapUserConfAdmin
175 85ad3d82 Assos Assos
 */
176
function ldap_user_conf($type = NULL, $reset = FALSE) {
177
  static $ldap_user_conf;
178
  static $ldap_user_conf_admin;
179
180
  if ($type == 'admin' && ($reset || !is_object($ldap_user_conf_admin))) {
181
    ldap_servers_module_load_include('php', 'ldap_user', 'LdapUserConfAdmin.class');
182
    $ldap_user_conf_admin = new LdapUserConfAdmin();
183
  }
184
  elseif ($type != 'admin' && ($reset || !is_object($ldap_user_conf))) {
185
    ldap_servers_module_load_include('php', 'ldap_user', 'LdapUserConf.class');
186
    $ldap_user_conf = new LdapUserConf();
187
  }
188
189
  return ($type == 'admin') ? $ldap_user_conf_admin : $ldap_user_conf;
190
}
191
192
/**
193
 * Implements hook_ldap_attributes_needed_alter().
194
 */
195
function ldap_user_ldap_attributes_needed_alter(&$attributes, $params) {
196
197 32700c57 Assos Assos
  // Puid attributes are server specific.
198
  if (isset($params['sid']) && $params['sid']) {
199 85ad3d82 Assos Assos
    if (is_scalar($params['sid'])) {
200
      $ldap_server = ldap_servers_get_servers($params['sid'], 'enabled', TRUE);
201
    }
202
    else {
203
      $ldap_server = $params['sid'];
204
    }
205
206 32700c57 Assos Assos
    // Failed to find enabled server.
207
    if ($ldap_server === FALSE) {
208 85ad3d82 Assos Assos
      return;
209
    }
210
211
    $ldap_user_conf = ldap_user_conf();
212
    if (!isset($attributes['dn'])) {
213 32700c57 Assos Assos
      $attributes['dn'] = [];
214 85ad3d82 Assos Assos
    }
215 32700c57 Assos Assos
    // Force dn "attribute" to exist.
216
    $attributes['dn'] = ldap_servers_set_attribute_map($attributes['dn']);
217
    // Add the attributes required by the user configuration when provisioning drupal users.
218
    switch ($params['ldap_context']) {
219 85ad3d82 Assos Assos
      case 'ldap_user_insert_drupal_user':
220
      case 'ldap_user_update_drupal_user':
221
      case 'ldap_user_ldap_associate':
222 5136ce55 Assos Assos
      case 'all':
223 32700c57 Assos Assos
        $attributes[$ldap_server->user_attr] = ldap_servers_set_attribute_map(@$attributes[$ldap_server->user_attr]);
224 85ad3d82 Assos Assos
        $attributes[$ldap_server->mail_attr] = ldap_servers_set_attribute_map(@$attributes[$ldap_server->mail_attr]);
225 be58a50c Assos Assos
        if ($ldap_server->picture_attr) {
226
          $attributes[$ldap_server->picture_attr] = ldap_servers_set_attribute_map(@$attributes[$ldap_server->picture_attr]);
227
        }
228
        if ($ldap_server->unique_persistent_attr) {
229
          $attributes[$ldap_server->unique_persistent_attr] = ldap_servers_set_attribute_map(@$attributes[$ldap_server->unique_persistent_attr]);
230
        }
231 85ad3d82 Assos Assos
        if ($ldap_server->mail_template) {
232 bc175c27 Assos Assos
          ldap_servers_token_extract_attributes($attributes, $ldap_server->mail_template);
233 85ad3d82 Assos Assos
        }
234 32700c57 Assos Assos
        break;
235 85ad3d82 Assos Assos
    }
236
237
    $ldap_context = empty($params['ldap_context']) ? NULL : $params['ldap_context'];
238
    $direction = empty($params['direction']) ? $ldap_user_conf->ldapContextToProvDirection($ldap_context) : $params['direction'];
239
    $attributes_required_by_user_module_mappings = $ldap_user_conf->getLdapUserRequiredAttributes($direction, $ldap_context);
240
    $attributes = array_merge($attributes_required_by_user_module_mappings, $attributes);
241
242
  }
243
}
244
245
/**
246
 * Implements hook_ldap_user_attrs_list_alter().
247
 */
248
function ldap_user_ldap_user_attrs_list_alter(&$available_user_attrs, &$params) {
249
250
  $sid = (isset($params['ldap_server']) && is_object($params['ldap_server'])) ? $params['ldap_server']->sid : LDAP_USER_NO_SERVER_SID;
251
252
  $ldap_user_conf = $params['ldap_user_conf'];
253
  $direction = isset($params['direction']) ? $params['direction'] : LDAP_USER_PROV_DIRECTION_NONE;
254
255
  if ($direction == LDAP_USER_PROV_DIRECTION_TO_LDAP_ENTRY) {
256 32700c57 Assos Assos
    $available_user_attrs['[property.name]'] = [
257 85ad3d82 Assos Assos
      'name' => 'Property: Username',
258
      'source' => '',
259
      'direction' => LDAP_USER_PROV_DIRECTION_TO_LDAP_ENTRY,
260
      'enabled' => TRUE,
261 32700c57 Assos Assos
      'prov_events' => [LDAP_USER_EVENT_CREATE_LDAP_ENTRY, LDAP_USER_EVENT_SYNCH_TO_LDAP_ENTRY],
262 85ad3d82 Assos Assos
      'config_module' => 'ldap_user',
263
      'prov_module' => 'ldap_user',
264
      'configurable_to_ldap' => TRUE,
265 32700c57 Assos Assos
    ];
266 85ad3d82 Assos Assos
267 32700c57 Assos Assos
    $available_user_attrs['[property.mail]'] = [
268 85ad3d82 Assos Assos
      'name' => 'Property: Email',
269
      'source' => '',
270
      'direction' => LDAP_USER_PROV_DIRECTION_TO_LDAP_ENTRY,
271
      'enabled' => TRUE,
272 32700c57 Assos Assos
      'prov_events' => [LDAP_USER_EVENT_CREATE_LDAP_ENTRY, LDAP_USER_EVENT_SYNCH_TO_LDAP_ENTRY],
273 85ad3d82 Assos Assos
      'config_module' => 'ldap_user',
274
      'prov_module' => 'ldap_user',
275
      'configurable_to_ldap' => TRUE,
276 32700c57 Assos Assos
    ];
277 85ad3d82 Assos Assos
278 32700c57 Assos Assos
    $available_user_attrs['[property.picture]'] = [
279 85ad3d82 Assos Assos
      'name' => 'Property: picture',
280
      'source' => '',
281
      'direction' => LDAP_USER_PROV_DIRECTION_TO_LDAP_ENTRY,
282
      'enabled' => TRUE,
283 32700c57 Assos Assos
      'prov_events' => [LDAP_USER_EVENT_CREATE_LDAP_ENTRY, LDAP_USER_EVENT_SYNCH_TO_LDAP_ENTRY],
284 85ad3d82 Assos Assos
      'config_module' => 'ldap_user',
285
      'prov_module' => 'ldap_user',
286
      'configurable_to_ldap' => TRUE,
287 32700c57 Assos Assos
    ];
288 85ad3d82 Assos Assos
289 32700c57 Assos Assos
    $available_user_attrs['[property.uid]'] = [
290 85ad3d82 Assos Assos
      'name' => 'Property: Drupal User Id (uid)',
291
      'source' => '',
292
      'direction' => LDAP_USER_PROV_DIRECTION_TO_LDAP_ENTRY,
293
      'enabled' => TRUE,
294 32700c57 Assos Assos
      'prov_events' => [LDAP_USER_EVENT_CREATE_LDAP_ENTRY, LDAP_USER_EVENT_SYNCH_TO_LDAP_ENTRY],
295 85ad3d82 Assos Assos
      'config_module' => 'ldap_user',
296
      'prov_module' => 'ldap_user',
297
      'configurable_to_ldap' => TRUE,
298 32700c57 Assos Assos
    ];
299 85ad3d82 Assos Assos
300
  }
301
302
  // 1. Drupal user properties
303 32700c57 Assos Assos
  // 1.a make sure empty array are present so array + function works.
304
  foreach (['property.status', 'property.timezone', 'property.signature'] as $i => $property_id) {
305 85ad3d82 Assos Assos
    $property_token = '[' . $property_id . ']';
306
    if (!isset($available_user_attrs[$property_token]) || !is_array($available_user_attrs[$property_token])) {
307 32700c57 Assos Assos
      $available_user_attrs[$property_token] = [];
308 85ad3d82 Assos Assos
    }
309
  }
310 32700c57 Assos Assos
  // @todo make these merges so they don't override saved values such as 'enabled'
311
  $available_user_attrs['[property.status]'] = $available_user_attrs['[property.status]'] + [
312 85ad3d82 Assos Assos
    'name' => 'Property: Acount Status',
313
    'configurable_to_drupal' => 1,
314
    'configurable_to_ldap' => 1,
315
    'user_tokens' => '1=enabled, 0=blocked.',
316
    'enabled' => FALSE,
317
    'config_module' => 'ldap_user',
318
    'prov_module' => 'ldap_user',
319 32700c57 Assos Assos
  ];
320 85ad3d82 Assos Assos
321 32700c57 Assos Assos
  $available_user_attrs['[property.timezone]'] = $available_user_attrs['[property.timezone]'] + [
322 85ad3d82 Assos Assos
    'name' => 'Property: User Timezone',
323
    'configurable_to_drupal' => 1,
324
    'configurable_to_ldap' => 1,
325
    'enabled' => FALSE,
326
    'config_module' => 'ldap_user',
327
    'prov_module' => 'ldap_user',
328 32700c57 Assos Assos
  ];
329 85ad3d82 Assos Assos
330 32700c57 Assos Assos
  $available_user_attrs['[property.signature]'] = $available_user_attrs['[property.signature]'] + [
331 85ad3d82 Assos Assos
    'name' => 'Property: User Signature',
332
    'configurable_to_drupal' => 1,
333
    'configurable_to_ldap' => 1,
334
    'enabled' => FALSE,
335
    'config_module' => 'ldap_user',
336
    'prov_module' => 'ldap_user',
337 32700c57 Assos Assos
  ];
338 85ad3d82 Assos Assos
339 32700c57 Assos Assos
  // 2. Drupal user fields.
340 85ad3d82 Assos Assos
  $user_fields = field_info_instances('user', 'user');
341
  foreach ($user_fields as $field_name => $field_instance) {
342
    $field_id = "[field.$field_name]";
343
    if (!isset($available_user_attrs[$field_id]) || !is_array($available_user_attrs[$field_id])) {
344 32700c57 Assos Assos
      $available_user_attrs[$field_id] = [];
345 85ad3d82 Assos Assos
    }
346
347 32700c57 Assos Assos
    $available_user_attrs[$field_id] = $available_user_attrs[$field_id] + [
348 85ad3d82 Assos Assos
      'name' => t('Field') . ': ' . $field_instance['label'],
349
      'configurable_to_drupal' => 1,
350
      'configurable_to_ldap' => 1,
351
      'enabled' => FALSE,
352
      'config_module' => 'ldap_user',
353
      'prov_module' => 'ldap_user',
354 32700c57 Assos Assos
    ];
355 85ad3d82 Assos Assos
  }
356
357
  if (!$ldap_user_conf->provisionsDrupalAccountsFromLdap) {
358
    $available_user_attrs['[property.mail]']['config_module'] = 'ldap_user';
359
    $available_user_attrs['[property.name]']['config_module'] = 'ldap_user';
360
    $available_user_attrs['[property.picture]']['config_module'] = 'ldap_user';
361
  }
362
363
  if ($direction == LDAP_USER_PROV_DIRECTION_TO_LDAP_ENTRY) {
364 32700c57 Assos Assos
    $available_user_attrs['[password.random]'] = [
365 85ad3d82 Assos Assos
      'name' => 'Pwd: Random',
366
      'source' => '',
367
      'direction' => LDAP_USER_PROV_DIRECTION_TO_LDAP_ENTRY,
368
      'enabled' => TRUE,
369 32700c57 Assos Assos
      'prov_events' => [LDAP_USER_EVENT_CREATE_LDAP_ENTRY, LDAP_USER_EVENT_SYNCH_TO_LDAP_ENTRY],
370 85ad3d82 Assos Assos
      'config_module' => 'ldap_user',
371
      'prov_module' => 'ldap_user',
372
      'configurable_to_ldap' => TRUE,
373 32700c57 Assos Assos
    ];
374 85ad3d82 Assos Assos
375 32700c57 Assos Assos
    // Use user password when available fall back to random pwd.
376
    $available_user_attrs['[password.user-random]'] = [
377 85ad3d82 Assos Assos
      'name' => 'Pwd: User or Random',
378
      'source' => '',
379
      'direction' => LDAP_USER_PROV_DIRECTION_TO_LDAP_ENTRY,
380
      'enabled' => TRUE,
381 32700c57 Assos Assos
      'prov_events' => [LDAP_USER_EVENT_CREATE_LDAP_ENTRY, LDAP_USER_EVENT_SYNCH_TO_LDAP_ENTRY],
382 85ad3d82 Assos Assos
      'config_module' => 'ldap_user',
383
      'prov_module' => 'ldap_user',
384
      'configurable_to_ldap' => TRUE,
385 32700c57 Assos Assos
    ];
386 85ad3d82 Assos Assos
387 32700c57 Assos Assos
    // Use user password, do not modify if unavailable.
388
    $available_user_attrs['[password.user-only]'] = [
389
      'name' => 'Pwd: User Only',
390
      'source' => '',
391
      'direction' => LDAP_USER_PROV_DIRECTION_TO_LDAP_ENTRY,
392
      'enabled' => TRUE,
393
      'prov_events' => [LDAP_USER_EVENT_CREATE_LDAP_ENTRY, LDAP_USER_EVENT_SYNCH_TO_LDAP_ENTRY],
394
      'config_module' => 'ldap_user',
395
      'prov_module' => 'ldap_user',
396
      'configurable_to_ldap' => TRUE,
397
    ];
398 85ad3d82 Assos Assos
399
  }
400
401 32700c57 Assos Assos
  // This is where need to be added to arrays.
402 85ad3d82 Assos Assos
  if (!empty($ldap_user_conf->ldapUserSynchMappings[$direction])) {
403
404
    foreach ($ldap_user_conf->ldapUserSynchMappings[$direction] as $target_token => $mapping) {
405
      if ($direction == LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER && isset($mapping['user_attr'])) {
406
        $key = $mapping['user_attr'];
407
      }
408
      elseif ($direction == LDAP_USER_PROV_DIRECTION_TO_LDAP_ENTRY && isset($mapping['ldap_attr'])) {
409
        $key = $mapping['ldap_attr'];
410
      }
411
      else {
412
        continue;
413
      }
414
415 32700c57 Assos Assos
      foreach (['ldap_attr', 'user_attr', 'convert', 'direction', 'enabled', 'prov_events'] as $k) {
416 85ad3d82 Assos Assos
        if (isset($mapping[$k])) {
417
          $available_user_attrs[$key][$k] = $mapping[$k];
418
        }
419
        else {
420
          $available_user_attrs[$key][$k] = NULL;
421
        }
422
        $available_user_attrs[$key]['config_module'] = 'ldap_user';
423
        $available_user_attrs[$key]['prov_module'] = 'ldap_user';
424
      }
425
      if ($mapping['user_attr'] == 'user_tokens') {
426
        $available_user_attrs['user_attr'] = $mapping['user_tokens'];
427
      }
428
429
    }
430
431
  }
432
433 32700c57 Assos Assos
  // 3. profile2 fields
434 85ad3d82 Assos Assos
  // 4. $user->data array.   will need to be added manually.  perhaps better not to implement this at all?
435
}
436 32700c57 Assos Assos
437 85ad3d82 Assos Assos
/**
438
 * Implements hook_help().
439
 */
440
function ldap_user_help($path, $arg) {
441
442
  $ldap_user_help = t('LDAP user configuration determines how and when
443
    Drupal accounts are created based on LDAP data and which user fields
444
    are derived and synched to and from LDAP. See !helplink.',
445 32700c57 Assos Assos
    [
446 85ad3d82 Assos Assos
      '!helplink' => l(LDAP_USER_DRUPAL_HELP_URL, LDAP_USER_DRUPAL_HELP_URL),
447 32700c57 Assos Assos
    ]);
448 85ad3d82 Assos Assos
449
  switch ($path) {
450
    case 'admin/config/people/ldap/user':
451
      $output = '<p>' . $ldap_user_help . '</p>';
452
      return $output;
453
454
    case 'admin/help#ldap_user':
455
      $output = '<p>' . $ldap_user_help . '</p>';
456
      return $output;
457
  }
458
}
459
460
/**
461 32700c57 Assos Assos
 * Implements hook_form_FORM_ID_alter(). for user_login_block.
462 85ad3d82 Assos Assos
 */
463
function ldap_user_form_user_login_block_alter(&$form, &$form_state) {
464
  array_unshift($form['#validate'], 'ldap_user_grab_password_validate');
465
}
466
467
/**
468 32700c57 Assos Assos
 * Implements hook_form_FORM_ID_alter(). for user_login_form.
469 85ad3d82 Assos Assos
 */
470
function ldap_user_form_user_login_alter(&$form, $form_state) {
471
  array_unshift($form['#validate'], 'ldap_user_grab_password_validate');
472
}
473
474
/**
475 32700c57 Assos Assos
 * Implements hook_form_FORM_ID_alter(). for user_register_form.
476 85ad3d82 Assos Assos
 */
477
function ldap_user_form_user_profile_form_alter(&$form, $form_state) {
478
  array_unshift($form['#submit'], 'ldap_user_grab_password_validate');
479
}
480
481
/**
482 32700c57 Assos Assos
 * Implements hook_form_FORM_ID_alter(). for password_policy_password_tab.
483
 */
484 85ad3d82 Assos Assos
function ldap_user_form_password_policy_password_tab_alter(&$form, &$form_state) {
485
  array_unshift($form['#validate'], 'ldap_user_grab_password_validate');
486
}
487
488 be58a50c Assos Assos
/**
489 32700c57 Assos Assos
 * Implements hook_form_FORM_ID_alter(). for user-pass-reset form. Useful for
490
 * sites where this is the form ID for a user to intially set their password
491
 * (user clicks an emailed registration link, is prompted to set their password).
492
 */
493 be58a50c Assos Assos
function ldap_user_form_user_pass_reset_alter(&$form, &$form_state) {
494
  array_unshift($form['#validate'], 'ldap_user_grab_password_validate');
495
}
496
497 85ad3d82 Assos Assos
/**
498 32700c57 Assos Assos
 * Store password from logon forms in ldap_user_ldap_provision_pwd static variable
499
 * for use in provisioning to ldap.
500 85ad3d82 Assos Assos
 */
501
function ldap_user_grab_password_validate($form, &$form_state) {
502
503 32700c57 Assos Assos
  // This is not a login form but profile form and user is inserting password to update email.
504 85ad3d82 Assos Assos
  if (!empty($form_state['values']['current_pass_required_values'])) {
505
    if (!empty($form_state['values']['current_pass']) && empty($form_state['values']['pass'])) {
506
      ldap_user_ldap_provision_pwd('set', $form_state['values']['current_pass']);
507
    }
508 32700c57 Assos Assos
    // Or this is a profile form where the user is updating their own password.
509 85ad3d82 Assos Assos
    elseif (!empty($form_state['values']['pass'])) {
510 32700c57 Assos Assos
      ldap_user_ldap_provision_pwd('set', $form_state['values']['pass']);
511 85ad3d82 Assos Assos
    }
512
  }
513 32700c57 Assos Assos
  // Otherwise a logon form.
514 85ad3d82 Assos Assos
  elseif (!empty($form_state['values']['pass'])) {
515
    ldap_user_ldap_provision_pwd('set', $form_state['values']['pass']);
516
  }
517
518
}
519
520
/**
521 32700c57 Assos Assos
 * Implements hook_form_FORM_ID_alter(). for user_register_form.
522 85ad3d82 Assos Assos
 */
523
function ldap_user_form_user_register_form_alter(&$form, $form_state) {
524
525
  array_unshift($form['#submit'], 'ldap_user_grab_password_validate');
526
527
  if (!user_access('administer users')) {
528
    return;
529
  }
530
  $ldap_user_conf = ldap_user_conf();
531
  if ($ldap_user_conf->disableAdminPasswordField == TRUE) {
532 5136ce55 Assos Assos
    $form['account']['pass']['#type'] = 'value';
533 85ad3d82 Assos Assos
    $form['account']['pass']['#value'] = user_password(20);
534 5136ce55 Assos Assos
    $form['account']['pass_disabled']['#type'] = 'fieldset';
535
    $form['account']['pass_disabled']['#title'] = t('Password');
536
    $form['account']['pass_disabled'][]['#markup'] = t('An LDAP setting at /admin/config/people/ldap/user has disabled the password fields. Drupal will store a 20 character random password in the Drupal "users" table, and the user will login with their LDAP password.');
537 85ad3d82 Assos Assos
  }
538
539 32700c57 Assos Assos
  $ldap_fieldset = [];
540
  $options = [
541 85ad3d82 Assos Assos
    LDAP_USER_MANUAL_ACCT_CONFLICT_LDAP_ASSOCIATE => t('Make this an LDAP Associated account.  If a related LDAP account can not be found, a validation error will appear and the account will not be created.'),
542
    LDAP_USER_MANUAL_ACCT_CONFLICT_NO_LDAP_ASSOCIATE => t('Do not make this an LDAP Associated account.'),
543 32700c57 Assos Assos
  ];
544
  $ldap_fieldset['ldap_user_association'] = [
545 85ad3d82 Assos Assos
    '#type' => 'radios',
546
    '#options' => $options,
547
    '#required' => FALSE,
548
    '#title' => t('LDAP Entry Association.'),
549 32700c57 Assos Assos
  ];
550 85ad3d82 Assos Assos
551
  if ($ldap_user_conf->provisionEnabled(LDAP_USER_PROV_DIRECTION_TO_LDAP_ENTRY, LDAP_USER_DRUPAL_USER_PROV_ON_USER_UPDATE_CREATE)) {
552
    $ldap_fieldset['ldap_user_association']['#disabled'] = TRUE;
553 bc175c27 Assos Assos
    $ldap_fieldset['ldap_user_association']['#description'] = t('Since "Create
554 85ad3d82 Assos Assos
      or Synch to Drupal user anytime a Drupal user account is created or updated"
555
      is selected at admin/config/people/ldap/user, this option will have no
556
      effect so its disabled.');
557
  }
558
  elseif ($ldap_user_conf->manualAccountConflict != LDAP_USER_MANUAL_ACCT_CONFLICT_SHOW_OPTION_ON_FORM) {
559
    $ldap_fieldset['ldap_user_association']['#disabled'] = TRUE;
560 bc175c27 Assos Assos
    $ldap_fieldset['ldap_user_association']['#description'] = t('To enable
561 85ad3d82 Assos Assos
      this an LDAP server must be selected for provisioning to Drupal in
562
      admin/config/people/ldap/user and "Show option on user create form..." must be selected.');
563
  }
564
565 32700c57 Assos Assos
  $ldap_fieldset['ldap_user_create_ldap_acct'] = [
566 85ad3d82 Assos Assos
    '#type' => 'checkbox',
567
    '#title' => t('Create corresponding LDAP entry.'),
568 32700c57 Assos Assos
  ];
569 85ad3d82 Assos Assos
  if (!$ldap_user_conf->provisionEnabled(LDAP_USER_PROV_DIRECTION_TO_LDAP_ENTRY, LDAP_USER_DRUPAL_USER_PROV_ON_ALLOW_MANUAL_CREATE)) {
570
    $ldap_fieldset['ldap_user_create_ldap_acct']['#disabled'] = TRUE;
571
    $ldap_fieldset['ldap_user_create_ldap_acct']['#description'] = t('To enable
572
      this an LDAP server must be selected for provisioning to Drupal in
573
      admin/config/people/ldap/user and manual creation of LDAP accounts
574
      must be enabled also.');
575
  }
576
577
  if (count($ldap_fieldset) > 0) {
578
    $form['ldap_user_fields'] = $ldap_fieldset;
579
    $form['ldap_user_fields']['#type'] = 'fieldset';
580 bc175c27 Assos Assos
    $form['ldap_user_fields']['#title'] = t('LDAP Options');
581
    $form['ldap_user_fields']['#collapsible'] = TRUE;
582
    $form['ldap_user_fields']['#collapsed'] = FALSE;
583 85ad3d82 Assos Assos
  }
584
585
  $form['#validate'][] = 'ldap_user_form_register_form_validate';
586
  $form['#submit'][] = 'ldap_user_form_register_form_submit2';
587
588
}
589
590 32700c57 Assos Assos
/**
591
 *
592
 */
593 85ad3d82 Assos Assos
function ldap_user_form_register_form_validate($form, &$form_state) {
594
595
  $values = $form_state['values'];
596
  $user_ldap_entry = NULL;
597
  $drupal_username = $form_state['values']['name'];
598
599
  if ($values['ldap_user_association'] == LDAP_USER_MANUAL_ACCT_CONFLICT_NO_LDAP_ASSOCIATE) {
600 7547bb19 Assos Assos
    $form_state['values']['ldap_user_ldap_exclude'][LANGUAGE_NONE][0]['value'] = 1;
601 85ad3d82 Assos Assos
  }
602
603 32700c57 Assos Assos
  // If corresponding ldap account doesn't exist and provision not selected and make ldap associated is selected, throw error.
604 85ad3d82 Assos Assos
  if (!@$values['ldap_user_create_ldap_acct'] && @$values['ldap_user_association'] == LDAP_USER_MANUAL_ACCT_CONFLICT_LDAP_ASSOCIATE) {
605
    $ldap_user_conf = ldap_user_conf();
606
    $ldap_user = ldap_servers_get_user_ldap_data($drupal_username, $ldap_user_conf->ldapEntryProvisionServer, 'ldap_user_prov_to_drupal');
607
    if (!$ldap_user) {
608
609
      form_set_error('ldap_user_association', t('User %name does not have a corresponding LDAP Entry (dn).
610 32700c57 Assos Assos
        Under LDAP options, you may NOT select "Make this an LDAP Associated Account"', ['%name' => $drupal_username]));
611 85ad3d82 Assos Assos
    }
612
  }
613
614 32700c57 Assos Assos
  // If trying to provision and ldap account and one already exists, throw error.
615 85ad3d82 Assos Assos
  if (@$values['ldap_user_create_ldap_acct']) {
616
    $ldap_user_conf = ldap_user_conf();
617
    $ldap_user = ldap_servers_get_user_ldap_data($drupal_username, $ldap_user_conf->ldapEntryProvisionServer, 'ldap_user_prov_to_ldap');
618
    if ($ldap_user) {
619 32700c57 Assos Assos
      $tokens = ['%dn' => $ldap_user['dn'], '%name' => $drupal_username];
620 85ad3d82 Assos Assos
      form_set_error('ldap_user_create_ldap_acct', t('User %name already has a corresponding LDAP Entry (%dn).
621
        Uncheck "Create corresponding LDAP entry" to allow this Drupal user to be created.  Select
622
        "Make this an LDAP associated account" to associate this account with the ldap entry.', $tokens));
623
    }
624
  }
625
}
626
627 32700c57 Assos Assos
/**
628
 * Called after user_register_form_submit .**/
629 85ad3d82 Assos Assos
function ldap_user_form_register_form_submit2($form, &$form_state) {
630
631
  $values = $form_state['values'];
632
  $ldap_user_association_set = FALSE;
633
634
  if (@$values['ldap_user_create_ldap_acct']) {
635
    if ($account = user_load_by_name($values['name'])) {
636
      $ldap_user_conf = ldap_user_conf();
637
      $ldap_provision_entry = $ldap_user_conf->getProvisionRelatedLdapEntry($account);
638
      if (!$ldap_provision_entry) {
639
        $provision_result = $ldap_user_conf->provisionLdapEntry($account);
640
      }
641
      else {
642
        $ldap_user_association_set = TRUE;
643
      }
644
    }
645
    else {
646 32700c57 Assos Assos
      // don't do anything here.  If account is not created, other user module warnings will exist.
647 85ad3d82 Assos Assos
    }
648
  }
649
650
  if ($ldap_user_association_set || @$values['ldap_user_association'] == LDAP_USER_MANUAL_ACCT_CONFLICT_LDAP_ASSOCIATE) {
651
    $ldap_user_conf = ldap_user_conf();
652
    $ldap_user_conf->ldapAssociateDrupalAccount($form_state['values']['name']);
653
  }
654
655
}
656
657
/**
658 32700c57 Assos Assos
 * @param object $account
659
 *   as drupal user object.
660
 * @param array $edit
661
 *   is a drupal user edit array.
662
 * @param enum int $direction
663
 *   indicating which directions to test for association.
664 85ad3d82 Assos Assos
 *
665
 *
666
 * @return boolean TRUE if user should be excluded from ldap provision/synching
667
 */
668
function ldap_user_ldap_exclude($account = NULL, $edit = NULL, $direction = LDAP_USER_PROV_DIRECTION_ALL) {
669 32700c57 Assos Assos
  // Always exclude user 1.
670 85ad3d82 Assos Assos
  if (is_object($account) && isset($account->uid) && $account->uid == 1) {
671
    return TRUE;
672
  }
673
674 32700c57 Assos Assos
  // Exclude users who have the field ldap_user_ldap_exclude set to 1.
675 7547bb19 Assos Assos
  if (is_object($account) && isset($account->ldap_user_ldap_exclude[LANGUAGE_NONE][0]['value'])
676 85ad3d82 Assos Assos
    && $account->ldap_user_ldap_exclude[LANGUAGE_NONE][0]['value'] == 1) {
677
    return TRUE;
678
  }
679
680 32700c57 Assos Assos
  // Exclude new users who have the value set to 1 in their $edit array.
681 7547bb19 Assos Assos
  if (is_array($edit) && isset($edit['ldap_user_ldap_exclude'][LANGUAGE_NONE][0]['value'])
682 85ad3d82 Assos Assos
    && $edit['ldap_user_ldap_exclude'][LANGUAGE_NONE][0]['value'] == 1) {
683
    return TRUE;
684
  }
685
686 32700c57 Assos Assos
  // Everyone else is fine.
687 85ad3d82 Assos Assos
  return FALSE;
688
689
}
690
691
/**
692 32700c57 Assos Assos
 * @param object $account
693
 *   as drupal user object.
694
 * @param enum int $direction
695
 *   indicating which directions to test for association
696 85ad3d82 Assos Assos
 *   LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER signifies test if drupal account has been provisioned or synched from ldap
697
 *   LDAP_USER_PROV_DIRECTION_TO_LDAP_ENTRY signifies test if ldap account has been provisioned or synched from drupal
698 32700c57 Assos Assos
 *   NULL signifies check for either direction.
699 85ad3d82 Assos Assos
 *
700
 * @return boolean if user is ldap associated
701
 */
702
function ldap_user_is_ldap_associated($account, $direction = NULL) {
703
704
  $to_drupal_user = FALSE;
705
  $to_ldap_entry = FALSE;
706
707
  if ($direction === NULL || $direction == LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER) {
708
709 7547bb19 Assos Assos
    if (property_exists($account, 'ldap_user_current_dn') && !empty($account->ldap_user_current_dn[LANGUAGE_NONE][0]['value'])) {
710 85ad3d82 Assos Assos
      $to_drupal_user = TRUE;
711
    }
712
    elseif (isset($account->uid)) {
713 7547bb19 Assos Assos
      $authname = ldap_user_get_authname($account);
714 32700c57 Assos Assos
      $to_drupal_user = (boolean) $authname;
715 85ad3d82 Assos Assos
    }
716
  }
717
718
  if ($direction === NULL || $direction == LDAP_USER_PROV_DIRECTION_TO_LDAP_ENTRY) {
719 7547bb19 Assos Assos
    if (property_exists($account, 'ldap_user_prov_entries') && !empty($account->ldap_user_prov_entries[LANGUAGE_NONE][0]['value'])) {
720 85ad3d82 Assos Assos
      $to_ldap_entry = TRUE;
721
    }
722
  }
723
724
  if ($direction == LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER) {
725
    return $to_drupal_user;
726
  }
727
  elseif ($direction == LDAP_USER_PROV_DIRECTION_TO_LDAP_ENTRY) {
728
    return $to_ldap_entry;
729
  }
730
  else {
731
    return ($to_ldap_entry || $to_drupal_user);
732
  }
733
734
}
735 32700c57 Assos Assos
736 85ad3d82 Assos Assos
/**
737 32700c57 Assos Assos
 * Api function for synching
738
 * note: does no checking if synching is enabled or configured for a given context.
739 85ad3d82 Assos Assos
 */
740
function ldap_user_synch_to_drupal($username, $prov_event = LDAP_USER_EVENT_SYNCH_TO_DRUPAL_USER, $ldap_user = NULL) {
741
742
  $ldap_user_conf = ldap_user_conf();
743
  $account = user_load_by_name($username);
744 32700c57 Assos Assos
  $user_edit = [];
745 dd54aff9 Assos Assos
  $ldap_user_conf->synchToDrupalAccount($account, $user_edit, $prov_event, $ldap_user, TRUE);
746 85ad3d82 Assos Assos
747
}
748
749
/**
750 32700c57 Assos Assos
 * Api function for ldap associated user provisioning
751
 * note: does no checking if synching is enabled or configured for a given context.
752 85ad3d82 Assos Assos
 */
753 32700c57 Assos Assos
function ldap_user_provision_to_drupal($ldap_user, $user_edit = []) {
754 85ad3d82 Assos Assos
755
  $sid = $ldap_user['sid'];
756
  $ldap_user_conf = ldap_user_conf();
757
  $account = NULL;
758
  $ldap_user_conf->provisionDrupalAccount($account, $user_edit, $ldap_user, TRUE);
759
760
}
761
762
/**
763 32700c57 Assos Assos
 * Function to:
764 85ad3d82 Assos Assos
 *   -- store user entered password during pageload
765 32700c57 Assos Assos
 *   and protect unencrypted user password from other modules.
766 85ad3d82 Assos Assos
 *
767 32700c57 Assos Assos
 * @param enum string $action
768
 *   'get' | 'set'.
769
 * @param string | FALSE $value
770
 *   as user entered password.
771 85ad3d82 Assos Assos
 */
772
function ldap_user_ldap_provision_pwd($action, $value = NULL, $reset = FALSE) {
773
774
  static $current_user_pass;
775
776
  if ($reset) {
777
    $current_user_pass = NULL;
778
  }
779
780
  if ($action == 'set') {
781
    $current_user_pass = $value;
782
  }
783
  elseif ($action == 'get' && $current_user_pass) {
784
    return $current_user_pass;
785
  }
786
  else {
787
    return FALSE;
788
  }
789
790
}
791
792
/**
793 32700c57 Assos Assos
 * Function to avoid multiple synch or provision in same page load (if desired)
794
 *
795
 * @param enum string $action
796
 *   'synch' | 'provision' | 'set_page_load_key' | NULL.
797
 * @param enum string $op
798
 *   = 'set' or 'get'.
799
 *
800
 * @value mixed value associate with $op.
801 85ad3d82 Assos Assos
 *
802 32700c57 Assos Assos
 * @return bool|void
803 85ad3d82 Assos Assos
 */
804
function ldap_user_ldap_provision_semaphore($action, $op, $value = NULL, $reset = FALSE) {
805
806
  $calling_function = FALSE;
807 32700c57 Assos Assos
  // {.
808
  if (function_exists('debug_backtrace') && $backtrace = debug_backtrace()) {
809 85ad3d82 Assos Assos
    $calling_function = $backtrace[1]['function'];
810
  }
811
812
  static $ldap_accts;
813
  static $intialized;
814
815
  if ($reset || !$intialized) {
816 32700c57 Assos Assos
    $ldap_accts = [];
817 85ad3d82 Assos Assos
    $intialized = TRUE;
818
  }
819
820 32700c57 Assos Assos
  // Mark that the given drupal user has had ldap entry synched or provisioned on this page load.
821 85ad3d82 Assos Assos
  if ($op == 'set') {
822
    if ($action && $value) {
823
      $ldap_accts[$action][$value] = TRUE;
824
    }
825
    return;
826
  }
827
828 32700c57 Assos Assos
  // Has the given drupal user x action (synch or provision) been executed.
829 85ad3d82 Assos Assos
  if ($op == 'get') {
830
    if ($action && $value && isset($ldap_accts[$action][$value])) {
831
      return $ldap_accts[$action][$value];
832
    }
833
    else {
834
      return FALSE;
835
    }
836
  }
837
838
}
839
840
/**
841
 * Implements hook_user_login().
842
 */
843
function ldap_user_user_login(&$edit, $account) {
844
845
  if (ldap_user_ldap_exclude($account, $edit)) {
846
    return;
847
  }
848
  $ldap_user_conf = ldap_user_conf();
849 32700c57 Assos Assos
  $user_edit = [];
850 85ad3d82 Assos Assos
851
  ldap_user_reset_provision_server($ldap_user_conf, $account);
852
853 32700c57 Assos Assos
  // Provision or synch to ldap, not both.
854
  $provision_result = ['status' => 'none'];
855 85ad3d82 Assos Assos
856 32700c57 Assos Assos
  // Provision to ldap
857
  // Check for first time user.
858 85ad3d82 Assos Assos
  if (
859
      $ldap_user_conf->provisionsLdapEntriesFromDrupalUsers
860
      && ldap_user_ldap_provision_semaphore('provision', 'get', $account->name) === FALSE
861
      && !$ldap_user_conf->getProvisionRelatedLdapEntry($account)
862
      && $ldap_user_conf->ldapEntryProvisionServer
863
      && $ldap_user_conf->provisionEnabled(LDAP_USER_PROV_DIRECTION_TO_LDAP_ENTRY, LDAP_USER_LDAP_ENTRY_PROV_ON_AUTHENTICATE)
864
      ) {
865
    $provision_result = $ldap_user_conf->provisionLdapEntry($account);
866
    if ($provision_result['status'] == 'success') {
867
      ldap_user_ldap_provision_semaphore('provision', 'set', $account->name);
868
    }
869
  }
870 32700c57 Assos Assos
  // don't synch if just provisioned.
871 85ad3d82 Assos Assos
  if (
872
    $ldap_user_conf->provisionsLdapEntriesFromDrupalUsers
873 32700c57 Assos Assos
    && ldap_user_ldap_provision_semaphore('synch', 'get', $account->name) === FALSE
874 85ad3d82 Assos Assos
    && $provision_result['status'] != 'success'
875
    && $ldap_user_conf->provisionEnabled(LDAP_USER_PROV_DIRECTION_TO_LDAP_ENTRY, LDAP_USER_LDAP_ENTRY_PROV_ON_AUTHENTICATE)
876
    ) {
877
    $bool_result = $ldap_user_conf->synchToLdapEntry($account, $user_edit);
878
    if ($bool_result) {
879
      ldap_user_ldap_provision_semaphore('synch', 'set', $account->name);
880
    }
881
  }
882
883
  $prov_enabled = $ldap_user_conf->provisionEnabled(LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER, LDAP_USER_LDAP_ENTRY_PROV_ON_AUTHENTICATE);
884
885 32700c57 Assos Assos
  // Provision from LDAP if a new account was not just provisioned from LDAP.
886 85ad3d82 Assos Assos
  if (ldap_user_ldap_provision_semaphore('drupal_created', 'get', $account->name) === FALSE) {
887
    if ($ldap_user_conf->provisionsDrupalAccountsFromLdap && in_array(LDAP_USER_EVENT_SYNCH_TO_DRUPAL_USER, array_keys($ldap_user_conf->provisionsDrupalEvents))) {
888
      $ldap_user = ldap_servers_get_user_ldap_data($account->name, $ldap_user_conf->drupalAcctProvisionServer, 'ldap_user_prov_to_drupal');
889
      if ($ldap_user) {
890
        $ldap_server = ldap_servers_get_servers($ldap_user_conf->drupalAcctProvisionServer, NULL, TRUE);
891 32700c57 Assos Assos
        $ldap_user_conf->entryToUserEdit($ldap_user, $user_edit, $ldap_server, LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER, [LDAP_USER_EVENT_SYNCH_TO_DRUPAL_USER]);
892
        // See #1973352 and #935592.
893
        if (empty($account->picture->fid)) {
894 dd54aff9 Assos Assos
          $account2 = user_load($account->uid);
895
          $account->picture = $account2->picture;
896
        }
897
        $account = user_save($account, $user_edit, 'ldap_user');
898 85ad3d82 Assos Assos
      }
899
    }
900
  }
901
902
}
903
904
/**
905
 * Implements hook_user_insert().
906
 */
907
function ldap_user_user_insert(&$user_edit, $account, $category) {
908
909
  global $user;
910
  $not_associated = ldap_user_ldap_exclude($account, $user_edit);
911 32700c57 Assos Assos
  // Check for first time user.
912
  $new_account_request = (boolean) ($user->uid == 0 && $account->access == 0 && $account->login == 0);
913
  $already_provisioned_to_ldap = ldap_user_ldap_provision_semaphore('provision', 'get', $account->name);
914
  $already_synched_to_ldap = ldap_user_ldap_provision_semaphore('synch', 'user_action_query', $account->name);
915 85ad3d82 Assos Assos
  if ($not_associated || $already_synched_to_ldap || $already_synched_to_ldap || $new_account_request) {
916
    return;
917
  }
918
919
  $ldap_user_conf = ldap_user_conf();
920
  /**
921
   * in hook_user_insert, account is already created, so never call provisionDrupalAccount(), just
922
   * synchToDrupalAccount(), even if action is 'provision'
923
   */
924 32700c57 Assos Assos
  $empty_user_edit = [];
925 85ad3d82 Assos Assos
  if ($account->status && $ldap_user_conf->provisionEnabled(LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER, LDAP_USER_DRUPAL_USER_PROV_ON_USER_UPDATE_CREATE)) {
926
    $ldap_user_conf->synchToDrupalAccount($account, $empty_user_edit, LDAP_USER_EVENT_CREATE_DRUPAL_USER, NULL, TRUE);
927
  }
928
929
  if ($ldap_user_conf->provisionsLdapEntriesFromDrupalUsers) {
930
    $prov_enabled = $ldap_user_conf->provisionEnabled(LDAP_USER_PROV_DIRECTION_TO_LDAP_ENTRY, LDAP_USER_LDAP_ENTRY_PROV_ON_USER_UPDATE_CREATE);
931
    if ($prov_enabled) {
932
      $ldap_provision_entry = $ldap_user_conf->getProvisionRelatedLdapEntry($account);
933
      if (!$ldap_provision_entry) {
934
        $provision_result = $ldap_user_conf->provisionLdapEntry($account);
935
        if ($provision_result['status'] == 'success') {
936
          ldap_user_ldap_provision_semaphore('provision', 'set', $account->name);
937
        }
938 32700c57 Assos Assos
      }
939 85ad3d82 Assos Assos
      elseif ($ldap_provision_entry) {
940
        $bool_result = $ldap_user_conf->synchToLdapEntry($account, $user_edit);
941
        if ($bool_result) {
942
          ldap_user_ldap_provision_semaphore('synch', 'set', $account->name);
943
        }
944
      }
945
    }
946
  }
947
}
948
949
/**
950
 * Implements hook_user_update()
951
 */
952
function ldap_user_user_update(&$user_edit, $account, $category) {
953
  if (ldap_user_ldap_exclude($account, $user_edit)) {
954
    return;
955
  }
956
957
  $ldap_user_conf = ldap_user_conf();
958 32700c57 Assos Assos
  // Check for provisioning to LDAP; this will normally occur on hook_user_insert or other event when drupal user is created.
959 85ad3d82 Assos Assos
  if ($ldap_user_conf->provisionsLdapEntriesFromDrupalUsers &&
960
      $ldap_user_conf->provisionEnabled(LDAP_USER_PROV_DIRECTION_TO_LDAP_ENTRY, LDAP_USER_LDAP_ENTRY_PROV_ON_USER_UPDATE_CREATE)) {
961
962 32700c57 Assos Assos
    $already_provisioned_to_ldap = ldap_user_ldap_provision_semaphore('provision', 'get', $account->name);
963
    $already_synched_to_ldap = ldap_user_ldap_provision_semaphore('synch', 'get', $account->name);
964 85ad3d82 Assos Assos
    if ($already_provisioned_to_ldap || $already_synched_to_ldap) {
965
      return;
966
    }
967
968 32700c57 Assos Assos
    $provision_result = ['status' => 'none'];
969
    // Always check if provisioning to ldap has already occurred this page load.
970 85ad3d82 Assos Assos
    $ldap_entry = $ldap_user_conf->getProvisionRelatedLdapEntry($account);
971 32700c57 Assos Assos
    // {.
972
    if (!$ldap_entry) {
973 85ad3d82 Assos Assos
      $provision_result = $ldap_user_conf->provisionLdapEntry($account);
974
      if ($provision_result['status'] == 'success') {
975
        ldap_user_ldap_provision_semaphore('provision', 'set', $account->name);
976
      }
977
    }
978 32700c57 Assos Assos
    // Synch if not just provisioned and enabled.
979
    if ($provision_result['status'] != 'success') {
980
      // Always check if provisioing to ldap has already occurred this page load.
981 85ad3d82 Assos Assos
      $provision_enabled = $ldap_user_conf->provisionEnabled(LDAP_USER_PROV_DIRECTION_TO_LDAP_ENTRY, LDAP_USER_LDAP_ENTRY_PROV_ON_USER_UPDATE_CREATE);
982
      $ldap_entry = $ldap_user_conf->getProvisionRelatedLdapEntry($account);
983
      if ($provision_enabled && $ldap_entry) {
984
        $bool_result = $ldap_user_conf->synchToLdapEntry($account, $user_edit);
985
        if ($bool_result) {
986
          ldap_user_ldap_provision_semaphore('synch', 'set', $account->name);
987
        }
988
      }
989
    }
990
  }
991
992
}
993
994 32700c57 Assos Assos
/**
995 85ad3d82 Assos Assos
 * Implements hook_user_presave()
996
 */
997
function ldap_user_user_presave(&$user_edit, $account, $category) {
998
999
  if (ldap_user_ldap_exclude($account, $user_edit)) {
1000
    return;
1001
  }
1002
  if (isset($account->name)) {
1003
    $drupal_username = $account->name;
1004
  }
1005
  elseif (!empty($user_edit['name'])) {
1006
    $drupal_username = $user_edit['name'];
1007
  }
1008
  else {
1009
    return;
1010
  }
1011
  $ldap_user_conf = ldap_user_conf();
1012
1013
  ldap_user_reset_provision_server($ldap_user_conf, $account);
1014
1015 32700c57 Assos Assos
  // Check for provisioning to drupal and override synched user fields/props
1016
  // Provision from LDAP if a new account was not just provisioned from LDAP.
1017 85ad3d82 Assos Assos
  if (ldap_user_ldap_provision_semaphore('drupal_created', 'get', $drupal_username) === FALSE) {
1018
    if ($ldap_user_conf->provisionsDrupalAccountsFromLdap && in_array(LDAP_USER_EVENT_SYNCH_TO_DRUPAL_USER, array_keys($ldap_user_conf->provisionsDrupalEvents))) {
1019
      if ($ldap_user_conf->provisionEnabled(LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER, LDAP_USER_DRUPAL_USER_PROV_ON_USER_UPDATE_CREATE)) {
1020
        if (ldap_user_is_ldap_associated($account, LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER)) {
1021
          $ldap_user = ldap_servers_get_user_ldap_data($drupal_username, $ldap_user_conf->drupalAcctProvisionServer, 'ldap_user_prov_to_drupal');
1022 bc175c27 Assos Assos
          if ($ldap_user) {
1023
            $ldap_server = ldap_servers_get_servers($ldap_user_conf->drupalAcctProvisionServer, NULL, TRUE);
1024 32700c57 Assos Assos
            $ldap_user_conf->entryToUserEdit($ldap_user, $user_edit, $ldap_server, LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER, [LDAP_USER_EVENT_SYNCH_TO_DRUPAL_USER]);
1025 bc175c27 Assos Assos
          }
1026 85ad3d82 Assos Assos
        }
1027
      }
1028
    }
1029
  }
1030
1031
}
1032
1033
/**
1034
 * Implements hook_user_delete().
1035
 */
1036
function ldap_user_user_delete($account) {
1037 32700c57 Assos Assos
  // Drupal user account is about to be deleted.
1038 85ad3d82 Assos Assos
  $ldap_user_conf = ldap_user_conf();
1039
  if (
1040
      $ldap_user_conf->provisionsLdapEntriesFromDrupalUsers
1041
      && $ldap_user_conf->provisionEnabled(LDAP_USER_PROV_DIRECTION_TO_LDAP_ENTRY, LDAP_USER_LDAP_ENTRY_DELETE_ON_USER_DELETE)
1042
      ) {
1043
    $boolean_result = $ldap_user_conf->deleteProvisionedLdapEntries($account);
1044 32700c57 Assos Assos
    // No need to watchdog here, because fail in deleteProvisionedLdapEntries provides watchdog entry.
1045 85ad3d82 Assos Assos
  }
1046
}
1047
1048
/**
1049
 * Implements hook_field_widget_info().
1050 32700c57 Assos Assos
 * to provide field type for LDAP fields.
1051 85ad3d82 Assos Assos
 */
1052
function ldap_user_field_widget_info() {
1053 32700c57 Assos Assos
  return [
1054
    'ldap_user_hidden' => [
1055 85ad3d82 Assos Assos
      'label' => t('Hidden Text Field'),
1056 32700c57 Assos Assos
      'field types' => ['text'],
1057
      'settings' => [],
1058
    ],
1059
  ];
1060 85ad3d82 Assos Assos
}
1061
1062
/**
1063
 * Implements hook_field_widget_settings_form().
1064
 */
1065
function ldap_user_field_widget_settings_form($field, $instance) {
1066 32700c57 Assos Assos
  return [];
1067 85ad3d82 Assos Assos
}
1068
1069
/**
1070
 * Implements hook_field_widget_form().
1071
 */
1072
function ldap_user_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
1073
1074 32700c57 Assos Assos
  $main_widget = [];
1075 85ad3d82 Assos Assos
1076
  switch ($instance['widget']['type']) {
1077
    case 'ldap_user_hidden':
1078 32700c57 Assos Assos
      $element['value'] = $element + [
1079 05237dd8 Assos Assos
        '#type' => 'value',
1080
        '#value' => isset($items[$delta]['value']) ? $items[$delta]['value'] : NULL,
1081 32700c57 Assos Assos
        '#attached' => [
1082
          'css' => [
1083 bc175c27 Assos Assos
            drupal_get_path('module', 'ldap_user') . '/ldap_user.css',
1084 32700c57 Assos Assos
          ],
1085
        ],
1086
      ];
1087 85ad3d82 Assos Assos
      break;
1088
  }
1089
1090
  return $element;
1091
}
1092
1093 32700c57 Assos Assos
/**
1094
 *
1095
 */
1096 85ad3d82 Assos Assos
function ldap_user_synch_triggers_key_values() {
1097
1098 32700c57 Assos Assos
  return [
1099 85ad3d82 Assos Assos
    LDAP_USER_DRUPAL_USER_PROV_ON_USER_UPDATE_CREATE => t('On synch to Drupal user create or update. Requires a server with binding method of "Service Account Bind" or "Anonymous Bind".'),
1100
    LDAP_USER_DRUPAL_USER_PROV_ON_AUTHENTICATE => t('On create or synch to Drupal user when successfully authenticated with LDAP credentials. (Requires LDAP Authentication module).'),
1101
    LDAP_USER_DRUPAL_USER_PROV_ON_ALLOW_MANUAL_CREATE => t('On manual creation of Drupal user from admin/people/create and "Create corresponding LDAP entry" is checked'),
1102
    LDAP_USER_LDAP_ENTRY_PROV_ON_USER_UPDATE_CREATE => t('On creation or synch of an LDAP entry when a Drupal account is created or updated. Only applied to accounts with a status of approved.'),
1103
    LDAP_USER_LDAP_ENTRY_PROV_ON_AUTHENTICATE => t('On creation or synch of an LDAP entry when a user authenticates.'),
1104
    LDAP_USER_LDAP_ENTRY_DELETE_ON_USER_DELETE => t('On deletion of an LDAP entry when the corresponding Drupal Account is deleted.  This only applies when the LDAP entry was provisioned by Drupal by the LDAP User module.'),
1105 32700c57 Assos Assos
  ];
1106 85ad3d82 Assos Assos
1107
}
1108
1109 32700c57 Assos Assos
/**
1110
 *
1111
 */
1112 85ad3d82 Assos Assos
function ldap_user_all_events() {
1113 32700c57 Assos Assos
  return [
1114 85ad3d82 Assos Assos
    LDAP_USER_EVENT_SYNCH_TO_DRUPAL_USER,
1115
    LDAP_USER_EVENT_CREATE_DRUPAL_USER,
1116
    LDAP_USER_EVENT_SYNCH_TO_LDAP_ENTRY,
1117
    LDAP_USER_EVENT_CREATE_LDAP_ENTRY,
1118
    LDAP_USER_EVENT_LDAP_ASSOCIATE_DRUPAL_ACCT,
1119 32700c57 Assos Assos
  ];
1120 85ad3d82 Assos Assos
1121
}
1122
1123
/**
1124
 * @param array $account
1125
 * @param string $text
1126
 * @return string text with tokens replaced
1127
 */
1128
function ldap_user_token_replace($token, $account, $entity = NULL) {
1129
  $desired_tokens = ldap_servers_token_tokens_needed_for_template($token);
1130
  $tokens = ldap_user_token_tokenize_entry($account, $desired_tokens, LDAP_SERVERS_TOKEN_PRE, LDAP_SERVERS_TOKEN_POST, $entity);
1131
  $result = str_replace(array_keys($tokens), array_values($tokens), $token);
1132
  return $result;
1133
}
1134
1135
/**
1136 32700c57 Assos Assos
 * Turn an ldap entry into a token array suitable for the t() function.
1137
 *
1138 85ad3d82 Assos Assos
 * @param drupal user object $account
1139 32700c57 Assos Assos
 * @param array $token_keys
1140
 *   as list of token/value pairs to generate.
1141 85ad3d82 Assos Assos
 * @param string prefix token prefix such as !,%,[
1142
 * @param string suffix token suffix such as ]
1143
 *
1144
 * @return token array suitable for t() functions of with lowercase keys as exemplified below
1145
 */
1146
function ldap_user_token_tokenize_entry($account, $token_keys, $pre = LDAP_SERVERS_TOKEN_PRE, $post = LDAP_SERVERS_TOKEN_POST, $user_entity = NULL) {
1147
1148
  $detailed_watchdog_log = variable_get('ldap_help_watchdog_detail', 0);
1149 32700c57 Assos Assos
  $tokens = [];
1150 85ad3d82 Assos Assos
  if (!$user_entity) {
1151
    list($discard, $user_entity) = ldap_user_load_user_acct_and_entity($account->uid, 'uid');
1152
  }
1153
1154
  foreach ($token_keys as $token_key) {
1155 32700c57 Assos Assos
    // Target id is of form field.lname, property.mail, field.dept:0, etc.
1156 85ad3d82 Assos Assos
    list($type, $attr_ordinal) = explode('.', $token_key);
1157
    $parts = explode(':', $attr_ordinal);
1158
    $attr = $parts[0];
1159
    $ordinal = (count($parts) > 1) ? $parts[1] : 0;
1160
    $token = $pre . $token_key . $post;
1161
    switch ($type) {
1162
1163
      case 'field':
1164 32700c57 Assos Assos
        if (isset($user_entity->{$attr}[LANGUAGE_NONE][$ordinal]['value'])) {
1165 7547bb19 Assos Assos
          $tokens[$token] = $user_entity->{$attr}[LANGUAGE_NONE][$ordinal]['value'];
1166 85ad3d82 Assos Assos
        }
1167 32700c57 Assos Assos
        break;
1168 85ad3d82 Assos Assos
1169
      case 'property':
1170
        if (property_exists($account, $attr)) {
1171
          $tokens[$token] = $account->{$attr};
1172
        }
1173 32700c57 Assos Assos
        break;
1174 85ad3d82 Assos Assos
1175
      // @todo: 3. tokenize profile 2
1176
    }
1177
1178
  }
1179
1180
  return $tokens;
1181
}
1182
1183 32700c57 Assos Assos
/**
1184
 * Load user $account and $entity, given uid or $username.
1185
 *
1186
 * @param string $user_id
1187
 *   is username or uid.
1188
 * @param enum $user_id_type
1189
 *   is 'username' or 'uid'
1190
 *
1191
 *   return array $account and $user_entity.
1192
 */
1193
function ldap_user_load_user_acct_and_entity($user_id, $user_id_type = 'username') {
1194 85ad3d82 Assos Assos
1195 32700c57 Assos Assos
  if ($user_id_type == 'username') {
1196
    $account = user_load_by_name($user_id);
1197
  }
1198
  else {
1199
    $account = user_load($user_id);
1200
  }
1201
  if ($account) {
1202
    $user_entities = entity_load('user', [$account->uid]);
1203
    $user_entity = $user_entities[$account->uid];
1204
  }
1205
  else {
1206
    $user_entity = NULL;
1207
  }
1208 85ad3d82 Assos Assos
1209 32700c57 Assos Assos
  return [$account, $user_entity];
1210 85ad3d82 Assos Assos
1211 32700c57 Assos Assos
}
1212 85ad3d82 Assos Assos
1213
/**
1214
 * Implements hook_ldap_servers_username_to_ldapname_alter
1215 32700c57 Assos Assos
 * - Set ldap name to auth name.
1216 85ad3d82 Assos Assos
 */
1217
function ldap_user_ldap_servers_username_to_ldapname_alter(&$ldap_username, $drupal_username, $context) {
1218 32700c57 Assos Assos
  // Alter the name only if it has not been altered already, ie php eval code.
1219 85ad3d82 Assos Assos
  if ($ldap_username == $drupal_username) {
1220
    $authname = ldap_user_get_authname($ldap_username);
1221
    if (!empty($authname)) {
1222
      $ldap_username = $authname;
1223
    }
1224
  }
1225
}
1226
1227
/**
1228 7547bb19 Assos Assos
 * Returns LDAP authname from the authmap table for a variant input.
1229 85ad3d82 Assos Assos
 *
1230
 * @param $data
1231
 *   A variant input. Allowed variable types:
1232
 *   - object: user account object
1233
 *   - string: username
1234 7547bb19 Assos Assos
 *
1235 32700c57 Assos Assos
 * @return string|null
1236 7547bb19 Assos Assos
 *   Returns the LDAP authname of the passed Drupal user.
1237 85ad3d82 Assos Assos
 */
1238
function ldap_user_get_authname($data) {
1239 32700c57 Assos Assos
  $cache = &drupal_static(__FUNCTION__, []);
1240 85ad3d82 Assos Assos
1241
  $authname = NULL;
1242
  $uid = NULL;
1243
1244
  if (is_object($data)) {
1245 32700c57 Assos Assos
    // Object - set uid if object has uid and uid > 0.
1246 85ad3d82 Assos Assos
    if (!empty($data->uid)) {
1247
      $uid = $data->uid;
1248
    }
1249
  }
1250 7547bb19 Assos Assos
  else {
1251 32700c57 Assos Assos
    // String - load account and set uid if uid > 0.
1252 85ad3d82 Assos Assos
    $account = user_load_by_name($data);
1253
    if (!empty($account->uid)) {
1254
      $uid = $account->uid;
1255
    }
1256
  }
1257
1258 32700c57 Assos Assos
  // Exit if no uid found.
1259 85ad3d82 Assos Assos
  if (empty($uid)) {
1260
    return NULL;
1261
  }
1262
1263 32700c57 Assos Assos
  // Run query if uid is not statically cached.
1264 85ad3d82 Assos Assos
  if (!array_key_exists($uid, $cache)) {
1265 32700c57 Assos Assos
    $authname = db_query('SELECT authname FROM {authmap} WHERE uid = :uid AND module = :module', [
1266 85ad3d82 Assos Assos
      ':uid' => $uid,
1267
      ':module' => 'ldap_user',
1268 32700c57 Assos Assos
    ])->fetchField();
1269 85ad3d82 Assos Assos
1270
    $cache[$uid] = !empty($authname) ? $authname : NULL;
1271
  }
1272
1273
  return $cache[$uid];
1274
}
1275
1276
/**
1277
 * Resets the drupalAcctProvisionServer if needed.
1278
 *
1279
 * Used when handling multi-domain authentication to set the provisioning
1280
 * server to be the server that last successfully authenticated the user.
1281
 *
1282
 * @param LdapUserConf $ldap_user_conf
1283
 *   The LDAP User Configuration object.
1284
 *
1285
 * @param object $account
1286
 *   The Drupal user account.
1287
 */
1288
function ldap_user_reset_provision_server($ldap_user_conf, $account) {
1289
  // Reset the Provision Server sid to the server that last authenticated the user.
1290
  if ($ldap_user_conf->drupalAcctProvisionServer == LDAP_USER_AUTH_SERVER_SID) {
1291
    $sid = FALSE;
1292
    if (isset($account->data['ldap_user']['init']['sid'])) {
1293
      $sid = $account->data['ldap_user']['init']['sid'];
1294
    }
1295
    else {
1296
      // Provisioning Server sid is not in the account object,
1297
      // see if we have a session variable with it.
1298
      $sid = isset($_SESSION[LDAP_USER_SESSION_PROV_SID]) ? $_SESSION[LDAP_USER_SESSION_PROV_SID] : FALSE;
1299
    }
1300
    if ($sid) {
1301
      $ldap_user_conf->drupalAcctProvisionServer = $sid;
1302
    }
1303
  }
1304
}