Projet

Général

Profil

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

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

1 85ad3d82 Assos Assos
<?php
2
3
define('LDAP_SERVER_LDAP_QUERY_CHUNK', 50);
4
define('LDAP_SERVERS_MAXFILTER_ORS', 30);
5
define('LDAP_SERVER_LDAP_QUERY_RECURSION_LIMIT', 10);
6
7
define('LDAP_SCOPE_BASE', 1);
8
define('LDAP_SCOPE_ONELEVEL', 2);
9
define('LDAP_SCOPE_SUBTREE', 3);
10
11
define('LDAP_TEST_QUERY_CONTEXT', 999);
12
13
define('LDAP_SERVERS_PROJECT_TAG', 'ldap');
14
define('LDAP_SERVERS_MENU_BASE_PATH', 'admin/config/people/ldap');
15
define('LDAP_SERVERS_INDEX_BASE_PATH', 'admin/config/people/ldap/servers');
16
define('LDAP_SERVERS_MENU_BASE_PATH_PARTS', 4); // for argument offsets
17
define('LDAP_SERVERS_DRUPAL_HELP_URL', 'http://drupal.org/node/997082');
18
19
define('LDAP_SERVERS_TOKEN_PRE', '[');
20
define('LDAP_SERVERS_TOKEN_POST', ']');
21
define('LDAP_SERVERS_TOKEN_DEL', ':');
22
define('LDAP_SERVERS_TOKEN_MODIFIER_DEL', ';');
23
24
define('LDAP_SERVERS_ENC_TYPE_MD5', 1);
25
define('LDAP_SERVERS_ENC_TYPE_CRYPT', 2);
26
define('LDAP_SERVERS_ENC_TYPE_SALTED_CRYPT', 3);
27
define('LDAP_SERVERS_ENC_TYPE_EXTENDED_DES', 4);
28
define('LDAP_SERVERS_ENC_TYPE_MD5C', 5);
29 dd54aff9 Assos Assos
define('LDAP_SERVERS_ENC_TYPE_BLOWFISH', 6);
30 85ad3d82 Assos Assos
define('LDAP_SERVERS_ENC_TYPE_SALTED_MD5', 7);
31
define('LDAP_SERVERS_ENC_TYPE_SHA', 8);
32
define('LDAP_SERVERS_ENC_TYPE_SALTED_SHA', 9);
33
define('LDAP_SERVERS_ENC_TYPE_CLEARTEXT', 10);
34 dd54aff9 Assos Assos
35 5136ce55 Assos Assos
define('LDAP_SERVERS_CYPHER_MODE', 'cfb');
36 85ad3d82 Assos Assos
37
define('LDAP_SERVERS_BIND_METHOD_SERVICE_ACCT', 1);
38
define('LDAP_SERVERS_BIND_METHOD_USER', 2);
39
define('LDAP_SERVERS_BIND_METHOD_ANON', 3);
40
define('LDAP_SERVERS_BIND_METHOD_ANON_USER', 4);
41
define('LDAP_SERVERS_BIND_METHOD_DEFAULT', 1);
42
43
define('LDAP_SERVERS_DERIVE_GROUP_FROM_DN', 1);
44
define('LDAP_SERVERS_DERIVE_GROUP_FROM_ATTRIBUTE', 2);
45
define('LDAP_SERVERS_DERIVE_GROUP_FROM_ENTRY', 4);
46
47
define('LDAP_SERVER_MASSAGE_DISPLAY', 1); //  ... value is being displayed in UI
48
define('LDAP_SERVER_MASSAGE_TOKEN_REPLACE', 2); // ... value is about to be used to generate token (e.g. [...] to be replaced
49
50
define('LDAP_SERVER_MASSAGE_QUERY_LDAP', 5); //  ...value is about to be used in ldap query
51
define('LDAP_SERVER_MASSAGE_QUERY_DB', 6); //  ...value is about to be in an sql query
52
define('LDAP_SERVER_MASSAGE_QUERY_ARRAY', 7); //  ...value is about to be found in array values
53
define('LDAP_SERVER_MASSAGE_QUERY_PROPERTY', 8); //  ...value is about to be found in object property values
54
55
define('LDAP_SERVER_MASSAGE_STORE_LDAP', 13); // ...value is about to be stored in ldap entry
56
define('LDAP_SERVER_MASSAGE_STORE_DB', 14); // ...value is about to be stored in db
57
define('LDAP_SERVER_MASSAGE_STORE_ARRAY', 15); // ...value is about to be stored in array
58
define('LDAP_SERVER_MASSAGE_STORE_PROPERTY', 16); // ...value is about to be stored in object property
59
60
define('LDAP_SERVER_GROUPS_RECURSE_DEPTH', 20);
61
62
define('LDAP_FAIL', -1);
63
64
define('LDAP_SUCCESS', 0x00);
65
define('LDAP_OPERATIONS_ERROR', 0x01);
66
define('LDAP_PROTOCOL_ERROR', 0x02);
67
define('LDAP_TIMELIMIT_EXCEEDED', 0x03);
68
define('LDAP_SIZELIMIT_EXCEEDED', 0x04);
69
define('LDAP_COMPARE_FALSE', 0x05);
70
define('LDAP_COMPARE_TRUE', 0x06);
71
define('LDAP_AUTH_METHOD_NOT_SUPPORTED', 0x07);
72
define('LDAP_STRONG_AUTH_REQUIRED', 0x08);
73
//NotusedinLDAPv3);
74
define('LDAP_PARTIAL_RESULTS', 0x09);
75
76
//Next5newinLDAPv3);
77
define('LDAP_REFERRAL', 0x0a);
78
define('LDAP_ADMINLIMIT_EXCEEDED', 0x0b);
79
define('LDAP_UNAVAILABLE_CRITICAL_EXTENSION', 0x0c);
80
define('LDAP_CONFIDENTIALITY_REQUIRED', 0x0d);
81
define('LDAP_SASL_BIND_INPROGRESS', 0x0e);
82
83
define('LDAP_NO_SUCH_ATTRIBUTE', 0x10);
84
define('LDAP_UNDEFINED_TYPE', 0x11);
85
define('LDAP_INAPPROPRIATE_MATCHING', 0x12);
86
define('LDAP_CONSTRAINT_VIOLATION', 0x13);
87
define('LDAP_TYPE_OR_VALUE_EXISTS', 0x14);
88
define('LDAP_INVALID_SYNTAX', 0x15);
89
90
define('LDAP_NO_SUCH_OBJECT', 0x20);
91
define('LDAP_ALIAS_PROBLEM', 0x21);
92
define('LDAP_INVALID_DN_SYNTAX', 0x22);
93
94
define('LDAP_IS_LEAF', 0x23);
95
define('LDAP_ALIAS_DEREF_PROBLEM', 0x24);
96 5136ce55 Assos Assos
if ( ! defined('LDAP_DEREF_NEVER') )
97
  define('LDAP_DEREF_NEVER', 0x25);
