Projet

Général

Profil

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

root / drupal7 / sites / all / modules / ldap / ldap_authentication / ldap_authentication.module @ 91af538d

1
<?php
2

    
3
/**
4
 * @file
5
 * This module injects itself into Drupal's Authentication stack.
6
 */
7

    
8
/**
9
 * @todo fix advanced help for ../ldap/authentication settings page
10
 */
11
define('LDAP_AUTHENTICATION_PROJECT_TAG', 'ldap');
12

    
13
define('LDAP_AUTHENTICATION_MIXED', 1);
14
define('LDAP_AUTHENTICATION_EXCLUSIVE', 2);
15
define('LDAP_AUTHENTICATION_MODE_DEFAULT', 1);
16

    
17
define('LDAP_AUTHENTICATION_EXCL_IF_NO_AUTHZ_DEFAULT', 0);
18
define('LDAP_AUTHENTICATION_CONFLICT_LOG', 1);
19
define('LDAP_AUTHENTICATION_CONFLICT_RESOLVE', 2);
20
define('LDAP_AUTHENTICATION_CONFLICT_RESOLVE_DEFAULT', 2);
21

    
22
define('LDAP_AUTHENTICATION_EMAIL_UPDATE_ON_LDAP_CHANGE_ENABLE_NOTIFY', 1);
23
define('LDAP_AUTHENTICATION_EMAIL_UPDATE_ON_LDAP_CHANGE_ENABLE', 2);
24
define('LDAP_AUTHENTICATION_EMAIL_UPDATE_ON_LDAP_CHANGE_DISABLE', 3);
25
define('LDAP_AUTHENTICATION_EMAIL_UPDATE_ON_LDAP_CHANGE_DEFAULT', 1);
26

    
27
define('LDAP_AUTHENTICATION_EMAIL_FIELD_REMOVE', 2);
28
define('LDAP_AUTHENTICATION_EMAIL_FIELD_DISABLE', 3);
29
define('LDAP_AUTHENTICATION_EMAIL_FIELD_ALLOW', 4);
30
define('LDAP_AUTHENTICATION_EMAIL_FIELD_DEFAULT', 3);
31

    
32
define('LDAP_AUTHENTICATION_EMAIL_TEMPLATE_NONE', 1);
33
define('LDAP_AUTHENTICATION_EMAIL_TEMPLATE_ALWAYS', 2);
34
define('LDAP_AUTHENTICATION_EMAIL_TEMPLATE_IF_EMPTY', 3);
35
define('LDAP_AUTHENTICATION_EMAIL_TEMPLATE_DEFAULT', 3);
36

    
37
define('LDAP_AUTHENTICATION_DEFAULT_TEMPLATE', '@username@fake-domain.com');
38

    
39
define('LDAP_AUTHENTICATION_DEFAULT_TEMPLATE_REGEX', '.*@fake-domain\\.com');
40

    
41
define('LDAP_AUTHENTICATION_TEMPLATE_USAGE_NEVER_UPDATE_DEFAULT', 0);
42
define('LDAP_AUTHENTICATION_TEMPLATE_USAGE_RESOLVE_CONFLICT_DEFAULT', 0);
43
define('LDAP_AUTHENTICATION_TEMPLATE_USAGE_PROMPT_USER_DEFAULT', 0);
44

    
45
define('LDAP_AUTHENTICATION_PASSWORD_FIELD_SHOW', 2);
46
define('LDAP_AUTHENTICATION_PASSWORD_FIELD_HIDE', 3);
47
define('LDAP_AUTHENTICATION_PASSWORD_FIELD_ALLOW', 4);
48
define('LDAP_AUTHENTICATION_PASSWORD_FIELD_DEFAULT', 2);
49

    
50
define('LDAP_AUTHENTICATION_RESULT_FAIL_CONNECT', 1);
51
define('LDAP_AUTHENTICATION_RESULT_FAIL_BIND', 2);
52
define('LDAP_AUTHENTICATION_RESULT_FAIL_FIND', 3);
53
define('LDAP_AUTHENTICATION_RESULT_FAIL_DISALLOWED', 4);
54
define('LDAP_AUTHENTICATION_RESULT_FAIL_CREDENTIALS', 5);
55
define('LDAP_AUTHENTICATION_RESULT_SUCCESS', 6);
56
define('LDAP_AUTHENTICATION_RESULT_FAIL_GENERIC', 7);
57
define('LDAP_AUTHENTICATION_RESULT_FAIL_SERVER', 8);
58

    
59
define('LDAP_AUTHENTICATION_ACCT_CREATION_DEFAULT', 4);
60
define('LDAP_AUTHENTICATION_ACCT_CREATION_USER_SETTINGS_FOR_LDAP', 1);
61
define('LDAP_AUTHENTICATION_ACCT_CREATION_LDAP_BEHAVIOR', 4);
62

    
63
define('LDAP_AUTHENTICATION_HELP_LINK_TEXT_DEFAULT', 'Logon Help');
64

    
65
define('LDAP_AUTHENTICATION_DISABLED_FOR_BAD_CONF_MSG', 'The site logon is currently not working due to a configuration error.  Please see logs for additional details.');
66
define('LDAP_AUTHENTICATION_COOKIE_EXPIRE', 0);
67

    
68
define('LDAP_AUTHENTICATION_REDIRECT_ON_LOGIN_DEFAULT', 0);
69

    
70
/**
71
 * Implements hook_menu().
72
 */
