TYPO3 CMS  TYPO3_7-6
adodb-ldap.inc.php
Go to the documentation of this file.
1 <?php
2 /*
3  @version v5.20.3 01-Jan-2016
4  @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
5  @copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
6  Released under both BSD license and Lesser GPL library license.
7  Whenever there is any discrepancy between the two licenses,
8  the BSD license will take precedence.
9  Set tabs to 8.
10 
11  Revision 1: (02/25/2005) Updated codebase to include the _inject_bind_options function. This allows
12  users to access the options in the ldap_set_option function appropriately. Most importantly
13  LDAP Version 3 is now supported. See the examples for more information. Also fixed some minor
14  bugs that surfaced when PHP error levels were set high.
15 
16  Joshua Eldridge (joshuae74#hotmail.com)
17 */
18 
19 // security - hide paths
20 if (!defined('ADODB_DIR')) die();
21 
22 if (!defined('LDAP_ASSOC')) {
23  define('LDAP_ASSOC',ADODB_FETCH_ASSOC);
24  define('LDAP_NUM',ADODB_FETCH_NUM);
25  define('LDAP_BOTH',ADODB_FETCH_BOTH);
26 }
27 
28 class ADODB_ldap extends ADOConnection {
29  var $databaseType = 'ldap';
30  var $dataProvider = 'ldap';
31 
32  # Connection information
33  var $username = false;
34  var $password = false;
35 
36  # Used during searches
37  var $filter;
38  var $dn;
39  var $version;
40  var $port = 389;
41 
42  # Options configuration information
44 
45  # error on binding, eg. "Binding: invalid credentials"
46  var $_bind_errmsg = "Binding: %s";
47 
48  function __construct()
49  {
50  }
51 
52  // returns true or false
53 
54  function _connect( $host, $username, $password, $ldapbase)
55  {
56  global $LDAP_CONNECT_OPTIONS;
57 
58  if ( !function_exists( 'ldap_connect' ) ) return null;
59 
60  if (strpos($host,'ldap://') === 0 || strpos($host,'ldaps://') === 0) {
61  $this->_connectionID = @ldap_connect($host);
62  } else {
63  $conn_info = array( $host,$this->port);
64 
65  if ( strstr( $host, ':' ) ) {
66  $conn_info = explode( ':', $host );
67  }
68 
69  $this->_connectionID = @ldap_connect( $conn_info[0], $conn_info[1] );
70  }
71  if (!$this->_connectionID) {
72  $e = 'Could not connect to ' . $conn_info[0];
73  $this->_errorMsg = $e;
74  if ($this->debug) ADOConnection::outp($e);
75  return false;
76  }
77  if( count( $LDAP_CONNECT_OPTIONS ) > 0 ) {
78  $this->_inject_bind_options( $LDAP_CONNECT_OPTIONS );
79  }
80 
81  if ($username) {
82  $bind = @ldap_bind( $this->_connectionID, $username, $password );
83  } else {
84  $username = 'anonymous';
85  $bind = @ldap_bind( $this->_connectionID );
86  }
87 
88  if (!$bind) {
89  $e = sprintf($this->_bind_errmsg,ldap_error($this->_connectionID));
90  $this->_errorMsg = $e;
91  if ($this->debug) ADOConnection::outp($e);
92  return false;
93  }
94  $this->_errorMsg = '';
95  $this->database = $ldapbase;
96  return $this->_connectionID;
97  }
98 
99 /*
100  Valid Domain Values for LDAP Options:
101 
102  LDAP_OPT_DEREF (integer)
103  LDAP_OPT_SIZELIMIT (integer)
104  LDAP_OPT_TIMELIMIT (integer)
105  LDAP_OPT_PROTOCOL_VERSION (integer)
106  LDAP_OPT_ERROR_NUMBER (integer)
107  LDAP_OPT_REFERRALS (boolean)
108  LDAP_OPT_RESTART (boolean)
109  LDAP_OPT_HOST_NAME (string)
110  LDAP_OPT_ERROR_STRING (string)
111  LDAP_OPT_MATCHED_DN (string)
112  LDAP_OPT_SERVER_CONTROLS (array)
113  LDAP_OPT_CLIENT_CONTROLS (array)
114 
115  Make sure to set this BEFORE calling Connect()
116 
117  Example:
118 
119  $LDAP_CONNECT_OPTIONS = Array(
120  Array (
121  "OPTION_NAME"=>LDAP_OPT_DEREF,
122  "OPTION_VALUE"=>2
123  ),
124  Array (
125  "OPTION_NAME"=>LDAP_OPT_SIZELIMIT,
126  "OPTION_VALUE"=>100
127  ),
128  Array (
129  "OPTION_NAME"=>LDAP_OPT_TIMELIMIT,
130  "OPTION_VALUE"=>30
131  ),
132  Array (
133  "OPTION_NAME"=>LDAP_OPT_PROTOCOL_VERSION,
134  "OPTION_VALUE"=>3
135  ),
136  Array (
137  "OPTION_NAME"=>LDAP_OPT_ERROR_NUMBER,
138  "OPTION_VALUE"=>13
139  ),
140  Array (
141  "OPTION_NAME"=>LDAP_OPT_REFERRALS,
142  "OPTION_VALUE"=>FALSE
143  ),
144  Array (
145  "OPTION_NAME"=>LDAP_OPT_RESTART,
146  "OPTION_VALUE"=>FALSE
147  )
148  );
149 */
150 
151  function _inject_bind_options( $options ) {
152  foreach( $options as $option ) {
153  ldap_set_option( $this->_connectionID, $option["OPTION_NAME"], $option["OPTION_VALUE"] )
154  or die( "Unable to set server option: " . $option["OPTION_NAME"] );
155  }
156  }
157 
158  /* returns _queryID or false */
159  function _query($sql,$inputarr=false)
160  {
161  $rs = @ldap_search( $this->_connectionID, $this->database, $sql );
162  $this->_errorMsg = ($rs) ? '' : 'Search error on '.$sql.': '.ldap_error($this->_connectionID);
163  return $rs;
164  }
165 
166  function ErrorMsg()
167  {
168  return $this->_errorMsg;
169  }
170 
171  function ErrorNo()
172  {
173  return @ldap_errno($this->_connectionID);
174  }
175 
176  /* closes the LDAP connection */
177  function _close()
178  {
179  @ldap_close( $this->_connectionID );
180  $this->_connectionID = false;
181  }
182 
183  function SelectDB($db) {
184  $this->database = $db;
185  return true;
186  } // SelectDB
187 
188  function ServerInfo()
189  {
190  if( !empty( $this->version ) ) {
191  return $this->version;
192  }
193 
194  $version = array();
195  /*
196  Determines how aliases are handled during search.
197  LDAP_DEREF_NEVER (0x00)
198  LDAP_DEREF_SEARCHING (0x01)
199  LDAP_DEREF_FINDING (0x02)
200  LDAP_DEREF_ALWAYS (0x03)
201  The LDAP_DEREF_SEARCHING value means aliases are dereferenced during the search but
202  not when locating the base object of the search. The LDAP_DEREF_FINDING value means
203  aliases are dereferenced when locating the base object but not during the search.
204  Default: LDAP_DEREF_NEVER
205  */
206  ldap_get_option( $this->_connectionID, LDAP_OPT_DEREF, $version['LDAP_OPT_DEREF'] ) ;
207  switch ( $version['LDAP_OPT_DEREF'] ) {
208  case 0:
209  $version['LDAP_OPT_DEREF'] = 'LDAP_DEREF_NEVER';
210  case 1:
211  $version['LDAP_OPT_DEREF'] = 'LDAP_DEREF_SEARCHING';
212  case 2:
213  $version['LDAP_OPT_DEREF'] = 'LDAP_DEREF_FINDING';
214  case 3:
215  $version['LDAP_OPT_DEREF'] = 'LDAP_DEREF_ALWAYS';
216  }
217 
218  /*
219  A limit on the number of entries to return from a search.
220  LDAP_NO_LIMIT (0) means no limit.
221  Default: LDAP_NO_LIMIT
222  */
223  ldap_get_option( $this->_connectionID, LDAP_OPT_SIZELIMIT, $version['LDAP_OPT_SIZELIMIT'] );
224  if ( $version['LDAP_OPT_SIZELIMIT'] == 0 ) {
225  $version['LDAP_OPT_SIZELIMIT'] = 'LDAP_NO_LIMIT';
226  }
227 
228  /*
229  A limit on the number of seconds to spend on a search.
230  LDAP_NO_LIMIT (0) means no limit.
231  Default: LDAP_NO_LIMIT
232  */
233  ldap_get_option( $this->_connectionID, LDAP_OPT_TIMELIMIT, $version['LDAP_OPT_TIMELIMIT'] );
234  if ( $version['LDAP_OPT_TIMELIMIT'] == 0 ) {
235  $version['LDAP_OPT_TIMELIMIT'] = 'LDAP_NO_LIMIT';
236  }
237 
238  /*
239  Determines whether the LDAP library automatically follows referrals returned by LDAP servers or not.
240  LDAP_OPT_ON
241  LDAP_OPT_OFF
242  Default: ON
243  */
244  ldap_get_option( $this->_connectionID, LDAP_OPT_REFERRALS, $version['LDAP_OPT_REFERRALS'] );
245  if ( $version['LDAP_OPT_REFERRALS'] == 0 ) {
246  $version['LDAP_OPT_REFERRALS'] = 'LDAP_OPT_OFF';
247  } else {
248  $version['LDAP_OPT_REFERRALS'] = 'LDAP_OPT_ON';
249  }
250 
251  /*
252  Determines whether LDAP I/O operations are automatically restarted if they abort prematurely.
253  LDAP_OPT_ON
254  LDAP_OPT_OFF
255  Default: OFF
256  */
257  ldap_get_option( $this->_connectionID, LDAP_OPT_RESTART, $version['LDAP_OPT_RESTART'] );
258  if ( $version['LDAP_OPT_RESTART'] == 0 ) {
259  $version['LDAP_OPT_RESTART'] = 'LDAP_OPT_OFF';
260  } else {
261  $version['LDAP_OPT_RESTART'] = 'LDAP_OPT_ON';
262  }
263 
264  /*
265  This option indicates the version of the LDAP protocol used when communicating with the primary LDAP server.
266  LDAP_VERSION2 (2)
267  LDAP_VERSION3 (3)
268  Default: LDAP_VERSION2 (2)
269  */
270  ldap_get_option( $this->_connectionID, LDAP_OPT_PROTOCOL_VERSION, $version['LDAP_OPT_PROTOCOL_VERSION'] );
271  if ( $version['LDAP_OPT_PROTOCOL_VERSION'] == 2 ) {
272  $version['LDAP_OPT_PROTOCOL_VERSION'] = 'LDAP_VERSION2';
273  } else {
274  $version['LDAP_OPT_PROTOCOL_VERSION'] = 'LDAP_VERSION3';
275  }
276 
277  /* The host name (or list of hosts) for the primary LDAP server. */
278  ldap_get_option( $this->_connectionID, LDAP_OPT_HOST_NAME, $version['LDAP_OPT_HOST_NAME'] );
279  ldap_get_option( $this->_connectionID, LDAP_OPT_ERROR_NUMBER, $version['LDAP_OPT_ERROR_NUMBER'] );
280  ldap_get_option( $this->_connectionID, LDAP_OPT_ERROR_STRING, $version['LDAP_OPT_ERROR_STRING'] );
281  ldap_get_option( $this->_connectionID, LDAP_OPT_MATCHED_DN, $version['LDAP_OPT_MATCHED_DN'] );
282 
283  return $this->version = $version;
284  }
285 }
286 
287 /*--------------------------------------------------------------------------------------
288  Class Name: Recordset
289 --------------------------------------------------------------------------------------*/
290 
291 class ADORecordSet_ldap extends ADORecordSet{
292 
293  var $databaseType = "ldap";
294  var $canSeek = false;
295  var $_entryID; /* keeps track of the entry resource identifier */
296 
297  function __construct($queryID,$mode=false)
298  {
299  if ($mode === false) {
300  global $ADODB_FETCH_MODE;
301  $mode = $ADODB_FETCH_MODE;
302  }
303  switch ($mode)
304  {
305  case ADODB_FETCH_NUM:
306  $this->fetchMode = LDAP_NUM;
307  break;
308  case ADODB_FETCH_ASSOC:
309  $this->fetchMode = LDAP_ASSOC;
310  break;
311  case ADODB_FETCH_DEFAULT:
312  case ADODB_FETCH_BOTH:
313  default:
314  $this->fetchMode = LDAP_BOTH;
315  break;
316  }
317 
318  parent::__construct($queryID);
319  }
320 
321  function _initrs()
322  {
323  /*
324  This could be teaked to respect the $COUNTRECS directive from ADODB
325  It's currently being used in the _fetch() function and the
326  GetAssoc() function
327  */
328  $this->_numOfRows = ldap_count_entries( $this->connection->_connectionID, $this->_queryID );
329  }
330 
331  /*
332  Return whole recordset as a multi-dimensional associative array
333  */
334  function GetAssoc($force_array = false, $first2cols = false)
335  {
336  $records = $this->_numOfRows;
337  $results = array();
338  for ( $i=0; $i < $records; $i++ ) {
339  foreach ( $this->fields as $k=>$v ) {
340  if ( is_array( $v ) ) {
341  if ( $v['count'] == 1 ) {
342  $results[$i][$k] = $v[0];
343  } else {
344  array_shift( $v );
345  $results[$i][$k] = $v;
346  }
347  }
348  }
349  }
350 
351  return $results;
352  }
353 
354  function GetRowAssoc($upper = ADODB_ASSOC_CASE)
355  {
356  $results = array();
357  foreach ( $this->fields as $k=>$v ) {
358  if ( is_array( $v ) ) {
359  if ( $v['count'] == 1 ) {
360  $results[$k] = $v[0];
361  } else {
362  array_shift( $v );
363  $results[$k] = $v;
364  }
365  }
366  }
367 
368  return $results;
369  }
370 
371  function GetRowNums()
372  {
373  $results = array();
374  foreach ( $this->fields as $k=>$v ) {
375  static $i = 0;
376  if (is_array( $v )) {
377  if ( $v['count'] == 1 ) {
378  $results[$i] = $v[0];
379  } else {
380  array_shift( $v );
381  $results[$i] = $v;
382  }
383  $i++;
384  }
385  }
386  return $results;
387  }
388 
389  function _fetch()
390  {
391  if ( $this->_currentRow >= $this->_numOfRows && $this->_numOfRows >= 0 ) {
392  return false;
393  }
394 
395  if ( $this->_currentRow == 0 ) {
396  $this->_entryID = ldap_first_entry( $this->connection->_connectionID, $this->_queryID );
397  } else {
398  $this->_entryID = ldap_next_entry( $this->connection->_connectionID, $this->_entryID );
399  }
400 
401  $this->fields = ldap_get_attributes( $this->connection->_connectionID, $this->_entryID );
402  $this->_numOfFields = $this->fields['count'];
403 
404  switch ( $this->fetchMode ) {
405 
406  case LDAP_ASSOC:
407  $this->fields = $this->GetRowAssoc();
408  break;
409 
410  case LDAP_NUM:
411  $this->fields = array_merge($this->GetRowNums(),$this->GetRowAssoc());
412  break;
413 
414  case LDAP_BOTH:
415  default:
416  $this->fields = $this->GetRowNums();
417  break;
418  }
419 
420  return is_array( $this->fields );
421  }
422 
423  function _close() {
424  @ldap_free_result( $this->_queryID );
425  $this->_queryID = false;
426  }
427 
428 }
if(isset($_REQUEST['nrows'])) else $rs
Definition: server.php:94
debug($variable='', $name=' *variable *', $line=' *line *', $file=' *file *', $recursiveDepth=3, $debugLevel='E_DEBUG')
GetAssoc($force_array=false, $first2cols=false)
_inject_bind_options( $options)
__construct($queryID, $mode=false)
_query($sql, $inputarr=false)
$host
Definition: server.php:37
$sql
Definition: server.php:84
GetRowAssoc($upper=ADODB_ASSOC_CASE)
_connect( $host, $username, $password, $ldapbase)