Projet

Général

Profil

Paste
Télécharger (14,2 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / ldap / ldap_authentication / LdapAuthenticationConf.class.php @ 91af538d

1
<?php
2

    
3
/**
4
 * @file
5
 * This class represents an ldap_authentication module's configuration
6
 * It is extended by LdapAuthenticationConfAdmin for configuration and other admin functions.
7
 */
8

    
9
module_load_include('php', 'ldap_user', 'LdapUserConf.class');
10
/**
11
 *
12
 */
13
class LdapAuthenticationConf {
14

    
15
  /**
16
   * Server configuration ids being used for authentication.
17
   *
18
   * @var array
19
   *
20
   * @see LdapServer->sid()
21
   */
22
  public $sids = [];
23

    
24
  /**
25
   * Server configuration ids being used for authentication.
26
   *
27
   * @var associativearrayofLdapServerobjectskeyedonsids
28
   *
29
   * @see LdapServer->sid()
30
   * @see LdapServer
31
   */
32
  public $enabledAuthenticationServers = [];
33

    
34

    
35
  /**
36
   * LdapUser configuration object.
37
   *
38
   * @var LdapUserobject
39
   */
40
  /**
41
   * Ldap_user configuration object.
42
   */
43
  public $ldapUser = NULL;
44

    
45
  /**
46
   * Has current object been saved to the database?
47
   *
48
   * @var bool
49
   */
50
  public $inDatabase = FALSE;
51

    
52
  /**
53
   * Choice of authentication modes.
54
   *
55
   * @var int
56
   *   LDAP_AUTHENTICATION_MODE_DEFAULT (LDAP_AUTHENTICATION_MIXED)
57
   *   LDAP_AUTHENTICATION_MIXED - signifies both LDAP and Drupal authentication are allowed
58
   *     Drupal authentication is attempted first.
59
   *   LDAP_AUTHENTICATION_EXCLUSIVE - signifies only LDAP authenication is allowed
60
   */
61
  public $authenticationMode = LDAP_AUTHENTICATION_MODE_DEFAULT;
62

    
63
  /**
64
   * The following are used to alter the logon interface to direct users
65
   * to local LDAP specific authentication help.
66
   */
67

    
68
  /**
69
   * Text describing username to use, such as "Hogwarts Username"
70
   *  which will be inserted on logon forms to help users figure out which
71
   *  username to use.
72
   *
73
   * @var string
74
   */
75
  public $loginUIUsernameTxt;
76

    
77
  /**
78
   * Text describing password to use, such as "Hogwards LDAP Password"
79
   *  which will be inserted on logon forms.  Useful in organizations with
80
   *  multiple account types for authentication.
81
   *
82
   * @var string
83
   */
84
  public $loginUIPasswordTxt;
85

    
86
  /**
87
   * Text and Url to provide help link for password such as:
88
   *   ldapUserHelpLinkUrl:    https://passwords.hogwarts.edu
89
   *   ldapUserHelpLinkText:  Hogwarts IT Password Support Page.
90
   *
91
   * @var string
92
   */
93
  public $ldapUserHelpLinkUrl;
94
  public $ldapUserHelpLinkText = LDAP_AUTHENTICATION_HELP_LINK_TEXT_DEFAULT;
95

    
96
  /**
97
   * Email handling option
98
   *   LDAP_AUTHENTICATION_EMAIL_FIELD_REMOVE -- don't show email on user forms
99
   *   LDAP_AUTHENTICATION_EMAIL_FIELD_DISABLE (default) -- disable email on user forms
100
   *   LDAP_AUTHENTICATION_EMAIL_FIELD_ALLOW -- allow editing of email on user forms.
101
   *
102
   * @var int
103
   */
104
  public $emailOption = LDAP_AUTHENTICATION_EMAIL_FIELD_DEFAULT;
105

    
106
  /**
107
   * Email handling option
108
   *   LDAP_AUTHENTICATION_EMAIL_UPDATE_ON_LDAP_CHANGE_ENABLE_NOTIFY -- (default) Update stored email if LDAP email differs at login and notify user
109
   *   LDAP_AUTHENTICATION_EMAIL_UPDATE_ON_LDAP_CHANGE_ENABLE  -- Update stored email if LDAP email differs at login but don\'t notify user
110
   *   LDAP_AUTHENTICATION_EMAIL_UPDATE_ON_LDAP_CHANGE_DISABLE -- Don\'t update stored email if LDAP email differs at login.
111
   *
112
   * @var int
113
   */
114
  public $emailUpdate = LDAP_AUTHENTICATION_EMAIL_UPDATE_ON_LDAP_CHANGE_DEFAULT;
115

    
116
  /**
117
   * Email default handling option.
118
   *
119
   * This affects how email addresses that are empty are handled by
120
   * the authentication process.
121
   *
122
   *   LDAP_AUTHENTICATION_EMAIL_TEMPLATE_NONE -- leaves the email empty
123
   *   LDAP_AUTHENTICATION_EMAIL_TEMPLATE_IF_EMPTY (default) -- if the email is empty, it will be replaced
124
   *   LDAP_AUTHENTICATION_EMAIL_TEMPLATE_ALWAYS -- always use the template
125
   *
126
   * @var int
127
   */
128
  public $emailTemplateHandling = LDAP_AUTHENTICATION_EMAIL_TEMPLATE_DEFAULT;
129

    
130
  /**
131
   * Email template.
132
   *
133
   * @var string
134
   */
135
  public $emailTemplate = LDAP_AUTHENTICATION_DEFAULT_TEMPLATE;
136

    
137
  /**
138
   * Whether or not to display a notification to the user on login, prompting
139
   * them to change their email.
140
   *
141
   * @var bool
142
   */
143
  public $templateUsagePromptUser = LDAP_AUTHENTICATION_TEMPLATE_USAGE_PROMPT_USER_DEFAULT;
144

    
145
  /**
146
   * Whether or not to avoid updating the email address of the user if the
147
   * template was used to generate it.
148
   *
149
   * @var bool
150
   */
151
  public $templateUsageNeverUpdate = LDAP_AUTHENTICATION_TEMPLATE_USAGE_NEVER_UPDATE_DEFAULT;
152

    
153
  /**
154
   * Whether or not to use the email template if there is a user with a different
155
   * login name but same email address in the system.
156
   *
157
   * @var bool
158
   */
159
  public $templateUsageResolveConflict = LDAP_AUTHENTICATION_TEMPLATE_USAGE_RESOLVE_CONFLICT_DEFAULT;
160

    
161
  /**
162
   * A PCRE regular expression (minus the delimiter and flags) that will be used
163
   * if $templateUsagePromptUser is set to true to determine if the email
164
   * address is a fake one or not.
165
   *
166
   * By allowing this to be customized, we let the administrators handle older
167
   * patterns should they decide to change the existing one, as well as avoiding
168
   * the complexity of determining a proper regex from the template.
169
   *
170
   * @var string
171
   */
172
  public $templateUsagePromptRegex = LDAP_AUTHENTICATION_DEFAULT_TEMPLATE_REGEX;
173

    
174
  /**
175
   * Controls whether or not we should check on login if the email template was
176
   * used and redirect the user if needed.
177
   *
178
   * @var bool
179
   */
180
  public $templateUsageRedirectOnLogin = LDAP_AUTHENTICATION_REDIRECT_ON_LOGIN_DEFAULT;
181

    
182

    
183

    
184
  /**
185
   * Password handling option
186
   *   LDAP_AUTHENTICATION_PASSWORD_FIELD_SHOW -- show field disabled on user forms
187
   *   LDAP_AUTHENTICATION_PASSWORD_FIELD_HIDE (default) -- disable password on user forms
188
   *   LDAP_AUTHENTICATION_PASSWORD_FIELD_ALLOW -- allow editing of password on user forms.
189
   *
190
   * @var int
191
   */
192
  public $passwordOption = LDAP_AUTHENTICATION_PASSWORD_FIELD_DEFAULT;
193

    
194
  public $ssoEnabled = FALSE;
195
  public $ssoRemoteUserStripDomainName = FALSE;
196
  public $ssoExcludedPaths = NULL;
197
  public $ssoExcludedHosts = NULL;
198
  public $seamlessLogin = FALSE;
199
  public $ssoNotifyAuthentication = FALSE;
200
  public $ldapImplementation = FALSE;
201
  public $cookieExpire = LDAP_AUTHENTICATION_COOKIE_EXPIRE;
202
  public $apiPrefs = [];
203

    
204
  /**
205
   * Advanced options.   whitelist / blacklist options.
206
   *
207
   * These are on the fuzzy line between authentication and authorization
208
   * and determine if a user is allowed to authenticate with ldap.
209
   */
210

    
211
  /**
212
   * Text which must be present in user's LDAP entry's DN for user to authenticate with LDAP
213
   *   e.g. "ou=people".
214
   *
215
   * @var string
216
   */
217
  /**
218
   * Eg ou=education that must be met to allow ldap authentication.
219
   */
220
  public $allowOnlyIfTextInDn = [];
221

    
222
  /**
223
   * Text which prohibits logon if found in user's LDAP entry's DN for user to authenticate with LDAP
224
   *   e.g. "ou=guest accounts".
225
   *
226
   * @var string
227
   */
228
  public $excludeIfTextInDn = [];
229

    
230
  /**
231
   * Code that prints 1 or 0 signifying if user is allowed
232
   *   should not start with <?php.
233
   *
234
   * @var stringofphp
235
   */
236
  public $allowTestPhp = NULL;
237

    
238
  /**
239
   * If at least 1 ldap authorization must exist for user to be allowed
240
   *   True signfies disallow if no authorizations.
241
   *   False signifies don't consider authorizations.
242
   *
243
   * @var bool
244
   */
245
  public $excludeIfNoAuthorizations = LDAP_AUTHENTICATION_EXCL_IF_NO_AUTHZ_DEFAULT;
246

    
247
  public $saveable = [
248
    'sids',
249
    'authenticationMode',
250
    'loginUIUsernameTxt',
251
    'loginUIPasswordTxt',
252
    'ldapUserHelpLinkUrl',
253
    'ldapUserHelpLinkText',
254
    'emailOption',
255
    'emailUpdate',
256
    'passwordOption',
257
    'allowOnlyIfTextInDn',
258
    'excludeIfTextInDn',
259
    'allowTestPhp',
260
    'excludeIfNoAuthorizations',
261
    'ssoRemoteUserStripDomainName',
262
    'ssoExcludedPaths',
263
    'ssoExcludedHosts',
264
    'seamlessLogin',
265
    'ssoNotifyAuthentication',
266
    'ldapImplementation',
267
    'cookieExpire',
268
    'emailTemplate',
269
    'emailTemplateHandling',
270
    'templateUsagePromptUser',
271
    'templateUsageNeverUpdate',
272
    'templateUsageResolveConflict',
273
    'templateUsagePromptRegex',
274
    'templateUsageRedirectOnLogin',
275
  ];
276

    
277
  /**
278
   *
279
   */
280
  public function hasEnabledAuthenticationServers() {
281
    return !(count($this->enabledAuthenticationServers) == 0);
282
  }
283

    
284
  /**
285
   *
286
   */
287
  public function enabled_servers() {
288
    return $this->hasEnabledAuthenticationServers();
289
  }
290

    
291
  /**
292
   *
293
   */
294
  public function __construct() {
295
    $this->load();
296
  }
297

    
298
  /**
299
   *
300
   */
301
  public function load() {
302

    
303
    if ($saved = variable_get("ldap_authentication_conf", FALSE)) {
304
      $this->inDatabase = TRUE;
305
      foreach ($this->saveable as $property) {
306
        if (isset($saved[$property])) {
307
          $this->{$property} = $saved[$property];
308
        }
309
      }
310
      // Reset in case reloading instantiated object.
311
      $this->enabledAuthenticationServers = [];
312
      $enabled_ldap_servers = ldap_servers_get_servers(NULL, 'enabled');
313
      foreach ($this->sids as $sid => $enabled) {
314
        if ($enabled && isset($enabled_ldap_servers[$sid])) {
315
          $this->enabledAuthenticationServers[$sid] = $enabled_ldap_servers[$sid];
316
        }
317
      }
318

    
319
    }
320
    else {
321
      $this->inDatabase = FALSE;
322
    }
323

    
324
    $this->ldapUser = new LdapUserConf();
325
    $this->ssoEnabled = module_exists('ldap_sso');
326
    $this->apiPrefs['requireHttps'] = variable_get('ldap_servers_require_ssl_for_credentials', 0);
327
    $this->apiPrefs['encryption'] = variable_get('ldap_servers_encryption', LDAP_SERVERS_ENC_TYPE_CLEARTEXT);
328

    
329
  }
330

    
331
  /**
332
   * Destructor Method.
333
   */
334
  public function __destruct() {}
335

    
336
  /**
337
   * Decide if a username is excluded or not.
338
   *
339
   * @param string $name
340
   *   as proposed drupal username.
341
   * @param array $ldap_user
342
   *   where top level keys are 'dn','attr','mail'.
343
   *
344
   * @return boolean FALSE means NOT allow; TRUE means allow
345
   *
346
   * @todo. this function should simply invoke hook_ldap_authentication_allowuser_results_alter
347
   *   and most of this function should go in ldap_authentication_allowuser_results_alter
348
   */
349
  public function allowUser($name, $ldap_user) {
350

    
351
    /**
352
     * do one of the exclude attribute pairs match
353
     */
354
    $ldap_user_conf = ldap_user_conf();
355
    // If user does not already exists and deferring to user settings AND user settings only allow.
356
    $user_register = variable_get('user_register', USER_REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL);
357

    
358
    foreach ($this->excludeIfTextInDn as $test) {
359
      if (stripos($ldap_user['dn'], $test) !== FALSE) {
360
        // Match.
361
        return FALSE;
362
      }
363
    }
364

    
365
    /**
366
     * evaluate php if it exists
367
     */
368

    
369
    if ($this->allowTestPhp) {
370
      if (module_exists('php')) {
371
        global $_name, $_ldap_user_entry;
372
        $_name = $name;
373
        $_ldap_user_entry = $ldap_user;
374
        $code = '<?php ' . "global \$_name; \n  global \$_ldap_user_entry; \n" . $this->allowTestPhp . ' ?>';
375
        $code_result = php_eval($code);
376
        $_name = NULL;
377
        $_ldap_user_entry = NULL;
378
        if ((boolean) ($code_result) == FALSE) {
379
          return FALSE;
380
        }
381
      }
382
      else {
383
        drupal_set_message(t(LDAP_AUTHENTICATION_DISABLED_FOR_BAD_CONF_MSG), 'warning');
384
        $tokens = ['!ldap_authentication_config' => l(t('LDAP Authentication Configuration'), 'admin/config/people/ldap/authentication')];
385
        watchdog('ldap_authentication', 'LDAP Authentication is configured to deny users based on php execution with php_eval function, but php module is not enabled. Please enable php module or remove php code at !ldap_authentication_config .', $tokens);
386
        return FALSE;
387
      }
388
    }
389

    
390
    /**
391
     * do one of the allow attribute pairs match
392
     */
393
    if (count($this->allowOnlyIfTextInDn)) {
394
      $fail = TRUE;
395
      foreach ($this->allowOnlyIfTextInDn as $test) {
396
        if (stripos($ldap_user['dn'], $test) !== FALSE) {
397
          $fail = FALSE;
398
        }
399
      }
400
      if ($fail) {
401
        return FALSE;
402
      }
403

    
404
    }
405
    /**
406
     * is excludeIfNoAuthorizations option enabled and user not granted any groups
407
     */
408

    
409
    if ($this->excludeIfNoAuthorizations) {
410

    
411
      if (!module_exists('ldap_authorization')) {
412
        drupal_set_message(t(LDAP_AUTHENTICATION_DISABLED_FOR_BAD_CONF_MSG), 'warning');
413
        $tokens = ['!ldap_authentication_config' => l(t('LDAP Authentication Configuration'), 'admin/config/people/ldap/authentication')];
414
        watchdog('ldap_authentication', 'LDAP Authentication is configured to deny users without LDAP Authorization mappings, but LDAP Authorization module is not enabled.  Please enable and configure LDAP Authorization or disable this option at !ldap_authentication_config .', $tokens);
415
        return FALSE;
416
      }
417

    
418
      $user = new stdClass();
419
      $user->name = $name;
420
      // Fake user property added for query.
421
      $user->ldap_authenticated = TRUE;
422
      $consumers = ldap_authorization_get_consumers();
423
      $has_enabled_consumers = FALSE;
424
      $has_ldap_authorizations = FALSE;
425

    
426
      foreach ($consumers as $consumer_type => $consumer_config) {
427
        $consumer_obj = ldap_authorization_get_consumer_object($consumer_type);
428
        if ($consumer_obj->consumerConf->status) {
429
          $has_enabled_consumers = TRUE;
430
          list($authorizations, $notifications) = ldap_authorizations_user_authorizations($user, 'query', $consumer_type, 'test_if_authorizations_granted');
431
          if (
432
            isset($authorizations[$consumer_type]) &&
433
            count($authorizations[$consumer_type]) > 0
434
            ) {
435
            $has_ldap_authorizations = TRUE;
436
          }
437
        }
438
      }
439

    
440
      if (!$has_enabled_consumers) {
441
        drupal_set_message(t(LDAP_AUTHENTICATION_DISABLED_FOR_BAD_CONF_MSG), 'warning');
442
        $tokens = ['!ldap_consumer_config' => l(t('LDAP Authorization Configuration'), 'admin/config/people/ldap/authorization')];
443
        watchdog('ldap_authentication', 'LDAP Authentication is configured to deny users without LDAP Authorization mappings, but 0 LDAP Authorization consumers are configured:  !ldap_consumer_config .', $tokens);
444
        return FALSE;
445
      }
446
      elseif (!$has_ldap_authorizations) {
447
        return FALSE;
448
      }
449

    
450
    }
451

    
452
    // Allow other modules to hook in and refuse if they like.
453
    $hook_result = TRUE;
454
    drupal_alter('ldap_authentication_allowuser_results', $ldap_user, $name, $hook_result);
455

    
456
    if ($hook_result === FALSE) {
457
      watchdog('ldap_authentication', "Authentication Allow User Result=refused for %name", ['%name' => $name], WATCHDOG_NOTICE);
458
      return FALSE;
459
    }
460

    
461
    /**
462
     * default to allowed
463
     */
464
    return TRUE;
465
  }
466

    
467
}