Projet

Général

Profil

Paste
Télécharger (47 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / ldap / ldap_user / ldap_user.module @ 7547bb19

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