[25027] | 1 | <?php
|
---|
| 2 | /**
|
---|
| 3 | * LDAP authentication backend
|
---|
| 4 | *
|
---|
| 5 | * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
|
---|
| 6 | * @author Andreas Gohr <[email protected]>
|
---|
| 7 | * @author Chris Smith <[email protected]>
|
---|
| 8 | */
|
---|
| 9 |
|
---|
| 10 | class auth_ldap extends auth_basic {
|
---|
| 11 | var $cnf = null;
|
---|
| 12 | var $con = null;
|
---|
| 13 | var $bound = 0; // 0: anonymous, 1: user, 2: superuser
|
---|
| 14 |
|
---|
| 15 | /**
|
---|
| 16 | * Constructor
|
---|
| 17 | */
|
---|
| 18 | function auth_ldap(){
|
---|
| 19 | global $conf;
|
---|
| 20 | $this->cnf = $conf['auth']['ldap'];
|
---|
| 21 |
|
---|
| 22 | // ldap extension is needed
|
---|
| 23 | if(!function_exists('ldap_connect')) {
|
---|
| 24 | if ($this->cnf['debug'])
|
---|
| 25 | msg("LDAP err: PHP LDAP extension not found.",-1,__LINE__,__FILE__);
|
---|
| 26 | $this->success = false;
|
---|
| 27 | return;
|
---|
| 28 | }
|
---|
| 29 |
|
---|
| 30 | if(empty($this->cnf['groupkey'])) $this->cnf['groupkey'] = 'cn';
|
---|
| 31 | if(empty($this->cnf['userscope'])) $this->cnf['userscope'] = 'sub';
|
---|
| 32 | if(empty($this->cnf['groupscope'])) $this->cnf['groupscope'] = 'sub';
|
---|
| 33 |
|
---|
| 34 | // auth_ldap currently just handles authentication, so no
|
---|
| 35 | // capabilities are set
|
---|
| 36 | }
|
---|
| 37 |
|
---|
| 38 | /**
|
---|
| 39 | * Check user+password
|
---|
| 40 | *
|
---|
| 41 | * Checks if the given user exists and the given
|
---|
| 42 | * plaintext password is correct by trying to bind
|
---|
| 43 | * to the LDAP server
|
---|
| 44 | *
|
---|
| 45 | * @author Andreas Gohr <[email protected]>
|
---|
| 46 | * @return bool
|
---|
| 47 | */
|
---|
| 48 | function checkPass($user,$pass){
|
---|
| 49 | // reject empty password
|
---|
| 50 | if(empty($pass)) return false;
|
---|
| 51 | if(!$this->_openLDAP()) return false;
|
---|
| 52 |
|
---|
| 53 | // indirect user bind
|
---|
| 54 | if($this->cnf['binddn'] && $this->cnf['bindpw']){
|
---|
| 55 | // use superuser credentials
|
---|
| 56 | if(!@ldap_bind($this->con,$this->cnf['binddn'],$this->cnf['bindpw'])){
|
---|
| 57 | if($this->cnf['debug'])
|
---|
| 58 | msg('LDAP bind as superuser: '.htmlspecialchars(ldap_error($this->con)),0,__LINE__,__FILE__);
|
---|
| 59 | return false;
|
---|
| 60 | }
|
---|
| 61 | $this->bound = 2;
|
---|
| 62 | }else if($this->cnf['binddn'] &&
|
---|
| 63 | $this->cnf['usertree'] &&
|
---|
| 64 | $this->cnf['userfilter']) {
|
---|
| 65 | // special bind string
|
---|
| 66 | $dn = $this->_makeFilter($this->cnf['binddn'],
|
---|
| 67 | array('user'=>$user,'server'=>$this->cnf['server']));
|
---|
| 68 |
|
---|
| 69 | }else if(strpos($this->cnf['usertree'], '%{user}')) {
|
---|
| 70 | // direct user bind
|
---|
| 71 | $dn = $this->_makeFilter($this->cnf['usertree'],
|
---|
| 72 | array('user'=>$user,'server'=>$this->cnf['server']));
|
---|
| 73 |
|
---|
| 74 | }else{
|
---|
| 75 | // Anonymous bind
|
---|
| 76 | if(!@ldap_bind($this->con)){
|
---|
| 77 | msg("LDAP: can not bind anonymously",-1);
|
---|
| 78 | if($this->cnf['debug'])
|
---|
| 79 | msg('LDAP anonymous bind: '.htmlspecialchars(ldap_error($this->con)),0,__LINE__,__FILE__);
|
---|
| 80 | return false;
|
---|
| 81 | }
|
---|
| 82 | }
|
---|
| 83 |
|
---|
| 84 | // Try to bind to with the dn if we have one.
|
---|
| 85 | if(!empty($dn)) {
|
---|
| 86 | // User/Password bind
|
---|
| 87 | if(!@ldap_bind($this->con,$dn,$pass)){
|
---|
| 88 | if($this->cnf['debug']){
|
---|
| 89 | msg("LDAP: bind with $dn failed", -1,__LINE__,__FILE__);
|
---|
| 90 | msg('LDAP user dn bind: '.htmlspecialchars(ldap_error($this->con)),0);
|
---|
| 91 | }
|
---|
| 92 | return false;
|
---|
| 93 | }
|
---|
| 94 | $this->bound = 1;
|
---|
| 95 | return true;
|
---|
| 96 | }else{
|
---|
| 97 | // See if we can find the user
|
---|
| 98 | $info = $this->getUserData($user,true);
|
---|
| 99 | if(empty($info['dn'])) {
|
---|
| 100 | return false;
|
---|
| 101 | } else {
|
---|
| 102 | $dn = $info['dn'];
|
---|
| 103 | }
|
---|
| 104 |
|
---|
| 105 | // Try to bind with the dn provided
|
---|
| 106 | if(!@ldap_bind($this->con,$dn,$pass)){
|
---|
| 107 | if($this->cnf['debug']){
|
---|
| 108 | msg("LDAP: bind with $dn failed", -1,__LINE__,__FILE__);
|
---|
| 109 | msg('LDAP user bind: '.htmlspecialchars(ldap_error($this->con)),0);
|
---|
| 110 | }
|
---|
| 111 | return false;
|
---|
| 112 | }
|
---|
| 113 | $this->bound = 1;
|
---|
| 114 | return true;
|
---|
| 115 | }
|
---|
| 116 |
|
---|
| 117 | return false;
|
---|
| 118 | }
|
---|
| 119 |
|
---|
| 120 | /**
|
---|
| 121 | * Return user info
|
---|
| 122 | *
|
---|
| 123 | * Returns info about the given user needs to contain
|
---|
| 124 | * at least these fields:
|
---|
| 125 | *
|
---|
| 126 | * name string full name of the user
|
---|
| 127 | * mail string email addres of the user
|
---|
| 128 | * grps array list of groups the user is in
|
---|
| 129 | *
|
---|
| 130 | * This LDAP specific function returns the following
|
---|
| 131 | * addional fields:
|
---|
| 132 | *
|
---|
| 133 | * dn string distinguished name (DN)
|
---|
| 134 | * uid string Posix User ID
|
---|
| 135 | * inbind bool for internal use - avoid loop in binding
|
---|
| 136 | *
|
---|
| 137 | * @author Andreas Gohr <[email protected]>
|
---|
| 138 | * @author Trouble
|
---|
| 139 | * @author Dan Allen <[email protected]>
|
---|
| 140 | * @author <[email protected]>
|
---|
| 141 | * @author Stephane Chazelas <[email protected]>
|
---|
| 142 | * @return array containing user data or false
|
---|
| 143 | */
|
---|
| 144 | function getUserData($user,$inbind=false) {
|
---|
| 145 | global $conf;
|
---|
| 146 | if(!$this->_openLDAP()) return false;
|
---|
| 147 |
|
---|
| 148 | // force superuser bind if wanted and not bound as superuser yet
|
---|
| 149 | if($this->cnf['binddn'] && $this->cnf['bindpw'] && $this->bound < 2){
|
---|
| 150 | // use superuser credentials
|
---|
| 151 | if(!@ldap_bind($this->con,$this->cnf['binddn'],$this->cnf['bindpw'])){
|
---|
| 152 | if($this->cnf['debug'])
|
---|
| 153 | msg('LDAP bind as superuser: '.htmlspecialchars(ldap_error($this->con)),0,__LINE__,__FILE__);
|
---|
| 154 | return false;
|
---|
| 155 | }
|
---|
| 156 | $this->bound = 2;
|
---|
| 157 | }elseif($this->bound == 0 && !$inbind) {
|
---|
| 158 | // in some cases getUserData is called outside the authentication workflow
|
---|
| 159 | // eg. for sending email notification on subscribed pages. This data might not
|
---|
| 160 | // be accessible anonymously, so we try to rebind the current user here
|
---|
| 161 | list($loginuser,$loginsticky,$loginpass) = auth_getCookie();
|
---|
| 162 | if($loginuser && $loginpass){
|
---|
| 163 | $loginpass = PMA_blowfish_decrypt($loginpass, auth_cookiesalt(!$loginsticky));
|
---|
| 164 | $this->checkPass($loginuser, $loginpass);
|
---|
| 165 | }
|
---|
| 166 | }
|
---|
| 167 |
|
---|
| 168 | $info['user'] = $user;
|
---|
| 169 | $info['server'] = $this->cnf['server'];
|
---|
| 170 |
|
---|
| 171 | //get info for given user
|
---|
| 172 | $base = $this->_makeFilter($this->cnf['usertree'], $info);
|
---|
| 173 | if(!empty($this->cnf['userfilter'])) {
|
---|
| 174 | $filter = $this->_makeFilter($this->cnf['userfilter'], $info);
|
---|
| 175 | } else {
|
---|
| 176 | $filter = "(ObjectClass=*)";
|
---|
| 177 | }
|
---|
| 178 |
|
---|
| 179 | $sr = $this->_ldapsearch($this->con, $base, $filter, $this->cnf['userscope']);
|
---|
| 180 | $result = @ldap_get_entries($this->con, $sr);
|
---|
| 181 | if($this->cnf['debug']){
|
---|
| 182 | msg('LDAP user search: '.htmlspecialchars(ldap_error($this->con)),0,__LINE__,__FILE__);
|
---|
| 183 | msg('LDAP search at: '.htmlspecialchars($base.' '.$filter),0,__LINE__,__FILE__);
|
---|
| 184 | }
|
---|
| 185 |
|
---|
| 186 | // Don't accept more or less than one response
|
---|
| 187 | if(!is_array($result) || $result['count'] != 1){
|
---|
| 188 | return false; //user not found
|
---|
| 189 | }
|
---|
| 190 |
|
---|
| 191 | $user_result = $result[0];
|
---|
| 192 | ldap_free_result($sr);
|
---|
| 193 |
|
---|
| 194 | // general user info
|
---|
| 195 | $info['dn'] = $user_result['dn'];
|
---|
| 196 | $info['gid'] = $user_result['gidnumber'][0];
|
---|
| 197 | $info['mail'] = $user_result['mail'][0];
|
---|
| 198 | $info['name'] = $user_result['cn'][0];
|
---|
| 199 | $info['grps'] = array();
|
---|
| 200 |
|
---|
| 201 | // overwrite if other attribs are specified.
|
---|
| 202 | if(is_array($this->cnf['mapping'])){
|
---|
| 203 | foreach($this->cnf['mapping'] as $localkey => $key) {
|
---|
| 204 | if(is_array($key)) {
|
---|
| 205 | // use regexp to clean up user_result
|
---|
| 206 | list($key, $regexp) = each($key);
|
---|
| 207 | if($user_result[$key]) foreach($user_result[$key] as $grp){
|
---|
| 208 | if (preg_match($regexp,$grp,$match)) {
|
---|
| 209 | if($localkey == 'grps') {
|
---|
| 210 | $info[$localkey][] = $match[1];
|
---|
| 211 | } else {
|
---|
| 212 | $info[$localkey] = $match[1];
|
---|
| 213 | }
|
---|
| 214 | }
|
---|
| 215 | }
|
---|
| 216 | } else {
|
---|
| 217 | $info[$localkey] = $user_result[$key][0];
|
---|
| 218 | }
|
---|
| 219 | }
|
---|
| 220 | }
|
---|
| 221 | $user_result = array_merge($info,$user_result);
|
---|
| 222 |
|
---|
| 223 | //get groups for given user if grouptree is given
|
---|
| 224 | if ($this->cnf['grouptree'] || $this->cnf['groupfilter']) {
|
---|
| 225 | $base = $this->_makeFilter($this->cnf['grouptree'], $user_result);
|
---|
| 226 | $filter = $this->_makeFilter($this->cnf['groupfilter'], $user_result);
|
---|
| 227 | $sr = $this->_ldapsearch($this->con, $base, $filter, $this->cnf['groupscope'], array($this->cnf['groupkey']));
|
---|
| 228 | if($this->cnf['debug']){
|
---|
| 229 | msg('LDAP group search: '.htmlspecialchars(ldap_error($this->con)),0,__LINE__,__FILE__);
|
---|
| 230 | msg('LDAP search at: '.htmlspecialchars($base.' '.$filter),0,__LINE__,__FILE__);
|
---|
| 231 | }
|
---|
| 232 | if(!$sr){
|
---|
| 233 | msg("LDAP: Reading group memberships failed",-1);
|
---|
| 234 | return false;
|
---|
| 235 | }
|
---|
| 236 | $result = ldap_get_entries($this->con, $sr);
|
---|
| 237 | ldap_free_result($sr);
|
---|
| 238 |
|
---|
| 239 | if(is_array($result)) foreach($result as $grp){
|
---|
| 240 | if(!empty($grp[$this->cnf['groupkey']][0])){
|
---|
| 241 | if($this->cnf['debug'])
|
---|
| 242 | msg('LDAP usergroup: '.htmlspecialchars($grp[$this->cnf['groupkey']][0]),0,__LINE__,__FILE__);
|
---|
| 243 | $info['grps'][] = $grp[$this->cnf['groupkey']][0];
|
---|
| 244 | }
|
---|
| 245 | }
|
---|
| 246 | }
|
---|
| 247 |
|
---|
| 248 | // always add the default group to the list of groups
|
---|
| 249 | if(!in_array($conf['defaultgroup'],$info['grps'])){
|
---|
| 250 | $info['grps'][] = $conf['defaultgroup'];
|
---|
| 251 | }
|
---|
| 252 | return $info;
|
---|
| 253 | }
|
---|
| 254 |
|
---|
| 255 | /**
|
---|
| 256 | * Most values in LDAP are case-insensitive
|
---|
| 257 | */
|
---|
| 258 | function isCaseSensitive(){
|
---|
| 259 | return false;
|
---|
| 260 | }
|
---|
| 261 |
|
---|
| 262 | /**
|
---|
| 263 | * Bulk retrieval of user data
|
---|
| 264 | *
|
---|
| 265 | * @author Dominik Eckelmann <[email protected]>
|
---|
| 266 | * @param start index of first user to be returned
|
---|
| 267 | * @param limit max number of users to be returned
|
---|
| 268 | * @param filter array of field/pattern pairs, null for no filter
|
---|
| 269 | * @return array of userinfo (refer getUserData for internal userinfo details)
|
---|
| 270 | */
|
---|
| 271 | function retrieveUsers($start=0,$limit=-1,$filter=array()) {
|
---|
| 272 | if(!$this->_openLDAP()) return false;
|
---|
| 273 |
|
---|
| 274 | if (!isset($this->users)) {
|
---|
| 275 | // Perform the search and grab all their details
|
---|
| 276 | if(!empty($this->cnf['userfilter'])) {
|
---|
| 277 | $all_filter = str_replace('%{user}', '*', $this->cnf['userfilter']);
|
---|
| 278 | } else {
|
---|
| 279 | $all_filter = "(ObjectClass=*)";
|
---|
| 280 | }
|
---|
| 281 | $sr=ldap_search($this->con,$this->cnf['usertree'],$all_filter);
|
---|
| 282 | $entries = ldap_get_entries($this->con, $sr);
|
---|
| 283 | $users_array = array();
|
---|
| 284 | for ($i=0; $i<$entries["count"]; $i++){
|
---|
| 285 | array_push($users_array, $entries[$i]["uid"][0]);
|
---|
| 286 | }
|
---|
| 287 | asort($users_array);
|
---|
| 288 | $result = $users_array;
|
---|
| 289 | if (!$result) return array();
|
---|
| 290 | $this->users = array_fill_keys($result, false);
|
---|
| 291 | }
|
---|
| 292 | $i = 0;
|
---|
| 293 | $count = 0;
|
---|
| 294 | $this->_constructPattern($filter);
|
---|
| 295 | $result = array();
|
---|
| 296 |
|
---|
| 297 | foreach ($this->users as $user => &$info) {
|
---|
| 298 | if ($i++ < $start) {
|
---|
| 299 | continue;
|
---|
| 300 | }
|
---|
| 301 | if ($info === false) {
|
---|
| 302 | $info = $this->getUserData($user);
|
---|
| 303 | }
|
---|
| 304 | if ($this->_filter($user, $info)) {
|
---|
| 305 | $result[$user] = $info;
|
---|
| 306 | if (($limit >= 0) && (++$count >= $limit)) break;
|
---|
| 307 | }
|
---|
| 308 | }
|
---|
| 309 | return $result;
|
---|
| 310 |
|
---|
| 311 |
|
---|
| 312 | }
|
---|
| 313 |
|
---|
| 314 | /**
|
---|
| 315 | * Make LDAP filter strings.
|
---|
| 316 | *
|
---|
| 317 | * Used by auth_getUserData to make the filter
|
---|
| 318 | * strings for grouptree and groupfilter
|
---|
| 319 | *
|
---|
| 320 | * filter string ldap search filter with placeholders
|
---|
| 321 | * placeholders array array with the placeholders
|
---|
| 322 | *
|
---|
| 323 | * @author Troels Liebe Bentsen <[email protected]>
|
---|
| 324 | * @return string
|
---|
| 325 | */
|
---|
| 326 | function _makeFilter($filter, $placeholders) {
|
---|
| 327 | preg_match_all("/%{([^}]+)/", $filter, $matches, PREG_PATTERN_ORDER);
|
---|
| 328 | //replace each match
|
---|
| 329 | foreach ($matches[1] as $match) {
|
---|
| 330 | //take first element if array
|
---|
| 331 | if(is_array($placeholders[$match])) {
|
---|
| 332 | $value = $placeholders[$match][0];
|
---|
| 333 | } else {
|
---|
| 334 | $value = $placeholders[$match];
|
---|
| 335 | }
|
---|
| 336 | $value = $this->_filterEscape($value);
|
---|
| 337 | $filter = str_replace('%{'.$match.'}', $value, $filter);
|
---|
| 338 | }
|
---|
| 339 | return $filter;
|
---|
| 340 | }
|
---|
| 341 |
|
---|
| 342 | /**
|
---|
| 343 | * return 1 if $user + $info match $filter criteria, 0 otherwise
|
---|
| 344 | *
|
---|
| 345 | * @author Chris Smith <[email protected]>
|
---|
| 346 | */
|
---|
| 347 | function _filter($user, $info) {
|
---|
| 348 | foreach ($this->_pattern as $item => $pattern) {
|
---|
| 349 | if ($item == 'user') {
|
---|
| 350 | if (!preg_match($pattern, $user)) return 0;
|
---|
| 351 | } else if ($item == 'grps') {
|
---|
| 352 | if (!count(preg_grep($pattern, $info['grps']))) return 0;
|
---|
| 353 | } else {
|
---|
| 354 | if (!preg_match($pattern, $info[$item])) return 0;
|
---|
| 355 | }
|
---|
| 356 | }
|
---|
| 357 | return 1;
|
---|
| 358 | }
|
---|
| 359 |
|
---|
| 360 | function _constructPattern($filter) {
|
---|
| 361 | $this->_pattern = array();
|
---|
| 362 | foreach ($filter as $item => $pattern) {
|
---|
| 363 | // $this->_pattern[$item] = '/'.preg_quote($pattern,"/").'/i'; // don't allow regex characters
|
---|
| 364 | $this->_pattern[$item] = '/'.str_replace('/','\/',$pattern).'/i'; // allow regex characters
|
---|
| 365 | }
|
---|
| 366 | }
|
---|
| 367 |
|
---|
| 368 | /**
|
---|
| 369 | * Escape a string to be used in a LDAP filter
|
---|
| 370 | *
|
---|
| 371 | * Ported from Perl's Net::LDAP::Util escape_filter_value
|
---|
| 372 | *
|
---|
| 373 | * @author Andreas Gohr
|
---|
| 374 | */
|
---|
| 375 | function _filterEscape($string){
|
---|
| 376 | return preg_replace('/([\x00-\x1F\*\(\)\\\\])/e',
|
---|
| 377 | '"\\\\\".join("",unpack("H2","$1"))',
|
---|
| 378 | $string);
|
---|
| 379 | }
|
---|
| 380 |
|
---|
| 381 | /**
|
---|
| 382 | * Opens a connection to the configured LDAP server and sets the wanted
|
---|
| 383 | * option on the connection
|
---|
| 384 | *
|
---|
| 385 | * @author Andreas Gohr <[email protected]>
|
---|
| 386 | */
|
---|
| 387 | function _openLDAP(){
|
---|
| 388 | if($this->con) return true; // connection already established
|
---|
| 389 |
|
---|
| 390 | $this->bound = 0;
|
---|
| 391 |
|
---|
| 392 | $port = ($this->cnf['port']) ? $this->cnf['port'] : 389;
|
---|
| 393 | $this->con = @ldap_connect($this->cnf['server'],$port);
|
---|
| 394 | if(!$this->con){
|
---|
| 395 | msg("LDAP: couldn't connect to LDAP server",-1);
|
---|
| 396 | return false;
|
---|
| 397 | }
|
---|
| 398 |
|
---|
| 399 | //set protocol version and dependend options
|
---|
| 400 | if($this->cnf['version']){
|
---|
| 401 | if(!@ldap_set_option($this->con, LDAP_OPT_PROTOCOL_VERSION,
|
---|
| 402 | $this->cnf['version'])){
|
---|
| 403 | msg('Setting LDAP Protocol version '.$this->cnf['version'].' failed',-1);
|
---|
| 404 | if($this->cnf['debug'])
|
---|
| 405 | msg('LDAP version set: '.htmlspecialchars(ldap_error($this->con)),0,__LINE__,__FILE__);
|
---|
| 406 | }else{
|
---|
| 407 | //use TLS (needs version 3)
|
---|
| 408 | if($this->cnf['starttls']) {
|
---|
| 409 | if (!@ldap_start_tls($this->con)){
|
---|
| 410 | msg('Starting TLS failed',-1);
|
---|
| 411 | if($this->cnf['debug'])
|
---|
| 412 | msg('LDAP TLS set: '.htmlspecialchars(ldap_error($this->con)),0,__LINE__,__FILE__);
|
---|
| 413 | }
|
---|
| 414 | }
|
---|
| 415 | // needs version 3
|
---|
| 416 | if(isset($this->cnf['referrals'])) {
|
---|
| 417 | if(!@ldap_set_option($this->con, LDAP_OPT_REFERRALS,
|
---|
| 418 | $this->cnf['referrals'])){
|
---|
| 419 | msg('Setting LDAP referrals to off failed',-1);
|
---|
| 420 | if($this->cnf['debug'])
|
---|
| 421 | msg('LDAP referal set: '.htmlspecialchars(ldap_error($this->con)),0,__LINE__,__FILE__);
|
---|
| 422 | }
|
---|
| 423 | }
|
---|
| 424 | }
|
---|
| 425 | }
|
---|
| 426 |
|
---|
| 427 | //set deref mode
|
---|
| 428 | if($this->cnf['deref']){
|
---|
| 429 | if(!@ldap_set_option($this->con, LDAP_OPT_DEREF, $this->cnf['deref'])){
|
---|
| 430 | msg('Setting LDAP Deref mode '.$this->cnf['deref'].' failed',-1);
|
---|
| 431 | if($this->cnf['debug'])
|
---|
| 432 | msg('LDAP deref set: '.htmlspecialchars(ldap_error($this->con)),0,__LINE__,__FILE__);
|
---|
| 433 | }
|
---|
| 434 | }
|
---|
| 435 |
|
---|
| 436 | $this->canDo['getUsers'] = true;
|
---|
| 437 | return true;
|
---|
| 438 | }
|
---|
| 439 |
|
---|
| 440 | /**
|
---|
| 441 | * Wraps around ldap_search, ldap_list or ldap_read depending on $scope
|
---|
| 442 | *
|
---|
| 443 | * @param $scope string - can be 'base', 'one' or 'sub'
|
---|
| 444 | * @author Andreas Gohr <[email protected]>
|
---|
| 445 | */
|
---|
| 446 | function _ldapsearch($link_identifier, $base_dn, $filter, $scope='sub', $attributes=null,
|
---|
| 447 | $attrsonly=0, $sizelimit=0, $timelimit=0, $deref=LDAP_DEREF_NEVER){
|
---|
| 448 | if(is_null($attributes)) $attributes = array();
|
---|
| 449 |
|
---|
| 450 | if($scope == 'base'){
|
---|
| 451 | return @ldap_read($link_identifier, $base_dn, $filter, $attributes,
|
---|
| 452 | $attrsonly, $sizelimit, $timelimit, $deref);
|
---|
| 453 | }elseif($scope == 'one'){
|
---|
| 454 | return @ldap_list($link_identifier, $base_dn, $filter, $attributes,
|
---|
| 455 | $attrsonly, $sizelimit, $timelimit, $deref);
|
---|
| 456 | }else{
|
---|
| 457 | return @ldap_search($link_identifier, $base_dn, $filter, $attributes,
|
---|
| 458 | $attrsonly, $sizelimit, $timelimit, $deref);
|
---|
| 459 | }
|
---|
| 460 | }
|
---|
| 461 | }
|
---|
| 462 |
|
---|
| 463 | //Setup VIM: ex: et ts=4 :
|
---|