JOOMLA中国
  • Joomla中国首页
  • 社区
  • 教程
  • 应用市场
  • B计划
Joomla! Framework TM
  • Namespace
  • Class
  • Tree
  • Deprecated

Namespaces

  • Composer
    • Autoload
  • Joomla
    • Application
      • Cli
        • Output
          • Processor
      • Web
    • Data
    • DI
      • Exception
    • Event
    • Filter
    • Input
    • Ldap
    • Registry
      • Format
    • Session
      • Storage
    • String
    • Uri
    • Utilities
  • None
  • PasswordCompat
    • binary
  • PHP
  • Psr
    • Log
  • Symfony
    • Component
      • Yaml
        • Exception
    • Polyfill
      • Util

Classes

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