3 V4.92a 29 Aug 2006 (c) 2000-2006 John Lim (jlim#natsoft.com.my). All rights reserved.
4 Released under both BSD license and Lesser GPL library license.
5 Whenever there is any discrepancy between the two licenses,
6 the BSD license will take precedence.
9 Revision 1: (02/25/2005) Updated codebase to include the _inject_bind_options function. This allows
10 users to access the options in the ldap_set_option function appropriately. Most importantly
11 LDAP Version 3 is now supported. See the examples for more information. Also fixed some minor
12 bugs that surfaced when PHP error levels were set high.
14 Joshua Eldridge (joshuae74#hotmail.com)
17 // security - hide paths
18 if (!defined('ADODB_DIR')) die();
20 if (!defined('LDAP_ASSOC')) {
21 define('LDAP_ASSOC',ADODB_FETCH_ASSOC
);
22 define('LDAP_NUM',ADODB_FETCH_NUM
);
23 define('LDAP_BOTH',ADODB_FETCH_BOTH
);
26 class ADODB_ldap
extends ADOConnection
{
27 var $databaseType = 'ldap';
28 var $dataProvider = 'ldap';
30 # Connection information
31 var $username = false;
32 var $password = false;
34 # Used during searches
40 # Options configuration information
41 var $LDAP_CONNECT_OPTIONS;
47 // returns true or false
49 function _connect( $host, $username, $password, $ldapbase)
51 global $LDAP_CONNECT_OPTIONS;
53 if ( !function_exists( 'ldap_connect' ) ) return null;
55 $conn_info = array( $host,$this->port
);
57 if ( strstr( $host, ':' ) ) {
58 $conn_info = split( ':', $host );
61 $this->_connectionID
= ldap_connect( $conn_info[0], $conn_info[1] );
62 if (!$this->_connectionID
) {
63 $e = 'Could not connect to ' . $conn_info[0];
64 $this->_errorMsg
= $e;
65 if ($this->debug
) ADOConnection
::outp($e);
68 if( count( $LDAP_CONNECT_OPTIONS ) > 0 ) {
69 $this->_inject_bind_options( $LDAP_CONNECT_OPTIONS );
73 $bind = ldap_bind( $this->_connectionID
, $username, $password );
75 $username = 'anonymous';
76 $bind = ldap_bind( $this->_connectionID
);
80 $e = 'Could not bind to ' . $conn_info[0] . " as ".$username;
81 $this->_errorMsg
= $e;
82 if ($this->debug
) ADOConnection
::outp($e);
85 $this->_errorMsg
= '';
86 $this->database
= $ldapbase;
87 return $this->_connectionID
;
91 Valid Domain Values for LDAP Options:
93 LDAP_OPT_DEREF (integer)
94 LDAP_OPT_SIZELIMIT (integer)
95 LDAP_OPT_TIMELIMIT (integer)
96 LDAP_OPT_PROTOCOL_VERSION (integer)
97 LDAP_OPT_ERROR_NUMBER (integer)
98 LDAP_OPT_REFERRALS (boolean)
99 LDAP_OPT_RESTART (boolean)
100 LDAP_OPT_HOST_NAME (string)
101 LDAP_OPT_ERROR_STRING (string)
102 LDAP_OPT_MATCHED_DN (string)
103 LDAP_OPT_SERVER_CONTROLS (array)
104 LDAP_OPT_CLIENT_CONTROLS (array)
106 Make sure to set this BEFORE calling Connect()
110 $LDAP_CONNECT_OPTIONS = Array(
112 "OPTION_NAME"=>LDAP_OPT_DEREF,
116 "OPTION_NAME"=>LDAP_OPT_SIZELIMIT,
120 "OPTION_NAME"=>LDAP_OPT_TIMELIMIT,
124 "OPTION_NAME"=>LDAP_OPT_PROTOCOL_VERSION,
128 "OPTION_NAME"=>LDAP_OPT_ERROR_NUMBER,
132 "OPTION_NAME"=>LDAP_OPT_REFERRALS,
133 "OPTION_VALUE"=>FALSE
136 "OPTION_NAME"=>LDAP_OPT_RESTART,
137 "OPTION_VALUE"=>FALSE
142 function _inject_bind_options( $options ) {
143 foreach( $options as $option ) {
144 ldap_set_option( $this->_connectionID
, $option["OPTION_NAME"], $option["OPTION_VALUE"] )
145 or die( "Unable to set server option: " . $option["OPTION_NAME"] );
149 /* returns _queryID or false */
150 function _query($sql,$inputarr)
152 $rs = ldap_search( $this->_connectionID
, $this->database
, $sql );
153 $this->_errorMsg
= ($rs) ?
'' : 'Search error on '.$sql;
157 /* closes the LDAP connection */
160 @ldap_close
( $this->_connectionID
);
161 $this->_connectionID
= false;
164 function SelectDB($db) {
165 $this->database
= $db;
169 function ServerInfo()
171 if( !empty( $this->version
) ) return $this->version
;
174 Determines how aliases are handled during search.
175 LDAP_DEREF_NEVER (0x00)
176 LDAP_DEREF_SEARCHING (0x01)
177 LDAP_DEREF_FINDING (0x02)
178 LDAP_DEREF_ALWAYS (0x03)
179 The LDAP_DEREF_SEARCHING value means aliases are dereferenced during the search but
180 not when locating the base object of the search. The LDAP_DEREF_FINDING value means
181 aliases are dereferenced when locating the base object but not during the search.
182 Default: LDAP_DEREF_NEVER
184 ldap_get_option( $this->_connectionID
, LDAP_OPT_DEREF
, $version['LDAP_OPT_DEREF'] ) ;
185 switch ( $version['LDAP_OPT_DEREF'] ) {
187 $version['LDAP_OPT_DEREF'] = 'LDAP_DEREF_NEVER';
189 $version['LDAP_OPT_DEREF'] = 'LDAP_DEREF_SEARCHING';
191 $version['LDAP_OPT_DEREF'] = 'LDAP_DEREF_FINDING';
193 $version['LDAP_OPT_DEREF'] = 'LDAP_DEREF_ALWAYS';
197 A limit on the number of entries to return from a search.
198 LDAP_NO_LIMIT (0) means no limit.
199 Default: LDAP_NO_LIMIT
201 ldap_get_option( $this->_connectionID
, LDAP_OPT_SIZELIMIT
, $version['LDAP_OPT_SIZELIMIT'] );
202 if ( $version['LDAP_OPT_SIZELIMIT'] == 0 ) {
203 $version['LDAP_OPT_SIZELIMIT'] = 'LDAP_NO_LIMIT';
207 A limit on the number of seconds to spend on a search.
208 LDAP_NO_LIMIT (0) means no limit.
209 Default: LDAP_NO_LIMIT
211 ldap_get_option( $this->_connectionID
, LDAP_OPT_TIMELIMIT
, $version['LDAP_OPT_TIMELIMIT'] );
212 if ( $version['LDAP_OPT_TIMELIMIT'] == 0 ) {
213 $version['LDAP_OPT_TIMELIMIT'] = 'LDAP_NO_LIMIT';
217 Determines whether the LDAP library automatically follows referrals returned by LDAP servers or not.
222 ldap_get_option( $this->_connectionID
, LDAP_OPT_REFERRALS
, $version['LDAP_OPT_REFERRALS'] );
223 if ( $version['LDAP_OPT_REFERRALS'] == 0 ) {
224 $version['LDAP_OPT_REFERRALS'] = 'LDAP_OPT_OFF';
226 $version['LDAP_OPT_REFERRALS'] = 'LDAP_OPT_ON';
230 Determines whether LDAP I/O operations are automatically restarted if they abort prematurely.
235 ldap_get_option( $this->_connectionID
, LDAP_OPT_RESTART
, $version['LDAP_OPT_RESTART'] );
236 if ( $version['LDAP_OPT_RESTART'] == 0 ) {
237 $version['LDAP_OPT_RESTART'] = 'LDAP_OPT_OFF';
239 $version['LDAP_OPT_RESTART'] = 'LDAP_OPT_ON';
243 This option indicates the version of the LDAP protocol used when communicating with the primary LDAP server.
246 Default: LDAP_VERSION2 (2)
248 ldap_get_option( $this->_connectionID
, LDAP_OPT_PROTOCOL_VERSION
, $version['LDAP_OPT_PROTOCOL_VERSION'] );
249 if ( $version['LDAP_OPT_PROTOCOL_VERSION'] == 2 ) {
250 $version['LDAP_OPT_PROTOCOL_VERSION'] = 'LDAP_VERSION2';
252 $version['LDAP_OPT_PROTOCOL_VERSION'] = 'LDAP_VERSION3';
255 /* The host name (or list of hosts) for the primary LDAP server. */
256 ldap_get_option( $this->_connectionID
, LDAP_OPT_HOST_NAME
, $version['LDAP_OPT_HOST_NAME'] );
257 ldap_get_option( $this->_connectionID
, LDAP_OPT_ERROR_NUMBER
, $version['LDAP_OPT_ERROR_NUMBER'] );
258 ldap_get_option( $this->_connectionID
, LDAP_OPT_ERROR_STRING
, $version['LDAP_OPT_ERROR_STRING'] );
259 ldap_get_option( $this->_connectionID
, LDAP_OPT_MATCHED_DN
, $version['LDAP_OPT_MATCHED_DN'] );
261 return $this->version
= $version;
266 /*--------------------------------------------------------------------------------------
267 Class Name: Recordset
268 --------------------------------------------------------------------------------------*/
270 class ADORecordSet_ldap
extends ADORecordSet
{
272 var $databaseType = "ldap";
273 var $canSeek = false;
274 var $_entryID; /* keeps track of the entry resource identifier */
276 function ADORecordSet_ldap($queryID,$mode=false)
278 if ($mode === false) {
279 global $ADODB_FETCH_MODE;
280 $mode = $ADODB_FETCH_MODE;
284 case ADODB_FETCH_NUM
:
285 $this->fetchMode
= LDAP_NUM
;
287 case ADODB_FETCH_ASSOC
:
288 $this->fetchMode
= LDAP_ASSOC
;
290 case ADODB_FETCH_DEFAULT
:
291 case ADODB_FETCH_BOTH
:
293 $this->fetchMode
= LDAP_BOTH
;
297 $this->ADORecordSet($queryID);
303 This could be teaked to respect the $COUNTRECS directive from ADODB
304 It's currently being used in the _fetch() function and the
307 $this->_numOfRows
= ldap_count_entries( $this->connection
->_connectionID
, $this->_queryID
);
312 Return whole recordset as a multi-dimensional associative array
314 function &GetAssoc($force_array = false, $first2cols = false)
316 $records = $this->_numOfRows
;
318 for ( $i=0; $i < $records; $i++
) {
319 foreach ( $this->fields
as $k=>$v ) {
320 if ( is_array( $v ) ) {
321 if ( $v['count'] == 1 ) {
322 $results[$i][$k] = $v[0];
325 $results[$i][$k] = $v;
334 function &GetRowAssoc()
337 foreach ( $this->fields
as $k=>$v ) {
338 if ( is_array( $v ) ) {
339 if ( $v['count'] == 1 ) {
340 $results[$k] = $v[0];
351 function GetRowNums()
354 foreach ( $this->fields
as $k=>$v ) {
356 if (is_array( $v )) {
357 if ( $v['count'] == 1 ) {
358 $results[$i] = $v[0];
371 if ( $this->_currentRow
>= $this->_numOfRows
&& $this->_numOfRows
>= 0 )
374 if ( $this->_currentRow
== 0 ) {
375 $this->_entryID
= ldap_first_entry( $this->connection
->_connectionID
, $this->_queryID
);
377 $this->_entryID
= ldap_next_entry( $this->connection
->_connectionID
, $this->_entryID
);
380 $this->fields
= ldap_get_attributes( $this->connection
->_connectionID
, $this->_entryID
);
381 $this->_numOfFields
= $this->fields
['count'];
382 switch ( $this->fetchMode
) {
385 $this->fields
= $this->GetRowAssoc();
389 $this->fields
= array_merge($this->GetRowNums(),$this->GetRowAssoc());
394 $this->fields
= $this->GetRowNums();
397 return ( is_array( $this->fields
) );
401 @ldap_free_result
( $this->_queryID
);
402 $this->_queryID
= false;