The following matching rules exists:
- equals: One of the attributes values is exactly $value.
Please note that case sensitiviness depends on the
attributes syntax configured in the server.
- begins: One of the attributes values must begin with $value.
- ends: One of the attributes values must end with $value.
- contains: One of the attributes values must contain $value.
- present | any: The attribute can contain any value but must exist.
- greater: The attributes value is greater than $value.
- less: The attributes value is less than $value.
- greaterOrEqual: The attributes value is greater or equal than $value.
- lessOrEqual: The attributes value is less or equal than $value.
- approx: One of the attributes values is similar to $value.
If $escape is set to true then $value will be escaped. If set to false
then $value will be treaten as a raw filter value string. You should
then escape it yourself using {@link Horde_Ldap_Util::escapeFilterValue()}.
Examples:
This will find entries that contain an attribute "sn" that ends with
"foobar":
$filter = Horde_Ldap_Filter::create('sn', 'ends', 'foobar');
This will find entries that contain an attribute "sn" that has any
value set:
$filter = Horde_Ldap_Filter::create('sn', 'any');
public static create ( string $attribute, string $match, string $value = '', boolean $escape = true ) : Horde_Ldap_Filter | ||
$attribute | string | Name of the attribute the filter should apply to. |
$match | string | Matching rule (equals, begins, ends, contains, greater, less, greaterOrEqual, lessOrEqual, approx, any). |
$value | string | If given, then this is used as a filter value. |
$escape | boolean | Should $value be escaped? |
return | Horde_Ldap_Filter |
/** * Retrieves user preferences from the backend. * * @throws Sam_Exception */ public function retrieve() { $attrib = Horde_String::lower($this->_params['attribute']); try { $search = $this->_ldap->search($this->_params['basedn'], Horde_Ldap_Filter::create($this->_params['uid'], 'equals', $this->_user), array('attributes' => array($attrib))); $entry = $search->shiftEntry(); if (!$entry) { throw new Sam_Exception(sprintf('LDAP user "%s" not found.', $this->_user)); } foreach ($entry->getValue($attrib, 'all') as $attribute) { list($a, $v) = explode(' ', $attribute); $ra = $this->_mapOptionToAttribute($a); if (is_numeric($v)) { if (strstr($v, '.')) { $newoptions[$ra][] = (double) $v; } else { $newoptions[$ra][] = (int) $v; } } else { $newoptions[$ra][] = $v; } } } catch (Horde_Ldap_Exception $e) { throw new Sam_Exception($e); } /* Go through new options and pull single values out of their * arrays. */ foreach ($newoptions as $k => $v) { if (count($v) > 1) { $this->_options[$k] = $v; } else { $this->_options[$k] = $v[0]; } } }
/** * Tries to find a DN for a given kolab mail address. * * @param string $mail The mail address to search for. * * @return string The corresponding dn or false. * @throws Horde_Group_Exception */ protected function _dnForMail($mail) { try { $filter = Horde_Ldap_Filter::combine('and', array(Horde_Ldap_Filter::create('objectclass', 'equals', 'kolabInetOrgPerson'), Horde_Ldap_Filter::create('mail', 'equals', $mail))); $search = $this->_ldap->search($this->_params['basedn'], $filter, array('dn')); if ($search->count()) { return $search->shiftEntry()->dn(); } } catch (Horde_Ldap_Exception $e) { throw new Horde_Group_Exception($e); } throw new Horde_Group_Exception(sprintf('Error searching for user with the email address "%s"', $mail)); }
/** * Checks if $userId exists in the LDAP backend system. * * @author Marco Ferrante, University of Genova (I) * * @param string $userId User ID for which to check * * @return boolean Whether or not $userId already exists. */ public function exists($userId) { $params = array('scope' => $this->_params['scope']); try { $uidfilter = Horde_Ldap_Filter::create($this->_params['uid'], 'equals', $userId); $classfilter = Horde_Ldap_Filter::build(array('filter' => $this->_params['filter'])); $search = $this->_ldap->search($this->_params['basedn'], Horde_Ldap_Filter::combine('and', array($uidfilter, $classfilter)), $params); if ($search->count() < 1) { return false; } if ($search->count() > 1 && $this->_logger) { $this->_logger->log('Multiple LDAP entries with user identifier ' . $userId, 'WARN'); } return true; } catch (Horde_Ldap_Exception $e) { if ($this->_logger) { $this->_logger->log('Error searching LDAP user: '******'ERR'); } return false; } }
/** * Returns the DN of a user. * * The purpose is to quickly find the full DN of a user so it can be used * to re-bind as this user. This method requires the 'user' configuration * parameter to be set. * * @param string $user The user to find. * * @return string The user's full DN. * @throws Horde_Ldap_Exception * @throws Horde_Exception_NotFound */ public function findUserDN($user) { $filter = Horde_Ldap_Filter::combine('and', array(Horde_Ldap_Filter::build($this->_config['user']), Horde_Ldap_Filter::create($this->_config['user']['uid'], 'equals', $user))); $search = $this->search(isset($this->_config['user']['basedn']) ? $this->_config['user']['basedn'] : null, $filter, array('attributes' => array($this->_config['user']['uid']))); if (!$search->count()) { throw new Horde_Exception_NotFound('DN for user ' . $user . ' not found'); } $entry = $search->shiftEntry(); return $entry->currentDN(); }
/** * Convert the single element to query format. * * @param Horde_Kolab_Server_Query_Element_Single $single The element to convert. * @param string $operator The element operation. * * @return mixed The query element in query format. * * @throws Horde_Kolab_Server_Exception If the query is malformed. */ private function _convertSingle(Horde_Kolab_Server_Query_Element_Single $single, $operator) { try { return Horde_Ldap_Filter::create($this->_structure->mapExternalToInternalAttribute($single->getName()), $operator, $single->getValue()); } catch (Horde_Ldap_Exception $e) { throw new Horde_Kolab_Server_Exception($e->getMessage(), Horde_Kolab_Server_Exception::INVALID_QUERY, $e); } }
/** * This tests the basic combination of filters. */ public function testCombine() { // Setup. $filter0 = Horde_Ldap_Filter::create('foo', 'equals', 'bar'); $this->assertInstanceOf('Horde_Ldap_Filter', $filter0); $filter1 = Horde_Ldap_Filter::create('bar', 'equals', 'foo'); $this->assertInstanceOf('Horde_Ldap_Filter', $filter1); $filter2 = Horde_Ldap_Filter::create('you', 'equals', 'me'); $this->assertInstanceOf('Horde_Ldap_Filter', $filter2); $filter3 = Horde_Ldap_Filter::parse('(perlinterface=used)'); $this->assertInstanceOf('Horde_Ldap_Filter', $filter3); // Negation test. $filter_not1 = Horde_Ldap_Filter::combine('not', $filter0); $this->assertInstanceOf('Horde_Ldap_Filter', $filter_not1, 'Negation failed for literal NOT'); $this->assertEquals('(!(foo=bar))', (string) $filter_not1); $filter_not2 = Horde_Ldap_Filter::combine('!', $filter0); $this->assertInstanceOf('Horde_Ldap_Filter', $filter_not2, 'Negation failed for logical NOT'); $this->assertEquals('(!(foo=bar))', (string) $filter_not2); $filter_not3 = Horde_Ldap_Filter::combine('!', (string) $filter0); $this->assertInstanceOf('Horde_Ldap_Filter', $filter_not3, 'Negation failed for logical NOT'); $this->assertEquals('(!' . $filter0 . ')', (string) $filter_not3); // Combination test: OR $filter_comb_or1 = Horde_Ldap_Filter::combine('or', array($filter1, $filter2)); $this->assertInstanceOf('Horde_Ldap_Filter', $filter_comb_or1, 'Combination failed for literal OR'); $this->assertEquals('(|(bar=foo)(you=me))', (string) $filter_comb_or1); $filter_comb_or2 = Horde_Ldap_Filter::combine('|', array($filter1, $filter2)); $this->assertInstanceOf('Horde_Ldap_Filter', $filter_comb_or2, 'combination failed for logical OR'); $this->assertEquals('(|(bar=foo)(you=me))', (string) $filter_comb_or2); // Combination test: AND $filter_comb_and1 = Horde_Ldap_Filter::combine('and', array($filter1, $filter2)); $this->assertInstanceOf('Horde_Ldap_Filter', $filter_comb_and1, 'Combination failed for literal AND'); $this->assertEquals('(&(bar=foo)(you=me))', (string) $filter_comb_and1); $filter_comb_and2 = Horde_Ldap_Filter::combine('&', array($filter1, $filter2)); $this->assertInstanceOf('Horde_Ldap_Filter', $filter_comb_and2, 'combination failed for logical AND'); $this->assertEquals('(&(bar=foo)(you=me))', (string) $filter_comb_and2); // Combination test: using filter created with perl interface. $filter_comb_perl1 = Horde_Ldap_Filter::combine('and', array($filter1, $filter3)); $this->assertInstanceOf('Horde_Ldap_Filter', $filter_comb_perl1, 'Combination failed for literal AND'); $this->assertEquals('(&(bar=foo)(perlinterface=used))', (string) $filter_comb_perl1); $filter_comb_perl2 = Horde_Ldap_Filter::combine('&', array($filter1, $filter3)); $this->assertInstanceOf('Horde_Ldap_Filter', $filter_comb_perl2, 'combination failed for logical AND'); $this->assertEquals('(&(bar=foo)(perlinterface=used))', (string) $filter_comb_perl2); // Combination test: using filter_str instead of object $filter_comb_fstr1 = Horde_Ldap_Filter::combine('and', array($filter1, '(filter_str=foo)')); $this->assertInstanceOf('Horde_Ldap_Filter', $filter_comb_fstr1, 'Combination failed for literal AND using filter_str'); $this->assertEquals('(&(bar=foo)(filter_str=foo))', (string) $filter_comb_fstr1); // Combination test: deep combination $filter_comp_deep = Horde_Ldap_Filter::combine('and', array($filter2, $filter_not1, $filter_comb_or1, $filter_comb_perl1)); $this->assertInstanceOf('Horde_Ldap_Filter', $filter_comp_deep, 'Deep combination failed!'); $this->assertEquals('(&(you=me)(!(foo=bar))(|(bar=foo)(you=me))(&(bar=foo)(perlinterface=used)))', (string) $filter_comp_deep); // Test failure in combination try { Horde_Ldap_Filter::create('foo', 'test_undefined_matchingrule', 'bar'); $this->fail('Horde_Ldap_Exception expected.'); } catch (Horde_Ldap_Exception $e) { } try { Horde_Ldap_Filter::combine('not', 'damaged_filter_str'); $this->fail('Horde_Ldap_Exception expected.'); } catch (Horde_Ldap_Exception $e) { } try { Horde_Ldap_Filter::combine('not', array($filter0, $filter1)); $this->fail('Horde_Ldap_Exception expected.'); } catch (Horde_Ldap_Exception $e) { } try { Horde_Ldap_Filter::combine('not', null); $this->fail('Horde_Ldap_Exception expected.'); } catch (Horde_Ldap_Exception $e) { } try { Horde_Ldap_Filter::combine('and', $filter_not1); $this->fail('Horde_Ldap_Exception expected.'); } catch (Horde_Ldap_Exception $e) { } try { Horde_Ldap_Filter::combine('and', array($filter_not1)); $this->fail('Horde_Ldap_Exception expected.'); } catch (Horde_Ldap_Exception $e) { } try { Horde_Ldap_Filter::combine('and', $filter_not1); $this->fail('Horde_Ldap_Exception expected.'); } catch (Horde_Ldap_Exception $e) { } try { Horde_Ldap_Filter::combine('or', array($filter_not1)); $this->fail('Horde_Ldap_Exception expected.'); } catch (Horde_Ldap_Exception $e) { } try { Horde_Ldap_Filter::combine('some_unknown_method', array($filter_not1)); $this->fail('Horde_Ldap_Exception expected.'); } catch (Horde_Ldap_Exception $e) { } try { Horde_Ldap_Filter::combine('and', array($filter_not1, 'some_invalid_filterstring')); $this->fail('Horde_Ldap_Exception expected.'); } catch (Horde_Ldap_Exception $e) { } try { Horde_Ldap_Filter::combine('and', array($filter_not1, null)); $this->fail('Horde_Ldap_Exception expected.'); } catch (Horde_Ldap_Exception $e) { } }
/** * Test search(). */ public function testSearch() { $ldap = new Horde_Ldap(self::$ldapcfg['server']); // Some testdata, so we can test sizelimit. $base = self::$ldapcfg['server']['basedn']; $ou1 = Horde_Ldap_Entry::createFresh('ou=Horde_Ldap_Test_search1,' . $base, array('objectClass' => array('top', 'organizationalUnit'), 'ou' => 'Horde_Ldap_Test_search1')); $ou1_1 = Horde_Ldap_Entry::createFresh('ou=Horde_Ldap_Test_search1_1,' . $ou1->dn(), array('objectClass' => array('top', 'organizationalUnit'), 'ou' => 'Horde_Ldap_Test_search1_1')); $ou2 = Horde_Ldap_Entry::createFresh('ou=Horde_Ldap_Test_search2,' . $base, array('objectClass' => array('top', 'organizationalUnit'), 'ou' => 'Horde_Ldap_Test_search2')); $ldap->add($ou1); $this->assertTrue($ldap->exists($ou1->dn())); $ldap->add($ou1_1); $this->assertTrue($ldap->exists($ou1_1->dn())); $ldap->add($ou2); $this->assertTrue($ldap->exists($ou2->dn())); // Search for test filter, should at least return our two test entries. $res = $ldap->search(null, '(ou=Horde_Ldap*)', array('attributes' => '1.1')); $this->assertInstanceOf('Horde_Ldap_Search', $res); $this->assertThat($res->count(), $this->greaterThanOrEqual(2)); // Same, but with Horde_Ldap_Filter object. $filtero = Horde_Ldap_Filter::create('ou', 'begins', 'Horde_Ldap'); $this->assertInstanceOf('Horde_Ldap_Filter', $filtero); $res = $ldap->search(null, $filtero, array('attributes' => '1.1')); $this->assertInstanceOf('Horde_Ldap_Search', $res); $this->assertThat($res->count(), $this->greaterThanOrEqual(2)); // Search using default filter for base-onelevel scope, should at least // return our two test entries. $res = $ldap->search(null, null, array('scope' => 'one', 'attributes' => '1.1')); $this->assertInstanceOf('Horde_Ldap_Search', $res); $this->assertThat($res->count(), $this->greaterThanOrEqual(2)); // Base-search using custom base (string), should only return the test // entry $ou1 and not the entry below it. $res = $ldap->search($ou1->dn(), null, array('scope' => 'base', 'attributes' => '1.1')); $this->assertInstanceOf('Horde_Ldap_Search', $res); $this->assertEquals(1, $res->count()); // Search using custom base, this time using an entry object. This // tests if passing an entry object as base works, should only return // the test entry $ou1. $res = $ldap->search($ou1, '(ou=*)', array('scope' => 'base', 'attributes' => '1.1')); $this->assertInstanceOf('Horde_Ldap_Search', $res); $this->assertEquals(1, $res->count()); // Search using default filter for base-onelevel scope with sizelimit, // should of course return more than one entry, but not more than // sizelimit $res = $ldap->search(null, null, array('scope' => 'one', 'sizelimit' => 1, 'attributes' => '1.1')); $this->assertInstanceOf('Horde_Ldap_Search', $res); $this->assertEquals(1, $res->count()); // Sizelimit should be exceeded now. $this->assertTrue($res->sizeLimitExceeded()); // Bad filter. try { $res = $ldap->search(null, 'somebadfilter', array('attributes' => '1.1')); $this->fail('Horde_Ldap_Exception expected.'); } catch (Horde_Ldap_Exception $e) { } // Bad base. try { $res = $ldap->search('badbase', null, array('attributes' => '1.1')); $this->fail('Horde_Ldap_Exception expected.'); } catch (Horde_Ldap_Exception $e) { } // Nullresult. $res = $ldap->search(null, '(cn=nevermatching_filter)', array('scope' => 'base', 'attributes' => '1.1')); $this->assertInstanceOf('Horde_Ldap_Search', $res); $this->assertEquals(0, $res->count()); }
/** * Lists all available scopes. * * @return array The list of scopes stored in the backend. */ public function listScopes() { $scopes = array(); try { $prefs = $this->_ldap->search($this->_prefsDN, Horde_Ldap_Filter::create('objectclass', 'equals', 'hordePerson'), array('attributes' => array('@hordePerson'), 'scope' => 'base', 'attrsonly' => true)); } catch (Horde_Ldap_Exception $e) { throw new Horde_Prefs_Exception($e); } if (!$prefs) { return $scopes; } foreach ($prefs->shiftEntry()->attributes() as $attr) { // Trim off prefs from attribute name to get scope (e.g. hordePrefs // -> horde). $scope = str_ireplace("prefs", "", $attr); // Skip non-prefs attributes like objectclass (no replacement // occurred above). if ($attr != $scope) { $scopes[] = $scope; } } return $scopes; }
/** * Searches for group names. * * @param string $name A search string. * * @return array A list of matching groups, with IDs as keys and names as * values. * @throws Horde_Group_Exception */ public function search($name) { $attr = $this->_params['gid']; try { $result = $this->_ldap->search($this->_params['basedn'], Horde_Ldap_Filter::create($attr, 'contains', $name), array($attr)); } catch (Horde_Ldap_Exception $e) { throw new Horde_Group_Exception($e); } $entries = array(); foreach ($result->sortedAsArray(array($attr)) as $entry) { $entries[$entry['dn']] = $entry[$attr][0]; } return $entries; }