0 && strlen($username) > 0)){ return false; } if(isset($simpleldap['LDAPTLS_REQCERT_never']) && $simpleldap['LDAPTLS_REQCERT_never']) { putenv('LDAPTLS_REQCERT=never'); } // ldap escape username $ldap_username = (function_exists('ldap_escape')) ? ldap_escape($username, '', LDAP_ESCAPE_DN) : $username; // Set LDAP options for all connections ldap_set_option(null, LDAP_OPT_NETWORK_TIMEOUT, 2); ldap_set_option(null, LDAP_OPT_PROTOCOL_VERSION, 3); if (!isset($simpleldap['ldaptype']) || $simpleldap['ldaptype'] == 1) { // AD - need to set this ldap_set_option(null, LDAP_OPT_REFERRALS, 0); } // Set up first connection if (substr(strtolower($simpleldap['ldapserver']),0,4) == "ldap") { $connstring = $simpleldap['ldapserver']; } elseif ($simpleldap['port'] == 636) { $connstring = 'ldaps://' . $simpleldap['ldapserver'] . ':636'; } else { $connstring = 'ldap://' . $simpleldap['ldapserver'] . ':' . $simpleldap['port']; } $ds = ldap_connect($connstring); if ($ds === false) { debug("LDAP - Invalid connection URL: '" . $connstring . "'"); return false; } // Bind to server // Set up array of different username formats to try and bind with $binddomains = explode(";",$simpleldap['basedn']); $binduserstrings[] = $ldap_username; if ( (!isset($simpleldap['ldaptype']) || $simpleldap['ldaptype'] == 1) && strpos($ldap_username, "@" . $userdomain) === false ) { // Ad and not in username@domain format, add that as well as cn $binduserstrings[] = $ldap_username . "@" . ldap_escape($userdomain, '', LDAP_ESCAPE_DN); foreach ($binddomains as $binddomain) { $binduserstrings[] = $loginfield . "=" . $ldap_username . "," . $binddomain; $binduserstrings[] = "cn=" . $ldap_username . "," . $binddomain; } } else { foreach ($binddomains as $binddomain) { $binduserstrings[] = $loginfield . "=" . str_replace("@" . $userdomain,"",$ldap_username) . "," . $binddomain; $binduserstrings[] = "cn=" . str_replace("@" . $userdomain,"",$ldap_username) . "," . $binddomain; } } // Try binding with each $login = false; foreach (array_unique($binduserstrings) as $binduserstring) { debug("LDAP - Attempting to bind to LDAP server as : " . $binduserstring); $GLOBALS["use_error_exception"] = true; try { $login = ldap_bind($ds, $binduserstring, $password); debug("LDAP bind success"); break; } catch (Exception $e) { $message = $e->getMessage(); debug("LDAP ERROR: LDAP bind failed " . $message); if (strpos($message, "Can't contact") !== false) { // Server is not accesssible, no point in trying different bind formats return false; } } unset($GLOBALS["use_error_exception"]); } if (!$login) { debug("LDAP - failed to bind to LDAP server"); return false; } // Search $ldapgroupfield = $simpleldap['ldapgroupfield']; $attributes = array("displayname",$ldapgroupfield,$email_attribute,$phone_attribute); if (strpos($ldap_username, "@" . $userdomain) !== false) { // Remove domain suffix for search $ldap_username = str_replace("@" . $userdomain,"",$ldap_username); } $filter = "(&(objectClass=person)(". $loginfield . "=" . ldap_escape($ldap_username,'',LDAP_ESCAPE_FILTER) . "))"; debug("LDAP - performing search: filter=" . $filter); debug("LDAP - retrieving attributes: " . implode(",",$attributes)); $foundmatch = false; foreach ($searchdns as $searchdn) { debug("LDAP - preparing search DN: " . $searchdn); $ldapresult = ldap_search($ds, $searchdn, $filter, $attributes); if ($ldapresult) { $resultcount = ldap_count_entries($ds,$ldapresult); debug("LDAP - found " . $resultcount . " entries"); if ($resultcount > 0) { $foundmatch = true; break; } } } if (!$foundmatch) { debug("LDAP - search returned no values"); return false; } $entries = ldap_get_entries($ds, $ldapresult); if ($entries["count"] > 0) { debug("LDAP - search returned values"); if (isset($entries[0]['displayname']) && count($entries[0]['displayname']) > 0) { $displayname = simpleldap_to_utf8($entries[0]['displayname'][0]); } else { $displayname = ''; } $department = ''; debug("LDAP - checking for group attribute - " . $ldapgroupfield); $usermemberof=array(); if (isset($entries[0][$ldapgroupfield]) && count($entries[0][$ldapgroupfield]) > 0) { debug("LDAP - found group attribute - checking against configured mappings"); $usermemberofgroups=$entries[0][$ldapgroupfield]; $deptresult = ps_query('SELECT ldapgroup, rsgroup FROM simpleldap_groupmap ORDER BY priority ASC'); // Go through each configured ldap->RS group mapping, adding each to the array of groups that user is a member of. Update $department with each match so we end up with the highest priority dept foreach ($deptresult as $thedeptresult) { $deptname = $thedeptresult['ldapgroup']; $deptmap = $thedeptresult['rsgroup']; $knowndept[strtolower($deptname)] = $deptmap; if ( (isset($deptmap) && !empty($deptmap)) && in_array(strtolower($deptname), array_map('strtolower', $usermemberofgroups)) ) { $department=$deptname; $usermemberof[]=$deptname; } } // Go through all mappings and add any unknown groups to the list of mappings so that it can be easily used (LDAP group names can be hard to remember) foreach ($usermemberofgroups as $usermemberofgroup) { if ( !isset($knowndept[strtolower($usermemberofgroup)]) // This group is not in the current list && !is_numeric($usermemberofgroup) ) { // Ignore numbers; some ldap servers return a result count as the first value $newdept = simpleldap_to_utf8($usermemberofgroup); $usermemberof[]=$newdept; ps_query("REPLACE INTO simpleldap_groupmap (ldapgroup, rsgroup) VALUES (?, NULL)", ['s', $newdept]); } } } // Extract email info if (isset($entries[0][$email_attribute]) && count($entries[0][$email_attribute]) > 0) { $email = simpleldap_to_utf8($entries[0][$email_attribute][0]); } elseif (strpos($username, "@" . $simpleldap['emailsuffix']) === false) { $email = $username . '@' . $simpleldap['emailsuffix']; } else { $email = $username; } // Extract phone info if (isset($entries[0][$phone_attribute]) && count($entries[0][$phone_attribute]) > 0) { $phone = simpleldap_to_utf8($entries[0][$phone_attribute][0]); } else { $phone = $GLOBALS["lang"]['unknown']; } $return['domain'] = $userdomain; $return['username'] = $username; $return['binduser'] = $binduserstring; $return['displayname'] = $displayname; $return['group'] = $department; $return['email'] = $email; $return['phone'] = $phone; $return['memberof'] = $usermemberof; } else { $return = false; } ldap_unbind($ds); return $return; } /** * Helper function to convert received data from LDAP server to UTF-8 * * @param string $str String to convert to UTF8 * * @return string */ function simpleldap_to_utf8($str) { global $simpleldap; if (!is_string($str) || !isset($simpleldap['ldap_encoding']) || trim($simpleldap['ldap_encoding']) == "") { return $str; } $converted_str = iconv($simpleldap['ldap_encoding'], "UTF-8", $str); return $converted_str !== false ? $converted_str : $str; }