PageRenderTime 33ms CodeModel.GetById 12ms app.highlight 16ms RepoModel.GetById 1ms app.codeStats 0ms

/library/Zend/Ldap/Attribute.php

https://bitbucket.org/nosen/jelly2
PHP | 417 lines | 240 code | 26 blank | 151 comment | 53 complexity | 1ecd485aaad34f1ec4463f4879efc156 MD5 | raw file
  1<?php
  2/**
  3 * Zend Framework
  4 *
  5 * LICENSE
  6 *
  7 * This source file is subject to the new BSD license that is bundled
  8 * with this package in the file LICENSE.txt.
  9 * It is also available through the world-wide-web at this URL:
 10 * http://framework.zend.com/license/new-bsd
 11 * If you did not receive a copy of the license and are unable to
 12 * obtain it through the world-wide-web, please send an email
 13 * to license@zend.com so we can send you a copy immediately.
 14 *
 15 * @category   Zend
 16 * @package    Zend_Ldap
 17 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 18 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 19 * @version    $Id: Attribute.php 23775 2011-03-01 17:25:24Z ralph $
 20 */
 21
 22/**
 23 * @see Zend_Ldap_Converter
 24 */
 25require_once 'Zend/Ldap/Converter.php';
 26
 27/**
 28 * Zend_Ldap_Attribute is a collection of LDAP attribute related functions.
 29 *
 30 * @category   Zend
 31 * @package    Zend_Ldap
 32 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 33 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 34 */
 35class Zend_Ldap_Attribute
 36{
 37    const PASSWORD_HASH_MD5   = 'md5';
 38    const PASSWORD_HASH_SMD5  = 'smd5';
 39    const PASSWORD_HASH_SHA   = 'sha';
 40    const PASSWORD_HASH_SSHA  = 'ssha';
 41    const PASSWORD_UNICODEPWD = 'unicodePwd';
 42
 43    /**
 44     * Sets a LDAP attribute.
 45     *
 46     * @param  array                    $data
 47     * @param  string                   $attribName
 48     * @param  scalar|array|Traversable $value
 49     * @param  boolean                  $append
 50     * @return void
 51     */
 52    public static function setAttribute(array &$data, $attribName, $value, $append = false)
 53    {
 54        $attribName = strtolower($attribName);
 55        $valArray = array();
 56        if (is_array($value) || ($value instanceof Traversable))
 57        {
 58            foreach ($value as $v)
 59            {
 60                $v = self::_valueToLdap($v);
 61                if ($v !== null) $valArray[] = $v;
 62            }
 63        }
 64        else if ($value !== null)
 65        {
 66            $value = self::_valueToLdap($value);
 67            if ($value !== null) $valArray[] = $value;
 68        }
 69
 70        if ($append === true && isset($data[$attribName]))
 71        {
 72            if (is_string($data[$attribName])) $data[$attribName] = array($data[$attribName]);
 73            $data[$attribName] = array_merge($data[$attribName], $valArray);
 74        }
 75        else
 76        {
 77            $data[$attribName] = $valArray;
 78        }
 79    }
 80
 81    /**
 82     * Gets a LDAP attribute.
 83     *
 84     * @param  array   $data
 85     * @param  string  $attribName
 86     * @param  integer $index
 87     * @return array|mixed
 88     */
 89    public static function getAttribute(array $data, $attribName, $index = null)
 90    {
 91        $attribName = strtolower($attribName);
 92        if ($index === null) {
 93            if (!isset($data[$attribName])) return array();
 94            $retArray = array();
 95            foreach ($data[$attribName] as $v)
 96            {
 97                $retArray[] = self::_valueFromLdap($v);
 98            }
 99            return $retArray;
100        } else if (is_int($index)) {
101            if (!isset($data[$attribName])) {
102                return null;
103            } else if ($index >= 0 && $index<count($data[$attribName])) {
104                return self::_valueFromLdap($data[$attribName][$index]);
105            } else {
106                return null;
107            }
108        }
109        return null;
110    }
111
112    /**
113     * Checks if the given value(s) exist in the attribute
114     *
115     * @param array       $data
116     * @param string      $attribName
117     * @param mixed|array $value
118     * @return boolean
119     */
120    public static function attributeHasValue(array &$data, $attribName, $value)
121    {
122        $attribName = strtolower($attribName);
123        if (!isset($data[$attribName])) return false;
124
125        if (is_scalar($value)) {
126            $value = array($value);
127        }
128
129        foreach ($value as $v) {
130            $v = self::_valueToLdap($v);
131            if (!in_array($v, $data[$attribName], true)) {
132                return false;
133            }
134        }
135        return true;
136    }
137
138    /**
139     * Removes duplicate values from a LDAP attribute
140     *
141     * @param array  $data
142     * @param string $attribName
143     * @return void
144     */
145    public static function removeDuplicatesFromAttribute(array &$data, $attribName)
146    {
147        $attribName = strtolower($attribName);
148        if (!isset($data[$attribName])) return;
149        $data[$attribName] = array_values(array_unique($data[$attribName]));
150    }
151
152    /**
153     * Remove given values from a LDAP attribute
154     *
155     * @param array       $data
156     * @param string      $attribName
157     * @param mixed|array $value
158     * @return void
159     */
160    public static function removeFromAttribute(array &$data, $attribName, $value)
161    {
162        $attribName = strtolower($attribName);
163        if (!isset($data[$attribName])) return;
164
165        if (is_scalar($value)) {
166            $value = array($value);
167        }
168
169        $valArray = array();
170        foreach ($value as $v)
171        {
172            $v = self::_valueToLdap($v);
173            if ($v !== null) $valArray[] = $v;
174        }
175
176        $resultArray = $data[$attribName];
177        foreach ($valArray as $rv) {
178            $keys = array_keys($resultArray, $rv);
179            foreach ($keys as $k) {
180                unset($resultArray[$k]);
181            }
182        }
183        $resultArray = array_values($resultArray);
184        $data[$attribName] = $resultArray;
185    }
186
187    /**
188     * @param  mixed $value
189     * @return string|null
190     */
191    private static function _valueToLdap($value)
192    {
193        return Zend_Ldap_Converter::toLdap($value);
194    }
195
196    /**
197     * @param  string $value
198     * @return mixed
199     */
200    private static function _valueFromLdap($value)
201    {
202        try {
203            $return = Zend_Ldap_Converter::fromLdap($value, Zend_Ldap_Converter::STANDARD, false);
204            if ($return instanceof DateTime) {
205                return Zend_Ldap_Converter::toLdapDateTime($return, false);
206            } else {
207                return $return;
208            }
209        } catch (InvalidArgumentException $e) {
210            return $value;
211        }
212    }
213
214    /**
215     * Converts a PHP data type into its LDAP representation
216     *
217     * @deprected    use Zend_Ldap_Converter instead
218     * @param          mixed $value
219     * @return         string|null - null if the PHP data type cannot be converted.
220     */
221    public static function convertToLdapValue($value)
222    {
223        return self::_valueToLdap($value);
224    }
225
226    /**
227     * Converts an LDAP value into its PHP data type
228     *
229     * @deprected    use Zend_Ldap_Converter instead
230     * @param          string $value
231     * @return         mixed
232     */
233    public static function convertFromLdapValue($value)
234    {
235        return self::_valueFromLdap($value);
236    }
237
238    /**
239     * Converts a timestamp into its LDAP date/time representation
240     *
241     * @param  integer $value
242     * @param  boolean $utc
243     * @return string|null - null if the value cannot be converted.
244     */
245    public static function convertToLdapDateTimeValue($value, $utc = false)
246    {
247        return self::_valueToLdapDateTime($value, $utc);
248    }
249
250    /**
251     * Converts LDAP date/time representation into a timestamp
252     *
253     * @param  string $value
254     * @return integer|null - null if the value cannot be converted.
255     */
256    public static function convertFromLdapDateTimeValue($value)
257    {
258        return self::_valueFromLdapDateTime($value);
259    }
260
261    /**
262     * Sets a LDAP password.
263     *
264     * @param  array       $data
265     * @param  string      $password
266     * @param  string      $hashType
267     * @param  string|null $attribName
268     * @return null
269     */
270    public static function setPassword(array &$data, $password, $hashType = self::PASSWORD_HASH_MD5,
271        $attribName = null)
272    {
273        if ($attribName === null) {
274            if ($hashType === self::PASSWORD_UNICODEPWD) {
275                $attribName = 'unicodePwd';
276            } else {
277                $attribName = 'userPassword';
278            }
279        }
280
281        $hash = self::createPassword($password, $hashType);
282        self::setAttribute($data, $attribName, $hash, false);
283    }
284
285    /**
286     * Creates a LDAP password.
287     *
288     * @param  string $password
289     * @param  string $hashType
290     * @return string
291     */
292    public static function createPassword($password, $hashType = self::PASSWORD_HASH_MD5)
293    {
294        switch ($hashType) {
295            case self::PASSWORD_UNICODEPWD:
296                /* see:
297                 * http://msdn.microsoft.com/en-us/library/cc223248(PROT.10).aspx
298                 */
299                $password = '"' . $password . '"';
300                if (function_exists('mb_convert_encoding')) {
301                    $password = mb_convert_encoding($password, 'UTF-16LE', 'UTF-8');
302                } else if (function_exists('iconv')) {
303                    $password = iconv('UTF-8', 'UTF-16LE', $password);
304                } else {
305                    $len = strlen($password);
306                    $new = '';
307                    for($i=0; $i < $len; $i++) {
308                        $new .= $password[$i] . "\x00";
309                    }
310                    $password = $new;
311                }
312                return $password;
313            case self::PASSWORD_HASH_SSHA:
314                $salt    = substr(sha1(uniqid(mt_rand(), true), true), 0, 4);
315                $rawHash = sha1($password . $salt, true) . $salt;
316                $method  = '{SSHA}';
317                break;
318            case self::PASSWORD_HASH_SHA:
319                $rawHash = sha1($password, true);
320                $method  = '{SHA}';
321                break;
322            case self::PASSWORD_HASH_SMD5:
323                $salt    = substr(sha1(uniqid(mt_rand(), true), true), 0, 4);
324                $rawHash = md5($password . $salt, true) . $salt;
325                $method  = '{SMD5}';
326                break;
327            case self::PASSWORD_HASH_MD5:
328            default:
329                $rawHash = md5($password, true);
330                $method  = '{MD5}';
331                break;
332        }
333        return $method . base64_encode($rawHash);
334    }
335
336    /**
337     * Sets a LDAP date/time attribute.
338     *
339     * @param  array                     $data
340     * @param  string                    $attribName
341     * @param  integer|array|Traversable $value
342     * @param  boolean                   $utc
343     * @param  boolean                   $append
344     * @return null
345     */
346    public static function setDateTimeAttribute(array &$data, $attribName, $value, $utc = false,
347        $append = false)
348    {
349        $convertedValues = array();
350        if (is_array($value) || ($value instanceof Traversable))
351        {
352            foreach ($value as $v) {
353                $v = self::_valueToLdapDateTime($v, $utc);
354                if ($v !== null) $convertedValues[] = $v;
355            }
356        }
357        else if ($value !== null) {
358            $value = self::_valueToLdapDateTime($value, $utc);
359            if ($value !== null) $convertedValues[] = $value;
360        }
361        self::setAttribute($data, $attribName, $convertedValues, $append);
362    }
363
364    /**
365     * @param  integer $value
366     * @param  boolean $utc
367     * @return string|null
368     */
369    private static function _valueToLdapDateTime($value, $utc)
370    {
371        if (is_int($value)) {
372            return Zend_Ldap_Converter::toLdapDateTime($value, $utc);
373        }
374        else return null;
375    }
376
377    /**
378     * Gets a LDAP date/time attribute.
379     *
380     * @param  array   $data
381     * @param  string  $attribName
382     * @param  integer $index
383     * @return array|integer
384     */
385    public static function getDateTimeAttribute(array $data, $attribName, $index = null)
386    {
387        $values = self::getAttribute($data, $attribName, $index);
388        if (is_array($values)) {
389            for ($i = 0; $i<count($values); $i++) {
390                $newVal = self::_valueFromLdapDateTime($values[$i]);
391                if ($newVal !== null) $values[$i] = $newVal;
392            }
393        }
394        else {
395            $newVal = self::_valueFromLdapDateTime($values);
396            if ($newVal !== null) $values = $newVal;
397        }
398        return $values;
399    }
400
401    /**
402     * @param  string|DateTime $value
403     * @return integer|null
404     */
405    private static function _valueFromLdapDateTime($value)
406    {
407        if ($value instanceof DateTime) {
408            return $value->format('U');
409        } else if (is_string($value)) {
410            try {
411                return Zend_Ldap_Converter::fromLdapDateTime($value, false)->format('U');
412            } catch (InvalidArgumentException $e) {
413                return null;
414            }
415        } else return null;
416    }
417}