|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00002 00018 defined('MOODLE_INTERNAL') || die(); 00019 00020 // rootDSE is defined as the root of the directory data tree on a directory server. 00021 if (!defined('ROOTDSE')) { 00022 define ('ROOTDSE', ''); 00023 } 00024 00030 function ldap_supported_usertypes() { 00031 $types = array(); 00032 $types['edir'] = 'Novell Edirectory'; 00033 $types['rfc2307'] = 'posixAccount (rfc2307)'; 00034 $types['rfc2307bis'] = 'posixAccount (rfc2307bis)'; 00035 $types['samba'] = 'sambaSamAccount (v.3.0.7)'; 00036 $types['ad'] = 'MS ActiveDirectory'; 00037 $types['default'] = get_string('default'); 00038 return $types; 00039 } 00040 00054 function ldap_getdefaults() { 00055 // All the values have to be written in lowercase, even if the 00056 // standard LDAP attributes are mixed-case 00057 $default['objectclass'] = array( 00058 'edir' => 'user', 00059 'rfc2307' => 'posixaccount', 00060 'rfc2307bis' => 'posixaccount', 00061 'samba' => 'sambasamaccount', 00062 'ad' => 'user', 00063 'default' => '*' 00064 ); 00065 $default['user_attribute'] = array( 00066 'edir' => 'cn', 00067 'rfc2307' => 'uid', 00068 'rfc2307bis' => 'uid', 00069 'samba' => 'uid', 00070 'ad' => 'cn', 00071 'default' => 'cn' 00072 ); 00073 $default['memberattribute'] = array( 00074 'edir' => 'member', 00075 'rfc2307' => 'member', 00076 'rfc2307bis' => 'member', 00077 'samba' => 'member', 00078 'ad' => 'member', 00079 'default' => 'member' 00080 ); 00081 $default['memberattribute_isdn'] = array( 00082 'edir' => '1', 00083 'rfc2307' => '0', 00084 'rfc2307bis' => '1', 00085 'samba' => '0', // is this right? 00086 'ad' => '1', 00087 'default' => '0' 00088 ); 00089 $default['expireattr'] = array ( 00090 'edir' => 'passwordexpirationtime', 00091 'rfc2307' => 'shadowexpire', 00092 'rfc2307bis' => 'shadowexpire', 00093 'samba' => '', // No support yet 00094 'ad' => 'pwdlastset', 00095 'default' => '' 00096 ); 00097 return $default; 00098 } 00099 00113 function ldap_isgroupmember($ldapconnection, $userid, $group_dns, $member_attrib) { 00114 if (empty($ldapconnection) || empty($userid) || empty($group_dns) || empty($member_attrib)) { 00115 return false; 00116 } 00117 00118 $result = false; 00119 foreach ($group_dns as $group) { 00120 $group = trim($group); 00121 if (empty($group)) { 00122 continue; 00123 } 00124 00125 // Check cheaply if the user's DN sits in a subtree of the 00126 // "group" DN provided. Granted, this isn't a proper LDAP 00127 // group, but it's a popular usage. 00128 if (stripos(strrev(strtolower($userid)), strrev(strtolower($group))) === 0) { 00129 $result = true; 00130 break; 00131 } 00132 00133 $search = ldap_read($ldapconnection, $group, 00134 '('.$member_attrib.'='.ldap_filter_addslashes($userid).')', 00135 array($member_attrib)); 00136 00137 if (!empty($search) && ldap_count_entries($ldapconnection, $search)) { 00138 $info = ldap_get_entries_moodle($ldapconnection, $search); 00139 if (count($info) > 0 ) { 00140 // User is member of group 00141 $result = true; 00142 break; 00143 } 00144 } 00145 } 00146 00147 return $result; 00148 } 00149 00163 function ldap_connect_moodle($host_url, $ldap_version, $user_type, $bind_dn, $bind_pw, $opt_deref, &$debuginfo) { 00164 if (empty($host_url) || empty($ldap_version) || empty($user_type)) { 00165 $debuginfo = 'No LDAP Host URL, Version or User Type specified in your LDAP settings'; 00166 return false; 00167 } 00168 00169 $debuginfo = ''; 00170 $urls = explode(';', $host_url); 00171 foreach ($urls as $server) { 00172 $server = trim($server); 00173 if (empty($server)) { 00174 continue; 00175 } 00176 00177 $connresult = ldap_connect($server); // ldap_connect returns ALWAYS true 00178 00179 if (!empty($ldap_version)) { 00180 ldap_set_option($connresult, LDAP_OPT_PROTOCOL_VERSION, $ldap_version); 00181 } 00182 00183 // Fix MDL-10921 00184 if ($user_type === 'ad') { 00185 ldap_set_option($connresult, LDAP_OPT_REFERRALS, 0); 00186 } 00187 00188 if (!empty($opt_deref)) { 00189 ldap_set_option($connresult, LDAP_OPT_DEREF, $opt_deref); 00190 } 00191 00192 if (!empty($bind_dn)) { 00193 $bindresult = @ldap_bind($connresult, $bind_dn, $bind_pw); 00194 } else { 00195 // Bind anonymously 00196 $bindresult = @ldap_bind($connresult); 00197 } 00198 00199 if ($bindresult) { 00200 return $connresult; 00201 } 00202 00203 $debuginfo .= "Server: '$server', Connection: '$connresult', Bind result: '$bindresult'\n"; 00204 } 00205 00206 // If any of servers were alive we have already returned connection. 00207 return false; 00208 } 00209 00223 function ldap_find_userdn($ldapconnection, $username, $contexts, $objectclass, $search_attrib, $search_sub) { 00224 if (empty($ldapconnection) || empty($username) || empty($contexts) || empty($objectclass) || empty($search_attrib)) { 00225 return false; 00226 } 00227 00228 // Default return value 00229 $ldap_user_dn = false; 00230 00231 // Get all contexts and look for first matching user 00232 foreach ($contexts as $context) { 00233 $context = trim($context); 00234 if (empty($context)) { 00235 continue; 00236 } 00237 00238 if ($search_sub) { 00239 $ldap_result = ldap_search($ldapconnection, $context, 00240 '(&'.$objectclass.'('.$search_attrib.'='.ldap_filter_addslashes($username).'))', 00241 array($search_attrib)); 00242 } else { 00243 $ldap_result = ldap_list($ldapconnection, $context, 00244 '(&'.$objectclass.'('.$search_attrib.'='.ldap_filter_addslashes($username).'))', 00245 array($search_attrib)); 00246 } 00247 00248 $entry = ldap_first_entry($ldapconnection, $ldap_result); 00249 if ($entry) { 00250 $ldap_user_dn = ldap_get_dn($ldapconnection, $entry); 00251 break; 00252 } 00253 } 00254 00255 return $ldap_user_dn; 00256 } 00257 00266 function ldap_get_entries_moodle($ldapconnection, $searchresult) { 00267 if (empty($ldapconnection) || empty($searchresult)) { 00268 return array(); 00269 } 00270 00271 $i = 0; 00272 $result = array(); 00273 $entry = ldap_first_entry($ldapconnection, $searchresult); 00274 if (!$entry) { 00275 return array(); 00276 } 00277 do { 00278 $attributes = array_change_key_case(ldap_get_attributes($ldapconnection, $entry), CASE_LOWER); 00279 for ($j = 0; $j < $attributes['count']; $j++) { 00280 $values = ldap_get_values_len($ldapconnection, $entry, $attributes[$j]); 00281 if (is_array($values)) { 00282 $result[$i][$attributes[$j]] = $values; 00283 } else { 00284 $result[$i][$attributes[$j]] = array($values); 00285 } 00286 } 00287 $i++; 00288 } while ($entry = ldap_next_entry($ldapconnection, $entry)); 00289 00290 return ($result); 00291 } 00292 00299 function ldap_filter_addslashes($text) { 00300 $text = str_replace('\\', '\\5c', $text); 00301 $text = str_replace(array('*', '(', ')', "\0"), 00302 array('\\2a', '\\28', '\\29', '\\00'), $text); 00303 return $text; 00304 } 00305 00306 if(!defined('LDAP_DN_SPECIAL_CHARS')) { 00307 define('LDAP_DN_SPECIAL_CHARS', 0); 00308 } 00309 if(!defined('LDAP_DN_SPECIAL_CHARS_QUOTED_NUM')) { 00310 define('LDAP_DN_SPECIAL_CHARS_QUOTED_NUM', 1); 00311 } 00312 if(!defined('LDAP_DN_SPECIAL_CHARS_QUOTED_ALPHA')) { 00313 define('LDAP_DN_SPECIAL_CHARS_QUOTED_ALPHA', 2); 00314 } 00315 00321 function ldap_get_dn_special_chars() { 00322 return array ( 00323 LDAP_DN_SPECIAL_CHARS => array('\\', ' ', '"', '#', '+', ',', ';', '<', '=', '>', "\0"), 00324 LDAP_DN_SPECIAL_CHARS_QUOTED_NUM => array('\\5c','\\20','\\22','\\23','\\2b','\\2c','\\3b','\\3c','\\3d','\\3e','\\00'), 00325 LDAP_DN_SPECIAL_CHARS_QUOTED_ALPHA => array('\\\\','\\ ', '\\"', '\\#', '\\+', '\\,', '\\;', '\\<', '\\>', '\\=', '\\00'), 00326 ); 00327 } 00328 00335 function ldap_addslashes($text) { 00336 $special_dn_chars = ldap_get_dn_special_chars(); 00337 00338 $text = str_replace ($special_dn_chars[LDAP_DN_SPECIAL_CHARS], 00339 $special_dn_chars[LDAP_DN_SPECIAL_CHARS_QUOTED_NUM], 00340 $text); 00341 return $text; 00342 } 00343 00350 function ldap_stripslashes($text) { 00351 $special_dn_chars = ldap_get_dn_special_chars(); 00352 00353 // First unquote the simply backslashed special characters. If we 00354 // do it the other way, we remove too many slashes. 00355 $text = str_replace($special_dn_chars[LDAP_DN_SPECIAL_CHARS_QUOTED_ALPHA], 00356 $special_dn_chars[LDAP_DN_SPECIAL_CHARS], 00357 $text); 00358 00359 // Next unquote the 'numerically' quoted characters. We don't use 00360 // LDAP_DN_SPECIAL_CHARS_QUOTED_NUM because the standard allows us 00361 // to quote any character with this encoding, not just the special 00362 // ones. 00363 $text = preg_replace('/\\\([0-9A-Fa-f]{2})/e', "chr(hexdec('\\1'))", $text); 00364 00365 return $text; 00366 }