3 * Zend Framework (http://framework.zend.com/)
5 * @link http://github.com/zendframework/zf2 for the canonical source repository
6 * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
7 * @license http://framework.zend.com/license/new-bsd New BSD License
15 * Zend\Ldap\Attribute is a collection of LDAP attribute related functions.
19 const PASSWORD_HASH_MD5
= 'md5';
20 const PASSWORD_HASH_SMD5
= 'smd5';
21 const PASSWORD_HASH_SHA
= 'sha';
22 const PASSWORD_HASH_SSHA
= 'ssha';
23 const PASSWORD_UNICODEPWD
= 'unicodePwd';
26 * Sets a LDAP attribute.
29 * @param string $attribName
30 * @param string|array|\Traversable $value
34 public static function setAttribute(array &$data, $attribName, $value, $append = false)
36 $attribName = strtolower($attribName);
38 if (is_array($value) ||
($value instanceof \Traversable
)) {
39 foreach ($value as $v) {
40 $v = static::valueToLdap($v);
45 } elseif ($value !== null) {
46 $value = static::valueToLdap($value);
47 if ($value !== null) {
52 if ($append === true && isset($data[$attribName])) {
53 if (is_string($data[$attribName])) {
54 $data[$attribName] = array($data[$attribName]);
56 $data[$attribName] = array_merge($data[$attribName], $valArray);
58 $data[$attribName] = $valArray;
63 * Gets a LDAP attribute.
66 * @param string $attribName
70 public static function getAttribute(array $data, $attribName, $index = null)
72 $attribName = strtolower($attribName);
73 if ($index === null) {
74 if (!isset($data[$attribName])) {
78 foreach ($data[$attribName] as $v) {
79 $retArray[] = static::valueFromLdap($v);
82 } elseif (is_int($index)) {
83 if (!isset($data[$attribName])) {
85 } elseif ($index >= 0 && $index < count($data[$attribName])) {
86 return static::valueFromLdap($data[$attribName][$index]);
96 * Checks if the given value(s) exist in the attribute
99 * @param string $attribName
100 * @param mixed|array $value
103 public static function attributeHasValue(array &$data, $attribName, $value)
105 $attribName = strtolower($attribName);
106 if (!isset($data[$attribName])) {
110 if (is_scalar($value)) {
111 $value = array($value);
114 foreach ($value as $v) {
115 $v = self
::valueToLdap($v);
116 if (!in_array($v, $data[$attribName], true)) {
125 * Removes duplicate values from a LDAP attribute
128 * @param string $attribName
131 public static function removeDuplicatesFromAttribute(array &$data, $attribName)
133 $attribName = strtolower($attribName);
134 if (!isset($data[$attribName])) {
137 $data[$attribName] = array_values(array_unique($data[$attribName]));
141 * Remove given values from a LDAP attribute
144 * @param string $attribName
145 * @param mixed|array $value
148 public static function removeFromAttribute(array &$data, $attribName, $value)
150 $attribName = strtolower($attribName);
151 if (!isset($data[$attribName])) {
155 if (is_scalar($value)) {
156 $value = array($value);
160 foreach ($value as $v) {
161 $v = self
::valueToLdap($v);
167 $resultArray = $data[$attribName];
168 foreach ($valArray as $rv) {
169 $keys = array_keys($resultArray, $rv);
170 foreach ($keys as $k) {
171 unset($resultArray[$k]);
174 $resultArray = array_values($resultArray);
175 $data[$attribName] = $resultArray;
179 * @param mixed $value
180 * @return string|null
182 private static function valueToLdap($value)
184 return Converter\Converter
::toLdap($value);
188 * @param string $value
191 private static function valueFromLdap($value)
194 $return = Converter\Converter
::fromLdap($value, Converter\Converter
::STANDARD
, false);
195 if ($return instanceof DateTime
) {
196 return Converter\Converter
::toLdapDateTime($return, false);
200 } catch (Exception\InvalidArgumentException
$e) {
206 * Sets a LDAP password.
209 * @param string $password
210 * @param string $hashType Optional by default MD5
211 * @param string $attribName Optional
213 public static function setPassword(
214 array &$data, $password, $hashType = self
::PASSWORD_HASH_MD5
,
218 if ($attribName === null) {
219 if ($hashType === self
::PASSWORD_UNICODEPWD
) {
220 $attribName = 'unicodePwd';
222 $attribName = 'userPassword';
226 $hash = static::createPassword($password, $hashType);
227 static::setAttribute($data, $attribName, $hash, false);
231 * Creates a LDAP password.
233 * @param string $password
234 * @param string $hashType
237 public static function createPassword($password, $hashType = self
::PASSWORD_HASH_MD5
)
240 case self
::PASSWORD_UNICODEPWD
:
242 * http://msdn.microsoft.com/en-us/library/cc223248(PROT.10).aspx
244 $password = '"' . $password . '"';
245 if (function_exists('mb_convert_encoding')) {
246 $password = mb_convert_encoding($password, 'UTF-16LE', 'UTF-8');
247 } elseif (function_exists('iconv')) {
248 $password = iconv('UTF-8', 'UTF-16LE', $password);
250 $len = strlen($password);
252 for ($i = 0; $i < $len; $i++
) {
253 $new .= $password[$i] . "\x00";
258 case self
::PASSWORD_HASH_SSHA
:
259 $salt = substr(sha1(uniqid(mt_rand(), true), true), 0, 4);
260 $rawHash = sha1($password . $salt, true) . $salt;
263 case self
::PASSWORD_HASH_SHA
:
264 $rawHash = sha1($password, true);
267 case self
::PASSWORD_HASH_SMD5
:
268 $salt = substr(sha1(uniqid(mt_rand(), true), true), 0, 4);
269 $rawHash = md5($password . $salt, true) . $salt;
272 case self
::PASSWORD_HASH_MD5
:
274 $rawHash = md5($password, true);
278 return $method . base64_encode($rawHash);
282 * Sets a LDAP date/time attribute.
285 * @param string $attribName
286 * @param int|array|\Traversable $value
288 * @param bool $append
290 public static function setDateTimeAttribute(
291 array &$data, $attribName, $value, $utc = false,
295 $convertedValues = array();
296 if (is_array($value) ||
($value instanceof \Traversable
)) {
297 foreach ($value as $v) {
298 $v = static::valueToLdapDateTime($v, $utc);
300 $convertedValues[] = $v;
303 } elseif ($value !== null) {
304 $value = static::valueToLdapDateTime($value, $utc);
305 if ($value !== null) {
306 $convertedValues[] = $value;
309 static::setAttribute($data, $attribName, $convertedValues, $append);
315 * @return string|null
317 private static function valueToLdapDateTime($value, $utc)
319 if (is_int($value)) {
320 return Converter\Converter
::toLdapDateTime($value, $utc);
327 * Gets a LDAP date/time attribute.
330 * @param string $attribName
334 public static function getDateTimeAttribute(array $data, $attribName, $index = null)
336 $values = static::getAttribute($data, $attribName, $index);
337 if (is_array($values)) {
338 for ($i = 0; $i < count($values); $i++
) {
339 $newVal = static::valueFromLdapDateTime($values[$i]);
340 if ($newVal !== null) {
341 $values[$i] = $newVal;
345 $newVal = static::valueFromLdapDateTime($values);
346 if ($newVal !== null) {
355 * @param string|DateTime $value
358 private static function valueFromLdapDateTime($value)
360 if ($value instanceof DateTime
) {
361 return $value->format('U');
362 } elseif (is_string($value)) {
364 return Converter\Converter
::fromLdapDateTime($value, false)->format('U');
365 } catch (Converter\Exception\InvalidArgumentException
$e) {