Fixing #48441 (ldap_search() with sizelimit/timelimit/deref options makes those options persistent)

This commit is contained in:
Patrick Allaert 2009-06-15 15:18:12 +00:00
parent 6afc513391
commit 0d91efd894
4 changed files with 259 additions and 3 deletions

View File

@ -555,13 +555,15 @@ PHP_FUNCTION(ldap_unbind)
/* {{{ php_set_opts
*/
static void php_set_opts(LDAP *ldap, int sizelimit, int timelimit, int deref)
static void php_set_opts(LDAP *ldap, int sizelimit, int timelimit, int deref, int *old_sizelimit, int *old_timelimit, int *old_deref)
{
/* sizelimit */
if (sizelimit > -1) {
#if (LDAP_API_VERSION >= 2004) || HAVE_NSLDAP || HAVE_ORALDAP_10
ldap_get_option(ldap, LDAP_OPT_SIZELIMIT, old_sizelimit);
ldap_set_option(ldap, LDAP_OPT_SIZELIMIT, &sizelimit);
#else
*old_sizelimit = ldap->ld_sizelimit;
ldap->ld_sizelimit = sizelimit;
#endif
}
@ -569,8 +571,10 @@ static void php_set_opts(LDAP *ldap, int sizelimit, int timelimit, int deref)
/* timelimit */
if (timelimit > -1) {
#if (LDAP_API_VERSION >= 2004) || HAVE_NSLDAP || HAVE_ORALDAP_10
ldap_get_option(ldap, LDAP_OPT_SIZELIMIT, old_timelimit);
ldap_set_option(ldap, LDAP_OPT_TIMELIMIT, &timelimit);
#else
*old_timelimit = ldap->ld_timelimit;
ldap->ld_timelimit = timelimit;
#endif
}
@ -578,8 +582,10 @@ static void php_set_opts(LDAP *ldap, int sizelimit, int timelimit, int deref)
/* deref */
if (deref > -1) {
#if (LDAP_API_VERSION >= 2004) || HAVE_NSLDAP || HAVE_ORALDAP_10
ldap_get_option(ldap, LDAP_OPT_SIZELIMIT, old_deref);
ldap_set_option(ldap, LDAP_OPT_DEREF, &deref);
#else
*old_deref = ldap->ld_deref;
ldap->ld_deref = deref;
#endif
}
@ -600,6 +606,9 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope)
int ldap_sizelimit = -1;
int ldap_timelimit = -1;
int ldap_deref = -1;
int old_ldap_sizelimit = -1;
int old_ldap_timelimit = -1;
int old_ldap_deref = -1;
int num_attribs = 0;
int i, errno;
int myargcount = ZEND_NUM_ARGS();
@ -735,7 +744,7 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope)
ldap_filter = Z_STRVAL_PP(entry);
}
php_set_opts(ld->link, ldap_sizelimit, ldap_timelimit, ldap_deref);
php_set_opts(ld->link, ldap_sizelimit, ldap_timelimit, ldap_deref, &old_ldap_sizelimit, &old_ldap_timelimit, &old_ldap_deref);
/* Run the actual search */
rcs[i] = ldap_search(ld->link, ldap_base_dn, scope, ldap_filter, ldap_attrs, ldap_attrsonly);
@ -777,7 +786,7 @@ cleanup_parallel:
goto cleanup;
}
php_set_opts(ld->link, ldap_sizelimit, ldap_timelimit, ldap_deref);
php_set_opts(ld->link, ldap_sizelimit, ldap_timelimit, ldap_deref, &old_ldap_sizelimit, &old_ldap_timelimit, &old_ldap_deref);
/* Run the actual search */
errno = ldap_search_s(ld->link, ldap_base_dn, scope, ldap_filter, ldap_attrs, ldap_attrsonly, &ldap_res);
@ -808,6 +817,8 @@ cleanup_parallel:
}
cleanup:
// Restoring previous options
php_set_opts(ld->link, old_ldap_sizelimit, old_ldap_timelimit, old_ldap_deref, &ldap_sizelimit, &ldap_timelimit, &ldap_deref);
if (ldap_attrs != NULL) {
efree(ldap_attrs);
}

View File

