Projects
Kolab:3.4:Updates
php-pear-Net-LDAP3
pear-Net-LDAP3-1.0.1-collated.patch
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File pear-Net-LDAP3-1.0.1-collated.patch of Package php-pear-Net-LDAP3 (Revision 16)
Currently displaying revision
16
,
Show latest
diff --git a/lib/Net/LDAP3.php b/lib/Net/LDAP3.php index b1e0572..311b3d2 100644 --- a/lib/Net/LDAP3.php +++ b/lib/Net/LDAP3.php @@ -723,9 +723,9 @@ class Net_LDAP3 $moz_ldapsearch, '-x', '-h', - $this->_ldap_server, + $this->_current_host, '-p', - $this->_ldap_port, + $this->config_get('port', 389), '-b', escapeshellarg($entry_dn), '-s', @@ -1068,7 +1068,7 @@ class Net_LDAP3 return $replica_hosts; } - public function login($username, $password, $domain = null) + public function login($username, $password, $domain = null, &$attributes = null) { $this->_debug("Net_LDAP3::login(\$username = '" . $username . "', \$password = '****', \$domain = '" . $domain . "')"); @@ -1102,6 +1102,12 @@ class Net_LDAP3 return null; } + // fetch user attributes if requested + if (!empty($attributes)) { + $attributes = $this->get_entry($entry_dn, $attributes); + $attributes = self::normalize_entry($attributes, true); + } + return $entry_dn; } @@ -1149,7 +1155,7 @@ class Net_LDAP3 $this->_debug("Net::LDAP3::login() actual filter: " . $filter); - $result = $this->search($base_dn, $filter, 'sub'); + $result = $this->search($base_dn, $filter, 'sub', $attributes); if (!$result) { $this->_debug("Could not search $base_dn with $filter"); @@ -1165,9 +1171,8 @@ class Net_LDAP3 return null; } - $entries = $result->entries(); - $entry = self::normalize_result($entries); - $entry_dn = key($entry); + $entries = $result->entries(true); + $entry_dn = key($entries); $bound = $this->bind($entry_dn, $password); @@ -1176,6 +1181,11 @@ class Net_LDAP3 return null; } + // replace attributes list with key-value data + if (!empty($attributes)) { + $attributes = $entries[$entry_dn]; + } + return $entry_dn; } @@ -1288,7 +1298,7 @@ class Net_LDAP3 $this->_debug("old attrs. is array, new attrs. is not array. new attr. exists in old attrs."); - $rdn_attr_value = array_shift($old_attrs[$attr]); + $rdn_attr_value = array_shift($old_attrs[$attr]); $_attr_to_remove = array(); foreach ($old_attrs[$attr] as $value) { @@ -1303,14 +1313,14 @@ class Net_LDAP3 if (strtolower($new_attrs[$attr]) !== strtolower($rdn_attr_value)) { $this->_debug("new attrs is not the same as the old rdn value, issuing a rename"); - $mod_array['rename']['dn'] = $subject_dn; - $mod_array['rename']['new_rdn'] = $rdn_attr . '=' . $new_attrs[$attr][0]; + $mod_array['rename']['dn'] = $subject_dn; + $mod_array['rename']['new_rdn'] = $rdn_attr . '=' . self::quote_string($new_attrs[$attr], true); } } else { $this->_debug("new attrs is not the same as any of the old rdn value, issuing a full rename"); - $mod_array['rename']['dn'] = $subject_dn; - $mod_array['rename']['new_rdn'] = $rdn_attr . '=' . $new_attrs[$attr]; + $mod_array['rename']['dn'] = $subject_dn; + $mod_array['rename']['new_rdn'] = $rdn_attr . '=' . self::quote_string($new_attrs[$attr], true); } } else { @@ -1321,17 +1331,17 @@ class Net_LDAP3 } else { // TODO: This fails. - $mod_array['rename']['dn'] = $subject_dn; - $mod_array['rename']['new_rdn'] = $rdn_attr . '=' . $new_attrs[$attr][0]; - $mod_array['del'][$attr] = $old_attrs[$attr][0]; + $mod_array['rename']['dn'] = $subject_dn; + $mod_array['rename']['new_rdn'] = $rdn_attr . '=' . self::quote_string($new_attrs[$attr][0], true); + $mod_array['del'][$attr] = $old_attrs[$attr][0]; } } } else { if (!is_array($new_attrs[$attr])) { $this->_debug("Renaming " . $old_attrs[$attr] . " to " . $new_attrs[$attr]); - $mod_array['rename']['dn'] = $subject_dn; - $mod_array['rename']['new_rdn'] = $rdn_attr . '=' . $new_attrs[$attr]; + $mod_array['rename']['dn'] = $subject_dn; + $mod_array['rename']['new_rdn'] = $rdn_attr . '=' . self::quote_string($new_attrs[$attr], true); } else { $this->_debug("Adding to replace"); @@ -1340,7 +1350,6 @@ class Net_LDAP3 continue; } } - } else { if (!isset($new_attrs[$attr]) || $new_attrs[$attr] === '' || (is_array($new_attrs[$attr]) && empty($new_attrs[$attr]))) { @@ -1436,9 +1445,12 @@ class Net_LDAP3 $old_ou = implode(',', $subject_dn_components); } + $subject_dn = self::unified_dn($subject_dn); + $prefix = self::unified_dn('ou=' . $old_ou) . ','; + // object is an organizational unit - if (strpos($subject_dn, 'ou=' . $old_ou) === 0) { - $root = substr($subject_dn, strlen($old_ou) + 4); // remove ou=*, + if (strpos($subject_dn, $prefix) === 0) { + $root = substr($subject_dn, strlen($prefix)); // remove ou=*, if ((!empty($new_attrs['base_dn']) && strtolower($new_attrs['base_dn']) !== strtolower($root)) || (strtolower($old_ou) !== strtolower($new_ou)) @@ -1449,15 +1461,22 @@ class Net_LDAP3 $mod_array['rename']['new_parent'] = $root; $mod_array['rename']['dn'] = $subject_dn; - $mod_array['rename']['new_rdn'] = 'ou=' . $new_ou; + $mod_array['rename']['new_rdn'] = 'ou=' . self::quote_string($new_ou, true); } } // not OU object, but changed ou attribute - else if ((!empty($old_ou) && !empty($new_ou)) && strtolower($old_ou) !== strtolower($new_ou)) { - $mod_array['rename']['new_parent'] = $new_ou; - if (empty($mod_array['rename']['dn']) || empty($mod_array['rename']['new_rdn'])) { - $mod_array['rename']['dn'] = $subject_dn; - $mod_array['rename']['new_rdn'] = $rdn_attr . '=' . $new_attrs[$rdn_attr]; + else if (!empty($old_ou) && !empty($new_ou)) { + // unify DN strings for comparison + $old_ou = self::unified_dn($old_ou); + $new_ou = self::unified_dn($new_ou); + + if (strtolower($old_ou) !== strtolower($new_ou)) { + $mod_array['rename']['new_parent'] = $new_ou; + if (empty($mod_array['rename']['dn']) || empty($mod_array['rename']['new_rdn'])) { + $rdn_attr_value = self::quote_string($new_attrs[$rdn_attr], true); + $mod_array['rename']['dn'] = $subject_dn; + $mod_array['rename']['new_rdn'] = $rdn_attr . '=' . $rdn_attr_value; + } } } @@ -1747,10 +1766,11 @@ class Net_LDAP3 * Turn an LDAP entry into a regular PHP array with attributes as keys. * * @param array $entry Attributes array as retrieved from ldap_get_attributes() or ldap_get_entries() + * @param bool $flat Convert one-element-array values into strings * * @return array Hash array with attributes as keys */ - public static function normalize_entry($entry) + public static function normalize_entry($entry, $flat = false) { $rec = array(); for ($i=0; $i < $entry['count']; $i++) { @@ -1758,6 +1778,10 @@ class Net_LDAP3 for ($j=0; $j < $entry[$attr]['count']; $j++) { $rec[$attr][$j] = $entry[$attr][$j]; } + + if ($flat && count($rec[$attr]) == 1) { + $rec[$attr] = $rec[$attr][0]; + } } return $rec; @@ -1775,34 +1799,19 @@ class Net_LDAP3 $result = array(); for ($x = 0; $x < $_result['count']; $x++) { - $dn = $_result[$x]['dn']; - $result[$dn] = array(); - for ($y = 0; $y < $_result[$x]['count']; $y++) { - $attr = $_result[$x][$y]; - if ($_result[$x][$attr]['count'] == 1) { - switch ($attr) { - case 'objectclass': - $result[$dn][$attr] = array(strtolower($_result[$x][$attr][0])); - break; - default: - $result[$dn][$attr] = $_result[$x][$attr][0]; - break; - } + $dn = $_result[$x]['dn']; + $entry = self::normalize_entry($_result[$x], true); + + if (!empty($entry['objectclass'])) { + if (is_array($entry['objectclass'])) { + $entry['objectclass'] = array_map('strtolower', $entry['objectclass']); } else { - $result[$dn][$attr] = array(); - for ($z = 0; $z < $_result[$x][$attr]['count']; $z++) { - switch ($attr) { - case 'objectclass': - $result[$dn][$attr][] = strtolower($_result[$x][$attr][$z]); - break; - default: - $result[$dn][$attr][] = $_result[$x][$attr][$z]; - break; - } - } + $entry['objectclass'] = strtolower($entry['objectclass']); } } + + $result[$dn] = $entry; } return $result; @@ -1813,16 +1822,15 @@ class Net_LDAP3 switch ($scope) { case 2: return 'sub'; - break; + case 1: return 'one'; - break; + case 0: return 'base'; - break; + default: $this->_debug("Scope $scope is not a valid scope integer"); - break; } } @@ -1837,7 +1845,7 @@ class Net_LDAP3 { switch ($scope) { case 'sub': - $function = $ns_function = 'ldap_search'; + $function = $ns_function = 'ldap_search'; break; case 'base': $function = $ns_function = 'ldap_read'; @@ -2203,23 +2211,23 @@ class Net_LDAP3 private function modify_entry_attributes($subject_dn, $attributes) { - // Opportunities to set false include failed ldap commands. - $result = true; - if (is_array($attributes['rename']) && !empty($attributes['rename'])) { - $olddn = $attributes['rename']['dn']; - $newrdn = $attributes['rename']['new_rdn']; - - if (!empty($attributes['rename']['new_parent'])) { - $new_parent = $attributes['rename']['new_parent']; - } - else { - $new_parent = null; - } + $olddn = $attributes['rename']['dn']; + $newrdn = $attributes['rename']['new_rdn']; + $new_parent = $attributes['rename']['new_parent']; $this->_debug("LDAP: C: Rename $olddn to $newrdn,$new_parent"); - $result = ldap_rename($this->conn, $olddn, $newrdn, $new_parent, true); + // Note: for some reason the operation fails if RDN contains special characters + // and last argument of ldap_rename() is set to TRUE. That's why we use FALSE. + // However, we need to modify RDN attribute value later, otherwise it + // will contain an array of previous and current values + for ($i = 1; $i >= 0; $i--) { + $result = ldap_rename($this->conn, $olddn, $newrdn, $new_parent, $i == 1); + if ($result) { + break; + } + } if ($result) { $this->_debug("LDAP: S: OK"); @@ -2234,6 +2242,12 @@ class Net_LDAP3 $old_parent_dn = implode(",", $old_parent_dn_components); $subject_dn = $newrdn . ',' . $old_parent_dn; } + + // modify RDN attribute value, see note above + if (!$i && empty($attributes['replace'][$attr])) { + list($attr, $val) = explode('=', $newrdn, 2); + $attributes['replace'][$attr] = self::quote_string($val, true, true); + } } else { $this->_debug("LDAP: S: " . ldap_error($this->conn)); @@ -2291,7 +2305,7 @@ class Net_LDAP3 } private function parse_aclrights(&$attributes, $attribute_value) { - $components = explode(':', $rights); + $components = explode(':', $attribute_value); $_acl_target = array_shift($components); $_acl_value = trim(implode(':', $components)); @@ -2515,14 +2529,15 @@ class Net_LDAP3 /** * Quotes attribute value string * - * @param string $str Attribute value - * @param bool $dn True if the attribute is a DN + * @param string $str Attribute value + * @param bool $dn True if the attribute is a DN + * @param bool $reverse Do reverse replacement * * @return string Quoted string */ - public static function quote_string($str, $is_dn = false) + public static function quote_string($str, $is_dn = false, $reverse = false) { - // take firt entry if array given + // take first entry if array given if (is_array($str)) { $str = reset($str); } @@ -2550,10 +2565,42 @@ class Net_LDAP3 ); } + if ($reverse) { + return str_replace(array_values($replace), array_keys($replace), $str); + } + return strtr($str, $replace); } /** + * Unify DN string for comparison + * + * @para string $str DN string + * + * @return string Unified DN string + */ + public static function unified_dn($str) + { + $result = array(); + + foreach (explode(',', $str) as $token) { + list($attr, $value) = explode('=', $token, 2); + + $pos = 0; + while (preg_match('/\\\\[0-9a-fA-F]{2}/', $value, $matches, PREG_OFFSET_CAPTURE, $pos)) { + $char = chr(hexdec(substr($matches[0][0], 1))); + $pos = $matches[0][1]; + $value = substr_replace($value, $char, $pos, 3); + $pos += 1; + } + + $result[] = $attr . '=' . self::quote_string($value, true); + } + + return implode(',', $result); + } + + /** * create ber encoding for sort control * * @param array List of cols to sort by
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.