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