98 85ad3d82 Assos Assos
99
define('LDAP_INAPPROPRIATE_AUTH', 0x30);
100
define('LDAP_INVALID_CREDENTIALS', 0x31);
101
define('LDAP_INSUFFICIENT_ACCESS', 0x32);
102
define('LDAP_BUSY', 0x33);
103
define('LDAP_UNAVAILABLE', 0x34);
104
define('LDAP_UNWILLING_TO_PERFORM', 0x35);
105
define('LDAP_LOOP_DETECT', 0x36);
106
107
define('LDAP_SORT_CONTROL_MISSING', 0x3C);
108
define('LDAP_INDEX_RANGE_ERROR', 0x3D);
109
110
define('LDAP_NAMING_VIOLATION', 0x40);
111
define('LDAP_OBJECT_CLASS_VIOLATION', 0x41);
112
define('LDAP_NOT_ALLOWED_ON_NONLEAF', 0x42);
113
define('LDAP_NOT_ALLOWED_ON_RDN', 0x43);
114
define('LDAP_ALREADY_EXISTS', 0x44);
115
define('LDAP_NO_OBJECT_CLASS_MODS', 0x45);
116
define('LDAP_RESULTS_TOO_LARGE', 0x46);
117
//NexttwoforLDAPv3);
118
define('LDAP_AFFECTS_MULTIPLE_DSAS', 0x47);
119
define('LDAP_OTHER', 0x50);
120
121
//UsedbysomeAPIs);
122
define('LDAP_SERVER_DOWN', 0x51);
123
define('LDAP_LOCAL_ERROR', 0x52);
124
define('LDAP_ENCODING_ERROR', 0x53);
125
define('LDAP_DECODING_ERROR', 0x54);
126
define('LDAP_TIMEOUT', 0x55);
127
define('LDAP_AUTH_UNKNOWN', 0x56);
128
define('LDAP_FILTER_ERROR', 0x57);
129
define('LDAP_USER_CANCELLED', 0x58);
130
define('LDAP_PARAM_ERROR', 0x59);
131
define('LDAP_NO_MEMORY', 0x5a);
132
133
//PreliminaryLDAPv3codes);
134
define('LDAP_CONNECT_ERROR', 0x5b);
135
define('LDAP_NOT_SUPPORTED', 0x5c);
136
define('LDAP_CONTROL_NOT_FOUND', 0x5d);
137
define('LDAP_NO_RESULTS_RETURNED', 0x5e);
138
define('LDAP_MORE_RESULTS_TO_RETURN', 0x5f);
139
define('LDAP_CLIENT_LOOP', 0x60);
140
define('LDAP_REFERRAL_LIMIT_EXCEEDED', 0x61);
141
142
require_once('ldap_servers.functions.inc');
143
require_once('ldap_servers.tokens.inc');
144
145
/**
146
 * Implements hook_init().
147
 */
148
function ldap_servers_init() {
149
  drupal_add_css(drupal_get_path('module', 'ldap_servers') . '/ldap_servers.admin.css', 'module');
150
}
151
152
/**
153
 * Advertise the current ldap api version
154
 */
155
function ldap_api_version() {
156
  return '2.0';
157
}
158
159
function ldap_servers_menu() {
160
  $menu_offset = 4;
161
162
  $items['admin/config/people/ldap'] = array(
163
    'title' => 'LDAP Configuration',
164
    'description' => 'LDAP authentication, authorization, provisioning, etc.',
165
    'page callback' => 'drupal_get_form',
166
    'page arguments' => array('ldap_servers_settings'),
167
    'access arguments' => array('administer site configuration'),
168
    'file' => 'ldap_servers.settings.inc',
169
  );
170
171
  $items['admin/config/people/ldap/settings'] = array(
172
    'title' => '1. Settings',
173
    'weight' => -2,
174
    'type' => MENU_DEFAULT_LOCAL_TASK,
175
  );
176
177
  $items['admin/config/people/ldap/servers'] = array(
178
    'title' => '2. Servers',
179
    'page callback' => 'ldap_servers_edit_index',
180
    'weight' => -1,
181
    'type' => MENU_LOCAL_TASK,
182
    'access arguments' => array('administer site configuration'),
183
    'file' => 'ldap_servers.admin.inc',
184
  );
185
186
  $items['admin/config/people/ldap/servers/list'] = array(
187
    'title' => 'List',
188
    'type' => MENU_DEFAULT_LOCAL_TASK,
189
  );
190
191
  $items['admin/config/people/ldap/servers/add'] = array(
192
    'title' => 'Add LDAP Server Configuration',
193
    'page callback' => 'drupal_get_form',
194
    'page arguments' => array('ldap_servers_admin_form', 'add'),
195
    'type' => MENU_LOCAL_TASK + MENU_CONTEXT_INLINE,
196
    'weight' => 3,
197
    'access arguments' => array('administer site configuration'),
198
    'file' => 'ldap_servers.admin.inc',
199
  );
200
201
  $items['admin/config/people/ldap/servers/edit/%'] = array(
202
    'title' => 'Edit LDAP Server Configuration',
203
    'page callback' => 'drupal_get_form',
204
    'page arguments' => array('ldap_servers_admin_form', 'edit', $menu_offset + 2),
205
    'access arguments' => array('administer site configuration'),
206
    'file' => 'ldap_servers.admin.inc',
207
  );
208
209
  $items['admin/config/people/ldap/servers/test/%'] = array(
210
    'title' => 'Test LDAP Server Configuration',
211
    'page callback' => 'drupal_get_form',
212
    'page arguments' => array('ldap_servers_test_form', $menu_offset + 1, $menu_offset + 2),
213
    'access arguments' => array('administer site configuration'),
214
    'file' => 'ldap_servers.test_form.inc',
215
  );
216
217
  $items['admin/config/people/ldap/servers/delete/%'] = array(
218
    'title' => 'Delete LDAP Server',
219
    'page callback' => 'drupal_get_form',
220
    'page arguments' => array('ldap_servers_admin_delete', $menu_offset + 1, $menu_offset + 2),
221
    'access arguments' => array('administer site configuration'),
222
    'file' => 'ldap_servers.admin.inc',
223
  );
224
225
  $items['admin/config/people/ldap/servers/enable/%'] = array(
226
    'title' => 'Enable LDAP Server',
227
    'page callback' => 'drupal_get_form',
228
    'page arguments' => array('ldap_servers_admin_enable_disable', $menu_offset + 1, $menu_offset + 2),
229
    'access arguments' => array('administer site configuration'),
230
    'file' => 'ldap_servers.admin.inc',
231
  );
232
233
  $items['admin/config/people/ldap/servers/disable/%'] = array(
234
    'title' => 'Enable LDAP Server',
235
    'page callback' => 'drupal_get_form',
236
    'page arguments' => array('ldap_servers_admin_enable_disable', $menu_offset + 1, $menu_offset + 2),
237
    'access arguments' => array('administer site configuration'),
238
    'file' => 'ldap_servers.admin.inc',
239
  );
240
241
  return $items;
242
}
243
244
245
/**
246
 * Implements hook_theme().
247
 */
