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

View File

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

View File

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

View File

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