diff options
Diffstat (limited to 'inc/auth/ldap.class.php')
-rw-r--r-- | inc/auth/ldap.class.php | 111 |
1 files changed, 107 insertions, 4 deletions
diff --git a/inc/auth/ldap.class.php b/inc/auth/ldap.class.php index c51924135..5cc186ce2 100644 --- a/inc/auth/ldap.class.php +++ b/inc/auth/ldap.class.php @@ -27,7 +27,9 @@ class auth_ldap extends auth_basic { return; } - if(empty($this->cnf['groupkey'])) $this->cnf['groupkey'] = 'cn'; + if(empty($this->cnf['groupkey'])) $this->cnf['groupkey'] = 'cn'; + if(empty($this->cnf['userscope'])) $this->cnf['userscope'] = 'sub'; + if(empty($this->cnf['groupscope'])) $this->cnf['groupscope'] = 'sub'; // auth_ldap currently just handles authentication, so no // capabilities are set @@ -171,7 +173,7 @@ class auth_ldap extends auth_basic { $filter = "(ObjectClass=*)"; } - $sr = @ldap_search($this->con, $base, $filter); + $sr = $this->_ldapsearch($this->con, $base, $filter, $this->cnf['userscope']); $result = @ldap_get_entries($this->con, $sr); if($this->cnf['debug']){ msg('LDAP user search: '.htmlspecialchars(ldap_error($this->con)),0,__LINE__,__FILE__); @@ -216,10 +218,10 @@ class auth_ldap extends auth_basic { $user_result = array_merge($info,$user_result); //get groups for given user if grouptree is given - if ($this->cnf['grouptree'] && $this->cnf['groupfilter']) { + if ($this->cnf['grouptree'] || $this->cnf['groupfilter']) { $base = $this->_makeFilter($this->cnf['grouptree'], $user_result); $filter = $this->_makeFilter($this->cnf['groupfilter'], $user_result); - $sr = @ldap_search($this->con, $base, $filter, array($this->cnf['groupkey'])); + $sr = $this->_ldapsearch($this->con, $base, $filter, $this->cnf['groupscope'], array($this->cnf['groupkey'])); if(!$sr){ msg("LDAP: Reading group memberships failed",-1); if($this->cnf['debug']){ @@ -255,6 +257,58 @@ class auth_ldap extends auth_basic { } /** + * Bulk retrieval of user data + * + * @author Dominik Eckelmann <dokuwiki@cosmocode.de> + * @param start index of first user to be returned + * @param limit max number of users to be returned + * @param filter array of field/pattern pairs, null for no filter + * @return array of userinfo (refer getUserData for internal userinfo details) + */ + function retrieveUsers($start=0,$limit=-1,$filter=array()) { + if(!$this->_openLDAP()) return false; + + if (!isset($this->users)) { + // Perform the search and grab all their details + if(!empty($this->cnf['userfilter'])) { + $all_filter = str_replace('%{user}', '*', $this->cnf['userfilter']); + } else { + $all_filter = "(ObjectClass=*)"; + } + $sr=ldap_search($this->con,$this->cnf['usertree'],$all_filter); + $entries = ldap_get_entries($this->con, $sr); + $users_array = array(); + for ($i=0; $i<$entries["count"]; $i++){ + array_push($users_array, $entries[$i]["uid"][0]); + } + asort($users_array); + $result = $users_array; + if (!$result) return array(); + $this->users = array_fill_keys($result, false); + } + $i = 0; + $count = 0; + $this->_constructPattern($filter); + $result = array(); + + foreach ($this->users as $user => &$info) { + if ($i++ < $start) { + continue; + } + if ($info === false) { + $info = $this->getUserData($user); + } + if ($this->_filter($user, $info)) { + $result[$user] = $info; + if (($limit >= 0) && (++$count >= $limit)) break; + } + } + return $result; + + + } + + /** * Make LDAP filter strings. * * Used by auth_getUserData to make the filter @@ -283,6 +337,32 @@ class auth_ldap extends auth_basic { } /** + * return 1 if $user + $info match $filter criteria, 0 otherwise + * + * @author Chris Smith <chris@jalakai.co.uk> + */ + function _filter($user, $info) { + foreach ($this->_pattern as $item => $pattern) { + if ($item == 'user') { + if (!preg_match($pattern, $user)) return 0; + } else if ($item == 'grps') { + if (!count(preg_grep($pattern, $info['grps']))) return 0; + } else { + if (!preg_match($pattern, $info[$item])) return 0; + } + } + return 1; + } + + function _constructPattern($filter) { + $this->_pattern = array(); + foreach ($filter as $item => $pattern) { +// $this->_pattern[$item] = '/'.preg_quote($pattern,"/").'/i'; // don't allow regex characters + $this->_pattern[$item] = '/'.str_replace('/','\/',$pattern).'/i'; // allow regex characters + } + } + + /** * Escape a string to be used in a LDAP filter * * Ported from Perl's Net::LDAP::Util escape_filter_value @@ -350,8 +430,31 @@ class auth_ldap extends auth_basic { } } + $this->canDo['getUsers'] = true; return true; } + + /** + * Wraps around ldap_search, ldap_list or ldap_read depending on $scope + * + * @param $scope string - can be 'base', 'one' or 'sub' + * @author Andreas Gohr <andi@splitbrain.org> + */ + function _ldapsearch($link_identifier, $base_dn, $filter, $scope='sub', $attributes=null, + $attrsonly=0, $sizelimit=0, $timelimit=0, $deref=LDAP_DEREF_NEVER){ + if(is_null($attributes)) $attributes = array(); + + if($scope == 'base'){ + return @ldap_read($link_identifier, $base_dn, $filter, $attributes, + $attrsonly, $sizelimit, $timelimit, $deref); + }elseif($scope == 'one'){ + return @ldap_list($link_identifier, $base_dn, $filter, $attributes, + $attrsonly, $sizelimit, $timelimit, $deref); + }else{ + return @ldap_search($link_identifier, $base_dn, $filter, $attributes, + $attrsonly, $sizelimit, $timelimit, $deref); + } + } } //Setup VIM: ex: et ts=4 enc=utf-8 : |