248
function ldap_servers_theme() {
249
  return array(
250
    'ldap_servers_list' => array(
251
      'variables' => array('ldap_servers' => NULL, 'actions' => TRUE, 'type' => 'table'),
252
      'render element' => 'element',
253
      'file' => 'ldap_servers.theme.inc'
254
    ),
255
    'ldap_servers_server' => array(
256
      'variables' => array('ldap_server' => NULL, 'actions' => FALSE, 'type' => 'detail'),
257
      'render element' => 'element',
258
      'file' => 'ldap_servers.theme.inc'
259
    ),
260
    'ldap_server_token_table' => array(
261
      'variables' => array('tokens' => array()),
262
      'render element' => 'element',
263
      'file' => 'ldap_servers.theme.inc'
264
    ),
265
    'ldap_server_ldap_entry_table' => array(
266
      'variables' => array('entry' => array()),
267
      'render element' => 'element',
268
      'file' => 'ldap_servers.theme.inc'
269
    ),
270
  );
271
}
272
273
274
  /**
275
    * Implements hook_cron().
276
    */
277
  function ldap_servers_cron() {
278
    // if any modules implement hook_ldap_servers_user_cron().
279
    // user entity query to find most recent 100 entries that have not been processed
280
    // query for these and pass to modules implementing hook_ldap_server_maintenance()
281
    // update user field to have current date as date most recently checked
282
  }
283
284
  /** get mixed case match from case insensitive search
285
   *
286
   * @param string mixed case $key
287
   * @param array mixed case $array
288
   * @return string matching key in mixed case or FALSE
289
   */
290
  function ldap_server_find_key($key, $array) {
291
    $keys = array_combine(array_change_key_case($array), $array);
292
    if (isset($keys[drupal_strtolower($key)])) {
293
      return $keys[drupal_strtolower($key)];
294
    }
295
    else {
296
      return FALSE;
297
    }
298
  }
299
300
  /**
301
   * Implements hook_ldap_attributes_needed_alter().
302
   */
303
  function ldap_servers_ldap_attributes_needed_alter(&$attributes, $params) {
304
305
    $attributes['dn'] = ldap_servers_set_attribute_map(@$attributes['dn'], 'ldap_dn'); // force this data type
306
307
    if ($params['sid'] && $params['sid']) { // puid attributes are server specific
308
      if (is_scalar($params['sid'])) {
309
        $ldap_server = ldap_servers_get_servers($params['sid'], 'enabled', TRUE);
310
      }
311
      else {
312
        $ldap_server = $params['sid'];
313
      }
314
      // mail, unique_persistent_attr, user_attr, mail_template, and user_dn_expression are needed for all functionality
315
      if (!isset($attributes[$ldap_server->mail_attr])) {
316
        $attributes[$ldap_server->mail_attr] = ldap_servers_set_attribute_map();
317
      }
318 be58a50c Assos Assos
      if ($ldap_server->picture_attr && !isset($attributes[$ldap_server->picture_attr])) {
319 85ad3d82 Assos Assos
        $attributes[$ldap_server->picture_attr] = ldap_servers_set_attribute_map();
320
      }
321
      if ($ldap_server->unique_persistent_attr && !isset($attributes[$ldap_server->unique_persistent_attr])) {
322
        $attributes[$ldap_server->unique_persistent_attr] = ldap_servers_set_attribute_map();
323
      }
324 be58a50c Assos Assos
      if ($ldap_server->groupUserMembershipsAttr && !isset($attributes[$ldap_server->groupUserMembershipsAttr])) {
325
        $attributes[$ldap_server->groupUserMembershipsAttr] = ldap_servers_set_attribute_map();
326
      }
327 85ad3d82 Assos Assos
      if ($ldap_server->user_dn_expression) {
328
        ldap_servers_token_extract_attributes($attributes, $ldap_server->user_dn_expression, TRUE);
329
      }
330
      if ($ldap_server->mail_template) {
331
        ldap_servers_token_extract_attributes($attributes, $ldap_server->mail_template);
332
      }
333
      if (!isset($attributes[$ldap_server->user_attr])) {
334
        $attributes[$ldap_server->user_attr] = ldap_servers_set_attribute_map();
335
      }
336
    }
337
  }
338
339
340
/**
341
 * Implements hook_ldap_user_attrs_list_alter().
342
 */
