mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-08 17:14:44 +01:00
* ActiveDirectory: fix account-selection type groupmembers (applies only to non-admins!) and ignore Domain Users group
not setting caseIgnoreMatch for sorting, as its not supported for Windows ActiveDirectory
This commit is contained in:
parent
5afe7ddbca
commit
9f9cce88b2
@ -246,6 +246,7 @@ class Accounts
|
||||
$members = array();
|
||||
foreach((array)$this->memberships($GLOBALS['egw_info']['user']['account_id'],true) as $grp)
|
||||
{
|
||||
if (isset($this->backend->ignore_membership) && in_array($grp, $this->backend->ignore_membership)) continue;
|
||||
$members = array_unique(array_merge($members, (array)$this->members($grp,true,$param['active'])));
|
||||
if ($param['type'] == 'groupmembers+memberships') $members[] = $grp;
|
||||
}
|
||||
@ -313,6 +314,7 @@ class Accounts
|
||||
* @param array $options
|
||||
* $options['filter']['group'] only return members of that group
|
||||
* $options['account_type'] "accounts", "groups", "both" or "groupmembers"
|
||||
* $options['tag_list'] true: return array of values for keys "value", "label" and "icon"
|
||||
* @return array with id - title pairs of the matching entries
|
||||
*/
|
||||
public static function link_query($pattern, array &$options = array())
|
||||
@ -367,8 +369,24 @@ class Accounts
|
||||
'order' => $order,
|
||||
)) as $account)
|
||||
{
|
||||
$accounts[$account['account_id']] = self::format_username($account['account_lid'],
|
||||
$displayName = self::format_username($account['account_lid'],
|
||||
$account['account_firstname'],$account['account_lastname'],$account['account_id']);
|
||||
|
||||
if (!empty($options['tag_list']))
|
||||
{
|
||||
$accounts[] = [
|
||||
'value' => $account['account_id'],
|
||||
'label' => $displayName,
|
||||
'icon' => Framework::link('/api/avatar.php', [
|
||||
'account_id' => $account['account_id'],
|
||||
'modified' => $account['account_modified'],
|
||||
]),
|
||||
];
|
||||
}
|
||||
else
|
||||
{
|
||||
$accounts[$account['account_id']] = $displayName;
|
||||
}
|
||||
}
|
||||
return $accounts;
|
||||
}
|
||||
|
@ -109,7 +109,14 @@ class Ads
|
||||
*/
|
||||
const MIN_ACCOUNT_ID = 1000;
|
||||
|
||||
|
||||
/**
|
||||
* Ignore group-membership of following groups, when compiling group-members
|
||||
*
|
||||
* We ignore "Domain Users" group with RID 513, as it contains all users!
|
||||
*
|
||||
* @var int[]
|
||||
*/
|
||||
public $ignore_membership = [ -513 ];
|
||||
/**
|
||||
* Timestamps ldap => egw used in several places
|
||||
*
|
||||
@ -1081,6 +1088,20 @@ class Ads
|
||||
{
|
||||
$type_filter .= $this->frontend->config['ads_user_filter'];
|
||||
}
|
||||
// for non-admins and account_selection "groupmembers" we have to filter by memberOf attribute
|
||||
if ($GLOBALS['egw_info']['user']['preferences']['common']['account_selection'] === 'groupmembers' &&
|
||||
(!isset($GLOBALS['egw_info']['user']['apps']['admin'])))
|
||||
{
|
||||
$type_filter .= '(|';
|
||||
foreach($GLOBALS['egw']->accounts->memberships($GLOBALS['egw_info']['user']['account_id'],true) as $group_id)
|
||||
{
|
||||
if (!in_array($group_id, $this->ignore_membership) && ($dn = Api\Accounts::id2name($group_id, 'account_dn')))
|
||||
{
|
||||
$type_filter .= '(memberOf='.$dn.')(primaryGroupID='.abs($group_id).')';
|
||||
}
|
||||
}
|
||||
$type_filter .= ')';
|
||||
}
|
||||
$type_filter .= ')';
|
||||
if ($account_type === 'u') break;
|
||||
$user_filter = $type_filter;
|
||||
@ -1103,9 +1124,11 @@ class Ads
|
||||
/**
|
||||
* Get value(s) for LDAP_CONTROL_SORTREQUEST
|
||||
*
|
||||
* Sorting by multiple criteria is supported in LDAP RFC 2891, but - at least with Univention Samba - gives wired results,
|
||||
* Windows AD does NOT support it and gives an error if the oid is specified!
|
||||
*
|
||||
* @param ?string $order_by sql order string eg. "contact_email ASC"
|
||||
* @return array of arrays with values for keys 'attr', 'oid' (caseIgnoreMatch='2.5.13.3') and 'reverse'
|
||||
* @todo sorting by multiple criteria is supported in LDAP RFC 2891, but - at least with Univention - gives wired results
|
||||
*/
|
||||
protected function sort_values($order_by)
|
||||
{
|
||||
@ -1122,14 +1145,17 @@ class Ads
|
||||
}
|
||||
elseif (($attr = array_search('account_'.$matches[2], $this->attributes2egw)))
|
||||
{
|
||||
$values[] = [
|
||||
'attr' => $attr,
|
||||
'oid' => '2.5.13.3', // caseIgnoreMatch
|
||||
$value = [
|
||||
'attr' => $mapping[$matches[2]],
|
||||
'oid' => '2.5.13.3', // caseIgnoreMatch
|
||||
'reverse' => strtoupper($matches[3]) === ' DESC',
|
||||
];
|
||||
// Windows AD does NOT support caseIgnoreMatch sorting, only it's default sorting
|
||||
if ($this->serverinfo->activeDirectory(true)) unset($value['oid']);
|
||||
$values[] = $value;
|
||||
}
|
||||
$order_by = substr($order_by, strlen($matches[0]));
|
||||
if ($values) break; // sorting by multiple criteria gives wired results
|
||||
if ($values) break; // sorting by multiple criteria gives no result for Windows AD and wired result for Samba4
|
||||
}
|
||||
return $values;
|
||||
}
|
||||
|
@ -233,7 +233,7 @@ class Ads extends Ldap
|
||||
$filter = '';
|
||||
if ($gid < 0 && ($dn = $GLOBALS['egw']->accounts->id2name($gid, 'account_dn')))
|
||||
{
|
||||
$filter .= '(memberOf='.$dn.')';
|
||||
$filter .= '(|(memberOf='.$dn.')(primaryGroupID='.abs($gid).'))';
|
||||
}
|
||||
return $filter;
|
||||
}
|
||||
|
@ -1096,9 +1096,11 @@ class Ldap
|
||||
/**
|
||||
* Get value(s) for LDAP_CONTROL_SORTREQUEST
|
||||
*
|
||||
* Sorting by multiple criteria is supported in LDAP RFC 2891, but - at least with Univention Samba - gives wired results,
|
||||
* Windows AD does NOT support it and gives an error if the oid is specified!
|
||||
*
|
||||
* @param ?string $order_by sql order string eg. "contact_email ASC"
|
||||
* @return array of arrays with values for keys 'attr', 'oid' (caseIgnoreMatch='2.5.13.3') and 'reverse'
|
||||
* @todo sorting by multiple criteria is supported in LDAP RFC 2891, but - at least with Univention - gives wired results
|
||||
*/
|
||||
protected function sort_values($order_by)
|
||||
{
|
||||
@ -1119,17 +1121,20 @@ class Ldap
|
||||
{
|
||||
if (isset($mapping[$matches[2]]))
|
||||
{
|
||||
$values[] = [
|
||||
$value = [
|
||||
'attr' => $mapping[$matches[2]],
|
||||
'oid' => '2.5.13.3', // caseIgnoreMatch
|
||||
'reverse' => strtoupper($matches[3]) === ' DESC',
|
||||
];
|
||||
// Windows AD does NOT support caseIgnoreMatch sorting, only it's default sorting
|
||||
if ($this->ldapServerInfo->activeDirectory(true)) unset($value['oid']);
|
||||
$values[] = $value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
$order_by = substr($order_by, strlen($matches[0]));
|
||||
if ($values) break; // sorting by multiple criteria gives wired results
|
||||
if ($values) break; // sorting by multiple criteria gives no result for Windows AD and wired result for Samba4
|
||||
}
|
||||
//error_log(__METHOD__."('$order_by') returning ".json_encode($values));
|
||||
return $values;
|
||||
|
@ -26,9 +26,13 @@ class ServerInfo
|
||||
*/
|
||||
const OPENLDAP = 1;
|
||||
/**
|
||||
* Samba4 LDAP server
|
||||
* Samba4 Active Directory server
|
||||
*/
|
||||
const SAMBA4 = 2;
|
||||
/**
|
||||
* Windows Active Directory server
|
||||
*/
|
||||
const WINDOWS_AD = 4;
|
||||
|
||||
/**
|
||||
* @var array $namingContext holds the supported namingcontexts
|
||||
@ -112,6 +116,16 @@ class ServerInfo
|
||||
$this->serverType = $_serverType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ?bool $windows_ad true: check for windows AD, false: check for Samba4, null: check of any AD
|
||||
* @return bool
|
||||
*/
|
||||
function activeDirectory($windows_ad=null)
|
||||
{
|
||||
return !isset($windows_ad) ? in_array($this->serverType, [self::WINDOWS_AD, self::SAMBA4], true) :
|
||||
$this->serverType === ($windows_ad ? self::WINDOWS_AD : self::SAMBA4);
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the DN for the subschema entry
|
||||
*
|
||||
@ -190,7 +204,7 @@ class ServerInfo
|
||||
public static function get($ds, $host, $version=3)
|
||||
{
|
||||
$filter='(objectclass=*)';
|
||||
$justthese = array('structuralObjectClass','namingContexts','supportedLDAPVersion','subschemaSubentry','vendorname','supportedControl');
|
||||
$justthese = array('structuralObjectClass','namingContexts','supportedLDAPVersion','subschemaSubentry','vendorname','supportedControl','forestFunctionality');
|
||||
if(($sr = @ldap_read($ds, '', $filter, $justthese)))
|
||||
{
|
||||
if(($info = ldap_get_entries($ds, $sr)))
|
||||
@ -222,9 +236,11 @@ class ServerInfo
|
||||
}
|
||||
$ldapServerInfo->setServerType($ldapServerType);
|
||||
}
|
||||
if ($info[0]['vendorname'] && stripos($info[0]['vendorname'][0], 'samba') !== false)
|
||||
// Check for ActiveDirectory by forestFunctionality and set Samba4 if vendorName includes samba
|
||||
if(!empty($info[0]['forestfunctionality'][0]))
|
||||
{
|
||||
$ldapServerInfo->setServerType(self::SAMBA4);
|
||||
$ldapServerInfo->setServerType(!empty($info[0]['vendorname']) && stripos($info[0]['vendorname'][0], 'samba') !== false ?
|
||||
self::SAMBA4 : self::WINDOWS_AD);
|
||||
}
|
||||
|
||||
// check for subschema entry dn
|
||||
|
Loading…
Reference in New Issue
Block a user