diff options
Diffstat (limited to 'apps/user_ldap/group_ldap.php')
-rw-r--r-- | apps/user_ldap/group_ldap.php | 93 |
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); |