343
344
function ldap_servers_ldap_user_attrs_list_alter(&$available_user_attrs, &$params) {
345
346
  if (isset($params['ldap_server']) && $params['ldap_server']) {
347
    $ldap_server = $params['ldap_server'];
348
  }
349
  else {
350
    return; // without a server id, ldap_servers module has nothing to offer
351
  }
352
  $ldap_user_conf  = $params['ldap_user_conf'];
353
  $direction = $params['direction'];
354
355
  $tokens = array(
356
    '!edit_link' => l($ldap_server->editPath, $ldap_server->editPath),
357
    '!sid' => $ldap_server->sid,
358
  );
359
360
  $server_edit_path = 'admin/config/people/ldap/servers/edit/' . $ldap_server->sid;
361
362
  if ($direction == LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER) {
363
364
    /** these 4 user fields indentify where in ldap and which ldap server they are associated with.
365
     they are required for a Drupal account to be "ldap associated" regardless of if any other
366
     fields/properties are provisioned or synched
367
    */
368
369
    if ($ldap_server->unique_persistent_attr) {
370
      foreach (array(
371
        'field.ldap_user_puid_sid',
372
        'field.ldap_user_puid',
373
        'field.ldap_user_puid_property',
374
        ) as $i => $property_id) {
375
        $property_token = '[' . $property_id . ']';
376
        if (!isset($available_user_attrs[$property_token]) || !is_array($available_user_attrs[$property_token])) {
377
          $available_user_attrs[$property_token] = array();
378
        }
379
      }
380
381
      $available_user_attrs['[field.ldap_user_puid_sid]'] =  array(
382
        'name' => t('Field: sid providing PUID'),
383
        'configurable_to_drupal' => 0,
384
        'configurable_to_ldap' => 1,
385
        'source' => t('!sid', $tokens),
386
        'notes' => 'not configurable',
387
        'direction' => LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER,
388
        'enabled' => TRUE,
389
        'prov_events' => array(LDAP_USER_EVENT_CREATE_DRUPAL_USER),
390
        'config_module' => 'ldap_servers',
391
        'prov_module' => 'ldap_user',
392
      ) + $available_user_attrs['[field.ldap_user_puid_sid]'];
393
394
      $available_user_attrs['[field.ldap_user_puid]'] =  array(
395
        'name' => t('Field: PUID', $tokens),
396
        'configurable_to_drupal' => 0,
397
        'configurable_to_ldap' => 1,
398
        'source' => '[' . $ldap_server->unique_persistent_attr . ']',
399
        'notes' => 'configure at ' . $server_edit_path,
400
        'convert' => $ldap_server->unique_persistent_attr_binary,
401
        'direction' => LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER,
402
        'enabled' => TRUE,
403
        'prov_events' => array(LDAP_USER_EVENT_CREATE_DRUPAL_USER),
404
        'config_module' => 'ldap_servers',
405
        'prov_module' => 'ldap_user',
406
      ) + $available_user_attrs['[field.ldap_user_puid]'];
407
408
      $available_user_attrs['[field.ldap_user_puid_property]'] =
409
      array(
410
        'name' => t('Field: PUID Attribute', $tokens),
411
        'configurable_to_drupal' => 0,
412
        'configurable_to_ldap' => 1,
413
        'source' =>  $ldap_server->unique_persistent_attr ,
414
        'notes' => 'configure at ' . $server_edit_path,
415
        'direction' => LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER,
416
        'enabled' => TRUE,
417
        'prov_events' => array(LDAP_USER_EVENT_CREATE_DRUPAL_USER),
418
        'config_module' => 'ldap_servers',
419
        'prov_module' => 'ldap_user',
420
      ) + $available_user_attrs['[field.ldap_user_puid_property]'];
421
    }
422
423
    $token = '[field.ldap_user_current_dn]';
424
    if (!isset($available_user_attrs[$token]) || !is_array($available_user_attrs[$token])) {
425
      $available_user_attrs[$token] = array();
426
    }
427
    $available_user_attrs[$token] =
428
    array(
429
      'name' => t('Field: Most Recent DN', $tokens),
430
      'configurable_to_drupal' => 0,
431
      'configurable_to_ldap' => 0,
432
      'source' => '[dn]',
433
      'notes' => 'not configurable',
434
      'direction' => LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER,
435
      'enabled' => TRUE,
436
      'prov_events' => array(LDAP_USER_EVENT_CREATE_DRUPAL_USER, LDAP_USER_EVENT_SYNCH_TO_DRUPAL_USER),
437
      'config_module' => 'ldap_servers',
438
      'prov_module' => 'ldap_user',
439
    ) + $available_user_attrs[$token];
440
441
    if ($ldap_user_conf->provisionsDrupalAccountsFromLdap) {
442
      if (!isset($available_user_attrs['[property.name]']) || !is_array($available_user_attrs['[property.name]'])) {
443
        $available_user_attrs['[property.name]'] = array();
444
      }
445
      $available_user_attrs['[property.name]'] = array(
446
        'name' => 'Property: Username',
447
        'source' => '[' . $ldap_server->user_attr . ']',
448
        'direction' => LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER,
449
        'enabled' => TRUE,
450
        'prov_events' => array(LDAP_USER_EVENT_CREATE_DRUPAL_USER, LDAP_USER_EVENT_SYNCH_TO_DRUPAL_USER),
451
        'config_module' => 'ldap_servers',
452
        'prov_module' => 'ldap_user',
453
      ) + $available_user_attrs['[property.name]'];
454
455
      if (!isset($available_user_attrs['[property.mail]']) || !is_array($available_user_attrs['[property.mail]'])) {
456
        $available_user_attrs['[property.mail]'] = array();
457
      }
458
      $available_user_attrs['[property.mail]'] =  array(
459
        'name' => 'Property: Email',
460
        'source' => ($ldap_server->mail_template) ? $ldap_server->mail_template : '[' . $ldap_server->mail_attr . ']',
461
        'direction' => LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER,
462
        'enabled' => TRUE,
463
        'prov_events' => array(LDAP_USER_EVENT_CREATE_DRUPAL_USER, LDAP_USER_EVENT_SYNCH_TO_DRUPAL_USER),
464
        'config_module' => 'ldap_servers',
465
        'prov_module' => 'ldap_user',
466
      ) + $available_user_attrs['[property.mail]'];
467
468
      if ($ldap_server->picture_attr) {
469
        if (!isset($available_user_attrs['[property.picture]']) || !is_array($available_user_attrs['[property.picture]'])) {
470
          $available_user_attrs['[property.picture]'] = array();
471
        }
472
        $available_user_attrs['[property.picture]'] = array(
473
            'name' => 'Property: Picture',
474
            'source' => '[' . $ldap_server->picture_attr . ']',
475
            'direction' => LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER,
476
            'enabled' => TRUE,
477
            'prov_events' => array(LDAP_USER_EVENT_CREATE_DRUPAL_USER, LDAP_USER_EVENT_SYNCH_TO_DRUPAL_USER),
478
            'config_module' => 'ldap_servers',
479
            'prov_module' => 'ldap_user',
480
        ) + $available_user_attrs['[property.picture]'];
481
      }
482
    }
483
  }
484
}
485
486
/**
487
 * flush server static cache
488
 */
