/** * Update LDAP registry * * @param string|Zend_Ldap_Dn $dn * @param array $entry * @return Zend_Ldap Provides a fluid interface * @throws Zend_Ldap_Exception */ public function update($dn, array $entry) { if (!$dn instanceof Zend_Ldap_Dn) { $dn = Zend_Ldap_Dn::factory($dn, null); } self::prepareLdapEntryArray($entry); $rdnParts = $dn->getRdn(Zend_Ldap_Dn::ATTR_CASEFOLD_LOWER); foreach ($rdnParts as $key => $value) { $value = Zend_Ldap_Dn::unescapeValue($value); if (array_key_exists($key, $entry) && !in_array($value, $entry[$key])) { $entry[$key] = array_merge(array($value), $entry[$key]); } } $adAttributes = array('distinguishedname', 'instancetype', 'name', 'objectcategory', 'objectguid', 'usnchanged', 'usncreated', 'whenchanged', 'whencreated'); foreach ($adAttributes as $attr) { if (array_key_exists($attr, $entry)) { unset($entry[$attr]); } } if (count($entry) > 0) { $isModified = @ldap_modify($this->getResource(), $dn->toString(), $entry); if ($isModified === false) { /** * @see Zend_Ldap_Exception */ #require_once 'Zend/Ldap/Exception.php'; throw new Zend_Ldap_Exception($this, 'updating: ' . $dn->toString()); } } return $this; }
/** * Sets the new DN for this node * * This is an offline method. * * @param Zend_Ldap_Dn|string|array $newDn * @throws Zend_Ldap_Exception * @return Zend_Ldap_Node Provides a fluid interface */ public function setDn($newDn) { if ($newDn instanceof Zend_Ldap_Dn) { $this->_newDn = clone $newDn; } else { $this->_newDn = Zend_Ldap_Dn::factory($newDn); } $this->_ensureRdnAttributeValues(true); return $this; }
/** * updates an existing user * * @todo check required objectclasses? * * @param Tinebase_Model_FullUser $_account * @return Tinebase_Model_FullUser */ public function updateUserInSyncBackend(Tinebase_Model_FullUser $_account) { if ($this->_isReadOnlyBackend) { return $_account; } $ldapEntry = $this->_getLdapEntry('accountId', $_account); $ldapData = $this->_user2ldap($_account, $ldapEntry); foreach ($this->_ldapPlugins as $plugin) { $plugin->inspectUpdateUser($_account, $ldapData, $ldapEntry); } // no need to update this attribute, it's not allowed to change and even might not be update-able unset($ldapData[$this->_userUUIDAttribute]); if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' DN: ' . $ldapEntry['dn']); } if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' LDAP data: ' . print_r($ldapData, true)); } $this->_ldap->update($ldapEntry['dn'], $ldapData); $dn = Zend_Ldap_Dn::factory($ldapEntry['dn'], null); $rdn = $dn->getRdn(); // do we need to rename the entry? if (isset($ldapData[key($rdn)]) && $rdn[key($rdn)] != $ldapData[key($rdn)]) { $groupsBackend = Tinebase_Group::factory(Tinebase_Group::LDAP); // get the current group memberships $memberships = $groupsBackend->getGroupMembershipsFromSyncBackend($_account); // remove the user from current groups, because the dn/uid has changed foreach ($memberships as $groupId) { $groupsBackend->removeGroupMemberInSyncBackend($groupId, $_account); } $newDN = $this->_generateDn($_account); if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' rename ldap entry to: ' . $newDN); } $this->_ldap->rename($dn, $newDN); // add the user to current groups again foreach ($memberships as $groupId) { $groupsBackend->addGroupMemberInSyncBackend($groupId, $_account); } } // refetch user from ldap backend $user = $this->getUserByPropertyFromSyncBackend('accountId', $_account, 'Tinebase_Model_FullUser'); return $user; }
public function testDnCreation() { Zend_Ldap_Dn::setDefaultCaseFold(Zend_Ldap_Dn::ATTR_CASEFOLD_NONE); $dnString1 = 'CN=Baker\\, Alice,CN=Users+OU=Lab,DC=example,DC=com'; $dnArray1 = array(array('CN' => 'Baker, Alice'), array('CN' => 'Users', 'OU' => 'Lab'), array('DC' => 'example'), array('DC' => 'com')); $dnString2 = 'cn=Baker\\, Alice,cn=Users+ou=Lab,dc=example,dc=com'; $dnArray2 = array(array('cn' => 'Baker, Alice'), array('cn' => 'Users', 'ou' => 'Lab'), array('dc' => 'example'), array('dc' => 'com')); $dnString3 = 'Cn=Baker\\, Alice,Cn=Users+Ou=Lab,Dc=example,Dc=com'; $dnArray3 = array(array('Cn' => 'Baker, Alice'), array('Cn' => 'Users', 'Ou' => 'Lab'), array('Dc' => 'example'), array('Dc' => 'com')); $dn11 = Zend_Ldap_Dn::fromString($dnString1); $dn12 = Zend_Ldap_Dn::fromArray($dnArray1); $dn13 = Zend_Ldap_Dn::factory($dnString1); $dn14 = Zend_Ldap_Dn::factory($dnArray1); $this->assertEquals($dn11, $dn12); $this->assertEquals($dn11, $dn13); $this->assertEquals($dn11, $dn14); $this->assertEquals($dnString1, $dn11->toString()); $this->assertEquals($dnString1, $dn11->toString(Zend_Ldap_Dn::ATTR_CASEFOLD_UPPER)); $this->assertEquals($dnString2, $dn11->toString(Zend_Ldap_Dn::ATTR_CASEFOLD_LOWER)); $this->assertEquals($dnArray1, $dn11->toArray()); $this->assertEquals($dnArray1, $dn11->toArray(Zend_Ldap_Dn::ATTR_CASEFOLD_UPPER)); $this->assertEquals($dnArray2, $dn11->toArray(Zend_Ldap_Dn::ATTR_CASEFOLD_LOWER)); $dn21 = Zend_Ldap_Dn::fromString($dnString2); $dn22 = Zend_Ldap_Dn::fromArray($dnArray2); $dn23 = Zend_Ldap_Dn::factory($dnString2); $dn24 = Zend_Ldap_Dn::factory($dnArray2); $this->assertEquals($dn21, $dn22); $this->assertEquals($dn21, $dn23); $this->assertEquals($dn21, $dn24); $this->assertEquals($dnString2, $dn21->toString()); $this->assertEquals($dnString1, $dn21->toString(Zend_Ldap_Dn::ATTR_CASEFOLD_UPPER)); $this->assertEquals($dnString2, $dn21->toString(Zend_Ldap_Dn::ATTR_CASEFOLD_LOWER)); $this->assertEquals($dnArray2, $dn21->toArray()); $this->assertEquals($dnArray1, $dn21->toArray(Zend_Ldap_Dn::ATTR_CASEFOLD_UPPER)); $this->assertEquals($dnArray2, $dn21->toArray(Zend_Ldap_Dn::ATTR_CASEFOLD_LOWER)); $this->assertEquals($dnArray2, $dn22->toArray()); $dn31 = Zend_Ldap_Dn::fromString($dnString3); $dn32 = Zend_Ldap_Dn::fromArray($dnArray3); $dn33 = Zend_Ldap_Dn::factory($dnString3); $dn34 = Zend_Ldap_Dn::factory($dnArray3); $this->assertEquals($dn31, $dn32); $this->assertEquals($dn31, $dn33); $this->assertEquals($dn31, $dn34); $this->assertEquals($dnString3, $dn31->toString()); $this->assertEquals($dnString1, $dn31->toString(Zend_Ldap_Dn::ATTR_CASEFOLD_UPPER)); $this->assertEquals($dnString2, $dn31->toString(Zend_Ldap_Dn::ATTR_CASEFOLD_LOWER)); $this->assertEquals($dnArray3, $dn31->toArray()); $this->assertEquals($dnArray1, $dn31->toArray(Zend_Ldap_Dn::ATTR_CASEFOLD_UPPER)); $this->assertEquals($dnArray2, $dn31->toArray(Zend_Ldap_Dn::ATTR_CASEFOLD_LOWER)); try { $dn = Zend_Ldap_Dn::factory(1); $this->fail('Expected Zend_Ldap_Exception not thrown'); } catch (Zend_Ldap_Exception $e) { $this->assertEquals('Invalid argument type for $dn', $e->getMessage()); } }
/** * updates an existing user * * @todo check required objectclasses? * * @param Tinebase_Model_FullUser $_account * @return Tinebase_Model_FullUser */ public function updateUserInSyncBackend(Tinebase_Model_FullUser $_account) { if ($this->_isReadOnlyBackend) { return; } Tinebase_Group::getInstance()->addGroupMemberInSyncBackend($_account->accountPrimaryGroup, $_account->getId()); $ldapEntry = $this->_getLdapEntry('accountId', $_account); $ldapData = $this->_user2ldap($_account, $ldapEntry); foreach ($this->_ldapPlugins as $plugin) { $plugin->inspectUpdateUser($_account, $ldapData, $ldapEntry); } // do we need to rename the entry? // TODO move to rename() $dn = Zend_Ldap_Dn::factory($ldapEntry['dn'], null); $rdn = $dn->getRdn(); if ($rdn['CN'] != $ldapData['cn']) { $newDN = $this->generateDn($_account); if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' rename ldap entry to: ' . $newDN); } $this->_ldap->rename($dn, $newDN); } // no need to update this attribute, it's not allowed to change and even might not be updateable unset($ldapData[$this->_userUUIDAttribute]); // remove cn as samba forbids updating the CN (even if it does not change... // 0x43 (Operation not allowed on RDN; 00002016: Modify of RDN 'CN' on CN=...,CN=Users,DC=example,DC=org // not permitted, must use 'rename' operation instead unset($ldapData['cn']); if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' $dn: ' . $ldapEntry['dn']); } if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' $ldapData: ' . print_r($ldapData, true)); } $this->_ldap->update($ldapEntry['dn'], $ldapData); // refetch user from ldap backend $user = $this->getUserByPropertyFromSyncBackend('accountId', $_account, 'Tinebase_Model_FullUser'); return $user; }