Subversion Repositories svnkaklik

Rev

Details | Last modification | View Log

Rev Author Line No. Line
36 kaklik 1
<?php
2
/*
3
  V4.80 8 Mar 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.
7
  Set tabs to 8.
8
 
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.
13
 
14
  Joshua Eldridge (joshuae74#hotmail.com)
15
*/ 
16
 
17
// security - hide paths
18
if (!defined('ADODB_DIR')) die();
19
 
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);
24
}
25
 
26
class ADODB_ldap extends ADOConnection {
27
    var $databaseType = 'ldap';
28
	var $dataProvider = 'ldap';
29
 
30
	# Connection information
31
    var $username = false;
32
    var $password = false;
33
 
34
    # Used during searches
35
    var $filter;
36
    var $dn;
37
	var $version;
38
	var $port = 389;
39
 
40
	# Options configuration information
41
	var $LDAP_CONNECT_OPTIONS;
42
 
43
	function ADODB_ldap() 
44
	{		
45
	}
46
 
47
	// returns true or false
48
 
49
	function _connect( $host, $username, $password, $ldapbase)
50
	{
51
	global $LDAP_CONNECT_OPTIONS;
52
 
53
		if ( !function_exists( 'ldap_connect' ) ) return null;
54
 
55
		$conn_info = array( $host,$this->port);
56
 
57
		if ( strstr( $host, ':' ) ) {
58
		    $conn_info = split( ':', $host );
59
		} 
60
 
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);
66
			return false;
67
		}
68
		if( count( $LDAP_CONNECT_OPTIONS ) > 0 ) {
69
			$this->_inject_bind_options( $LDAP_CONNECT_OPTIONS );
70
		}
71
 
72
		if ($username) {
73
		    $bind = ldap_bind( $this->_connectionID, $username, $password );
74
		} else {
75
			$username = 'anonymous';
76
		    $bind = ldap_bind( $this->_connectionID );		
77
		}
78
 
79
		if (!$bind) {
80
			$e = 'Could not bind to ' . $conn_info[0] . " as ".$username;
81
			$this->_errorMsg = $e;
82
			if ($this->debug) ADOConnection::outp($e);
83
			return false;
84
		}
85
		$this->_errorMsg = '';
86
		$this->database = $ldapbase;
87
		return $this->_connectionID;
88
	}
89
 
90
/*
91
	Valid Domain Values for LDAP Options:
92
 
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)
105
 
106
	Make sure to set this BEFORE calling Connect()
107
 
108
	Example:
109
 
110
	$LDAP_CONNECT_OPTIONS = Array(
111
		Array (
112
			"OPTION_NAME"=>LDAP_OPT_DEREF,
113
			"OPTION_VALUE"=>2
114
		),
115
		Array (
116
			"OPTION_NAME"=>LDAP_OPT_SIZELIMIT,
117
			"OPTION_VALUE"=>100
118
		),
119
		Array (
120
			"OPTION_NAME"=>LDAP_OPT_TIMELIMIT,
121
			"OPTION_VALUE"=>30
122
		),
123
		Array (
124
			"OPTION_NAME"=>LDAP_OPT_PROTOCOL_VERSION,
125
			"OPTION_VALUE"=>3
126
		),
127
		Array (
128
			"OPTION_NAME"=>LDAP_OPT_ERROR_NUMBER,
129
			"OPTION_VALUE"=>13
130
		),
131
		Array (
132
			"OPTION_NAME"=>LDAP_OPT_REFERRALS,
133
			"OPTION_VALUE"=>FALSE
134
		),
135
		Array (
136
			"OPTION_NAME"=>LDAP_OPT_RESTART,
137
			"OPTION_VALUE"=>FALSE
138
		)
139
	);
140
*/
141
 
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"] );
146
		}
147
	}
148
 
149
	/* returns _queryID or false */
150
	function _query($sql,$inputarr)
151
	{
152
		$rs = ldap_search( $this->_connectionID, $this->database, $sql );
153
		$this->_errorMsg = ($rs) ? '' : 'Search error on '.$sql;
154
		return $rs; 
155
	}
156
 
157
    /* closes the LDAP connection */
158
	function _close()
159
	{
160
		@ldap_close( $this->_connectionID );
161
		$this->_connectionID = false;
162
	}
163
 
164
	function SelectDB($db) {
165
		$this->database = $db;
166
		return true;
167
	} // SelectDB
168
 
169
    function ServerInfo()
170
    {
171
        if( !empty( $this->version ) ) return $this->version;
172
        $version = array();
173
        /*
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
183
        */
184
        ldap_get_option( $this->_connectionID, LDAP_OPT_DEREF, $version['LDAP_OPT_DEREF'] ) ;
185
        switch ( $version['LDAP_OPT_DEREF'] ) {
186
          case 0:
187
            $version['LDAP_OPT_DEREF'] = 'LDAP_DEREF_NEVER';
188
          case 1:
189
            $version['LDAP_OPT_DEREF'] = 'LDAP_DEREF_SEARCHING';
190
          case 2:
191
            $version['LDAP_OPT_DEREF'] = 'LDAP_DEREF_FINDING';
192
          case 3:
193
            $version['LDAP_OPT_DEREF'] = 'LDAP_DEREF_ALWAYS';
194
        }
195
 
196
        /* 
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
200
        */
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';
204
        }
205
 
206
        /*
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
210
        */
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';
214
        }
215
 
