php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login | |
Patch patch_61853_and_61921.patch for LDAP related Bug #61853Patch version 2013-02-24 17:05 UTC Return to Bug #61853 | Download this patchThis patch renders other patches obsolete Obsolete patches: Patch Revisions:Developer: etienne@lamaisondebarbie.chFrom 4fc6ae12d72b0be83813535d448d3b445e0708e7 Mon Sep 17 00:00:00 2001 From: Etienne Bagnoud <tchetch@i-james.com> Date: Sun, 24 Feb 2013 17:40:58 +0100 Subject: [PATCH 1/3] Bug #61853 and #61921 --- ext/ldap/ldap_dev_utils.c | 87 +++++++++++++++++++++++++++++++++++++++++++++ ext/ldap/ldap_dev_utils.h | 34 ++++++++++++++++++ 2 files changed, 121 insertions(+) create mode 100644 ext/ldap/ldap_dev_utils.c create mode 100644 ext/ldap/ldap_dev_utils.h diff --git a/ext/ldap/ldap_dev_utils.c b/ext/ldap/ldap_dev_utils.c new file mode 100644 index 0000000..0a8d109 --- /dev/null +++ b/ext/ldap/ldap_dev_utils.c @@ -0,0 +1,87 @@ +#include <string.h> +#include "ldap_dev_utils.h" + +struct berval * ldu_ber_dupbv(struct berval * dst, struct berval * src) +{ + struct berval * new = NULL; + + if(src != NULL) { + if(dst == NULL) { + new = LDU_MALLOC(sizeof(*dst)); + } else { + new = dst; + } + if(new != NULL) { + if(src->bv_val == NULL) { + new->bv_val = NULL; + new->bv_len = 0; + } else { + new->bv_val = LDU_MALLOC(src->bv_len + 1); + if(new->bv_val == NULL) { + if(dst == NULL) { + LDU_FREE(new); + } + new = NULL; + } else { + memcpy(new->bv_val, src->bv_val, src->bv_len); + new->bv_val[src->bv_len] = '\0'; + new->bv_len = src->bv_len; + } + } + } + } + + return new; +} + +LDAPControl * ldu_ldap_control_create(const char * oid, int iscritical, + struct berval * value) +{ + LDAPControl * ctrl = NULL; + + if(oid != NULL) { + ctrl = LDU_CALLOC(sizeof(*ctrl), 1); + if(ctrl != NULL) { + ctrl->ldctl_iscritical = iscritical ? 1 : 0; + + if(value != NULL && ! BER_BVISNULL(value)) { + ldu_ber_dupbv( &(ctrl->ldctl_value), value); + } + + ctrl->ldctl_oid = LDU_STRDUP(oid); + if(ctrl->ldctl_oid == NULL) { + ldu_ldap_control_free(ctrl); + ctrl = NULL; + } + } + } + + return ctrl; +} + +void ldu_ldap_controls_free(LDAPControl ** ctrls) +{ + LDAPControl ** orig = ctrls; + + if(ctrls != NULL) { + while(*ctrls != NULL) { + ldu_ldap_control_free(*ctrls); + ctrls++; + } + LDU_FREE(orig); + } +} + +void ldu_ldap_control_free(LDAPControl * ctrl) +{ + if(ctrl != NULL) { + if(ctrl->ldctl_value.bv_val != NULL) { + LDU_FREE(ctrl->ldctl_value.bv_val); + } + if(ctrl->ldctl_oid != NULL) { + LDU_FREE(ctrl->ldctl_oid); + } + + LDU_FREE(ctrl); + } +} diff --git a/ext/ldap/ldap_dev_utils.h b/ext/ldap/ldap_dev_utils.h new file mode 100644 index 0000000..2591698 --- /dev/null +++ b/ext/ldap/ldap_dev_utils.h @@ -0,0 +1,34 @@ +#ifndef LDAP_DEV_UTILS_H__ +#define LDAP_DEV_UTILS_H__ + +#include <ldap.h> +#include "php.h" + + +#ifndef BER_BVISNULL +#define BER_BVISNULL(bv) ((bv)->bv_val == NULL) +#endif /* BER_BVISNULL */ + + +#ifndef LDU_MALLOC +#define LDU_MALLOC emalloc +#endif + +#ifndef LDU_CALLOC +#define LDU_CALLOC ecalloc +#endif + +#ifndef LDU_FREE +#define LDU_FREE efree +#endif + +#ifndef LDU_STRDUP +#define LDU_STRDUP estrdup +#endif + +struct berval * ldu_ber_dupbv(struct berval * dst, struct berval * src); +LDAPControl * ldu_ldap_control_create(const char * oid, int iscritical, + struct berval * value); +void ldu_ldap_controls_free(LDAPControl ** ctrls); +void ldu_ldap_control_free(LDAPControl * ctrl); +#endif /* LDAP_DEV_UTILS_H__ */ -- 1.7.10.4 From 0b2f50ed43bf212c53b3d077b5033022cf76ee96 Mon Sep 17 00:00:00 2001 From: Etienne Bagnoud <tchetch@i-james.com> Date: Sun, 24 Feb 2013 17:45:42 +0100 Subject: [PATCH 2/3] Bugs correction --- ext/ldap/config.m4 | 2 +- ext/ldap/config.w32 | 5 +- ext/ldap/ldap.c | 668 ++++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 643 insertions(+), 32 deletions(-) diff --git a/ext/ldap/config.m4 b/ext/ldap/config.m4 index 58d994c..069680c 100644 --- a/ext/ldap/config.m4 +++ b/ext/ldap/config.m4 @@ -70,7 +70,7 @@ PHP_ARG_WITH(ldap-sasl,for LDAP Cyrus SASL support, if test "$PHP_LDAP" != "no"; then - PHP_NEW_EXTENSION(ldap, ldap.c, $ext_shared,,-DLDAP_DEPRECATED=1) + PHP_NEW_EXTENSION(ldap, ldap.c ldap_dev_utils.c, $ext_shared,,) if test "$PHP_LDAP" = "yes"; then for i in /usr/local /usr; do diff --git a/ext/ldap/config.w32 b/ext/ldap/config.w32 index 2fa05f4..98bbe0c 100644 --- a/ext/ldap/config.w32 +++ b/ext/ldap/config.w32 @@ -13,15 +13,14 @@ if (PHP_LDAP != "no") { CHECK_LIB("oldap32_a.lib", "ldap", PHP_LDAP) && CHECK_LIB("olber32_a.lib", "ldap", PHP_LDAP)&& CHECK_LIB("libsasl.lib", "ldap", PHP_LDAP)) { - EXTENSION('ldap', 'ldap.c'); - + EXTENSION('ldap', 'ldap.c ldap_dev_utils.c'); + AC_DEFINE('HAVE_LDAP_PARSE_RESULT', 1); AC_DEFINE('HAVE_LDAP_PARSE_REFERENCE', 1); AC_DEFINE('HAVE_LDAP_START_TLS_S', 1); AC_DEFINE('HAVE_LDAP', 1); AC_DEFINE('HAVE_LDAP_SASL', 1); AC_DEFINE('HAVE_LDAP_SASL_SASL_H', 1); - AC_DEFINE('LDAP_DEPRECATED', 1); } else { WARNING("ldap not enabled; libraries and headers not found"); diff --git a/ext/ldap/ldap.c b/ext/ldap/ldap.c index 3cfa209..c7d0512 100644 --- a/ext/ldap/ldap.c +++ b/ext/ldap/ldap.c @@ -67,6 +67,8 @@ #include <sasl/sasl.h> #endif +#include "ldap_dev_utils.h" + typedef struct { LDAP *link; #if defined(LDAP_API_FEATURE_X_OPENLDAP) && defined(HAVE_3ARG_SETREBINDPROC) @@ -125,6 +127,435 @@ static void _free_ldap_result_entry(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ } /* }}} */ +/* {{{ _php_ber_to_array_recursive + Convert 'struct berval' to an indexed array. This function does the work + recursively as BER is a recursive data structure. + */ +static int _php_ber_to_array_recursive(BerElement * element, zval * array) +{ + int error_count = 0; + zval *new = NULL, *value = NULL, *root = NULL; + char *cookie = NULL; + ber_tag_t tag = LBER_ERROR; + ber_len_t len = 0, bitstring_len = 0, bitstring_len_bytes = 0; + ber_int_t int_value = 0; + struct berval * berval_value = NULL; + char * char_value = NULL; + div_t bits_to_bytes = {0, 0}; + + if(element != NULL && array != NULL) { + for( + tag = ber_first_element(element, &len, &cookie); + tag != LBER_ERROR; + tag = ber_next_element(element, &len, cookie)) + { + switch(tag) { + case LBER_BOOLEAN: + if( LBER_ERROR != ber_scanf(element, "b" ,&int_value)) { + ALLOC_INIT_ZVAL(value); + array_init(value); + + add_assoc_string(value, "type", "boolean", 1); + add_assoc_bool(value, "value", int_value ? 1 : 0); + + add_next_index_zval(array, value); + value = NULL; + } else { + error_count++; + } + break; + case LBER_INTEGER: + if( LBER_ERROR != ber_scanf(element, "i", &int_value)) { + ALLOC_INIT_ZVAL(value); + array_init(value); + + add_assoc_string(value, "type", "integer", 1); + add_assoc_long(value, "value", int_value); + + add_next_index_zval(array, value); + value = NULL; + } else { + add_next_index_null(array); + error_count++; + } + break; + case LBER_BITSTRING: + if( LBER_ERROR != ber_scanf( + element, + "B", + &char_value, + &bitstring_len)) { + ALLOC_INIT_ZVAL(value); + array_init(value); + + /* bitstrings length is in bits. We calculate enough + space for the whole bitstring. + */ + bits_to_bytes = div(abs(bitstring_len), 8); + bitstring_len_bytes = bits_to_bytes.quot; + if(bits_to_bytes.rem > 0) bitstring_len_bytes++; + + add_assoc_string(value, "type", "bitstring", 1); + add_assoc_stringl( + value, + "value", + char_value, + bitstring_len_bytes, + 1); + add_assoc_long(value, "lenght", bitstring_len); + + add_next_index_zval(array, value); + value = NULL; + + ber_memfree(char_value); + char_value=NULL; + } else { + error_count++; + } + break; + case LBER_OCTETSTRING: + if( LBER_ERROR != ber_scanf(element, "O", &berval_value)) { + ALLOC_INIT_ZVAL(value); + array_init(value); + + add_assoc_string(value, "type", "octetstring", 1); + add_assoc_stringl( + value, + "value", + berval_value->bv_val, + berval_value->bv_len, + 1); + add_assoc_long(value, "length", berval_value->bv_len); + + add_next_index_zval(array, value); + value = NULL; + + ber_bvfree(berval_value); + char_value = NULL; + } else { + add_next_index_null(array); + error_count++; + } + break; + case LBER_NULL: + if( LBER_ERROR != ber_scanf(element, "n")) { + ALLOC_INIT_ZVAL(value); + array_init(value); + + add_assoc_string(value, "type", "null", 1); + add_assoc_null(value, "value"); + + add_next_index_zval(array, value); + value = NULL; + } else { + add_next_index_null(array); + error_count++; + } + break; + case LBER_ENUMERATED: + if( LBER_ERROR != ber_scanf(element, "e", &int_value)) { + ALLOC_INIT_ZVAL(value); + array_init(value); + + add_assoc_string(value, "type", "enumerated", 1); + add_assoc_long(value, "value", int_value); + + add_next_index_zval(array, value); + } else { + add_next_index_null(array); + error_count++; + } + break; + /* Recursive call for sequence and set */ + case LBER_SEQUENCE: + case LBER_SET: + if(LBER_SEQUENCE == ber_scanf(element, "}") || + LBER_SET == ber_scanf(element, "]")) { + return error_count; + } + + ALLOC_INIT_ZVAL(value); + array_init(value); + + if(tag == LBER_SEQUENCE) { + add_assoc_string(value, "type", "sequence", 1); + } else { + add_assoc_string(value, "type", "set", 1); + } + + ALLOC_INIT_ZVAL(new); + array_init(new); + error_count+=_php_ber_to_array_recursive(element, new); + + add_assoc_zval(value, "value", new); + + add_next_index_zval(array, value); + new = NULL; + break; + default: break; + } + + } + } + + return error_count; +} +/* }}} + */ + +/* {{{ _php_ber_to_array + Convert 'struct berval' to an indexed array. Does some initialization then + call _php_ber_to_array_recursive. + */ +static int _php_ber_to_array(struct berval * ber, zval ** array) +{ + int error_count = -1; + ber_tag_t tag = LBER_DEFAULT; + ber_len_t len = 0; + BerElement *element = NULL; + zval *new = NULL, *root = NULL; + + if(array != NULL) { + if( ber == NULL) { + *array=NULL; + } else { + element = ber_init(ber); + if(element == NULL) { + *array=NULL; + } else { + /* First ber element is either a set or a sequence but libler + skips this firts one. We add it now. If it's not a sequence + or a set, we add a sequence anyway. + LBER_DEFAULT is returned if something's wrong. + */ + ALLOC_INIT_ZVAL(root); + array_init(root); + + tag = ber_peek_tag(element, &len); + if(tag == LBER_SET) { + add_assoc_string(root, "type", "set", 1); + } else { + add_assoc_string(root, "type", "sequence", 1); + } + + ALLOC_INIT_ZVAL(new); + array_init(new); + error_count = _php_ber_to_array_recursive(element, new); + + add_assoc_zval(root, "value", new); + + *array=root; + ber_memfree(element); + element = NULL; + } + } + } + + return error_count; +} +/* }}} + */ + +/* {{{ _php_ber_from_array_recursive + */ +static int _php_ber_from_array_recursive(HashTable * array, BerElement ** pelement) +{ + zval **data = NULL, **type = NULL, **value = NULL, **length=NULL; + HashPosition p; + HashTable * sub = NULL; + int i = 0, error_count = 0; + BerElement * element = NULL; + ber_tag_t tag = LBER_DEFAULT; + + if(pelement != NULL) { + element = *pelement; + } else { + return -1; + } + + if(array != NULL && element != NULL) { + if(zend_hash_find(array, "type", sizeof("type"), (void **) &type) != FAILURE) { + if(zend_hash_find(array, "value", sizeof("value"), (void **) &value) != FAILURE) { + convert_to_string_ex(type); + if(strncmp(Z_STRVAL_PP(type), "null", Z_STRLEN_PP(type)) == 0) { + if(LBER_ERROR == ber_printf(element, "n")) { + error_count++; + } + } else if(strncmp( + Z_STRVAL_PP(type), + "boolean", + Z_STRLEN_PP(type))==0) { + convert_to_long_ex(value); + if(LBER_ERROR == ber_printf( + element, + "b", + (ber_int_t)Z_LVAL_PP(value) ? 1 : 0)) { + error_count++; + } + } else if(strncmp( + Z_STRVAL_PP(type), + "integer", + Z_STRLEN_PP(type))==0) { + convert_to_long_ex(value); + if(LBER_ERROR == ber_printf( + element, + "i", + (ber_int_t)Z_LVAL_PP(value))) { + error_count++; + } + } else if(strncmp( + Z_STRVAL_PP(type), + "bitstring", + Z_STRLEN_PP(type))==0) { + + convert_to_string_ex(value); + if(FAILURE != zend_hash_find( + array, + "length", + sizeof("length"), + (void **) &length)) { + convert_to_long_ex(length); + + if(LBER_ERROR == ber_printf( + element, + "B", + Z_STRVAL_PP(value), + (ber_len_t)Z_LVAL_PP(length))) { + error_count++; + } + } else { + if(LBER_ERROR == ber_printf( + element, + "B", + Z_STRVAL_PP(value), + /* bistrings require number of _bits_ */ + (ber_len_t)(Z_STRLEN_PP(value) * 8))) { + error_count++; + } + } + } else if(strncmp( + Z_STRVAL_PP(type), + "octetstring", + Z_STRLEN_PP(type))==0) { + convert_to_string_ex(value); + + if(FAILURE != zend_hash_find( + array, + "length", + sizeof("length"), + (void **) &length)) { + convert_to_long_ex(length); + + if(LBER_ERROR == ber_printf( + element, + "o", + Z_STRVAL_PP(value), + (ber_len_t)Z_LVAL_PP(length))) { + error_count++; + } + } else { + if(LBER_ERROR == ber_printf( + element, + "o", + Z_STRVAL_PP(value), + (ber_len_t)Z_STRLEN_PP(value))) { + error_count++; + } + } + } else if(strncmp( + Z_STRVAL_PP(type), + "enumerated", + Z_STRLEN_PP(type)) == 0) { + convert_to_long_ex(value); + if(LBER_ERROR == ber_printf( + element, + "e", + (ber_int_t)Z_LVAL_PP(value))) { + error_count++; + } + } else if( + (strncmp(Z_STRVAL_PP(type), "sequence", Z_STRLEN_PP(type)) == 0) || + (strncmp(Z_STRVAL_PP(type), "set", Z_STRLEN_PP(type)) == 0)) { + if(Z_TYPE_PP(value) == IS_ARRAY) { + if(strncmp(Z_STRVAL_PP(type), "set", Z_STRLEN_PP(type)) == 0) { + tag = ber_printf(element, "["); + } else { + tag = ber_printf(element, "{"); + } + if(LBER_ERROR != tag) { + for( + zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(value), &p); + zend_hash_get_current_data_ex(Z_ARRVAL_PP(value), (void **) &data, &p) == SUCCESS; + zend_hash_move_forward_ex(Z_ARRVAL_PP(value), &p)) { + if(Z_TYPE_PP(data) == IS_ARRAY) { + sub = Z_ARRVAL_PP(data); + error_count+=_php_ber_from_array_recursive( + sub, + &element); + } + } + + if(strncmp(Z_STRVAL_PP(type), "set", Z_STRLEN_PP(type)) == 0) { + tag = ber_printf(element, "]"); + } else { + tag = ber_printf(element, "}"); + } + if(LBER_ERROR == tag) { + error_count++; + } + } else { + error_count++; + } + } else { + error_count++; + } + } else { + error_count++; + } + } else { + error_count++; + } + } else { + error_count++; + } + } + *pelement = element; + + return error_count; +} +/* }}} + */ + +/* {{{ _php_ber_from_array + */ +static int _php_ber_from_array(HashTable * array, struct berval ** ber) +{ + BerElement * new = NULL; + int error_count = -1; + + if(array != NULL && ber != NULL) { + new = ber_alloc_t(LBER_USE_DER); + + error_count=_php_ber_from_array_recursive(array, &new); + + if(error_count == 0) { + if(LBER_ERROR == ber_flatten(new, ber)) { + *ber = NULL; + } + } else { + *ber = NULL; + } + + ber_memfree(new); + } + return error_count; +} +/* }}} + */ + + + + /* {{{ PHP_INI_BEGIN */ PHP_INI_BEGIN() @@ -546,6 +977,10 @@ PHP_FUNCTION(ldap_unbind) /* {{{ php_set_opts */ +#if LDAP_API_VERSION > 2000 +static void php_set_opts(LDAP *ldap, int timelimit, int deref, int *old_timelimit, int *old_deref) +{ +#else static void php_set_opts(LDAP *ldap, int sizelimit, int timelimit, int deref, int *old_sizelimit, int *old_timelimit, int *old_deref) { /* sizelimit */ @@ -558,7 +993,7 @@ static void php_set_opts(LDAP *ldap, int sizelimit, int timelimit, int deref, in ldap->ld_sizelimit = sizelimit; #endif } - +#endif /* timelimit */ if (timelimit > -1) { #if (LDAP_API_VERSION >= 2004) || HAVE_NSLDAP || HAVE_ORALDAP_10 @@ -592,6 +1027,9 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope) char *ldap_base_dn = NULL, *ldap_filter = NULL, **ldap_attrs = NULL; ldap_linkdata *ld = NULL; LDAPMessage *ldap_res; +#if LDAP_API_VERSION > 2000 + LDAPControl **clientctrl = NULL, ** serverctrl = NULL; +#endif int ldap_attrsonly = 0, ldap_sizelimit = -1, ldap_timelimit = -1, ldap_deref = -1; int old_ldap_sizelimit = -1, old_ldap_timelimit = -1, old_ldap_deref = -1; int num_attribs = 0, ret = 1, i, errno, argcount = ZEND_NUM_ARGS(); @@ -706,11 +1144,46 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope) ldap_filter = Z_STRVAL_PP(entry); } - php_set_opts(ld->link, ldap_sizelimit, ldap_timelimit, ldap_deref, &old_ldap_sizelimit, &old_ldap_timelimit, &old_ldap_deref); +#if LDAP_API_VERSION > 2000 + php_set_opts(ld->link, ldap_timelimit, ldap_deref, &old_ldap_timelimit, &old_ldap_deref); + /* Fill controls. + Discouraged by documentation but there's no way to pass + controls yet. Better than nothing + */ + if(LDAP_OPT_SUCCESS != ldap_get_option( + ld->link, + LDAP_OPT_CLIENT_CONTROLS, + &clientctrl)) { + clientctrl = NULL; + } + if(LDAP_OPT_SUCCESS != ldap_get_option( + ld->link, + LDAP_OPT_SERVER_CONTROLS, + &serverctrl)) { + serverctrl = NULL; + } /* Run the actual search */ + if(LDAP_OPT_SUCCESS != ldap_search_ext( + ld->link, + ldap_base_dn, + scope, + ldap_filter, + ldap_attrs, + ldap_attrsonly, + serverctrl, + clientctrl, + NULL, /* timeval not defined, see ldap.h */ + ldap_sizelimit, + &(rcs[i]))) { + rcs[i] = -1; + } +#else + php_set_opts(ld->link, ldap_sizelimit, ldap_timelimit, ldap_deref, &old_ldap_sizelimit, &old_ldap_timelimit, &old_ldap_deref); rcs[i] = ldap_search(ld->link, ldap_base_dn, scope, ldap_filter, ldap_attrs, ldap_attrsonly); +#endif lds[i] = ld; + zend_hash_move_forward(Z_ARRVAL_P(link)); } @@ -748,11 +1221,44 @@ cleanup_parallel: goto cleanup; } - php_set_opts(ld->link, ldap_sizelimit, ldap_timelimit, ldap_deref, &old_ldap_sizelimit, &old_ldap_timelimit, &old_ldap_deref); +#if LDAP_API_VERSION > 2000 + php_set_opts(ld->link, ldap_timelimit, ldap_deref, &old_ldap_timelimit, &old_ldap_deref); + + /* Fill controls. + Discouraged by documentation but there's no way to pass + controls yet. Better than nothing + */ + if(LDAP_OPT_SUCCESS != ldap_get_option( + ld->link, + LDAP_OPT_CLIENT_CONTROLS, + &clientctrl)) { + clientctrl = NULL; + } + if(LDAP_OPT_SUCCESS != ldap_get_option( + ld->link, + LDAP_OPT_SERVER_CONTROLS, + &serverctrl)) { + serverctrl = NULL; + } /* Run the actual search */ + errno = ldap_search_ext_s( + ld->link, + ldap_base_dn, + scope, + ldap_filter, + ldap_attrs, + ldap_attrsonly, + serverctrl, + clientctrl, + NULL, /* timeval not defined, see ldap.h */ + ldap_sizelimit, + &ldap_res); +#else + php_set_opts(ld->link, ldap_sizelimit, ldap_timelimit, ldap_deref, &old_ldap_sizelimit, &old_ldap_timelimit, &old_ldap_deref); errno = ldap_search_s(ld->link, ldap_base_dn, scope, ldap_filter, ldap_attrs, ldap_attrsonly, &ldap_res); - +#endif + if (errno != LDAP_SUCCESS && errno != LDAP_SIZELIMIT_EXCEEDED #ifdef LDAP_ADMINLIMIT_EXCEEDED @@ -779,10 +1285,27 @@ cleanup_parallel: } cleanup: +#if LDAP_API_VERSION > 2000 + /* Free controls */ + if(clientctrl != NULL) { + ldap_controls_free(clientctrl); + clientctrl = NULL; + } + if(serverctrl != NULL) { + ldap_controls_free(serverctrl); + serverctrl = NULL; + } + + /* Restoring previous options */ + if (ld) { + php_set_opts(ld->link, old_ldap_timelimit, old_ldap_deref, &ldap_timelimit, &ldap_deref); + } +#else if (ld) { - /* Restoring previous options */ php_set_opts(ld->link, old_ldap_sizelimit, old_ldap_timelimit, old_ldap_deref, &ldap_sizelimit, &ldap_timelimit, &ldap_deref); } +#endif + if (ldap_attrs != NULL) { efree(ldap_attrs); } @@ -1261,6 +1784,9 @@ static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper) ldap_linkdata *ld; char *dn; LDAPMod **ldap_mods; +#if LDAP_API_VERSION > 2000 + LDAPControl **clientctrl = NULL, **serverctrl = NULL; +#endif int i, j, num_attribs, num_values, dn_len; int *num_berval; char *attribute; @@ -1344,20 +1870,49 @@ static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper) } ldap_mods[num_attribs] = NULL; +#if LDAP_API_VERSION > 2000 + if(LDAP_OPT_SUCCESS != ldap_get_option(ld->link, LDAP_OPT_CLIENT_CONTROLS, &clientctrl)) { + clientctrl = NULL; + } + if(LDAP_OPT_SUCCESS != ldap_get_option(ld->link, LDAP_OPT_SERVER_CONTROLS, &serverctrl)) { + serverctrl = NULL; + } +#endif + /* check flag to see if do_mod was called to perform full add , gerrit thomson */ if (is_full_add == 1) { +#if LDAP_API_VERSION > 2000 + if ((i = ldap_add_ext_s(ld->link, dn, ldap_mods, serverctrl, clientctrl)) != LDAP_SUCCESS) { +#else if ((i = ldap_add_s(ld->link, dn, ldap_mods)) != LDAP_SUCCESS) { +#endif 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 LDAP_API_VERSION > 2000 + if ((i = ldap_modify_ext_s(ld->link, dn, ldap_mods, serverctrl, clientctrl)) != LDAP_SUCCESS) { +#else + if ((i = ldap_modify_s(ld->link, dn, ldap_mods)) != LDAP_SUCCESS) { +#endif php_error_docref(NULL TSRMLS_CC, E_WARNING, "Modify: %s", ldap_err2string(i)); RETVAL_FALSE; } else RETVAL_TRUE; } errexit: + +#if LDAP_API_VERSION > 2000 + if(serverctrl != NULL) { + ldap_controls_free(serverctrl); + serverctrl = NULL; + } + if(clientctrl != NULL) { + ldap_controls_free(clientctrl); + clientctrl = NULL; + } +#endif + for (i = 0; i < num_attribs; i++) { efree(ldap_mods[i]->mod_type); for (j = 0; j < num_berval[i]; j++) { @@ -1659,7 +2214,10 @@ PHP_FUNCTION(ldap_set_option) ldap_linkdata *ld; LDAP *ldap; long option; - + struct berval * control_value = NULL; + int control_iscritical = 0; + char * control_oid = NULL; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zlZ", &link, &option, &newval) != SUCCESS) { return; } @@ -1778,37 +2336,55 @@ PHP_FUNCTION(ldap_set_option) error = 1; break; } - ctrl = *ctrlp = emalloc(sizeof(**ctrlp)); + convert_to_string_ex(val); - ctrl->ldctl_oid = Z_STRVAL_PP(val); + control_oid = Z_STRVAL_PP(val); if (zend_hash_find(Z_ARRVAL_PP(ctrlval), "value", sizeof("value"), (void **) &val) == SUCCESS) { - convert_to_string_ex(val); - ctrl->ldctl_value.bv_val = Z_STRVAL_PP(val); - ctrl->ldctl_value.bv_len = Z_STRLEN_PP(val); + if(Z_TYPE_PP(val) != IS_ARRAY) { + convert_to_string_ex(val); + control_value = ber_memalloc(sizeof * control_value); + if(control_value != NULL) { + control_value->bv_val = Z_STRVAL_PP(val); + control_value->bv_len = Z_STRLEN_PP(val); + } + } else { + if(_php_ber_from_array(Z_ARRVAL_PP(val), &control_value) != 0) { + if(control_value != NULL) { + ber_memfree(control_value); + control_value = NULL; + } + } + } } else { - ctrl->ldctl_value.bv_val = NULL; - ctrl->ldctl_value.bv_len = 0; + control_value = NULL; } if (zend_hash_find(Z_ARRVAL_PP(ctrlval), "iscritical", sizeof("iscritical"), (void **) &val) == SUCCESS) { convert_to_boolean_ex(val); - ctrl->ldctl_iscritical = Z_BVAL_PP(val); + control_iscritical = Z_BVAL_PP(val); } else { - ctrl->ldctl_iscritical = 0; + control_iscritical = 0; } - ++ctrlp; + if((ctrl = ldu_ldap_control_create(control_oid, + control_iscritical, control_value)) != NULL) { + *ctrlp = ctrl; + ++ctrlp; + } + + if(control_value != NULL) { + ber_memfree(control_value); + control_value = NULL; + } + *ctrlp = NULL; zend_hash_move_forward(Z_ARRVAL_PP(newval)); } if (!error) { error = ldap_set_option(ldap, option, ctrls); } - ctrlp = ctrls; - while (*ctrlp) { - efree(*ctrlp); - ctrlp++; - } - efree(ctrls); + + ldu_ldap_controls_free(ctrls); + if (error) { RETURN_FALSE; } @@ -1821,18 +2397,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, array 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, *ctrl, *php_ber; ldap_linkdata *ld; LDAPMessage *ldap_result; + LDAPControl **lserverctrls = NULL, **ctrlp = NULL; char **lreferrals, **refp; char *lmatcheddn, *lerrmsg; - int rc, lerrcode, myargcount = ZEND_NUM_ARGS(); + int rc, lerrcode, myargcount = ZEND_NUM_ARGS(), ber_decode_error_count = -1; - 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 +2420,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 +2432,40 @@ PHP_FUNCTION(ldap_parse_result) /* Reverse -> fall through */ switch (myargcount) { + case 7: + zval_dtor(serverctrls); + array_init(serverctrls); + if(lserverctrls != NULL) { + ctrlp = lserverctrls; + while (*ctrlp) { + ALLOC_INIT_ZVAL(ctrl); + array_init(ctrl); + + add_assoc_bool( + ctrl, + "critical", + (*ctrlp)->ldctl_iscritical ? 1 : 0); + + php_ber = NULL; + ber_decode_error_count = _php_ber_to_array( + &((*ctrlp)->ldctl_value), + &php_ber); + if(php_ber != NULL) { + add_assoc_zval(ctrl, "value", php_ber); + } else { + add_assoc_null(ctrl, "value"); + } + add_assoc_long( + ctrl, + "ber_error_count", + ber_decode_error_count); + add_assoc_string(ctrl, "oid", (*ctrlp)->ldctl_oid, 1); + + add_next_index_zval(serverctrls, ctrl); + ctrlp++; + } + ldap_controls_free(lserverctrls); + } case 6: zval_dtor(referrals); array_init(referrals); @@ -2614,6 +3225,7 @@ 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() #endif #endif -- 1.7.10.4 From ad7abb214011c638eefa29b40afa961aabd25b43 Mon Sep 17 00:00:00 2001 From: Etienne Bagnoud <tchetch@i-james.com> Date: Sun, 24 Feb 2013 18:03:16 +0100 Subject: [PATCH 3/3] Added licence text --- ext/ldap/ldap_dev_utils.c | 17 +++++++++++++++++ ext/ldap/ldap_dev_utils.h | 17 +++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/ext/ldap/ldap_dev_utils.c b/ext/ldap/ldap_dev_utils.c index 0a8d109..78dcb34 100644 --- a/ext/ldap/ldap_dev_utils.c +++ b/ext/ldap/ldap_dev_utils.c @@ -1,3 +1,20 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Etienne Bagnoud <etienne@lamaisondebarbie.ch> | + +----------------------------------------------------------------------+ + */ #include <string.h> #include "ldap_dev_utils.h" diff --git a/ext/ldap/ldap_dev_utils.h b/ext/ldap/ldap_dev_utils.h index 2591698..d24ca7f 100644 --- a/ext/ldap/ldap_dev_utils.h +++ b/ext/ldap/ldap_dev_utils.h @@ -1,3 +1,20 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Etienne Bagnoud <etienne@lamaisondebarbie.ch> | + +----------------------------------------------------------------------+ + */ #ifndef LDAP_DEV_UTILS_H__ #define LDAP_DEV_UTILS_H__ -- 1.7.10.4 |
Copyright © 2001-2024 The PHP Group All rights reserved. |
Last updated: Thu Nov 21 21:01:28 2024 UTC |