PageRenderTime 90ms CodeModel.GetById 8ms RepoModel.GetById 0ms app.codeStats 1ms

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

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