From 58c86087a89c232d7cc87a2abee1f53aee8b1704 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tiziano=20M=C3=BCller?= Date: Wed, 23 Apr 2014 20:48:20 +0200 Subject: [PATCH 1/7] Add LDAPControl resource type. --- ext/ldap/ldap.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/ext/ldap/ldap.c b/ext/ldap/ldap.c index 50055a25a7531..e54d2d5fa0996 100644 --- a/ext/ldap/ldap.c +++ b/ext/ldap/ldap.c @@ -86,7 +86,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_control; #ifdef COMPILE_DL_LDAP ZEND_GET_MODULE(ldap) @@ -128,6 +128,12 @@ static void _free_ldap_result_entry(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ } /* }}} */ +static void _free_ldap_control(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */ +{ + ldap_control_free((LDAPControl *)rsrc->ptr); +} +/* }}} */ + /* {{{ PHP_INI_BEGIN */ PHP_INI_BEGIN() @@ -213,6 +219,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_control = zend_register_list_destructors_ex(_free_ldap_control, NULL, "ldap control", module_number); Z_TYPE(ldap_module_entry) = type; From 4e0d96a1a75273db9e217ded42a304c90ace9821 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tiziano=20M=C3=BCller?= Date: Wed, 23 Apr 2014 20:49:07 +0200 Subject: [PATCH 2/7] Add ldap_control_assertion to create assertion controls. --- ext/ldap/ldap.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/ext/ldap/ldap.c b/ext/ldap/ldap.c index e54d2d5fa0996..6d13522e84d7d 100644 --- a/ext/ldap/ldap.c +++ b/ext/ldap/ldap.c @@ -2830,6 +2830,43 @@ PHP_FUNCTION(ldap_control_paged_result_response) /* }}} */ #endif +#ifdef LDAP_CONTROL_ASSERT +/* {{{ proto mixed ldap_control_assertion(resource link, string assert) + Assertion control*/ +PHP_FUNCTION(ldap_control_assertion) +{ + zval *link; + char *assert = NULL; + int assert_len = 0; + ldap_linkdata *ld; + LDAP *ldap; + LDAPControl *control; + + int rc; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &link, &assert, &assert_len) != SUCCESS) { + RETURN_FALSE; + } + + if (Z_TYPE_P(link) == IS_NULL) { + ldap = NULL; + } else { + ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link); + ldap = ld->link; + } + + rc = ldap_create_assertion_control(ldap, assert, 0, &control); + + if (rc != LDAP_SUCCESS) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to create assertion control"); + RETURN_FALSE; + } + + ZEND_REGISTER_RESOURCE(return_value, control, le_control); +} +/* }}} */ +#endif + /* {{{ arginfo */ ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_connect, 0, 0, 0) ZEND_ARG_INFO(0, hostname) @@ -3031,6 +3068,13 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_control_paged_result_response, 0, 0, 2) ZEND_END_ARG_INFO(); #endif +#ifdef LDAP_CONTROL_ASSERT +ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_control_assertion, 0, 0, 2) + ZEND_ARG_INFO(0, link) + ZEND_ARG_INFO(0, assert) +ZEND_END_ARG_INFO(); +#endif + #if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_rename, 0, 0, 5) ZEND_ARG_INFO(0, link_identifier) @@ -3186,6 +3230,10 @@ const zend_function_entry ldap_functions[] = { PHP_FE(ldap_control_paged_result, arginfo_ldap_control_paged_result) PHP_FE(ldap_control_paged_result_response, arginfo_ldap_control_paged_result_response) #endif + +#ifdef LDAP_CONTROL_ASSERT + PHP_FE(ldap_control_assertion, arginfo_ldap_control_assertion) +#endif PHP_FE_END }; /* }}} */ From 88bf2ea695f32d1f1ae4a6721b84e3c83caf0c55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tiziano=20M=C3=BCller?= Date: Wed, 23 Apr 2014 20:50:44 +0200 Subject: [PATCH 3/7] Add optional control parameters for add/modify/replace/delete. Currently only one LDAPControl (per server/client) can be specified. --- ext/ldap/ldap.c | 46 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/ext/ldap/ldap.c b/ext/ldap/ldap.c index 6d13522e84d7d..06b3dc2119dd0 100644 --- a/ext/ldap/ldap.c +++ b/ext/ldap/ldap.c @@ -1289,17 +1289,18 @@ PHP_FUNCTION(ldap_dn2ufn) */ static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper) { - zval *link, *entry, **value, **ivalue; + zval *link, *entry, **value, **ivalue, *server_control = NULL, *client_control = NULL; ldap_linkdata *ld; char *dn; LDAPMod **ldap_mods; + LDAPControl **server_ctrls = NULL, **client_ctrls = NULL; int i, j, num_attribs, num_values, dn_len; int *num_berval; char *attribute; ulong index; int is_full_add=0; /* flag for full add operation so ldap_mod_add can be put back into oper, gerrit THomson */ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsa", &link, &dn, &dn_len, &entry) != SUCCESS) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsa|rr", &link, &dn, &dn_len, &entry, &server_control, &client_control) != SUCCESS) { return; } @@ -1310,6 +1311,19 @@ static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper) num_berval = safe_emalloc(num_attribs, sizeof(int), 0); zend_hash_internal_pointer_reset(Z_ARRVAL_P(entry)); + + if (server_control) { + server_ctrls = safe_emalloc(2, sizeof(LDAPControl *), 0); + ZEND_FETCH_RESOURCE(server_ctrls[0], LDAPControl *, &server_control, -1, "ldap control", le_control); + server_ctrls[1] = NULL; + } + + if (client_control) { + client_ctrls = safe_emalloc(2, sizeof(LDAPControl *), 0); + ZEND_FETCH_RESOURCE(client_ctrls[0], LDAPControl *, &client_control, -1, "ldap control", le_control); + client_ctrls[1] = NULL; + } + /* added by gerrit thomson to fix ldap_add using ldap_mod_add */ if (oper == PHP_LD_FULL_ADD) { oper = LDAP_MOD_ADD; @@ -1378,12 +1392,12 @@ static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper) /* check flag to see if do_mod was called to perform full add , gerrit thomson */ if (is_full_add == 1) { - if ((i = ldap_add_s(ld->link, dn, ldap_mods)) != LDAP_SUCCESS) { + if ((i = ldap_add_ext_s(ld->link, dn, ldap_mods, server_ctrls, client_ctrls)) != LDAP_SUCCESS) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Add: %s", ldap_err2string(i)); RETVAL_FALSE; } else RETVAL_TRUE; } else { - if ((i = ldap_modify_ext_s(ld->link, dn, ldap_mods, NULL, NULL)) != LDAP_SUCCESS) { + if ((i = ldap_modify_ext_s(ld->link, dn, ldap_mods, server_ctrls, client_ctrls)) != LDAP_SUCCESS) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Modify: %s", ldap_err2string(i)); RETVAL_FALSE; } else RETVAL_TRUE; @@ -1399,7 +1413,9 @@ static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper) efree(ldap_mods[i]); } efree(num_berval); - efree(ldap_mods); + efree(ldap_mods); + efree(server_ctrls); + efree(client_ctrls); return; } @@ -2994,10 +3010,12 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_dn2ufn, 0, 0, 1) ZEND_ARG_INFO(0, dn) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_add, 0, 0, 3) +ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_add, 0, 0, 5) ZEND_ARG_INFO(0, link_identifier) ZEND_ARG_INFO(0, dn) ZEND_ARG_INFO(0, entry) + ZEND_ARG_INFO(0, server_control) + ZEND_ARG_INFO(0, client_control) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_delete, 0, 0, 2) @@ -3005,10 +3023,12 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_delete, 0, 0, 2) ZEND_ARG_INFO(0, dn) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_modify, 0, 0, 3) +ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_modify, 0, 0, 5) ZEND_ARG_INFO(0, link_identifier) ZEND_ARG_INFO(0, dn) ZEND_ARG_INFO(0, entry) + ZEND_ARG_INFO(0, server_control) + ZEND_ARG_INFO(0, client_control) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_modify_batch, 0, 0, 3) @@ -3017,22 +3037,28 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_modify_batch, 0, 0, 3) ZEND_ARG_ARRAY_INFO(0, modifications_info, 0) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_mod_add, 0, 0, 3) +ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_mod_add, 0, 0, 5) ZEND_ARG_INFO(0, link_identifier) ZEND_ARG_INFO(0, dn) ZEND_ARG_INFO(0, entry) + ZEND_ARG_INFO(0, server_control) + ZEND_ARG_INFO(0, client_control) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_mod_replace, 0, 0, 3) +ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_mod_replace, 0, 0, 5) ZEND_ARG_INFO(0, link_identifier) ZEND_ARG_INFO(0, dn) ZEND_ARG_INFO(0, entry) + ZEND_ARG_INFO(0, server_control) + ZEND_ARG_INFO(0, client_control) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_mod_del, 0, 0, 3) +ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_mod_del, 0, 0, 5) ZEND_ARG_INFO(0, link_identifier) ZEND_ARG_INFO(0, dn) ZEND_ARG_INFO(0, entry) + ZEND_ARG_INFO(0, server_control) + ZEND_ARG_INFO(0, client_control) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_err2str, 0, 0, 1) From 171291a950556c1566a09d2347c0892253c56d1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tiziano=20M=C3=BCller?= Date: Wed, 23 Apr 2014 20:55:17 +0200 Subject: [PATCH 4/7] Add tests for ldap_control_assertion --- .../tests/ldap_control_assertion_basic.phpt | 47 ++++++++++++++++ .../tests/ldap_control_assertion_error.phpt | 54 +++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 ext/ldap/tests/ldap_control_assertion_basic.phpt create mode 100644 ext/ldap/tests/ldap_control_assertion_error.phpt diff --git a/ext/ldap/tests/ldap_control_assertion_basic.phpt b/ext/ldap/tests/ldap_control_assertion_basic.phpt new file mode 100644 index 0000000000000..eb12669364e62 --- /dev/null +++ b/ext/ldap/tests/ldap_control_assertion_basic.phpt @@ -0,0 +1,47 @@ +--TEST-- +ldap_control_assertion() - Assertion control creation +--CREDITS-- +Tiziano Müller +--SKIPIF-- + + +--FILE-- + array( + "top", + "dcObject", + "organization"), + "dc" => "my-domain", + "o" => "my-domain", + "description" => "Domain description", +); +ldap_modify($link, "dc=my-domain,dc=com", $entry); + +$assertion_string = "(description=Domain description)"; +$control = ldap_control_assertion($link, $assertion_string); + +var_dump( + $control, + ldap_modify($link, "dc=my-domain,dc=com", $entry, $control) +); + +?> +===DONE=== +--CLEAN-- + +--EXPECTF-- +resource(%d) of type (ldap control) +bool(true) +===DONE=== diff --git a/ext/ldap/tests/ldap_control_assertion_error.phpt b/ext/ldap/tests/ldap_control_assertion_error.phpt new file mode 100644 index 0000000000000..4dbc3dbab7aab --- /dev/null +++ b/ext/ldap/tests/ldap_control_assertion_error.phpt @@ -0,0 +1,54 @@ +--TEST-- +ldap_control_assertion() - Assertion control creation error +--CREDITS-- +Tiziano Müller +--SKIPIF-- + + +--FILE-- + array( + "top", + "dcObject", + "organization"), + "dc" => "my-domain", + "o" => "my-domain", + "description" => "Domain description", +); +ldap_modify($link, "dc=my-domain,dc=com", $entry); + +$garbage_assertion_string = "garbage assertion string"; +$invalid_assertion_string = "(description=Invalid domain description)"; + +$control = ldap_control_assertion($link, $invalid_assertion_string); + +var_dump( + ldap_control_assertion($link, $garbage_assertion_string), + $control, + ldap_modify($link, "dc=my-domain,dc=com", $entry, $control) +); + +?> +===DONE=== +--CLEAN-- + +--EXPECTF-- +Warning: ldap_control_assertion(): Unable to create assertion control in %s on line %d + +Warning: ldap_modify(): Modify: Assertion Failed in %s on line %d +bool(false) +resource(%d) of type (ldap control) +bool(false) +===DONE=== From cf855cd6f1d31f6b8efd33f94274a928d5e73b3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tiziano=20M=C3=BCller?= Date: Thu, 24 Apr 2014 16:48:40 +0200 Subject: [PATCH 5/7] Implement session tracking control --- ext/ldap/ldap.c | 59 +++++++++++++++++++ .../ldap_control_session_tracking_basic.phpt | 45 ++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 ext/ldap/tests/ldap_control_session_tracking_basic.phpt diff --git a/ext/ldap/ldap.c b/ext/ldap/ldap.c index 06b3dc2119dd0..69540523df4f0 100644 --- a/ext/ldap/ldap.c +++ b/ext/ldap/ldap.c @@ -216,6 +216,12 @@ PHP_MINIT_FUNCTION(ldap) REGISTER_LONG_CONSTANT("LDAP_ESCAPE_FILTER", PHP_LDAP_ESCAPE_FILTER, CONST_PERSISTENT | CONST_CS); REGISTER_LONG_CONSTANT("LDAP_ESCAPE_DN", PHP_LDAP_ESCAPE_DN, CONST_PERSISTENT | CONST_CS); +#ifdef LDAP_CONTROL_X_SESSION_TRACKING + REGISTER_STRING_CONSTANT("LDAP_CONTROL_X_SESSION_TRACKING_RADIUS_ACCT_SESSION_ID", LDAP_CONTROL_X_SESSION_TRACKING_RADIUS_ACCT_SESSION_ID, CONST_PERSISTENT | CONST_CS); + REGISTER_STRING_CONSTANT("LDAP_CONTROL_X_SESSION_TRACKING_RADIUS_ACCT_MULTI_SESSION_ID", LDAP_CONTROL_X_SESSION_TRACKING_RADIUS_ACCT_MULTI_SESSION_ID, CONST_PERSISTENT | CONST_CS); + REGISTER_STRING_CONSTANT("LDAP_CONTROL_X_SESSION_TRACKING_USERNAME", LDAP_CONTROL_X_SESSION_TRACKING_USERNAME, CONST_PERSISTENT | CONST_CS); +#endif + 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); @@ -2883,6 +2889,45 @@ PHP_FUNCTION(ldap_control_assertion) /* }}} */ #endif +#ifdef LDAP_CONTROL_X_SESSION_TRACKING +/* {{{ proto mixed ldap_control_session_tracking(resource link, string source_ip, string source_name, string format_oid, string identifier) + Session Tracking Control*/ +PHP_FUNCTION(ldap_control_session_tracking) +{ + zval *link; + char *source_ip = NULL, *source_name = NULL, *format_oid = NULL, *identifier = NULL; + int assert_len = 0, source_ip_len = 0, source_name_len = 0, format_oid_len = 0, identifier_len = 0; + + ldap_linkdata *ld; + LDAP *ldap; + LDAPControl *control; + + int rc; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rssss", &link, &source_ip, &source_ip_len, &source_name, &source_name_len, &format_oid, &format_oid_len, &identifier, &identifier_len) != SUCCESS) { + RETURN_FALSE; + } + + if (Z_TYPE_P(link) == IS_NULL) { + ldap = NULL; + } else { + ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link); + ldap = ld->link; + } + + rc = ldap_create_session_tracking_control(ldap, source_ip, source_name, format_oid, ber_bvstr(identifier), &control); + + if (rc != LDAP_SUCCESS) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to create session tracking control"); + RETURN_FALSE; + } + + ZEND_REGISTER_RESOURCE(return_value, control, le_control); +} +/* }}} */ + +#endif + /* {{{ arginfo */ ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_connect, 0, 0, 0) ZEND_ARG_INFO(0, hostname) @@ -3101,6 +3146,16 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_control_assertion, 0, 0, 2) ZEND_END_ARG_INFO(); #endif +#ifdef LDAP_CONTROL_X_SESSION_TRACKING +ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_control_session_tracking, 0, 0, 5) + ZEND_ARG_INFO(0, link) + ZEND_ARG_INFO(0, source_ip) + ZEND_ARG_INFO(0, source_name) + ZEND_ARG_INFO(0, format_oid) + ZEND_ARG_INFO(0, identifier) +ZEND_END_ARG_INFO(); +#endif + #if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_rename, 0, 0, 5) ZEND_ARG_INFO(0, link_identifier) @@ -3260,6 +3315,10 @@ const zend_function_entry ldap_functions[] = { #ifdef LDAP_CONTROL_ASSERT PHP_FE(ldap_control_assertion, arginfo_ldap_control_assertion) #endif + +#ifdef LDAP_CONTROL_X_SESSION_TRACKING + PHP_FE(ldap_control_session_tracking, arginfo_ldap_control_session_tracking) +#endif PHP_FE_END }; /* }}} */ diff --git a/ext/ldap/tests/ldap_control_session_tracking_basic.phpt b/ext/ldap/tests/ldap_control_session_tracking_basic.phpt new file mode 100644 index 0000000000000..4b09e1218519b --- /dev/null +++ b/ext/ldap/tests/ldap_control_session_tracking_basic.phpt @@ -0,0 +1,45 @@ +--TEST-- +ldap_control_assertion() - Assertion control creation +--CREDITS-- +Tiziano Müller +--SKIPIF-- + + +--FILE-- + array( + "top", + "dcObject", + "organization"), + "dc" => "my-domain", + "o" => "my-domain", + "description" => "Domain description", +); + +$control = ldap_control_session_tracking($link, "127.0.0.1", "localhost", LDAP_CONTROL_X_SESSION_TRACKING_USERNAME, "testuser"); + +var_dump( + $control, + ldap_modify($link, "dc=my-domain,dc=com", $entry, $control) +); + +?> +===DONE=== +--CLEAN-- + +--EXPECTF-- +resource(%d) of type (ldap control) +bool(true) +===DONE=== From cbdec31de599b625b9d37f7150c4426f2455f844 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tiziano=20M=C3=BCller?= Date: Fri, 25 Apr 2014 14:36:24 +0200 Subject: [PATCH 6/7] Add functionality to pass single controls or a list of controls as server controls in functions using php_ldap_do_modify --- ext/ldap/ldap.c | 38 ++++++++++++++----- .../tests/ldap_control_assertion_basic.phpt | 8 +++- .../tests/ldap_control_assertion_error.phpt | 25 +++++++++--- 3 files changed, 55 insertions(+), 16 deletions(-) diff --git a/ext/ldap/ldap.c b/ext/ldap/ldap.c index 69540523df4f0..6b89f2c3d6d2b 100644 --- a/ext/ldap/ldap.c +++ b/ext/ldap/ldap.c @@ -1295,18 +1295,18 @@ PHP_FUNCTION(ldap_dn2ufn) */ static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper) { - zval *link, *entry, **value, **ivalue, *server_control = NULL, *client_control = NULL; + zval *link, *entry, **value, **ivalue, *server_control = NULL, *client_control = NULL, **control; ldap_linkdata *ld; char *dn; LDAPMod **ldap_mods; LDAPControl **server_ctrls = NULL, **client_ctrls = NULL; - int i, j, num_attribs, num_values, dn_len; + int i, j, num_attribs, num_values, dn_len, num_server_controls = 0; int *num_berval; char *attribute; ulong index; int is_full_add=0; /* flag for full add operation so ldap_mod_add can be put back into oper, gerrit THomson */ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsa|rr", &link, &dn, &dn_len, &entry, &server_control, &client_control) != SUCCESS) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsa|z!z!", &link, &dn, &dn_len, &entry, &server_control, &client_control) != SUCCESS) { return; } @@ -1319,15 +1319,33 @@ static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper) if (server_control) { - server_ctrls = safe_emalloc(2, sizeof(LDAPControl *), 0); - ZEND_FETCH_RESOURCE(server_ctrls[0], LDAPControl *, &server_control, -1, "ldap control", le_control); - server_ctrls[1] = NULL; + if (Z_TYPE_P(server_control) == IS_ARRAY) { + num_server_controls = zend_hash_num_elements(Z_ARRVAL_P(server_control)); + } else { + num_server_controls = 1; + } + } + + if (num_server_controls > 0) { + server_ctrls = safe_emalloc(num_server_controls + 1, sizeof(LDAPControl *), 0); + server_ctrls[num_server_controls] = NULL; + + if (Z_TYPE_P(server_control) == IS_ARRAY) { + zend_hash_internal_pointer_reset(Z_ARRVAL_P(server_control)); + for (i=0; i < num_server_controls; i++) { + zend_hash_get_current_data(Z_ARRVAL_P(server_control), (void **)&control); + ZEND_FETCH_RESOURCE(server_ctrls[i], LDAPControl *, control, -1, "ldap control", le_control); + zend_hash_move_forward(Z_ARRVAL_P(server_control)); + } + } else { + ZEND_FETCH_RESOURCE(server_ctrls[0], LDAPControl *, &server_control, -1, "ldap control", le_control); + } } - if (client_control) { - client_ctrls = safe_emalloc(2, sizeof(LDAPControl *), 0); - ZEND_FETCH_RESOURCE(client_ctrls[0], LDAPControl *, &client_control, -1, "ldap control", le_control); - client_ctrls[1] = NULL; + if (client_control) { + client_ctrls = safe_emalloc(2, sizeof(LDAPControl *), 0); + ZEND_FETCH_RESOURCE(client_ctrls[0], LDAPControl *, &client_control, -1, "ldap control", le_control); + client_ctrls[1] = NULL; } /* added by gerrit thomson to fix ldap_add using ldap_mod_add */ diff --git a/ext/ldap/tests/ldap_control_assertion_basic.phpt b/ext/ldap/tests/ldap_control_assertion_basic.phpt index eb12669364e62..a533a8fdfd071 100644 --- a/ext/ldap/tests/ldap_control_assertion_basic.phpt +++ b/ext/ldap/tests/ldap_control_assertion_basic.phpt @@ -28,7 +28,10 @@ $control = ldap_control_assertion($link, $assertion_string); var_dump( $control, - ldap_modify($link, "dc=my-domain,dc=com", $entry, $control) + ldap_modify($link, "dc=my-domain,dc=com", $entry, $control), + ldap_modify($link, "dc=my-domain,dc=com", $entry, [$control]), + ldap_modify($link, "dc=my-domain,dc=com", $entry, []), + ldap_modify($link, "dc=my-domain,dc=com", $entry, NULL) ); ?> @@ -44,4 +47,7 @@ remove_dummy_data($link); --EXPECTF-- resource(%d) of type (ldap control) bool(true) +bool(true) +bool(true) +bool(true) ===DONE=== diff --git a/ext/ldap/tests/ldap_control_assertion_error.phpt b/ext/ldap/tests/ldap_control_assertion_error.phpt index 4dbc3dbab7aab..f5129156d061f 100644 --- a/ext/ldap/tests/ldap_control_assertion_error.phpt +++ b/ext/ldap/tests/ldap_control_assertion_error.phpt @@ -26,12 +26,21 @@ ldap_modify($link, "dc=my-domain,dc=com", $entry); $garbage_assertion_string = "garbage assertion string"; $invalid_assertion_string = "(description=Invalid domain description)"; -$control = ldap_control_assertion($link, $invalid_assertion_string); +$session_tracking_control = ldap_control_session_tracking($link, "127.0.0.1", "localhost", LDAP_CONTROL_X_SESSION_TRACKING_USERNAME, "testuser"); +$invalid_assertion_control = ldap_control_assertion($link, $invalid_assertion_string); var_dump( - ldap_control_assertion($link, $garbage_assertion_string), - $control, - ldap_modify($link, "dc=my-domain,dc=com", $entry, $control) + ldap_control_assertion($link, $garbage_assertion_string) +); + +var_dump( + $invalid_assertion_control, + ldap_modify($link, "dc=my-domain,dc=com", $entry, $invalid_assertion_control), + ldap_modify($link, "dc=my-domain,dc=com", $entry, [$invalid_assertion_control]) +); + +var_dump( + ldap_modify($link, "dc=my-domain,dc=com", $entry, [$session_tracking_control, $invalid_assertion_control]) ); ?> @@ -46,9 +55,15 @@ remove_dummy_data($link); ?> --EXPECTF-- Warning: ldap_control_assertion(): Unable to create assertion control in %s on line %d +bool(false) + +Warning: ldap_modify(): Modify: Assertion Failed in %s on line %d Warning: ldap_modify(): Modify: Assertion Failed in %s on line %d -bool(false) resource(%d) of type (ldap control) bool(false) +bool(false) + +Warning: ldap_modify(): Modify: Assertion Failed in %s on line %d +bool(false) ===DONE=== From 8ba14aee4165c5208f02087dae61f128c3e404a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tiziano=20M=C3=BCller?= Date: Fri, 25 Apr 2014 15:07:09 +0200 Subject: [PATCH 7/7] Factor out the ldap controls handling code. And reuse it for client controls as well. --- ext/ldap/ldap.c | 72 ++++++++++++++++++++++++++----------------------- 1 file changed, 39 insertions(+), 33 deletions(-) diff --git a/ext/ldap/ldap.c b/ext/ldap/ldap.c index 6b89f2c3d6d2b..2ff2687de80ee 100644 --- a/ext/ldap/ldap.c +++ b/ext/ldap/ldap.c @@ -92,6 +92,40 @@ static int le_link, le_result, le_result_entry, le_control; ZEND_GET_MODULE(ldap) #endif +static LDAPControl** _handle_ldap_controls(zval **control, zval *return_value TSRMLS_DC) /* {{{ */ +{ + zval **single_control; + int i, num_controls = 0; + LDAPControl **ctrls = NULL; + + if (control) { + if (Z_TYPE_PP(control) == IS_ARRAY) { + num_controls = zend_hash_num_elements(Z_ARRVAL_PP(control)); + } else { + num_controls = 1; + } + } + + if (num_controls > 0) { + ctrls = safe_emalloc(num_controls + 1, sizeof(LDAPControl *), 0); + ctrls[num_controls] = NULL; + + if (Z_TYPE_PP(control) == IS_ARRAY) { + zend_hash_internal_pointer_reset(Z_ARRVAL_PP(control)); + for (i=0; i < num_controls; i++) { + zend_hash_get_current_data(Z_ARRVAL_PP(control), (void **)&single_control); + ZEND_FETCH_RESOURCE(ctrls[i], LDAPControl *, single_control, -1, "ldap control", le_control); + zend_hash_move_forward(Z_ARRVAL_PP(control)); + } + } else { + ZEND_FETCH_RESOURCE(ctrls[0], LDAPControl *, control, -1, "ldap control", le_control); + } + } + + return ctrls; +} +/* }}} */ + static void _close_ldap_link(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */ { ldap_linkdata *ld = (ldap_linkdata *)rsrc->ptr; @@ -1295,18 +1329,18 @@ PHP_FUNCTION(ldap_dn2ufn) */ static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper) { - zval *link, *entry, **value, **ivalue, *server_control = NULL, *client_control = NULL, **control; + zval *link, *entry, **value, **ivalue, **server_controls = NULL, **client_controls = NULL; ldap_linkdata *ld; char *dn; LDAPMod **ldap_mods; LDAPControl **server_ctrls = NULL, **client_ctrls = NULL; - int i, j, num_attribs, num_values, dn_len, num_server_controls = 0; + int i, j, num_attribs, num_values, dn_len; int *num_berval; char *attribute; ulong index; int is_full_add=0; /* flag for full add operation so ldap_mod_add can be put back into oper, gerrit THomson */ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsa|z!z!", &link, &dn, &dn_len, &entry, &server_control, &client_control) != SUCCESS) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsa|Z!Z!", &link, &dn, &dn_len, &entry, &server_controls, &client_controls) != SUCCESS) { return; } @@ -1317,36 +1351,8 @@ static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper) num_berval = safe_emalloc(num_attribs, sizeof(int), 0); zend_hash_internal_pointer_reset(Z_ARRVAL_P(entry)); - - if (server_control) { - if (Z_TYPE_P(server_control) == IS_ARRAY) { - num_server_controls = zend_hash_num_elements(Z_ARRVAL_P(server_control)); - } else { - num_server_controls = 1; - } - } - - if (num_server_controls > 0) { - server_ctrls = safe_emalloc(num_server_controls + 1, sizeof(LDAPControl *), 0); - server_ctrls[num_server_controls] = NULL; - - if (Z_TYPE_P(server_control) == IS_ARRAY) { - zend_hash_internal_pointer_reset(Z_ARRVAL_P(server_control)); - for (i=0; i < num_server_controls; i++) { - zend_hash_get_current_data(Z_ARRVAL_P(server_control), (void **)&control); - ZEND_FETCH_RESOURCE(server_ctrls[i], LDAPControl *, control, -1, "ldap control", le_control); - zend_hash_move_forward(Z_ARRVAL_P(server_control)); - } - } else { - ZEND_FETCH_RESOURCE(server_ctrls[0], LDAPControl *, &server_control, -1, "ldap control", le_control); - } - } - - if (client_control) { - client_ctrls = safe_emalloc(2, sizeof(LDAPControl *), 0); - ZEND_FETCH_RESOURCE(client_ctrls[0], LDAPControl *, &client_control, -1, "ldap control", le_control); - client_ctrls[1] = NULL; - } + server_ctrls = _handle_ldap_controls(server_controls, return_value TSRMLS_CC); + client_ctrls = _handle_ldap_controls(client_controls, return_value TSRMLS_CC); /* added by gerrit thomson to fix ldap_add using ldap_mod_add */ if (oper == PHP_LD_FULL_ADD) {