489
490
function ldap_servers_flush_server_cache() {
491
  $discard = ldap_servers_get_servers(NULL, 'all', FALSE, TRUE); // flush server cache
492
}
493
494
495
/**
496
 * function to replace module_load_include such that when
497
 * something is not included, drupal will exit instead
498
 * of attempting something half baked.
499
 */
500
function ldap_servers_module_load_include($type, $module, $name = NULL) {
501
  $result = module_load_include($type, $module, $name);
502
  if ($result === FALSE) {
503
    print "Failed to load file $name.$type in module $module";
504
    drupal_exit();
505
  }
506
}
507
508
/**
509
 *
510
 * return ldap server conf objects
511
 *
512
 * @param alphanum $sid
513
 * @param enum $type 'all', 'enabled',
514
 * @param boolean $flatten signifies if array or single object returned.  Only works if sid is specified
515
 * @param boolean $reset do not use cached or static result
516
 * @return - array of server conf object keyed on sid
517
 *         - single server conf object (if flatten == TRUE)
518
 */
519
function ldap_servers_get_servers($sid = NULL, $type = NULL, $flatten = FALSE, $reset = FALSE) {
520
  if (variable_get('ldap_simpletest', FALSE)) {
521
    return _ldap_servers_get_simpletest_servers($sid, $type, $flatten, $reset);
522
  }
523
  else {
524
    return _ldap_servers_get_servers($sid, $type, $flatten, $reset);
525
  }
526
}
527
528
529
/**
530
 * see ldap_servers_get_servers()
531
 */
532
function _ldap_servers_get_servers($sid, $type, $flatten, $reset) {
533
  ldap_servers_module_load_include('php', 'ldap_servers', 'LdapServerAdmin.class');
534
  static $servers;
535
  $type = ($type) ? $type : 'all';
536
  if ($reset) {
537
    $servers = array();
538
  }
539
  if (!isset($servers['all'])) {
540
    $servers['all'] = LdapServerAdmin::getLdapServerObjects('all', NULL, 'LdapServer', $reset);
541
  }
542
543
  if (!isset($servers['enabled'])) {
544
    $servers['enabled'] = array();
545
    foreach ($servers['all'] as $_sid => $ldap_server) {
546
      if ($ldap_server->status == 1) {
547
        $servers['enabled'][$_sid] = $ldap_server;
548
      }
549
    }
550
  }
551
552
  if ($sid) {
553
    if (!isset($servers[$type][$sid])) {
554
      return FALSE;
555
    }
556
    return ($flatten) ? $servers[$type][$sid] : array($sid => $servers[$type][$sid]);
557
  }
558
559
  if (isset($servers[$type])) {
560
    return $servers[$type];
561
  }
562
}
563
564
/**
565
 * see ldap_servers_get_servers()
566
 */
567
function _ldap_servers_get_simpletest_servers($sid, $type = NULL, $flatten, $reset = TRUE) {
568
569
  if (!$type) {
570
    $type = 'all';
571
  }
572
573
  //two flavors of mock servers exist.  ultimately v2 will be used in all simpletests
574
  if (variable_get('ldap_simpletest', 0) == 2) {
575
    ldap_servers_module_load_include('php', 'ldap_test', 'LdapServerTest.class');
576
    $servers['all'] = LdapServerTest::getLdapServerObjects(NULL, 'all', FALSE);
577
    foreach ($servers['all'] as $_sid => $ldap_server) {
578
      if ($ldap_server->status == 1) {
579
        $servers['enabled'][$_sid] = $ldap_server;
580
      }
581
    }
582
  }
583
584
  if ($sid) {
585
    if (!isset($servers[$type][$sid])) {
586
      return FALSE;
587
    }
588
    return ($flatten) ? $servers[$type][$sid] : array($sid => $servers[$type][$sid]);
589
  }
590
591
  if (isset($servers[$type])) {
592
    return $servers[$type];
593
  }
594
}
595
function ldap_servers_debug($variable) {
596
  if (variable_get('ldap_simpletest', FALSE) && function_exists('dpm')) {
597
    dpm($variable);
598
  }
599
  else {
600
    debug($variable);
601
  }
602
}
603
function ldap_servers_cache_clear() {
604
  $discard = ldap_servers_get_servers(NULL, 'all', FALSE, TRUE);
605
  if (module_exists('ctools')) {
606
    ctools_export_load_object_reset('ldap_servers');
607
  }
608
}
609
610
/**
611
 * function to convert microsoft style guids to strings
612
 */
613
function ldap_servers_msguid($value) {
614
615
  $hex_string = bin2hex($value);
616
  // (MS?) GUID are displayed with first three GUID parts as "big endian"
617
  // Doing this so String value matches what other LDAP tool displays for AD.
618
  $value = strtoupper(substr( $hex_string, 6, 2) . substr( $hex_string, 4, 2) .
619
  substr( $hex_string, 2, 2) . substr( $hex_string, 0, 2) . '-' .
620
  substr( $hex_string, 10, 2) . substr( $hex_string, 8, 2) . '-' .
621
  substr( $hex_string, 14, 2) . substr( $hex_string, 12, 2) . '-' .
622
  substr( $hex_string, 16, 4) . '-' . substr( $hex_string, 20, 12));
623
624
  return $value;
625
}
626
627
 /**
628
 * Create a "binary safe" string for use in LDAP filters
629
 * @param $value
630
 * @return string
631
 */
632
function ldap_servers_binary_filter($value) {
633
  $match = '';
634
  if (preg_match('/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/i', $value)) {
635
    // Reconstruct proper "memory" order from (MS?) GUID string.
636
    $hex_string = str_replace('-', '', $value);
637
    $value = substr($hex_string, 6, 2) . substr($hex_string, 4, 2) .
638
      substr($hex_string, 2, 2) . substr($hex_string, 0, 2) .
639
      substr($hex_string, 10, 2) . substr($hex_string, 8, 2) .
640
      substr($hex_string, 14, 2) . substr($hex_string, 12, 2) .
641
      substr($hex_string, 16, 4) . substr($hex_string, 20, 12);
642
  }
643
644
  for ($i = 0; $i < strlen($value); $i = $i + 2 ) {
645
    $match .= '\\' . substr($value, $i, 2);
646
  }
647
648
  return $match;
649
}
650
651
/**
652
 * general binary conversion function for guids
653
 * tries to determine which approach based on length
654
 * of string
655
 */
