Patch php-5.2_ldap-pagination.patch for LDAP related Bug #51869
Patch version 2010-05-20 09:38 UTC
Return to Bug #51869 |
Download this patch
Patch Revisions:
Developer: jeanseb@au-fil-du.net
Index: ext/ldap/ldap.c
===================================================================
--- ext/ldap/ldap.c (révision 39622)
+++ ext/ldap/ldap.c (révision 39985)
@@ -19,6 +19,8 @@
| Jani Taskinen <sniper@iki.fi> |
| Stig Venaas <venaas@uninett.no> |
| Doug Goldstein <cardoe@cardoe.com> |
+ | Pierangelo Masarati <ando@OpenLDAP.org> |
+ | Iñaki Arenaza <iarenuno@eteo.mondragon.edu> |
| PHP 4.0 updates: Zeev Suraski <zeev@zend.com> |
+----------------------------------------------------------------------+
*/
@@ -83,6 +85,13 @@
static PHP_GINIT_FUNCTION(ldap);
static
+ ZEND_BEGIN_ARG_INFO(arg3to4of4_force_ref, 0)
+ ZEND_ARG_PASS_INFO(0)
+ ZEND_ARG_PASS_INFO(0)
+ ZEND_ARG_PASS_INFO(1)
+ ZEND_ARG_PASS_INFO(1)
+ ZEND_END_ARG_INFO();
+static
ZEND_BEGIN_ARG_INFO(arg3to6of6_force_ref, 0)
ZEND_ARG_PASS_INFO(0)
ZEND_ARG_PASS_INFO(0)
@@ -166,6 +175,10 @@
PHP_FE(ldap_8859_to_t61, NULL)
#endif
+#ifdef LDAP_CONTROL_PAGEDRESULTS
+ PHP_FE(ldap_ctrl_paged_results, fourth_arg_force_ref)
+ PHP_FE(ldap_ctrl_paged_results_resp, arg3to4of4_force_ref)
+#endif
{NULL, NULL, NULL}
};
/* }}} */
@@ -2289,6 +2302,193 @@
/* }}} */
#endif
+#ifdef LDAP_CONTROL_PAGEDRESULTS
+/* {{{ proto bool ldap_ctrl_paged_results(resource link, int pagesize [, bool iscritical [, string cookie]])
+ Inject paged results control*/
+PHP_FUNCTION(ldap_ctrl_paged_results)
+{
+ zval **link, **pagesize, **iscritical, **cookie;
+ int lpagesize = 0;
+ struct berval lcookie = { 0, NULL };
+ ldap_linkdata *ld;
+ LDAP *ldap;
+ BerElement *ber = NULL;
+ LDAPControl ctrl, *ctrlsp[2];
+ int rc, myargcount = ZEND_NUM_ARGS();
+
+ if (myargcount < 2 || myargcount > 4 || zend_get_parameters_ex(myargcount, &link, &pagesize, &iscritical, &cookie) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+
+ if (Z_TYPE_PP(link) == IS_NULL) {
+ ldap = NULL;
+ } else {
+ ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, link, -1, "ldap link", le_link);
+ ldap = ld->link;
+ }
+
+ ber = ber_alloc_t(LBER_USE_DER);
+ if (ber == NULL) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to alloc BER encoding resources for paged results control");
+ RETURN_FALSE;
+ }
+
+ ctrl.ldctl_iscritical = 0;
+
+ switch (myargcount) {
+ case 4:
+ convert_to_string_ex(cookie);
+ lcookie.bv_val = Z_STRVAL_PP(cookie);
+ lcookie.bv_len = Z_STRLEN_PP(cookie);
+ /* fallthru */
+ case 3:
+ convert_to_boolean_ex(iscritical);
+ ctrl.ldctl_iscritical = Z_BVAL_PP(iscritical);
+ /* fallthru */
+ }
+ convert_to_long_ex(pagesize);
+ lpagesize = Z_LVAL_PP(pagesize);
+
+ if (ber_printf(ber, "{iO}", lpagesize, &lcookie) == LBER_ERROR) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to BER printf paged results control");
+ RETVAL_BOOL(0);
+ goto lcpr_error_out;
+ }
+ rc = ber_flatten2(ber, &ctrl.ldctl_value, 0);
+ if (rc == LBER_ERROR) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to BER encode paged results control");
+ RETVAL_BOOL(0);
+ goto lcpr_error_out;
+ }
+
+ ctrl.ldctl_oid = LDAP_CONTROL_PAGEDRESULTS;
+
+ if (ldap) {
+ /* directly set the option */
+ ctrlsp[0] = &ctrl;
+ ctrlsp[1] = NULL;
+
+ rc = ldap_set_option(ldap, LDAP_OPT_SERVER_CONTROLS, ctrlsp);
+ if (rc != LDAP_SUCCESS) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to set paged results control: %s (%d)", ldap_err2string(rc), rc);
+ RETVAL_BOOL(0);
+ goto lcpr_error_out;
+ }
+ RETVAL_BOOL(1);
+ } else {
+ /* return a PHP control object */
+ array_init(return_value);
+
+ add_assoc_string(return_value, "oid", ctrl.ldctl_oid, 1);
+ if ( ctrl.ldctl_value.bv_len ) {
+ add_assoc_stringl(return_value, "value", ctrl.ldctl_value.bv_val, ctrl.ldctl_value.bv_len, 1);
+ }
+ if (ctrl.ldctl_iscritical) {
+ add_assoc_bool(return_value, "iscritical", ctrl.ldctl_iscritical);
+ }
+ }
+
+lcpr_error_out:
+ if (ber != NULL) {
+ ber_free(ber, 1);
+ }
+ return;
+}
+/* }}} */
+
+/* {{{ proto bool ldap_ctrl_paged_results_resp(resource link, resource result [, string cookie [, int estimated]])
+ Extract paged results control response */
+PHP_FUNCTION(ldap_ctrl_paged_results_resp)
+{
+ zval **link, **result, **cookie, **estimated;
+ struct berval lcookie;
+ int lestimated;
+ ldap_linkdata *ld;
+ LDAPMessage *ldap_result;
+ LDAPControl **lserverctrls, *lctrl;
+ BerElement *ber;
+ ber_tag_t tag;
+ int rc, lerrcode, myargcount = ZEND_NUM_ARGS();
+
+ if (myargcount < 3 || myargcount > 4 || zend_get_parameters_ex(myargcount, &link, &result, &cookie, &estimated) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+
+ ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, link, -1, "ldap link", le_link);
+ ZEND_FETCH_RESOURCE(ldap_result, LDAPMessage *, result, -1, "ldap result", le_result);
+
+ rc = ldap_parse_result(ld->link,
+ ldap_result,
+ &lerrcode,
+ NULL, /* matcheddn */
+ NULL, /* errmsg */
+ NULL, /* referrals */
+ &lserverctrls,
+ 0);
+
+ if (rc != LDAP_SUCCESS) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to parse result: %s (%d)", ldap_err2string(rc), rc);
+ RETURN_FALSE;
+ }
+
+ if (lerrcode != LDAP_SUCCESS) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Result is: %s (%d)", ldap_err2string(lerrcode), lerrcode);
+ RETURN_FALSE;
+ }
+
+ if (lserverctrls == NULL) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "No server controls in result");
+ RETURN_FALSE;
+ }
+
+ lctrl = ldap_find_control(LDAP_CONTROL_PAGEDRESULTS, lserverctrls);
+ if (lctrl == NULL) {
+ ldap_controls_free(lserverctrls);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "No paged results control response in result");
+ RETURN_FALSE;
+ }
+
+ ber = ber_init(&lctrl->ldctl_value);
+ if (ber == NULL) {
+ ldap_controls_free(lserverctrls);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to alloc BER decoding resources for paged results control response");
+ RETURN_FALSE;
+ }
+
+ tag = ber_scanf(ber, "{io}", &lestimated, &lcookie );
+ (void)ber_free(ber, 1);
+
+ if (tag == LBER_ERROR) {
+ ldap_controls_free(lserverctrls);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to decode paged results control response");
+ RETURN_FALSE;
+ }
+
+ if (lestimated < 0) {
+ ldap_controls_free(lserverctrls);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid paged results control response value");
+ RETURN_FALSE;
+ }
+
+ ldap_controls_free(lserverctrls);
+
+ if (myargcount == 4) {
+ zval_dtor(*estimated);
+ ZVAL_LONG(*estimated, lestimated);
+ }
+
+ zval_dtor(*cookie);
+ if (lcookie.bv_len == 0) {
+ ZVAL_EMPTY_STRING(*cookie);
+ } else {
+ ZVAL_STRINGL(*cookie, lcookie.bv_val, lcookie.bv_len, 1);
+ }
+ ldap_memfree(lcookie.bv_val);
+
+ RETURN_TRUE;
+}
+/* }}} */
+#endif
/*
* Local variables:
* tab-width: 4
Index: ext/ldap/tests/ldap_ctrl_paged_results_variation1.phpt
===================================================================
--- ext/ldap/tests/ldap_ctrl_paged_results_variation1.phpt (révision 0)
+++ ext/ldap/tests/ldap_ctrl_paged_results_variation1.phpt (révision 39985)
@@ -0,0 +1,56 @@
+--TEST--
+ldap_ldap_ctrl_paged_results() test (fetching the first page)
+--CREDITS--
+Jean-Sebastien Hedde <jeanseb@au-fil-du.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 = "(cn=*)";
+var_dump(
+ ldap_ctrl_paged_results($link, 1),
+ $result = ldap_search($link, $dn, $filter, array('cn')),
+ 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);
+?>
+--EXPECTF--
+bool(true)
+resource(6) of type (ldap result)
+array(2) {
+ ["count"]=>
+ int(1)
+ [0]=>
+ array(4) {
+ ["cn"]=>
+ array(2) {
+ ["count"]=>
+ int(1)
+ [0]=>
+ string(5) "userA"
+ }
+ [0]=>
+ string(2) "cn"
+ ["count"]=>
+ int(1)
+ ["dn"]=>
+ string(28) "cn=userA,dc=my-domain,dc=com"
+ }
+}
+===DONE===
Index: ext/ldap/tests/ldap_ctrl_paged_results_variation2.phpt
===================================================================
--- ext/ldap/tests/ldap_ctrl_paged_results_variation2.phpt (révision 0)
+++ ext/ldap/tests/ldap_ctrl_paged_results_variation2.phpt (révision 39985)
@@ -0,0 +1,72 @@
+--TEST--
+ldap_ldap_ctrl_paged_results() test (fetching the first page with a pagesize=2)
+--CREDITS--
+Jean-Sebastien Hedde <jeanseb@au-fil-du.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 = "(cn=*)";
+var_dump(
+ ldap_ctrl_paged_results($link, 2),
+ $result = ldap_search($link, $dn, $filter, array('cn')),
+ 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);
+?>
+--EXPECTF--
+bool(true)
+resource(6) of type (ldap result)
+array(3) {
+ ["count"]=>
+ int(2)
+ [0]=>
+ array(4) {
+ ["cn"]=>
+ array(2) {
+ ["count"]=>
+ int(1)
+ [0]=>
+ string(5) "userA"
+ }
+ [0]=>
+ string(2) "cn"
+ ["count"]=>
+ int(1)
+ ["dn"]=>
+ string(28) "cn=userA,dc=my-domain,dc=com"
+ }
+ [1]=>
+ array(4) {
+ ["cn"]=>
+ array(2) {
+ ["count"]=>
+ int(1)
+ [0]=>
+ string(5) "userB"
+ }
+ [0]=>
+ string(2) "cn"
+ ["count"]=>
+ int(1)
+ ["dn"]=>
+ string(28) "cn=userB,dc=my-domain,dc=com"
+ }
+}
+===DONE===
Index: ext/ldap/tests/ldap_ctrl_paged_results_variation3.phpt
===================================================================
--- ext/ldap/tests/ldap_ctrl_paged_results_variation3.phpt (révision 0)
+++ ext/ldap/tests/ldap_ctrl_paged_results_variation3.phpt (révision 39985)
@@ -0,0 +1,100 @@
+--TEST--
+ldap_ldap_ctrl_paged_results() test (fetching the first page then the next final page)
+--CREDITS--
+Jean-Sebastien Hedde <jeanseb@au-fil-du.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 = "(cn=*)";
+$cookie = '';
+var_dump(
+ ldap_ctrl_paged_results($link, 2, true, $cookie),
+ $result = ldap_search($link, $dn, $filter, array('cn')),
+ ldap_get_entries($link, $result),
+ ldap_ctrl_paged_results_resp($link, $result, &$cookie),
+ ldap_ctrl_paged_results($link, 20, true, &$cookie),
+ $result = ldap_search($link, $dn, $filter, array('cn')),
+ 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);
+?>
+--EXPECTF--
+bool(true)
+resource(%d) of type (ldap result)
+array(3) {
+ ["count"]=>
+ int(2)
+ [0]=>
+ array(4) {
+ ["cn"]=>
+ array(2) {
+ ["count"]=>
+ int(1)
+ [0]=>
+ string(5) "userA"
+ }
+ [0]=>
+ string(2) "cn"
+ ["count"]=>
+ int(1)
+ ["dn"]=>
+ string(28) "cn=userA,dc=my-domain,dc=com"
+ }
+ [1]=>
+ array(4) {
+ ["cn"]=>
+ array(2) {
+ ["count"]=>
+ int(1)
+ [0]=>
+ string(5) "userB"
+ }
+ [0]=>
+ string(2) "cn"
+ ["count"]=>
+ int(1)
+ ["dn"]=>
+ string(28) "cn=userB,dc=my-domain,dc=com"
+ }
+}
+bool(true)
+bool(true)
+resource(%d) of type (ldap result)
+array(2) {
+ ["count"]=>
+ int(1)
+ [0]=>
+ array(4) {
+ ["cn"]=>
+ array(2) {
+ ["count"]=>
+ int(1)
+ [0]=>
+ string(5) "userC"
+ }
+ [0]=>
+ string(2) "cn"
+ ["count"]=>
+ int(1)
+ ["dn"]=>
+ string(37) "cn=userC,cn=userB,dc=my-domain,dc=com"
+ }
+}
+===DONE===
Index: ext/ldap/php_ldap.h
===================================================================
--- ext/ldap/php_ldap.h (révision 39622)
+++ ext/ldap/php_ldap.h (révision 39985)
@@ -15,6 +15,8 @@
| Authors: Amitay Isaacs <amitay@w-o-i.com> |
| Eric Warnke <ericw@albany.edu> |
| Jani Taskinen <sniper@iki.fi> |
+ | Pierangelo Masarati <ando@OpenLDAP.org> |
+ | Iñaki Arenaza <iarenuno@eteo.mondragon.edu> |
+----------------------------------------------------------------------+
*/
@@ -96,6 +98,11 @@
PHP_FUNCTION(ldap_8859_to_t61);
#endif
+#ifdef LDAP_CONTROL_PAGEDRESULTS
+/* RFC 2696 */
+PHP_FUNCTION(ldap_ctrl_paged_results);
+PHP_FUNCTION(ldap_ctrl_paged_results_resp);
+#endif
ZEND_BEGIN_MODULE_GLOBALS(ldap)
long num_links;
long max_links;
|