73
function ldap_authentication_menu() {
74
  $items = [];
75

    
76
  $items['user/ldap-profile-update'] = [
77
    'title' => 'Update Profile',
78
    'page callback' => 'drupal_get_form',
79
    'page arguments' => ['ldap_authentication_profile_update_form'],
80
    'access callback' => TRUE,
81
    'type' => MENU_CALLBACK,
82
    'file' => 'ldap_authentication.pages.inc',
83
  ];
84

    
85
  $items['admin/config/people/ldap/authentication'] = [
86
    'title' => 'Authentication',
87
    'description' => 'Configure LDAP Authentication',
88
    'page callback' => 'drupal_get_form',
89
    'page arguments' => ['ldap_authentication_admin_form'],
90
    'access arguments' => ['administer site configuration'],
91
    'type' => MENU_LOCAL_TASK,
92
    'weight' => 3,
93
    'file' => 'ldap_authentication.admin.inc',
94
  ];
95

    
96
  return $items;
97
}
98

    
99
/**
100
 * Implements hook_menu_alter().
101
 * since menu items are cached, only useful to add or alter callbacks
102
 * for ldap authentication driven menu items.
103
 */
104
function ldap_authentication_menu_alter(&$items) {
105
  ldap_servers_module_load_include('inc', 'ldap_authentication', 'ldap_authentication');
106
  $items['user/password']['access callback'] = 'ldap_authentication_show_reset_pwd';
107
  $auth_conf = ldap_authentication_get_valid_conf();
108
  if (@$auth_conf->ldapUserHelpLinkUrl) {
109
    $items['user/ldaphelp'] = [
110
      'title' => $auth_conf->ldapUserHelpLinkText,
111
      'page callback' => 'drupal_goto',
112
      'page arguments' => [$auth_conf->ldapUserHelpLinkUrl],
113
      'access callback' => 'ldap_authentication_show_ldap_help_link',
114
      'type' => MENU_LOCAL_TASK,
115
    ];
116
  }
117
}
118

    
119
/**
120
 * Implements hook_theme().
121
 */
122
function ldap_authentication_theme() {
123
  return [
124
    'ldap_authentication_user_login_block_links' => [
125
      'variables' => ['ldap_user_help_link' => NULL, 'user_register' => TRUE],
126
      'render element' => 'element',
127
      'file' => 'ldap_authentication.theme.inc',
128
    ],
129
    'ldap_authentication_user_pass_message' => [
130
      'variables' => ['show_reset_pwd' => NULL, 'auth_conf' => TRUE],
131
      'render element' => 'element',
132
      'file' => 'ldap_authentication.theme.inc',
133
    ],
134
    'ldap_authentication_user_pass_validate_ldap_authenticated' => [
135
      'variables' => ['account' => NULL, 'auth_conf' => TRUE],
136
      'render element' => 'element',
137
      'file' => 'ldap_authentication.theme.inc',
138
    ],
139
    'ldap_authentication_login_message' => [
140
      'render element' => 'element',
141
      'variables' => ['message' => NULL],
142
      'file' => 'ldap_authentication.theme.inc',
143
    ],
144
    'ldap_authentication_message_not_found' => [
145
      'render element' => 'element',
146
      'variables' => ['message' => NULL],
147
      'file' => 'ldap_authentication.theme.inc',
148
    ],
149
    'ldap_authentication_message_not_authenticated' => [
150
      'render element' => 'element',
151
      'variables' => ['message' => NULL],
152
      'file' => 'ldap_authentication.theme.inc',
153
    ],
154
  ];
155
}
156

    
157
/**
158
 * Implements hook_help().
159
 */
