explodeDN() public static méthode

{@link http://www.ietf.org/rfc/rfc2253.txt RFC 2253} says, a Distinguished Name is a sequence of Relative Distinguished Names (RDNs), which themselves are sets of Attributes. For each RDN a array is constructed where the RDN part is stored. For example, the DN 'OU=Sales+CN=J. Smith,DC=example,DC=net' is exploded to: array(array('OU=Sales', 'CN=J. Smith'), 'DC=example', 'DC=net') [NOT IMPLEMENTED] DNs might also contain values, which are the bytes of the BER encoding of the X.500 AttributeValue rather than some LDAP string syntax. These values are hex-encoded and prefixed with a #. To distinguish such BER values, explodeDN uses references to the actual values, e.g. '1.3.6.1.4.1.1466.0=#04024869,DC=example,DC=com' is exploded to: array(array('1.3.6.1.4.1.1466.0' => "\004\002Hi"), array('DC' => 'example', array('DC' => 'com')) See {@link http://www.vijaymukhi.com/vmis/berldap.htm} for more information on BER. It also performs the following operations on the given DN: - Unescape "\" followed by ",", "+", """, "\", "<", ">", ";", "#", "=", " ", or a hexpair and strings beginning with "#". - Removes the leading 'OID.' characters if the type is an OID instead of a name. - If an RDN contains multiple parts, the parts are re-ordered so that the attribute type names are in alphabetical order. $options is a list of name/value pairs, valid options are: - casefold: Controls case folding of attribute types names. Attribute values are not affected by this option. The default is to uppercase. Valid values are: - lower: Lowercase attribute types names. - upper: Uppercase attribute type names. This is the default. - none: Do not change attribute type names. - reverse: If true, the RDN sequence is reversed. - onlyvalues: If true, then only attributes values are returned ('foo' instead of 'cn=foo')
public static explodeDN ( string $dn, array $options = [] ) : array
$dn string The DN that should be exploded.
$options array Options to use.
Résultat array Parts of the exploded DN.
Exemple #1
0
 /**
  * Returns the win32 AD epoch number of days the password may be unchanged.
  *
  * @return integer|boolean  Number of days or false if no limit.
  */
 protected function _getMaxPasswd()
 {
     $dn = Horde_Ldap_Util::explodeDN($this->_params['basedn']);
     $domaindn = array();
     foreach ($dn as $rdn) {
         $attribute = Horde_Ldap_Util::splitAttributeString($rdn);
         if ($attribute[0] == 'DC') {
             $domaindn[] = $rdn;
         }
     }
     $dn = Horde_Ldap_Util::canonicalDN($domaindn);
     $search = $this->_ldap->search($domaindn, 'objectClass=*');
     $entry = $search->shiftEntry();
     try {
         return $entry->getValue('maxPwdAge', 'single');
     } catch (Horde_Ldap_Exception $e) {
         return false;
     }
 }
Exemple #2
0
 /**
  * Returns whether a DN exists in the directory.
  *
  * @param string|Horde_Ldap_Entry $dn The DN of the object to test.
  *
  * @return boolean  True if the DN exists.
  * @throws Horde_Ldap_Exception
  */
 public function exists($dn)
 {
     if ($dn instanceof Horde_Ldap_Entry) {
         $dn = $dn->dn();
     }
     if (!is_string($dn)) {
         throw new Horde_Ldap_Exception('Parameter $dn is not a string nor an entry object!');
     }
     /* Make dn relative to parent. */
     $base = Horde_Ldap_Util::explodeDN($dn, array('casefold' => 'none', 'reverse' => false, 'onlyvalues' => false));
     $entry_rdn = array_shift($base);
     $base = Horde_Ldap_Util::canonicalDN($base);
     $result = @ldap_list($this->_link, $base, $entry_rdn, array(), 1, 1);
     if (@ldap_count_entries($this->_link, $result)) {
         return true;
     }
     if ($this->errorName(@ldap_errno($this->_link)) == 'LDAP_NO_SUCH_OBJECT') {
         return false;
     }
     if (@ldap_errno($this->_link)) {
         throw new Horde_Ldap_Exception(@ldap_error($this->_link), @ldap_errno($this->_link));
     }
     return false;
 }
Exemple #3
0
 /**
  * Updates the entry on the directory server.
  *
  * This will evaluate all changes made so far and send them to the
  * directory server.
  *
  * If you make changes to objectclasses wich have mandatory attributes set,
  * update() will currently fail. Remove the entry from the server and readd
  * it as new in such cases. This also will deal with problems with setting
  * structural object classes.
  *
  * @todo Entry rename with a DN containing special characters needs testing!
  *
  * @throws Horde_Ldap_Exception
  */
 public function update()
 {
     /* Ensure we have a valid LDAP object. */
     $ldap = $this->getLDAP();
     /* Get and check link. */
     $link = $ldap->getLink();
     if (!is_resource($link)) {
         throw new Horde_Ldap_Exception('Could not update entry: internal LDAP link is invalid');
     }
     /* Delete the entry. */
     if ($this->_delete) {
         return $ldap->delete($this);
     }
     /* New entry. */
     if ($this->_new) {
         $ldap->add($this);
         $this->_new = false;
         $this->_changes['add'] = array();
         $this->_changes['delete'] = array();
         $this->_changes['replace'] = array();
         $this->_original = $this->_attributes;
         return;
     }
     /* Rename/move entry. */
     if (!is_null($this->_newdn)) {
         if ($ldap->getVersion() != 3) {
             throw new Horde_Ldap_Exception('Renaming/Moving an entry is only supported in LDAPv3');
         }
         /* Make DN relative to parent (needed for LDAP rename). */
         $parent = Horde_Ldap_Util::explodeDN($this->_newdn, array('casefolding' => 'none', 'reverse' => false, 'onlyvalues' => false));
         $child = array_shift($parent);
         /* Maybe the DN consist of a multivalued RDN, we must build the DN
          * in this case because the $child RDN is an array. */
         if (is_array($child)) {
             $child = Horde_Ldap_Util::canonicalDN($child);
         }
         $parent = Horde_Ldap_Util::canonicalDN($parent);
         /* Rename/move. */
         if (!@ldap_rename($link, $this->_dn, $child, $parent, true)) {
             throw new Horde_Ldap_Exception('Entry not renamed: ' . @ldap_error($link), @ldap_errno($link));
         }
         /* Reflect changes to local copy. */
         $this->_dn = $this->_newdn;
         $this->_newdn = null;
     }
     /* Carry out modifications to the entry. */
     foreach ($this->_changes['add'] as $attr => $value) {
         /* If attribute exists, add new values. */
         if ($this->exists($attr)) {
             if (!@ldap_mod_add($link, $this->dn(), array($attr => $value))) {
                 throw new Horde_Ldap_Exception('Could not add new values to attribute ' . $attr . ': ' . @ldap_error($link), @ldap_errno($link));
             }
         } else {
             /* New attribute. */
             if (!@ldap_modify($link, $this->dn(), array($attr => $value))) {
                 throw new Horde_Ldap_Exception('Could not add new attribute ' . $attr . ': ' . @ldap_error($link), @ldap_errno($link));
             }
         }
         unset($this->_changes['add'][$attr]);
     }
     foreach ($this->_changes['delete'] as $attr => $value) {
         /* In LDAPv3 you need to specify the old values for deleting. */
         if (is_null($value) && $ldap->getVersion() == 3) {
             $value = $this->_original[$attr];
         }
         if (!@ldap_mod_del($link, $this->dn(), array($attr => $value))) {
             throw new Horde_Ldap_Exception('Could not delete attribute ' . $attr . ': ' . @ldap_error($link), @ldap_errno($link));
         }
         unset($this->_changes['delete'][$attr]);
     }
     foreach ($this->_changes['replace'] as $attr => $value) {
         if (!@ldap_modify($link, $this->dn(), array($attr => $value))) {
             throw new Horde_Ldap_Exception('Could not replace attribute ' . $attr . ' values: ' . @ldap_error($link), @ldap_errno($link));
         }
         unset($this->_changes['replace'][$attr]);
     }
     /* All went well, so $_attributes (local copy) becomes $_original
      * (server). */
     $this->_original = $this->_attributes;
 }
Exemple #4
0
 /**
  * Get the parent GUID of this object.
  *
  * @param string $guid The GUID of the child.
  *
  * @return string the parent GUID of this object.
  */
 public function getParentGuid($guid)
 {
     try {
         $base = Horde_Ldap_Util::explodeDN($guid, array('casefold' => 'none', 'reverse' => false, 'onlyvalues' => false));
         $id = array_shift($base);
         $parent = Horde_Ldap_Util::canonicalDN($base, array('casefold' => 'none'));
     } catch (Horde_Ldap_Exception $e) {
         throw new Horde_Kolab_Server_Exception('Retrieving the parent object failed!', Horde_Kolab_Server_Exception::SYSTEM, $e);
     }
     return $parent;
 }
Exemple #5
0
 /**
  * Returns whether a DN exists in the directory.
  *
  * @param string|Horde_Ldap_Entry $dn The DN of the object to test.
  *
  * @return boolean  True if the DN exists.
  * @throws Horde_Ldap_Exception
  */
 public function exists($dn)
 {
     if ($dn instanceof Horde_Ldap_Entry) {
         $dn = $dn->dn();
     }
     if (!is_string($dn)) {
         throw new Horde_Ldap_Exception('Parameter $dn is not a string nor an entry object!');
     }
     /* Make dn relative to parent. */
     $options = array('casefold' => 'none');
     $base = Horde_Ldap_Util::explodeDN($dn, $options);
     $entry_rdn = '(&(' . Horde_Ldap_Util::canonicalDN(array_shift($base), array_merge($options, array('separator' => ')('))) . '))';
     $base = Horde_Ldap_Util::canonicalDN($base, $options);
     $result = @ldap_list($this->_link, $base, $entry_rdn, array('dn'), 1, 1);
     if ($result && @ldap_count_entries($this->_link, $result)) {
         return true;
     }
     if ($this->errorName(@ldap_errno($this->_link)) == 'LDAP_NO_SUCH_OBJECT') {
         return false;
     }
     if (@ldap_errno($this->_link)) {
         throw new Horde_Ldap_Exception(@ldap_error($this->_link), @ldap_errno($this->_link));
     }
     return false;
 }
Exemple #6
0
 /**
  * Tests Ldap_explode_dn()
  */
 public function testExplodeDN()
 {
     $dn = 'ou=Sales+CN=J. Smith,dc=example,dc=net';
     $expected_casefold_none = array(array('CN=J. Smith', 'ou=Sales'), 'dc=example', 'dc=net');
     $expected_casefold_upper = array(array('CN=J. Smith', 'OU=Sales'), 'DC=example', 'DC=net');
     $expected_casefold_lower = array(array('cn=J. Smith', 'ou=Sales'), 'dc=example', 'dc=net');
     $expected_onlyvalues = array(array('J. Smith', 'Sales'), 'example', 'net');
     $expected_reverse = array_reverse($expected_casefold_upper);
     $dn_exploded_cnone = Horde_Ldap_Util::explodeDN($dn, array('casefold' => 'none'));
     $this->assertEquals($expected_casefold_none, $dn_exploded_cnone, 'Option casefold none failed');
     $dn_exploded_cupper = Horde_Ldap_Util::explodeDN($dn, array('casefold' => 'upper'));
     $this->assertEquals($expected_casefold_upper, $dn_exploded_cupper, 'Option casefold upper failed');
     $dn_exploded_clower = Horde_Ldap_Util::explodeDN($dn, array('casefold' => 'lower'));
     $this->assertEquals($expected_casefold_lower, $dn_exploded_clower, 'Option casefold lower failed');
     $dn_exploded_onlyval = Horde_Ldap_Util::explodeDN($dn, array('onlyvalues' => true));
     $this->assertEquals($expected_onlyvalues, $dn_exploded_onlyval, 'Option onlyval failed');
     $dn_exploded_reverse = Horde_Ldap_Util::explodeDN($dn, array('reverse' => true));
     $this->assertEquals($expected_reverse, $dn_exploded_reverse, 'Option reverse failed');
     $this->assertEquals(array('CN=J\\, Smith', 'DC=example', 'DC=net'), Horde_Ldap_Util::explodeDN('cn=J\\, Smith,dc=example,dc=net'));
 }
Exemple #7
0
 /**
  * Writes an LDIF file that describes an entry change.
  *
  * @param Horde_Ldap_Entry $entry
  *
  * @throws Horde_Ldap_Exception
  */
 protected function _changeEntry($entry)
 {
     // Fetch change information from entry.
     $entry_attrs_changes = $entry->getChanges();
     $num_of_changes = count($entry_attrs_changes['add']) + count($entry_attrs_changes['replace']) + count($entry_attrs_changes['delete']);
     $is_changed = $num_of_changes > 0 || $entry->willBeDeleted() || $entry->willBeMoved();
     // Write version if not done yet, also write DN of entry.
     if ($is_changed) {
         if (!$this->_versionWritten) {
             $this->writeVersion();
         }
         $this->_writeDN($entry->currentDN());
     }
     // Process changes.
     // TODO: consider DN add!
     if ($entry->willBeDeleted()) {
         $this->_writeLine('changetype: delete');
     } elseif ($entry->willBeMoved()) {
         $this->_writeLine('changetype: modrdn');
         $olddn = Horde_Ldap_Util::explodeDN($entry->currentDN(), array('casefold' => 'none'));
         array_shift($olddn);
         $oldparent = implode(',', $olddn);
         $newdn = Horde_Ldap_Util::explodeDN($entry->dn(), array('casefold' => 'none'));
         $rdn = array_shift($newdn);
         $parent = implode(',', $newdn);
         $this->_writeLine('newrdn: ' . $rdn);
         $this->_writeLine('deleteoldrdn: 1');
         if ($parent !== $oldparent) {
             $this->_writeLine('newsuperior: ' . $parent);
         }
         // TODO: What if the entry has attribute changes as well?
         //       I think we should check for that and make a dummy
         //       entry with the changes that is written to the LDIF file.
     } elseif ($num_of_changes > 0) {
         // Write attribute change data.
         $this->_writeLine('changetype: modify');
         foreach ($entry_attrs_changes as $changetype => $entry_attrs) {
             foreach ($entry_attrs as $attr_name => $attr_values) {
                 $this->_writeLine("{$changetype}: {$attr_name}");
                 if ($attr_values !== null) {
                     $this->_writeAttribute($attr_name, $attr_values, $changetype);
                 }
                 $this->_writeLine('-');
             }
         }
     }
     // Finish this entry's data if we had changes.
     if ($is_changed) {
         $this->_finishEntry();
     }
 }
Exemple #8
0
 /**
  * Test adding a person with two common names.
  *
  * @return NULL
  */
 public function testAddDoubleCnPerson()
 {
     foreach ($this->servers as $server) {
         $person = $this->assertAdd($server, $this->objects[5], array());
         $cn_result = $server->uidForCn($this->objects[5]['Cn'][0]);
         $this->assertNoError($cn_result);
         $dn_parts = Horde_Ldap_Util::explodeDN($cn_result, array('casefold' => 'lower'));
         $dnpart = Horde_Ldap_Util::unescapeDNValue($dn_parts[0]);
         $this->assertContains('Cn' . '=' . $this->objects[5]['Cn'][0], $dnpart[0]);
     }
 }
Exemple #9
0
 /**
  * Returns a list of users in a group.
  *
  * @param mixed $gid  A group ID.
  *
  * @return array  List of group users.
  * @throws Horde_Group_Exception
  * @throws Horde_Exception_NotFound
  */
 public function listUsers($gid)
 {
     $attr = $this->_params['memberuid'];
     try {
         $entry = $this->_ldap->getEntry($gid, array($attr));
         if (!$entry->exists($attr)) {
             return array();
         }
         if (empty($this->_params['attrisdn'])) {
             return $entry->getValue($attr, 'all');
         }
         $users = array();
         foreach ($entry->getValue($attr, 'all') as $user) {
             $dn = Horde_Ldap_Util::explodeDN($user, array('onlyvalues' => true));
             // Very simplified approach: assume the first element of the DN
             // contains the user ID.
             $user = $dn[0];
             // Check for multi-value RDNs.
             if (is_array($element)) {
                 $user = $element[0];
             }
             $users[] = $user;
         }
         return $users;
     } catch (Horde_Ldap_Exception $e) {
         throw new Horde_Group_Exception($e);
     }
 }