@ -0,0 +1,171 @@
--TEST--
ldap_search() bug 48441 - options persists after specifying them in ldap_search
--CREDITS--
Patrick Allaert <patrickallaert@php.net>
--SKIPIF--
<?php
require_once('skipif.inc');
require_once('skipifbindfailure.inc');
?>
--FILE--
<?php
include "connect.inc";
$link = ldap_connect_and_bind($host, $port, $user, $passwd, $protocol_version);
insert_dummy_data($link);
$dn = "dc=my-domain,dc=com";
$filter = "(objectclass=person)";
var_dump(
$result = ldap_search($link, $dn, $filter, array('sn')),
ldap_get_entries($link, $result)
);
var_dump(
$result = ldap_search($link, $dn, $filter, array('sn'), 1, 1, 1, LDAP_DEREF_ALWAYS),
ldap_get_entries($link, $result)
);
var_dump(
$result = ldap_search($link, $dn, $filter, array('sn')),
ldap_get_entries($link, $result)
);
?>
===DONE===
--CLEAN--
<?php
include "connect.inc";
$link = ldap_connect_and_bind($host, $port, $user, $passwd, $protocol_version);
remove_dummy_data($link);
?>
--XFAIL--
This test may still fail in PHP 6 as ext/ldap is still not ready
--EXPECTF--
resource(%d) of type (ldap result)
array(4) {
["count"]=>
int(3)
[0]=>
array(4) {
["sn"]=>
array(2) {
["count"]=>
int(1)
[0]=>
string(7) "testSN1"
}
[0]=>
string(2) "sn"
["count"]=>
int(1)
["dn"]=>
string(28) "cn=userA,dc=my-domain,dc=com"
}
[1]=>
array(4) {
["sn"]=>
array(2) {
["count"]=>
int(1)
[0]=>
string(7) "testSN2"
}
[0]=>
string(2) "sn"
["count"]=>
int(1)
["dn"]=>
string(28) "cn=userB,dc=my-domain,dc=com"
}
[2]=>
array(4) {
["sn"]=>
array(2) {
["count"]=>
int(1)
[0]=>
string(7) "testSN3"
}
[0]=>
string(2) "sn"
["count"]=>
int(1)
["dn"]=>
string(37) "cn=userC,cn=userB,dc=my-domain,dc=com"
}
}
Warning: ldap_search(): Partial search results returned: Sizelimit exceeded in %s on line %d
resource(%d) of type (ldap result)
array(2) {
["count"]=>
int(1)
[0]=>
array(4) {
["sn"]=>
array(1) {
["count"]=>
int(0)
}
[0]=>
string(2) "sn"
["count"]=>
int(1)
["dn"]=>
string(28) "cn=userA,dc=my-domain,dc=com"
}
}
resource(%d) of type (ldap result)
array(4) {
["count"]=>
int(3)
[0]=>
array(4) {
["sn"]=>
array(2) {
["count"]=>
int(1)
[0]=>
string(7) "testSN1"
}
[0]=>
string(2) "sn"
["count"]=>
int(1)
["dn"]=>
string(28) "cn=userA,dc=my-domain,dc=com"
}
[1]=>
array(4) {
["sn"]=>
array(2) {
["count"]=>
int(1)
[0]=>
string(7) "testSN2"
}
[0]=>
string(2) "sn"
["count"]=>
int(1)
["dn"]=>
string(28) "cn=userB,dc=my-domain,dc=com"
}
[2]=>
array(4) {
["sn"]=>
array(2) {
["count"]=>
int(1)
[0]=>
string(7) "testSN3"
}
[0]=>
string(2) "sn"
["count"]=>
int(1)
["dn"]=>
string(37) "cn=userC,cn=userB,dc=my-domain,dc=com"
}
}
===DONE===

View File

@ -0,0 +1,61 @@
<?php
/*
Default values are "localhost", "root", database "test" and empty password.
Change the LDAP_TEST_* environment values if you want to use another configuration.
*/
$host = getenv("LDAP_TEST_HOST") ? getenv("LDAP_TEST_HOST") : "localhost";
$port = getenv("LDAP_TEST_PORT") ? getenv("LDAP_TEST_PORT") : 389;
$user = getenv("LDAP_TEST_USER") ? getenv("LDAP_TEST_USER") : "cn=Manager,dc=my-domain,dc=com";
$sasl_user = getenv("LDAP_TEST_SASL_USER") ? getenv("LDAP_TEST_SASL_USER") : "Manager";
$passwd = getenv("LDAP_TEST_PASSWD") ? getenv("LDAP_TEST_PASSWD") : "secret";
$protocol_version = getenv("LDAP_TEST_OPT_PROTOCOL_VERSION") ? getenv("LDAP_TEST_OPT_PROTOCOL_VERSION") : 3;
$skip_on_bind_failure = getenv("LDAP_TEST_SKIP_BIND_FAILURE") ? getenv("LDAP_TEST_SKIP_BIND_FAILURE") : true;
function ldap_connect_and_bind($host, $port, $user, $passwd, $protocol_version) {
$link = ldap_connect($host, $port);
ldap_set_option($link, LDAP_OPT_PROTOCOL_VERSION, $protocol_version);
ldap_bind($link, $user, $passwd);
return $link;
}
function insert_dummy_data($link) {
ldap_add($link, "dc=my-domain,dc=com", array(
"objectClass" => array(
"top",
"dcObject",
"organization"),
"dc" => "my-domain",
"o" => "my-domain",
));
ldap_add($link, "cn=userA,dc=my-domain,dc=com", array(
"objectclass" => "person",
"cn" => "userA",
"sn" => "testSN1",
"userPassword" => "oops",
"telephoneNumber" => "xx-xx-xx-xx-xx",
"description" => "user A",
));
ldap_add($link, "cn=userB,dc=my-domain,dc=com", array(
"objectclass" => "person",
"cn" => "userB",
"sn" => "testSN2",
"userPassword" => "oopsIDitItAgain",
"description" => "user B",
));
ldap_add($link, "cn=userC,cn=userB,dc=my-domain,dc=com", array(
"objectclass" => "person",
"cn" => "userC",
"sn" => "testSN3",
"userPassword" => "0r1g1na1 passw0rd",
));
}
function remove_dummy_data($link) {
ldap_delete($link, "cn=userC,cn=userB,dc=my-domain,dc=com");
ldap_delete($link, "cn=userA,dc=my-domain,dc=com");
ldap_delete($link, "cn=userB,dc=my-domain,dc=com");
ldap_delete($link, "dc=my-domain,dc=com");
}
?>

View File

@ -0,0 +1,13 @@
<?php
require_once 'connect.inc';
if ($skip_on_bind_failure) {
$link = ldap_connect($host, $port);
ldap_set_option($link, LDAP_OPT_PROTOCOL_VERSION, $protocol_version);
if (!@ldap_bind($link, $user, $passwd))
die(sprintf("skip Can't bind to LDAP Server - [%d] %s", ldap_errno($link), ldap_error($link)));
ldap_unbind($link);
}
?>