function LdapServerTest::search in Lightweight Directory Access Protocol (LDAP) 8.2
Same name and namespace in other branches
- 7.2 ldap_test/LdapServerTest.class.php \LdapServerTest::search()
- 7 ldap_servers/tests/LdapServerTest.class.php \LdapServerTest::search()
Perform an LDAP search.
Parameters
string $filter: The search filter. such as sAMAccountName=jbarclay
string $basedn: The search base. If NULL, we use $this->basedn
array $attributes: List of desired attributes. If omitted, we only return "dn".
Return value
An array of matching entries->attributes, or FALSE if the search is empty.
Overrides LdapServer::search
File
- ldap_test/
LdapServerTest.class.php, line 140 - Simpletest ldapServer class for testing without an actual ldap server
Class
Code
function search($base_dn = NULL, $filter, $attributes = array(), $attrsonly = 0, $sizelimit = 0, $timelimit = 0, $deref = LDAP_DEREF_NEVER, $scope = LDAP_SCOPE_SUBTREE) {
// debug("ldap test server search base_dn=$base_dn, filter=$filter");
$lcase_attribute = array();
foreach ($attributes as $i => $attribute_name) {
$lcase_attribute[] = drupal_strtolower($attribute_name);
}
$attributes = $lcase_attribute;
$filter = trim(str_replace(array(
"\n",
" ",
), array(
'',
'',
), $filter));
// for test matching simplicity remove line breaks and tab spacing
if ($base_dn == NULL) {
if (count($this->basedn) == 1) {
$base_dn = $this->basedn[0];
}
else {
// debug("fail basedn: ldap test server search base_dn=$base_dn, filter=$filter");
return FALSE;
}
}
/**
* Search CASE 1: for some mock ldap servers, a set of fixed ldap filters
* are prepolulated in test data
*/
if (isset($this->searchResults[$filter][$base_dn])) {
// debug("case1 filter= $filter base_dn=$base_dn ");
$results = $this->searchResults[$filter][$base_dn];
foreach ($results as $i => $entry) {
if (is_array($entry) && isset($entry['FULLENTRY'])) {
unset($results[$i]['FULLENTRY']);
$dn = $results[$i]['dn'];
$results[$i] = $this->entries[$dn];
$results[$i]['dn'] = $dn;
}
}
// debug($results);
return $results;
}
/**
* Search CASE 2: attempt to programmatically evaluate ldap filter
* by looping through fake ldap entries
*/
$base_dn = drupal_strtolower($base_dn);
$filter = trim($filter, "()");
$subqueries = array();
$operand = FALSE;
if (strpos($filter, '&') === 0) {
// debug('2.A.');
/**
* case 2.A.: filter of form (&(<attribute>=<value>)(<attribute>=<value>)(<attribute>=<value>))
* such as (&(samaccountname=hpotter)(samaccountname=hpotter)(samaccountname=hpotter))
*/
$operand = '&';
$filter = substr($filter, 1);
$filter = trim($filter, "()");
$parts = explode(')(', $filter);
foreach ($parts as $i => $pair) {
$subqueries[] = explode('=', $pair);
}
}
elseif (strpos($filter, '|') === 0) {
//debug('2.B.');
/**
* case 2.B: filter of form (|(<attribute>=<value>)(<attribute>=<value>)(<attribute>=<value>))
* such as (|(samaccountname=hpotter)(samaccountname=hpotter)(samaccountname=hpotter))
*/
$operand = '|';
$filter = substr($filter, 1);
$filter = trim($filter, "()");
$parts = explode(')(', $filter);
$parts = explode(')(', $filter);
foreach ($parts as $i => $pair) {
$subqueries[] = explode('=', $pair);
}
// debug("operand=$operand, filter=$filter subqueries"); debug($subqueries);
// debug($this->entries['cn=hpotter,ou=people,dc=hogwarts,dc=edu']);
// debug($this->entries['cn=clone0,ou=people,dc=hogwarts,dc=edu']);
}
elseif (count(explode('=', $filter)) == 2) {
// debug('2.C.');
/**
* case 2.C.: filter of form (<attribute>=<value>)
* such as (samaccountname=hpotter)
*/
$operand = '|';
$subqueries[] = explode('=', $filter);
}
else {
// debug('no case');
return FALSE;
}
// need to perform feaux ldap search here with data in
$results = array();
if ($operand == '|') {
foreach ($subqueries as $i => $subquery) {
$filter_attribute = drupal_strtolower($subquery[0]);
$filter_value = $subquery[1];
// debug("filter_attribute=$filter_attribute, filter_value=$filter_value");
foreach ($this->entries as $dn => $entry) {
$dn_lcase = drupal_strtolower($dn);
// if not in basedn, skip
// eg. basedn ou=campus accounts,dc=ad,dc=myuniversity,dc=edu
// should be leftmost string in:
// cn=jdoe,ou=campus accounts,dc=ad,dc=myuniversity,dc=edu
//$pos = strpos($dn_lcase, $base_dn);
$substring = strrev(substr(strrev($dn_lcase), 0, strlen($base_dn)));
$cascmp = strcasecmp($base_dn, $substring);
//debug("dn_lcase=$dn_lcase, base_dn=$base_dn,pos=$pos,substring=$substring,cascmp=$cascmp");
if ($cascmp !== 0) {
continue;
// not in basedn
}
// if doesn't filter attribute has no data, continue
$attr_value_to_compare = FALSE;
foreach ($entry as $attr_name => $attr_value) {
if (drupal_strtolower($attr_name) == $filter_attribute) {
$attr_value_to_compare = $attr_value;
break;
}
}
// debug("filter value=$filter_value, attr_value_to_compare="); debug($attr_value_to_compare);
if (!$attr_value_to_compare || drupal_strtolower($attr_value_to_compare[0]) != $filter_value) {
continue;
}
// match!
// debug("match"); debug($attr_value); debug($attributes);
$entry['dn'] = $dn;
if ($attributes) {
$selected_data = array();
foreach ($attributes as $i => $attr_name) {
$selected_data[$attr_name] = isset($entry[$attr_name]) ? $entry[$attr_name] : NULL;
}
$results[] = $selected_data;
}
else {
$results[] = $entry;
}
}
}
}
elseif ($operand == '&') {
// reverse the loops
foreach ($this->entries as $dn => $entry) {
$dn_lcase = drupal_strtolower($dn);
$match = TRUE;
// until 1 subquery fails
foreach ($subqueries as $i => $subquery) {
$filter_attribute = drupal_strtolower($subquery[0]);
$filter_value = $subquery[1];
$substring = strrev(substr(strrev($dn_lcase), 0, strlen($base_dn)));
$cascmp = strcasecmp($base_dn, $substring);
//debug("dn_lcase=$dn_lcase, base_dn=$base_dn,pos=$pos,substring=$substring,cascmp=$cascmp");
if ($cascmp !== 0) {
$match = FALSE;
break;
// not in basedn
}
// if doesn't filter attribute has no data, continue
$attr_value_to_compare = FALSE;
foreach ($entry as $attr_name => $attr_value) {
if (drupal_strtolower($attr_name) == $filter_attribute) {
$attr_value_to_compare = $attr_value;
break;
}
}
// debug("filter value=$filter_value, attr_value_to_compare="); debug($attr_value_to_compare);
if (!$attr_value_to_compare || drupal_strtolower($attr_value_to_compare[0]) != $filter_value) {
$match = FALSE;
break;
// not in basedn
}
}
if ($match === TRUE) {
$entry['dn'] = $dn;
if ($attributes) {
$selected_data = array();
foreach ($attributes as $i => $attr_name) {
$selected_data[$attr_name] = isset($entry[$attr_name]) ? $entry[$attr_name] : NULL;
}
$results[] = $selected_data;
}
else {
$results[] = $entry;
}
}
}
}
$results['count'] = count($results);
// debug("ldap test server search results"); debug($results);
return $results;
}