PageRenderTime 42ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/libraries/joomla/client/ldap.php

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