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 85ad3d82 Assos Assos
<?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 dd54aff9 Assos Assos
   * @see LdapServer->sid()
19 85ad3d82 Assos Assos
   */
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 dd54aff9 Assos Assos
   * @see LdapServer->sid()
28 85ad3d82 Assos Assos
   * @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 dd54aff9 Assos Assos
  
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 85ad3d82 Assos Assos
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 dd54aff9 Assos Assos
    'emailTemplate',
262
    'emailTemplateHandling',
263
    'templateUsagePromptUser',
264
    'templateUsageNeverUpdate',
265
    'templateUsageResolveConflict',
266
    'templateUsagePromptRegex',
267
    'templateUsageRedirectOnLogin',
268 85ad3d82 Assos Assos
  );
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 7547bb19 Assos Assos
    $this->apiPrefs['requireHttps'] = variable_get('ldap_servers_require_ssl_for_credentials', 0);
307 85ad3d82 Assos Assos
    $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
}