PageRenderTime 48ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/joomla/libraries/joomla/client/ldap.php

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