656
function ldap_servers_binary($value) {
657
  if (strlen($value) == 16) {
658
    $value = ldap_servers_msguid($value);
659
  }
660
  else {
661
    $value = bin2hex($value);
662
  }
663
  return $value;
664
}
665
666
/**
667
 * @todo needs caching element.  several modules could potentially call this in the same
668
 * page request.
669
 *
670
 * @param std object $drupal_user is drupal $user object
671
 * @param string $sid is a server id
672
 * @param scalar $ldap_context
673
 */
674
675
function ldap_servers_get_user_ldap_data($drupal_user, $sid = NULL, $ldap_context = NULL) {
676
  if (is_object($drupal_user) && property_exists($drupal_user, 'uid') &&
677
      function_exists('ldap_user_get_authname') && ($authname = ldap_user_get_authname($drupal_user))) {
678
    $drupal_username = $authname;
679
  }
680
  else {
681
    $drupal_username = (is_object($drupal_user)) ? $drupal_user->name : $drupal_user;
682
  }
683 dd54aff9 Assos Assos
  //Sometimes we have username instead of a drupal user object
684
  //For example, when using LDAP user test form (admin/config/people/ldap/user/test)
685
  //But we can still load the user by using $drupal_username  if $drupal_user is not an object
686
  if ( !(is_object($drupal_user)) ) {
687
    $user_object = user_load_by_name($drupal_username);
688
    if (is_object($user_object) && property_exists($user_object, 'uid')) {
689
      $drupal_user = $user_object;
690
    }
691
  }
692 85ad3d82 Assos Assos
  // if no explicit $sid, find most appropriate one
693
  if (module_exists('ldap_user') && (!$sid || $sid == LDAP_USER_AUTH_SERVER_SID)) {
694
    if (property_exists($drupal_user, 'ldap_user_puid_sid') &&
695 7547bb19 Assos Assos
        !empty($drupal_user->ldap_user_puid_sid[LANGUAGE_NONE][0]['value'])
696 85ad3d82 Assos Assos
      ) {
697 7547bb19 Assos Assos
      $sid = $drupal_user->ldap_user_puid_sid[LANGUAGE_NONE][0]['value'];
698 85ad3d82 Assos Assos
    }
699
    else {
700
      $ldap_user_conf = ldap_user_conf();
701
      ldap_user_reset_provision_server($ldap_user_conf, $drupal_user);
702
      $sid = $ldap_user_conf->drupalAcctProvisionServer;
703
    }
704
  }
705
  elseif (!$sid) {
706
    $ldap_servers = ldap_servers_get_servers(NULL, 'enabled');
707
    if (count($ldap_servers) == 1) {
708
      $sids = array_keys($ldap_servers);
709
      $sid = $sids[0];
710
    }
711
  }
712
713
  $ldap_server = ($sid) ? ldap_servers_get_servers($sid, 'enabled', TRUE) : FALSE;
714
715
  if ($ldap_server === FALSE) {
716
    watchdog('ldap_servers', 'Failed to load server object %sid in _ldap_servers_get_user_ldap_data', array('%sid' => $sid), WATCHDOG_ERROR);
717
    return FALSE;
718
  }
719
720
  $ldap_user = $ldap_server->userUserNameToExistingLdapEntry($drupal_username, $ldap_context);
721
722
  if ($ldap_user) {
723
    $ldap_user['sid'] = $sid;
724
  }
725
  else {
726
    $ldap_user = FALSE;
727
  }
728
729
  return $ldap_user;
730
}
731
732
/**
733
 * @param array $attribute_map for a given attribute in form array('values' => array(), 'data_type' => NULL) as outlined in ldap_user/README.developers.txt
734
 * @param enum string $conversion as type of conversion to do @see ldap_servers_convert_attribute().  e.g. base64_encode, bin2hex, msguid, md5
735
 * @param array $values in form array(<ordinal> => <value> | NULL) where NULL indicates value is needed for provisioning or other operations.
736
 *
737
 * @return array $attribute_map with converted values.  If nothing passed in create empty array in proper structure.
738
 *   array('values' => array(
739
 *      0 => 'john',
740
 *      1 => 'johnny'
741
 *      )
742
 *   );
743
 ))
744
 */
745
746
function ldap_servers_set_attribute_map($attribute = NULL, $conversion = NULL, $values = NULL) {
747
748
  $attribute = (is_array($attribute)) ? $attribute : array();
749
  $attribute['conversion'] = $conversion;
750
  if (!$values && (!isset($attribute['values']) || !is_array($attribute['values']))) {
751
    $attribute['values'] = array(0 => NULL);
752
  }
753
  elseif (is_array($values)) { //merge into array overwriting ordinals
754
    foreach ($values as $ordinal => $value) {
755
      if ($conversion) {
756
        $value = ldap_servers_convert_attribute($value, $conversion);
757
      }
758
      $attribute['values'][(int)$ordinal] = $value;
759
    }
760
  }
761
  return $attribute;
762
}
763
764
/**
765
 * @param string $value as value to be converted
766
 * @param string $conversion such as base64_encode, bin2hex, msguid, md5
767
 * @return converted $value
768
 */
