limit server side filtering to known attributes

This commit is contained in:
Roland Gruber 2018-05-30 19:43:44 +02:00
parent 97cb8bcce9
commit dfc3dcb4c6
4 changed files with 78 additions and 38 deletions

View File

@ -74,9 +74,12 @@ class lamList {
/** refresh page switch */
protected $refresh = true;
/** LDAP entries */
/** entries to show */
protected $entries;
/** entries from LDAP */
protected $ldapEntries;
/** sort mapping for entries array(original index => sorted index) */
protected $sortMapping;
@ -95,12 +98,20 @@ class lamList {
/** tabindex for GUI elements */
protected $tabindex = 1;
/** defines if the server side filter changed */
protected $serverSideFilterChanged;
/** ID for list size config option */
const LIST_SIZE_OPTION_NAME = "L_SIZE";
/** prefix for virtual (non-LDAP) attributes */
const VIRTUAL_ATTRIBUTE_PREFIX = 'lam_virtual_';
const SERVER_SIDE_FILTER_ATTRIBUTES = array(
'cn', 'uid', 'memberuid', 'description',
'sn', 'surname', 'gn', 'givenname'
);
/**
* Constructor
*
@ -151,6 +162,8 @@ class lamList {
$this->tabindex = 1;
// do POST actions
$postFragment = $this->listDoPost();
// update filter
$this->listBuildFilter();
// get some parameters
$this->listGetParams();
// print HTML head
@ -159,7 +172,6 @@ class lamList {
$this->listPrintRedirectMessages();
// refresh data if needed
if ($this->refresh) {
$this->listBuildFilter();
$this->listRefreshData();
}
// sort rows by sort column
@ -210,7 +222,8 @@ class lamList {
if (isset($_GET['accountEditBack'])) {
return;
}
$filter = array();
$oldFilter = $this->filters;
$this->serverSideFilterChanged = false;
$this->filters = array();
if (!isset($_POST['clear_filter'])) {
// build filter array
@ -232,6 +245,17 @@ class lamList {
}
}
}
$filterAttrs = array_merge(array_keys($oldFilter), array_keys($this->filters));
$filterAttrs = array_unique($filterAttrs);
foreach ($filterAttrs as $attrName) {
if (!$this->isAttributeFilteredByServer($attrName)) {
continue;
}
if (!isset($oldFilter[$attrName]) || !isset($this->filters[$attrName]) || ($oldFilter[$attrName] != $this->filters[$attrName])) {
$this->serverSideFilterChanged = true;
break;
}
}
}
/**
@ -931,10 +955,17 @@ class lamList {
}
// check if LDAP data should be refreshed
$this->refresh = true;
if (isset($_GET['norefresh'])) $this->refresh = false;
if (isset($_POST['refresh']) || isset($_POST['apply_filter']) || isset($_POST['clear_filter'])) {
if (isset($_GET['norefresh'])) {
$this->refresh = false;
}
if (isset($_POST['refresh'])) {
$this->refresh = true;
}
if (isset($_POST['apply_filter']) || isset($_POST['clear_filter'])) {
if ($this->serverSideFilterChanged) {
$this->refresh = true;
}
}
}
/**
@ -963,7 +994,11 @@ class lamList {
$attrs[] = $additionalAttrs[$i];
}
}
$this->entries = searchLDAP($this->suffix, $filter, $attrs);
$this->ldapEntries = searchLDAP($this->suffix, $filter, $attrs);
$this->entries = array();
foreach ($this->ldapEntries as $index => &$attrs) {
$this->entries[$index] = &$attrs;
}
$lastError = getLastLDAPError();
if ($lastError != null) {
call_user_func_array('StatusMessage', $lastError);
@ -995,7 +1030,7 @@ class lamList {
* @return bool filter server side
*/
protected function isAttributeFilteredByServer($attrName) {
return true;
return in_array(strtolower($attrName), lamList::SERVER_SIDE_FILTER_ATTRIBUTES);
}
/**

View File

@ -1,11 +1,10 @@
<?php
/*
$Id$
This code is part of LDAP Account Manager (http://www.sourceforge.net/projects/lam)
Copyright (C) 2009 - 2012 Pozdnyak Pavel
2010 - 2016 Roland Gruber
2010 - 2018 Roland Gruber
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -167,7 +166,6 @@ class lamAsteriskExtList extends lamList {
* @see lamList::listRefreshData()
*/
protected function listRefreshData() {
parent::listRefreshData();
// configure search filter
$module_filter = get_ldap_filter($this->type->getId()); // basic filter is provided by modules
$filter = "(&" . $module_filter . $this->buildLDAPAttributeFilter() . ")";
@ -179,8 +177,11 @@ class lamAsteriskExtList extends lamList {
call_user_func_array('StatusMessage', $lastError);
}
$entries = $this->normalizeLdapOutput($entries);
$this->entries = $entries;
$this->ldapEntries = $this->normalizeLdapOutput($entries);
$this->entries = array();
foreach ($this->ldapEntries as $index => &$attrs) {
$this->entries[$index] = &$attrs;
}
// generate list of possible suffixes
$this->possibleSuffixes = $this->type->getSuffixList();
}

View File

@ -1,10 +1,9 @@
<?php
use \LAM\TYPES\TypeManager;
/*
$Id$
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
Copyright (C) 2005 - 2017 Roland Gruber
Copyright (C) 2005 - 2018 Roland Gruber
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -399,17 +398,19 @@ class lamGroupList extends lamList {
function groupRefreshPrimary() {
$this->refresh_primary = false;
// return unless some entries
if (sizeof($this->entries) <= 0) return;
if (sizeof($this->ldapEntries) <= 0) {
return;
}
$scope = "user";
// configure search filter
$module_filter = get_ldap_filter($scope); // basic filter is provided by modules
$attrs = array( "uid" );
for ($i = 0; $i < sizeof($this->entries); $i++) {
if (empty($this->entries[$i]['gidnumber'][0])) {
for ($i = 0; $i < sizeof($this->ldapEntries); $i++) {
if (empty($this->ldapEntries[$i]['gidnumber'][0])) {
continue;
}
$gid = $this->entries[$i]['gidnumber'][0];
$gid = $this->ldapEntries[$i]['gidnumber'][0];
$filter = "(&(&" . $module_filter . ")(gidNumber=" . $gid . "))";
$entries = searchLDAPByFilter($filter, $attrs, array($scope));
for ($j = 0; $j < sizeof($entries); $j++) {

View File

@ -930,7 +930,10 @@ class lamUserList extends lamList {
*/
protected function isAttributeFilteredByServer($attrName) {
// do not filter status server side
return $attrName != self::ATTR_ACCOUNT_STATUS;
if ($attrName == self::ATTR_ACCOUNT_STATUS) {
return false;
}
return parent::isAttributeFilteredByServer($attrName);
}
/**
@ -966,20 +969,20 @@ class lamUserList extends lamList {
* Injects values for the virtual account status attribute to make it sortable.
*/
private function injectAccountStatusAttributeAndFilterByStatus() {
$entryCount = sizeof($this->entries);
$entryCount = sizeof($this->ldapEntries);
for ($i = 0; $i < $entryCount; $i++) {
$unixAvailable = self::isUnixAvailable($this->entries[$i]);
$sambaAvailable = self::isSambaAvailable($this->entries[$i]);
$ppolicyAvailable = $this->isPPolicyAvailable($this->entries[$i]);
$windowsAvailable = self::isWindowsAvailable($this->entries[$i]);
$unixLocked = self::isUnixLocked($this->entries[$i]);
$sambaLocked = self::isSambaLocked($this->entries[$i]);
$ppolicyLocked = self::isPPolicyLocked($this->entries[$i]);
$windowsLocked = self::isWindowsLocked($this->entries[$i]);
$windowsPasswordLocked = ($this->getWindowsPasswordLockedTime($this->entries[$i]) != null);
$is389dsLocked = self::is389dsLocked($this->entries[$i]);
$is389dsDeactivated = self::is389dsDeactivated($this->entries[$i]);
$is389dsPwdExpired = self::is389dsPwdExpired($this->entries[$i]);
$unixAvailable = self::isUnixAvailable($this->ldapEntries[$i]);
$sambaAvailable = self::isSambaAvailable($this->ldapEntries[$i]);
$ppolicyAvailable = $this->isPPolicyAvailable($this->ldapEntries[$i]);
$windowsAvailable = self::isWindowsAvailable($this->ldapEntries[$i]);
$unixLocked = self::isUnixLocked($this->ldapEntries[$i]);
$sambaLocked = self::isSambaLocked($this->ldapEntries[$i]);
$ppolicyLocked = self::isPPolicyLocked($this->ldapEntries[$i]);
$windowsLocked = self::isWindowsLocked($this->ldapEntries[$i]);
$windowsPasswordLocked = ($this->getWindowsPasswordLockedTime($this->ldapEntries[$i]) != null);
$is389dsLocked = self::is389dsLocked($this->ldapEntries[$i]);
$is389dsDeactivated = self::is389dsDeactivated($this->ldapEntries[$i]);
$is389dsPwdExpired = self::is389dsPwdExpired($this->ldapEntries[$i]);
$hasLocked = ($unixAvailable && $unixLocked)
|| ($sambaAvailable && $sambaLocked)
|| ($ppolicyAvailable && $ppolicyLocked)
@ -990,9 +993,9 @@ class lamUserList extends lamList {
|| ($sambaAvailable && !$sambaLocked)
|| ($ppolicyAvailable && !$ppolicyLocked)
|| ($windowsAvailable && !$windowsLocked);
$shadowExpired = shadowAccount::isAccountExpired($this->entries[$i]);
$shadowPasswordExpired = shadowAccount::isPasswordExpired($this->entries[$i]);
$windowsExpired = windowsUser::isAccountExpired($this->entries[$i]);
$shadowExpired = shadowAccount::isAccountExpired($this->ldapEntries[$i]);
$shadowPasswordExpired = shadowAccount::isPasswordExpired($this->ldapEntries[$i]);
$windowsExpired = windowsUser::isAccountExpired($this->ldapEntries[$i]);
$expired = $shadowExpired || $shadowPasswordExpired || $windowsExpired;
$status = self::FILTER_UNLOCKED;
if ($expired) {
@ -1007,14 +1010,14 @@ class lamUserList extends lamList {
// filter accounts
if (!empty($this->accountStatusFilter)) {
if ($status != $this->accountStatusFilter) {
unset($this->entries[$i]);
unset($this->ldapEntries[$i]);
continue;
}
}
// add virtual attribute
$this->entries[$i][self::ATTR_ACCOUNT_STATUS][0] = $status;
$this->ldapEntries[$i][self::ATTR_ACCOUNT_STATUS][0] = $status;
}
$this->entries = array_values($this->entries);
$this->ldapEntries = array_values($this->ldapEntries);
}
/**