support paged results

This commit is contained in:
Roland Gruber 2014-11-29 17:40:39 +00:00
parent 700182bed4
commit ecb08a6141
9 changed files with 94 additions and 29 deletions

View File

@ -1,4 +1,5 @@
December 2014 4.8 December 2014 4.8
- Active Directory: support paged result as workaround for size limit exceeded
- FreeRadius: support dialupAccess and radiusProfileDn - FreeRadius: support dialupAccess and radiusProfileDn
- Usability improvements - Usability improvements
- LAM Pro: - LAM Pro:

View File

@ -1291,10 +1291,16 @@ Have fun!
linkend="a_accessLevelPasswordReset">this page</link> for details on linkend="a_accessLevelPasswordReset">this page</link> for details on
the different access levels.</para> the different access levels.</para>
<para><emphasis role="bold">Advanced options</emphasis></para>
<para>By default LAM will not follow LDAP referrals. This is ok for <para>By default LAM will not follow LDAP referrals. This is ok for
most installations. If you use LDAP referrals please activate the most installations. If you use LDAP referrals please activate the
referral option in advanced settings.</para> referral option in advanced settings.</para>
<para>Paged results should be activated only if you encounter any
problems regarding size limits on Active Directory. LAM will then
query LDAP to return results in chunks of 999 entries.</para>
<screenshot> <screenshot>
<mediaobject> <mediaobject>
<imageobject> <imageobject>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

View File

