Projet

Général

Profil

Paste
Télécharger (46,6 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / ldap / ldap_user / ldap_user.module @ b42754b9

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