PageRenderTime 61ms CodeModel.GetById 33ms RepoModel.GetById 0ms app.codeStats 0ms

/libraries/joomla/client/ldap.php

https://bitbucket.org/biojazzard/joomla-eboracast
PHP | 683 lines | 367 code | 62 blank | 254 comment | 27 complexity | eaaac8942189ac94b66378c2b4a8a6c5 MD5 | raw file
Possible License(s): LGPL-2.1, GPL-2.0, MIT, BSD-3-Clause
  1. <?php
  2. /**
  3. * @package Joomla.Platform
  4. * @subpackage Client
  5. *
  6. * @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
  7. * @license GNU General Public License version 2 or later; see LICENSE
  8. */
  9. defined('JPATH_PLATFORM') or die;
  10. /**
  11. * LDAP client class
  12. *
  13. * @package Joomla.Platform
  14. * @subpackage Client
  15. * @since 12.1
  16. */
  17. class JClientLdap
  18. {
  19. /**
  20. * @var string Hostname of LDAP server
  21. * @since 12.1
  22. */
  23. public $host = null;
  24. /**
  25. * @var bool Authorization Method to use
  26. * @since 12.1
  27. */
  28. public $auth_method = null;
  29. /**
  30. * @var int Port of LDAP server
  31. * @since 12.1
  32. */
  33. public $port = null;
  34. /**
  35. * @var string Base DN (e.g. o=MyDir)
  36. * @since 12.1
  37. */
  38. public $base_dn = null;
  39. /**
  40. * @var string User DN (e.g. cn=Users,o=MyDir)
  41. * @since 12.1
  42. */
  43. public $users_dn = null;
  44. /**
  45. * @var string Search String
  46. * @since 12.1
  47. */
  48. public $search_string = null;
  49. /**
  50. * @var boolean Use LDAP Version 3
  51. * @since 12.1
  52. */
  53. public $use_ldapV3 = null;
  54. /**
  55. * @var boolean No referrals (server transfers)
  56. * @since 11.1
  57. */
  58. public $no_referrals = null;
  59. /**
  60. * @var boolean Negotiate TLS (encrypted communications)
  61. * @since 12.1
  62. */
  63. public $negotiate_tls = null;
  64. /**
  65. * @var string Username to connect to server
  66. * @since 12.1
  67. */
  68. public $username = null;
  69. /**
  70. *
  71. * @var string Password to connect to server
  72. * @since 12.1
  73. */
  74. public $password = null;
  75. /**
  76. * @var mixed LDAP Resource Identifier
  77. * @since 12.1
  78. */
  79. private $_resource = null;
  80. /**
  81. *
  82. * @var string Current DN
  83. * @since 12.1
  84. */
  85. private $_dn = null;
  86. /**
  87. * Constructor
  88. *
  89. * @param object $configObj An object of configuration variables
  90. *
  91. * @since 12.1
  92. */
  93. public function __construct($configObj = null)
  94. {
  95. if (is_object($configObj))
  96. {
  97. $vars = get_class_vars(get_class($this));
  98. foreach (array_keys($vars) as $var)
  99. {
  100. if (substr($var, 0, 1) != '_')
  101. {
  102. $param = $configObj->get($var);
  103. if ($param)
  104. {
  105. $this->$var = $param;
  106. }
  107. }
  108. }
  109. }
  110. }
  111. /**
  112. * Connect to server
  113. *
  114. * @return boolean True if successful
  115. *
  116. * @since 12.1
  117. */
  118. public function connect()
  119. {
  120. if ($this->host == '')
  121. {
  122. return false;
  123. }
  124. $this->_resource = @ ldap_connect($this->host, $this->port);
  125. if ($this->_resource)
  126. {
  127. if ($this->use_ldapV3)
  128. {
  129. if (!@ldap_set_option($this->_resource, LDAP_OPT_PROTOCOL_VERSION, 3))
  130. {
  131. return false;
  132. }
  133. }
  134. if (!@ldap_set_option($this->_resource, LDAP_OPT_REFERRALS, (int) $this->no_referrals))
  135. {
  136. return false;
  137. }
  138. if ($this->negotiate_tls)
  139. {
  140. if (!@ldap_start_tls($this->_resource))
  141. {
  142. return false;
  143. }
  144. }
  145. return true;
  146. }
  147. else
  148. {
  149. return false;
  150. }
  151. }
  152. /**
  153. * Close the connection
  154. *
  155. * @return void
  156. *
  157. * @since 12.1
  158. */
  159. public function close()
  160. {
  161. @ ldap_close($this->_resource);
  162. }
  163. /**
  164. * Sets the DN with some template replacements
  165. *
  166. * @param string $username The username
  167. * @param string $nosub ...
  168. *
  169. * @return void
  170. *
  171. * @since 12.1
  172. */
  173. public function setDN($username, $nosub = 0)
  174. {
  175. if ($this->users_dn == '' || $nosub)
  176. {
  177. $this->_dn = $username;
  178. }
  179. elseif (strlen($username))
  180. {
  181. $this->_dn = str_replace('[username]', $username, $this->users_dn);
  182. }
  183. else
  184. {
  185. $this->_dn = '';
  186. }
  187. }
  188. /**
  189. * Get the DN
  190. *
  191. * @return string The current dn
  192. *
  193. * @since 12.1
  194. */
  195. public function getDN()
  196. {
  197. return $this->_dn;
  198. }
  199. /**
  200. * Anonymously binds to LDAP directory
  201. *
  202. * @return array
  203. *
  204. * @since 12.1
  205. */
  206. public function anonymous_bind()
  207. {
  208. $bindResult = @ldap_bind($this->_resource);
  209. return $bindResult;
  210. }
  211. /**
  212. * Binds to the LDAP directory
  213. *
  214. * @param string $username The username
  215. * @param string $password The password
  216. * @param string $nosub ...
  217. *
  218. * @return boolean
  219. *
  220. * @since 12.1
  221. */
  222. public function bind($username = null, $password = null, $nosub = 0)
  223. {
  224. if (is_null($username))
  225. {
  226. $username = $this->username;
  227. }
  228. if (is_null($password))
  229. {
  230. $password = $this->password;
  231. }
  232. $this->setDN($username, $nosub);
  233. $bindResult = @ldap_bind($this->_resource, $this->getDN(), $password);
  234. return $bindResult;
  235. }
  236. /**
  237. * Perform an LDAP search using comma separated search strings
  238. *
  239. * @param string $search search string of search values
  240. *
  241. * @return array Search results
  242. *
  243. * @since 12.1
  244. */
  245. public function simple_search($search)
  246. {
  247. $results = explode(';', $search);
  248. foreach ($results as $key => $result)
  249. {
  250. $results[$key] = '(' . $result . ')';
  251. }
  252. return $this->search($results);
  253. }
  254. /**
  255. * Performs an LDAP search
  256. *
  257. * @param array $filters Search Filters (array of strings)
  258. * @param string $dnoverride DN Override
  259. * @param array $attributes An array of attributes to return (if empty, all fields are returned).
  260. *
  261. * @return array Multidimensional array of results
  262. *
  263. * @since 12.1
  264. */
  265. public function search(array $filters, $dnoverride = null, array $attributes = array())
  266. {
  267. $result = array();
  268. if ($dnoverride)
  269. {
  270. $dn = $dnoverride;
  271. }
  272. else
  273. {
  274. $dn = $this->base_dn;
  275. }
  276. $resource = $this->_resource;
  277. foreach ($filters as $search_filter)
  278. {
  279. $search_result = @ldap_search($resource, $dn, $search_filter, $attributes);
  280. if ($search_result && ($count = @ldap_count_entries($resource, $search_result)) > 0)
  281. {
  282. for ($i = 0; $i < $count; $i++)
  283. {
  284. $result[$i] = array();
  285. if (!$i)
  286. {
  287. $firstentry = @ldap_first_entry($resource, $search_result);
  288. }
  289. else
  290. {
  291. $firstentry = @ldap_next_entry($resource, $firstentry);
  292. }
  293. // Load user-specified attributes
  294. $result_array = @ldap_get_attributes($resource, $firstentry);
  295. // LDAP returns an array of arrays, fit this into attributes result array
  296. foreach ($result_array as $ki => $ai)
  297. {
  298. if (is_array($ai))
  299. {
  300. $subcount = $ai['count'];
  301. $result[$i][$ki] = array();
  302. for ($k = 0; $k < $subcount; $k++)
  303. {
  304. $result[$i][$ki][$k] = $ai[$k];
  305. }
  306. }
  307. }
  308. $result[$i]['dn'] = @ldap_get_dn($resource, $firstentry);
  309. }
  310. }
  311. }
  312. return $result;
  313. }
  314. /**
  315. * Replace an entry and return a true or false result
  316. *
  317. * @param string $dn The DN which contains the attribute you want to replace
  318. * @param string $attribute The attribute values you want to replace
  319. *
  320. * @return mixed result of comparison (true, false, -1 on error)
  321. *
  322. * @since 12.1
  323. */
  324. public function replace($dn, $attribute)
  325. {
  326. return @ldap_mod_replace($this->_resource, $dn, $attribute);
  327. }
  328. /**
  329. * Modifies an entry and return a true or false result
  330. *
  331. * @param string $dn The DN which contains the attribute you want to modify
  332. * @param string $attribute The attribute values you want to modify
  333. *
  334. * @return mixed result of comparison (true, false, -1 on error)
  335. *
  336. * @since 12.1
  337. */
  338. public function modify($dn, $attribute)
  339. {
  340. return @ldap_modify($this->_resource, $dn, $attribute);
  341. }
  342. /**
  343. * Removes attribute value from given dn and return a true or false result
  344. *
  345. * @param string $dn The DN which contains the attribute you want to remove
  346. * @param string $attribute The attribute values you want to remove
  347. *
  348. * @return mixed result of comparison (true, false, -1 on error)
  349. *
  350. * @since 12.1
  351. */
  352. public function remove($dn, $attribute)
  353. {
  354. $resource = $this->_resource;
  355. return @ldap_mod_del($resource, $dn, $attribute);
  356. }
  357. /**
  358. * Compare an entry and return a true or false result
  359. *
  360. * @param string $dn The DN which contains the attribute you want to compare
  361. * @param string $attribute The attribute whose value you want to compare
  362. * @param string $value The value you want to check against the LDAP attribute
  363. *
  364. * @return mixed result of comparison (true, false, -1 on error)
  365. *
  366. * @since 12.1
  367. */
  368. public function compare($dn, $attribute, $value)
  369. {
  370. return @ldap_compare($this->_resource, $dn, $attribute, $value);
  371. }
  372. /**
  373. * Read all or specified attributes of given dn
  374. *
  375. * @param string $dn The DN of the object you want to read
  376. *
  377. * @return mixed array of attributes or -1 on error
  378. *
  379. * @since 12.1
  380. */
  381. public function read($dn)
  382. {
  383. $base = substr($dn, strpos($dn, ',') + 1);
  384. $cn = substr($dn, 0, strpos($dn, ','));
  385. $result = @ldap_read($this->_resource, $base, $cn);
  386. if ($result)
  387. {
  388. return @ldap_get_entries($this->_resource, $result);
  389. }
  390. else
  391. {
  392. return $result;
  393. }
  394. }
  395. /**
  396. * Deletes a given DN from the tree
  397. *
  398. * @param string $dn The DN of the object you want to delete
  399. *
  400. * @return boolean Result of operation
  401. *
  402. * @since 12.1
  403. */
  404. public function delete($dn)
  405. {
  406. return @ldap_delete($this->_resource, $dn);
  407. }
  408. /**
  409. * Create a new DN
  410. *
  411. * @param string $dn The DN where you want to put the object
  412. * @param array $entries An array of arrays describing the object to add
  413. *
  414. * @return boolean Result of operation
  415. *
  416. * @since 12.1
  417. */
  418. public function create($dn, array $entries)
  419. {
  420. return @ldap_add($this->_resource, $dn, $entries);
  421. }
  422. /**
  423. * Add an attribute to the given DN
  424. * Note: DN has to exist already
  425. *
  426. * @param string $dn The DN of the entry to add the attribute
  427. * @param array $entry An array of arrays with attributes to add
  428. *
  429. * @return boolean Result of operation
  430. *
  431. * @since 12.1
  432. */
  433. public function add($dn, array $entry)
  434. {
  435. return @ldap_mod_add($this->_resource, $dn, $entry);
  436. }
  437. /**
  438. * Rename the entry
  439. *
  440. * @param string $dn The DN of the entry at the moment
  441. * @param string $newdn The DN of the entry should be (only cn=newvalue)
  442. * @param string $newparent The full DN of the parent (null by default)
  443. * @param boolean $deleteolddn Delete the old values (default)
  444. *
  445. * @return boolean Result of operation
  446. *
  447. * @since 12.1
  448. */
  449. public function rename($dn, $newdn, $newparent, $deleteolddn)
  450. {
  451. return @ldap_rename($this->_resource, $dn, $newdn, $newparent, $deleteolddn);
  452. }
  453. /**
  454. * Returns the error message
  455. *
  456. * @return string error message
  457. *
  458. * @since 12.1
  459. */
  460. public function getErrorMsg()
  461. {
  462. return @ldap_error($this->_resource);
  463. }
  464. /**
  465. * Converts a dot notation IP address to net address (e.g. for Netware, etc)
  466. *
  467. * @param string $ip IP Address (e.g. xxx.xxx.xxx.xxx)
  468. *
  469. * @return string Net address
  470. *
  471. * @since 12.1
  472. */
  473. public static function ipToNetAddress($ip)
  474. {
  475. $parts = explode('.', $ip);
  476. $address = '1#';
  477. foreach ($parts as $int)
  478. {
  479. $tmp = dechex($int);
  480. if (strlen($tmp) != 2)
  481. {
  482. $tmp = '0' . $tmp;
  483. }
  484. $address .= '\\' . $tmp;
  485. }
  486. return $address;
  487. }
  488. /**
  489. * Extract readable network address from the LDAP encoded networkAddress attribute.
  490. *
  491. * Please keep this document block and author attribution in place.
  492. *
  493. * Novell Docs, see: http://developer.novell.com/ndk/doc/ndslib/schm_enu/data/sdk5624.html#sdk5624
  494. * for Address types: http://developer.novell.com/ndk/doc/ndslib/index.html?page=/ndk/doc/ndslib/schm_enu/data/sdk4170.html
  495. * LDAP Format, String:
  496. * taggedData = uint32String "#" octetstring
  497. * byte 0 = uint32String = Address Type: 0= IPX Address; 1 = IP Address
  498. * byte 1 = char = "#" - separator
  499. * byte 2+ = octetstring - the ordinal value of the address
  500. * Note: with eDirectory 8.6.2, the IP address (type 1) returns
  501. * correctly, however, an IPX address does not seem to. eDir 8.7 may correct this.
  502. * Enhancement made by Merijn van de Schoot:
  503. * If addresstype is 8 (UDP) or 9 (TCP) do some additional parsing like still returning the IP address
  504. *
  505. * @param string $networkaddress The network address
  506. *
  507. * @return array
  508. *
  509. * @author Jay Burrell, Systems & Networks, Mississippi State University
  510. * @since 12.1
  511. */
  512. public static function LDAPNetAddr($networkaddress)
  513. {
  514. $addr = "";
  515. $addrtype = (int) substr($networkaddress, 0, 1);
  516. // Throw away bytes 0 and 1 which should be the addrtype and the "#" separator
  517. $networkaddress = substr($networkaddress, 2);
  518. if (($addrtype == 8) || ($addrtype = 9))
  519. {
  520. // TODO 1.6: If UDP or TCP, (TODO fill addrport and) strip portnumber information from address
  521. $networkaddress = substr($networkaddress, (strlen($networkaddress) - 4));
  522. }
  523. $addrtypes = array(
  524. 'IPX',
  525. 'IP',
  526. 'SDLC',
  527. 'Token Ring',
  528. 'OSI',
  529. 'AppleTalk',
  530. 'NetBEUI',
  531. 'Socket',
  532. 'UDP',
  533. 'TCP',
  534. 'UDP6',
  535. 'TCP6',
  536. 'Reserved (12)',
  537. 'URL',
  538. 'Count');
  539. $len = strlen($networkaddress);
  540. if ($len > 0)
  541. {
  542. for ($i = 0; $i < $len; $i++)
  543. {
  544. $byte = substr($networkaddress, $i, 1);
  545. $addr .= ord($byte);
  546. if (($addrtype == 1) || ($addrtype == 8) || ($addrtype = 9))
  547. {
  548. // Dot separate IP addresses...
  549. $addr .= ".";
  550. }
  551. }
  552. if (($addrtype == 1) || ($addrtype == 8) || ($addrtype = 9))
  553. {
  554. // Strip last period from end of $addr
  555. $addr = substr($addr, 0, strlen($addr) - 1);
  556. }
  557. }
  558. else
  559. {
  560. $addr .= JText::_('JLIB_CLIENT_ERROR_LDAP_ADDRESS_NOT_AVAILABLE');
  561. }
  562. return array('protocol' => $addrtypes[$addrtype], 'address' => $addr);
  563. }
  564. /**
  565. * Generates a LDAP compatible password
  566. *
  567. * @param string $password Clear text password to encrypt
  568. * @param string $type Type of password hash, either md5 or SHA
  569. *
  570. * @return string Encrypted password
  571. *
  572. * @since 12.1
  573. */
  574. public static function generatePassword($password, $type = 'md5')
  575. {
  576. switch (strtolower($type))
  577. {
  578. case 'sha':
  579. $userpassword = '{SHA}' . base64_encode(pack('H*', sha1($password)));
  580. break;
  581. case 'md5':
  582. default:
  583. $userpassword = '{MD5}' . base64_encode(pack('H*', md5($password)));
  584. break;
  585. }
  586. return $userpassword;
  587. }
  588. }
  589. /**
  590. * Deprecated class placeholder. You should use JClientLdap instead.
  591. *
  592. * @package Joomla.Platform
  593. * @subpackage Client
  594. * @since 11.1
  595. * @deprecated 12.3 (Platform) & 4.0 (CMS)
  596. */
  597. class JLDAP extends JClientLdap
  598. {
  599. /**
  600. * Constructor
  601. *
  602. * @param object $configObj An object of configuration variables
  603. *
  604. * @since 11.1
  605. */
  606. public function __construct($configObj = null)
  607. {
  608. JLog::add('JLDAP is deprecated. Use JClientLdap instead.', JLog::WARNING, 'deprecated');
  609. parent::__construct($configObj);
  610. }
  611. }