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 @ 7547bb19

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
class LdapAuthenticationConf {
12

    
13
  /**
14
   * server configuration ids being used for authentication
15
   *
16
   * @var array
17
   *
18
   * @see LdapServer->sid()
19
   */
20
  public $sids = array();
21

    
22
  /**
23
   * server configuration ids being used for authentication
24
   *
25
   * @var associative array of LdapServer objects keyed on sids
26
   *
27
   * @see LdapServer->sid()
28
   * @see LdapServer
29
   */
30
  public $enabledAuthenticationServers = array();
31

    
32

    
33
  /**
34
   * LdapUser configuration object
35
   *
36
   * @var LdapUser object
37
   */
38
  public $ldapUser = NULL; // ldap_user configuration object
39

    
40
  /**
41
   * Has current object been saved to the database?
42
   *
43
   * @var boolean
44
   */
45
  public $inDatabase = FALSE;
46

    
47
  /**
48
    * Choice of authentication modes
49
    *
50
    * @var integer
51
    *   LDAP_AUTHENTICATION_MODE_DEFAULT (LDAP_AUTHENTICATION_MIXED)
52
    *   LDAP_AUTHENTICATION_MIXED - signifies both LDAP and Drupal authentication are allowed
53
    *     Drupal authentication is attempted first.
54
    *   LDAP_AUTHENTICATION_EXCLUSIVE - signifies only LDAP authenication is allowed
55
    */
56
  public $authenticationMode = LDAP_AUTHENTICATION_MODE_DEFAULT;
57

    
58
  /**
59
   * The following are used to alter the logon interface to direct users
60
   * to local LDAP specific authentication help
61
   */
62

    
63
  /**
64
   * Text describing username to use, such as "Hogwarts Username"
65
   *  which will be inserted on logon forms to help users figure out which
66
   *  username to use
67
   *
68
   * @var string
69
   */
70
  public $loginUIUsernameTxt;
71

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

    
81
  /**
82
   * Text and Url to provide help link for password such as:
83
   *   ldapUserHelpLinkUrl:    https://passwords.hogwarts.edu
84
   *   ldapUserHelpLinkText:  Hogwarts IT Password Support Page
85
   *
86
   * @var string
87
   */
88
  public $ldapUserHelpLinkUrl;
89
  public $ldapUserHelpLinkText = LDAP_AUTHENTICATION_HELP_LINK_TEXT_DEFAULT;
90

    
91
  /**
92
   * Email handling option
93
   *   LDAP_AUTHENTICATION_EMAIL_FIELD_REMOVE -- don't show email on user forms
94
   *   LDAP_AUTHENTICATION_EMAIL_FIELD_DISABLE (default) -- disable email on user forms
95
   *   LDAP_AUTHENTICATION_EMAIL_FIELD_ALLOW -- allow editing of email on user forms
96
   *
97
   * @var int
98
   */
99
  public $emailOption = LDAP_AUTHENTICATION_EMAIL_FIELD_DEFAULT;
100

    
101
   /**
102
   * Email handling option
103
   *   LDAP_AUTHENTICATION_EMAIL_UPDATE_ON_LDAP_CHANGE_ENABLE_NOTIFY -- (default) Update stored email if LDAP email differs at login and notify user
104
   *   LDAP_AUTHENTICATION_EMAIL_UPDATE_ON_LDAP_CHANGE_ENABLE  -- Update stored email if LDAP email differs at login but don\'t notify user
105
   *   LDAP_AUTHENTICATION_EMAIL_UPDATE_ON_LDAP_CHANGE_DISABLE -- Don\'t update stored email if LDAP email differs at login
106
   *
107
   * @var int
108
   */
109
  public $emailUpdate = LDAP_AUTHENTICATION_EMAIL_UPDATE_ON_LDAP_CHANGE_DEFAULT;
110
  
111
  /**
112
   * Email default handling option
113
   * 
114
   * This affects how email addresses that are empty are handled by 
115
   * the authentication process.
116
   * 
117
   *   LDAP_AUTHENTICATION_EMAIL_TEMPLATE_NONE -- leaves the email empty
118
   *   LDAP_AUTHENTICATION_EMAIL_TEMPLATE_IF_EMPTY (default) -- if the email is empty, it will be replaced
119
   *   LDAP_AUTHENTICATION_EMAIL_TEMPLATE_ALWAYS -- always use the template
120
   * 
121
   * @var int
122
   */
123
  public $emailTemplateHandling = LDAP_AUTHENTICATION_EMAIL_TEMPLATE_DEFAULT;
124
  
125
  /**
126
   * Email template.
127
   * 
128
   * @var string
129
   */
130
  public $emailTemplate = LDAP_AUTHENTICATION_DEFAULT_TEMPLATE;
131
      
132
  /**
133
   * Whether or not to display a notification to the user on login, prompting 
134
   * them to change their email.
135
   * 
136
   * @var boolean
137
   */
138
  public $templateUsagePromptUser = LDAP_AUTHENTICATION_TEMPLATE_USAGE_PROMPT_USER_DEFAULT;
139
  
140
  /**
141
   * Whether or not to avoid updating the email address of the user if the
142
   * template was used to generate it.
143
   * 
144
   * @var boolean
145
   */
146
  public $templateUsageNeverUpdate = LDAP_AUTHENTICATION_TEMPLATE_USAGE_NEVER_UPDATE_DEFAULT;
147
  
148
  /**
149
   * Whether or not to use the email template if there is a user with a different
150
   * login name but same email address in the system.
151
   * 
152
   * @var boolean
153
   */
154
  public $templateUsageResolveConflict = LDAP_AUTHENTICATION_TEMPLATE_USAGE_RESOLVE_CONFLICT_DEFAULT;
155
  
156
  /**
157
   * A PCRE regular expression (minus the delimiter and flags) that will be used
158
   * if $templateUsagePromptUser is set to true to determine if the email 
159
   * address is a fake one or not. 
160
   * 
161
   * By allowing this to be customized, we let the administrators handle older
162
   * patterns should they decide to change the existing one, as well as avoiding
163
   * the complexity of determining a proper regex from the template.
164
   * 
165
   * @var string
166
   */
167
  public $templateUsagePromptRegex = LDAP_AUTHENTICATION_DEFAULT_TEMPLATE_REGEX;
168
  
169
  /**
170
   * Controls whether or not we should check on login if the email template was
171
   * used and redirect the user if needed.
172
   * 
173
   * @var boolean
174
   */
175
  public $templateUsageRedirectOnLogin = LDAP_AUTHENTICATION_REDIRECT_ON_LOGIN_DEFAULT;
176
  
177

    
178

    
179
   /**
180
   * Password handling option
181
   *   LDAP_AUTHENTICATION_PASSWORD_FIELD_SHOW -- show field disabled on user forms
182
   *   LDAP_AUTHENTICATION_PASSWORD_FIELD_HIDE (default) -- disable password on user forms
183
   *   LDAP_AUTHENTICATION_PASSWORD_FIELD_ALLOW -- allow editing of password on user forms
184
   *
185
   * @var int
186
   */
187
  public $passwordOption = LDAP_AUTHENTICATION_PASSWORD_FIELD_DEFAULT;
188

    
189
  public $ssoEnabled = FALSE;
190
  public $ssoRemoteUserStripDomainName = FALSE;
191
  public $ssoExcludedPaths = NULL;
192
  public $ssoExcludedHosts = NULL;
193
  public $seamlessLogin = FALSE;
194
  public $ssoNotifyAuthentication = FALSE;
195
  public $ldapImplementation = FALSE;
196
  public $cookieExpire = LDAP_AUTHENTICATION_COOKIE_EXPIRE;
197
  public $apiPrefs = array();
198

    
199
  /**
200
   * Advanced options.   whitelist / blacklist options
201
   *
202
   * these are on the fuzzy line between authentication and authorization
203
   * and determine if a user is allowed to authenticate with ldap
204
   *
205
   */
206

    
207
  /**
208
   * text which must be present in user's LDAP entry's DN for user to authenticate with LDAP
209
   *   e.g. "ou=people"
210
   *
211
   * @var string
212
   */
213
  public $allowOnlyIfTextInDn = array(); // eg ou=education that must be met to allow ldap authentication
214

    
215
  /**
216
   * text which prohibits logon if found in user's LDAP entry's DN for user to authenticate with LDAP
217
   *   e.g. "ou=guest accounts"
218
   *
219
   * @var string
220
   */
221
  public $excludeIfTextInDn = array();
222

    
223
  /**
224
   * code that prints 1 or 0 signifying if user is allowed
225
   *   should not start with <?php
226
   *
227
   * @var string of php
228
   */
229
  public $allowTestPhp = NULL;
230

    
231
  /**
232
   * if at least 1 ldap authorization must exist for user to be allowed
233
   *   True signfies disallow if no authorizations.
234
   *   False signifies don't consider authorizations.
235
   *
236
   * @var boolean.
237
   */
238
  public $excludeIfNoAuthorizations = LDAP_AUTHENTICATION_EXCL_IF_NO_AUTHZ_DEFAULT;
239

    
240
  public $saveable = array(
241
    'sids',
242
    'authenticationMode',
243
    'loginUIUsernameTxt',
244
    'loginUIPasswordTxt',
245
    'ldapUserHelpLinkUrl',
246
    'ldapUserHelpLinkText',
247
    'emailOption',
248
    'emailUpdate',
249
    'passwordOption',
250
    'allowOnlyIfTextInDn',
251
    'excludeIfTextInDn',
252
    'allowTestPhp',
253
    'excludeIfNoAuthorizations',
254
    'ssoRemoteUserStripDomainName',
255
    'ssoExcludedPaths',
256
    'ssoExcludedHosts',
257
    'seamlessLogin',
258
    'ssoNotifyAuthentication',
259
    'ldapImplementation',
260
    'cookieExpire',
261
    'emailTemplate',
262
    'emailTemplateHandling',
263
    'templateUsagePromptUser',
264
    'templateUsageNeverUpdate',
265
    'templateUsageResolveConflict',
266
    'templateUsagePromptRegex',
267
    'templateUsageRedirectOnLogin',
268
  );
269

    
270
  public function hasEnabledAuthenticationServers() {
271
    return !(count($this->enabledAuthenticationServers) == 0);
272
  }
273

    
274
  public function enabled_servers() {
275
    return $this->hasEnabledAuthenticationServers();
276
  }
277

    
278
  function __construct() {
279
    $this->load();
280
  }
281

    
282
  function load() {
283

    
284
    if ($saved = variable_get("ldap_authentication_conf", FALSE)) {
285
      $this->inDatabase = TRUE;
286
      foreach ($this->saveable as $property) {
287
        if (isset($saved[$property])) {
288
          $this->{$property} = $saved[$property];
289
        }
290
      }
291
      $this->enabledAuthenticationServers = array(); // reset in case reloading instantiated object
292
      $enabled_ldap_servers = ldap_servers_get_servers(NULL, 'enabled');
293
      foreach ($this->sids as $sid => $enabled) {
294
        if ($enabled && isset($enabled_ldap_servers[$sid])) {
295
          $this->enabledAuthenticationServers[$sid] = $enabled_ldap_servers[$sid];
296
        }
297
      }
298

    
299
    }
300
    else {
301
      $this->inDatabase = FALSE;
302
    }
303

    
304
    $this->ldapUser = new LdapUserConf();
305
    $this->ssoEnabled = module_exists('ldap_sso');
306
    $this->apiPrefs['requireHttps'] = variable_get('ldap_servers_require_ssl_for_credentials', 0);
307
    $this->apiPrefs['encryption'] = variable_get('ldap_servers_encryption', LDAP_SERVERS_ENC_TYPE_CLEARTEXT);
308

    
309
  }
310

    
311
  /**
312
   * Destructor Method
313
   */
314
  function __destruct() { }
315

    
316

    
317
 /**
318
   * decide if a username is excluded or not
319
   *
320
   * @param string $name as proposed drupal username
321
   * @param array $ldap_user where top level keys are 'dn','attr','mail'
322
   * @return boolean FALSE means NOT allow; TRUE means allow
323
   *
324
   * @todo.  this function should simply invoke hook_ldap_authentication_allowuser_results_alter
325
   *   and most of this function should go in ldap_authentication_allowuser_results_alter
326
   */
327
  public function allowUser($name, $ldap_user) {
328

    
329
    /**
330
     * do one of the exclude attribute pairs match
331
     */
332
    $ldap_user_conf = ldap_user_conf();
333
    // if user does not already exists and deferring to user settings AND user settings only allow
334
    $user_register = variable_get('user_register', USER_REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL);
335

    
336
    foreach ($this->excludeIfTextInDn as $test) {
337
      if (stripos($ldap_user['dn'], $test) !== FALSE) {
338
        return FALSE;//  if a match, return FALSE;
339
      }
340
    }
341

    
342
    /**
343
     * evaluate php if it exists
344
     */
345

    
346
    if ($this->allowTestPhp) {
347
      if (module_exists('php')) {
348
        global $_name, $_ldap_user_entry;
349
        $_name = $name;
350
        $_ldap_user_entry = $ldap_user;
351
        $code = '<?php ' . "global \$_name; \n  global \$_ldap_user_entry; \n" . $this->allowTestPhp . ' ?>';
352
        $code_result = php_eval($code);
353
        $_name = NULL;
354
        $_ldap_user_entry = NULL;
355
        if ((boolean)($code_result) == FALSE) {
356
          return FALSE;
357
        }
358
      }
359
      else {
360
        drupal_set_message(t(LDAP_AUTHENTICATION_DISABLED_FOR_BAD_CONF_MSG), 'warning');
361
        $tokens = array('!ldap_authentication_config' => l(t('LDAP Authentication Configuration'), 'admin/config/people/ldap/authentication'));
362
        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);
363
        return FALSE;
364
      }
365
    }
366

    
367
    /**
368
     * do one of the allow attribute pairs match
369
     */
370
    if (count($this->allowOnlyIfTextInDn)) {
371
      $fail = TRUE;
372
      foreach ($this->allowOnlyIfTextInDn as $test) {
373
        if (stripos($ldap_user['dn'], $test) !== FALSE) {
374
          $fail = FALSE;
375
        }
376
      }
377
      if ($fail) {
378
        return FALSE;
379
      }
380

    
381
    }
382
    /**
383
     * is excludeIfNoAuthorizations option enabled and user not granted any groups
384
     */
385

    
386
    if ($this->excludeIfNoAuthorizations) {
387

    
388
      if (!module_exists('ldap_authorization')) {
389
        drupal_set_message(t(LDAP_AUTHENTICATION_DISABLED_FOR_BAD_CONF_MSG), 'warning');
390
        $tokens = array('!ldap_authentication_config' => l(t('LDAP Authentication Configuration'), 'admin/config/people/ldap/authentication'));
391
        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);
392
        return FALSE;
393
      }
394

    
395
      $user = new stdClass();
396
      $user->name = $name;
397
      $user->ldap_authenticated = TRUE; // fake user property added for query
398
      $consumers = ldap_authorization_get_consumers();
399
      $has_enabled_consumers = FALSE;
400
      $has_ldap_authorizations = FALSE;
401

    
402
      foreach ($consumers as $consumer_type => $consumer_config) {
403
        $consumer_obj = ldap_authorization_get_consumer_object($consumer_type);
404
        if ($consumer_obj->consumerConf->status) {
405
          $has_enabled_consumers = TRUE;
406
          list($authorizations, $notifications) = ldap_authorizations_user_authorizations($user, 'query', $consumer_type, 'test_if_authorizations_granted');
407
          if (
408
            isset($authorizations[$consumer_type]) &&
409
            count($authorizations[$consumer_type]) > 0
410
            ) {
411
            $has_ldap_authorizations = TRUE;
412
          }
413
        }
414
      }
415

    
416
      if (!$has_enabled_consumers) {
417
        drupal_set_message(t(LDAP_AUTHENTICATION_DISABLED_FOR_BAD_CONF_MSG), 'warning');
418
        $tokens = array('!ldap_consumer_config' => l(t('LDAP Authorization Configuration'), 'admin/config/people/ldap/authorization'));
419
        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);
420
        return FALSE;
421
      }
422
      elseif (!$has_ldap_authorizations) {
423
        return FALSE;
424
      }
425

    
426
    }
427

    
428
    // allow other modules to hook in and refuse if they like
429
    $hook_result = TRUE;
430
    drupal_alter('ldap_authentication_allowuser_results', $ldap_user, $name, $hook_result);
431

    
432
    if ($hook_result === FALSE) {
433
      watchdog('ldap_authentication', "Authentication Allow User Result=refused for %name", array('%name' => $name), WATCHDOG_NOTICE);
434
      return FALSE;
435
    }
436

    
437
    /**
438
     * default to allowed
439
     */
440
    return TRUE;
441
  }
442

    
443

    
444
}