Merge pull request #4276 from Icinga/fix/handling-of-multi-valued-ldap-attributes-4213

Fix handling of multi valued ldap attributes
This commit is contained in:
Johannes Meyer 2021-02-23 08:35:01 +01:00 committed by GitHub
commit 293021b200
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 39 additions and 2 deletions

View File

@ -654,6 +654,7 @@ class LdapUserGroupBackend extends LdapRepository implements Inspectable, UserGr
return $this->ds return $this->ds
->select() ->select()
->from('*', array($this->userNameAttribute)) ->from('*', array($this->userNameAttribute))
->setUnfoldAttribute($this->userNameAttribute)
->setBase($dn) ->setBase($dn)
->fetchOne(); ->fetchOne();
} }
@ -694,8 +695,8 @@ class LdapUserGroupBackend extends LdapRepository implements Inspectable, UserGr
public function requireQueryColumn($table, $name, RepositoryQuery $query = null) public function requireQueryColumn($table, $name, RepositoryQuery $query = null)
{ {
$column = parent::requireQueryColumn($table, $name, $query); $column = parent::requireQueryColumn($table, $name, $query);
if ($name === 'user_name' && $query !== null) { if (($name === 'user_name' || $name === 'group_name') && $query !== null) {
$query->getQuery()->setUnfoldAttribute('user_name'); $query->getQuery()->setUnfoldAttribute($name);
} }
return $column; return $column;
@ -749,6 +750,7 @@ class LdapUserGroupBackend extends LdapRepository implements Inspectable, UserGr
$groupQuery = $this->ds $groupQuery = $this->ds
->select() ->select()
->from($this->groupClass, array($this->groupNameAttribute)) ->from($this->groupClass, array($this->groupNameAttribute))
->setUnfoldAttribute($this->groupNameAttribute)
->where($groupMemberAttribute, $queryValue) ->where($groupMemberAttribute, $queryValue)
->setBase($this->groupBaseDn); ->setBase($this->groupBaseDn);
if ($this->groupFilter) { if ($this->groupFilter) {

View File

@ -215,6 +215,41 @@ class LdapQuery extends SimpleQuery
} }
} }
public function compare($a, $b, $orderIndex = 0)
{
if (array_key_exists($orderIndex, $this->order)) {
$column = $this->order[$orderIndex][0];
$direction = $this->order[$orderIndex][1];
$flippedColumns = $this->flippedColumns ?: array_flip($this->columns);
if (array_key_exists($column, $flippedColumns) && is_string($flippedColumns[$column])) {
$column = $flippedColumns[$column];
}
if (is_array($a->$column)) {
// rfc2891 states: If a sort key is a multi-valued attribute, and an entry happens to
// have multiple values for that attribute and no other controls are
// present that affect the sorting order, then the server SHOULD use the
// least value (according to the ORDERING rule for that attribute).
$a = clone $a;
$a->$column = array_reduce($a->$column, function ($carry, $item) use ($direction) {
$result = $carry === null ? 0 : strcmp($item, $carry);
return ($direction === self::SORT_ASC ? $result : $result * -1) < 1 ? $item : $carry;
});
}
if (is_array($b->$column)) {
$b = clone $b;
$b->$column = array_reduce($b->$column, function ($carry, $item) use ($direction) {
$result = $carry === null ? 0 : strcmp($item, $carry);
return ($direction === self::SORT_ASC ? $result : $result * -1) < 1 ? $item : $carry;
});
}
}
return parent::compare($a, $b, $orderIndex);
}
/** /**
* Fetch result as tree * Fetch result as tree
* *