} else {
add_assoc_null(array, "value");
}
+ } else if (strcmp(ctrl->ldctl_oid, LDAP_CONTROL_VLVRESPONSE) == 0) {
+ int target, count, errcode, rc;
+ struct berval *context;
+ zval value;
+
+ if (ctrl->ldctl_value.bv_len) {
+ rc = ldap_parse_vlvresponse_control(ld, ctrl, &target, &count, &context, &errcode);
+ } else {
+ rc = -1;
+ }
+ if ( rc == LDAP_SUCCESS ) {
+ array_init(&value);
+ add_assoc_long(&value, "target", target);
+ add_assoc_long(&value, "count", count);
+ add_assoc_long(&value, "errcode", errcode);
+ add_assoc_stringl(&value, "context", context->bv_val, context->bv_len);
+ add_assoc_zval(array, "value", &value);
+ } else {
+ add_assoc_null(array, "value");
+ }
+ ber_bvfree(context);
} else {
if (ctrl->ldctl_value.bv_len) {
add_assoc_stringl(array, "value", ctrl->ldctl_value.bv_val, ctrl->ldctl_value.bv_len);
php_error_docref(NULL, E_WARNING, "Failed to create sort control value: %s (%d)", ldap_err2string(rc), rc);
}
}
+ } else if (strcmp(control_oid, LDAP_CONTROL_VLVREQUEST) == 0) {
+ zval* tmp;
+ LDAPVLVInfo vlvInfo;
+ struct berval attrValue;
+ struct berval context;
+
+ if ((tmp = zend_hash_str_find(Z_ARRVAL_P(val), "before", sizeof("before") - 1)) != NULL) {
+ convert_to_long_ex(tmp);
+ vlvInfo.ldvlv_before_count = Z_LVAL_P(tmp);
+ } else {
+ rc = -1;
+ php_error_docref(NULL, E_WARNING, "Before key missing from array value for VLV control");
+ goto failure;
+ }
+
+ if ((tmp = zend_hash_str_find(Z_ARRVAL_P(val), "after", sizeof("after") - 1)) != NULL) {
+ convert_to_long_ex(tmp);
+ vlvInfo.ldvlv_after_count = Z_LVAL_P(tmp);
+ } else {
+ rc = -1;
+ php_error_docref(NULL, E_WARNING, "After key missing from array value for VLV control");
+ goto failure;
+ }
+
+ if ((tmp = zend_hash_str_find(Z_ARRVAL_P(val), "attrvalue", sizeof("attrvalue") - 1)) != NULL) {
+ convert_to_string_ex(tmp);
+ attrValue.bv_val = Z_STRVAL_P(tmp);
+ attrValue.bv_len = Z_STRLEN_P(tmp);
+ vlvInfo.ldvlv_attrvalue = &attrValue;
+ } else if ((tmp = zend_hash_str_find(Z_ARRVAL_P(val), "offset", sizeof("offset") - 1)) != NULL) {
+ vlvInfo.ldvlv_attrvalue = NULL;
+ convert_to_long_ex(tmp);
+ vlvInfo.ldvlv_offset = Z_LVAL_P(tmp);
+ if ((tmp = zend_hash_str_find(Z_ARRVAL_P(val), "count", sizeof("count") - 1)) != NULL) {
+ convert_to_long_ex(tmp);
+ vlvInfo.ldvlv_count = Z_LVAL_P(tmp);
+ } else {
+ rc = -1;
+ php_error_docref(NULL, E_WARNING, "Count key missing from array value for VLV control");
+ goto failure;
+ }
+ } else {
+ rc = -1;
+ php_error_docref(NULL, E_WARNING, "Missing either attrvalue or offset key from array value for VLV control");
+ goto failure;
+ }
+
+ if ((tmp = zend_hash_str_find(Z_ARRVAL_P(val), "context", sizeof("context") - 1)) != NULL) {
+ convert_to_string_ex(tmp);
+ context.bv_val = Z_STRVAL_P(tmp);
+ context.bv_len = Z_STRLEN_P(tmp);
+ vlvInfo.ldvlv_context = &context;
+ } else {
+ vlvInfo.ldvlv_context = NULL;
+ }
+
+ control_value = ber_memalloc(sizeof * control_value);
+ if (control_value == NULL) {
+ rc = -1;
+ php_error_docref(NULL, E_WARNING, "Failed to allocate control value");
+ } else {
+ rc = ldap_create_vlv_control_value(ld, &vlvInfo, control_value);
+ if (rc != LDAP_SUCCESS) {
+ php_error_docref(NULL, E_WARNING, "Failed to create VLV control value: %s (%d)", ldap_err2string(rc), rc);
+ }
+ }
} else {
php_error_docref(NULL, E_WARNING, "Control OID %s does not expect an array as value", control_oid);
rc = -1;
--TEST--
-ldap_search() test with sort controls
+ldap_search() test with sort and VLV controls
--CREDITS--
Côme Chilliet <mcmic@php.net>
--SKIPIF--
require_once('skipifbindfailure.inc');
require_once('skipifcontrol.inc');
skipifunsupportedcontrol(LDAP_CONTROL_SORTREQUEST);
+skipifunsupportedcontrol(LDAP_CONTROL_VLVREQUEST);
?>
--FILE--
<?php
$link = ldap_connect_and_bind($host, $port, $user, $passwd, $protocol_version);
insert_dummy_data($link, $base);
-$dn = "$base";
-$filter = "(cn=*)";
+/* First test with only SORT control */
var_dump(
- $result = ldap_search($link, $base, $filter, array('cn'), 0, 0, 0, LDAP_DEREF_NEVER,
+ $result = ldap_search($link, $base, '(cn=*)', array('cn'), 0, 0, 0, LDAP_DEREF_NEVER,
[
[
'oid' => LDAP_CONTROL_SORTREQUEST,
$errmsg,
$controls
);
+
+/* Then with VLV control */
+var_dump(
+ $result = ldap_search($link, $base, '(cn=*)', array('cn'), 0, 0, 0, LDAP_DEREF_NEVER,
+ [
+ [
+ 'oid' => LDAP_CONTROL_SORTREQUEST,
+ 'iscritical' => TRUE,
+ 'value' => [
+ ['attr' => 'cn', 'oid' => '2.5.13.3' /* caseIgnoreOrderingMatch */, 'reverse' => TRUE]
+ ]
+ ],
+ [
+ 'oid' => LDAP_CONTROL_VLVREQUEST,
+ 'iscritical' => TRUE,
+ 'value' => [
+ 'before' => 0, // Return 0 entry before target
+ 'after' => 1, // Return 1 entry after target
+ 'offset' => 2, // Target entry is the second one
+ 'count' => 0, // We have no idea how many entries there are
+ ]
+ ]
+ ]
+ ),
+ ldap_get_entries($link, $result),
+ ldap_parse_result($link, $result, $errcode , $matcheddn , $errmsg , $referrals, $controls),
+ array_keys($controls),
+ $controls[LDAP_CONTROL_SORTRESPONSE],
+ $controls[LDAP_CONTROL_VLVRESPONSE]['value']['target'],
+ $controls[LDAP_CONTROL_VLVRESPONSE]['value']['count'],
+ $controls[LDAP_CONTROL_VLVRESPONSE]['value']['errcode'],
+ bin2hex($controls[LDAP_CONTROL_VLVRESPONSE]['value']['context'])
+);
?>
===DONE===
--CLEAN--
}
}
}
+resource(%d) of type (ldap result)
+array(3) {
+ ["count"]=>
+ int(2)
+ [0]=>
+ array(4) {
+ ["cn"]=>
+ array(2) {
+ ["count"]=>
+ int(1)
+ [0]=>
+ string(5) "userB"
+ }
+ [0]=>
+ string(2) "cn"
+ ["count"]=>
+ int(1)
+ ["dn"]=>
+ string(%d) "cn=userB,%s"
+ }
+ [1]=>
+ array(4) {
+ ["cn"]=>
+ array(2) {
+ ["count"]=>
+ int(1)
+ [0]=>
+ string(5) "userA"
+ }
+ [0]=>
+ string(2) "cn"
+ ["count"]=>
+ int(1)
+ ["dn"]=>
+ string(%d) "cn=userA,%s"
+ }
+}
+bool(true)
+array(2) {
+ [0]=>
+ string(22) "1.2.840.113556.1.4.474"
+ [1]=>
+ string(24) "2.16.840.1.113730.3.4.10"
+}
+array(2) {
+ ["oid"]=>
+ string(22) "1.2.840.113556.1.4.474"
+ ["value"]=>
+ array(1) {
+ ["errcode"]=>
+ int(0)
+ }
+}
+int(2)
+int(3)
+int(0)
+string(%d) "%s"
===DONE===