* @author Roeland Jago Douma <roeland@famdouma.nl>
* @author Roland Tapken <roland@bitarbeiter.net>
* @author Thomas Müller <thomas.mueller@tmit.eu>
+ * @author Tobias Perschon <tobias@perschon.at>
* @author Victor Dubiniuk <dubiniuk@owncloud.com>
* @author Vincent Petry <pvince81@owncloud.com>
* @author Vinicius Cubas Brand <vinicius@eita.org.br>
/** @var ILogger */
protected $logger;
+ /**
+ * @var string $ldapGroupMemberAssocAttr contains the LDAP setting (in lower case) with the same name
+ */
+ protected $ldapGroupMemberAssocAttr;
+
public function __construct(Access $access, GroupPluginManager $groupPluginManager) {
parent::__construct($access);
$filter = $this->access->connection->ldapGroupFilter;
$this->cachedNestedGroups = new CappedMemoryCache();
$this->groupPluginManager = $groupPluginManager;
$this->logger = OC::$server->getLogger();
+ $this->ldapGroupMemberAssocAttr = strtolower($gAssoc);
}
/**
}
//extra work if we don't get back user DNs
- if (strtolower($this->access->connection->ldapGroupMemberAssocAttr) === 'memberuid') {
- $requestAttributes = $this->access->userManager->getAttributes(true);
- $dns = [];
- $filterParts = [];
- $bytes = 0;
- foreach ($members as $mid) {
- $filter = str_replace('%uid', $mid, $this->access->connection->ldapLoginFilter);
- $filterParts[] = $filter;
- $bytes += strlen($filter);
- if ($bytes >= 9000000) {
- // AD has a default input buffer of 10 MB, we do not want
- // to take even the chance to exceed it
+ switch ($this->ldapGroupMemberAssocAttr) {
+ case 'memberuid':
+ case 'zimbramailforwardingaddress':
+ $requestAttributes = $this->access->userManager->getAttributes(true);
+ $dns = [];
+ $filterParts = [];
+ $bytes = 0;
+ foreach ($members as $mid) {
+ if ($this->ldapGroupMemberAssocAttr === 'zimbramailforwardingaddress') {
+ $parts = explode('@', $mid); //making sure we get only the uid
+ $mid = $parts[0];
+ }
+ $filter = str_replace('%uid', $mid, $this->access->connection->ldapLoginFilter);
+ $filterParts[] = $filter;
+ $bytes += strlen($filter);
+ if ($bytes >= 9000000) {
+ // AD has a default input buffer of 10 MB, we do not want
+ // to take even the chance to exceed it
+ $filter = $this->access->combineFilterWithOr($filterParts);
+ $users = $this->access->fetchListOfUsers($filter, $requestAttributes, count($filterParts));
+ $bytes = 0;
+ $filterParts = [];
+ $dns = array_merge($dns, $users);
+ }
+ }
+ if (count($filterParts) > 0) {
$filter = $this->access->combineFilterWithOr($filterParts);
- $bytes = 0;
- $filterParts = [];
$users = $this->access->fetchListOfUsers($filter, $requestAttributes, count($filterParts));
$dns = array_merge($dns, $users);
}
- }
- if (count($filterParts) > 0) {
- $filter = $this->access->combineFilterWithOr($filterParts);
- $users = $this->access->fetchListOfUsers($filter, $requestAttributes, count($filterParts));
- $dns = array_merge($dns, $users);
- }
- $members = $dns;
+ $members = $dns;
+ break;
}
$isInGroup = in_array($userDN, $members);
// memberof doesn't support memberuid, so skip it here.
if ((int)$this->access->connection->hasMemberOfFilterSupport === 1
&& (int)$this->access->connection->useMemberOfToDetectMembership === 1
- && strtolower($this->access->connection->ldapGroupMemberAssocAttr) !== 'memberuid'
- ) {
+ && $this->ldapGroupMemberAssocAttr !== 'memberuid'
+ && $this->ldapGroupMemberAssocAttr !== 'zimbramailforwardingaddress') {
$groupDNs = $this->_getGroupDNsFromMemberOf($userDN);
if (is_array($groupDNs)) {
foreach ($groupDNs as $dn) {
}
//uniqueMember takes DN, memberuid the uid, so we need to distinguish
- if ((strtolower($this->access->connection->ldapGroupMemberAssocAttr) === 'uniquemember')
- || (strtolower($this->access->connection->ldapGroupMemberAssocAttr) === 'member')
- ) {
- $uid = $userDN;
- } elseif (strtolower($this->access->connection->ldapGroupMemberAssocAttr) === 'memberuid') {
- $result = $this->access->readAttribute($userDN, 'uid');
- if ($result === false) {
- $this->logger->debug('No uid attribute found for DN {dn} on {host}',
- [
- 'app' => 'user_ldap',
- 'dn' => $userDN,
- 'host' => $this->access->connection->ldapHost,
- ]
- );
- $uid = false;
- } else {
- $uid = $result[0];
- }
- } else {
- // just in case
- $uid = $userDN;
+ switch ($this->ldapGroupMemberAssocAttr) {
+ case 'uniquemember':
+ case 'member':
+ $uid = $userDN;
+ break;
+
+ case 'memberuid':
+ case 'zimbramailforwardingaddress':
+ $result = $this->access->readAttribute($userDN, 'uid');
+ if ($result === false) {
+ $this->logger->debug('No uid attribute found for DN {dn} on {host}',
+ [
+ 'app' => 'user_ldap',
+ 'dn' => $userDN,
+ 'host' => $this->access->connection->ldapHost,
+ ]
+ );
+ $uid = false;
+ } else {
+ $uid = $result[0];
+ }
+ break;
+
+ default:
+ // just in case
+ $uid = $userDN;
+ break;
}
if ($uid !== false) {
$allGroups = [];
$seen[$dn] = true;
$filter = $this->access->connection->ldapGroupMemberAssocAttr . '=' . $dn;
+
+ if ($this->ldapGroupMemberAssocAttr === 'zimbramailforwardingaddress') {
+ //in this case the member entries are email addresses
+ $filter .= '@*';
+ }
+
$groups = $this->access->fetchListOfGroups($filter,
[strtolower($this->access->connection->ldapGroupMemberAssocAttr), $this->access->connection->ldapGroupDisplayName, 'dn']);
if (is_array($groups)) {
}
return $this->getGroupsByMember($dn, $seen);
};
+
+ if (empty($dn)) {
+ $dn = "";
+ }
+
$allGroups = $this->walkNestedGroups($dn, $fetcher, $groups);
}
$visibleGroups = $this->filterValidGroups($allGroups);
}
$groupUsers = [];
- $isMemberUid = (strtolower($this->access->connection->ldapGroupMemberAssocAttr) === 'memberuid');
$attrs = $this->access->userManager->getAttributes(true);
foreach ($members as $member) {
- if ($isMemberUid) {
- //we got uids, need to get their DNs to 'translate' them to user names
- $filter = $this->access->combineFilterWithAnd([
- str_replace('%uid', trim($member), $this->access->connection->ldapLoginFilter),
- $this->access->combineFilterWithAnd([
- $this->access->getFilterPartForUserSearch($search),
- $this->access->connection->ldapUserFilter
- ])
- ]);
- $ldap_users = $this->access->fetchListOfUsers($filter, $attrs, 1);
- if (count($ldap_users) < 1) {
- continue;
- }
- $groupUsers[] = $this->access->dn2username($ldap_users[0]['dn'][0]);
- } else {
- //we got DNs, check if we need to filter by search or we can give back all of them
- $uid = $this->access->dn2username($member);
- if (!$uid) {
- continue;
- }
-
- $cacheKey = 'userExistsOnLDAP' . $uid;
- $userExists = $this->access->connection->getFromCache($cacheKey);
- if ($userExists === false) {
- continue;
- }
- if ($userExists === null || $search !== '') {
- if (!$this->access->readAttribute($member,
- $this->access->connection->ldapUserDisplayName,
+ switch ($this->ldapGroupMemberAssocAttr) {
+ case 'zimbramailforwardingaddress':
+ //we get email addresses and need to convert them to uids
+ $parts = explode('@', $member);
+ $member = $parts[0];
+ //no break needed because we just needed to remove the email part and now we have uids
+ case 'memberuid':
+ //we got uids, need to get their DNs to 'translate' them to user names
+ $filter = $this->access->combineFilterWithAnd([
+ str_replace('%uid', trim($member), $this->access->connection->ldapLoginFilter),
$this->access->combineFilterWithAnd([
$this->access->getFilterPartForUserSearch($search),
$this->access->connection->ldapUserFilter
- ]))) {
- if ($search === '') {
- $this->access->connection->writeToCache($cacheKey, false);
- }
+ ])
+ ]);
+ $ldap_users = $this->access->fetchListOfUsers($filter, $attrs, 1);
+ if (count($ldap_users) < 1) {
continue;
}
- $this->access->connection->writeToCache($cacheKey, true);
- }
- $groupUsers[] = $uid;
+ $groupUsers[] = $this->access->dn2username($ldap_users[0]['dn'][0]);
+ break;
+ default:
+ //we got DNs, check if we need to filter by search or we can give back all of them
+ $uid = $this->access->dn2username($member);
+ if (!$uid) {
+ continue;
+ }
+
+ $cacheKey = 'userExistsOnLDAP' . $uid;
+ $userExists = $this->access->connection->getFromCache($cacheKey);
+ if ($userExists === false) {
+ continue;
+ }
+ if ($userExists === null || $search !== '') {
+ if (!$this->access->readAttribute($member,
+ $this->access->connection->ldapUserDisplayName,
+ $this->access->combineFilterWithAnd([
+ $this->access->getFilterPartForUserSearch($search),
+ $this->access->connection->ldapUserFilter
+ ]))) {
+ if ($search === '') {
+ $this->access->connection->writeToCache($cacheKey, false);
+ }
+ continue;
+ }
+ $this->access->connection->writeToCache($cacheKey, true);
+ }
+ $groupUsers[] = $uid;
+ break;
}
}
}
$search = $this->access->escapeFilterPart($search, true);
$isMemberUid =
- (strtolower($this->access->connection->ldapGroupMemberAssocAttr)
- === 'memberuid');
+ ($this->ldapGroupMemberAssocAttr === 'memberuid' ||
+ $this->ldapGroupMemberAssocAttr === 'zimbramailforwardingaddress');
//we need to apply the search filter
//alternatives that need to be checked:
$groupUsers = [];
foreach ($members as $member) {
if ($isMemberUid) {
+ if ($this->ldapGroupMemberAssocAttr === 'zimbramailforwardingaddress') {
+ //we get email addresses and need to convert them to uids
+ $parts = explode('@', $member);
+ $member = $parts[0];
+ }
//we got uids, need to get their DNs to 'translate' them to user names
$filter = $this->access->combineFilterWithAnd([
str_replace('%uid', $member, $this->access->connection->ldapLoginFilter),