160
function ldap_authentication_help($path, $arg) {
161

    
162
  $authentication_help = t('LDAP authentication allows authentication against an LDAP server.  It
163
        may be used alongside other authentication means such as built in Drupal authentication,
164
        open id, etc.  More detailed help is available on drupal.org at !helplink.',
165
          [
166
            '!helplink' => l(LDAP_SERVERS_DRUPAL_HELP_URL, LDAP_SERVERS_DRUPAL_HELP_URL),
167
          ]);
168

    
169
  switch ($path) {
170
    case 'admin/config/people/ldap/authentication':
171
      $output = '<p>' . $authentication_help . '</p>';
172
      return $output;
173

    
174
    case 'admin/help#ldap_authentication':
175
      $output = '<p>' . $authentication_help . '</p>';
176
      return $output;
177
  }
178
}
179

    
180
/**
181
 * Helper function that determines whether or not the user's profile
182
 * is valid or needs to be updated on login.
183
 *
184
 * Currently this only checks if mail is valid or not according to the
185
 * authentication settings.
186
 *
187
 * @return bool
188
 *   TRUE if the user's profile is valid, otherwise FALSE.
189
 */
190
function _ldap_authentication_verify_user_profile() {
191
  global $user;
192
  $result = TRUE;
193
  // We only want non-anonymous and non-1 users.
194
  if ($user->uid > 1) {
195
    // We store the value in the session for speed.
196
    if (isset($_SESSION['ldap_authentication_template']) &&
197
            isset($_SESSION['ldap_authentication_template']['verify_user_profile'])) {
198
      return $_SESSION['ldap_authentication_template']['verify_user_profile'];
199
    }
200
    if (ldap_authentication_ldap_authenticated($user)) {
201
      $auth_conf = ldap_authentication_get_valid_conf();
202
      $regex = '`' . $auth_conf->templateUsagePromptRegex . '`i';
203
      if (preg_match($regex, $user->mail)) {
204
        $result = FALSE;
205
      }
206
      $_SESSION['ldap_authentication_template'] = [
207
        'verify_user_profile' => $result,
208
      ];
209
    }
210
  }
211
  return $result;
212
}
213

    
214
/**
215
 * Implements hook_init().
216
 */
217
function ldap_authentication_init() {
218
  $auth_conf = ldap_authentication_get_valid_conf();
219
  if ($auth_conf && $auth_conf->templateUsagePromptUser) {
220
    ldap_authentication_check_for_email_template();
221
  }
222
}
223

    
224
/**
225
 * Form submit callback to check for an email template and redirect if needed.
226
 */
227
function ldap_authentication_check_for_email_template() {
228
  if (!_ldap_authentication_verify_user_profile()) {
229
    $url = 'user/ldap-profile-update';
230
    $cp = current_path();
231
    // Avoid redirects on these two pages.
232
    if ($cp != $url && $cp != 'user/logout') {
233
      if (isset($_GET['destination'])) {
234
        unset($_GET['destination']);
235
      }
236
      drupal_goto($url, [
237
        'query' => [
238
          'next' => current_path(),
239
        ],
240
      ]);
241
    }
242
  }
243
}
244

    
245
/**
246
 * Implements hook_info().
247
 */
248
function ldap_authentication_info($field = 0) {
249
  $info['name'] = 'ldap_authentication';
250
  $info['protocol'] = 'LDAP';
251

    
252
  if ($field) {
253
    return $info[$field];
254
  }
255

    
256
  return $info;
257
}
258

    
259
/**
260
 * Determines if the passed user has a valid authmap record.
261
 *
262
 * @param object $user
263
 *   A drupal user account.
264
 *
265
 * @return bool
266
 *   true if user is recorded as ldap authenticated and identified (ldap_authentified)
267
 */
268
function ldap_authentication_ldap_authenticated($user) {
269
  if (!is_object($user) || $user->uid == 0) {
270
    return FALSE;
271
  }
272

    
273
  $authname = ldap_user_get_authname($user);
274
  return !empty($authname);
275

    
276
}
277

    
278
/**
279
 * A user access callback for using the single sign-on URL, denying access to
280
 * authenticated users, and granting access to anonymous users and menu
281
 * administrators viewing the menu item.
282
 */
