summaryrefslogtreecommitdiffstats
path: root/apps/user_ldap/group_ldap.php
diff options
context:
space:
mode:
Diffstat (limited to 'apps/user_ldap/group_ldap.php')
-rw-r--r--apps/user_ldap/group_ldap.php93
1 files changed, 89 insertions, 4 deletions
diff --git a/apps/user_ldap/group_ldap.php b/apps/user_ldap/group_ldap.php
index 76152e1780a..add66d8e870 100644
--- a/apps/user_ldap/group_ldap.php
+++ b/apps/user_ldap/group_ldap.php
@@ -12,6 +12,7 @@
* @author Robin McCorkell <robin@mccorkell.me.uk>
* @author Thomas Müller <thomas.mueller@tmit.eu>
* @author Vincent Petry <pvince81@owncloud.com>
+ * @author Richard Bentley <rbentley@e2advance.com>
*
* @copyright Copyright (c) 2016, ownCloud, Inc.
* @license AGPL-3.0
@@ -148,6 +149,46 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface {
/**
* @param string $dnGroup
+ * @return array
+ *
+ * For a group that has user membership defined by an LDAP search url attribute returns the users
+ * that match the search url otherwise returns an empty array.
+ */
+ public function getDynamicGroupMembers($dnGroup) {
+ $dynamicGroupMemberURL = strtolower($this->access->connection->ldapDynamicGroupMemberURL);
+
+ if (empty($dynamicGroupMemberURL)) {
+ return array();
+ }
+
+ $dynamicMembers = array();
+ $memberURLs = $this->access->readAttribute(
+ $dnGroup,
+ $dynamicGroupMemberURL,
+ $this->access->connection->ldapGroupFilter
+ );
+ if ($memberURLs !== false) {
+ // this group has the 'memberURL' attribute so this is a dynamic group
+ // example 1: ldap:///cn=users,cn=accounts,dc=dcsubbase,dc=dcbase??one?(o=HeadOffice)
+ // example 2: ldap:///cn=users,cn=accounts,dc=dcsubbase,dc=dcbase??one?(&(o=HeadOffice)(uidNumber>=500))
+ $pos = strpos($memberURLs[0], '(');
+ if ($pos !== false) {
+ $memberUrlFilter = substr($memberURLs[0], $pos);
+ $foundMembers = $this->access->searchUsers($memberUrlFilter,'dn');
+ $dynamicMembers = array();
+ foreach($foundMembers as $value) {
+ $dynamicMembers[$value['dn'][0]] = 1;
+ }
+ } else {
+ \OCP\Util::writeLog('user_ldap', 'No search filter found on member url '.
+ 'of group ' . $dnGroup, \OCP\Util::DEBUG);
+ }
+ }
+ return $dynamicMembers;
+ }
+
+ /**
+ * @param string $dnGroup
* @param array|null &$seen
* @return array|mixed|null
*/
@@ -180,6 +221,9 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface {
}
}
}
+
+ $allMembers = array_merge($allMembers, $this->getDynamicGroupMembers($dnGroup));
+
$this->access->connection->writeToCache($cacheKey, $allMembers);
return $allMembers;
}
@@ -387,6 +431,8 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface {
*
* This function fetches all groups a user belongs to. It does not check
* if the user exists at all.
+ *
+ * This function includes groups based on dynamic group membership.
*/
public function getUserGroups($uid) {
if(!$this->enabled) {
@@ -405,6 +451,8 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface {
$groups = [];
$primaryGroup = $this->getUserPrimaryGroup($userDN);
+ $dynamicGroupMemberURL = strtolower($this->access->connection->ldapDynamicGroupMemberURL);
+
// if possible, read out membership via memberOf. It's far faster than
// performing a search, which still is a fallback later.
if(intval($this->access->connection->hasMemberOfFilterSupport) === 1
@@ -422,11 +470,15 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface {
}
}
- if($primaryGroup !== false) {
- $groups[] = $primaryGroup;
+ if (empty($dynamicGroupMemberURL)) {
+ // if dynamic group membership is not enabled then we can return
+ // straight away
+ if($primaryGroup !== false) {
+ $groups[] = $primaryGroup;
+ }
+ $this->access->connection->writeToCache($cacheKey, $groups);
+ return $groups;
}
- $this->access->connection->writeToCache($cacheKey, $groups);
- return $groups;
}
//uniqueMember takes DN, memberuid the uid, so we need to distinguish
@@ -458,6 +510,39 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface {
$groups[] = $primaryGroup;
}
+ if (!empty($dynamicGroupMemberURL)) {
+ // look through dynamic groups to add them to the result array if needed
+ $groupsToMatch = $this->access->fetchListOfGroups(
+ $this->access->connection->ldapGroupFilter,array('dn',$dynamicGroupMemberURL));
+ foreach($groupsToMatch as $value) {
+ if (!array_key_exists($dynamicGroupMemberURL, $value)) {
+ continue;
+ }
+ $pos = strpos($value[$dynamicGroupMemberURL][0], '(');
+ if ($pos !== false) {
+ $memberUrlFilter = substr($value[$dynamicGroupMemberURL][0],$pos);
+ // apply filter via ldap search to see if this user is in this
+ // dynamic group
+ $userMatch = $this->access->readAttribute(
+ $uid,
+ $this->access->connection->ldapUserDisplayName,
+ $memberUrlFilter
+ );
+ if ($userMatch !== false) {
+ // match found so this user is in this group
+ $pos = strpos($value['dn'][0], ',');
+ if ($pos !== false) {
+ $membershipGroup = substr($value['dn'][0],3,$pos-3);
+ $groups[] = $membershipGroup;
+ }
+ }
+ } else {
+ \OCP\Util::writeLog('user_ldap', 'No search filter found on member url '.
+ 'of group ' . $dnGroup, \OCP\Util::DEBUG);
+ }
+ }
+ }
+
$groups = array_unique($groups, SORT_LOCALE_STRING);
$this->access->connection->writeToCache($cacheKey, $groups);