mirror of
https://github.com/moodle/moodle.git
synced 2025-04-15 05:25:08 +02:00
MDL-50625 auth_ldap: Better check for paged results support
There is at least one LDAP server (Sun Directory Server) that doesn't support Paged Results extension, even if it supports LDAP version 3. So checking just for LDAP version is not enough. If possible, we check the supportedControl attribute of the LDAP rootDSE and see if the paged results control is available. This needs an LDAP connection, which might not be possible to establish before we configure some essential LDAP settings (server, bind user, password, etc.). Thus we try to establish the connection and check the supportedControl attribute. But if we fail, we perform only basic checks that are less accurate and err on the side of cautiousness.
This commit is contained in:
parent
5130953c8a
commit
e47863e840
@ -99,9 +99,31 @@ if (!isset($config->removeuser)) {
|
||||
$yesno = array( get_string('no'), get_string('yes') );
|
||||
|
||||
$disabled = '';
|
||||
if (!ldap_paged_results_supported($config->ldap_version)) {
|
||||
$pagedresultssupported = false;
|
||||
if ($config->host_url !== '') {
|
||||
/**
|
||||
* We try to connect each and every time we open the config, because we want to set the Page
|
||||
* Size setting as enabled or disabled depending on the configured LDAP server supporting
|
||||
* pagination or not, and to notify the user about it. If the user changed the LDAP server (or
|
||||
* the LDAP protocol version) last time, it might happen that paged results are no longer
|
||||
* available and we want to show that to the user the next time she goes to the settings page.
|
||||
*/
|
||||
try {
|
||||
$ldapconn = $this->ldap_connect();
|
||||
$pagedresultssupported = ldap_paged_results_supported($config->ldap_version, $ldapconn);
|
||||
} catch (Exception $e) {
|
||||
// If we couldn't connect and get the supported options, we can only assume we don't support paged results.
|
||||
$pagedresultssupported = false;
|
||||
}
|
||||
}
|
||||
/* Make sure we only disable the paged result size setting and show the notification about it if
|
||||
* there is a configured server that we tried to contact. Othersiwe, if someone's LDAP server does
|
||||
* support paged results, they won't be able to turn it on the first time they set it up (because
|
||||
* the field will be disabled).
|
||||
*/
|
||||
if (($config->host_url !== '') && (!$pagedresultssupported)) {
|
||||
$disabled = ' disabled="disabled"';
|
||||
echo $OUTPUT->notification(get_string('pagedresultsnotsupp', 'auth_ldap'));
|
||||
echo $OUTPUT->notification(get_string('pagedresultsnotsupp', 'auth_ldap'), \core\output\notification::NOTIFY_INFO);
|
||||
}
|
||||
|
||||
?>
|
||||
|
@ -695,7 +695,7 @@ class auth_plugin_ldap extends auth_plugin_base {
|
||||
array_push($contexts, $this->config->create_context);
|
||||
}
|
||||
|
||||
$ldap_pagedresults = ldap_paged_results_supported($this->config->ldap_version);
|
||||
$ldap_pagedresults = ldap_paged_results_supported($this->config->ldap_version, $ldapconnection);
|
||||
$ldap_cookie = '';
|
||||
foreach ($contexts as $context) {
|
||||
$context = trim($context);
|
||||
@ -1540,7 +1540,7 @@ class auth_plugin_ldap extends auth_plugin_base {
|
||||
}
|
||||
|
||||
$ldap_cookie = '';
|
||||
$ldap_pagedresults = ldap_paged_results_supported($this->config->ldap_version);
|
||||
$ldap_pagedresults = ldap_paged_results_supported($this->config->ldap_version, $ldapconnection);
|
||||
foreach ($contexts as $context) {
|
||||
$context = trim($context);
|
||||
if (empty($context)) {
|
||||
|
@ -117,9 +117,31 @@ $fastpathoptions = array(AUTH_NTLM_FASTPATH_YESFORM => get_string('auth_ntlmsso_
|
||||
AUTH_NTLM_FASTPATH_ATTEMPT => get_string('auth_ntlmsso_ie_fastpath_attempt', 'auth_ldap'));
|
||||
|
||||
$disabled = '';
|
||||
if (!ldap_paged_results_supported($config->ldap_version)) {
|
||||
$pagedresultssupported = false;
|
||||
if ($config->host_url !== '') {
|
||||
/**
|
||||
* We try to connect each and every time we open the config, because we want to set the Page
|
||||
* Size setting as enabled or disabled depending on the configured LDAP server supporting
|
||||
* pagination or not, and to notify the user about it. If the user changed the LDAP server (or
|
||||
* the LDAP protocol version) last time, it might happen that paged results are no longer
|
||||
* available and we want to show that to the user the next time she goes to the settings page.
|
||||
*/
|
||||
try {
|
||||
$ldapconn = $this->ldap_connect();
|
||||
$pagedresultssupported = ldap_paged_results_supported($config->ldap_version, $ldapconn);
|
||||
} catch (Exception $e) {
|
||||
// If we couldn't connect and get the supported options, we can only assume we don't support paged results.
|
||||
$pagedresultssupported = false;
|
||||
}
|
||||
}
|
||||
/* Make sure we only disable the paged result size setting and show the notification about it if
|
||||
* there is a configured server that we tried to contact. Othersiwe, if someone's LDAP server does
|
||||
* support paged results, they won't be able to turn it on the first time they set it up (because
|
||||
* the field will be disabled).
|
||||
*/
|
||||
if (($config->host_url !== '') && (!$pagedresultssupported)) {
|
||||
$disabled = ' disabled="disabled"';
|
||||
echo $OUTPUT->notification(get_string('pagedresultsnotsupp', 'auth_ldap'));
|
||||
echo $OUTPUT->notification(get_string('pagedresultsnotsupp', 'auth_ldap'), \core\output\notification::NOTIFY_INFO);
|
||||
}
|
||||
|
||||
?>
|
||||
|
@ -132,7 +132,7 @@ $string['ntlmsso_attempting'] = 'Attempting Single Sign On via NTLM...';
|
||||
$string['ntlmsso_failed'] = 'Auto-login failed, try the normal login page...';
|
||||
$string['ntlmsso_isdisabled'] = 'NTLM SSO is disabled.';
|
||||
$string['ntlmsso_unknowntype'] = 'Unknown ntlmsso type!';
|
||||
$string['pagedresultsnotsupp'] = 'LDAP paged results not supported (either your PHP version lacks support or you have configured Moodle to use LDAP protocol version 2)';
|
||||
$string['pagedresultsnotsupp'] = 'LDAP paged results not supported (either your PHP version lacks support, you have configured Moodle to use LDAP protocol version 2 or Moodle cannot contact your LDAP server to see if paged support is available.)';
|
||||
$string['pagesize'] = 'Make sure this value is smaller than your LDAP server result set size limit (the maximum number of entries that can be returned in a single query)';
|
||||
$string['pagesize_key'] = 'Page size';
|
||||
$string['pluginname'] = 'LDAP server';
|
||||
|
@ -22,6 +22,11 @@ if (!defined('ROOTDSE')) {
|
||||
define ('ROOTDSE', '');
|
||||
}
|
||||
|
||||
// Paged results control OID value.
|
||||
if (!defined('LDAP_PAGED_RESULTS_CONTROL')) {
|
||||
define ('LDAP_PAGED_RESULTS_CONTROL', '1.2.840.113556.1.4.319');
|
||||
}
|
||||
|
||||
// Default page size when using LDAP paged results
|
||||
if (!defined('LDAP_DEFAULT_PAGESIZE')) {
|
||||
define('LDAP_DEFAULT_PAGESIZE', 250);
|
||||
@ -452,14 +457,39 @@ function ldap_stripslashes($text) {
|
||||
|
||||
|
||||
/**
|
||||
* Check if we use LDAP version 3, otherwise the server cannot use them.
|
||||
* Check if we can use paged results (see RFC 2696). We need to use
|
||||
* LDAP version 3 (or later), otherwise the server cannot use them. If
|
||||
* we also pass in a valid LDAP connection handle, we also check
|
||||
* whether the server actually supports them.
|
||||
*
|
||||
* @param ldapversion integer The LDAP protocol version we use.
|
||||
* @param ldapconnection resource An existing LDAP connection (optional).
|
||||
*
|
||||
* @return boolean true is paged results can be used, false otherwise.
|
||||
*/
|
||||
function ldap_paged_results_supported($ldapversion) {
|
||||
if ((int)$ldapversion === 3) {
|
||||
function ldap_paged_results_supported($ldapversion, $ldapconnection = null) {
|
||||
if ((int)$ldapversion < 3) {
|
||||
// Minimun required version: LDAP v3.
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($ldapconnection === null) {
|
||||
// Can't verify it, so assume it isn't supported.
|
||||
return false;
|
||||
}
|
||||
|
||||
// Connect to the rootDSE and get the supported controls.
|
||||
$sr = ldap_read($ldapconnection, ROOTDSE, '(objectClass=*)', array('supportedControl'));
|
||||
if (!$sr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$entries = ldap_get_entries_moodle($ldapconnection, $sr);
|
||||
if (empty($entries)) {
|
||||
return false;
|
||||
}
|
||||
$info = array_change_key_case($entries[0], CASE_LOWER);
|
||||
if (isset($info['supportedcontrol']) && in_array(LDAP_PAGED_RESULTS_CONTROL, $info['supportedcontrol'])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user