php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login

Patch 0001-Add-function-ldap_parse_virtual_list_control.patch for LDAP related Bug #62853

Patch version 2012-08-18 13:57 UTC

Return to Bug #62853 | Download this patch
Patch Revisions:

Developer: vanmeeuwen@kolabsys.com

From 5fc659963b82fef52b2be424f4e00e1793f70115 Mon Sep 17 00:00:00 2001
From: "Jeroen van Meeuwen (Kolab Systems)" <vanmeeuwen@kolabsys.com>
Date: Sat, 14 Apr 2012 11:14:46 +0100
Subject: [PATCH] Add function ldap_parse_virtual_list_control()

---
 ext/ldap/ldap.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 91 insertions(+), 6 deletions(-)

diff --git a/ext/ldap/ldap.c b/ext/ldap/ldap.c
index 47d3ab1..a887412 100644
--- a/ext/ldap/ldap.c
+++ b/ext/ldap/ldap.c
@@ -83,7 +83,7 @@ typedef struct {
 ZEND_DECLARE_MODULE_GLOBALS(ldap)
 static PHP_GINIT_FUNCTION(ldap);
 
-static int le_link, le_result, le_result_entry;
+static int le_link, le_result, le_result_entry, le_server_ctrls;
 
 #ifdef COMPILE_DL_LDAP
 ZEND_GET_MODULE(ldap)
@@ -124,6 +124,14 @@ static void _free_ldap_result_entry(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{
 	efree(entry);
 } 
 /* }}} */
+static void _free_ldap_server_ctrls(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */
+{
+	LDAPControl **serverctrls = (LDAPControl **)rsrc->ptr;
+	if (serverctrls != NULL)
+		ldap_controls_free(serverctrls);
+}
+/* }}} */
+
 
 /* {{{ PHP_INI_BEGIN
  */
@@ -198,6 +206,7 @@ PHP_MINIT_FUNCTION(ldap)
 	le_link = zend_register_list_destructors_ex(_close_ldap_link, NULL, "ldap link", module_number);
 	le_result = zend_register_list_destructors_ex(_free_ldap_result, NULL, "ldap result", module_number);
 	le_result_entry = zend_register_list_destructors_ex(_free_ldap_result_entry, NULL, "ldap result entry", module_number);
+	le_server_ctrls = zend_register_list_destructors_ex(_free_ldap_server_ctrls, NULL, "ldap server controls", module_number);
 
 	Z_TYPE(ldap_module_entry) = type;
 
@@ -1821,18 +1830,19 @@ PHP_FUNCTION(ldap_set_option)
 /* }}} */
 
 #ifdef HAVE_LDAP_PARSE_RESULT
-/* {{{ proto bool ldap_parse_result(resource link, resource result, int errcode, string matcheddn, string errmsg, array referrals)
+/* {{{ proto bool ldap_parse_result(resource link, resource result, int errcode, string matcheddn, string errmsg, array referrals, resource serverctrls)
    Extract information from result */
 PHP_FUNCTION(ldap_parse_result) 
 {
-	zval *link, *result, *errcode, *matcheddn, *errmsg, *referrals;
+	zval *link, *result, *errcode, *matcheddn, *errmsg, *referrals, *serverctrls;
 	ldap_linkdata *ld;
 	LDAPMessage *ldap_result;
 	char **lreferrals, **refp;
+	LDAPControl **lserverctrls, **ctrlp;
 	char *lmatcheddn, *lerrmsg;
 	int rc, lerrcode, myargcount = ZEND_NUM_ARGS();
 
-	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rrz|zzz", &link, &result, &errcode, &matcheddn, &errmsg, &referrals) != SUCCESS) {
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rrz|zzzz", &link, &result, &errcode, &matcheddn, &errmsg, &referrals, &serverctrls) != SUCCESS) {
 		return; 
 	}
 
@@ -1843,7 +1853,7 @@ PHP_FUNCTION(ldap_parse_result)
 				myargcount > 3 ? &lmatcheddn : NULL,
 				myargcount > 4 ? &lerrmsg : NULL,
 				myargcount > 5 ? &lreferrals : NULL,
-				NULL /* &serverctrls */,
+				myargcount > 6 ? &lserverctrls : NULL,
 				0);
 	if (rc != LDAP_SUCCESS) {
 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to parse result: %s", ldap_err2string(rc));
@@ -1855,6 +1865,11 @@ PHP_FUNCTION(ldap_parse_result)
 
 	/* Reverse -> fall through */
 	switch (myargcount) {
+		case 7:
+			zval_dtor(serverctrls);
+			if (lserverctrls != NULL) {
+				ZEND_REGISTER_RESOURCE(serverctrls, lserverctrls, le_server_ctrls);
+			}
 		case 6:
 			zval_dtor(referrals);
 			array_init(referrals);
@@ -1886,6 +1901,68 @@ PHP_FUNCTION(ldap_parse_result)
 	RETURN_TRUE;
 }
 /* }}} */
+/* {{{ proto array ldap_parse_virtuallist_control(resource link, array serverctrls, int position, int size, int errcode)
+   Get position and size from virtual list view response control */
+PHP_FUNCTION(ldap_parse_virtuallist_control)
+{
+	zval *link, *serverctrls, *position, *size, *errcode;
+	ldap_linkdata *ld;
+	BerElement    *ber;
+	LDAPControl   **ctrls;
+	int i, foundListControl, version;
+	LDAPControl *listCtrlp;
+	ber_int_t   pos, sz, ec;
+
+
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rrzzz", &link, &serverctrls, &position, &size, &errcode) != SUCCESS) {
+		return;
+	}
+
+	ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
+	ZEND_FETCH_RESOURCE(ctrls, LDAPControl **, &serverctrls, -1, "ldap server controls", le_server_ctrls);
+
+	if (LDAP_OPT_SUCCESS != ldap_get_option(ld->link,LDAP_OPT_PROTOCOL_VERSION,(void*)&version) || version < LDAP_VERSION3) {
+		php_error_docref(NULL TSRMLS_CC, E_WARNING, "LDAP protocol version does not support controls");
+		RETURN_FALSE;
+	}
+	if (ctrls == NULL) {
+		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Virtual list view response control not found");
+		RETURN_FALSE;
+	}
+	foundListControl = 0;
+	for ( i = 0; (( ctrls[i] != NULL ) && ( !foundListControl )); i++ ) { 
+		foundListControl = !strcmp( ctrls[i]->ldctl_oid, LDAP_CONTROL_VLVRESPONSE);
+	}   
+	if ( !foundListControl ) {
+		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Virtual list view response control not found");
+		RETURN_FALSE;
+	}
+	/* let local var point to the listControl */
+	listCtrlp = ctrls[i-1];
+	/* allocate a ber element for the response value */
+	if ( ( ber = ber_init( &listCtrlp->ldctl_value ) ) == NULL ) {
+		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to allocate a Ber element: %s", ldap_err2string(LDAP_NO_MEMORY));
+		RETURN_FALSE;
+	}
+	/* decode the result from the Ber element */
+	if (  LBER_ERROR == ber_scanf( ber, "{iie}", &pos, &sz, &ec ) ) {
+		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to decode response control: %s", ldap_err2string(LDAP_DECODING_ERROR));
+		ber_free( ber, 1 );
+		RETURN_FALSE;
+	}
+	zval_dtor(position);
+	ZVAL_LONG(position, (long)pos);
+
+	zval_dtor(size);
+	ZVAL_LONG(size, (long)sz);
+
+	zval_dtor(errcode);
+	ZVAL_LONG(errcode, (long)ec);
+
+	ber_free(ber,1);
+	RETURN_TRUE;
+}
+/* }}} */
 #endif
 
 /* {{{ proto resource ldap_first_reference(resource link, resource result)
@@ -2605,7 +2682,6 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_parse_reference, 0, 0, 3)
 ZEND_END_ARG_INFO()
 #endif
 
-
 #ifdef HAVE_LDAP_PARSE_RESULT
 ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_parse_result, 0, 0, 3)
 	ZEND_ARG_INFO(0, link)
@@ -2614,6 +2690,14 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_parse_result, 0, 0, 3)
 	ZEND_ARG_INFO(1, matcheddn)
 	ZEND_ARG_INFO(1, errmsg)
 	ZEND_ARG_INFO(1, referrals)
+	ZEND_ARG_INFO(1, serverctrls)
+ZEND_END_ARG_INFO()
+ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_parse_virtuallist_control, 0, 0, 5)
+	ZEND_ARG_INFO(0, link)
+	ZEND_ARG_INFO(0, serverctrls)
+	ZEND_ARG_INFO(1, position)
+	ZEND_ARG_INFO(1, size)
+	ZEND_ARG_INFO(1, errcode)
 ZEND_END_ARG_INFO()
 #endif
 #endif
@@ -2693,6 +2777,7 @@ const zend_function_entry ldap_functions[] = {
 #endif
 #ifdef HAVE_LDAP_PARSE_RESULT
 	PHP_FE(ldap_parse_result,							arginfo_ldap_parse_result)
+	PHP_FE(ldap_parse_virtuallist_control,				arginfo_ldap_parse_virtuallist_control)
 #endif
 #ifdef HAVE_LDAP_START_TLS_S
 	PHP_FE(ldap_start_tls,								arginfo_ldap_resource)
-- 
1.7.11.2

 
PHP Copyright © 2001-2023 The PHP Group
All rights reserved.
Last updated: Sun Feb 05 11:05:50 2023 UTC