769
function ldap_servers_convert_attribute($value, $conversion = NULL) {
770
771
      if ($conversion) {
772
773
        switch ($conversion) {
774
          case 'base64_encode':
775
            $value = base64_encode($value);
776
            break;
777
778
          case 'bin2hex':
779
            $value = bin2hex($value);
780
            break;
781
782
          case 'msguid':
783
            $value = ldap_servers_msguid($value);
784
            break;
785
786
          case 'binary':
787
            $value = ldap_servers_binary($value);
788
            break;
789
790
          case 'md5':
791
            $value = '{md5}' . base64_encode(pack('H*', md5($value)));
792
            break;
793
        }
794
795
      }
796
797
  return $value;
798
}
799
800
function ldap_servers_ldap_extension_summary($op = 'data') {
801
  ldap_servers_module_load_include('inc', 'ldap_servers', 'ldap_servers.status');
802
  return _ldap_servers_ldap_extension_summary($op);
803
}
804
805
function ldap_servers_ldap_extension_loaded() {
806
  return extension_loaded('ldap');
807
}
808
809
function ldap_servers_encrypt($text, $encryption = NULL) {
810
  ldap_servers_module_load_include('inc', 'ldap_servers', 'ldap_servers.encryption');
811
  return _ldap_servers_encrypt($text, $encryption);
812
}
813
814
function ldap_servers_encrypt_types($category = 'all') {
815
  ldap_servers_module_load_include('inc', 'ldap_servers', 'ldap_servers.encryption');
816
  return _ldap_servers_encrypt_types($category);
817
}
818
819
function ldap_servers_decrypt($encrypted, $encryption = NULL) {
820
  ldap_servers_module_load_include('inc', 'ldap_servers', 'ldap_servers.encryption');
821
  return _ldap_servers_decrypt($encrypted, $encryption);
822
}
823
824
function ldap_servers_php_supports_pagination() {
825
  return (boolean)(function_exists('ldap_control_paged_result_response') && function_exists('ldap_control_paged_result'));
826
}
827
828
829
function ldap_servers_help($path, $arg) {
830
831
  $servers_help = '<p>' . t('LDAP Servers store "LDAP server configurations" so other modules can connect to them and leverage their data.') . ' ';
832
  $servers_help .= t('LDAP Authentication and LDAP Authorization are two such modules. Generally, only one LDAP Server configuration is needed.') . ' ' . '</p>';
833
  $servers_help .= '<p>' . t('When multiple LDAP server configurations are needed, each is not necessarily a separate physical LDAP server; they may have different binding users or some other configuration difference.') . ' </p>';
834
835
  switch ($path) {
836
    case 'admin/config/people/ldap/servers':
837
      return $servers_help;
838
839
   case 'admin/help#ldap_servers':
840
      $servers_help .= '<h3>' . t('Configuration - Settings') . '</h3>';
841
      $servers_help .= '<dl>';
842
      $servers_help .= '<dt>' . t('ENCRYPTION') . '</dt>';
843
      $servers_help .= '<dd>' . t('With encryption enabled, passwords will be stored in encrypted form. This is two way encryption because the actual password needs to used to bind to LDAP. So it offers minimal defense if someone gets in the filespace. It mainly helps avoid the accidental discovery of a clear text password.') . '</dd>';
844
      $servers_help .= '<dt>' . t('LOG DETAILED LDAP ACTIONS') . '</dt>';
845
      $servers_help .= '<dd>' . t('Enables LDAP logging to the Drupal Watchdog system') . '</dd>';
846
      $servers_help .= '</dl>';
847
      $servers_help .= '<h3>' . t('Configuration - Servers (List)') . '</h3>';
848
      $servers_help .= '<dl>';
849
      $servers_help .= '<dt>' . t('Configuration Table') . '</dt>';
850
      $servers_help .= '<dd>' . t('Provides a list of currently stored LDAP server configuratins.') . '</dd>';
851
      $servers_help .= '<h3>' . t('Configuration - Servers (Add LDAP Server Configuration)') . '</h3>';
852
      $servers_help .= '<dl>';
853
      $servers_help .= '<dt>' . t('CONNECTION SETTINGS') . '</dt>';
854
      $servers_help .= '<dd>' . t('Machine name -') . ' </dd>';
855
      $servers_help .= '<dd>' . t('Name -') . ' </dd>';
856
      $servers_help .= '<dd>' . t('Enabled -') . ' </dd>';
857
      $servers_help .= '<dd>' . t('LDAP Server Type') . ' </dd>';
858
      $servers_help .= '<dd>' . t('LDAP Server -') . ' </dd>';
859
      $servers_help .= '<dd>' . t('LDAP port -') . ' </dd>';
860
      $servers_help .= '<dd>' . t('Use Start-TLS -') . ' </dd>';
861
      $servers_help .= '<dd>' . t('Follow LDAP Referrals -') . ' </dd>';
862
      $servers_help .= '</dl>';
863
      $servers_help .= '<dl>';
864
      $servers_help .= '<dt>' . t('BINDING METHOD') . '</dt>';
865
      $servers_help .= '<dd>' . t('Binding Method for searches -') . ' </dd>';
866
      $servers_help .= '<dd>' . t('Service Account -') . ' </dd>';
867
      $servers_help .= '<dd>' . t('DN for non-anonymous search -') . ' </dd>';
868
      $servers_help .= '<dd>' . t('Password for non-anonymous search -') . ' </dd>';
869
      $servers_help .= '<dd>' . t('Clear existing password from database -') . ' </dd>';
870
      $servers_help .= '</dl>';
871
      $servers_help .= '<dl>';
872
      $servers_help .= '<dt>' . t('LDAP USER TO DRUPAL USER RELATIONSHIP') . '</dt>';
873
      $servers_help .= '<dd>' . t('Base DNs for LDAP Users, Groups, and Other Entries -') . ' </dd>';
874
      $servers_help .= '<dd>' . t('AuthName Attribute -') . ' </dd>';
875
      $servers_help .= '<dd>' . t('AccountName Attribute -') . ' </dd>';
876
      $servers_help .= '<dd>' . t('Email Attribute -') . ' </dd>';
877
      $servers_help .= '<dd>' . t('Email Template -') . ' </dd>';
878
      $servers_help .= '<dd>' . t('Persistant and Unique User ID Attribute -') . ' </dd>';
879
      $servers_help .= '<dd>' . t('Does PUID hold a binary value? -') . ' </dd>';
880
      $servers_help .= '<dd>' . t('Expression for User DN -') . ' </dd>';
881
      $servers_help .= '<dd>' . t('PHP to Transform Drupal Login Username to LDAP UserName Attribute -') . ' </dd>';
882
      $servers_help .= '<dd>' . t('Testing Drupal Username -') . ' </dd>';
883
      $servers_help .= '<dd>' . t('DN of Testing Username -') . ' </dd>';
884
      $servers_help .= '</dl>';
885
      return $servers_help;
886
887
    case 'admin/config/people/ldap/servers/add':
888
      $output = '<p>' . t('Setup an LDAP server configuration to be used by other modules such as LDAP Authentication, LDAP Authorization, etc.') . '</p>';
889
      $output .= '<p>' . t('More than one LDAP server configuration can exist for a physical LDAP server. Multiple configurations for the same physical ldap server are useful in cases such as: (1) different base dn\'s for authentication and authorization and (2) service accounts with different privileges for different purposes.') . '</p>';
890
      return $output;
891
  }
892
}
893
894
895
/**
896
 * @return list of ldap configuration classes and names
897
 */
