From: Côme Chilliet Date: Tue, 12 Sep 2017 07:53:49 +0000 (+0200) Subject: Added ldap_add_ext and preread/postread support and tests X-Git-Tag: php-7.3.0alpha1~1385^2~11 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=32b51035bedda2786d80f170b3aad1b2bf0f329f;p=php Added ldap_add_ext and preread/postread support and tests --- diff --git a/ext/ldap/ldap.c b/ext/ldap/ldap.c index 8962d421bf..00b6050d27 100644 --- a/ext/ldap/ldap.c +++ b/ext/ldap/ldap.c @@ -182,6 +182,45 @@ static void _php_ldap_control_to_array(LDAP *ld, LDAPControl* ctrl, zval* array) } else { add_assoc_null(array, "value"); } + } else if ((strcmp(ctrl->ldctl_oid, LDAP_CONTROL_PRE_READ) == 0) || (strcmp(ctrl->ldctl_oid, LDAP_CONTROL_POST_READ) == 0)) { + BerElement *ber; + struct berval bv; + + ber = ber_init(&ctrl->ldctl_value); + if (ber == NULL) { + add_assoc_null(array, "value"); + } else if (ber_scanf(ber, "{m{" /*}}*/, &bv) == LBER_ERROR) { + add_assoc_null(array, "value"); + } else { + zval value; + + array_init(&value); + add_assoc_stringl(&value, "dn", bv.bv_val, bv.bv_len); + + while (ber_scanf(ber, "{m" /*}*/, &bv) != LBER_ERROR) { + int i; + BerVarray vals = NULL; + zval tmp; + + if (ber_scanf(ber, "[W]", &vals) == LBER_ERROR || vals == NULL) + { + break; + } + + array_init(&tmp); + for (i = 0; vals[i].bv_val != NULL; i++) { + add_next_index_stringl(&tmp, vals[i].bv_val, vals[i].bv_len); + } + add_assoc_zval(&value, bv.bv_val, &tmp); + + ber_bvarray_free(vals); + } + add_assoc_zval(array, "value", &value); + } + + if (ber != NULL) { + ber_free(ber, 1); + } } else { if (ctrl->ldctl_value.bv_len) { add_assoc_stringl(array, "value", ctrl->ldctl_value.bv_val, ctrl->ldctl_value.bv_len); @@ -196,6 +235,7 @@ static int _php_ldap_control_from_array(LDAP *ld, LDAPControl** ctrl, zval* arra zval* val; char * control_oid = NULL; int control_iscritical = 0, rc = LDAP_SUCCESS; + char** ldap_attrs = NULL; if ((val = zend_hash_str_find(Z_ARRVAL_P(array), "oid", sizeof("oid") - 1)) == NULL) { php_error_docref(NULL, E_WARNING, "Control must have an oid key"); @@ -276,14 +316,13 @@ static int _php_ldap_control_from_array(LDAP *ld, LDAPControl** ctrl, zval* arra } } else if (strcmp(control_oid, LDAP_CONTROL_VALUESRETURNFILTER) == 0) { zval* tmp; - char* filter; if ((tmp = zend_hash_str_find(Z_ARRVAL_P(val), "filter", sizeof("filter") - 1)) == NULL) { rc = -1; php_error_docref(NULL, E_WARNING, "Filter missing from control value array"); } else { - BerElement *vrber = NULL; + BerElement *vrber = ber_alloc_t(LBER_USE_DER); control_value = ber_memalloc(sizeof * control_value); - if ((vrber = ber_alloc_t(LBER_USE_DER)) == NULL) { + if ((control_value == NULL) || (vrber == NULL)) { rc = -1; php_error_docref(NULL, E_WARNING, "Failed to allocate control value"); } else { @@ -300,6 +339,52 @@ static int _php_ldap_control_from_array(LDAP *ld, LDAPControl** ctrl, zval* arra } } } + } else if ((strcmp(control_oid, LDAP_CONTROL_PRE_READ) == 0) || (strcmp(control_oid, LDAP_CONTROL_POST_READ) == 0)) { + zval* tmp; + if ((tmp = zend_hash_str_find(Z_ARRVAL_P(val), "attrs", sizeof("attrs") - 1)) == NULL) { + rc = -1; + php_error_docref(NULL, E_WARNING, "Attributes list missing from control value array"); + } else { + BerElement *ber = ber_alloc_t(LBER_USE_DER); + + control_value = ber_memalloc(sizeof * control_value); + if ((control_value == NULL) || (ber == NULL)) { + rc = -1; + php_error_docref(NULL, E_WARNING, "Failed to allocate control value"); + } else { + int num_attribs, i; + zval* attr; + + num_attribs = zend_hash_num_elements(Z_ARRVAL_P(tmp)); + ldap_attrs = safe_emalloc((num_attribs+1), sizeof(char *), 0); + + for (i = 0; ilink, dn, ldap_mods, lserverctrls, NULL)) != LDAP_SUCCESS) { + if (ext) { + i = ldap_add_ext(ld->link, dn, ldap_mods, lserverctrls, NULL, &msgid); + } else { + i = ldap_add_ext_s(ld->link, dn, ldap_mods, lserverctrls, NULL); + } + if (i != LDAP_SUCCESS) { php_error_docref(NULL, E_WARNING, "Add: %s", ldap_err2string(i)); RETVAL_FALSE; + } else if (ext) { + i = ldap_result(ld->link, msgid, 1 /* LDAP_MSG_ALL */, NULL, &ldap_res); + if (i == -1) { + php_error_docref(NULL, E_WARNING, "Add operation failed"); + RETVAL_FALSE; + goto cleanup; + } + + /* return a PHP control object */ + RETVAL_RES(zend_register_resource(ldap_res, le_result)); } else RETVAL_TRUE; } else { - if ((i = ldap_modify_ext_s(ld->link, dn, ldap_mods, lserverctrls, NULL)) != LDAP_SUCCESS) { + if (ext) { + i = ldap_modify_ext(ld->link, dn, ldap_mods, lserverctrls, NULL, &msgid); + } else { + i = ldap_modify_ext_s(ld->link, dn, ldap_mods, lserverctrls, NULL); + } + if (i != LDAP_SUCCESS) { php_error_docref(NULL, E_WARNING, "Modify: %s", ldap_err2string(i)); RETVAL_FALSE; + } else if (ext) { + i = ldap_result(ld->link, msgid, 1 /* LDAP_MSG_ALL */, NULL, &ldap_res); + if (i == -1) { + php_error_docref(NULL, E_WARNING, "Modify operation failed"); + RETVAL_FALSE; + goto cleanup; + } + + /* return a PHP control object */ + RETVAL_RES(zend_register_resource(ldap_res, le_result)); } else RETVAL_TRUE; } @@ -2027,6 +2147,7 @@ cleanup: } efree(num_berval); efree(ldap_mods); + if (lserverctrls) { _php_ldap_controls_free(&lserverctrls); } @@ -2040,7 +2161,15 @@ cleanup: PHP_FUNCTION(ldap_add) { /* use a newly define parameter into the do_modify so ldap_mod_add can be used the way it is supposed to be used , Gerrit THomson */ - php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_LD_FULL_ADD); + php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_LD_FULL_ADD, 0); +} +/* }}} */ + +/* {{{ proto resource ldap_add_ext(resource link, string dn, array entry [, array servercontrols]) + Add entries to LDAP directory */ +PHP_FUNCTION(ldap_add_ext) +{ + php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_LD_FULL_ADD, 1); } /* }}} */ @@ -2050,7 +2179,7 @@ PHP_FUNCTION(ldap_add) Replace attribute values with new ones */ PHP_FUNCTION(ldap_mod_replace) { - php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_MOD_REPLACE); + php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_MOD_REPLACE, 0); } /* }}} */ @@ -2058,7 +2187,7 @@ PHP_FUNCTION(ldap_mod_replace) Add attribute values to current */ PHP_FUNCTION(ldap_mod_add) { - php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_MOD_ADD); + php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_MOD_ADD, 0); } /* }}} */ @@ -2066,7 +2195,7 @@ PHP_FUNCTION(ldap_mod_add) Delete attribute values */ PHP_FUNCTION(ldap_mod_del) { - php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_MOD_DELETE); + php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_MOD_DELETE, 0); } /* }}} */ @@ -2979,7 +3108,6 @@ PHP_FUNCTION(ldap_set_option) PHP_FUNCTION(ldap_parse_result) { zval *link, *result, *errcode, *matcheddn, *errmsg, *referrals, *serverctrls; - zval ctrl, php_ber; ldap_linkdata *ld; LDAPMessage *ldap_result; LDAPControl **lserverctrls = NULL, **ctrlp = NULL; @@ -4152,6 +4280,13 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_add, 0, 0, 3) ZEND_ARG_INFO(0, servercontrols) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_add_ext, 0, 0, 3) + ZEND_ARG_INFO(0, link_identifier) + ZEND_ARG_INFO(0, dn) + ZEND_ARG_INFO(0, entry) + ZEND_ARG_INFO(0, servercontrols) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_delete, 0, 0, 2) ZEND_ARG_INFO(0, link_identifier) ZEND_ARG_INFO(0, dn) @@ -4381,6 +4516,7 @@ const zend_function_entry ldap_functions[] = { PHP_FE(ldap_explode_dn, arginfo_ldap_explode_dn) PHP_FE(ldap_dn2ufn, arginfo_ldap_dn2ufn) PHP_FE(ldap_add, arginfo_ldap_add) + PHP_FE(ldap_add_ext, arginfo_ldap_add_ext) PHP_FE(ldap_delete, arginfo_ldap_delete) PHP_FE(ldap_modify_batch, arginfo_ldap_modify_batch) PHP_FALIAS(ldap_modify, ldap_mod_replace, arginfo_ldap_modify) diff --git a/ext/ldap/tests/ldap_add_ext.phpt b/ext/ldap/tests/ldap_add_ext.phpt new file mode 100644 index 0000000000..aa08afd094 --- /dev/null +++ b/ext/ldap/tests/ldap_add_ext.phpt @@ -0,0 +1,95 @@ +--TEST-- +ldap_add_ext() - Add operation with controls +--CREDITS-- +Côme Chilliet +--SKIPIF-- + + +--FILE-- + array( + "top", + "organization"), + "o" => "test_ldap_add_ext", + ), [['oid' => LDAP_CONTROL_POST_READ, 'iscritical' => TRUE, 'value' => ['attrs' => ['o']]]]), + ldap_parse_result($link, $result, $errcode, $matcheddn, $errmsg, $referrals, $ctrls), + $errcode, + $errmsg, + $ctrls, + ldap_get_entries( + $link, + ldap_search($link, "$base", "(o=test_ldap_add_ext)") + ) +); +?> +===DONE=== +--CLEAN-- + +--EXPECTF-- +resource(%d) of type (ldap result) +bool(true) +int(0) +string(0) "" +array(1) { + [0]=> + array(3) { + ["oid"]=> + string(14) "1.3.6.1.1.13.2" + ["iscritical"]=> + bool(false) + ["value"]=> + array(2) { + ["dn"]=> + string(%d) "o=test_ldap_add_ext,%s" + ["o"]=> + array(1) { + [0]=> + string(17) "test_ldap_add_ext" + } + } + } +} +array(2) { + ["count"]=> + int(1) + [0]=> + array(6) { + ["objectclass"]=> + array(3) { + ["count"]=> + int(2) + [0]=> + string(3) "top" + [1]=> + string(12) "organization" + } + [0]=> + string(11) "objectclass" + ["o"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(17) "test_ldap_add_ext" + } + [1]=> + string(1) "o" + ["count"]=> + int(2) + ["dn"]=> + string(%d) "o=test_ldap_add_ext,%s" + } +} +===DONE===