From 2b52cb74da92a2cc9b355a4b422168a1069ab321 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20Chilliet?= Date: Thu, 7 Sep 2017 12:19:36 +0200 Subject: [PATCH] Added controls support to ldap_compare Note: for functions like ldap_compare, ldap_delete, ldap_modify, a way to get the result object back will need to be added so that controls returned by the server may be analyzed. --- ext/ldap/ldap.c | 42 ++++++++++++++++++++++---- ext/ldap/tests/ldap_compare_error.phpt | 10 +++--- ext/ldap/tests/ldap_controls.phpt | 10 +++++- 3 files changed, 50 insertions(+), 12 deletions(-) diff --git a/ext/ldap/ldap.c b/ext/ldap/ldap.c index 7b954e80381..9c0d598d782 100644 --- a/ext/ldap/ldap.c +++ b/ext/ldap/ldap.c @@ -2445,14 +2445,16 @@ PHP_FUNCTION(ldap_error) Determine if an entry has a specific value for one of its attributes */ PHP_FUNCTION(ldap_compare) { + zval *serverctrls = NULL, *clientctrls = NULL; zval *link; char *dn, *attr, *value; size_t dn_len, attr_len, value_len; ldap_linkdata *ld; + LDAPControl **lserverctrls = NULL, **lclientctrls = NULL; int errno; struct berval lvalue; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rsss", &link, &dn, &dn_len, &attr, &attr_len, &value, &value_len) != SUCCESS) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "rsss|aa", &link, &dn, &dn_len, &attr, &attr_len, &value, &value_len, &serverctrls, &clientctrls) != SUCCESS) { return; } @@ -2460,23 +2462,49 @@ PHP_FUNCTION(ldap_compare) RETURN_FALSE; } + if (serverctrls) { + lserverctrls = _php_ldap_controls_from_array(ld->link, serverctrls); + if (lserverctrls == NULL) { + RETVAL_FALSE; + goto cleanup; + } + } + if (clientctrls) { + lclientctrls = _php_ldap_controls_from_array(ld->link, clientctrls); + if (lclientctrls == NULL) { + RETVAL_FALSE; + goto cleanup; + } + } + lvalue.bv_val = value; lvalue.bv_len = value_len; - errno = ldap_compare_ext_s(ld->link, dn, attr, &lvalue, NULL, NULL); + errno = ldap_compare_ext_s(ld->link, dn, attr, &lvalue, lserverctrls, lclientctrls); switch (errno) { case LDAP_COMPARE_TRUE: - RETURN_TRUE; + RETVAL_TRUE; break; case LDAP_COMPARE_FALSE: - RETURN_FALSE; + RETVAL_FALSE; break; + + default: + php_error_docref(NULL, E_WARNING, "Compare: %s", ldap_err2string(errno)); + RETVAL_LONG(-1); } - php_error_docref(NULL, E_WARNING, "Compare: %s", ldap_err2string(errno)); - RETURN_LONG(-1); +cleanup: + if (lserverctrls) { + _php_ldap_controls_free(&lserverctrls); + } + if (lclientctrls) { + _php_ldap_controls_free(&lclientctrls); + } + + return; } /* }}} */ @@ -4107,6 +4135,8 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_compare, 0, 0, 4) ZEND_ARG_INFO(0, dn) ZEND_ARG_INFO(0, attribute) ZEND_ARG_INFO(0, value) + ZEND_ARG_INFO(0, servercontrols) + ZEND_ARG_INFO(0, clientcontrols) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_sort, 0, 0, 3) diff --git a/ext/ldap/tests/ldap_compare_error.phpt b/ext/ldap/tests/ldap_compare_error.phpt index 07393f6de65..b1d4514eb11 100644 --- a/ext/ldap/tests/ldap_compare_error.phpt +++ b/ext/ldap/tests/ldap_compare_error.phpt @@ -19,7 +19,7 @@ var_dump(ldap_compare($link, $link)); var_dump(ldap_compare($link, $link, $link)); // Too many parameters -var_dump(ldap_compare($link, $link, $link, $link, "Additional data")); +var_dump(ldap_compare($link, $link, $link, $link, [], [], "Additional data")); var_dump( ldap_compare($link, "cn=userNotAvailable,$base", "sn", "testSN1"), @@ -36,16 +36,16 @@ $link = ldap_connect_and_bind($host, $port, $user, $passwd, $protocol_version); remove_dummy_data($link, $base); ?> --EXPECTF-- -Warning: ldap_compare() expects exactly 4 parameters, 1 given in %s on line %d +Warning: ldap_compare() expects at least 4 parameters, 1 given in %s on line %d NULL -Warning: ldap_compare() expects exactly 4 parameters, 2 given in %s on line %d +Warning: ldap_compare() expects at least 4 parameters, 2 given in %s on line %d NULL -Warning: ldap_compare() expects exactly 4 parameters, 3 given in %s on line %d +Warning: ldap_compare() expects at least 4 parameters, 3 given in %s on line %d NULL -Warning: ldap_compare() expects exactly 4 parameters, 5 given in %s on line %d +Warning: ldap_compare() expects at most 6 parameters, 7 given in %s on line %d NULL Warning: ldap_compare(): Compare: No such object in %s on line %d diff --git a/ext/ldap/tests/ldap_controls.phpt b/ext/ldap/tests/ldap_controls.phpt index 51187bdcfb0..b5fd6ac4401 100644 --- a/ext/ldap/tests/ldap_controls.phpt +++ b/ext/ldap/tests/ldap_controls.phpt @@ -32,7 +32,10 @@ var_dump( ldap_delete($link, "o=test,$base", [['oid' => LDAP_CONTROL_ASSERT, 'iscritical' => TRUE, 'value' => ['filter' => '(description=desc2)']]]), ldap_errno($link), ldap_error($link), - ldap_rename($link, "o=test,$base", "o=test2", "", TRUE, [['oid' => LDAP_CONTROL_ASSERT, 'iscritical' => TRUE, 'value' => ['filter' => '(description=desc2)']]]) + ldap_rename($link, "o=test,$base", "o=test2", "", TRUE, [['oid' => LDAP_CONTROL_ASSERT, 'iscritical' => TRUE, 'value' => ['filter' => '(description=desc2)']]]), + ldap_compare($link, "o=test,$base", "o", "test"), + ldap_compare($link, "o=test,$base", "o", "test", [['oid' => LDAP_CONTROL_ASSERT, 'iscritical' => TRUE, 'value' => ['filter' => '(description=desc2)']]]), + ldap_compare($link, "o=test,$base", "o", "test", [['oid' => LDAP_CONTROL_ASSERT, 'iscritical' => TRUE, 'value' => ['filter' => '(description=desc)']]]) ); ?> ===DONE=== @@ -49,6 +52,8 @@ Warning: ldap_search(): Search: Assertion Failed in %s on line %d Warning: ldap_modify(): Modify: Assertion Failed in %s on line %d Warning: ldap_delete(): Delete: Assertion Failed in %s on line %d + +Warning: ldap_compare(): Compare: Assertion Failed in %s on line %d resource(%d) of type (ldap result) array(2) { ["count"]=> @@ -119,4 +124,7 @@ bool(false) int(122) string(16) "Assertion Failed" bool(false) +bool(true) +int(-1) +bool(true) ===DONE===