@ -181,6 +181,8 @@ $helpArray = array (
"Text" => _('Here you can overwrite the display name for this account type.')), "Text" => _('Here you can overwrite the display name for this account type.')),
"265" => array ("Headline" => _('Read-only'), "265" => array ("Headline" => _('Read-only'),
"Text" => _('Sets this account type to read-only.')), "Text" => _('Sets this account type to read-only.')),
"266" => array ("Headline" => _("Paged results"),
"Text" => _("This is a workaround for Active Directory. Enable it if you get messages about size limit exceeded.")),
// 300 - 399 // 300 - 399
// profile editor, file upload // profile editor, file upload
"301" => array ("Headline" => _("RDN identifier"), "301" => array ("Headline" => _("RDN identifier"),

View File

@ -668,20 +668,13 @@ function searchLDAPByAttribute($name, $value, $objectClass, $attributes, $scopes
continue; // skip non-active account types continue; // skip non-active account types
} }
// search LDAP // search LDAP
$sr = @ldap_search($_SESSION['ldap']->server(), escapeDN($_SESSION['config']->get_Suffix($scopes[$s])), $entries = searchLDAPPaged($_SESSION['ldap']->server(), escapeDN($_SESSION['config']->get_Suffix($scopes[$s])),
$filter, $attributes, 0, $_SESSION['config']->get_searchLimit(), 0, LDAP_DEREF_NEVER); $filter, $attributes, 0, $_SESSION['config']->get_searchLimit());
if (ldap_errno($_SESSION['ldap']->server()) == 4) { if (ldap_errno($_SESSION['ldap']->server()) == 4) {
logNewMessage(LOG_WARNING, 'LDAP size limit exeeded. Please increase the limit on your server.'); logNewMessage(LOG_WARNING, 'LDAP size limit exeeded. Please increase the limit on your server.');
} }
if ($sr) {
$entries = ldap_get_entries($_SESSION['ldap']->server(), $sr);
if ($entries) {
cleanLDAPResult($entries);
$return = array_merge($return, $entries); $return = array_merge($return, $entries);
} }
@ldap_free_result($sr);
}
}
return $return; return $return;
} }
@ -702,20 +695,13 @@ function searchLDAPByFilter($filter, $attributes, $scopes, $attrsOnly = false) {
} }
for ($s = 0; $s < sizeof($scopes); $s++) { for ($s = 0; $s < sizeof($scopes); $s++) {
// search LDAP // search LDAP
$sr = @ldap_search($_SESSION['ldap']->server(), escapeDN($_SESSION['config']->get_Suffix($scopes[$s])), $entries = searchLDAPPaged($_SESSION['ldap']->server(), escapeDN($_SESSION['config']->get_Suffix($scopes[$s])),
$filter, $attributes, $readAttributesOnly, $_SESSION['config']->get_searchLimit(), 0, LDAP_DEREF_NEVER); $filter, $attributes, $readAttributesOnly, $_SESSION['config']->get_searchLimit());
if (ldap_errno($_SESSION['ldap']->server()) == 4) { if (ldap_errno($_SESSION['ldap']->server()) == 4) {
logNewMessage(LOG_WARNING, 'LDAP size limit exeeded. Please increase the limit on your server.'); logNewMessage(LOG_WARNING, 'LDAP size limit exeeded. Please increase the limit on your server.');
} }
if ($sr) {
$entries = ldap_get_entries($_SESSION['ldap']->server(), $sr);
if ($entries) {
cleanLDAPResult($entries);
$return = array_merge($return, $entries); $return = array_merge($return, $entries);
} }
@ldap_free_result($sr);
}
}
return $return; return $return;
} }
@ -728,20 +714,56 @@ function searchLDAPByFilter($filter, $attributes, $scopes, $attrsOnly = false) {
* @return array list of found entries * @return array list of found entries
*/ */
function searchLDAP($suffix, $filter, $attributes) { function searchLDAP($suffix, $filter, $attributes) {
$return = array(); $return = searchLDAPPaged($_SESSION['ldap']->server(), escapeDN($suffix), $filter, $attributes,
$sr = @ldap_search($_SESSION['ldap']->server(), escapeDN($suffix), $filter, $attributes, 0, $_SESSION['config']->get_searchLimit());
0, $_SESSION['config']->get_searchLimit(), 0, LDAP_DEREF_NEVER);
if (ldap_errno($_SESSION['ldap']->server()) == 4) { if (ldap_errno($_SESSION['ldap']->server()) == 4) {
logNewMessage(LOG_WARNING, 'LDAP size limit exeeded. Please increase the limit on your server.'); logNewMessage(LOG_WARNING, 'LDAP size limit exeeded. Please increase the limit on your server.');
} }
return $return;
}
/**
* Runs an LDAP search and uses paging if configured.
*
* @param handle $server LDAP connection handle
* @param String $dn DN
* @param String $filter filter
* @param array $attributes attribute list
* @param boolean $attrsOnly return only attribute names
* @param int $limit size limit
*/
function searchLDAPPaged($server, $dn, $filter, $attributes, $attrsOnly, $limit) {
if (empty($_SESSION['config']) || ($_SESSION['config']->getPagedResults() !== 'true')) {
$sr = @ldap_search($server, $dn, $filter, $attributes, $attrsOnly, $limit, 0, LDAP_DEREF_NEVER);
if ($sr) { if ($sr) {
$entries = ldap_get_entries($_SESSION['ldap']->server(), $sr); $entries = ldap_get_entries($server, $sr);
if ($entries) { if (!$entries) {
return array();
}
cleanLDAPResult($entries); cleanLDAPResult($entries);
@ldap_free_result($sr);
return $entries; return $entries;
} }
else {
return array();
} }
}
$pageSize = 999;
$cookie = '';
$return = array();
do {
@ldap_control_paged_result($server, $pageSize, true, $cookie);
$sr = @ldap_search($server, $dn, $filter, $attributes, $attrsOnly, $limit, 0, LDAP_DEREF_NEVER);
if (!$sr) {
break;
}
$entries = ldap_get_entries($server, $sr);
if (!$entries) {
break;
}
$return = array_merge($return, $entries);
@ldap_control_paged_result_response($server, $sr, $cookie);
} while($cookie !== null && $cookie != '');
cleanLDAPResult($return);
return $return; return $return;
} }

View File

@ -362,6 +362,9 @@ class LAMConfig {
/** automatically follow referrals */ /** automatically follow referrals */
private $followReferrals = 'false'; private $followReferrals = 'false';
/** use paged results */
private $pagedResults = 'false';
/** Array of string: users with admin rights */ /** Array of string: users with admin rights */
private $Admins; private $Admins;
@ -456,7 +459,7 @@ class LAMConfig {
private $lamProMailText = ''; private $lamProMailText = '';
/** List of all settings in config file */ /** List of all settings in config file */
private $settings = array("ServerURL", "useTLS", "followReferrals", "Passwd", "Admins", "treesuffix", private $settings = array("ServerURL", "useTLS", "followReferrals", 'pagedResults', "Passwd", "Admins", "treesuffix",
"defaultLanguage", "scriptPath", "scriptServer", "scriptRights", "cachetimeout", "defaultLanguage", "scriptPath", "scriptServer", "scriptRights", "cachetimeout",
"modules", "activeTypes", "types", "tools", "accessLevel", 'loginMethod', 'loginSearchSuffix', "modules", "activeTypes", "types", "tools", "accessLevel", 'loginMethod', 'loginSearchSuffix',
'loginSearchFilter', 'searchLimit', 'lamProMailFrom', 'lamProMailReplyTo', 'lamProMailSubject', 'loginSearchFilter', 'searchLimit', 'lamProMailFrom', 'lamProMailReplyTo', 'lamProMailSubject',
@ -625,6 +628,7 @@ class LAMConfig {
if (!in_array("ServerURL", $saved)) array_push($file_array, "\n\n# server address (e.g. ldap://localhost:389 or ldaps://localhost:636)\n" . "serverURL: " . $this->ServerURL . "\n"); if (!in_array("ServerURL", $saved)) array_push($file_array, "\n\n# server address (e.g. ldap://localhost:389 or ldaps://localhost:636)\n" . "serverURL: " . $this->ServerURL . "\n");
if (!in_array("useTLS", $saved)) array_push($file_array, "\n\n# enable TLS encryption\n" . "useTLS: " . $this->useTLS . "\n"); if (!in_array("useTLS", $saved)) array_push($file_array, "\n\n# enable TLS encryption\n" . "useTLS: " . $this->useTLS . "\n");
if (!in_array("followReferrals", $saved)) array_push($file_array, "\n\n# follow referrals\n" . "followReferrals: " . $this->followReferrals . "\n"); if (!in_array("followReferrals", $saved)) array_push($file_array, "\n\n# follow referrals\n" . "followReferrals: " . $this->followReferrals . "\n");
if (!in_array("pagedResults", $saved)) array_push($file_array, "\n\n# paged results\n" . "pagedResults: " . $this->pagedResults . "\n");
if (!in_array("Passwd", $saved)) array_push($file_array, "\n\n# password to change these preferences via webfrontend\n" . "passwd: " . $this->Passwd . "\n"); if (!in_array("Passwd", $saved)) array_push($file_array, "\n\n# password to change these preferences via webfrontend\n" . "passwd: " . $this->Passwd . "\n");
if (!in_array("Admins", $saved)) array_push($file_array, "\n\n# list of users who are allowed to use LDAP Account Manager\n" . if (!in_array("Admins", $saved)) array_push($file_array, "\n\n# list of users who are allowed to use LDAP Account Manager\n" .
"# names have to be seperated by semicolons\n" . "# names have to be seperated by semicolons\n" .
@ -777,6 +781,24 @@ class LAMConfig {
$this->followReferrals = $followReferrals; $this->followReferrals = $followReferrals;
} }
/**
* Returns if paged results should be used.
*
* @return String true or false
*/
public function getPagedResults() {
return $this->pagedResults;
}
/**
* Sets if paged results should be used.
*
* @param String $pagedResults true or false
*/
public function setPagedResults($pagedResults) {
$this->pagedResults = $pagedResults;
}
/** /**
* Returns an array of string with all admin names * Returns an array of string with all admin names
* *

View File

@ -405,6 +405,9 @@ class lamGroupList extends lamList {
$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->entries); $i++) {
if (empty($this->entries[$i]['gidnumber'][0])) {
continue;
}
$gid = $this->entries[$i]['gidnumber'][0]; $gid = $this->entries[$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));

View File

@ -271,6 +271,9 @@ $advancedOptionsContent = new htmlTable();
// referrals // referrals
$followReferrals = ($conf->getFollowReferrals() === 'true'); $followReferrals = ($conf->getFollowReferrals() === 'true');
$advancedOptionsContent->addElement(new htmlTableExtendedInputCheckbox('followReferrals', $followReferrals , _('Follow referrals'), '205'), true); $advancedOptionsContent->addElement(new htmlTableExtendedInputCheckbox('followReferrals', $followReferrals , _('Follow referrals'), '205'), true);
// paged results
$pagedResults = ($conf->getPagedResults() === 'true');
$advancedOptionsContent->addElement(new htmlTableExtendedInputCheckbox('pagedResults', $pagedResults , _('Paged results'), '266'), true);
// build advanced options box // build advanced options box
$advancedOptions = new htmlAccordion('advancedOptions_server', array(_('Advanced options') => $advancedOptionsContent), false); $advancedOptions = new htmlAccordion('advancedOptions_server', array(_('Advanced options') => $advancedOptionsContent), false);
@ -509,6 +512,12 @@ function checkInput() {
else { else {
$conf->setFollowReferrals('false'); $conf->setFollowReferrals('false');
} }
if (isset($_POST['pagedResults']) && ($_POST['pagedResults'] == 'on')) {
$conf->setPagedResults('true');
}
else {
$conf->setPagedResults('false');
}
/* if (!$conf->set_cacheTimeout($_POST['cachetimeout'])) { /* if (!$conf->set_cacheTimeout($_POST['cachetimeout'])) {
$errors[] = array("ERROR", _("Cache timeout is invalid!")); $errors[] = array("ERROR", _("Cache timeout is invalid!"));
}*/ }*/