898
function ldap_servers_ldap_servers_types() {
899
900
  $path = drupal_get_path('module', 'ldap_servers') . '/ldap_types';
901
902
  $types['default'] =  array(
903
    'class' => t('LdapTypeDefault'),
904
    'directory_path' => $path,
905
    'name' => 'Default LDAP',
906
  );
907
908
  $types['ad'] =  array(
909
    'class' => t('LdapTypeActiveDirectory'),
910
    'directory_path' => $path,
911
    'name' => 'Active Directory',
912
  );
913
914
  $types['novell_edir'] =  array(
915
    'class' => t('LdapTypeNovell'),
916
    'directory_path' => $path,
917
    'name' => 'Novell',
918
  );
919
920
  $types['openldap'] =  array(
921
    'class' => t('LdapTypeOpenLdap'),
922
    'directory_path' => $path,
923
    'name' => 'Open LDAP',
924
  );
925
926
  $types['opendir'] =  array(
927
    'class' => t('LdapTypeOpenDirectory'),
928
    'directory_path' => $path,
929
    'name' => 'Apple Open Directory',
930
  );
931
932
  drupal_alter('ldap_servers_ldap_types', $types);
933
  return $types;
934
935
}
936
937
/**
938
 * @param string or array ldap type id or conf array
939
 * @return options for ldap type pulldown
940
 */
941
function ldap_servers_get_ldap_type_object($ldap_conf) {
942
943
  if (!is_array($ldap_conf)) {
944
    $ldap_confs = ldap_servers_ldap_servers_types();
945
    $ldap_conf = $ldap_confs[$ldap_conf];
946
  }
947
948
  require_once($ldap_conf['directory_path'] . '/' . $ldap_conf['class'] . 'class.php');
949
  $ldap_type_class = new $ldap_conf['class']();
950
  return $ldap_type_class;
951
952
}
953
954
/**
955
 * given a dn (such as cn=jdoe,ou=people)
956
 * and an rdn (such as cn)
957
 * determine that rdn value (such as jdoe)
958
 *
959
 * @param string $dn
960
 * @param string $rdn
961
 * @return string value of rdn
962
 */
963
function ldap_servers_get_first_rdn_value_from_dn($dn, $rdn) {
964
  $pairs = ldap_explode_dn($dn, 0); // escapes attribute values, need to be unescaped later
965
  $count = array_shift($pairs);
966
  $rdn = drupal_strtolower($rdn);
967
  $rdn_value = FALSE;
968
  foreach ($pairs as $p) {
969
    $pair = explode('=', $p);
970
    if (drupal_strtolower(trim($pair[0])) == $rdn) {
971
      $rdn_value = ldap_pear_unescape_dn_value(trim($pair[1]));
972
      break;
973
    }
974
  }
975
  return $rdn_value;
976
}
977
978
/**
979
 * given a dn (such as cn=jdoe,ou=people)
980
 * and an rdn (such as cn)
981
 * determine that rdn value (such as jdoe)
982
 *
983
 * @param string $dn
984
 * @param string $rdn
985
 * @return array of all values of rdn
986
 */
987
function ldap_servers_get_all_rdn_values_from_dn($dn, $rdn) {
988
  $pairs = ldap_explode_dn($dn, 0); // escapes attribute values, need to be unescaped later
989
  $count = array_shift($pairs);
990
  $rdn = drupal_strtolower($rdn);
991
  $rdn_values = array();
992
  foreach ($pairs as $p) {
993
    $pair = explode('=', $p);
994
    if (drupal_strtolower(trim($pair[0])) == $rdn) {
995
      $rdn_values[] = ldap_pear_unescape_dn_value(trim($pair[1]));
996
    }
997
  }
998
  return $rdn_values;
999
}
1000
1001
1002
/**
1003
 * @return options for ldap type pulldown
1004
 */
1005
function ldap_servers_ldaps_option_array() {
1006
1007
  $options = array();
1008
  foreach (ldap_servers_ldap_servers_types() as $ldap_id => $conf) {
1009
    $options[$ldap_id] = $conf['name'];
1010
  }
1011
  return $options;
1012
1013
}
1014
1015
/**
1016
 * @param string $ldap_type indicating ldap type 'default','ad','novell_edir', 'openldap'
1017
 * @param boolean $reset clear static array
1018
 * @param boolean $flatted indicating if only one ldap type returned, skip top level array key
1019
 *
1020
 * @return one or more ldap type objects
1021
 */
1022
function ldap_servers_get_types($ldap_type = NULL, $reset = FALSE, $flatten = FALSE) {
1023
  static $ldap_types;
1024
  if ($reset || !is_array($ldap_types)) {
1025
    $ldap_types = module_invoke_all('ldap_servers_type');
1026
    if ($ldap_type) {
1027
      require_once($ldap_types[$ldap_type]['directory_path'] . '/' . $ldap_types[$ldap_type]['class'] . '.class.php');
1028
      $ldap_types[$ldap_type] = new $ldap_types[$ldap_type]['class'] . '.class.php';
1029
    }
1030
    else {
1031
      foreach ($ldap_types as $ldap_type_id => $ldap_class_info) {
1032
        require_once($ldap_class_info['directory_path'] . '/' . $ldap_class_info['class'] . '.class.php');
1033
        $ldap_types[$ldap_type_id] = new $ldap_class_info['class'];
1034
      }
1035
    }
1036
  }
1037
  if ($flatten && $ldap_type) {
1038
    return $ldap_types[$ldap_type];
1039
  }
1040
  else {
1041
    return $ldap_types;
1042
  }
1043
}
1044
1045
1046
function ldap_servers_no_enabled_servers_msg($action) {
1047
1048
  $servers = ldap_servers_get_servers(NULL, 'enabled');
1049
  if (count($servers) == 0) {
1050
1051
    $message = t('At least one ldap server must configured and <em>enabled</em> before') .
1052
      $action . '. ' . t('Please go to') . ' ' . l('admin/config/people/ldap/servers', 'admin/config/people/ldap/servers') . ' to configure an LDAP server';
1053
1054
    drupal_set_message($message, 'warning');
1055
    return $message;
1056
  }
1057
}