283
function _ldap_authentication_user_access() {
284
  return (boolean) (!$GLOBALS['user']->uid || !empty($GLOBALS['menu_admin']));
285
}
286

    
287
/**
288
 * Get LdapAuthenticationConf object.
289
 *
290
 * @return object LdapAuthenticationConf object if configured, otherwise FALSE
291
 */
292
function ldap_authentication_get_valid_conf($reset = FALSE) {
293

    
294
  static $auth_conf;
295
  if (!$reset && is_object($auth_conf)) {
296
    return $auth_conf;
297
  }
298
  ldap_servers_module_load_include('php', 'ldap_authentication', 'LdapAuthenticationConf.class');
299

    
300
  $auth_conf = new LdapAuthenticationConf();
301
  return ($auth_conf->inDatabase) ? $auth_conf : FALSE;
302

    
303
}
304

    
305
/**
306
 * Implements hook_ldap_ldap_server_in_use().
307
 */
308
function ldap_authentication_ldap_server_in_use($sid, $server_name) {
309

    
310
  $use_warnings = [];
311
  $auth_conf = ldap_authentication_get_valid_conf();
312
  if ($auth_conf && in_array($sid, array_keys($auth_conf->sids)) && !empty($auth_conf->sids[$sid])) {
313
    $use_warnings[] = t('This server (%server_name) may not be deleted or
314
      disabled because it is being used for ldap authentication.',
315
      ['%server_name' => $server_name]);
316
  }
317
  return $use_warnings;
318
}
319

    
320
/**
321
 *
322
 */
323
function ldap_authentication_show_reset_pwd($user = NULL) {
324

    
325
  if (!$user) {
326
    global $user;
327
  }
328
  $auth_conf = ldap_authentication_get_valid_conf();
329
  // Hide user/password form if ldap authentication is required and deny access
330
  // to users without ldap authorizations is enabled.
331
  if ($user->uid == 1 || !$auth_conf || (current_path() == 'user/password' && $auth_conf->authenticationMode != LDAP_AUTHENTICATION_EXCLUSIVE)) {
332
    return TRUE;
333
    // Always show at user/passwordurl. otherwise user 1 will not be able to reset password.
334
  }
335

    
336
  if ($user->uid == 0) {
337
    // Hide reset password for anonymous users if ldap only authentication and password updates are disabled, otherwise show.
338
    if ($auth_conf->authenticationMode == LDAP_AUTHENTICATION_EXCLUSIVE) {
339
      if ($auth_conf->passwordOption == LDAP_AUTHENTICATION_PASSWORD_FIELD_ALLOW) {
340
        return TRUE;
341
      }
342
      return FALSE;
343
    }
344
    return TRUE;
345
  }
346
  else {
347
    // Authenticated user.  hide if ldap authenticated and updating password is
348
    // not allowed, otherwise show.
349
    if (ldap_authentication_ldap_authenticated($user)) {
350
      if ($auth_conf->passwordOption == LDAP_AUTHENTICATION_PASSWORD_FIELD_ALLOW) {
351
        return TRUE;
352
      }
353
      return FALSE;
354
    }
355
    return TRUE;
356
  }
357

    
358
}
359

    
360
/**
361
 * Implements hook_form_FORM_ID_alter().
362
 */
363
function ldap_authentication_form_user_pass_alter(&$form, $form_state) {
364
  // The following could be in a theme preproces function.
365
  $auth_conf = ldap_authentication_get_valid_conf();
366
  $form['ldap_warning'] = [
367
    '#type' => 'item',
368
    '#markup' => theme('ldap_authentication_user_pass_message', ['auth_conf' => $auth_conf]),
369
    '#weight' => 10,
370
  ];
371

    
372
  // Need to insert before user_pass_validate.
373
  array_unshift($form['#validate'], 'ldap_authentication_user_pass_validate');
374
}
375

    
376
/**
377
 * A validate handler on the login form. Check supplied username/password
378
 * against local users table. If successful, $form_state['uid']
379
 * is set to the matching user ID.
380
 */
