$base and $filter may be ommitted. The one from config will then be
used. $base is either a DN-string or an Horde_Ldap_Entry object in which
case its DN will be used.
$params may contain:
- scope: The scope which will be used for searching, defaults to 'sub':
- base: Just one entry
- sub: The whole tree
- one: Immediately below $base
- sizelimit: Limit the number of entries returned
(default: 0 = unlimited)
- timelimit: Limit the time spent for searching (default: 0 = unlimited)
- attrsonly: If true, the search will only return the attribute names
- attributes: Array of attribute names, which the entry should contain.
It is good practice to limit this to just the ones you
need.
You cannot override server side limitations to sizelimit and timelimit:
You can always only lower a given limit.
public search ( string | Horde_Ldap_Entry $base = null, string | Horde_Ldap_Filter $filter = null, array $params = [] ) : Horde_Ldap_Search | ||
$base | string | Horde_Ldap_Entry | LDAP searchbase. |
$filter | string | Horde_Ldap_Filter | LDAP search filter. |
$params | array | Array of options. |
return | Horde_Ldap_Search | The search result. |
/** * 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]; } } }
/** * Returns the user account from the LDAP source. * * @return Horde_Ldap_Entry An entry with complete account details. * * @throws Horde_Exception if user not found. * @throws Horde_Ldap_Exception on LDAP errors. */ protected function _getAccount() { if (!isset($this->_information)) { $search = $this->_ldap->search($this->_params['basedn'], $this->_params['attr'] . '=' . $this->_params['user']); if (!$search->count()) { throw new Horde_Exception(_("User account not found")); } $this->_information = $search->shiftEntry(); } return $this->_information; }
/** * Searches existing groups for the highest gidnumber, and returns one * higher. * * @return integer The next group ID. * * @throws Horde_Group_Exception */ protected function _nextGid() { try { $search = $this->_ldap->search($this->_params['basedn'], $this->_filter, array('attributes' => array('gidnumber'))); } catch (Horde_Ldap_Exception $e) { throw new Horde_Group_Exception($e); } if (!$search->count()) { return 1; } $nextgid = 0; foreach ($search as $entry) { $nextgid = max($nextgid, $entry->getValue('gidnumber', 'single')); } return $nextgid + 1; }
/** * 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; } }
/** * Constructor. * * Fetches a RootDSE object from an LDAP connection. * * @param Horde_Ldap $ldap Directory from which the RootDSE should be * fetched. * @param array $attrs Array of attributes to search for. * * @throws Horde_Ldap_Exception */ public function __construct(Horde_Ldap $ldap, $attrs = null) { if (is_array($attrs) && count($attrs)) { $attributes = $attrs; } else { $attributes = array('vendorName', 'vendorVersion', 'namingContexts', 'altServer', 'supportedExtension', 'supportedControl', 'supportedSASLMechanisms', 'supportedLDAPVersion', 'subschemaSubentry'); } $referral = $ldap->getOption('LDAP_OPT_REFERRALS'); $ldap->setOption('LDAP_OPT_REFERRALS', false); try { $result = $ldap->search('', '(objectClass=*)', array('attributes' => $attributes, 'scope' => 'base')); } catch (Horde_Ldap_Exception $e) { $ldap->setOption('LDAP_OPT_REFERRALS', $referral); throw $e; } $ldap->setOption('LDAP_OPT_REFERRALS', $referral); $entry = $result->shiftEntry(); if (!$entry) { throw new Horde_Ldap_Exception('Could not fetch RootDSE entry'); } $this->_entry = $entry; }
/** * 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; }
/** * Constructor. * * Fetches the Schema from an LDAP connection. * * @param Horde_Ldap $ldap LDAP connection. * @param string $dn Subschema entry DN. * * @throws Horde_Ldap_Exception */ public function __construct(Horde_Ldap $ldap, $dn = null) { if (is_null($dn)) { // Get the subschema entry via rootDSE. $dse = $ldap->rootDSE(array('subschemaSubentry')); $base = $dse->getValue('subschemaSubentry', 'single'); $dn = $base; } // Support for buggy LDAP servers (e.g. Siemens DirX 6.x) that // incorrectly call this entry subSchemaSubentry instead of // subschemaSubentry. Note the correct case/spelling as per RFC 2251. if (is_null($dn)) { // Get the subschema entry via rootDSE. $dse = $ldap->rootDSE(array('subSchemaSubentry')); $base = $dse->getValue('subSchemaSubentry', 'single'); $dn = $base; } // Final fallback in case there is no subschemaSubentry attribute in // the root DSE (this is a bug for an LDAPv3 server so report this to // your LDAP vendor if you get this far). if (is_null($dn)) { $dn = 'cn=Subschema'; } // Fetch the subschema entry. $result = $ldap->search($dn, '(objectClass=*)', array('attributes' => array_values($this->types), 'scope' => 'base')); $entry = $result->shiftEntry(); if (!$entry instanceof Horde_Ldap_Entry) { throw new Horde_Ldap_Exception('Could not fetch Subschema entry'); } $this->parse($entry); }
/** * Tests SPL iterator. */ public function testSPLIterator() { $ldap = new Horde_Ldap(self::$ldapcfg['server']); // Some testdata, so we have some entries to search for. $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')); $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($ou2); $this->assertTrue($ldap->exists($ou2->dn())); /* Search and test each method. */ $search = $ldap->search(null, '(ou=Horde_Ldap*)'); $this->assertInstanceOf('Horde_Ldap_Search', $search); $this->assertEquals(2, $search->count()); // current() is supposed to return first valid element. $e1 = $search->current(); $this->assertInstanceOf('Horde_Ldap_Entry', $e1); $this->assertEquals($e1->dn(), $search->key()); $this->assertTrue($search->valid()); // Shift to next entry. $search->next(); $e2 = $search->current(); $this->assertInstanceOf('Horde_Ldap_Entry', $e2); $this->assertEquals($e2->dn(), $search->key()); $this->assertTrue($search->valid()); // Shift to non existent third entry. $search->next(); $this->assertFalse($search->current()); $this->assertFalse($search->key()); $this->assertFalse($search->valid()); // Rewind and test, which should return the first entry a second time. $search->rewind(); $e1_1 = $search->current(); $this->assertInstanceOf('Horde_Ldap_Entry', $e1_1); $this->assertEquals($e1_1->dn(), $search->key()); $this->assertTrue($search->valid()); $this->assertEquals($e1->dn(), $e1_1->dn()); // Don't rewind but call current, should return first entry again. $e1_2 = $search->current(); $this->assertInstanceOf('Horde_Ldap_Entry', $e1_2); $this->assertEquals($e1_2->dn(), $search->key()); $this->assertTrue($search->valid()); $this->assertEquals($e1->dn(), $e1_2->dn()); // Rewind again and test, which should return the first entry a third // time. $search->rewind(); $e1_3 = $search->current(); $this->assertInstanceOf('Horde_Ldap_Entry', $e1_3); $this->assertEquals($e1_3->dn(), $search->key()); $this->assertTrue($search->valid()); $this->assertEquals($e1->dn(), $e1_3->dn()); /* Try methods on empty search result. */ $search = $ldap->search(null, '(ou=Horde_LdapTest_NotExistentEntry)'); $this->assertInstanceOf('Horde_Ldap_Search', $search); $this->assertEquals(0, $search->count()); $this->assertFalse($search->current()); $this->assertFalse($search->key()); $this->assertFalse($search->valid()); $search->next(); $this->assertFalse($search->current()); $this->assertFalse($search->key()); $this->assertFalse($search->valid()); /* Search and simple iterate through the test entries. Then, rewind * and do it again several times. */ $search2 = $ldap->search(null, '(ou=Horde_Ldap*)'); $this->assertInstanceOf('Horde_Ldap_Search', $search2); $this->assertEquals(2, $search2->count()); for ($i = 0; $i <= 5; $i++) { $counter = 0; foreach ($search2 as $dn => $entry) { $counter++; // Check on type. $this->assertInstanceOf('Horde_Ldap_Entry', $entry); // Check on key. $this->assertThat(strlen($dn), $this->greaterThan(1)); $this->assertEquals($dn, $entry->dn()); } $this->assertEquals($search2->count(), $counter, "Failed at loop {$i}"); // Revert to start. $search2->rewind(); } }
/** * 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()); }