This also links the entry to the connection used for the add, if it was
a fresh entry.
public add ( Horde_Ldap_Entry $entry ) | ||
$entry | Horde_Ldap_Entry | An LDAP entry. |
/** * Add a set of authentication credentials. * * @param string $userId The userId to add. * @param array $credentials The credentials to be set. * * @throws Horde_Auth_Exception */ public function addUser($userId, $credentials) { if (!empty($this->_params['ad'])) { throw new Horde_Auth_Exception(__CLASS__ . ': Adding users is not supported for Active Directory.'); } if (isset($credentials['ldap'])) { $entry = $credentials['ldap']; $dn = $entry['dn']; /* Remove the dn entry from the array. */ unset($entry['dn']); } else { /* Try this simple default and hope it works. */ $dn = $this->_params['uid'] . '=' . $userId . ',' . $this->_params['basedn']; $entry['cn'] = $userId; $entry['sn'] = $userId; $entry[$this->_params['uid']] = $userId; $entry['objectclass'] = array_merge(array('top'), $this->_params['newuser_objectclass']); $entry['userPassword'] = Horde_Auth::getCryptedPassword($credentials['password'], '', $this->_params['encryption'], 'true'); if ($this->_params['password_expiration'] == 'yes') { $entry['shadowMin'] = $this->_params['minage']; $entry['shadowMax'] = $this->_params['maxage']; $entry['shadowWarning'] = $this->_params['warnage']; $entry['shadowLastChange'] = floor(time() / 86400); } } try { $this->_ldap->add(Horde_Ldap_Entry::createFresh($dn, $entry)); } catch (Horde_Ldap_Exception $e) { throw new Horde_Auth_Exception(sprintf(__CLASS__ . ': Unable to add user "%s". This is what the server said: ', $userId) . $e->getMessage()); } }
/** * Creates a new group. * * @param string $name A group name. * @param array $attributes The group's attributes. * * @return mixed The ID of the created group. * @throws Horde_Group_Exception */ protected function _create($name, array $attributes) { $dn = Horde_Ldap::quoteDN(array(array($this->_params['gid'], $name))) . ',' . $this->_params['basedn']; try { $entry = Horde_Ldap_Entry::createFresh($dn, $attributes); $this->_rebind(true); $this->_ldap->add($entry); $this->_rebind(false); return $dn; } catch (Horde_Ldap_Exception $e) { throw new Horde_Group_Exception($e); } }
/** * Creates a new group. * * @param string $name A group name. * @param string $email The group's email address. * * @return mixed The ID of the created group. * @throws Horde_Group_Exception */ protected function _create($name, $email = null) { if ($this->readOnly()) { throw new Horde_Group_Exception('This group backend is read-only.'); } $attributes = array($this->_params['gid'] => $name, 'objectclass' => $this->_params['newgroup_objectclass'], 'gidnumber' => $this->_nextGid()); if (!empty($email)) { $attributes['mail'] = $email; } $dn = Horde_Ldap::quoteDN(array(array($this->_params['gid'], $name))) . ',' . $this->_params['basedn']; try { $entry = Horde_Ldap_Entry::createFresh($dn, $attributes); $this->_rebind(true); $this->_ldap->add($entry); $this->_rebind(false); } catch (Horde_Ldap_Exception $e) { throw new Horde_Group_Exception($e); } return $dn; }
/** * Renames or moves an entry. * * This method will instantly carry out an update() after the * move, so the entry is moved instantly. * * You can pass an optional Horde_Ldap object. In this case, a * cross directory move will be performed which deletes the entry * in the source (THIS) directory and adds it in the directory * $target_ldap. * * A cross directory move will switch the entry's internal LDAP * reference so updates to the entry will go to the new directory. * * If you want to do a cross directory move, you need to pass an * Horde_Ldap_Entry object, otherwise the attributes will be * empty. * * @param string|Horde_Ldap_Entry $entry An LDAP entry. * @param string $newdn The new location. * @param Horde_Ldap $target_ldap Target directory for cross * server move. * * @throws Horde_Ldap_Exception */ public function move($entry, $newdn, $target_ldap = null) { if (is_string($entry)) { if ($target_ldap && $target_ldap !== $this) { throw new Horde_Ldap_Exception('Unable to perform cross directory move: operation requires a Horde_Ldap_Entry object'); } $entry = $this->getEntry($entry); } if (!$entry instanceof Horde_Ldap_Entry) { throw new Horde_Ldap_Exception('Parameter $entry is expected to be a Horde_Ldap_Entry object! (If DN was passed, conversion failed)'); } if ($target_ldap && !$target_ldap instanceof Horde_Ldap) { throw new Horde_Ldap_Exception('Parameter $target_ldap is expected to be a Horde_Ldap object!'); } if (!$target_ldap || $target_ldap === $this) { /* Local move. */ $entry->dn($newdn); $entry->setLDAP($this); $entry->update(); return; } /* Cross directory move. */ if ($target_ldap->exists($newdn)) { throw new Horde_Ldap_Exception('Unable to perform cross directory move: entry does exist in target directory'); } $entry->dn($newdn); try { $target_ldap->add($entry); } catch (Exception $e) { throw new Horde_Ldap_Exception('Unable to perform cross directory move: ' . $e->getMessage() . ' in target directory'); } try { $this->delete($entry->currentDN()); } catch (Exception $e) { try { $add_error_string = ''; /* Undo add. */ $target_ldap->delete($entry); } catch (Exception $e) { $add_error_string = ' Additionally, the deletion (undo add) of $entry in target directory failed.'; } throw new Horde_Ldap_Exception('Unable to perform cross directory move: ' . $e->getMessage() . ' in source directory.' . $add_error_string); } $entry->setLDAP($target_ldap); }
/** * 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 copy(). */ public function testCopy() { $ldap = new Horde_Ldap(self::$ldapcfg['server']); // Some testdata. $base = self::$ldapcfg['server']['basedn']; $ou1 = Horde_Ldap_Entry::createFresh('ou=Horde_Ldap_Test_pool,' . $base, array('objectClass' => array('top', 'organizationalUnit'), 'ou' => 'Horde_Ldap_Test_copy')); $ou2 = Horde_Ldap_Entry::createFresh('ou=Horde_Ldap_Test_tgt,' . $base, array('objectClass' => array('top', 'organizationalUnit'), 'ou' => 'Horde_Ldap_Test_copy')); $ldap->add($ou1); $this->assertTrue($ldap->exists($ou1->dn())); $ldap->add($ou2); $this->assertTrue($ldap->exists($ou2->dn())); $entry = Horde_Ldap_Entry::createFresh('l=cptest,' . $ou1->dn(), array('objectClass' => array('top', 'locality'), 'l' => 'cptest')); $ldap->add($entry); $ldap->exists($entry->dn()); // Copy over the entry to another tree with rename. $entrycp = $ldap->copy($entry, 'l=test_copied,' . $ou2->dn()); $this->assertInstanceOf('Horde_Ldap_Entry', $entrycp); $this->assertNotEquals($entry->dn(), $entrycp->dn()); $this->assertTrue($ldap->exists($entrycp->dn())); // Copy same again (fails, entry exists). try { $entrycp_f = $ldap->copy($entry, 'l=test_copied,' . $ou2->dn()); $this->fail('Horde_Ldap_Exception expected.'); } catch (Horde_Ldap_Exception $e) { } // Use only DNs to copy (fails). try { $entrycp = $ldap->copy($entry->dn(), 'l=test_copied2,' . $ou2->dn()); $this->fail('Horde_Ldap_Exception expected.'); } catch (Horde_Ldap_Exception $e) { } }