PageRenderTime 123ms CodeModel.GetById 3ms RepoModel.GetById 0ms app.codeStats 0ms

/library/Zend/Auth/Adapter/Ldap.php

https://bitbucket.org/baruffaldi/cms-php-bfcms
PHP | 296 lines | 127 code | 34 blank | 135 comment | 18 complexity | f2db0494f3310cbb2da92b66ebaa3cab 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_Auth
  17. * @subpackage Zend_Auth_Adapter
  18. * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
  19. * @license http://framework.zend.com/license/new-bsd New BSD License
  20. * @version $Id: Ldap.php 10171 2008-07-18 04:57:08Z miallen $
  21. */
  22. /**
  23. * @see Zend_Auth_Adapter_Interface
  24. */
  25. require_once 'Zend/Auth/Adapter/Interface.php';
  26. /**
  27. * @category Zend
  28. * @package Zend_Auth
  29. * @subpackage Zend_Auth_Adapter
  30. * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
  31. * @license http://framework.zend.com/license/new-bsd New BSD License
  32. */
  33. class Zend_Auth_Adapter_Ldap implements Zend_Auth_Adapter_Interface
  34. {
  35. /**
  36. * The Zend_Ldap context.
  37. *
  38. * @var Zend_Ldap
  39. */
  40. protected $_ldap = null;
  41. /**
  42. * The array of arrays of Zend_Ldap options passed to the constructor.
  43. *
  44. * @var array
  45. */
  46. protected $_options = null;
  47. /**
  48. * The username of the account being authenticated.
  49. *
  50. * @var string
  51. */
  52. protected $_username = null;
  53. /**
  54. * The password of the account being authenticated.
  55. *
  56. * @var string
  57. */
  58. protected $_password = null;
  59. /**
  60. * Constructor
  61. *
  62. * @param array $options An array of arrays of Zend_Ldap options
  63. * @param string $username The username of the account being authenticated
  64. * @param string $password The password of the account being authenticated
  65. * @return void
  66. */
  67. public function __construct(array $options = array(), $username = null, $password = null)
  68. {
  69. $this->setOptions($options);
  70. if ($username !== null) {
  71. $this->setUsername($username);
  72. }
  73. if ($password !== null) {
  74. $this->setPassword($password);
  75. }
  76. }
  77. /**
  78. * Returns the array of arrays of Zend_Ldap options of this adapter.
  79. *
  80. * @return array|null
  81. */
  82. public function getOptions()
  83. {
  84. return $this->_options;
  85. }
  86. /**
  87. * Sets the array of arrays of Zend_Ldap options to be used by
  88. * this adapter.
  89. *
  90. * @param array $options The array of arrays of Zend_Ldap options
  91. * @return Zend_Auth_Adapter_Ldap Provides a fluent interface
  92. */
  93. public function setOptions($options)
  94. {
  95. $this->_options = is_array($options) ? $options : array();
  96. return $this;
  97. }
  98. /**
  99. * Returns the username of the account being authenticated, or
  100. * NULL if none is set.
  101. *
  102. * @return string|null
  103. */
  104. public function getUsername()
  105. {
  106. return $this->_username;
  107. }
  108. /**
  109. * Sets the username for binding
  110. *
  111. * @param string $username The username for binding
  112. * @return Zend_Auth_Adapter_Ldap Provides a fluent interface
  113. */
  114. public function setUsername($username)
  115. {
  116. $this->_username = (string) $username;
  117. return $this;
  118. }
  119. /**
  120. * Returns the password of the account being authenticated, or
  121. * NULL if none is set.
  122. *
  123. * @return string|null
  124. */
  125. public function getPassword()
  126. {
  127. return $this->_password;
  128. }
  129. /**
  130. * Sets the passwort for the account
  131. *
  132. * @param string $password The password of the account being authenticated
  133. * @return Zend_Auth_Adapter_Ldap Provides a fluent interface
  134. */
  135. public function setPassword($password)
  136. {
  137. $this->_password = (string) $password;
  138. return $this;
  139. }
  140. /**
  141. * Returns the LDAP Object
  142. *
  143. * @return Zend_Ldap The Zend_Ldap object used to authenticate the credentials
  144. */
  145. public function getLdap()
  146. {
  147. if ($this->_ldap === null) {
  148. /**
  149. * @see Zend_Ldap
  150. */
  151. require_once 'Zend/Ldap.php';
  152. $this->_ldap = new Zend_Ldap();
  153. }
  154. return $this->_ldap;
  155. }
  156. /**
  157. * Authenticate the user
  158. *
  159. * @throws Zend_Auth_Adapter_Exception
  160. * @return Zend_Auth_Result
  161. */
  162. public function authenticate()
  163. {
  164. /**
  165. * @see Zend_Ldap_Exception
  166. */
  167. require_once 'Zend/Ldap/Exception.php';
  168. $messages = array();
  169. $messages[0] = ''; // reserved
  170. $messages[1] = ''; // reserved
  171. $username = $this->_username;
  172. $password = $this->_password;
  173. if (!$username) {
  174. $code = Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND;
  175. $messages[0] = 'A username is required';
  176. return new Zend_Auth_Result($code, '', $messages);
  177. }
  178. if (!$password) {
  179. /* A password is required because some servers will
  180. * treat an empty password as an anonymous bind.
  181. */
  182. $code = Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID;
  183. $messages[0] = 'A password is required';
  184. return new Zend_Auth_Result($code, '', $messages);
  185. }
  186. $ldap = $this->getLdap();
  187. $code = Zend_Auth_Result::FAILURE;
  188. $messages[0] = "Authority not found: $username";
  189. /* Iterate through each server and try to authenticate the supplied
  190. * credentials against it.
  191. */
  192. foreach ($this->_options as $name => $options) {
  193. if (!is_array($options)) {
  194. /**
  195. * @see Zend_Auth_Adapter_Exception
  196. */
  197. require_once 'Zend/Auth/Adapter/Exception.php';
  198. throw new Zend_Auth_Adapter_Exception('Adapter options array not in array');
  199. }
  200. $ldap->setOptions($options);
  201. try {
  202. $canonicalName = $ldap->getCanonicalAccountName($username);
  203. if ($messages[1])
  204. $messages[] = $messages[1];
  205. $messages[1] = '';
  206. $messages[] = $this->_optionsToString($options);
  207. $ldap->bind($canonicalName, $password);
  208. $messages[0] = '';
  209. $messages[1] = '';
  210. $messages[] = "$canonicalName authentication successful";
  211. return new Zend_Auth_Result(Zend_Auth_Result::SUCCESS, $canonicalName, $messages);
  212. } catch (Zend_Ldap_Exception $zle) {
  213. /* LDAP based authentication is notoriously difficult to diagnose. Therefore
  214. * we bend over backwards to capture and record every possible bit of
  215. * information when something goes wrong.
  216. */
  217. $err = $zle->getCode();
  218. if ($err == Zend_Ldap_Exception::LDAP_X_DOMAIN_MISMATCH) {
  219. /* This error indicates that the domain supplied in the
  220. * username did not match the domains in the server options
  221. * and therefore we should just skip to the next set of
  222. * server options.
  223. */
  224. continue;
  225. } else if ($err == Zend_Ldap_Exception::LDAP_NO_SUCH_OBJECT) {
  226. $code = Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND;
  227. $messages[0] = "Account not found: $username";
  228. } else if ($err == Zend_Ldap_Exception::LDAP_INVALID_CREDENTIALS) {
  229. $code = Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID;
  230. $messages[0] = 'Invalid credentials';
  231. } else {
  232. $line = $zle->getLine();
  233. $messages[] = $zle->getFile() . "($line): " . $zle->getMessage();
  234. $messages[] = str_replace($password, '*****', $zle->getTraceAsString());
  235. $messages[0] = 'An unexpected failure occurred';
  236. }
  237. $messages[1] = $zle->getMessage();
  238. }
  239. }
  240. $msg = isset($messages[1]) ? $messages[1] : $messages[0];
  241. $messages[] = "$username authentication failed: $msg";
  242. return new Zend_Auth_Result($code, $username, $messages);
  243. }
  244. /**
  245. * Converts options to string
  246. *
  247. * @param array $options
  248. * @return string
  249. */
  250. private function _optionsToString(array $options)
  251. {
  252. $str = '';
  253. foreach ($options as $key => $val) {
  254. if ($key === 'password')
  255. $val = '*****';
  256. if ($str)
  257. $str .= ',';
  258. $str .= $key . '=' . $val;
  259. }
  260. return $str;
  261. }
  262. }