Merge branch 'wip_master_mdl-50625_ldap_better_check_paged_results_support' of https://github.com/iarenaza/moodle

This commit is contained in:
Dan Poltawski 2017-01-23 16:21:02 +00:00
commit cffa0ec79b
5 changed files with 84 additions and 10 deletions

View File

@ -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);
}
?>

View File

@ -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)) {

View File

@ -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);
}
?>

View File

@ -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';

View File

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