Ejemplo n.º 1
0
 /**
  * Explodes the given DN into its elements
  *
  * {@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:
  * <kbd>array( [0] => array([0] => 'OU=Sales', [1] => 'CN=J. Smith'), [2] => 'DC=example', [3] => 'DC=net' )</kbd>
  *
  * [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, ldap_explode_dn uses references to
  * the actual values, e.g. '1.3.6.1.4.1.1466.0=#04024869,DC=example,DC=com' is exploded to:
  * [ { '1.3.6.1.4.1.1466.0' => "\004\002Hi" }, { 'DC' => 'example' }, { '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.
  *
  * 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')
  *
  * @static
  * @author beni@php.net
  * @param string $dn      The DN that should be exploded
  * @param array  $options  Options to use
  * @return array    Parts of the exploded DN
  * @todo implement BER
  */
 function ldap_explode_dn($dn, $options = array('casefold' => 'upper'))
 {
     $options['onlyvalues'] == true ? $options['onlyvalues'] = 1 : ($options['onlyvalues'] = 0);
     !isset($options['reverse']) ? $options['reverse'] = false : ($options['reverse'] = true);
     if (!isset($options['casefold'])) {
         $options['casefold'] = 'upper';
     }
     // Escaping of DN and stripping of "OID."
     $dn = Net_LDAP_Util::canonical_dn($dn);
     // splitting the DN
     $dn_array = preg_split('/(?<=[^\\\\]),/', $dn);
     // construct subarrays for multivalued RDNs and unescape DN value
     // also convert to output format and apply casefolding
     foreach ($dn_array as $key => $value) {
         $value_u = Net_LDAP_Util::unescape_dn_value($value);
         $rdns = Net_LDAP_Util::split_rdn_multival($value_u[0]);
         if (count($rdns) > 1) {
             // MV RDN!
             foreach ($rdns as $subrdn_k => $subrdn_v) {
                 // Casefolding
                 if ($options['casefold'] == 'upper') {
                     $subrdn_v = preg_replace("/^(\\w+=)/e", "''.strtoupper('\\1').''", $subrdn_v);
                 }
                 if ($options['casefold'] == 'lower') {
                     $subrdn_v = preg_replace("/^(\\w+=)/e", "''.strtolower('\\1').''", $subrdn_v);
                 }
                 if ($options['onlyvalues']) {
                     preg_match('/(.+?)(?<!\\\\)=(.+)/', $subrdn_v, $matches);
                     $rdn_ocl = $matches[1];
                     $rdn_val = $matches[2];
                     $unescaped = Net_LDAP_Util::unescape_dn_value($rdn_val);
                     $rdns[$subrdn_k] = $unescaped[0];
                 } else {
                     $unescaped = Net_LDAP_Util::unescape_dn_value($subrdn_v);
                     $rdns[$subrdn_k] = $unescaped[0];
                 }
             }
             $dn_array[$key] = $rdns;
         } else {
             // normal RDN
             // Casefolding
             if ($options['casefold'] == 'upper') {
                 $value = preg_replace("/^(\\w+=)/e", "''.strtoupper('\\1').''", $value);
             }
             if ($options['casefold'] == 'lower') {
                 $value = preg_replace("/^(\\w+=)/e", "''.strtolower('\\1').''", $value);
             }
             if ($options['onlyvalues']) {
                 preg_match('/(.+?)(?<!\\\\)=(.+)/', $value, $matches);
                 $dn_ocl = $matches[1];
                 $dn_val = $matches[2];
                 $unescaped = Net_LDAP_Util::unescape_dn_value($dn_val);
                 $dn_array[$key] = $unescaped[0];
             } else {
                 $unescaped = Net_LDAP_Util::unescape_dn_value($value);
                 $dn_array[$key] = $unescaped[0];
             }
         }
     }
     if ($options['reverse']) {
         return array_reverse($dn_array);
     } else {
         return $dn_array;
     }
 }