Failed Conditions
Push — psr2 ( ccc4c7...2140e7 )
by Andreas
26s queued 20s
created

auth_plugin_authldap::_getUserData()   F

Complexity

Conditions 31
Paths 130

Size

Total Lines 137

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 31
nc 130
nop 2
dl 0
loc 137
rs 3.1333
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * LDAP authentication backend
5
 *
6
 * @license   GPL 2 (http://www.gnu.org/licenses/gpl.html)
7
 * @author    Andreas Gohr <[email protected]>
8
 * @author    Chris Smith <[email protected]>
9
 * @author    Jan Schumann <[email protected]>
10
 */
11
class auth_plugin_authldap extends DokuWiki_Auth_Plugin
12
{
13
    /* @var resource $con holds the LDAP connection */
14
    protected $con = null;
15
16
    /* @var int $bound What type of connection does already exist? */
17
    protected $bound = 0; // 0: anonymous, 1: user, 2: superuser
18
19
    /* @var array $users User data cache */
20
    protected $users = null;
21
22
    /* @var array $pattern User filter pattern */
23
    protected $pattern = null;
24
25
    /**
26
     * Constructor
27
     */
28
    public function __construct()
29
    {
30
        parent::__construct();
31
32
        // ldap extension is needed
33
        if (!function_exists('ldap_connect')) {
34
            $this->debug("LDAP err: PHP LDAP extension not found.", -1, __LINE__, __FILE__);
35
            $this->success = false;
36
            return;
37
        }
38
39
        // Add the capabilities to change the password
40
        $this->cando['modPass'] = $this->getConf('modPass');
41
    }
42
43
    /**
44
     * Check user+password
45
     *
46
     * Checks if the given user exists and the given
47
     * plaintext password is correct by trying to bind
48
     * to the LDAP server
49
     *
50
     * @author  Andreas Gohr <[email protected]>
51
     * @param string $user
52
     * @param string $pass
53
     * @return  bool
54
     */
55
    public function checkPass($user, $pass)
56
    {
57
        // reject empty password
58
        if (empty($pass)) return false;
59
        if (!$this->openLDAP()) return false;
60
61
        // indirect user bind
62
        if ($this->getConf('binddn') && $this->getConf('bindpw')) {
63
            // use superuser credentials
64
            if (!@ldap_bind($this->con, $this->getConf('binddn'), conf_decodeString($this->getConf('bindpw')))) {
65
                $this->debug('LDAP bind as superuser: ' . hsc(ldap_error($this->con)), 0, __LINE__, __FILE__);
66
                return false;
67
            }
68
            $this->bound = 2;
69
        } elseif ($this->getConf('binddn') &&
70
            $this->getConf('usertree') &&
71
            $this->getConf('userfilter')
72
        ) {
73
            // special bind string
74
            $dn = $this->makeFilter(
75
                $this->getConf('binddn'),
76
                array('user' => $user, 'server' => $this->getConf('server'))
77
            );
78
        } elseif (strpos($this->getConf('usertree'), '%{user}')) {
79
            // direct user bind
80
            $dn = $this->makeFilter(
81
                $this->getConf('usertree'),
82
                array('user' => $user, 'server' => $this->getConf('server'))
83
            );
84
        } else {
85
            // Anonymous bind
86
            if (!@ldap_bind($this->con)) {
87
                msg("LDAP: can not bind anonymously", -1);
88
                $this->debug('LDAP anonymous bind: ' . hsc(ldap_error($this->con)), 0, __LINE__, __FILE__);
89
                return false;
90
            }
91
        }
92
93
        // Try to bind to with the dn if we have one.
94
        if (!empty($dn)) {
95
            // User/Password bind
96
            if (!@ldap_bind($this->con, $dn, $pass)) {
97
                $this->debug("LDAP: bind with $dn failed", -1, __LINE__, __FILE__);
98
                $this->debug('LDAP user dn bind: ' . hsc(ldap_error($this->con)), 0, __LINE__, __FILE__);
99
                return false;
100
            }
101
            $this->bound = 1;
102
            return true;
103
        } else {
104
            // See if we can find the user
105
            $info = $this->fetchUserData($user, true);
106
            if (empty($info['dn'])) {
107
                return false;
108
            } else {
109
                $dn = $info['dn'];
110
            }
111
112
            // Try to bind with the dn provided
113
            if (!@ldap_bind($this->con, $dn, $pass)) {
114
                $this->debug("LDAP: bind with $dn failed", -1, __LINE__, __FILE__);
115
                $this->debug('LDAP user bind: ' . hsc(ldap_error($this->con)), 0, __LINE__, __FILE__);
116
                return false;
117
            }
118
            $this->bound = 1;
119
            return true;
120
        }
121
    }
122
123
    /**
124
     * Return user info
125
     *
126
     * Returns info about the given user needs to contain
127
     * at least these fields:
128
     *
129
     * name string  full name of the user
130
     * mail string  email addres of the user
131
     * grps array   list of groups the user is in
132
     *
133
     * This LDAP specific function returns the following
134
     * addional fields:
135
     *
136
     * dn     string  distinguished name (DN)
137
     * uid    string  Posix User ID
138
     * inbind bool    for internal use - avoid loop in binding
139
     *
140
     * @author  Andreas Gohr <[email protected]>
141
     * @author  Trouble
142
     * @author  Dan Allen <[email protected]>
143
     * @author  <[email protected]>
144
     * @author  Stephane Chazelas <[email protected]>
145
     * @author  Steffen Schoch <[email protected]>
146
     *
147
     * @param   string $user
148
     * @param   bool $requireGroups (optional) - ignored, groups are always supplied by this plugin
149
     * @return  array containing user data or false
150
     */
151
    public function getUserData($user, $requireGroups = true)
152
    {
153
        return $this->fetchUserData($user);
154
    }
155
156
    /**
157
     * @param   string $user
158
     * @param   bool $inbind authldap specific, true if in bind phase
159
     * @return  array containing user data or false
160
     */
161
    protected function fetchUserData($user, $inbind = false)
162
    {
163
        global $conf;
164
        if (!$this->openLDAP()) return array();
165
166
        // force superuser bind if wanted and not bound as superuser yet
167
        if ($this->getConf('binddn') && $this->getConf('bindpw') && $this->bound < 2) {
168
            // use superuser credentials
169
            if (!@ldap_bind($this->con, $this->getConf('binddn'), conf_decodeString($this->getConf('bindpw')))) {
170
                $this->debug('LDAP bind as superuser: ' . hsc(ldap_error($this->con)), 0, __LINE__, __FILE__);
171
                return array();
172
            }
173
            $this->bound = 2;
174
        } elseif ($this->bound == 0 && !$inbind) {
175
            // in some cases getUserData is called outside the authentication workflow
176
            // eg. for sending email notification on subscribed pages. This data might not
177
            // be accessible anonymously, so we try to rebind the current user here
178
            list($loginuser, $loginsticky, $loginpass) = auth_getCookie();
179
            if ($loginuser && $loginpass) {
180
                $loginpass = auth_decrypt($loginpass, auth_cookiesalt(!$loginsticky, true));
0 ignored issues
show
Bug introduced by
It seems like auth_cookiesalt(!$loginsticky, true) targeting auth_cookiesalt() can also be of type boolean; however, auth_decrypt() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
181
                $this->checkPass($loginuser, $loginpass);
182
            }
183
        }
184
185
        $info = array();
186
        $info['user'] = $user;
187
        $this->debug('LDAP user to find: ' . hsc($info['user']), 0, __LINE__, __FILE__);
188
189
        $info['server'] = $this->getConf('server');
190
        $this->debug('LDAP Server: ' . hsc($info['server']), 0, __LINE__, __FILE__);
191
192
        //get info for given user
193
        $base = $this->makeFilter($this->getConf('usertree'), $info);
194
        if ($this->getConf('userfilter')) {
195
            $filter = $this->makeFilter($this->getConf('userfilter'), $info);
196
        } else {
197
            $filter = "(ObjectClass=*)";
198
        }
199
200
        $this->debug('LDAP Filter: ' . hsc($filter), 0, __LINE__, __FILE__);
201
202
        $this->debug('LDAP user search: ' . hsc(ldap_error($this->con)), 0, __LINE__, __FILE__);
203
        $this->debug('LDAP search at: ' . hsc($base . ' ' . $filter), 0, __LINE__, __FILE__);
204
        $sr = $this->ldapSearch($this->con, $base, $filter, $this->getConf('userscope'));
205
206
        $result = @ldap_get_entries($this->con, $sr);
207
208
        // if result is not an array
209
        if (!is_array($result)) {
210
            // no objects found
211
            $this->debug('LDAP search returned non-array result: ' . hsc(print($result)), -1, __LINE__, __FILE__);
212
            return array();
213
        }
214
215
        // Don't accept more or less than one response
216
        if ($result['count'] != 1) {
217
            $this->debug(
218
                'LDAP search returned ' . hsc($result['count']) . ' results while it should return 1!',
219
                -1,
220
                __LINE__,
221
                __FILE__
222
            );
223
            //for($i = 0; $i < $result["count"]; $i++) {
224
            //$this->_debug('result: '.hsc(print_r($result[$i])), 0, __LINE__, __FILE__);
225
            //}
226
            return array();
227
        }
228
229
        $this->debug('LDAP search found single result !', 0, __LINE__, __FILE__);
230
231
        $user_result = $result[0];
232
        ldap_free_result($sr);
233
234
        // general user info
235
        $info['dn'] = $user_result['dn'];
236
        $info['gid'] = $user_result['gidnumber'][0];
237
        $info['mail'] = $user_result['mail'][0];
238
        $info['name'] = $user_result['cn'][0];
239
        $info['grps'] = array();
240
241
        // overwrite if other attribs are specified.
242
        if (is_array($this->getConf('mapping'))) {
243
            foreach ($this->getConf('mapping') as $localkey => $key) {
244
                if (is_array($key)) {
245
                    // use regexp to clean up user_result
246
                    // $key = array($key=>$regexp), only handles the first key-value
247
                    $regexp = current($key);
248
                    $key = key($key);
249
                    if ($user_result[$key]) foreach ($user_result[$key] as $grpkey => $grp) {
250
                        if ($grpkey !== 'count' && preg_match($regexp, $grp, $match)) {
251
                            if ($localkey == 'grps') {
252
                                $info[$localkey][] = $match[1];
253
                            } else {
254
                                $info[$localkey] = $match[1];
255
                            }
256
                        }
257
                    }
258
                } else {
259
                    $info[$localkey] = $user_result[$key][0];
260
                }
261
            }
262
        }
263
        $user_result = array_merge($info, $user_result);
264
265
        //get groups for given user if grouptree is given
266
        if ($this->getConf('grouptree') || $this->getConf('groupfilter')) {
267
            $base = $this->makeFilter($this->getConf('grouptree'), $user_result);
268
            $filter = $this->makeFilter($this->getConf('groupfilter'), $user_result);
269
            $sr = $this->ldapSearch(
270
                $this->con,
271
                $base,
272
                $filter,
273
                $this->getConf('groupscope'),
274
                array($this->getConf('groupkey'))
275
            );
276
            $this->debug('LDAP group search: ' . hsc(ldap_error($this->con)), 0, __LINE__, __FILE__);
277
            $this->debug('LDAP search at: ' . hsc($base . ' ' . $filter), 0, __LINE__, __FILE__);
278
279
            if (!$sr) {
280
                msg("LDAP: Reading group memberships failed", -1);
281
                return array();
282
            }
283
            $result = ldap_get_entries($this->con, $sr);
284
            ldap_free_result($sr);
285
286
            if (is_array($result)) foreach ($result as $grp) {
287
                if (!empty($grp[$this->getConf('groupkey')])) {
288
                    $group = $grp[$this->getConf('groupkey')];
289
                    if (is_array($group)) {
290
                        $group = $group[0];
291
                    } else {
292
                        $this->debug('groupkey did not return a detailled result', 0, __LINE__, __FILE__);
293
                    }
294
                    if ($group === '') continue;
295
296
                    $this->debug('LDAP usergroup: ' . hsc($group), 0, __LINE__, __FILE__);
297
                    $info['grps'][] = $group;
298
                }
299
            }
300
        }
301
302
        // always add the default group to the list of groups
303
        if (!$info['grps'] or !in_array($conf['defaultgroup'], $info['grps'])) {
304
            $info['grps'][] = $conf['defaultgroup'];
305
        }
306
        return $info;
307
    }
308
309
    /**
310
     * Definition of the function modifyUser in order to modify the password
311
     *
312
     * @param   string $user nick of the user to be changed
313
     * @param   array $changes array of field/value pairs to be changed (password will be clear text)
314
     * @return  bool   true on success, false on error
315
     */
316
    public function modifyUser($user, $changes)
317
    {
318
319
        // open the connection to the ldap
320
        if (!$this->openLDAP()) {
321
            $this->debug('LDAP cannot connect: ' . hsc(ldap_error($this->con)), 0, __LINE__, __FILE__);
322
            return false;
323
        }
324
325
        // find the information about the user, in particular the "dn"
326
        $info = $this->getUserData($user, true);
327
        if (empty($info['dn'])) {
328
            $this->debug('LDAP cannot find your user dn', 0, __LINE__, __FILE__);
329
            return false;
330
        }
331
        $dn = $info['dn'];
332
333
        // find the old password of the user
334
        list($loginuser, $loginsticky, $loginpass) = auth_getCookie();
335
        if ($loginuser !== null) { // the user is currently logged in
336
            $secret = auth_cookiesalt(!$loginsticky, true);
337
            $pass = auth_decrypt($loginpass, $secret);
338
339
            // bind with the ldap
340
            if (!@ldap_bind($this->con, $dn, $pass)) {
341
                $this->debug(
342
                    'LDAP user bind failed: ' . hsc($dn) . ': ' . hsc(ldap_error($this->con)),
343
                    0,
344
                    __LINE__,
345
                    __FILE__
346
                );
347
                return false;
348
            }
349
        } elseif ($this->getConf('binddn') && $this->getConf('bindpw')) {
350
            // we are changing the password on behalf of the user (eg: forgotten password)
351
            // bind with the superuser ldap
352
            if (!@ldap_bind($this->con, $this->getConf('binddn'), conf_decodeString($this->getConf('bindpw')))) {
353
                $this->debug('LDAP bind as superuser: ' . hsc(ldap_error($this->con)), 0, __LINE__, __FILE__);
354
                return false;
355
            }
356
        } else {
357
            return false; // no otherway
358
        }
359
360
        // Generate the salted hashed password for LDAP
361
        $phash = new PassHash();
362
        $hash = $phash->hash_ssha($changes['pass']);
363
364
        // change the password
365
        if (!@ldap_mod_replace($this->con, $dn, array('userpassword' => $hash))) {
366
            $this->debug(
367
                'LDAP mod replace failed: ' . hsc($dn) . ': ' . hsc(ldap_error($this->con)),
368
                0,
369
                __LINE__,
370
                __FILE__
371
            );
372
            return false;
373
        }
374
375
        return true;
376
    }
377
378
    /**
379
     * Most values in LDAP are case-insensitive
380
     *
381
     * @return bool
382
     */
383
    public function isCaseSensitive()
384
    {
385
        return false;
386
    }
387
388
    /**
389
     * Bulk retrieval of user data
390
     *
391
     * @author  Dominik Eckelmann <[email protected]>
392
     * @param   int $start index of first user to be returned
393
     * @param   int $limit max number of users to be returned
394
     * @param   array $filter array of field/pattern pairs, null for no filter
395
     * @return  array of userinfo (refer getUserData for internal userinfo details)
396
     */
397
    public function retrieveUsers($start = 0, $limit = 0, $filter = array())
398
    {
399
        if (!$this->openLDAP()) return array();
400
401
        if (is_null($this->users)) {
402
            // Perform the search and grab all their details
403
            if ($this->getConf('userfilter')) {
404
                $all_filter = str_replace('%{user}', '*', $this->getConf('userfilter'));
405
            } else {
406
                $all_filter = "(ObjectClass=*)";
407
            }
408
            $sr = ldap_search($this->con, $this->getConf('usertree'), $all_filter);
409
            $entries = ldap_get_entries($this->con, $sr);
410
            $users_array = array();
411
            $userkey = $this->getConf('userkey');
412
            for ($i = 0; $i < $entries["count"]; $i++) {
413
                array_push($users_array, $entries[$i][$userkey][0]);
414
            }
415
            asort($users_array);
416
            $result = $users_array;
417
            if (!$result) return array();
0 ignored issues
show
Bug Best Practice introduced by
The expression $result of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
418
            $this->users = array_fill_keys($result, false);
419
        }
420
        $i = 0;
421
        $count = 0;
422
        $this->constructPattern($filter);
423
        $result = array();
424
425
        foreach ($this->users as $user => &$info) {
426
            if ($i++ < $start) {
427
                continue;
428
            }
429
            if ($info === false) {
430
                $info = $this->getUserData($user);
431
            }
432
            if ($this->filter($user, $info)) {
433
                $result[$user] = $info;
434
                if (($limit > 0) && (++$count >= $limit)) break;
435
            }
436
        }
437
        return $result;
438
    }
439
440
    /**
441
     * Make LDAP filter strings.
442
     *
443
     * Used by auth_getUserData to make the filter
444
     * strings for grouptree and groupfilter
445
     *
446
     * @author  Troels Liebe Bentsen <[email protected]>
447
     * @param   string $filter ldap search filter with placeholders
448
     * @param   array $placeholders placeholders to fill in
449
     * @return  string
450
     */
451
    protected function makeFilter($filter, $placeholders)
452
    {
453
        preg_match_all("/%{([^}]+)/", $filter, $matches, PREG_PATTERN_ORDER);
454
        //replace each match
455
        foreach ($matches[1] as $match) {
456
            //take first element if array
457
            if (is_array($placeholders[$match])) {
458
                $value = $placeholders[$match][0];
459
            } else {
460
                $value = $placeholders[$match];
461
            }
462
            $value = $this->filterEscape($value);
463
            $filter = str_replace('%{' . $match . '}', $value, $filter);
464
        }
465
        return $filter;
466
    }
467
468
    /**
469
     * return true if $user + $info match $filter criteria, false otherwise
470
     *
471
     * @author Chris Smith <[email protected]>
472
     *
473
     * @param  string $user the user's login name
474
     * @param  array $info the user's userinfo array
475
     * @return bool
476
     */
477
    protected function filter($user, $info)
478
    {
479
        foreach ($this->pattern as $item => $pattern) {
480
            if ($item == 'user') {
481
                if (!preg_match($pattern, $user)) return false;
482
            } elseif ($item == 'grps') {
483
                if (!count(preg_grep($pattern, $info['grps']))) return false;
484
            } else {
485
                if (!preg_match($pattern, $info[$item])) return false;
486
            }
487
        }
488
        return true;
489
    }
490
491
    /**
492
     * Set the filter pattern
493
     *
494
     * @author Chris Smith <[email protected]>
495
     *
496
     * @param $filter
497
     * @return void
498
     */
499
    protected function constructPattern($filter)
500
    {
501
        $this->pattern = array();
502
        foreach ($filter as $item => $pattern) {
503
            $this->pattern[$item] = '/' . str_replace('/', '\/', $pattern) . '/i'; // allow regex characters
504
        }
505
    }
506
507
    /**
508
     * Escape a string to be used in a LDAP filter
509
     *
510
     * Ported from Perl's Net::LDAP::Util escape_filter_value
511
     *
512
     * @author Andreas Gohr
513
     * @param  string $string
514
     * @return string
515
     */
516
    protected function filterEscape($string)
517
    {
518
        // see https://github.com/adldap/adLDAP/issues/22
519
        return preg_replace_callback(
520
            '/([\x00-\x1F\*\(\)\\\\])/',
521
            function ($matches) {
522
                return "\\" . join("", unpack("H2", $matches[1]));
523
            },
524
            $string
525
        );
526
    }
527
528
    /**
529
     * Opens a connection to the configured LDAP server and sets the wanted
530
     * option on the connection
531
     *
532
     * @author  Andreas Gohr <[email protected]>
533
     */
534
    protected function openLDAP()
535
    {
536
        if ($this->con) return true; // connection already established
537
538
        if ($this->getConf('debug')) {
539
            ldap_set_option(null, LDAP_OPT_DEBUG_LEVEL, 7);
540
        }
541
542
        $this->bound = 0;
543
544
        $port = $this->getConf('port');
545
        $bound = false;
546
        $servers = explode(',', $this->getConf('server'));
547
        foreach ($servers as $server) {
548
            $server = trim($server);
549
            $this->con = @ldap_connect($server, $port);
550
            if (!$this->con) {
551
                continue;
552
            }
553
554
            /*
555
             * When OpenLDAP 2.x.x is used, ldap_connect() will always return a resource as it does
556
             * not actually connect but just initializes the connecting parameters. The actual
557
             * connect happens with the next calls to ldap_* funcs, usually with ldap_bind().
558
             *
559
             * So we should try to bind to server in order to check its availability.
560
             */
561
562
            //set protocol version and dependend options
563
            if ($this->getConf('version')) {
564
                if (!@ldap_set_option(
565
                    $this->con,
566
                    LDAP_OPT_PROTOCOL_VERSION,
567
                    $this->getConf('version')
568
                )
569
                ) {
570
                    msg('Setting LDAP Protocol version ' . $this->getConf('version') . ' failed', -1);
571
                    $this->debug('LDAP version set: ' . hsc(ldap_error($this->con)), 0, __LINE__, __FILE__);
572
                } else {
573
                    //use TLS (needs version 3)
574
                    if ($this->getConf('starttls')) {
575
                        if (!@ldap_start_tls($this->con)) {
576
                            msg('Starting TLS failed', -1);
577
                            $this->debug('LDAP TLS set: ' . hsc(ldap_error($this->con)), 0, __LINE__, __FILE__);
578
                        }
579
                    }
580
                    // needs version 3
581
                    if ($this->getConf('referrals') > -1) {
582
                        if (!@ldap_set_option(
583
                            $this->con,
584
                            LDAP_OPT_REFERRALS,
585
                            $this->getConf('referrals')
586
                        )
587
                        ) {
588
                            msg('Setting LDAP referrals failed', -1);
589
                            $this->debug('LDAP referal set: ' . hsc(ldap_error($this->con)), 0, __LINE__, __FILE__);
590
                        }
591
                    }
592
                }
593
            }
594
595
            //set deref mode
596
            if ($this->getConf('deref')) {
597
                if (!@ldap_set_option($this->con, LDAP_OPT_DEREF, $this->getConf('deref'))) {
598
                    msg('Setting LDAP Deref mode ' . $this->getConf('deref') . ' failed', -1);
599
                    $this->debug('LDAP deref set: ' . hsc(ldap_error($this->con)), 0, __LINE__, __FILE__);
600
                }
601
            }
602
            /* As of PHP 5.3.0 we can set timeout to speedup skipping of invalid servers */
603
            if (defined('LDAP_OPT_NETWORK_TIMEOUT')) {
604
                ldap_set_option($this->con, LDAP_OPT_NETWORK_TIMEOUT, 1);
605
            }
606
607
            if ($this->getConf('binddn') && $this->getConf('bindpw')) {
608
                $bound = @ldap_bind($this->con, $this->getConf('binddn'), conf_decodeString($this->getConf('bindpw')));
609
                $this->bound = 2;
610
            } else {
611
                $bound = @ldap_bind($this->con);
612
            }
613
            if ($bound) {
614
                break;
615
            }
616
        }
617
618
        if (!$bound) {
619
            msg("LDAP: couldn't connect to LDAP server", -1);
620
            $this->debug(ldap_error($this->con), 0, __LINE__, __FILE__);
621
            return false;
622
        }
623
624
        $this->cando['getUsers'] = true;
625
        return true;
626
    }
627
628
    /**
629
     * Wraps around ldap_search, ldap_list or ldap_read depending on $scope
630
     *
631
     * @author Andreas Gohr <[email protected]>
632
     * @param resource $link_identifier
633
     * @param string $base_dn
634
     * @param string $filter
635
     * @param string $scope can be 'base', 'one' or 'sub'
636
     * @param null|array $attributes
637
     * @param int $attrsonly
638
     * @param int $sizelimit
639
     * @return resource
640
     */
641
    protected function ldapSearch(
642
        $link_identifier,
643
        $base_dn,
644
        $filter,
645
        $scope = 'sub',
646
        $attributes = null,
647
        $attrsonly = 0,
648
        $sizelimit = 0
649
    ) {
650
        if (is_null($attributes)) $attributes = array();
651
652
        if ($scope == 'base') {
653
            return @ldap_read(
654
                $link_identifier,
655
                $base_dn,
656
                $filter,
657
                $attributes,
658
                $attrsonly,
659
                $sizelimit
660
            );
661
        } elseif ($scope == 'one') {
662
            return @ldap_list(
663
                $link_identifier,
664
                $base_dn,
665
                $filter,
666
                $attributes,
667
                $attrsonly,
668
                $sizelimit
669
            );
670
        } else {
671
            return @ldap_search(
672
                $link_identifier,
673
                $base_dn,
674
                $filter,
675
                $attributes,
676
                $attrsonly,
677
                $sizelimit
678
            );
679
        }
680
    }
681
682
    /**
683
     * Wrapper around msg() but outputs only when debug is enabled
684
     *
685
     * @param string $message
686
     * @param int $err
687
     * @param int $line
688
     * @param string $file
689
     * @return void
690
     */
691
    protected function debug($message, $err, $line, $file)
692
    {
693
        if (!$this->getConf('debug')) return;
694
        msg($message, $err, $line, $file);
695
    }
696
}
697