summaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authorVicDeo <dubiniuk@owncloud.com>2014-02-25 15:41:10 +0200
committerVicDeo <dubiniuk@owncloud.com>2014-02-25 15:41:10 +0200
commitec9fe3f57f60f1b4f4f5050cd10aab9e9b1238c5 (patch)
tree1ec2b348d63d7931642c83f00ff35cad588adab4 /apps
parente10ca7c2e9d748a4abd607acd293311d8d570c7c (diff)
parent300b1131b47842252395d54ad28b4d6691d7775e (diff)
downloadnextcloud-server-ec9fe3f57f60f1b4f4f5050cd10aab9e9b1238c5.tar.gz
nextcloud-server-ec9fe3f57f60f1b4f4f5050cd10aab9e9b1238c5.zip
Merge pull request #6299 from leo-b/ldap_nested_groups
Add LDAP nested groups
Diffstat (limited to 'apps')
-rw-r--r--apps/user_ldap/group_ldap.php78
-rw-r--r--apps/user_ldap/lib/configuration.php3
-rw-r--r--apps/user_ldap/templates/settings.php1
3 files changed, 72 insertions, 10 deletions
diff --git a/apps/user_ldap/group_ldap.php b/apps/user_ldap/group_ldap.php
index 32e2cec5960..cef9ca3c4cf 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($dnGroup, &$seen = null) {
+ if ($seen === null) {
+ $seen = array();
+ }
+ $allMembers = array();
+ if (array_key_exists($dnGroup, $seen)) {
+ // avoid loops
+ return array();
+ }
+ // used extensively in cron job, caching makes sense for nested groups
+ $cacheKey = '_groupMembers'.$dnGroup;
+ if($this->access->connection->isCached($cacheKey)) {
+ return $this->access->connection->getFromCache($cacheKey);
+ }
+ $seen[$dnGroup] = 1;
+ $members = $this->access->readAttribute($dnGroup, $this->access->connection->ldapGroupMemberAssocAttr,
+ $this->access->connection->ldapGroupFilter);
+ if (is_array($members)) {
+ foreach ($members as $memberDN) {
+ $allMembers[$memberDN] = 1;
+ $nestedGroups = $this->access->connection->ldapNestedGroups;
+ if (!empty($nestedGroups)) {
+ $subMembers = $this->_groupMembers($memberDN, $seen);
+ if ($subMembers) {
+ $allMembers = array_merge($allMembers, $subMembers);
+ }
+ }
+ }
+ }
+ $this->access->connection->writeToCache($cacheKey, $allMembers);
+ return $allMembers;
+ }
+
/**
* @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);
$this->access->connection->writeToCache($cacheKey, $groups);
return $groups;
}
+ private function getGroupsByMember($dn, &$seen = null) {
+ if ($seen === null) {
+ $seen = array();
+ }
+ $allGroups = array();
+ if (array_key_exists($dn, $seen)) {
+ // avoid loops
+ return array();
+ }
+ $seen[$dn] = true;
+ $filter = $this->access->combineFilterWithAnd(array(
+ $this->access->connection->ldapGroupFilter,
+ $this->access->connection->ldapGroupMemberAssocAttr.'='.$dn
+ ));
+ $groups = $this->access->fetchListOfGroups($filter,
+ array($this->access->connection->ldapGroupDisplayName, 'dn'));
+ if (is_array($groups)) {
+ foreach ($groups as $groupobj) {
+ $groupDN = $groupobj['dn'];
+ $allGroups[$groupDN] = $groupobj;
+ $nestedGroups = $this->access->connection->ldapNestedGroups;
+ if (!empty($nestedGroups)) {
+ $supergroups = $this->getGroupsByMember($groupDN, $seen);
+ if (is_array($supergroups) && (count($supergroups)>0)) {
+ $allGroups = array_merge($allGroups, $supergroups);
+ }
+ }
+ }
+ }
+ return $allGroups;
+ }
+
/**
* @brief get a list of all users in a group
* @returns array with user ids
@@ -172,8 +231,7 @@ 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));
if(!$members) {
//in case users could not be retrieved, return empty resultset
$this->access->connection->writeToCache($cachekey, array());
diff --git a/apps/user_ldap/lib/configuration.php b/apps/user_ldap/lib/configuration.php
index 954d0501fad..612a623e910 100644
--- a/apps/user_ldap/lib/configuration.php
+++ b/apps/user_ldap/lib/configuration.php
@@ -76,6 +76,7 @@ class Configuration {
'ldapExpertUUIDUserAttr' => null,
'ldapExpertUUIDGroupAttr' => null,
'lastJpegPhotoLookup' => null,
+ 'ldapNestedGroups' => false,
);
/**
@@ -342,6 +343,7 @@ class Configuration {
'ldap_expert_uuid_group_attr' => '',
'has_memberof_filter_support' => 0,
'last_jpegPhoto_lookup' => 0,
+ 'ldap_nested_groups' => 0,
);
}
@@ -393,6 +395,7 @@ class Configuration {
'ldap_expert_uuid_group_attr' => 'ldapExpertUUIDGroupAttr',
'has_memberof_filter_support' => 'hasMemberOfFilterSupport',
'last_jpegPhoto_lookup' => 'lastJpegPhotoLookup',
+ 'ldap_nested_groups' => 'ldapNestedGroups',
);
return $array;
}
diff --git a/apps/user_ldap/templates/settings.php b/apps/user_ldap/templates/settings.php
index 3ccc7a860f5..79c4ae224c3 100644
--- a/apps/user_ldap/templates/settings.php
+++ b/apps/user_ldap/templates/settings.php
@@ -36,6 +36,7 @@
<p><label for="ldap_base_groups"><?php p($l->t('Base Group Tree'));?></label><textarea id="ldap_base_groups" name="ldap_base_groups" placeholder="<?php p($l->t('One Group Base DN per line'));?>" data-default="<?php p($_['ldap_base_groups_default']); ?>" title="<?php p($l->t('Base Group Tree'));?>"></textarea></p>
<p><label for="ldap_attributes_for_group_search"><?php p($l->t('Group Search Attributes'));?></label><textarea id="ldap_attributes_for_group_search" name="ldap_attributes_for_group_search" placeholder="<?php p($l->t('Optional; one attribute per line'));?>" data-default="<?php p($_['ldap_attributes_for_group_search_default']); ?>" title="<?php p($l->t('Group Search Attributes'));?>"></textarea></p>
<p><label for="ldap_group_member_assoc_attribute"><?php p($l->t('Group-Member association'));?></label><select id="ldap_group_member_assoc_attribute" name="ldap_group_member_assoc_attribute" data-default="<?php p($_['ldap_group_member_assoc_attribute_default']); ?>" ><option value="uniqueMember"<?php if (isset($_['ldap_group_member_assoc_attribute']) && ($_['ldap_group_member_assoc_attribute'] === 'uniqueMember')) p(' selected'); ?>>uniqueMember</option><option value="memberUid"<?php if (isset($_['ldap_group_member_assoc_attribute']) && ($_['ldap_group_member_assoc_attribute'] === 'memberUid')) p(' selected'); ?>>memberUid</option><option value="member"<?php if (isset($_['ldap_group_member_assoc_attribute']) && ($_['ldap_group_member_assoc_attribute'] === 'member')) p(' selected'); ?>>member (AD)</option></select></p>
+ <p><label for="ldap_nested_groups"><?php p($l->t('Nested Groups'));?></label><input type="checkbox" id="ldap_nested_groups" name="ldap_nested_groups" value="1" data-default="<?php p($_['ldap_nested_groups_default']); ?>" title="<?php p($l->t('When switched on, groups that contain groups are supported. (Only works if the group member attribute contains DNs.)'));?>" /></p>
</div>
<h3><?php p($l->t('Special Attributes'));?></h3>
<div>