|
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.ch
From 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-2025 The PHP GroupAll rights reserved. |
Last updated: Fri Oct 24 14:00:01 2025 UTC |