PageRenderTime 44ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/vendor/zendframework/zendframework/library/Zend/Ldap/Attribute.php

https://bitbucket.org/pcelta/zf2
PHP | 376 lines | 242 code | 28 blank | 106 comment | 40 complexity | f772500856e4367cbe5c5441dd960d00 MD5 | raw file
  1. <?php
  2. /**
  3. * Zend Framework (http://framework.zend.com/)
  4. *
  5. * @link http://github.com/zendframework/zf2 for the canonical source repository
  6. * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
  7. * @license http://framework.zend.com/license/new-bsd New BSD License
  8. * @package Zend_Ldap
  9. */
  10. namespace Zend\Ldap;
  11. use DateTime;
  12. /**
  13. * Zend\Ldap\Attribute is a collection of LDAP attribute related functions.
  14. *
  15. * @category Zend
  16. * @package Zend_Ldap
  17. */
  18. class Attribute
  19. {
  20. const PASSWORD_HASH_MD5 = 'md5';
  21. const PASSWORD_HASH_SMD5 = 'smd5';
  22. const PASSWORD_HASH_SHA = 'sha';
  23. const PASSWORD_HASH_SSHA = 'ssha';
  24. const PASSWORD_UNICODEPWD = 'unicodePwd';
  25. /**
  26. * Sets a LDAP attribute.
  27. *
  28. * @param array $data
  29. * @param string $attribName
  30. * @param string|array|\Traversable $value
  31. * @param boolean $append
  32. * @return void
  33. */
  34. public static function setAttribute(array &$data, $attribName, $value, $append = false)
  35. {
  36. $attribName = strtolower($attribName);
  37. $valArray = array();
  38. if (is_array($value) || ($value instanceof \Traversable)) {
  39. foreach ($value as $v) {
  40. $v = static::valueToLdap($v);
  41. if ($v !== null) {
  42. $valArray[] = $v;
  43. }
  44. }
  45. } elseif ($value !== null) {
  46. $value = static::valueToLdap($value);
  47. if ($value !== null) {
  48. $valArray[] = $value;
  49. }
  50. }
  51. if ($append === true && isset($data[$attribName])) {
  52. if (is_string($data[$attribName])) {
  53. $data[$attribName] = array($data[$attribName]);
  54. }
  55. $data[$attribName] = array_merge($data[$attribName], $valArray);
  56. } else {
  57. $data[$attribName] = $valArray;
  58. }
  59. }
  60. /**
  61. * Gets a LDAP attribute.
  62. *
  63. * @param array $data
  64. * @param string $attribName
  65. * @param integer $index
  66. * @return array|mixed
  67. */
  68. public static function getAttribute(array $data, $attribName, $index = null)
  69. {
  70. $attribName = strtolower($attribName);
  71. if ($index === null) {
  72. if (!isset($data[$attribName])) {
  73. return array();
  74. }
  75. $retArray = array();
  76. foreach ($data[$attribName] as $v) {
  77. $retArray[] = static::valueFromLdap($v);
  78. }
  79. return $retArray;
  80. } elseif (is_int($index)) {
  81. if (!isset($data[$attribName])) {
  82. return null;
  83. } elseif ($index >= 0 && $index < count($data[$attribName])) {
  84. return static::valueFromLdap($data[$attribName][$index]);
  85. } else {
  86. return null;
  87. }
  88. }
  89. return null;
  90. }
  91. /**
  92. * Checks if the given value(s) exist in the attribute
  93. *
  94. * @param array $data
  95. * @param string $attribName
  96. * @param mixed|array $value
  97. * @return boolean
  98. */
  99. public static function attributeHasValue(array &$data, $attribName, $value)
  100. {
  101. $attribName = strtolower($attribName);
  102. if (!isset($data[$attribName])) {
  103. return false;
  104. }
  105. if (is_scalar($value)) {
  106. $value = array($value);
  107. }
  108. foreach ($value as $v) {
  109. $v = self::valueToLdap($v);
  110. if (!in_array($v, $data[$attribName], true)) {
  111. return false;
  112. }
  113. }
  114. return true;
  115. }
  116. /**
  117. * Removes duplicate values from a LDAP attribute
  118. *
  119. * @param array $data
  120. * @param string $attribName
  121. * @return void
  122. */
  123. public static function removeDuplicatesFromAttribute(array &$data, $attribName)
  124. {
  125. $attribName = strtolower($attribName);
  126. if (!isset($data[$attribName])) {
  127. return;
  128. }
  129. $data[$attribName] = array_values(array_unique($data[$attribName]));
  130. }
  131. /**
  132. * Remove given values from a LDAP attribute
  133. *
  134. * @param array $data
  135. * @param string $attribName
  136. * @param mixed|array $value
  137. * @return void
  138. */
  139. public static function removeFromAttribute(array &$data, $attribName, $value)
  140. {
  141. $attribName = strtolower($attribName);
  142. if (!isset($data[$attribName])) {
  143. return;
  144. }
  145. if (is_scalar($value)) {
  146. $value = array($value);
  147. }
  148. $valArray = array();
  149. foreach ($value as $v) {
  150. $v = self::valueToLdap($v);
  151. if ($v !== null) {
  152. $valArray[] = $v;
  153. }
  154. }
  155. $resultArray = $data[$attribName];
  156. foreach ($valArray as $rv) {
  157. $keys = array_keys($resultArray, $rv);
  158. foreach ($keys as $k) {
  159. unset($resultArray[$k]);
  160. }
  161. }
  162. $resultArray = array_values($resultArray);
  163. $data[$attribName] = $resultArray;
  164. }
  165. /**
  166. * @param mixed $value
  167. * @return string|null
  168. */
  169. private static function valueToLdap($value)
  170. {
  171. return Converter\Converter::toLdap($value);
  172. }
  173. /**
  174. * @param string $value
  175. * @return mixed
  176. */
  177. private static function valueFromLdap($value)
  178. {
  179. try {
  180. $return = Converter\Converter::fromLdap($value, Converter\Converter::STANDARD, false);
  181. if ($return instanceof DateTime) {
  182. return Converter\Converter::toLdapDateTime($return, false);
  183. } else {
  184. return $return;
  185. }
  186. } catch (Exception\InvalidArgumentException $e) {
  187. return $value;
  188. }
  189. }
  190. /**
  191. * Sets a LDAP password.
  192. *
  193. * @param array $data
  194. * @param string $password
  195. * @param string $hashType Optional by default MD5
  196. * @param string $attribName Optional
  197. */
  198. public static function setPassword(
  199. array &$data, $password, $hashType = self::PASSWORD_HASH_MD5,
  200. $attribName = null
  201. )
  202. {
  203. if ($attribName === null) {
  204. if ($hashType === self::PASSWORD_UNICODEPWD) {
  205. $attribName = 'unicodePwd';
  206. } else {
  207. $attribName = 'userPassword';
  208. }
  209. }
  210. $hash = static::createPassword($password, $hashType);
  211. static::setAttribute($data, $attribName, $hash, false);
  212. }
  213. /**
  214. * Creates a LDAP password.
  215. *
  216. * @param string $password
  217. * @param string $hashType
  218. * @return string
  219. */
  220. public static function createPassword($password, $hashType = self::PASSWORD_HASH_MD5)
  221. {
  222. switch ($hashType) {
  223. case self::PASSWORD_UNICODEPWD:
  224. /* see:
  225. * http://msdn.microsoft.com/en-us/library/cc223248(PROT.10).aspx
  226. */
  227. $password = '"' . $password . '"';
  228. if (function_exists('mb_convert_encoding')) {
  229. $password = mb_convert_encoding($password, 'UTF-16LE', 'UTF-8');
  230. } elseif (function_exists('iconv')) {
  231. $password = iconv('UTF-8', 'UTF-16LE', $password);
  232. } else {
  233. $len = strlen($password);
  234. $new = '';
  235. for ($i = 0; $i < $len; $i++) {
  236. $new .= $password[$i] . "\x00";
  237. }
  238. $password = $new;
  239. }
  240. return $password;
  241. case self::PASSWORD_HASH_SSHA:
  242. $salt = substr(sha1(uniqid(mt_rand(), true), true), 0, 4);
  243. $rawHash = sha1($password . $salt, true) . $salt;
  244. $method = '{SSHA}';
  245. break;
  246. case self::PASSWORD_HASH_SHA:
  247. $rawHash = sha1($password, true);
  248. $method = '{SHA}';
  249. break;
  250. case self::PASSWORD_HASH_SMD5:
  251. $salt = substr(sha1(uniqid(mt_rand(), true), true), 0, 4);
  252. $rawHash = md5($password . $salt, true) . $salt;
  253. $method = '{SMD5}';
  254. break;
  255. case self::PASSWORD_HASH_MD5:
  256. default:
  257. $rawHash = md5($password, true);
  258. $method = '{MD5}';
  259. break;
  260. }
  261. return $method . base64_encode($rawHash);
  262. }
  263. /**
  264. * Sets a LDAP date/time attribute.
  265. *
  266. * @param array $data
  267. * @param string $attribName
  268. * @param integer|array|\Traversable $value
  269. * @param boolean $utc
  270. * @param boolean $append
  271. */
  272. public static function setDateTimeAttribute(
  273. array &$data, $attribName, $value, $utc = false,
  274. $append = false
  275. )
  276. {
  277. $convertedValues = array();
  278. if (is_array($value) || ($value instanceof \Traversable)) {
  279. foreach ($value as $v) {
  280. $v = static::valueToLdapDateTime($v, $utc);
  281. if ($v !== null) {
  282. $convertedValues[] = $v;
  283. }
  284. }
  285. } elseif ($value !== null) {
  286. $value = static::valueToLdapDateTime($value, $utc);
  287. if ($value !== null) {
  288. $convertedValues[] = $value;
  289. }
  290. }
  291. static::setAttribute($data, $attribName, $convertedValues, $append);
  292. }
  293. /**
  294. * @param integer $value
  295. * @param boolean $utc
  296. * @return string|null
  297. */
  298. private static function valueToLdapDateTime($value, $utc)
  299. {
  300. if (is_int($value)) {
  301. return Converter\Converter::toLdapDateTime($value, $utc);
  302. }
  303. return null;
  304. }
  305. /**
  306. * Gets a LDAP date/time attribute.
  307. *
  308. * @param array $data
  309. * @param string $attribName
  310. * @param integer $index
  311. * @return array|integer
  312. */
  313. public static function getDateTimeAttribute(array $data, $attribName, $index = null)
  314. {
  315. $values = static::getAttribute($data, $attribName, $index);
  316. if (is_array($values)) {
  317. for ($i = 0; $i < count($values); $i++) {
  318. $newVal = static::valueFromLdapDateTime($values[$i]);
  319. if ($newVal !== null) {
  320. $values[$i] = $newVal;
  321. }
  322. }
  323. } else {
  324. $newVal = static::valueFromLdapDateTime($values);
  325. if ($newVal !== null) {
  326. $values = $newVal;
  327. }
  328. }
  329. return $values;
  330. }
  331. /**
  332. * @param string|DateTime $value
  333. * @return integer|null
  334. */
  335. private static function valueFromLdapDateTime($value)
  336. {
  337. if ($value instanceof DateTime) {
  338. return $value->format('U');
  339. } elseif (is_string($value)) {
  340. try {
  341. return Converter\Converter::fromLdapDateTime($value, false)->format('U');
  342. } catch (Converter\Exception\InvalidArgumentException $e) {
  343. return null;
  344. }
  345. }
  346. return null;
  347. }
  348. }