216
        /*
217
        Determines whether the LDAP library automatically follows referrals returned by LDAP servers or not. 
218
        LDAP_OPT_ON
219
        LDAP_OPT_OFF
220
        Default: ON
221
        */
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';
225
        } else {
226
           $version['LDAP_OPT_REFERRALS'] = 'LDAP_OPT_ON';
227
 
228
        }
229
        /*
230
        Determines whether LDAP I/O operations are automatically restarted if they abort prematurely. 
231
        LDAP_OPT_ON
232
        LDAP_OPT_OFF
233
        Default: OFF
234
        */
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';
238
        } else {
239
           $version['LDAP_OPT_RESTART'] = 'LDAP_OPT_ON';
240
 
241
        }
242
        /*
243
        This option indicates the version of the LDAP protocol used when communicating with the primary LDAP server.
244
        LDAP_VERSION2 (2)
245
        LDAP_VERSION3 (3)
246
        Default: LDAP_VERSION2 (2)
247
        */
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';
251
        } else {
252
           $version['LDAP_OPT_PROTOCOL_VERSION'] = 'LDAP_VERSION3';
253
 
254
        }
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'] ); 
260
 
261
        return $this->version = $version;
262
 
263
    }
264
}
265
 
266
/*--------------------------------------------------------------------------------------
267
	 Class Name: Recordset
268
--------------------------------------------------------------------------------------*/
269
 
270
class ADORecordSet_ldap extends ADORecordSet{	
271
 
272
	var $databaseType = "ldap";
273
	var $canSeek = false;
274
	var $_entryID; /* keeps track of the entry resource identifier */
275
 
276
	function ADORecordSet_ldap($queryID,$mode=false) 
277
	{
278
		if ($mode === false) { 
279
			global $ADODB_FETCH_MODE;
280
			$mode = $ADODB_FETCH_MODE;
281
		}
282
		switch ($mode)
283
		{
284
		case ADODB_FETCH_NUM: 
285
		  $this->fetchMode = LDAP_NUM; 
286
		break;
287
		case ADODB_FETCH_ASSOC: 
288
		  $this->fetchMode = LDAP_ASSOC; 
289
		break;
290
		case ADODB_FETCH_DEFAULT:
291
		case ADODB_FETCH_BOTH: 
292
		default:
293
		  $this->fetchMode = LDAP_BOTH; 
294
		break;
295
		}
296
 
297
		$this->ADORecordSet($queryID);	
298
	}
299
 
300
	function _initrs()
301
	{
302
	   /* 
303
	   This could be teaked to respect the $COUNTRECS directive from ADODB
304
	   It's currently being used in the _fetch() function and the
305
	   GetAssoc() function
306
       */
307
	    $this->_numOfRows = ldap_count_entries( $this->connection->_connectionID, $this->_queryID );
308
 
309
	}
310
 
311
    /*
312
    Return whole recordset as a multi-dimensional associative array
313
	*/
314
	function &GetAssoc($force_array = false, $first2cols = false) 
315
	{
316
		$records = $this->_numOfRows;
317
        $results = array();
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];
323
                        } else {
324
                            array_shift( $v );
325
                            $results[$i][$k] = $v;
326
                        } 
327
                    }
328
                }
329
            }
330
 
331
		return $results; 
332
	}
333
 
334
    function &GetRowAssoc()
335
	{
336
        $results = array();
337
        foreach ( $this->fields as $k=>$v ) {
338
            if ( is_array( $v ) ) {
339
                if ( $v['count'] == 1 ) {
340
                    $results[$k] = $v[0];
341
                } else {
342
                    array_shift( $v );
343
                    $results[$k] = $v;
344
                } 
345
            }
346
        }
347
 
348
		return $results; 
349
	}
350
 
351
    function GetRowNums()
352
    {
353
        $results = array();
354
        foreach ( $this->fields as $k=>$v ) {
355
        static $i = 0;
356
            if (is_array( $v )) {
357
                if ( $v['count'] == 1 ) {
358
                    $results[$i] = $v[0];
359
                } else {
360
                    array_shift( $v );
361
                    $results[$i] = $v;
362
                } 
363
            $i++;
364
            }
365
        }
366
        return $results;
367
    }
368
 
369
	function _fetch()
370
	{		
371
		if ( $this->_currentRow >= $this->_numOfRows && $this->_numOfRows >= 0 )
372
        	return false;
373
 
374
        if ( $this->_currentRow == 0 ) {
375
		  $this->_entryID = ldap_first_entry( $this->connection->_connectionID, $this->_queryID );
376
        } else {
377
          $this->_entryID = ldap_next_entry( $this->connection->_connectionID, $this->_entryID );
378
        }
379
 
380
	    $this->fields = ldap_get_attributes( $this->connection->_connectionID, $this->_entryID );
381
	    $this->_numOfFields = $this->fields['count'];	
382
	    switch ( $this->fetchMode ) {
383
 
384
            case LDAP_ASSOC:
385
            $this->fields = $this->GetRowAssoc();
386
            break;
387
 
388
            case LDAP_NUM:
389
			$this->fields = array_merge($this->GetRowNums(),$this->GetRowAssoc());
390
            break;
391
 
392
            case LDAP_BOTH:
393
            default:
394
			$this->fields = $this->GetRowNums();
395
            break;
396
        }
397
        return ( is_array( $this->fields ) );        
398
	}
399
 
400
	function _close() {
401
		@ldap_free_result( $this->_queryID );	
402
		$this->_queryID = false;
403
	}
404
 
405
}
406
?>