381
function ldap_authentication_core_override_user_login_authenticate_validate($form, &$form_state) {
382
  // No additional validation of user credentials is needed when
383
  // $form_state['uid'] is set.
384
  if (!empty($form_state['uid'])) {
385
    return;
386
  }
387
  user_login_authenticate_validate($form, $form_state);
388
}
389

    
390
/**
391
 *
392
 */
393
function ldap_authentication_user_pass_validate(&$form_state) {
394
  $name_or_mail = trim($form_state['name']['#value']);
395
  if ($account = user_load_by_mail($name_or_mail)) {
396

    
397
  }
398
  else {
399
    $account = user_load_by_name($name_or_mail);
400
  }
401

    
402
  if (ldap_authentication_ldap_authenticated($account)) {
403
    $vars = [
404
      'account' => $account,
405
      'auth_conf' => ldap_authentication_get_valid_conf(),
406
    ];
407
    $error = TRUE;
408
    if (is_object($vars['auth_conf'])) {
409
      if ($vars['auth_conf']->passwordOption == LDAP_AUTHENTICATION_PASSWORD_FIELD_ALLOW) {
410
        $error = FALSE;
411
      }
412
    }
413
    if (!empty($error)) {
414
      form_set_error('name', theme('ldap_authentication_user_pass_validate_ldap_authenticated', $vars));
415
    }
416
  }
417
}
418

    
419
/**
420
 * Implements hook_form_FORM_ID_alter(). for user_profile_form.
421
 */
422
function ldap_authentication_form_user_profile_form_alter(&$form, $form_state) {
423
  ldap_servers_module_load_include('inc', 'ldap_authentication', 'ldap_authentication');
424
  _ldap_authentication_form_user_profile_form_alter($form, $form_state, 'user_login');
425

    
426
}
427

    
428
/**
429
 * Implements hook_form_FORM_ID_alter(). for user_login.
430
 */
431
function ldap_authentication_form_user_login_alter(&$form, &$form_state) {
432
  ldap_servers_module_load_include('inc', 'ldap_authentication', 'ldap_authentication');
433
  _ldap_authentication_login_form_alter($form, $form_state, 'user_login');
434

    
435
}
436

    
437
/**
438
 * Implements hook_form_FORM_ID_alter(). for user_login_block.
439
 */
440
function ldap_authentication_form_user_login_block_alter(&$form, &$form_state) {
441
  ldap_servers_module_load_include('inc', 'ldap_authentication', 'ldap_authentication');
442
  _ldap_authentication_login_form_alter($form, $form_state, 'user_login_block');
443

    
444
}
445

    
446
/**
447
 * Validate function for user logon forms.
448
 */
449
function ldap_authentication_user_login_authenticate_validate($form, &$form_state, $return_user = FALSE) {
450
  ldap_servers_module_load_include('inc', 'ldap_authentication', 'ldap_authentication');
451
  return _ldap_authentication_user_login_authenticate_validate($form_state, $return_user);
452
}
453

    
454
/**
455
 * Implements hook_user_presave().
456
 *  A user account is about to be created or updated.
457
 */
458
function ldap_authentication_user_presave(&$edit, $account, $category = NULL) {
459

    
460
}
461

    
462
/**
463
 * Implements hook_user_insert().
464
 *
465
 * A user account was created.
466
 * The module should save its custom additions to the user object into the database.
467
 */
468
function ldap_authentication_user_insert(&$edit, $account, $category) {
469

    
470
}
471

    
472
/**
473
 * Implements hook_user_update().
474
 *
475
 *  A user account was updated.
476
 *  Modules may use this hook to update their user data in a custom storage after a user account has been updated.
477
 */
478
function ldap_authentication_user_update($edit, $user, $category) {
479

    
480
}
481

    
482
/**
483
 *
484
 */
485
function ldap_authentication_show_ldap_help_link($user = NULL) {
486
  global $user;
487

    
488
  if (!$auth_conf = ldap_authentication_get_valid_conf()) {
489
    return FALSE;
490
  }
491
  elseif ($auth_conf->authenticationMode == LDAP_AUTHENTICATION_MIXED) {
492
    return (ldap_authentication_ldap_authenticated($user));
493
  }
494
  elseif ($auth_conf->authenticationMode == LDAP_AUTHENTICATION_EXCLUSIVE) {
495
    if ($user->uid == 0 || ldap_authentication_ldap_authenticated($user)) {
496
      return TRUE;
497
    }
498
    else {
499
      return FALSE;
500
    }
501
  }
502
}