From fc54986465f329b7b2407415d951dd6345bd4ce4 Mon Sep 17 00:00:00 2001 From: iarenaza Date: Mon, 6 Jul 2009 18:51:30 +0000 Subject: [PATCH] ldap auth and enrolment: MDL-19672 prevent update_user_record() from mangling distinguished names with backslashes In addition to it, in order to be able to used a distiguished name with '\' (and other LDAP special characters) in a LDAP filter to find the user enrolments, we need to quote it using the LDAP filter quoting rules --- auth/ldap/auth.php | 21 +++++++++++++++------ enrol/ldap/enrol.php | 14 +++++++++++++- lib/moodlelib.php | 2 +- 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/auth/ldap/auth.php b/auth/ldap/auth.php index bcced6e92ea..dd05be6dbd7 100644 --- a/auth/ldap/auth.php +++ b/auth/ldap/auth.php @@ -222,7 +222,7 @@ class auth_plugin_ldap extends auth_plugin_base { } $ldapval = NULL; foreach ($values as $value) { - if ($value == 'dn') { + if ((moodle_strtolower($value) == 'dn') || (moodle_strtolower($value) == 'distinguishedname')) { $result[$key] = $user_dn; } if (!array_key_exists($value, $user_entry[0])) { @@ -2121,7 +2121,7 @@ class auth_plugin_ldap extends auth_plugin_base { } /** - * Quote control characters in texts used in ldap filters - see rfc2254.txt + * Quote control characters in texts used in ldap filters - see RFC 4515/2254 * * @param string */ @@ -2133,14 +2133,23 @@ class auth_plugin_ldap extends auth_plugin_base { } /** - * Quote control characters in quoted "texts" used in ldap + * The order of the special characters in these arrays _IS IMPORTANT_. + * Make sure '\\5C' (and '\\') are the first elements of the arrays. + * Otherwise we'll double replace '\' with '\5C' which is Bad(tm) + */ + var $LDAP_DN_QUOTED_SPECIAL_CHARS = array('\\5c','\\20','\\22','\\23','\\2b','\\2c','\\3b','\\3c','\\3d','\\3e','\\00'); + var $LDAP_DN_SPECIAL_CHARS = array('\\', ' ', '"', '#', '+', ',', ';', '<', '=', '>', "\0"); + + /** + * Quote control characters in distinguished names used in ldap - See RFC 4514/2253 * * @param string + * @return string */ function ldap_addslashes($text) { - $text = str_replace('\\', '\\\\', $text); - $text = str_replace(array('"', "\0"), - array('\\"', '\\00'), $text); + $text = str_replace ($this->LDAP_DN_SPECIAL_CHARS, + $this->LDAP_DN_QUOTED_SPECIAL_CHARS, + $text); return $text; } diff --git a/enrol/ldap/enrol.php b/enrol/ldap/enrol.php index 3f247c37006..f5dc7f4a363 100755 --- a/enrol/ldap/enrol.php +++ b/enrol/ldap/enrol.php @@ -501,7 +501,7 @@ function find_ext_enrolments ($ldap_connection, $memberuid, $role){ } // define the search pattern - $ldap_search_pattern = "(".$CFG->{'enrol_ldap_memberattribute_role'.$role->id}."=".$memberuid.")"; + $ldap_search_pattern = "(".$CFG->{'enrol_ldap_memberattribute_role'.$role->id}."=".$this->filter_addslashes($memberuid).")"; if (!empty($CFG->enrol_ldap_objectclass)){ $ldap_search_pattern='(&(objectclass='.$CFG->enrol_ldap_objectclass.')'.$ldap_search_pattern.')'; } @@ -671,6 +671,18 @@ function check_legacy_config () { } } +/** + * Quote control characters in texts used in ldap filters - see RFC 4515/2254 + * + * @param string + */ +function filter_addslashes($text) { + $text = str_replace('\\', '\\5c', $text); + $text = str_replace(array('*', '(', ')', "\0"), + array('\\2a', '\\28', '\\29', '\\00'), $text); + return $text; +} + } // end of class ?> diff --git a/lib/moodlelib.php b/lib/moodlelib.php index 1a3d2920001..6834d820672 100644 --- a/lib/moodlelib.php +++ b/lib/moodlelib.php @@ -2975,7 +2975,7 @@ function update_user_record($username, $authplugin) { continue; } if ($confval === 'onlogin') { - $value = addslashes(stripslashes($value)); // Just in case + $value = addslashes($value); // MDL-4207 Don't overwrite modified user profile values with // empty LDAP values when 'unlocked if empty' is set. The purpose // of the setting 'unlocked if empty' is to allow the user to fill