protected function loadPage() { if (!ldap_control_paged_result($this->connection, $this->pageSize, true, $this->pageToken)) { throw new SearchException("Unable to set paged control pageSize: " . $this->pageSize); } $search = ldap_search($this->connection, $this->baseDn, $this->filter, is_array($this->attributes) ? $this->attributes : []); if (!$search) { // Something went wrong in search throw Connection::createLdapSearchException(ldap_errno($this->connection), $this->baseDn, $this->filter, $this->pageSize); } $this->entries = ldap_get_entries($this->connection, $search); $this->entriesPosition = 0; if (!$this->entries) { throw Connection::createLdapSearchException(ldap_errno($this->connection), $this->baseDn, $this->filter, $this->pageSize); } // check if on first page if (empty($this->pageToken)) { $this->currentPage = 0; } else { $this->currentPage++; } // Ok go to next page ldap_control_paged_result_response($this->connection, $search, $this->pageToken); if (empty($this->pageToken)) { $this->isLastPage = true; } }
/** * @param LDAP $link * @param LDAP $result * @param string $cookie * @return bool|LDAP */ public function controlPagedResultResponse($link, $result, &$cookie) { $this->preFunctionCall('ldap_control_paged_result_response', array($link, $result, $cookie)); $result = ldap_control_paged_result_response($link, $result, $cookie); $this->postFunctionCall(); return $result; }
/** * @param int $estimated * @return string * @throws PaginationFailureException */ public function controlPagedResult(&$estimated = null) { if (!ldap_control_paged_result_response($this->link, $this->result, $cookie, $estimated)) { throw new PaginationFailureException(ldap_error($this->link), ldap_errno($this->link)); } return $cookie; }
public function getAvailableValues() { if (!empty($this->fields['values'])) { $ldap_values = json_decode($this->fields['values']); $ldap_dropdown = new RuleRightParameter(); if (!$ldap_dropdown->getFromDB($ldap_values->ldap_attribute)) { return array(); } $attribute = array($ldap_dropdown->fields['value']); $config_ldap = new AuthLDAP(); if (!$config_ldap->getFromDB($ldap_values->ldap_auth)) { return array(); } if (!function_exists('warning_handler')) { function warning_handler($errno, $errstr, $errfile, $errline, array $errcontext) { if (0 === error_reporting()) { return false; } throw new ErrorException($errstr, 0, $errno, $errfile, $errline); } } set_error_handler("warning_handler", E_WARNING); try { $tab_values = array(); $ds = $config_ldap->connect(); ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3); $cookie = ''; do { if (AuthLDAP::isLdapPageSizeAvailable($config_ldap)) { ldap_control_paged_result($ds, $config_ldap->fields['pagesize'], true, $cookie); } $result = ldap_search($ds, $config_ldap->fields['basedn'], $ldap_values->ldap_filter, $attribute); $entries = ldap_get_entries($ds, $result); array_shift($entries); foreach ($entries as $id => $attr) { if (isset($attr[$attribute[0]]) && !in_array($attr[$attribute[0]][0], $tab_values)) { $tab_values[$id] = $attr[$attribute[0]][0]; } } if (AuthLDAP::isLdapPageSizeAvailable($config_ldap)) { ldap_control_paged_result_response($ds, $result, $cookie); } } while ($cookie !== null && $cookie != ''); if ($this->fields['show_empty']) { $tab_values = array('' => '-----') + $tab_values; } asort($tab_values); return $tab_values; } catch (Exception $e) { return array(); } restore_error_handler(); } else { return array(); } }
/** * Retrieve the LDAP pagination cookie * * @param string $key Optionally return only one of the keys: 'cookie' or 'estimated' * @return array|mixed Array with two keys: 'cookie' and 'estimated' or, if `$key` was * specified, returns the value of only that key */ public function pagedResultResponse($key = null) { $cookie = null; $estimated = null; @ldap_control_paged_result_response($this->link, $this->resource, $cookie, $estimated); switch ($key) { case 'cookie': return $cookie; case 'estimated': return $estimated; default: return ['cookie' => $cookie, 'estimated' => $estimated]; } }
public function __construct(Ldap $link, $result = null) { $this->result = $result; if (is_resource($result)) { // Get the status code, matched DN and referrals from the response ldap_parse_result($link->resource(), $result, $this->code, $this->matchedDN, $this->message, $this->referrals); // Get the string representation of the status code $this->message = ldap_err2str($this->code); // Extract the data from the resource $this->data = ldap_get_entries($link->resource(), $result); $this->data = $this->cleanup_result($this->data); // Remove the referrals array if there's nothing inside count($this->referrals) == 0 && ($this->referrals = null); // Try to extract pagination cookie and estimated number of objects to be returned // Since there's no way to tell if pagination has been enabled or not, I am suppressing php errors @ldap_control_paged_result_response($link->resource(), $result, $this->cookie, $this->estimated); } else { $this->code = ldap_errno($link->resource()); $this->message = ldap_error($link->resource()); } // Active Directory conceals some additional error codes in the ErrorMessage of the response // that we cannot get to with ldap_errno() in authentication failures - let's try to // extract them! if ($this->code == 49) { $message = null; ldap_get_option($link->resource(), Option::ErrorString, $message); if (stripos($message, 'AcceptSecurityContext') !== false) { $message = explode(', ', $message); end($message); $message = prev($message); $this->code = explode(' ', $message)[1]; // For compatibility reasons with standard ldap, if the error code // is 52e let's replace it with 49 ( their meanings are equal, it's just // Microsoft doing it its own way again ) if ($this->code == '52e') { $this->code = ResponseCode::InvalidCredentials; } } } }
/** * Search LDAP registry for entries matching filter and optional attributes * and return ALL values, including those beyond the usual 1000 entries, as an array. * * @param string $filter * @param array $attributes -OPTIONAL * @return array * @throws Exception\LdapException */ public function searchAll($filter, array $attributes = []) { $ldap = $this->getResource(); // $ds is a valid link identifier (see ldap_connect) ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3); $cookie = ''; $result = []; do { ldap_control_paged_result($ldap, self::PAGE_SIZE, true, $cookie); Stdlib\ErrorHandler::start(E_WARNING); $search = ldap_search($ldap, $this->getBaseDn(), $filter, $attributes); Stdlib\ErrorHandler::stop(); if ($search === false) { throw new Lp\Exception\LdapException($this, 'searching: ' . $filter); } $entries = $this->createCollection(new Lp\Collection\DefaultIterator($this, $search), null); foreach ($entries as $es) { $result[] = $es; } ldap_control_paged_result_response($ldap, $search, $cookie); } while ($cookie !== null && $cookie != ''); return $result; }
/** * Searches LDAP * * @author [A. Gianotto] [<*****@*****.**>] * @since [v3.0] * @param $ldapatttibutes * @return array|bool */ static function findLdapUsers() { $ldapconn = Ldap::connectToLdap(); $ldap_bind = Ldap::bindAdminToLdap($ldapconn); $base_dn = Setting::getSettings()->ldap_basedn; $filter = Setting::getSettings()->ldap_filter; // Set up LDAP pagination for very large databases // @author Richard Hofman $page_size = 500; $cookie = ''; $result_set = array(); $global_count = 0; // Perform the search do { // Paginate (non-critical, if not supported by server) ldap_control_paged_result($ldapconn, $page_size, false, $cookie); $search_results = ldap_search($ldapconn, $base_dn, '(' . $filter . ')'); if (!$search_results) { return redirect()->route('users')->with('error', trans('admin/users/message.error.ldap_could_not_search') . ldap_error($ldapconn)); } // Get results from page $results = ldap_get_entries($ldapconn, $search_results); if (!$results) { return redirect()->route('users')->with('error', trans('admin/users/message.error.ldap_could_not_get_entries') . ldap_error($ldapconn)); } // Add results to result set $global_count += $results['count']; $result_set = array_merge($result_set, $results); ldap_control_paged_result_response($ldapconn, $search_results, $cookie); } while ($cookie !== null && $cookie != ''); // Clean up after search $result_set['count'] = $global_count; $results = $result_set; ldap_control_paged_result($ldapconn, 0); return $results; }
/** * Wrapper function for ldap_control_paged_result_response(). * * @param resource $link * An LDAP link identifier. * @param resouce $result * An LDAP search result identifier. * @param string $cookie * An opaque structure sent by the server. * @param int $estimated * The estimated number of entries to retrieve. * * @return boolean * TRUE on success. * * @throw SimpleLdapException */ public static function ldap_control_paged_result_response($link, $result, &$cookie = NULL, &$estimated = NULL) { // Devel debugging. if (variable_get('simple_ldap_devel', FALSE)) { dpm(__FUNCTION__); dpm(array('$result' => $result, '$cookie' => $cookie, '$estimated' => $estimated)); } // Wrapped function call. $return = @ldap_control_paged_result_response($link, $result, $cookie, $estimated); // Debugging. if (variable_get('simple_ldap_debug', FALSE)) { $message = __FUNCTION__ . '($link = @link, $result = @result, $cookie = @cookie, $estimated = @estimated) returns @return'; $variables = array('@link' => print_r($link, TRUE), '@result' => print_r($result, TRUE), '@cookie' => print_r($cookie, TRUE), '@estimated' => print_r($estimated, TRUE), '@return' => print_r($return, TRUE)); watchdog('simple_ldap', $message, $variables, WATCHDOG_DEBUG); } return $return; }
/** * Retrieve a paginated result response. * * @param resource $result * @paaram string $cookie * * @return bool * * @throws AdldapException */ public function controlPagedResultResponse($result, &$cookie) { if ($this->isPagingSupported()) { if ($this->suppressErrors) { return @ldap_control_paged_result_response($this->getConnection(), $result, $cookie); } return ldap_control_paged_result_response($this->getConnection(), $result, $cookie); } $message = 'LDAP Pagination is not supported on your current PHP installation.'; throw new AdldapException($message); }
/** * @since version 0.84 new parameter $limitexceeded * * @param $ldap_connection * @param $config_ldap * @param $filter * @param $search_in_groups (true by default) * @param $groups array * @param $limitexceeded **/ static function getGroupsFromLDAP($ldap_connection, $config_ldap, $filter, $search_in_groups = true, $groups = array(), &$limitexceeded) { global $DB; //First look for groups in group objects $extra_attribute = $search_in_groups ? "cn" : $config_ldap->fields["group_field"]; $attrs = array("dn", $extra_attribute); if ($filter == '') { if ($search_in_groups) { $filter = !empty($config_ldap->fields['group_condition']) ? $config_ldap->fields['group_condition'] : "(objectclass=*)"; } else { $filter = !empty($config_ldap->fields['condition']) ? $config_ldap->fields['condition'] : "(objectclass=*)"; } } $cookie = ''; $count = 0; do { if (self::isLdapPageSizeAvailable($config_ldap)) { ldap_control_paged_result($ldap_connection, $config_ldap->fields['pagesize'], true, $cookie); } $filter = Toolbox::unclean_cross_side_scripting_deep($filter); $sr = @ldap_search($ldap_connection, $config_ldap->fields['basedn'], $filter, $attrs); if ($sr) { if (in_array(ldap_errno($ldap_connection), array(4, 11))) { // openldap return 4 for Size limit exceeded $limitexceeded = true; } $infos = self::get_entries_clean($ldap_connection, $sr); if (in_array(ldap_errno($ldap_connection), array(4, 11))) { // openldap return 4 for Size limit exceeded $limitexceeded = true; } $count += $infos['count']; //If page results are enabled and the number of results is greater than the maximum allowed //warn user that limit is exceeded and stop search if (self::isLdapPageSizeAvailable($config_ldap) && $config_ldap->fields['ldap_maxlimit'] && $count > $config_ldap->fields['ldap_maxlimit']) { $limitexceeded = true; break; } for ($ligne = 0; $ligne < $infos["count"]; $ligne++) { if ($search_in_groups) { // No cn : not a real object if (isset($infos[$ligne]["cn"][0])) { $cn = $infos[$ligne]["cn"][0]; $groups[$infos[$ligne]["dn"]] = array("cn" => $infos[$ligne]["cn"][0], "search_type" => "groups"); } } else { if (isset($infos[$ligne][$extra_attribute])) { if ($config_ldap->fields["group_field"] == 'dn' || in_array('ou', $groups)) { $dn = $infos[$ligne][$extra_attribute]; $ou = array(); for ($tmp = $dn; count($tmptab = explode(',', $tmp, 2)) == 2; $tmp = $tmptab[1]) { $ou[] = $tmptab[1]; } /// Search in DB for group with ldap_group_dn if ($config_ldap->fields["group_field"] == 'dn' && count($ou) > 0) { $query = "SELECT `ldap_value`\n FROM `glpi_groups`\n WHERE `ldap_group_dn`\n IN ('" . implode("', '", Toolbox::addslashes_deep($ou)) . "')"; foreach ($DB->request($query) as $group) { $groups[$group['ldap_value']] = array("cn" => $group['ldap_value'], "search_type" => "users"); } } } else { for ($ligne_extra = 0; $ligne_extra < $infos[$ligne][$extra_attribute]["count"]; $ligne_extra++) { $groups[$infos[$ligne][$extra_attribute][$ligne_extra]] = array("cn" => self::getGroupCNByDn($ldap_connection, $infos[$ligne][$extra_attribute][$ligne_extra]), "search_type" => "users"); } } } } } } if (self::isLdapPageSizeAvailable($config_ldap)) { ldap_control_paged_result_response($ldap_connection, $sr, $cookie); } } while ($cookie !== null && $cookie != ''); return $groups; }
public function searchRaw($search = "*") { if (!$this->adldap->getLdapBind()) { return false; } // Perform the search and grab all their details $filter = "(&(objectClass=user)(samaccounttype=" . adLDAP::ADLDAP_NORMAL_ACCOUNT . ")(objectCategory=person)(cn=" . $search . "))"; $fields = array("samaccountname", "displayname"); $pageSize = 25; $cookie = ''; ldap_control_paged_result($this->adldap->getLdapConnection(), $pageSize, true, $cookie); $sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields); $entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr); ldap_control_paged_result_response($this->adldap->getLdapConnection(), $sr, $cookie); $return = []; foreach ($entries as $k => $r) { $comp = explode(",", $r['dn']); $cn = ''; $ou = ''; $dc = ''; foreach ($comp as $c) { $x = explode("=", "{$c}"); switch ($x[0]) { case 'CN': $cn = $x[1]; break; case 'OU': $ou = $x[1]; break; case 'DC': $dc .= $x[1] . "."; break; } } if (count($r['samaccountname']) == 0) { continue; } $return[] = ['fullname' => isset($r['displayname']) ? @$r['displayname'][0] : @$r['samaccountname'][0], 'username' => @$r['samaccountname'][0], 'cn' => $cn, 'dc' => $dc, 'ou' => $ou]; } return $return; }
public function ldap() { set_time_limit(0); //$this->db->query("truncate px_tmp"); $host = "192.168.5.3"; $user = "******"; $pswd = "zldc@8888"; $cookie = ''; $result = []; $result['count'] = 0; do { $ad = ldap_connect($host) or die("Could not connect!"); //var_dump($ad); if ($ad) { //璁剧疆鍙傛暟 ldap_set_option($ad, LDAP_OPT_PROTOCOL_VERSION, 3); ldap_set_option($ad, LDAP_OPT_REFERRALS, 0); // bool ldap_bind ( resource $link_identifier [, string $bind_rdn = NULL [, string $bind_password = NULL ]] ) $bd = ldap_bind($ad, $user, $pswd) or die("Could not bind"); ldap_control_paged_result($ad, 500, true, $cookie); $attrs = array("displayname", "name", "sAMAccountName", "userPrincipalName", "objectclass"); //鎸囧畾闇�鏌ヨ鐨勭敤鎴疯寖鍥� $filter = "(objectclass=*)"; //ldap_search ( resource $link_identifier , string $base_dn , string $filter [, array $attributes [, int $attrsonly [, int $sizelimit [, int $timelimit [, int $deref ]]]]] ) $search = ldap_search($ad, 'ou=中梁集团,DC=zldcgroup,DC=com', $filter, $attrs, 0, 0, 0) or die("ldap search failed"); $entries = ldap_get_entries($ad, $search); ldap_set_option($ad, LDAP_OPT_PROTOCOL_VERSION, 3); $result = array_merge($result, $entries); ldap_control_paged_result_response($ad, $search, $cookie); //echo json_encode($entries); // var_dump($entries); $data = array(); if ($entries["count"] > 0) { //echo '返回记录数:'.$entries["count"]; for ($i = 0; $i < $entries["count"]; $i++) { //所要获取的字段,都必须小写 //if(isset($entries[$i]["displayname"])){ // echo "<p>name: ".$entries[$i]["name"][0]."<br />";//用户名 // echo "<p>sAMAccountName: ".@$entries[$i]["samaccountname"][0]."<br />";//用户名 if (isset($entries[$i]["dn"][0])) { // echo "dn: ".$entries[$i]["dn"]."<br />";//用户名字 $is_user = in_array('user', $entries[$i]["objectclass"]) ? 1 : 0; if ($is_user == 0) { continue; } $dn = $entries[$i]["dn"]; $dn = explode(",", $dn); $area = array(); foreach ($dn as $v) { if (strpos($v, 'OU=') !== false) { array_push($area, str_replace("OU=", "", $v)); //有的抬头不是OU } else { if (strpos($v, 'CN=') !== false) { array_push($area, str_replace("CN=", "", $v)); //有的抬头不是CN } else { if (strpos($v, 'DC=') !== false) { array_push($area, str_replace("DC=", "", $v)); //有的抬头不是DC } } } } $area = array_reverse($area); $insertArr = array(); $flag = 1; if (is_array($area)) { $flag = count($area, COUNT_NORMAL); } // var_dump($area); // list($f6,$f5,$f4,$f3,$f2,$f1) = $area; foreach ($area as $val) { $keyStr = 'F' . $flag; $flag--; $insertArr[$keyStr] = $val; } $insertArr['FISUSER'] = 1; $insertArr['FNUMBER'] = $entries[$i]["samaccountname"][0]; $insertArr['FNAME'] = $entries[$i]["name"][0]; $insertArr['FORG'] = 'test'; if (is_array($area)) { if (count($area, COUNT_NORMAL) >= 7) { //echo "test 5 "; } } $where = 'FNUMBER = ' . $entries[$i]["samaccountname"][0]; $tableName = 'T_USER'; $this->db->select('*'); $this->db->where('FNUMBER', $entries[$i]["samaccountname"][0]); $row = $this->db->get('T_USER')->row_array(); if (isset($row)) { $result = $this->Tools->updateDataWithFID($insertArr, $tableName, $row['FID']); } else { $result = $this->Tools->addData($insertArr, $tableName); } } } //} } else { //echo "<p>No results found!</p>"; } } } while ($cookie !== null && $cookie != ''); return $result; }
/** * Group Information. Returns an array of information about a group. * The group name is case sensitive * * @param string $group_name The group name to retrieve info about * @param array $fields Fields to retrieve * @return array */ public function group_info($group_name, $fields = NULL) { if ($group_name === NULL) { return false; } if (!$this->_bind) { return false; } if (stristr($group_name, '+')) { $group_name = stripslashes($group_name); } $filter = "(&(objectCategory=group)(name=" . $this->ldap_slashes($group_name) . "))"; //echo ($filter."!!!<br>"); if ($fields === NULL) { $fields = array("member", "memberof", "cn", "description", "distinguishedname", "objectcategory", "samaccountname"); } // Let's use paging if available if (function_exists('ldap_control_paged_result')) { $pageSize = 500; $cookie = ''; $entries = array(); $entries_page = array(); do { ldap_control_paged_result($this->_conn, $pageSize, true, $cookie); $sr = ldap_search($this->_conn, $this->_base_dn, $filter, $fields); $entries_page = ldap_get_entries($this->_conn, $sr); if (!is_array($entries_page)) { return false; } $entries = array_merge($entries, $entries_page); ldap_control_paged_result_response($this->_conn, $sr, $cookie); } while ($cookie !== null && $cookie != ''); $entries['count'] = count($entries) - 1; // Set a new count value !important! ldap_control_paged_result($this->_conn, $pageSize, true, $cookie); // RESET is important } else { // Non-Paged version $sr = ldap_search($this->_conn, $this->_base_dn, $filter, $fields); $entries = ldap_get_entries($this->_conn, $sr); } //print_r($entries); return $entries; }
/** * @brief executes an LDAP search * @param $filter the LDAP filter for the search * @param $base the LDAP subtree that shall be searched * @param $attr optional, when a certain attribute shall be filtered out * @returns array with the search result * * Executes an LDAP search */ private function search($filter, $base, $attr = null, $limit = null, $offset = null, $skipHandling = false) { if (!is_null($attr) && !is_array($attr)) { $attr = array(mb_strtolower($attr, 'UTF-8')); } // See if we have a resource, in case not cancel with message $link_resource = $this->connection->getConnectionResource(); if (!is_resource($link_resource)) { // Seems like we didn't find any resource. // Return an empty array just like before. \OCP\Util::writeLog('user_ldap', 'Could not search, because resource is missing.', \OCP\Util::DEBUG); return array(); } //check wether paged search should be attempted $pagedSearchOK = $this->initPagedSearch($filter, $base, $attr, $limit, $offset); $sr = ldap_search($link_resource, $base, $filter, $attr); if (!$sr) { \OCP\Util::writeLog('user_ldap', 'Error when searching: ' . ldap_error($link_resource) . ' code ' . ldap_errno($link_resource), \OCP\Util::ERROR); \OCP\Util::writeLog('user_ldap', 'Attempt for Paging? ' . print_r($pagedSearchOK, true), \OCP\Util::ERROR); return array(); } $findings = ldap_get_entries($link_resource, $sr); if ($pagedSearchOK) { \OCP\Util::writeLog('user_ldap', 'Paged search successful', \OCP\Util::INFO); ldap_control_paged_result_response($link_resource, $sr, $cookie); \OCP\Util::writeLog('user_ldap', 'Set paged search cookie ' . $cookie, \OCP\Util::INFO); $this->setPagedResultCookie($filter, $limit, $offset, $cookie); //browsing through prior pages to get the cookie for the new one if ($skipHandling) { return; } //if count is bigger, then the server does not support paged search. Instead, he did a normal search. We set a flag here, so the callee knows how to deal with it. if ($findings['count'] <= $limit) { $this->pagedSearchedSuccessful = true; } } else { \OCP\Util::writeLog('user_ldap', 'Paged search failed :(', \OCP\Util::INFO); } // if we're here, probably no connection resource is returned. // to make ownCloud behave nicely, we simply give back an empty array. if (is_null($findings)) { return array(); } if (!is_null($attr)) { $selection = array(); $multiarray = false; if (count($attr) > 1) { $multiarray = true; $i = 0; } foreach ($findings as $item) { if (!is_array($item)) { continue; } $item = \OCP\Util::mb_array_change_key_case($item, MB_CASE_LOWER, 'UTF-8'); if ($multiarray) { foreach ($attr as $key) { $key = mb_strtolower($key, 'UTF-8'); if (isset($item[$key])) { if ($key != 'dn') { $selection[$i][$key] = $this->resemblesDN($key) ? $this->sanitizeDN($item[$key][0]) : $item[$key][0]; } else { $selection[$i][$key] = $this->sanitizeDN($item[$key]); } } } $i++; } else { //tribute to case insensitivity $key = mb_strtolower($attr[0], 'UTF-8'); if (isset($item[$key])) { if ($this->resemblesDN($key)) { $selection[] = $this->sanitizeDN($item[$key]); } else { $selection[] = $item[$key]; } } } } $findings = $selection; } //we slice the findings, when //a) paged search insuccessful, though attempted //b) no paged search, but limit set if (!$this->pagedSearchedSuccessful && $pagedSearchOK || !$pagedSearchOK && !is_null($limit)) { $findings = array_slice($findings, intval($offset), $limit); } return $findings; }
/** * The core of ORM behavior for this bundle: retrieve data * from LDAP and convert results into objects. * * Options maybe: * * attributes (array): array of attribute types (strings) * * filter (LdapFilter): a filter array or a correctly formatted filter string * * max (integer): the maximum limit of entries to return * * searchDn (string): the search DN * * subentryNodes (array): parameters for the left hand side of a searchDN, useful for mining subentries. * * pageSize (integer): employ pagination and return pages of the given size * * pageCookie (opaque): The opaque stucture sent by the LDAP server to maintain pagination state. Default is empty string. * * pageCritical (boolean): if pagination employed, force paging and return no results on service which do not provide it. Default is true. * * checkOnly (boolean): Only check result existence; don't convert search results to Symfony entities. Default is false. * * @param string $entityName * @param array $options * @return array * @throws MissingSearchDnException */ public function retrieve($entityName, $options = array()) { $paging = !empty($options['pageSize']); $instanceMetadataCollection = $this->getClassMetadata($entityName); // Discern max result size $max = empty($options['max']) ? self::DEFAULT_MAX_RESULT_COUNT : $options['max']; // Employ results paging if requested with pageSize option if ($paging) { if (!isset($options['pageCritical'])) { $options['pageCritical'] = FALSE; } if (isset($options['pageCookie'])) { $this->pageCookie = $options['pageCookie']; } ldap_control_paged_result($this->client->getLdapResource(), $options['pageSize'], $options['pageCritical'], $this->pageCookie); } // Discern subentryNodes for substituing into searchDN $subentryNodes = empty($options['subentryNodes']) ? array() : $options['subentryNodes']; // Discern search DN if (isset($options['searchDn'])) { $searchDn = $options['searchDn']; } else { $searchDn = $instanceMetadataCollection->getSearchDn(); } if (empty($searchDn)) { throw new MissingSearchDnException('Could not discern search DN while searching for ' . $entityName); } // Discern LDAP filter $objectClass = $instanceMetadataCollection->getObjectClass(); if (empty($options['filter'])) { $filter = '(objectClass=' . $objectClass . ')'; } else { if (is_array($options['filter'])) { $options['filter'] = array('&' => array('objectClass' => $objectClass, $options['filter'])); $ldapFilter = new LdapFilter($options['filter']); $filter = $ldapFilter->format(); } else { if (is_a($options['filter'], LdapFilter::class)) { $options['filter']->setFilterArray(array('&' => array('objectClass' => $objectClass, $options['filter']->getFilterArray()))); $filter = $options['filter']->format(); } else { // assume pre-formatted scale/string filter value $filter = '(&(objectClass=' . $objectClass . ')' . $options['filter'] . ')'; } } } // Discern attributes to retrieve if (empty($options['attributes'])) { $attributes = array_values($instanceMetadataCollection->getMetadatas()); } else { $attributes = $options['attributes']; } // Search LDAP $searchResult = $this->doRawLdapSearch($filter, $attributes, $max, $searchDn); $entries = @ldap_get_entries($this->client->getLdapResource(), $searchResult); if (!empty($options['checkOnly']) && $options['checkOnly'] == true) { return $entries['count'] > 0; } $entities = array(); foreach ($entries as $entry) { if (is_array($entry)) { $entities[] = $this->entryToEntity($entityName, $entry); } } if ($paging) { ldap_control_paged_result_response($this->client->getLdapResource(), $searchResult, $this->pageCookie); $this->pageMore = !empty($this->pageCookie); } if ($entries['count'] == 1) { return $entities[0]; } return $entities; }
/** * Performs multiple ldap_search calls to retrieve multiple pages of entries * * @param int $pageSize Page size * @param string $baseDn Base distinguished name to look below * @param string $filter Filter for the search * @param array $attributes Names of attributes to retrieve (Default: All) * * @return SearchInterface */ protected function searchLdapPaged($pageSize, $baseDn, $filter, $attributes = null) { $cookie = ''; $allResults = new SearchPreloaded(); do { if (!ldap_control_paged_result($this->connection, $pageSize, true, $cookie)) { throw new SearchException("Unable to set paged control pageSize: " . $pageSize); } $search = ldap_search($this->connection, $baseDn, $filter, is_array($attributes) ? $attributes : array()); if (!$search) { // Something went wrong in search throw self::createLdapSearchException(ldap_errno($this->connection), $baseDn, $filter, $pageSize); } $entries = ldap_get_entries($this->connection, $search); if (!$entries) { // No entries? throw self::createLdapSearchException(ldap_errno($this->connection), $baseDn, $filter, $pageSize); } // Ok add all entries $allResults->addEntries($entries); // Ok go to next page ldap_control_paged_result_response($this->connection, $search, $cookie); } while ($cookie !== null && $cookie != ''); return $allResults; }
function QueryArray($str = '(ObjectClass=*)', $fields = false) { global $APPLICATION; if (strlen($this->arFields['BASE_DN']) <= 0) { return false; } $arBaseDNs = explode(";", $this->arFields['BASE_DN']); $info = false; $i = 0; if ($this->arFields["CONVERT_UTF8"] == "Y") { $str = $APPLICATION->ConvertCharset($str, SITE_CHARSET, "utf-8"); } foreach ($arBaseDNs as $BaseDN) { global $APPLICATION; $BaseDN = trim($BaseDN); if ($BaseDN == "") { continue; } if ($this->arFields["CONVERT_UTF8"] == "Y") { $BaseDN = $APPLICATION->ConvertCharset($BaseDN, SITE_CHARSET, "utf-8"); } $defaultMaxPageSizeAD = 1000; $pageSize = isset($this->arFields['MAX_PAGE_SIZE']) && intval($this->arFields['MAX_PAGE_SIZE'] > 0) ? intval($this->arFields['MAX_PAGE_SIZE']) : $defaultMaxPageSizeAD; $cookie = ''; do { if (CLdapUtil::isLdapPaginationAviable()) { ldap_control_paged_result($this->conn, $pageSize, false, $cookie); } if ($fields === false) { $sr = @ldap_search($this->conn, $BaseDN, $str); } else { $sr = @ldap_search($this->conn, $BaseDN, $str, $fields); } if ($sr) { $entry = ldap_first_entry($this->conn, $sr); if ($entry) { if (!is_array($info)) { $info = array(); $i = 0; } do { $attributes = ldap_get_attributes($this->conn, $entry); for ($j = 0; $j < $attributes['count']; $j++) { $values = @ldap_get_values_len($this->conn, $entry, $attributes[$j]); if ($values === false) { continue; } $bPhotoAttr = in_array($attributes[$j], self::$PHOTO_ATTRIBS); $info[$i][strtolower($attributes[$j])] = $bPhotoAttr ? $values : $this->WorkAttr($values); } if (!is_set($info[$i], 'dn')) { if ($this->arFields["CONVERT_UTF8"] == "Y") { $info[$i]['dn'] = $APPLICATION->ConvertCharset(ldap_get_dn($this->conn, $entry), "utf-8", SITE_CHARSET); } else { $info[$i]['dn'] = ldap_get_dn($this->conn, $entry); } } $i++; } while ($entry = ldap_next_entry($this->conn, $entry)); } } elseif ($sr === false) { $APPLICATION->ThrowException("LDAP_SEARCH_ERROR"); } if (CLdapUtil::isLdapPaginationAviable()) { ldap_control_paged_result_response($this->conn, $sr, $cookie); } } while ($cookie !== null && $cookie != ''); } return $info; }
/** * Retrieve a paginated result response. * @param resource $result * @param string $cookie * @return bool */ public function setControlPagedResultResponse($result, &$cookie) { return ldap_control_paged_result_response($this->resource, $result, $cookie); }
/** * Run the given LDAP query and return the resulting entries * * This utilizes paged search requests as defined in RFC 2696. * * @param LdapQuery $query The query to fetch results with * @param array $fields Request these attributes instead of the ones registered in the given query * @param int $pageSize The maximum page size, defaults to self::PAGE_SIZE * * @return array * * @throws LdapException In case an error occured while fetching the results */ protected function runPagedQuery(LdapQuery $query, array $fields = null, $pageSize = null) { if ($pageSize === null) { $pageSize = static::PAGE_SIZE; } $limit = $query->getLimit(); $offset = $query->hasOffset() ? $query->getOffset() : 0; if ($fields === null) { $fields = $query->getColumns(); } $ds = $this->getConnection(); $serverSorting = false; //$this->getCapabilities()->hasOid(LdapCapabilities::LDAP_SERVER_SORT_OID); if (!$serverSorting && $query->hasOrder() && !empty($fields)) { foreach ($query->getOrder() as $rule) { if (!in_array($rule[0], $fields, true)) { $fields[] = $rule[0]; } } } $unfoldAttribute = $query->getUnfoldAttribute(); if ($unfoldAttribute) { foreach ($query->getFilter()->listFilteredColumns() as $filterColumn) { $fieldKey = array_search($filterColumn, $fields, true); if ($fieldKey === false || is_string($fieldKey)) { $fields[] = $filterColumn; } } } $count = 0; $cookie = ''; $entries = array(); do { // Do not request the pagination control as a critical extension, as we want the // server to return results even if the paged search request cannot be satisfied ldap_control_paged_result($ds, $pageSize, false, $cookie); if ($serverSorting && $query->hasOrder()) { ldap_set_option($ds, LDAP_OPT_SERVER_CONTROLS, array(array('oid' => LdapCapabilities::LDAP_SERVER_SORT_OID, 'value' => $this->encodeSortRules($query->getOrder())))); } $results = $this->ldapSearch($query, array_values($fields), 0, $serverSorting && $limit ? $offset + $limit : 0); if ($results === false) { if (ldap_errno($ds) === self::LDAP_NO_SUCH_OBJECT) { break; } throw new LdapException('LDAP query "%s" (base %s) failed. Error: %s', (string) $query, $query->getBase() ?: $this->getDn(), ldap_error($ds)); } elseif (ldap_count_entries($ds, $results) === 0) { if (in_array(ldap_errno($ds), array(static::LDAP_SIZELIMIT_EXCEEDED, static::LDAP_ADMINLIMIT_EXCEEDED), true)) { Logger::warning('Unable to request more than %u results. Does the server allow paged search requests? (%s)', $count, ldap_error($ds)); } break; } $entry = ldap_first_entry($ds, $results); do { if ($unfoldAttribute) { $rows = $this->cleanupAttributes(ldap_get_attributes($ds, $entry), $fields, $unfoldAttribute); if (is_array($rows)) { // TODO: Register the DN the same way as a section name in the ArrayDatasource! foreach ($rows as $row) { if ($query->getFilter()->matches($row)) { $count += 1; if (!$serverSorting || $offset === 0 || $offset < $count) { $entries[] = $row; } if ($serverSorting && $limit > 0 && $limit === count($entries)) { break; } } } } else { $count += 1; if (!$serverSorting || $offset === 0 || $offset < $count) { $entries[ldap_get_dn($ds, $entry)] = $rows; } } } else { $count += 1; if (!$serverSorting || $offset === 0 || $offset < $count) { $entries[ldap_get_dn($ds, $entry)] = $this->cleanupAttributes(ldap_get_attributes($ds, $entry), $fields); } } } while ((!$serverSorting || $limit === 0 || $limit !== count($entries)) && ($entry = ldap_next_entry($ds, $entry))); if (false === @ldap_control_paged_result_response($ds, $results, $cookie)) { // If the page size is greater than or equal to the sizeLimit value, the server should ignore the // control as the request can be satisfied in a single page: https://www.ietf.org/rfc/rfc2696.txt // This applies no matter whether paged search requests are permitted or not. You're done once you // got everything you were out for. if ($serverSorting && count($entries) !== $limit) { // The server does not support pagination, but still returned a response by ignoring the // pagedResultsControl. We output a warning to indicate that the pagination control was ignored. Logger::warning('Unable to request paged LDAP results. Does the server allow paged search requests?'); } } ldap_free_result($results); } while ($cookie && (!$serverSorting || $limit === 0 || count($entries) < $limit)); if ($cookie) { // A sequence of paged search requests is abandoned by the client sending a search request containing a // pagedResultsControl with the size set to zero (0) and the cookie set to the last cookie returned by // the server: https://www.ietf.org/rfc/rfc2696.txt ldap_control_paged_result($ds, 0, false, $cookie); // Returns no entries, due to the page size ldap_search($ds, $query->getBase() ?: $this->getDn(), (string) $query); } if (!$serverSorting && $query->hasOrder()) { uasort($entries, array($query, 'compare')); if ($limit && $count > $limit) { $entries = array_splice($entries, $query->hasOffset() ? $query->getOffset() : 0, $limit); } } return $entries; }
/** * @brief search a list in ldap server * @param $ldapbasedn the base dn * @param $bindsearch the search filter * @param $entries the ldap entries to reach * @param $start the starting point * @param $num the number of entries to return * @return array|false */ public function ldapFindMultiple($ldapbasedn, $bindsearch, $entriesName, $start = null, $num = null) { if ($entriesName != null && self::ldapCreateAndBindConnection() && $ldapbasedn != null && $bindsearch != null) { if ($start == null) { $start = 0; } if ($num == null) { $num = PHP_INT_MAX; } $pageSize = isset($this->ldapParams['ldappagesize']) ? $this->ldapParams['ldappagesize'] : "20"; $cookie = ''; $entries = array(); $cpt = 0; \OC_Log::write('contacts_ldap', __METHOD__ . " - search what {$ldapbasedn}, {$bindsearch} {$pageSize}", \OC_Log::DEBUG); do { ldap_control_paged_result($this->ldapConnection, $pageSize, true, $cookie); $ldap_results = ldap_search($this->ldapConnection, $ldapbasedn, $bindsearch, $entriesName); $LdapEntries = ldap_get_entries($this->ldapConnection, $ldap_results); for ($i = 0; $i < $LdapEntries['count']; $i++) { $entries[] = $LdapEntries[$i]; } ldap_control_paged_result_response($this->ldapConnection, $ldap_results, $cookie); $cpt++; } while ($cookie !== null && $cookie != '' && $cpt < 10); $entries['count'] = count($entries); return $entries; self::ldapCloseConnection(); } return false; }
/** * @link http://php.net/manual/en/function.ldap-control-paged-result-response.php * @param $link * @param $result * @param null $cookie * @param null $estimated * @return bool */ public function controlPagedResultResponse($link, $result, &$cookie = null, &$estimated = null) { return ldap_control_paged_result_response($link, $result, $cookie, $estimated); }
/** * Returns all usernames from LDAP * * @param $filter An LDAP search filter to select desired users * @return array of LDAP user names converted to UTF-8 */ function ldap_get_userlist($filter = '*') { $fresult = array(); $ldapconnection = $this->ldap_connect(); if ($filter == '*') { $filter = '(&(' . $this->config->user_attribute . '=*)' . $this->config->objectclass . ')'; } $contexts = explode(';', $this->config->contexts); if (!empty($this->config->create_context)) { array_push($contexts, $this->config->create_context); } $ldap_cookie = ''; $ldap_pagedresults = ldap_paged_results_supported($this->config->ldap_version); foreach ($contexts as $context) { $context = trim($context); if (empty($context)) { continue; } do { if ($ldap_pagedresults) { ldap_control_paged_result($ldapconnection, $this->config->pagesize, true, $ldap_cookie); } if ($this->config->search_sub) { // Use ldap_search to find first user from subtree. $ldap_result = ldap_search($ldapconnection, $context, $filter, array($this->config->user_attribute)); } else { // Search only in this context. $ldap_result = ldap_list($ldapconnection, $context, $filter, array($this->config->user_attribute)); } if (!$ldap_result) { continue; } if ($ldap_pagedresults) { ldap_control_paged_result_response($ldapconnection, $ldap_result, $ldap_cookie); } $users = ldap_get_entries_moodle($ldapconnection, $ldap_result); // Add found users to list. for ($i = 0; $i < count($users); $i++) { $extuser = core_text::convert($users[$i][$this->config->user_attribute][0], $this->config->ldapencoding, 'utf-8'); array_push($fresult, $extuser); } unset($ldap_result); // Free mem. } while ($ldap_pagedresults && !empty($ldap_cookie)); } // If paged results were used, make sure the current connection is completely closed $this->ldap_close($ldap_pagedresults); return $fresult; }
/** * Updating the paging operation based on the result resource returned from a query. * * @param resource $result * @throws LdapConnectionException */ public function update($result) { if (!$this->isEnabled) { return; } $this->resultNumber += $this->pageSize; if (!@ldap_control_paged_result_response($this->connection->getConnection(), $result, $this->cookie)) { throw new LdapConnectionException(sprintf('Unable to set paged results response: %s', $this->connection->getLastError())); } }
/** * Return multidimensional array with details of user courses (at * least dn and idnumber). * * @param string $memberuid user idnumber (without magic quotes). * @param object role is a record from the mdl_role table. * @return array */ protected function find_ext_enrolments($memberuid, $role) { global $CFG; require_once $CFG->libdir . '/ldaplib.php'; if (empty($memberuid)) { // No "idnumber" stored for this user, so no LDAP enrolments return array(); } $ldap_contexts = trim($this->get_config('contexts_role' . $role->id)); if (empty($ldap_contexts)) { // No role contexts, so no LDAP enrolments return array(); } $extmemberuid = core_text::convert($memberuid, 'utf-8', $this->get_config('ldapencoding')); if ($this->get_config('memberattribute_isdn')) { if (!($extmemberuid = $this->ldap_find_userdn($extmemberuid))) { return array(); } } $ldap_search_pattern = ''; if ($this->get_config('nested_groups')) { $usergroups = $this->ldap_find_user_groups($extmemberuid); if (count($usergroups) > 0) { foreach ($usergroups as $group) { $ldap_search_pattern .= '(' . $this->get_config('memberattribute_role' . $role->id) . '=' . $group . ')'; } } } // Default return value $courses = array(); // Get all the fields we will want for the potential course creation // as they are light. don't get membership -- potentially a lot of data. $ldap_fields_wanted = array('dn', $this->get_config('course_idnumber')); $fullname = $this->get_config('course_fullname'); $shortname = $this->get_config('course_shortname'); $summary = $this->get_config('course_summary'); if (isset($fullname)) { array_push($ldap_fields_wanted, $fullname); } if (isset($shortname)) { array_push($ldap_fields_wanted, $shortname); } if (isset($summary)) { array_push($ldap_fields_wanted, $summary); } // Define the search pattern if (empty($ldap_search_pattern)) { $ldap_search_pattern = '(' . $this->get_config('memberattribute_role' . $role->id) . '=' . ldap_filter_addslashes($extmemberuid) . ')'; } else { $ldap_search_pattern = '(|' . $ldap_search_pattern . '(' . $this->get_config('memberattribute_role' . $role->id) . '=' . ldap_filter_addslashes($extmemberuid) . ')' . ')'; } $ldap_search_pattern = '(&' . $this->get_config('objectclass') . $ldap_search_pattern . ')'; // Get all contexts and look for first matching user $ldap_contexts = explode(';', $ldap_contexts); $ldap_pagedresults = ldap_paged_results_supported($this->get_config('ldap_version')); foreach ($ldap_contexts as $context) { $context = trim($context); if (empty($context)) { continue; } $ldap_cookie = ''; $flat_records = array(); do { if ($ldap_pagedresults) { ldap_control_paged_result($this->ldapconnection, $this->config->pagesize, true, $ldap_cookie); } if ($this->get_config('course_search_sub')) { // Use ldap_search to find first user from subtree $ldap_result = @ldap_search($this->ldapconnection, $context, $ldap_search_pattern, $ldap_fields_wanted); } else { // Search only in this context $ldap_result = @ldap_list($this->ldapconnection, $context, $ldap_search_pattern, $ldap_fields_wanted); } if (!$ldap_result) { continue; } if ($ldap_pagedresults) { ldap_control_paged_result_response($this->ldapconnection, $ldap_result, $ldap_cookie); } // Check and push results. ldap_get_entries() already // lowercases the attribute index, so there's no need to // use array_change_key_case() later. $records = ldap_get_entries($this->ldapconnection, $ldap_result); // LDAP libraries return an odd array, really. Fix it. for ($c = 0; $c < $records['count']; $c++) { array_push($flat_records, $records[$c]); } // Free some mem unset($records); } while ($ldap_pagedresults && !empty($ldap_cookie)); // If LDAP paged results were used, the current connection must be completely // closed and a new one created, to work without paged results from here on. if ($ldap_pagedresults) { $this->ldap_close(); $this->ldap_connect(); } if (count($flat_records)) { $courses = array_merge($courses, $flat_records); } } return $courses; }
/** * * @param type $baseDn * @param type $filter * @param array $attributes * @param int $pageSize * @return \Generator * @throws LdapException */ public function pagedSearch($baseDn, $filter, array $attributes = [], $pageSize = 100) { $this->checkConnection(); $resource = $this->conn->getResource(); $cookie = ''; do { ldap_control_paged_result($resource, $pageSize, true, $cookie); $search = @ldap_search($resource, $baseDn, $filter, $attributes); if ($search === false) { ErrorHandler::throwException($this->conn); } $result = @ldap_get_entries($resource, $search); if ($result === false) { ErrorHandler::throwException($this->conn); } for ($i = 0; $i < $result['count']; $i++) { $row = $result[$i]; $entry = $this->parseArray($row); (yield $entry); } ldap_control_paged_result_response($resource, $search, $cookie); } while ($cookie !== null && $cookie != ''); }
public function getUserEntries($login = null, $countOnly = false, $offset = -1, $limit = -1, $regexpOnSearchAttr = false) { if ($login == null) { $filter = $this->ldapFilter; } else { if ($regexpOnSearchAttr && !empty($this->options["LDAP_SEARCHUSER_ATTR"])) { $searchAttr = $this->options["LDAP_SEARCHUSER_ATTR"]; $searchAttrArray = explode(",", $searchAttr); } if (isset($searchAttrArray)) { if (count($searchAttrArray) > 1) { $searchAttrFilter = "(|"; foreach ($searchAttrArray as $attr) { $searchAttrFilter .= "(" . $attr . "=" . $login . ")"; } $searchAttrFilter .= ")"; } else { $searchAttrFilter = "(" . $searchAttrArray[0] . "=" . $login . ")"; } } else { $searchAttrFilter = "(" . $this->ldapUserAttr . "=" . $login . ")"; } if ($this->ldapFilter == "") { $filter = $searchAttrFilter; } else { $filter = "(&" . $this->ldapFilter . $searchAttrFilter . ")"; } } if (empty($filter)) { if (!empty($this->dynamicFilter)) { $filter = $this->dynamicFilter; } else { $filter = $this->ldapUserAttr . "=*"; } } else { if (!empty($this->dynamicFilter)) { $filter = "(&(" . $this->dynamicFilter . ")" . $filter . ")"; } } if ($this->ldapconn == null) { $this->startConnexion(); } $conn = array(); if (is_array($this->ldapDN)) { foreach ($this->ldapDN as $dn) { $conn[] = $this->ldapconn; } } else { $conn = array($this->ldapconn); } $expected = array($this->ldapUserAttr); if ($login != null && (!empty($this->customParamsMapping) || !empty($this->paramsMapping))) { if (!empty($this->customParamsMapping)) { $expected = array_merge($expected, array_keys($this->customParamsMapping)); } if (!empty($this->paramsMapping)) { $keys = array(); foreach ($this->paramsMapping as $param) { $keys[] = $param["MAPPING_LDAP_PARAM"]; } $expected = array_merge($expected, $keys); } } if (is_array($this->dynamicExpected)) { $expected = array_merge($expected, $this->dynamicExpected); } foreach ($conn as $dn => $ldapc) { if (!$ldapc) { unset($conn[$dn]); } } if (count($conn) < 1) { return array("count" => 0); } //$ret = ldap_search($conn,$this->ldapDN,$filter, $expected); $cookie = ''; if (empty($this->pageSize) || !is_numeric($this->pageSize)) { $this->pageSize = 500; } $allEntries = array("count" => 0); $isSupportPagedResult = function_exists("ldap_control_paged_result") && function_exists("ldap_control_paged_result_response"); $gotAllEntries = false; $index = 0; //Update progress bar in CLI mode $isListAll = $offset == -1 && $limit == -1 && is_null($login) && $regexpOnSearchAttr && php_sapi_name() == "cli"; if ($isListAll) { $total = $this->getCountFromCache(); $progressBar = new AJXP_ProgressBarCLI(); $progressBar->init($index, $total["count"], "Get ldap users"); } do { if ($isSupportPagedResult) { ldap_control_paged_result($this->ldapconn, $this->pageSize, false, $cookie); } $ret = ldap_search($conn, $this->ldapDN, $filter, $expected, 0, 0); if ($ret === false) { break; } foreach ($ret as $i => $resourceResult) { if ($resourceResult === false) { continue; } if ($countOnly) { $allEntries["count"] += ldap_count_entries($conn[$i], $resourceResult); continue; } if ($limit != -1) { //usort($entries, array($this, "userSortFunction")); ldap_sort($conn[$i], $resourceResult, $this->ldapUserAttr); } $entries = ldap_get_entries($conn[$i], $resourceResult); // for better performance if (is_array($entries) && $offset != -1 && $limit != -1 && $index + $this->pageSize < $offset) { $index += $this->pageSize; continue; } if (!empty($entries["count"])) { $allEntries["count"] += $entries["count"]; unset($entries["count"]); foreach ($entries as $entry) { if ($offset != -1 && $index < $offset) { $index++; continue; } // fake memberOf if ($this->fakeAttrMemberOf && method_exists($this, "fakeMemberOf") && in_array(strtolower("memberof"), array_map("strtolower", $expected))) { if ($this->attrMemberInGroup) { $uid = $entry["dn"]; } else { $uidWithEqual = explode(",", $entry["dn"]); $uidShort = explode("=", $uidWithEqual[0]); $uid = $uidShort[1]; } $strldap = "(&" . $this->ldapGFilter . "(" . $this->fakeAttrMemberOf . "=" . $uid . "))"; $this->fakeMemberOf($conn, $this->ldapGDN, $strldap, array("cn"), $entry); } $allEntries[] = $entry; $index++; //Update progress bar in CLI mode if (isset($progressBar)) { $progressBar->update($index); } if ($offset != -1 && $limit != -1 && $index > $offset + $limit) { break; } } if ($index > $offset + $limit && $limit != -1 && $offset != -1) { $gotAllEntries = true; } } } if ($isSupportPagedResult) { foreach ($ret as $element) { if (is_resource($element)) { @ldap_control_paged_result_response($this->ldapconn, $element, $cookie); } } } } while ($cookie !== null && $cookie != '' && $isSupportPagedResult && !$gotAllEntries); // reset paged_result for other activities (otherwise we will experience ldap error) if ($isSupportPagedResult) { ldap_control_paged_result($this->ldapconn, 0); } return $allEntries; }
protected function objectSearchResultCount($conn, $base_dn, $search_filter) { $base_dn = $this->prepareQueryString($base_dn); $search_filter = $this->prepareQueryString($search_filter); $resultCount = 0; $pageCookie = ""; do { if (function_exists("ldap_control_paged_result") && function_exists("ldap_control_paged_result_response")) { ldap_control_paged_result($conn, $this->ldapSearchPageSize, true, $pageCookie); } // Start search in LDAP directory. $sr = ldap_search($conn, $base_dn, $search_filter, array(), 0, 0); if (!$sr) { break; } // Get number of found results. $resultCount += ldap_count_entries($conn, $sr); if (function_exists("ldap_control_paged_result") && function_exists("ldap_control_paged_result_response")) { ldap_control_paged_result_response($conn, $sr, $pageCookie); } } while ($pageCookie !== null && $pageCookie != ""); return $resultCount; }
/** * execute a paged ldap query and return entries as one aggregated array * * $this->searchPageStart and $this->searchPageEnd should be set before calling if * a particular set of pages is desired * * @param array $ldap_query_params of form: 'base_dn' => base_dn, 'filter' => filter, 'attributes' => attributes, 'attrsonly' => attrsonly, 'sizelimit' => sizelimit, 'timelimit' => timelimit, 'deref' => deref, 'scope' => scope, (this array of parameters is primarily passed on to ldapQuery() method) * * @return array of ldap entries or FALSE on error. * */ public function pagedLdapQuery($ldap_query_params) { if (!($this->searchPagination && $this->paginationEnabled)) { watchdog('ldap', "LDAP server pagedLdapQuery() called when functionality not available in php install or\n not enabled in ldap server configuration. error. basedn: %basedn| filter: %filter| attributes:\n %attributes| errmsg: %errmsg| ldap err no: %errno|", $watchdog_tokens); return FALSE; } $paged_entries = array(); $page_token = ''; $page = 0; $estimated_entries = 0; $aggregated_entries = array(); $aggregated_entries_count = 0; $has_page_results = FALSE; do { ldap_control_paged_result($this->connection, $this->searchPageSize, TRUE, $page_token); $result = $this->ldapQuery($ldap_query_params['scope'], $ldap_query_params); if ($page >= $this->searchPageStart) { $skipped_page = FALSE; if ($result && $this->countEntries($result) !== FALSE) { $page_entries = ldap_get_entries($this->connection, $result); unset($page_entries['count']); $has_page_results = is_array($page_entries) && count($page_entries) > 0; $aggregated_entries = array_merge($aggregated_entries, $page_entries); $aggregated_entries_count = count($aggregated_entries); } elseif ($this->ldapErrorNumber()) { $watchdog_tokens = array('%basedn' => $ldap_query_params['base_dn'], '%filter' => $ldap_query_params['filter'], '%attributes' => print_r($ldap_query_params['attributes'], TRUE), '%errmsg' => $this->errorMsg('ldap'), '%errno' => $this->ldapErrorNumber()); watchdog('ldap', "LDAP ldap_search error. basedn: %basedn| filter: %filter| attributes:\n %attributes| errmsg: %errmsg| ldap err no: %errno|", $watchdog_tokens); return FALSE; } else { return FALSE; } } else { $skipped_page = TRUE; } @ldap_control_paged_result_response($this->connection, $result, $page_token, $estimated_entries); if ($ldap_query_params['sizelimit'] && $this->ldapErrorNumber() == LDAP_SIZELIMIT_EXCEEDED) { // false positive error thrown. do not set result limit error when $sizelimit specified } elseif ($this->hasError()) { watchdog('ldap_server', 'ldap_control_paged_result_response() function error. LDAP Error: %message, ldap_list() parameters: %query', array('%message' => $this->errorMsg('ldap'), '%query' => $ldap_query_params['query_display']), WATCHDOG_ERROR); } if (isset($ldap_query_params['sizelimit']) && $ldap_query_params['sizelimit'] && $aggregated_entries_count >= $ldap_query_params['sizelimit']) { $discarded_entries = array_splice($aggregated_entries, $ldap_query_params['sizelimit']); break; } elseif ($this->searchPageEnd !== NULL && $page >= $this->searchPageEnd) { // user defined pagination has run out break; } elseif ($page_token === NULL || $page_token == '') { // ldap reference pagination has run out break; } $page++; } while ($skipped_page || $has_page_results); $aggregated_entries['count'] = count($aggregated_entries); return $aggregated_entries; }
/** * Perform the lookup operation on server and return the resultset * * This method sends the lookup request to the server with the * configuration you provided. If the {@link Link} has pagination enabled, * it will return a single page. To get the subsequent pages, call this method * again on the object, without modifying the lookup criteria. * * @uses Link::$rootDSE to get the domain base dn ( from <i>defaultnamingcontext</i> ) if no override has been specified * * @return Result|false The Result object with returned Objects or FALSE if maximum number of referrals was chased */ public function run() { // Prepare the information needed for the operation $link_id = $this->adxLink->get_link(); $baseDN = $this->dn || $this->dn === '' ? $this->dn : $this->adxLink->rootDSE->defaultnamingcontext(0); if ($this->use_pages && $this->complete) { $this->cookie = ''; } // Reset the cookie if the operation is started again $this->complete = false; // Reset the completion status // Send the pagination control cookie if present // I must check explicitly for NULL bcause '' also evaluates to FALSE if ($this->cookie !== null) { ldap_control_paged_result($link_id, $this->sizelimit, true, $this->cookie); } // Perform the lookup operation // All exceptions thrown here will bubble up! $result_id = $this->_directory_lookup($this->operationType, $link_id, $baseDN, $this->filter, $this->attributes); // Get the new cookie from the response if pagination is enabled // I must check explicitly for NULL bcause '' also evaluates to FALSE if ($this->cookie !== null) { ldap_control_paged_result_response($link_id, $result_id, $this->cookie); } // Lookup operation successful - continue processing... $referral_link = $this->_parse_referrals($result_id); // Check for referrals if ($referral_link) { if ($this->referral_counter <= $this->max_referrals) { // Do we have this connection in the pool already? if (isset(static::$connection_pool[$referral_link])) { $link = static::$connection_pool[$referral_link]; // Use the existing link to perform the lookup } else { $link = $this->adxLink->_redirect($referral_link); // Reconnect to the new server static::$connection_pool[$referral_link] = $link; // Save the connection in the link pool } $this->referral_counter++; $this->adxLink = $link; // Replace the current link with the new link return $this->run(); // Only those calls that actually succeed in getting data should continue with code below } else { return false; } // Reached maximum number of referrals -> do not continue } // Successfully retrieved data from server $this->referral_counter = 0; $result = ldap_get_entries($this->adxLink->get_link(), $result_id); unset($result['count']); // Clean up some unneeded mess ( more cleanup happens at object instantiation ) $data = array(); // Create new objects from result, converting the values to php-compatible data formats on the way foreach ($result as $objectData) { // Is there a special class defined for this particular object class ( under ADX\Classes namespace )? // Use 'Object' if the objectClass attribute is either not present or there is no class override if (isset($objectData['objectclass'])) { $class = 'ADX\\Classes\\' . end($objectData['objectclass']); $class = class_exists($class) ? $class : 'ADX\\Core\\Object'; } else { $class = 'ADX\\Core\\Object'; } $data[] = new $class($this->adxLink, $objectData, true); } $this->complete = !$this->cookie; // As long as cookie is present, the result cannot be complete return new Result($data); }