* @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
return $isInGroup;
}
+ /**
+ * @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
}
}
}
+
+ $allMembers = array_merge($allMembers, $this->getDynamicGroupMembers($dnGroup));
+
$this->access->connection->writeToCache($cacheKey, $allMembers);
return $allMembers;
}
*
* 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) {
$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
}
}
- 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
$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);
* @author Lukas Reschke <lukas@owncloud.com>
* @author Morris Jobke <hey@morrisjobke.de>
* @author Robin McCorkell <robin@mccorkell.me.uk>
+ * @author Richard Bentley <rbentley@e2advance.com>
*
* @copyright Copyright (c) 2016, ownCloud, Inc.
* @license AGPL-3.0
'lastJpegPhotoLookup' => null,
'ldapNestedGroups' => false,
'ldapPagingSize' => null,
+ 'ldapDynamicGroupMemberURL' => null,
);
/**
'ldap_nested_groups' => 0,
'ldap_paging_size' => 500,
'ldap_experienced_admin' => 0,
+ 'ldap_dynamic_group_member_url' => '',
);
}
'last_jpegPhoto_lookup' => 'lastJpegPhotoLookup',
'ldap_nested_groups' => 'ldapNestedGroups',
'ldap_paging_size' => 'ldapPagingSize',
- 'ldap_experienced_admin' => 'ldapExperiencedAdmin'
+ 'ldap_experienced_admin' => 'ldapExperiencedAdmin',
+ 'ldap_dynamic_group_member_url' => 'ldapDynamicGroupMemberURL',
);
return $array;
}