diff options
author | root <leo@strike.wu.ac.at> | 2013-12-06 16:46:52 +0100 |
---|---|---|
committer | root <leo@strike.wu.ac.at> | 2013-12-06 16:46:52 +0100 |
commit | 48e426b589029b8e616be2785afc8c0b4b4aecaf (patch) | |
tree | 840f212c381df5ef18c4b27b5d6a80c054b4be6f /apps/user_ldap/group_ldap.php | |
parent | 9371944e438bb30435732788b6b3d76a98374131 (diff) | |
download | nextcloud-server-48e426b589029b8e616be2785afc8c0b4b4aecaf.tar.gz nextcloud-server-48e426b589029b8e616be2785afc8c0b4b4aecaf.zip |
add support for nested groups
Diffstat (limited to 'apps/user_ldap/group_ldap.php')
-rw-r--r-- | apps/user_ldap/group_ldap.php | 79 |
1 files changed, 69 insertions, 10 deletions
diff --git a/apps/user_ldap/group_ldap.php b/apps/user_ldap/group_ldap.php index 32e2cec5960..0a5ab192763 100644 --- a/apps/user_ldap/group_ldap.php +++ b/apps/user_ldap/group_ldap.php @@ -61,8 +61,7 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface { return false; } //usually, LDAP attributes are said to be case insensitive. But there are exceptions of course. - $members = $this->access->readAttribute($dn_group, - $this->access->connection->ldapGroupMemberAssocAttr); + $members = array_keys($this->_groupMembers($dn_group)); if(!$members) { $this->access->connection->writeToCache('inGroup'.$uid.':'.$gid, false); return false; @@ -89,6 +88,39 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface { return $isInGroup; } + private function _groupMembers($dn_group, &$groups_seen = null) { + if ($groups_seen == null) { + $groups_seen = array(); + } + $all_members = array(); + if (array_key_exists($dn_group, $groups_seen)) { + // avoid loops + return array(); + } + // used extensively in cron job, caching makes sense for nested groups + $cache_key = '_groupMembers'.$dn_group; + if($this->access->connection->isCached($cache_key)) { + \OCP\Util::writeLog('user_ldap', 'LEO _groupMembers('.$dn_group.') using cached value', \OCP\Util::DEBUG); + return $this->access->connection->getFromCache($cache_key); + } + $groups_seen[$dn_group] = 1; + $members = $this->access->readAttribute($dn_group, $this->access->connection->ldapGroupMemberAssocAttr, + $this->access->connection->ldapGroupFilter); + if ($members) { + foreach ($members as $member_dn) { + $all_members[$member_dn] = 1; + if ($this->access->connection->ldapNestedGroups) { + $submembers = $this->_groupMembers($member_dn, $groups_seen); + if ($submembers) { + $all_members = array_merge($all_members, $submembers); + } + } + } + } + $this->access->connection->writeToCache($cache_key, $all_members); + return $all_members; + } + /** * @brief Get all groups a user belongs to * @param $uid Name of the user @@ -124,18 +156,45 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface { $uid = $userDN; } - $filter = $this->access->combineFilterWithAnd(array( - $this->access->connection->ldapGroupFilter, - $this->access->connection->ldapGroupMemberAssocAttr.'='.$uid - )); - $groups = $this->access->fetchListOfGroups($filter, - array($this->access->connection->ldapGroupDisplayName, 'dn')); + $groups = array_values($this->_getGroupsByMember($uid)); $groups = array_unique($this->access->ownCloudGroupNames($groups), SORT_LOCALE_STRING); + \OCP\Util::writeLog('user_ldap', 'LEO _getGroupsByMember('.$uid.'): '.implode(", ", $groups), \OCP\Util::DEBUG); $this->access->connection->writeToCache($cacheKey, $groups); return $groups; } + /* private */ public function _getGroupsByMember($dn, &$seen = null) { + if ($seen == null) { + $seen = array(); + } + $all_groups = array(); + if (array_key_exists($dn, $seen)) { + // avoid loops + return array(); + } + $seen[$dn] = 1; + $filter = $this->combineFilterWithAnd(array( + $this->access->connection->ldapGroupFilter, + $this->access->connection->ldapGroupMemberAssocAttr.'='.$dn + )); + $groups = $this->fetchListOfGroups($filter, + array($this->access->connection->ldapGroupDisplayName, 'dn')); + if ($groups) { + foreach ($groups as $groupobj) { + $group_dn = $groupobj['dn']; + $all_groups[$group_dn] = $groupobj; + if ($this->access->connection->ldapNestedGroups) { + $supergroups = $this->_getGroupsByMember($group_dn, $seen); + if ($supergroups) { + $all_groups = array_merge($all_groups, $supergroups); + } + } + } + } + return $all_groups; + } + /** * @brief get a list of all users in a group * @returns array with user ids @@ -172,8 +231,8 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface { return array(); } - $members = $this->access->readAttribute($groupDN, - $this->access->connection->ldapGroupMemberAssocAttr); + $members = array_keys($this->_groupMembers($groupDN)); + \OCP\Util::writeLog('user_ldap', 'LEO _groupMembers('.$groupDN.'): '.implode(", ", $members), \OCP\Util::DEBUG); if(!$members) { //in case users could not be retrieved, return empty resultset $this->access->connection->writeToCache($cachekey, array()); |