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 |
} |