summaryrefslogtreecommitdiff
path: root/databases/php-ldap
diff options
context:
space:
mode:
authormanu <manu>2017-05-12 08:28:12 +0000
committermanu <manu>2017-05-12 08:28:12 +0000
commit6fb1a68dce060fd94cec3562e634b0a596ec7f84 (patch)
tree0ae96fa24944e5c8edbb3b2d61298bffe42226d7 /databases/php-ldap
parent3b310409a357dc8264b159702912b0652660dedc (diff)
downloadpkgsrc-6fb1a68dce060fd94cec3562e634b0a596ec7f84.tar.gz
Update the LDAP EXOP patch to build with PHP 5.6.x
Remove the versions for retired PHP 5.4 and 5.5
Diffstat (limited to 'databases/php-ldap')
-rw-r--r--databases/php-ldap/files/ldap-ctrl-exop54.patch2271
-rw-r--r--databases/php-ldap/files/ldap-ctrl-exop55.patch2300
-rw-r--r--databases/php-ldap/files/ldap-ctrl-exop56.patch628
3 files changed, 237 insertions, 4962 deletions
diff --git a/databases/php-ldap/files/ldap-ctrl-exop54.patch b/databases/php-ldap/files/ldap-ctrl-exop54.patch
deleted file mode 100644
index 69a3a946e33..00000000000
--- a/databases/php-ldap/files/ldap-ctrl-exop54.patch
+++ /dev/null
@@ -1,2271 +0,0 @@
---- ext/ldap/ldap.c.orig 2015-09-01 22:09:37.000000000 +0200
-+++ ext/ldap/ldap.c 2015-11-08 05:12:41.000000000 +0100
-@@ -66,8 +66,13 @@
- #elif defined(HAVE_LDAP_SASL_SASL_H)
- #include <sasl/sasl.h>
- #endif
-
-+/* XXX Not detected by configure... */
-+#ifdef LDAP_EXOP_REFRESH
-+#define HAVE_LDAP_REFRESH 1
-+#endif
-+
- typedef struct {
- LDAP *link;
- #if defined(LDAP_API_FEATURE_X_OPENLDAP) && defined(HAVE_3ARG_SETREBINDPROC)
- zval *rebindproc;
-@@ -88,31 +93,46 @@
- #ifdef COMPILE_DL_LDAP
- ZEND_GET_MODULE(ldap)
- #endif
-
-+
-+/* {{{ proto void _close_ldap_link()
-+ close a connection and free LDAP resources */
- static void _close_ldap_link(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */
- {
- ldap_linkdata *ld = (ldap_linkdata *)rsrc->ptr;
-
-- ldap_unbind_s(ld->link);
--#if defined(LDAP_API_FEATURE_X_OPENLDAP) && defined(HAVE_3ARG_SETREBINDPROC)
-+ /* ldap_unbind_s() is deprecated;
-+ * the distinction between ldap_unbind() and ldap_unbind_s() is moot */
-+#ifdef LDAP_API_FEATURE_X_OPENLDAP
-+ ldap_unbind_ext(ld->link, NULL, NULL);
-+#ifdef HAVE_3ARG_SETREBINDPROC
-+
- if (ld->rebindproc != NULL) {
- zval_dtor(ld->rebindproc);
- FREE_ZVAL(ld->rebindproc);
- }
- #endif
-+#else /* ! LDAP_API_FEATURE_X_OPENLDAP */
-+ ldap_unbind_s(ld->link);
-+#endif /* ! LDAP_API_FEATURE_X_OPENLDAP */
-+
- efree(ld);
- LDAPG(num_links)--;
- }
- /* }}} */
-
-+/* {{{ proto void _free_ldap_result()
-+ free the result of an LDAP operation */
- static void _free_ldap_result(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */
- {
- LDAPMessage *result = (LDAPMessage *)rsrc->ptr;
- ldap_msgfree(result);
- }
- /* }}} */
-
-+/* {{{ proto void _free_ldap_result_entry()
-+ free an entry resulting from an LDAP search operation */
- static void _free_ldap_result_entry(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */
- {
- ldap_resultentry *entry = (ldap_resultentry *)rsrc->ptr;
-
-@@ -203,8 +223,21 @@
- REGISTER_LONG_CONSTANT("GSLC_SSL_ONEWAY_AUTH", GSLC_SSL_ONEWAY_AUTH, CONST_PERSISTENT | CONST_CS);
- REGISTER_LONG_CONSTANT("GSLC_SSL_TWOWAY_AUTH", GSLC_SSL_TWOWAY_AUTH, CONST_PERSISTENT | CONST_CS);
- #endif
-
-+#ifdef LDAP_CONTROL_PASSWORDPOLICYREQUEST
-+ REGISTER_LONG_CONSTANT("PP_passwordExpired", PP_passwordExpired, CONST_PERSISTENT | CONST_CS);
-+ REGISTER_LONG_CONSTANT("PP_accountLocked", PP_accountLocked, CONST_PERSISTENT | CONST_CS);
-+ REGISTER_LONG_CONSTANT("PP_changeAfterReset", PP_changeAfterReset, CONST_PERSISTENT | CONST_CS);
-+ REGISTER_LONG_CONSTANT("PP_passwordModNotAllowed", PP_passwordModNotAllowed, CONST_PERSISTENT | CONST_CS);
-+ REGISTER_LONG_CONSTANT("PP_mustSupplyOldPassword", PP_mustSupplyOldPassword, CONST_PERSISTENT | CONST_CS);
-+ REGISTER_LONG_CONSTANT("PP_insufficientPasswordQuality", PP_insufficientPasswordQuality, CONST_PERSISTENT | CONST_CS);
-+ REGISTER_LONG_CONSTANT("PP_passwordTooShort", PP_passwordTooShort, CONST_PERSISTENT | CONST_CS);
-+ REGISTER_LONG_CONSTANT("PP_passwordTooYoung", PP_passwordTooYoung, CONST_PERSISTENT | CONST_CS);
-+ REGISTER_LONG_CONSTANT("PP_passwordInHistory", PP_passwordInHistory, CONST_PERSISTENT | CONST_CS);
-+ REGISTER_LONG_CONSTANT("PP_noError", PP_noError, CONST_PERSISTENT | CONST_CS);
-+#endif /* LDAP_CONTROL_PASSWORDPOLICYREQUEST */
-+
- 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);
-
-@@ -285,15 +318,176 @@
- DISPLAY_INI_ENTRIES();
- }
- /* }}} */
-
-+
-+/* {{{ proto int _php_parse_referrals_resp()
-+ parse an array of LDAP referrals into a zval array */
-+static int _php_parse_referrals_resp(char ***lreferralsp, zval **referrals)
-+{
-+ int num_referrals = 0;
-+
-+ if (*lreferralsp != NULL) {
-+ char **refp = *lreferralsp;
-+
-+ while (*refp) {
-+ add_next_index_string(*referrals, *refp, 1);
-+ refp++;
-+ num_referrals++;
-+ }
-+#ifdef LDAP_API_FEATURE_X_OPENLDAP
-+ ber_memvfree((void **)*lreferralsp);
-+#else
-+ ldap_value_free(*lreferralsp);
-+#endif
-+ *lreferralsp = NULL;
-+ }
-+
-+ return num_referrals;
-+}
-+/* }}} */
-+
-+/* {{{ proto int _php_parse_controls()
-+ parse an array of zvals into an array of LDAP controls */
-+static int _php_parse_controls(zval **ctrls, LDAPControl ***lctrlsp)
-+{
-+ LDAPControl *lctrl, **lctrls, **lctrlp;
-+ zval **ctrlval, **val;
-+ int ncontrols;
-+ char error = 0;
-+
-+
-+ if ((Z_TYPE_PP(ctrls) != IS_ARRAY) || !(ncontrols = zend_hash_num_elements(Z_ARRVAL_PP(ctrls)))) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Expected non-empty array value");
-+ return 0;
-+ }
-+
-+ lctrls = safe_emalloc((1 + ncontrols), sizeof(*lctrls), 0);
-+ *lctrls = NULL;
-+ lctrlp = lctrls;
-+ zend_hash_internal_pointer_reset(Z_ARRVAL_PP(ctrls));
-+ while (zend_hash_get_current_data(Z_ARRVAL_PP(ctrls), (void**)&ctrlval) == SUCCESS) {
-+ if (Z_TYPE_PP(ctrlval) != IS_ARRAY) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "The array value must contain only arrays, where each array is a control");
-+ error = 1;
-+ break;
-+ }
-+ if (zend_hash_find(Z_ARRVAL_PP(ctrlval), "oid", sizeof("oid"), (void **) &val) == FAILURE) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Control must have an oid key");
-+ error = 1;
-+ break;
-+ }
-+ lctrl = *lctrlp = emalloc(sizeof(**lctrlp));
-+ convert_to_string_ex(val);
-+ lctrl->ldctl_oid = Z_STRVAL_PP(val);
-+ if (zend_hash_find(Z_ARRVAL_PP(ctrlval), "value", sizeof("value"), (void **) &val) == SUCCESS) {
-+ convert_to_string_ex(val);
-+ lctrl->ldctl_value.bv_val = Z_STRVAL_PP(val);
-+ lctrl->ldctl_value.bv_len = Z_STRLEN_PP(val);
-+ } else {
-+ lctrl->ldctl_value.bv_val = NULL;
-+ lctrl->ldctl_value.bv_len = 0;
-+ }
-+ if (zend_hash_find(Z_ARRVAL_PP(ctrlval), "iscritical", sizeof("iscritical"), (void **) &val) == SUCCESS) {
-+ convert_to_boolean_ex(val);
-+ lctrl->ldctl_iscritical = Z_BVAL_PP(val);
-+ } else {
-+ lctrl->ldctl_iscritical = 0;
-+ }
-+
-+ ++lctrlp;
-+ *lctrlp = NULL;
-+ zend_hash_move_forward(Z_ARRVAL_PP(ctrls));
-+ }
-+ if (!error) {
-+ *lctrlsp = lctrls;
-+ }
-+ return ncontrols;
-+}
-+/* }}} */
-+
-+/* {{{ proto void _php_free_controls()
-+ frees an array of LDAP controls as parsed (and malloc'ed) by _php_parse_controls */
-+static void _php_free_controls(LDAPControl ***lctrlsp)
-+{
-+ LDAPControl **lctrlp;
-+
-+ for (lctrlp = *lctrlsp; *lctrlp; lctrlp++) {
-+ efree(*lctrlp);
-+ }
-+ efree(*lctrlsp);
-+ *lctrlsp = NULL;
-+}
-+/* }}} */
-+
-+/* {{{ proto void _php_parse_controls_resp()
-+ parse an array of LDAP controls into a zval array */
-+static int _php_parse_controls_resp(LDAPControl ***lctrlsp, zval **ctrls)
-+{
-+ int num_ctrls = 0;
-+
-+ if (*lctrlsp != NULL) {
-+ int error = 0;
-+ LDAPControl **ctrlp = *lctrlsp;
-+
-+ while (*ctrlp) {
-+ zval *ctrlval = NULL;
-+
-+ if ( (*ctrlp)->ldctl_oid == NULL ) {
-+ error = 1;
-+ break;
-+ }
-+
-+ MAKE_STD_ZVAL(ctrlval);
-+ array_init(ctrlval);
-+
-+ add_assoc_string(ctrlval, "oid", (*ctrlp)->ldctl_oid, 1);
-+ if ( (*ctrlp)->ldctl_value.bv_len ) {
-+ add_assoc_stringl(ctrlval, "value", (*ctrlp)->ldctl_value.bv_val, (*ctrlp)->ldctl_value.bv_len, 1);
-+ }
-+
-+ /* As per <draft-ietf-ldapbis-protocol>:
-+ *
-+ * 4.1.11
-+
-+ The criticality field only has meaning in controls attached to
-+ request messages (except UnbindRequest). For controls attached to
-+ response messages and the UnbindRequest, the criticality field SHOULD
-+ be FALSE, and MUST be ignored by the receiving protocol peer.
-+
-+ */
-+
-+ add_next_index_zval(*ctrls, ctrlval);
-+
-+ num_ctrls++;
-+ ctrlp++;
-+ }
-+ ldap_controls_free(*lctrlsp);
-+ *lctrlsp = NULL;
-+
-+ if (error) {
-+ /* ... */
-+ return -1;
-+ }
-+ }
-+
-+ return num_ctrls;
-+}
-+/* }}} */
-+
- /* {{{ proto resource ldap_connect([string host [, int port [, string wallet [, string wallet_passwd [, int authmode]]]]])
- Connect to an LDAP server */
- PHP_FUNCTION(ldap_connect)
- {
- char *host = NULL;
- int hostlen;
-- long port = 389; /* Default port */
-+ int port =
-+#ifdef LDAP_API_FEATURE_X_OPENLDAP
-+ LDAP_PORT
-+#else /* ! LDAP_API_FEATURE_X_OPENLDAP */
-+ 389 /* Default port */
-+#endif /* ! LDAP_API_FEATURE_X_OPENLDAP */
-+ ;
- #ifdef HAVE_ORALDAP
- char *wallet = NULL, *walletpasswd = NULL;
- int walletlen = 0, walletpasswdlen = 0;
- long authmode = GSLC_SSL_NO_AUTH;
-@@ -327,23 +521,41 @@
-
- ld = ecalloc(1, sizeof(ldap_linkdata));
-
- #ifdef LDAP_API_FEATURE_X_OPENLDAP
-- if (host != NULL && strchr(host, '/')) {
-- int rc;
-+ /* OpenLDAP provides a specific call to detect valid LDAP URIs;
-+ * ldap_init()/ldap_open() is deprecated, use ldap_initialize() instead.
-+ */
-+ {
-+ int rc;
-+ char *url = host;
-+
-+ if (!ldap_is_ldap_url(url)) {
-+ int urllen = hostlen + sizeof( "ldap://:65535" );
-+
-+ if (port <= 0 || port > 65535) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid port number: %ld", port);
-+ RETURN_FALSE;
-+ }
-+
-+ url = emalloc(urllen);
-+ snprintf( url, urllen, "ldap://%s:%d", host ? host : "", port );
-+ }
-
-- rc = ldap_initialize(&ldap, host);
-+ rc = ldap_initialize(&ldap, url);
- if (rc != LDAP_SUCCESS) {
- efree(ld);
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not create session handle: %s", ldap_err2string(rc));
- RETURN_FALSE;
- }
-- } else {
-- ldap = ldap_init(host, port);
-+
-+ if (url != host) {
-+ efree(url);
-+ }
- }
--#else
-+#else /* ! LDAP_API_FEATURE_X_OPENLDAP */
- ldap = ldap_open(host, port);
--#endif
-+#endif /* ! LDAP_API_FEATURE_X_OPENLDAP */
-
- if (ldap == NULL) {
- efree(ld);
- RETURN_FALSE;
-@@ -429,17 +641,33 @@
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Password contains a null byte");
- RETURN_FALSE;
- }
-
-- if ((rc = ldap_bind_s(ld->link, ldap_bind_dn, ldap_bind_pw, LDAP_AUTH_SIMPLE)) != LDAP_SUCCESS) {
-+#ifdef LDAP_API_FEATURE_X_OPENLDAP
-+ {
-+ struct berval cred;
-+
-+ /* ldap_bind_s() is deprecated; use ldap_sasl_bind_s() instead */
-+ cred.bv_val = ldap_bind_pw;
-+ cred.bv_len = ldap_bind_pw ? ldap_bind_pwlen : 0;
-+ rc = ldap_sasl_bind_s(ld->link, ldap_bind_dn, LDAP_SASL_SIMPLE, &cred,
-+ NULL, NULL, /* no controls right now */
-+ NULL); /* we don't care about the server's credentials */
-+ }
-+#else
-+ rc = ldap_bind_s(ld->link, ldap_bind_dn, ldap_bind_pw, LDAP_AUTH_SIMPLE);
-+#endif
-+ if ( rc != LDAP_SUCCESS) {
-+
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to bind to server: %s", ldap_err2string(rc));
- RETURN_FALSE;
- } else {
- RETURN_TRUE;
- }
- }
- /* }}} */
-
-+/* {{{ SASL bind stuff */
- #ifdef HAVE_LDAP_SASL
- typedef struct {
- char *mech;
- char *realm;
-@@ -510,8 +738,10 @@
- break;
- case SASL_CB_USER:
- p = ctx->authzid;
- break;
-+ case SASL_CB_ECHOPROMPT:
-+ case SASL_CB_NOECHOPROMPT:
- case SASL_CB_PASS:
- p = ctx->passwd;
- break;
- }
-@@ -562,8 +792,9 @@
- _php_sasl_freedefs(ctx);
- }
- /* }}} */
- #endif /* HAVE_LDAP_SASL */
-+/* }}} */
-
- /* {{{ proto bool ldap_unbind(resource link)
- Unbind from LDAP directory */
- PHP_FUNCTION(ldap_unbind)
-@@ -1259,9 +1490,14 @@
- for (i = 0; i<count; i++) {
- add_index_string(return_value, i, ldap_value[i], 1);
- }
-
-+#ifdef LDAP_API_FEATURE_X_OPENLDAP
-+ /* ldap_value_free() is deprecated */
-+ ber_memvfree((void **)ldap_value);
-+#else /* ! LDAP_API_FEATURE_X_OPENLDAP */
- ldap_value_free(ldap_value);
-+#endif /* ! LDAP_API_FEATURE_X_OPENLDAP */
- }
- /* }}} */
-
- /* {{{ proto string ldap_dn2ufn(string dn)
-@@ -1292,38 +1528,67 @@
- /* added to fix use of ldap_modify_add for doing an ldap_add, gerrit thomson. */
- #define PHP_LD_FULL_ADD 0xff
- /* {{{ php_ldap_do_modify
- */
--static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper)
-+static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper, int ext)
- {
-- zval *link, *entry, **value, **ivalue;
-+ zval *link, *entry, **value, **ivalue, **sctrls, **cctrls;
- ldap_linkdata *ld;
- char *dn;
- LDAPMod **ldap_mods;
- 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 */
-+ int rc, msgid, myargcount = ZEND_NUM_ARGS();
-+ LDAPMessage *ldap_res;
-+ LDAPControl **lsctrls = NULL, **lcctrls = NULL;
-+ if (ext) {
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsaZZ", &link, &dn, &dn_len, &entry, &sctrls, &cctrls) != SUCCESS)
-+ WRONG_PARAM_COUNT;
-+ } else {
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsa", &link, &dn, &dn_len, &entry) != SUCCESS)
-+ WRONG_PARAM_COUNT;
-+ }
-
-- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsa", &link, &dn, &dn_len, &entry) != SUCCESS) {
-- return;
-- }
-+ if (Z_TYPE_PP(&entry) != IS_ARRAY) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Expected Array as the last element");
-+ RETURN_FALSE;
-+ }
-
-- ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
-
-- num_attribs = zend_hash_num_elements(Z_ARRVAL_P(entry));
-- ldap_mods = safe_emalloc((num_attribs+1), sizeof(LDAPMod *), 0);
-- num_berval = safe_emalloc(num_attribs, sizeof(int), 0);
-- zend_hash_internal_pointer_reset(Z_ARRVAL_P(entry));
-
- /* added by gerrit thomson to fix ldap_add using ldap_mod_add */
- if (oper == PHP_LD_FULL_ADD) {
- oper = LDAP_MOD_ADD;
- is_full_add = 1;
- }
- /* end additional , gerrit thomson */
-
-+ if (myargcount > 3) {
-+ if (is_full_add) {
-+#ifndef HAVE_LDAP_ADD_EXT_S
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "ldap_add_ext not available");
-+ RETURN_FALSE;
-+#endif /* ! HAVE_LDAP_ADD_EXT_S */
-+
-+ } else {
-+#ifndef HAVE_LDAP_MODIFY_EXT_S
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "ldap_modify_ext not available");
-+ RETURN_FALSE;
-+#endif /* ! HAVE_LDAP_MODIFY_EXT_S */
-+ }
-+ }
-+
-+ ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
-+
-+ num_attribs = zend_hash_num_elements(Z_ARRVAL_P(entry));
-+ ldap_mods = safe_emalloc((num_attribs+1), sizeof(LDAPMod *), 0);
-+ num_berval = safe_emalloc(num_attribs, sizeof(int), 0);
-+ zend_hash_internal_pointer_reset(Z_ARRVAL_P(entry));
-+
-+
- for (i = 0; i < num_attribs; i++) {
- ldap_mods[i] = emalloc(sizeof(LDAPMod));
- ldap_mods[i]->mod_op = oper | LDAP_MOD_BVALUES;
- ldap_mods[i]->mod_type = NULL;
-@@ -1381,19 +1646,78 @@
- zend_hash_move_forward(Z_ARRVAL_P(entry));
- }
- ldap_mods[num_attribs] = NULL;
-
-+ if (ext) {
-+ switch (myargcount) {
-+ case 5:
-+ if (_php_parse_controls(cctrls, &lcctrls) == 0) {
-+ RETVAL_FALSE;
-+ goto errexit;
-+ }
-+
-+ case 4:
-+ if (_php_parse_controls(sctrls, &lsctrls) == 0) {
-+ RETVAL_FALSE;
-+ goto errexit;
-+ }
-+ }
-+ }
-+
- /* 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) {
-- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Add: %s", ldap_err2string(i));
-- RETVAL_FALSE;
-- } else RETVAL_TRUE;
-+#ifdef HAVE_LDAP_ADD_EXT_S
-+ if (ext) {
-+ rc = ldap_add_ext(ld->link, dn, ldap_mods, lsctrls, lcctrls, &msgid);
-+
-+ } else {
-+ rc = ldap_add_ext_s(ld->link, dn, ldap_mods, NULL, NULL);
-+ }
-+#else /* ! HAVE_LDAP_ADD_EXT_S */
-+ rc = ldap_add_s(ld->link, dn, ldap_mods);
-+#endif /* ! HAVE_LDAP_ADD_EXT_S */
-+
- } else {
-- if ((i = ldap_modify_ext_s(ld->link, dn, ldap_mods, NULL, NULL)) != LDAP_SUCCESS) {
-- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Modify: %s", ldap_err2string(i));
-- RETVAL_FALSE;
-- } else RETVAL_TRUE;
-+#ifdef HAVE_LDAP_MODIFY_EXT_S
-+ if (ext) {
-+ rc = ldap_modify_ext(ld->link, dn, ldap_mods, lsctrls, lcctrls, &msgid);
-+
-+ } else {
-+ rc = ldap_modify_ext_s(ld->link, dn, ldap_mods, NULL, NULL);
-+ }
-+#else /* ! HAVE_LDAP_MODIFY_EXT_S */
-+ rc = ldap_modify_s(ld->link, dn, ldap_mods);
-+#endif /* ! HAVE_LDAP_MODIFY_EXT_S */
-+ }
-+
-+ if (rc != LDAP_SUCCESS) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s: %s", is_full_add ? "Add" : "Modify", ldap_err2string(i));
-+ RETVAL_FALSE;
-+
-+ } else {
-+ if (ext) {
-+ rc = ldap_result(ld->link, msgid, LDAP_MSG_ALL, NULL, &ldap_res);
-+ if ((is_full_add && rc != LDAP_RES_ADD) || (!is_full_add && rc != LDAP_RES_MODIFY)) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s: unable to collect result", is_full_add ? "Add" : "Modify");
-+ RETVAL_FALSE;
-+
-+ } else {
-+ int lerr;
-+
-+ ZEND_REGISTER_RESOURCE(return_value, ldap_res, le_result);
-+ rc = ldap_parse_result(ld->link, ldap_res, &lerr, NULL, NULL, NULL, NULL, 0);
-+ if (rc == LDAP_SUCCESS) {
-+ rc = lerr;
-+ }
-+
-+ if (rc != LDAP_SUCCESS) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s failed: %s", is_full_add ? "Add" : "Modify", ldap_err2string(rc));
-+ }
-+ }
-+
-+ } else {
-+ RETVAL_TRUE;
-+ }
- }
-
- errexit:
- for (i = 0; i < num_attribs; i++) {
-@@ -1406,46 +1730,57 @@
- }
- efree(num_berval);
- efree(ldap_mods);
-
-+ if (ext) {
-+ if (lsctrls) {
-+ _php_free_controls(&lsctrls);
-+ }
-+ if (lcctrls) {
-+ _php_free_controls(&lcctrls);
-+ }
-+ }
-+
- return;
- }
- /* }}} */
-
- /* {{{ proto bool ldap_add(resource link, string dn, array entry)
- Add entries to LDAP directory */
- 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);
-+ /* 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, 0);
- }
- /* }}} */
-
--/* three functions for attribute base modifications, gerrit Thomson */
-+/* {{{ Three functions for attribute base modifications, gerrit Thomson */
-
- /* {{{ proto bool ldap_mod_replace(resource link, string dn, array entry)
- 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);
- }
- /* }}} */
-
- /* {{{ proto bool ldap_mod_add(resource link, string dn, array entry)
- 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);
- }
- /* }}} */
-
- /* {{{ proto bool ldap_mod_del(resource link, string dn, array entry)
-+
- 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);
- }
- /* }}} */
-+/* }}} */
-
- /* {{{ proto bool ldap_delete(resource link, string dn)
- Delete an entry from a directory */
- PHP_FUNCTION(ldap_delete)
-@@ -1869,38 +2204,109 @@
- RETURN_STRING(ldap_err2string(ld_errno), 1);
- }
- /* }}} */
-
--/* {{{ proto bool ldap_compare(resource link, string dn, string attr, string value)
-- Determine if an entry has a specific value for one of its attributes */
--PHP_FUNCTION(ldap_compare)
-+/* {{{ proto void php_ldap_do_compare */
-+void php_ldap_do_compare(INTERNAL_FUNCTION_PARAMETERS, int ext)
- {
-- zval *link;
-- char *dn, *attr, *value;
-+ zval *link, *dn, *attr, *value, **sctrls, **cctrls;
-+ char *ldap_dn, *ldap_attr;
- int dn_len, attr_len, value_len;
- ldap_linkdata *ld;
-- int errno;
-+ int rc, msgid, lerr, myargcount = ZEND_NUM_ARGS();
-+ LDAPMessage *ldap_res;
-+ LDAPControl **lsctrls = NULL, **lcctrls = NULL;
-
-- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsss", &link, &dn, &dn_len, &attr, &attr_len, &value, &value_len) != SUCCESS) {
-- return;
-+ if (ext) {
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsss|ZZ", &link, &dn, &dn_len, &attr, &attr_len, &value, &value_len, &sctrls, &cctrls) != SUCCESS) {
-+ WRONG_PARAM_COUNT;
-+ }
-+ } else {
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsss", &link, &dn, &dn_len, &attr, &attr_len, &value, &value_len) != SUCCESS) {
-+ WRONG_PARAM_COUNT;
-+ }
- }
-
- ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
-
-- errno = ldap_compare_s(ld->link, dn, attr, value);
--
-- switch (errno) {
-- case LDAP_COMPARE_TRUE:
-- RETURN_TRUE;
-- break;
-+ if (ext) {
-+ struct berval ldap_bvalue;
-+ switch (myargcount) {
-+ case 6:
-+ _php_parse_controls(cctrls, &lcctrls);
-+ case 5:
-+ _php_parse_controls(sctrls, &lsctrls);
-+ }
-
-- case LDAP_COMPARE_FALSE:
-+ ldap_bvalue.bv_val = Z_STRVAL_PP(&value);
-+ ldap_bvalue.bv_len = Z_STRLEN_PP(&value);
-+ rc = ldap_compare_ext(ld->link, ldap_dn, ldap_attr, &ldap_bvalue, lsctrls, lcctrls, &msgid);
-+ if (lsctrls) {
-+ _php_free_controls(&lsctrls);
-+ }
-+ if (lcctrls) {
-+ _php_free_controls(&lcctrls);
-+ }
-+ if (rc != LDAP_SUCCESS) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Compare: %s", ldap_err2string(rc));
- RETURN_FALSE;
-- break;
-+ }
-+
-+ rc = ldap_result(ld->link, msgid, LDAP_MSG_ALL, NULL, &ldap_res);
-+ if (rc != LDAP_RES_COMPARE) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Compare: unable to get result");
-+ RETURN_FALSE;
-+ }
-+
-+ ZEND_REGISTER_RESOURCE(return_value, ldap_res, le_result);
-+ rc = ldap_parse_result(ld->link, ldap_res, &lerr, NULL, NULL, NULL, NULL, 0);
-+ if (rc == LDAP_SUCCESS) {
-+ rc = lerr;
-+ }
-+
-+ switch (rc) {
-+ case LDAP_COMPARE_TRUE:
-+ case LDAP_COMPARE_FALSE:
-+ break;
-+
-+ default:
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Compare failed: %s", ldap_err2string(rc));
-+ break;
-+ }
-+
-+ } else {
-+#ifdef HAVE_LDAP_COMPARE_EXT_S
-+ struct berval ldap_bvalue;
-+
-+ ldap_bvalue.bv_val = Z_STRVAL_PP(&value);
-+ ldap_bvalue.bv_len = Z_STRLEN_PP(&value);
-+ rc = ldap_compare_ext_s(ld->link, ldap_dn, ldap_attr, &ldap_bvalue, NULL, NULL);
-+#else /* ! HAVE_LDAP_COMPARE_EXT_S */
-+ char *ldap_value;
-+
-+ ldap_value = Z_STRVAL_PP(&value);
-+ rc = ldap_compare_s(ld->link, ldap_dn, ldap_attr, ldap_value);
-+#endif /* ! HAVE_LDAP_COMPARE_EXT_S */
-+
-+ switch (rc) {
-+ case LDAP_COMPARE_TRUE:
-+ RETURN_TRUE;
-+ break;
-+
-+ case LDAP_COMPARE_FALSE:
-+ RETURN_FALSE;
-+ break;
-+ }
-+
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Compare: %s", ldap_err2string(rc));
-+ RETURN_LONG(-1);
- }
--
-- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Compare: %s", ldap_err2string(errno));
-- RETURN_LONG(-1);
-+}
-+/* {{{ proto bool ldap_compare(resource link, string dn, string attr, string valu)
-+ Determine if an entry has a specific value for one of its attributes */
-+PHP_FUNCTION(ldap_compare)
-+{
-+ php_ldap_do_compare(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
- }
- /* }}} */
-
- /* {{{ proto bool ldap_sort(resource link, resource result, string sortfilter)
-@@ -1932,59 +2338,233 @@
- RETURN_TRUE;
- }
- /* }}} */
-
--#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10
--/* {{{ proto bool ldap_get_option(resource link, int option, mixed retval)
-- Get the current value of various session-wide parameters */
--PHP_FUNCTION(ldap_get_option)
-+/* {{{ Extended API that returns result instead of just bool
-+ * to allow further manipulation by the ldap_parse_*() funcs,
-+ * Pierangelo Masarati */
-+
-+/* {{{ proto result ldap_bind_ext(resource link [, string dn, string password])
-+ Bind to LDAP directory */
-+PHP_FUNCTION(ldap_bind_ext)
- {
-- zval *link, *retval;
-+ zval *link;
-+ char *ldap_bind_dn = NULL, *ldap_bind_pw = NULL;
-+ int ldap_bind_dnlen, ldap_bind_pwlen;
- ldap_linkdata *ld;
-- long option;
--
-- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rlz", &link, &option, &retval) != SUCCESS) {
-- return;
-+ int rc, msgid, lerr;
-+ LDAPMessage *ldap_res;
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|ss", &link, &ldap_bind_dn, &ldap_bind_dnlen, &ldap_bind_pw, &ldap_bind_pwlen) == FAILURE) {
-+
-+ RETURN_FALSE;
- }
-
- ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
-
-- switch (option) {
-- /* options with int value */
-- case LDAP_OPT_DEREF:
-- case LDAP_OPT_SIZELIMIT:
-- case LDAP_OPT_TIMELIMIT:
-- case LDAP_OPT_PROTOCOL_VERSION:
-- case LDAP_OPT_ERROR_NUMBER:
-- case LDAP_OPT_REFERRALS:
--#ifdef LDAP_OPT_RESTART
-- case LDAP_OPT_RESTART:
-+#ifdef LDAP_API_FEATURE_X_OPENLDAP
-+ {
-+ struct berval cred;
-+
-+ /* ldap_bind() is deprecated; use ldap_sasl_bind() instead */
-+ cred.bv_val = ldap_bind_pw;
-+ cred.bv_len = ldap_bind_pw ? ldap_bind_pwlen : 0;
-+
-+ rc = ldap_sasl_bind(ld->link, ldap_bind_dn, LDAP_SASL_SIMPLE, &cred,
-+ NULL, NULL, /* no controls right now */
-+ &msgid);
-+ if (rc != LDAP_SUCCESS) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to bind: %s", ldap_err2string(rc));
-+ RETURN_FALSE;
-+ }
-+ }
-+#else
-+ msgid = ldap_bind(ld->link, ldap_bind_dn, ldap_bind_pw, LDAP_AUTH_SIMPLE);
-+ if (msgid == -1) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to bind");
-+ RETURN_FALSE;
-+ }
- #endif
-- {
-- int val;
-
-- if (ldap_get_option(ld->link, option, &val)) {
-- RETURN_FALSE;
-- }
-- zval_dtor(retval);
-- ZVAL_LONG(retval, val);
-- } break;
--#ifdef LDAP_OPT_NETWORK_TIMEOUT
-- case LDAP_OPT_NETWORK_TIMEOUT:
-- {
-- struct timeval *timeout = NULL;
-+ rc = ldap_result(ld->link, msgid, LDAP_MSG_ALL, NULL, &ldap_res);
-+ if (rc != LDAP_RES_BIND) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to get bind result: %s", ldap_err2string(rc));
-+ RETURN_FALSE;
-+ }
-
-- if (ldap_get_option(ld->link, LDAP_OPT_NETWORK_TIMEOUT, (void *) &timeout)) {
-- if (timeout) {
-- ldap_memfree(timeout);
-- }
-- RETURN_FALSE;
-- }
-- if (!timeout) {
-- RETURN_FALSE;
-- }
-- zval_dtor(retval);
-- ZVAL_LONG(retval, timeout->tv_sec);
-+ ZEND_REGISTER_RESOURCE(return_value, ldap_res, le_result);
-+ rc = ldap_parse_result(ld->link, ldap_res, &lerr, NULL, NULL, NULL, NULL, 0);
-+ if (rc == LDAP_SUCCESS) {
-+ rc = lerr;
-+ }
-+
-+
-+ if (rc != LDAP_SUCCESS) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to bind to server: %s", ldap_err2string(rc));
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto result ldap_add_ext(resource link, string dn, array entry)
-+ Add entries to LDAP directory; returns result */
-+PHP_FUNCTION(ldap_add_ext)
-+{
-+ php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_LD_FULL_ADD, 1);
-+}
-+/* }}} */
-+
-+/* {{{ proto result ldap_mod_replace_ext(resource link, string dn, array entry)
-+ Replace attribute values with new ones */
-+PHP_FUNCTION(ldap_mod_replace_ext)
-+{
-+ php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_MOD_REPLACE, 1);
-+}
-+/* }}} */
-+
-+
-+/* {{{ proto result ldap_mod_add_ext(resource link, string dn, array entry)
-+ Add attribute values to current */
-+PHP_FUNCTION(ldap_mod_add_ext)
-+{
-+ php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_MOD_ADD, 1);
-+}
-+/* }}} */
-+
-+/* {{{ proto result ldap_mod_del_ext(resource link, string dn, array entry)
-+ Delete attribute values */
-+PHP_FUNCTION(ldap_mod_del_ext)
-+{
-+ php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_MOD_DELETE, 1);
-+}
-+/* }}} */
-+
-+/* {{{ proto result ldap_delete_ext(resource link, string dn)
-+ Delete an entry from a directory */
-+PHP_FUNCTION(ldap_delete_ext)
-+{
-+ zval **link, **dn, **sctrls, **cctrls;
-+ ldap_linkdata *ld;
-+ char *ldap_dn;
-+ int rc, dn_len, msgid, lerr, myargcount = ZEND_NUM_ARGS();
-+ LDAPMessage *ldap_res;
-+ LDAPControl **lsctrls = NULL, **lcctrls = NULL;
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|ZZ", &link, &dn, &dn_len, &sctrls, &cctrls) == FAILURE) {
-+ WRONG_PARAM_COUNT;
-+ }
-+
-+ switch (myargcount) {
-+ case 4:
-+ _php_parse_controls(cctrls, &lcctrls);
-+
-+ case 3:
-+ _php_parse_controls(sctrls, &lsctrls);
-+ }
-+
-+ ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, link, -1, "ldap link", le_link);
-+
-+ convert_to_string_ex(dn);
-+ ldap_dn = Z_STRVAL_PP(dn);
-+
-+#ifdef HAVE_LDAP_DELETE_EXT_S
-+ rc = ldap_delete_ext_s(ld->link, ldap_dn, NULL, NULL);
-+#else /* ! HAVE_LDAP_DELETE_EXT_S */
-+ rc = ldap_delete_s(ld->link, ldap_dn);
-+#endif /* ! HAVE_LDAP_DELETE_EXT_S */
-+ if (lsctrls) {
-+ _php_free_controls(&lsctrls);
-+ }
-+ if (lcctrls) {
-+ _php_free_controls(&lcctrls);
-+ }
-+ if (rc != LDAP_SUCCESS) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Delete: %s", ldap_err2string(rc));
-+ RETURN_FALSE;
-+ }
-+
-+ rc = ldap_result(ld->link, msgid, LDAP_MSG_ALL, NULL, &ldap_res);
-+ if (rc != LDAP_RES_DELETE) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Delete: unable to get result");
-+ RETURN_FALSE;
-+ }
-+
-+ ZEND_REGISTER_RESOURCE(return_value, ldap_res, le_result);
-+ rc = ldap_parse_result(ld->link, ldap_res, &lerr, NULL, NULL, NULL, NULL, 0);
-+ if (rc == LDAP_SUCCESS) {
-+ rc = lerr;
-+ }
-+
-+ if (rc != LDAP_SUCCESS) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Delete failed: %s", ldap_err2string(rc));
-+ }
-+}
-+/* }}} */
-+
-+/* }}} End of extended API, Pierangelo Masarati */
-+
-+
-+/* {{{ proto result ldap_compare_ext(resource link, string dn, string attr, string value)
-+ Determine if an entry has a specific value for one of its attributes */
-+PHP_FUNCTION(ldap_compare_ext)
-+{
-+ php_ldap_do_compare(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
-+}
-+/* }}} */
-+
-+/* }}} End of extended API, Pierangelo Masarati */
-+
-+
-+#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10
-+/* {{{ proto bool ldap_get_option(resource link, int option, mixed retval)
-+ Get the current value of various session-wide parameters */
-+PHP_FUNCTION(ldap_get_option)
-+{
-+ zval *link, *retval;
-+ ldap_linkdata *ld;
-+ long option;
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rlz", &link, &option, &retval) != SUCCESS) {
-+ return;
-+ }
-+
-+ ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
-+
-+ switch (option) {
-+ /* options with int value */
-+ case LDAP_OPT_DEREF:
-+ case LDAP_OPT_SIZELIMIT:
-+ case LDAP_OPT_TIMELIMIT:
-+ case LDAP_OPT_PROTOCOL_VERSION:
-+ case LDAP_OPT_ERROR_NUMBER:
-+ case LDAP_OPT_REFERRALS:
-+#ifdef LDAP_OPT_RESTART
-+ case LDAP_OPT_RESTART:
-+#endif
-+ {
-+ int val;
-+
-+ if (ldap_get_option(ld->link, option, &val)) {
-+ RETURN_FALSE;
-+ }
-+ zval_dtor(retval);
-+ ZVAL_LONG(retval, val);
-+ } break;
-+#ifdef LDAP_OPT_NETWORK_TIMEOUT
-+ case LDAP_OPT_NETWORK_TIMEOUT:
-+ {
-+ struct timeval *timeout = NULL;
-+
-+ if (ldap_get_option(ld->link, LDAP_OPT_NETWORK_TIMEOUT, (void *) &timeout)) {
-+ if (timeout) {
-+ ldap_memfree(timeout);
-+ }
-+ RETURN_FALSE;
-+ }
-+ if (!timeout) {
-+ RETURN_FALSE;
-+ }
-+ zval_dtor(retval);
-+ ZVAL_LONG(retval, timeout->tv_sec);
- ldap_memfree(timeout);
- } break;
- #elif defined(LDAP_X_OPT_CONNECT_TIMEOUT)
- case LDAP_X_OPT_CONNECT_TIMEOUT:
-@@ -2207,21 +2787,23 @@
- }
- /* }}} */
-
- #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;
- ldap_linkdata *ld;
- LDAPMessage *ldap_result;
-- char **lreferrals, **refp;
-+ LDAPControl **lserverctrls;
-+ char **lreferrals;
- char *lmatcheddn, *lerrmsg;
- int rc, lerrcode, myargcount = ZEND_NUM_ARGS();
-+ /* int matcheddn_len, errmsg_len; */
-
-- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rrz|zzz", &link, &result, &errcode, &matcheddn, &errmsg, &referrals) != SUCCESS) {
-- return;
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rrz|zzzz", &link, &result, &errcode, &matcheddn, &errmsg, &referrals, &serverctrls) != SUCCESS) {
-+ WRONG_PARAM_COUNT;
- }
-
- ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
- ZEND_FETCH_RESOURCE(ldap_result, LDAPMessage *, &result, -1, "ldap result", le_result);
-@@ -2229,9 +2811,9 @@
- rc = ldap_parse_result(ld->link, ldap_result, &lerrcode,
- 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));
- RETURN_FALSE;
-@@ -2241,19 +2823,15 @@
- ZVAL_LONG(errcode, lerrcode);
-
- /* Reverse -> fall through */
- switch (myargcount) {
-+ case 7:
-+ /* use arg #7 as the array of controls returned by the server */
-+ zval_dtor(serverctrls);
-+ array_init(serverctrls);
-+ _php_parse_controls_resp(&lserverctrls, &serverctrls);
- case 6:
-- zval_dtor(referrals);
-- array_init(referrals);
-- if (lreferrals != NULL) {
-- refp = lreferrals;
-- while (*refp) {
-- add_next_index_string(referrals, *refp, 1);
-- refp++;
-- }
-- ldap_value_free(lreferrals);
-- }
-+ _php_parse_referrals_resp(&lreferrals, &referrals);
- case 5:
- zval_dtor(errmsg);
- if (lerrmsg == NULL) {
- ZVAL_EMPTY_STRING(errmsg);
-@@ -2274,8 +2852,142 @@
- }
- /* }}} */
- #endif
-
-+/* {{{ Extended operation response parsing, Pierangelo Masarati */
-+#ifdef HAVE_LDAP_PARSE_EXTENDED_RESULT
-+/* {{{ proto bool ldap_parse_exop(resource link, resource result [, string retoid [, string retdata]])
-+ Extract information from extended operation result */
-+PHP_FUNCTION(ldap_parse_exop)
-+{
-+ zval *link, *result, *retoid, *retdata;
-+ ldap_linkdata *ld;
-+ LDAPMessage *ldap_result;
-+ char *lretoid;
-+ struct berval *lretdata;
-+ int rc, myargcount = ZEND_NUM_ARGS();
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rr|zz", &link, &result, &retoid, &retdata) == SUCCESS) {
-+ WRONG_PARAM_COUNT;
-+ }
-+
-+ ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
-+ ZEND_FETCH_RESOURCE(ldap_result, LDAPMessage *, &result, -1, "ldap result", le_result);
-+
-+ rc = ldap_parse_extended_result(ld->link, ldap_result,
-+ myargcount > 2 ? &lretoid: NULL,
-+ myargcount > 3 ? &lretdata: NULL,
-+ 0);
-+ if (rc != LDAP_SUCCESS) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to parse extended operation result: %s", ldap_err2string(rc));
-+ RETURN_FALSE;
-+ }
-+
-+ /* Reverse -> fall through */
-+ switch (myargcount) {
-+ case 4:
-+ /* use arg #4 as the data returned by the server */
-+ zval_dtor(retdata);
-+ if (lretdata == NULL) {
-+ ZVAL_EMPTY_STRING(retdata);
-+ } else {
-+ ZVAL_STRINGL(retdata, lretdata->bv_val, lretdata->bv_len, 1);
-+ ldap_memfree(lretdata->bv_val);
-+ ldap_memfree(lretdata);
-+ }
-+ case 3:
-+ zval_dtor(retoid);
-+ if (lretoid == NULL) {
-+ ZVAL_EMPTY_STRING(retoid);
-+ } else {
-+ ZVAL_STRING(retoid, lretoid, 1);
-+ ldap_memfree(lretoid);
-+ }
-+ }
-+ RETURN_TRUE;
-+}
-+/* }}} */
-+
-+#ifdef HAVE_LDAP_PARSE_PASSWD
-+/* {{{ proto bool ldap_parse_exop_passwd(resource link, resource result, string newpasswd)
-+ Extract information from RFC 3062 password modify extended operation result */
-+PHP_FUNCTION(ldap_parse_exop_passwd)
-+{
-+ zval **link, **result, **newpasswd;
-+ ldap_linkdata *ld;
-+ LDAPMessage *ldap_result;
-+ struct berval lnewpasswd;
-+ int rc, myargcount = ZEND_NUM_ARGS();
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZZ", &link, &result, &newpasswd) != SUCCESS) {
-+ WRONG_PARAM_COUNT;
-+ }
-+
-+ ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, link, -1, "ldap link", le_link);
-+ ZEND_FETCH_RESOURCE(ldap_result, LDAPMessage *, result, -1, "ldap result", le_result);
-+
-+ rc = ldap_parse_passwd(ld->link, ldap_result, &lnewpasswd);
-+ if (rc != LDAP_SUCCESS) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to parse passwd modify extended operation result: %s", ldap_err2string(rc));
-+ RETURN_FALSE;
-+ }
-+
-+ zval_dtor(*newpasswd);
-+ if (lnewpasswd.bv_len == 0) {
-+ ZVAL_EMPTY_STRING(*newpasswd);
-+ } else {
-+ ZVAL_STRINGL(*newpasswd, lnewpasswd.bv_val, lnewpasswd.bv_len, 1);
-+ ldap_memfree(lnewpasswd.bv_val);
-+ }
-+
-+ RETURN_TRUE;
-+}
-+#else
-+/* TODO: implement based on ldap_parse_exop() */
-+/* }}} */
-+#endif
-+
-+#ifdef HAVE_LDAP_PARSE_WHOAMI
-+/* {{{ proto bool ldap_parse_exop_whoami(resource link, resource result, string authzid)
-+ Extract information from <draft-zeilenga-ldap-authzid> whoami extended operation result (a Work in Progress) */
-+PHP_FUNCTION(ldap_parse_exop_whoami)
-+{
-+ zval **link, **result, **authzid;
-+ ldap_linkdata *ld;
-+ LDAPMessage *ldap_result;
-+ struct berval *lauthzid;
-+ int rc, myargcount = ZEND_NUM_ARGS();
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZZ", &link, &result, &authzid) != SUCCESS) {
-+ WRONG_PARAM_COUNT;
-+ }
-+
-+ ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, link, -1, "ldap link", le_link);
-+ ZEND_FETCH_RESOURCE(ldap_result, LDAPMessage *, result, -1, "ldap result", le_result);
-+
-+ rc = ldap_parse_whoami(ld->link, ldap_result, &lauthzid );
-+ if (rc != LDAP_SUCCESS) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to parse whoami extended operation result: %s", ldap_err2string(rc));
-+ RETURN_FALSE;
-+ }
-+
-+ zval_dtor(*authzid);
-+ if (lauthzid == NULL) {
-+ ZVAL_EMPTY_STRING(*authzid);
-+ } else {
-+ ZVAL_STRINGL(*authzid, lauthzid->bv_val, lauthzid->bv_len, 1);
-+ ldap_memfree(lauthzid->bv_val);
-+ ldap_memfree(lauthzid);
-+ }
-+ RETURN_TRUE;
-+}
-+#else
-+/* TODO: implement based on ldap_parse_extended_result() */
-+/* }}} */
-+#endif
-+/* }}} */
-+#endif
-+
- /* {{{ proto resource ldap_first_reference(resource link, resource result)
- Return first reference */
- PHP_FUNCTION(ldap_first_reference)
- {
-@@ -2758,51 +3470,733 @@
- }
- /* }}} */
- #endif
-
--/* {{{ arginfo */
--ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_connect, 0, 0, 0)
-- ZEND_ARG_INFO(0, hostname)
-- ZEND_ARG_INFO(0, port)
--#ifdef HAVE_ORALDAP
-- ZEND_ARG_INFO(0, wallet)
-- ZEND_ARG_INFO(0, wallet_passwd)
-- ZEND_ARG_INFO(0, authmode)
--#endif
--ZEND_END_ARG_INFO()
-+/* {{{ Extended operations, Pierangelo Masarati */
-+#ifdef HAVE_LDAP_EXTENDED_OPERATION_S
-+/* {{{ proto ? ldap_exop(resource link, string reqoid [, string reqdata [, string retoid [, string retdata]]])
-+ Extended operation */
-+PHP_FUNCTION(ldap_exop)
-+{
-+ zval **link, **reqoid, **reqdata, **retoid, **retdata;
-+ char *lreqoid, *lretoid = NULL;
-+ struct berval lreqdata, *lretdata = NULL;
-+ ldap_linkdata *ld;
-+ LDAP *ldap;
-+ LDAPMessage *ldap_res;
-+ int rc, msgid, myargcount = ZEND_NUM_ARGS();
-+ /* int reqoid_len, reqdata_len, retdata_len, retoid_len, retdat_len; */
-
--ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_resource, 0, 0, 1)
-- ZEND_ARG_INFO(0, link_identifier)
--ZEND_END_ARG_INFO()
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZ|ZZZ", &link, &reqoid, &reqdata, &retoid, &retdata) != SUCCESS) {
-+ WRONG_PARAM_COUNT;
-+ }
-
--ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_bind, 0, 0, 1)
-- ZEND_ARG_INFO(0, link_identifier)
-- ZEND_ARG_INFO(0, bind_rdn)
-- ZEND_ARG_INFO(0, bind_password)
--ZEND_END_ARG_INFO()
-+ if (Z_TYPE_PP(link) == IS_NULL) {
-+ ldap = NULL;
-+ } else {
-+ ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, link, -1, "ldap link", le_link);
-+ ldap = ld->link;
-+ }
-
--#ifdef HAVE_LDAP_SASL
--ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_sasl_bind, 0, 0, 1)
-- ZEND_ARG_INFO(0, link)
-- ZEND_ARG_INFO(0, binddn)
-- ZEND_ARG_INFO(0, password)
-- ZEND_ARG_INFO(0, sasl_mech)
-- ZEND_ARG_INFO(0, sasl_realm)
-- ZEND_ARG_INFO(0, sasl_authz_id)
-- ZEND_ARG_INFO(0, props)
--ZEND_END_ARG_INFO()
--#endif
-+ switch (myargcount) {
-+ case 5:
-+ case 4:
-+ case 3:
-+ convert_to_string_ex(reqdata);
-+ lreqdata.bv_val = Z_STRVAL_PP(reqdata);
-+ lreqdata.bv_len = Z_STRLEN_PP(reqdata);
-+ /* fallthru */
-+ case 2:
-+ convert_to_string_ex(reqoid);
-+ lreqoid = Z_STRVAL_PP(reqoid);
-+ }
-+
-+ if (myargcount > 3) {
-+ /* synchronous call */
-+ rc = ldap_extended_operation_s(ld->link, lreqoid,
-+ lreqdata.bv_len > 0 ? &lreqdata: NULL,
-+ NULL,
-+ NULL,
-+ &lretoid,
-+ myargcount > 4 ? &lretdata : NULL );
-+ if (rc != LDAP_SUCCESS ) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Extended operation %s failed: %s (%d)", lreqoid, ldap_err2string(rc), rc);
-+ RETURN_FALSE;
-+ }
-
--ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_read, 0, 0, 3)
-- ZEND_ARG_INFO(0, link_identifier)
-- ZEND_ARG_INFO(0, base_dn)
-- ZEND_ARG_INFO(0, filter)
-- ZEND_ARG_INFO(0, attributes)
-- ZEND_ARG_INFO(0, attrsonly)
-- ZEND_ARG_INFO(0, sizelimit)
-- ZEND_ARG_INFO(0, timelimit)
-- ZEND_ARG_INFO(0, deref)
--ZEND_END_ARG_INFO()
-+ /* Reverse -> fall through */
-+ switch (myargcount) {
-+ case 5:
-+ /* use arg #4 as the data returned by the server */
-+ zval_dtor(*retdata);
-+ if (lretdata == NULL) {
-+ ZVAL_EMPTY_STRING(*retdata);
-+ } else {
-+ ZVAL_STRINGL(*retdata, lretdata->bv_val, lretdata->bv_len, 1);
-+ ldap_memfree(lretdata->bv_val);
-+ ldap_memfree(lretdata);
-+ }
-+ case 4:
-+ zval_dtor(*retoid);
-+ if (lretoid == NULL) {
-+ ZVAL_EMPTY_STRING(*retoid);
-+ } else {
-+ ZVAL_STRING(*retoid, lretoid, 1);
-+ ldap_memfree(lretoid);
-+ }
-+ }
-+
-+ RETURN_TRUE;
-+ }
-+
-+ /* asynchronous call */
-+ rc = ldap_extended_operation(ld->link, lreqoid,
-+ lreqdata.bv_len > 0 ? &lreqdata: NULL,
-+ NULL, NULL, &msgid);
-+ if (rc != LDAP_SUCCESS ) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Extended operation %s failed: %s (%d)", lreqoid, ldap_err2string(rc), rc);
-+ RETURN_FALSE;
-+ }
-+
-+ rc = ldap_result(ld->link, msgid, 1 /* LDAP_MSG_ALL */, NULL, &ldap_res);
-+ if (rc == -1) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Extended operation %s failed", lreqoid);
-+ RETURN_FALSE;
-+ }
-+
-+ /* return a PHP control object */
-+ array_init(return_value);
-+
-+ ZEND_REGISTER_RESOURCE(return_value, ldap_res, le_result);
-+}
-+/* }}} */
-+
-+#ifdef HAVE_LDAP_PASSWD_S
-+/* {{{ proto ? ldap_exop_passwd(resource link [, string user [, string oldpw [, string newpw [, string newpasswd ]]]])
-+ Passwd modify extended operation */
-+PHP_FUNCTION(ldap_exop_passwd)
-+{
-+ zval **link, **user, **newpw, **oldpw, **newpasswd;
-+ struct berval luser, loldpw, lnewpw, lnewpasswd;
-+ ldap_linkdata *ld;
-+ LDAP *ldap;
-+ LDAPMessage *ldap_res;
-+ int rc, msgid, myargcount = ZEND_NUM_ARGS();
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z|ZZZZ", &link, &user, &oldpw, &newpw, &newpasswd) == FAILURE) {
-+ WRONG_PARAM_COUNT;
-+ }
-+
-+ if (Z_TYPE_PP(link) == IS_NULL) {
-+ ldap = NULL;
-+ } else {
-+ ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, link, -1, "ldap link", le_link);
-+ ldap = ld->link;
-+ }
-+
-+ luser.bv_len = 0;
-+ loldpw.bv_len = 0;
-+ lnewpw.bv_len = 0;
-+
-+ switch (myargcount) {
-+ case 5:
-+ case 4:
-+ convert_to_string_ex(newpw);
-+ lnewpw.bv_val = Z_STRVAL_PP(newpw);
-+ lnewpw.bv_len = Z_STRLEN_PP(newpw);
-+
-+ case 3:
-+ convert_to_string_ex(oldpw);
-+ loldpw.bv_val = Z_STRVAL_PP(oldpw);
-+ loldpw.bv_len = Z_STRLEN_PP(oldpw);
-+
-+ case 2:
-+ convert_to_string_ex(user);
-+ luser.bv_val = Z_STRVAL_PP(user);
-+ luser.bv_len = Z_STRLEN_PP(user);
-+ }
-+
-+ if (myargcount > 4 || lnewpw.bv_len > 0) {
-+ /* synchronous call */
-+ rc = ldap_passwd_s(ld->link, &luser,
-+ loldpw.bv_len > 0 ? &loldpw : NULL,
-+ /* loldpw.bv_len > 0 ? &loldpw : NULL, */
-+ lnewpw.bv_len > 0 ? &lnewpw : NULL,
-+ &lnewpasswd, NULL, NULL);
-+ if (rc != LDAP_SUCCESS ) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Passwd modify extended operation failed: %s (%d)", ldap_err2string(rc), rc);
-+ RETURN_FALSE;
-+ }
-+
-+ if (myargcount > 4) {
-+ zval_dtor(*newpasswd);
-+ if (lnewpasswd.bv_len == 0) {
-+ ZVAL_EMPTY_STRING(*newpasswd);
-+ } else {
-+ ZVAL_STRINGL(*newpasswd, lnewpasswd.bv_val, lnewpasswd.bv_len, 1);
-+ }
-+ }
-+
-+ ldap_memfree(lnewpasswd.bv_val);
-+
-+ RETURN_TRUE;
-+ }
-+
-+ /* asynchronous call */
-+ rc = ldap_passwd(ld->link, &luser,
-+ loldpw.bv_len > 0 ? &loldpw : NULL,
-+ lnewpw.bv_len > 0 ? &lnewpw : NULL,
-+ NULL, NULL, &msgid);
-+ if (rc != LDAP_SUCCESS ) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Passwd modify extended operation failed: %s (%d)", ldap_err2string(rc), rc);
-+ RETURN_FALSE;
-+ }
-+
-+ rc = ldap_result(ld->link, msgid, 1 /* LDAP_MSG_ALL */, NULL, &ldap_res);
-+ if (rc == -1) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Passwd modify extended operation failed");
-+ RETURN_FALSE;
-+ }
-+
-+ /* return a PHP control object */
-+ array_init(return_value);
-+
-+ ZEND_REGISTER_RESOURCE(return_value, ldap_res, le_result);
-+}
-+#else
-+/* TODO: implement based on ldap_extended_operation_s() */
-+/* }}} */
-+#endif
-+
-+#ifdef HAVE_LDAP_WHOAMI_S
-+/* {{{ proto bool ldap_exop_whoami(resource link [, string authzid])
-+ Whoami extended operation */
-+PHP_FUNCTION(ldap_exop_whoami)
-+{
-+ zval **link, **authzid;
-+ struct berval *lauthzid;
-+ ldap_linkdata *ld;
-+ LDAP *ldap;
-+ LDAPMessage *ldap_res;
-+ int rc, msgid, myargcount = ZEND_NUM_ARGS();
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z|Z", &link, &authzid) == FAILURE) {
-+ WRONG_PARAM_COUNT;
-+ }
-+
-+ if (Z_TYPE_PP(link) == IS_NULL) {
-+ ldap = NULL;
-+ } else {
-+ ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, link, -1, "ldap link", le_link);
-+ ldap = ld->link;
-+ }
-+
-+ if (myargcount == 2) {
-+ /* synchronous call */
-+ rc = ldap_whoami_s(ld->link, &lauthzid, NULL, NULL);
-+ if (rc != LDAP_SUCCESS ) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Whoami extended operation failed: %s (%d)", ldap_err2string(rc), rc);
-+ RETURN_FALSE;
-+ }
-+
-+ zval_dtor(*authzid);
-+ if (lauthzid == NULL) {
-+ ZVAL_EMPTY_STRING(*authzid);
-+ } else {
-+ ZVAL_STRINGL(*authzid, lauthzid->bv_val, lauthzid->bv_len, 1);
-+ ldap_memfree(lauthzid->bv_val);
-+ ldap_memfree(lauthzid);
-+ }
-+
-+ RETURN_TRUE;
-+ }
-+
-+ /* asynchronous call */
-+ rc = ldap_whoami(ld->link, NULL, NULL, &msgid);
-+ if (rc != LDAP_SUCCESS ) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Whoami extended operation failed: %s (%d)", ldap_err2string(rc), rc);
-+ RETURN_FALSE;
-+ }
-+
-+ rc = ldap_result(ld->link, msgid, 1 /* LDAP_MSG_ALL */, NULL, &ldap_res);
-+ if (rc == -1) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Whoami extended operation failed");
-+ RETURN_FALSE;
-+ }
-+
-+ /* return a PHP control object */
-+ array_init(return_value);
-+
-+ ZEND_REGISTER_RESOURCE(return_value, ldap_res, le_result);
-+}
-+#else
-+/* TODO: implement based on ldap_extended_operation_s() */
-+#endif
-+/* }}} */
-+#endif
-+/* }}} */
-+
-+/* {{{ LDAP controls encoding/decoding, Pierangelo Masarati */
-+/* {{{ php_set_no_value_server_ctrl
-+ */
-+void php_set_no_value_server_ctrl(INTERNAL_FUNCTION_PARAMETERS, const char *oid, const char *msg)
-+{
-+ zval **link, **iscritical;
-+ ldap_linkdata *ld;
-+ LDAP *ldap;
-+ LDAPControl ctrl = { 0 }, *ctrlsp[2];
-+ int rc, myargcount = ZEND_NUM_ARGS();
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z|Z", &link, &iscritical) != SUCCESS) {
-+ WRONG_PARAM_COUNT;
-+ }
-+
-+ if (Z_TYPE_PP(link) == IS_NULL) {
-+ ldap = NULL;
-+
-+ } else {
-+ ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, link, -1, "ldap link", le_link);
-+ ldap = ld->link;
-+ }
-+
-+ if (myargcount == 2) {
-+ convert_to_boolean_ex(iscritical);
-+ ctrl.ldctl_iscritical = Z_BVAL_PP(iscritical);
-+ }
-+
-+ ctrl.ldctl_oid = (char *)oid;
-+
-+ if (ldap) {
-+ /* directly set the option */
-+ ctrlsp[0] = &ctrl;
-+ ctrlsp[1] = NULL;
-+
-+ rc = ldap_set_option(ldap, LDAP_OPT_SERVER_CONTROLS, ctrlsp);
-+ if (rc != LDAP_SUCCESS) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to set %s control: %s (%d)", msg, ldap_err2string(rc), rc);
-+ RETURN_FALSE;
-+ }
-+
-+ } else {
-+ /* return a PHP control object */
-+ array_init(return_value);
-+
-+ add_assoc_string(return_value, "oid", ctrl.ldctl_oid, 1);
-+ if (ctrl.ldctl_iscritical) {
-+ add_assoc_bool(return_value, "iscritical", ctrl.ldctl_iscritical);
-+ }
-+ }
-+
-+ RETURN_TRUE;
-+}
-+/* }}} */
-+
-+#ifdef LDAP_CONTROL_MANAGEDSAIT
-+/* {{{ proto bool ldap_ctrl_manageDSAit(resource link [, bool iscritical])
-+ Inject manageDSAit control */
-+PHP_FUNCTION(ldap_ctrl_manageDSAit)
-+{
-+ php_set_no_value_server_ctrl(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_CONTROL_MANAGEDSAIT, "manageDSAit");
-+}
-+/* }}} */
-+#endif
-+
-+#ifdef LDAP_CONTROL_PAGEDRESULTS
-+/* {{{ proto bool ldap_ctrl_paged_results(resource link, int pagesize [, bool iscritical [, string cookie]])
-+ Inject paged results control*/
-+PHP_FUNCTION(ldap_ctrl_paged_results)
-+{
-+ zval **link, **pagesize, **iscritical, **cookie;
-+ int lpagesize = 0;
-+ struct berval lcookie = { 0, NULL };
-+ ldap_linkdata *ld;
-+ LDAP *ldap;
-+ BerElement *ber = NULL;
-+ LDAPControl ctrl, *ctrlsp[2];
-+ int rc, myargcount = ZEND_NUM_ARGS();
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZ|ZZ", &link, &pagesize, &iscritical, &cookie) != SUCCESS) {
-+ WRONG_PARAM_COUNT;
-+ }
-+
-+ if (Z_TYPE_PP(link) == IS_NULL) {
-+ ldap = NULL;
-+ } else {
-+ ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, link, -1, "ldap link", le_link);
-+ ldap = ld->link;
-+ }
-+
-+ ber = ber_alloc_t(LBER_USE_DER);
-+ if (ber == NULL) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to alloc BER encoding resources for paged results control");
-+ RETURN_FALSE;
-+ }
-+
-+ ctrl.ldctl_iscritical = 0;
-+
-+ switch (myargcount) {
-+ case 4:
-+ convert_to_string_ex(cookie);
-+ lcookie.bv_val = Z_STRVAL_PP(cookie);
-+ lcookie.bv_len = Z_STRLEN_PP(cookie);
-+ /* fallthru */
-+ case 3:
-+ convert_to_boolean_ex(iscritical);
-+ ctrl.ldctl_iscritical = Z_BVAL_PP(iscritical);
-+ /* fallthru */
-+ }
-+ convert_to_long_ex(pagesize);
-+ lpagesize = Z_LVAL_PP(pagesize);
-+
-+ ber_printf(ber, "{iO}", lpagesize, &lcookie );
-+ rc = ber_flatten2( ber, &ctrl.ldctl_value, 0 );
-+ if ( rc == -1 ) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to BER encode paged results control");
-+ RETURN_FALSE;
-+ }
-+
-+ ctrl.ldctl_oid = LDAP_CONTROL_PAGEDRESULTS;
-+
-+ if (ldap) {
-+ /* directly set the option */
-+ ctrlsp[0] = &ctrl;
-+ ctrlsp[1] = NULL;
-+
-+ rc = ldap_set_option(ldap, LDAP_OPT_SERVER_CONTROLS, ctrlsp);
-+ if (rc != LDAP_SUCCESS) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to set paged results control: %s (%d)", ldap_err2string(rc), rc);
-+ RETURN_FALSE;
-+ }
-+
-+ } else {
-+ /* return a PHP control object */
-+ array_init(return_value);
-+
-+ add_assoc_string(return_value, "oid", ctrl.ldctl_oid, 1);
-+ if ( ctrl.ldctl_value.bv_len ) {
-+ add_assoc_stringl(return_value, "value", ctrl.ldctl_value.bv_val, ctrl.ldctl_value.bv_len, 1);
-+ }
-+ if (ctrl.ldctl_iscritical) {
-+ add_assoc_bool(return_value, "iscritical", ctrl.ldctl_iscritical);
-+ }
-+ }
-+
-+ if (ber != NULL) {
-+ ber_free(ber, 1);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto bool ldap_ctrl_paged_results_resp(resource link, resource result [, string cookie [, int estimated]])
-+ Extract paged results control response */
-+PHP_FUNCTION(ldap_ctrl_paged_results_resp)
-+{
-+ zval **link, **result, **cookie, **estimated;
-+ struct berval lcookie;
-+ int lestimated;
-+ ldap_linkdata *ld;
-+ LDAPMessage *ldap_result;
-+ LDAPControl **lserverctrls, *lctrl;
-+ BerElement *ber;
-+ ber_tag_t tag;
-+ int rc, lerrcode, myargcount = ZEND_NUM_ARGS();
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZ|ZZ", &link, &result, &cookie, &estimated) != SUCCESS) {
-+ WRONG_PARAM_COUNT;
-+ }
-+
-+ ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, link, -1, "ldap link", le_link);
-+ ZEND_FETCH_RESOURCE(ldap_result, LDAPMessage *, result, -1, "ldap result", le_result);
-+
-+ rc = ldap_parse_result(ld->link,
-+ ldap_result,
-+ &lerrcode,
-+ NULL, /* matcheddn */
-+ NULL, /* errmsg */
-+ NULL, /* referrals */
-+ &lserverctrls,
-+ 0);
-+
-+ if (rc != LDAP_SUCCESS) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to parse result: %s (%d)", ldap_err2string(rc), rc);
-+ RETURN_FALSE;
-+ }
-+
-+ if (lerrcode != LDAP_SUCCESS) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Result is: %s (%d)", ldap_err2string(lerrcode), lerrcode);
-+ RETURN_FALSE;
-+ }
-+
-+ if (lserverctrls == NULL) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "No server controls in result");
-+ RETURN_FALSE;
-+ }
-+
-+ lctrl = ldap_find_control(LDAP_CONTROL_PAGEDRESULTS, lserverctrls);
-+ if (lctrl == NULL) {
-+ ldap_controls_free(lserverctrls);
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "No paged results control response in result");
-+ RETURN_FALSE;
-+ }
-+
-+ ber = ber_init(&lctrl->ldctl_value);
-+ if (ber == NULL) {
-+ ldap_controls_free(lserverctrls);
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to alloc BER decoding resources for paged results control response");
-+ RETURN_FALSE;
-+ }
-+
-+ tag = ber_scanf(ber, "{io}", &lestimated, &lcookie );
-+ (void)ber_free(ber, 1);
-+
-+ if (tag == LBER_ERROR) {
-+ ldap_controls_free(lserverctrls);
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to decode paged results control response");
-+ RETURN_FALSE;
-+ }
-+
-+ if (lestimated < 0) {
-+ ldap_controls_free(lserverctrls);
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid paged results control response value");
-+ RETURN_FALSE;
-+ }
-+
-+ ldap_controls_free(lserverctrls);
-+
-+ if (myargcount == 4) {
-+ zval_dtor(*estimated);
-+ ZVAL_LONG(*estimated, lestimated);
-+ }
-+
-+ zval_dtor(*cookie);
-+ if (lcookie.bv_len == 0) {
-+ ZVAL_EMPTY_STRING(*cookie);
-+ } else {
-+ ZVAL_STRINGL(*cookie, lcookie.bv_val, lcookie.bv_len, 1);
-+ }
-+ ldap_memfree(lcookie.bv_val);
-+
-+ RETURN_TRUE;
-+}
-+/* }}} */
-+#endif
-+
-+#ifdef LDAP_CONTROL_PASSWORDPOLICYREQUEST
-+/* {{{ proto bool ldap_ctrl_ppolicy(resource link [, bool iscritical])
-+ Inject password policy control */
-+PHP_FUNCTION(ldap_ctrl_ppolicy)
-+{
-+ php_set_no_value_server_ctrl(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_CONTROL_PASSWORDPOLICYREQUEST, "passwordPolicy");
-+}
-+/* }}} */
-+
-+/* {{{ proto bool ldap_ctrl_ppolicy_resp(resource link, resource result [, expire [, grace [, error[, errmsg]]]])
-+ Extract password policy control response */
-+PHP_FUNCTION(ldap_ctrl_ppolicy_resp)
-+{
-+ zval **link, **result, **ppexpire, **ppgrace, **pperror, **pperrmsg;
-+ int lexpire, lgrace;
-+ LDAPPasswordPolicyError lerror;
-+ ldap_linkdata *ld;
-+ LDAPMessage *ldap_result;
-+ LDAPControl **lserverctrls, *lctrl;
-+ int rc, pperrmsg_len, lerrcode, myargcount = ZEND_NUM_ARGS();
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZ|ZZZZ", &link, &result, &ppexpire, &ppgrace, &pperror, &pperrmsg) != SUCCESS) {
-+ WRONG_PARAM_COUNT;
-+ }
-+
-+ ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, link, -1, "ldap link", le_link);
-+ ZEND_FETCH_RESOURCE(ldap_result, LDAPMessage *, result, -1, "ldap result", le_result);
-+
-+ rc = ldap_parse_result(ld->link,
-+ ldap_result,
-+ &lerrcode,
-+ NULL, /* matcheddn */
-+ NULL, /* errmsg */
-+ NULL, /* referrals */
-+ &lserverctrls,
-+ 0);
-+
-+ if (rc != LDAP_SUCCESS) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to parse result: %s (%d)", ldap_err2string(rc), rc);
-+ RETURN_FALSE;
-+ }
-+
-+ if (lerrcode != LDAP_SUCCESS && lerrcode != LDAP_INVALID_CREDENTIALS) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Result is: %s (%d)", ldap_err2string(lerrcode), lerrcode);
-+ RETURN_FALSE;
-+ }
-+
-+ if (lserverctrls == NULL) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "No server controls in result");
-+ RETURN_FALSE;
-+ }
-+
-+ lctrl = ldap_find_control(LDAP_CONTROL_PASSWORDPOLICYRESPONSE, lserverctrls);
-+ if (lctrl == NULL) {
-+ ldap_controls_free(lserverctrls);
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "No password policy control response in result");
-+ RETURN_FALSE;
-+ }
-+
-+ lerrcode = ldap_parse_passwordpolicy_control(ld->link, lctrl, &lexpire, &lgrace, &lerror);
-+ ldap_controls_free(lserverctrls);
-+ if (lerrcode != LDAP_SUCCESS) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to parse password policy control response: %s (%d)", ldap_err2string(lerrcode), lerrcode);
-+ RETURN_FALSE;
-+ }
-+
-+ switch (myargcount) {
-+ case 6:
-+ zval_dtor(*pperrmsg);
-+ ZVAL_STRING(*pperrmsg, (char *)ldap_passwordpolicy_err2txt(lerror), 1);
-+
-+ case 5:
-+ zval_dtor(*pperror);
-+ ZVAL_LONG(*pperror, (long)lerror);
-+
-+ case 4:
-+ zval_dtor(*ppgrace);
-+ ZVAL_LONG(*ppgrace, (long)lgrace);
-+ }
-+
-+ zval_dtor(*ppexpire);
-+ ZVAL_LONG(*ppexpire, (long)lexpire);
-+
-+ RETURN_TRUE;
-+}
-+/* }}} */
-+#endif
-+
-+#ifdef LDAP_CONTROL_NOOP
-+/* {{{ proto bool ldap_ctrl_noop(resource link, bool iscritical)
-+ Inject control*/
-+PHP_FUNCTION(ldap_ctrl_noop)
-+{
-+ php_set_no_value_server_ctrl(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_CONTROL_NOOP, "no-op");
-+}
-+/* }}} */
-+#endif
-+
-+#ifdef LDAP_CONTROL_MANAGEDIT
-+/* {{{ proto bool ldap_ctrl_manageDIT(resource link [, bool iscritical])
-+ Inject control*/
-+PHP_FUNCTION(ldap_ctrl_manageDIT)
-+{
-+ php_set_no_value_server_ctrl(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_CONTROL_MANAGEDIT, "manageDIT");
-+}
-+/* }}} */
-+#endif
-+
-+#ifdef LDAP_CONTROL_X_PERMISSIVE_MODIFY
-+/* {{{ proto bool ldap_ctrl_permissive_modify(resource link [, bool iscritical])
-+ Inject control*/
-+PHP_FUNCTION(ldap_ctrl_permissive_modify)
-+{
-+ php_set_no_value_server_ctrl(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_CONTROL_X_PERMISSIVE_MODIFY, "permissive modify");
-+}
-+/* }}} */
-+#endif
-+/* }}} */
-+
-+#ifdef HAVE_LDAP_REFRESH
-+/* {{{ proto ? ldap_refresh(resource link , string dn , int ttl, [int *newttl])
-+ DDS refresh extended operation */
-+PHP_FUNCTION(ldap_refresh)
-+{
-+ zval **link, **dn, **ttl, **newttl;
-+ struct berval ldn;
-+ ber_int_t lttl;
-+ ber_int_t lnewttl;
-+ ldap_linkdata *ld;
-+ LDAP *ldap;
-+ LDAPMessage *ldap_res;
-+ int rc, msgid, myargcount = ZEND_NUM_ARGS();
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZZ|Z", &link, &dn, &ttl, &newttl) != SUCCESS) {
-+ WRONG_PARAM_COUNT;
-+ }
-+
-+ if (Z_TYPE_PP(link) == IS_NULL) {
-+ ldap = NULL;
-+ } else {
-+ ZEND_FETCH_RESOURCE(ld, ldap_linkdata *,
-+ link, -1, "ldap link", le_link);
-+ ldap = ld->link;
-+ }
-+
-+ ldn.bv_len = 0;
-+ convert_to_string_ex(dn);
-+ ldn.bv_val = Z_STRVAL_PP(dn);
-+ ldn.bv_len = Z_STRLEN_PP(dn);
-+
-+ convert_to_long_ex(ttl);
-+ lttl = (ber_int_t)Z_LVAL_PP(ttl);
-+
-+ /* asynchronous call */
-+ rc = ldap_refresh_s(ld->link, &ldn, lttl, &lnewttl, NULL, NULL);
-+ if (rc != LDAP_SUCCESS ) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING,
-+ "Refresh extended operation failed: %s (%d)",
-+ ldap_err2string(rc), rc);
-+ RETURN_FALSE;
-+ }
-+
-+ if (myargcount == 4) {
-+ zval_dtor(*newttl);
-+ ZVAL_LONG(*newttl, (long)lnewttl);
-+ }
-+ RETURN_TRUE;
-+}
-+#else
-+/* TODO: implement based on ldap_extended_operation_s() */
-+/* }}} */
-+#endif
-+
-+/* {{{ arginfo */
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_connect, 0, 0, 0)
-+ ZEND_ARG_INFO(0, hostname)
-+ ZEND_ARG_INFO(0, port)
-+#ifdef HAVE_ORALDAP
-+ ZEND_ARG_INFO(0, wallet)
-+ ZEND_ARG_INFO(0, wallet_passwd)
-+ ZEND_ARG_INFO(0, authmode)
-+#endif
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_resource, 0, 0, 1)
-+ ZEND_ARG_INFO(0, link_identifier)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_bind, 0, 0, 1)
-+ ZEND_ARG_INFO(0, link_identifier)
-+ ZEND_ARG_INFO(0, bind_rdn)
-+ ZEND_ARG_INFO(0, bind_password)
-+ZEND_END_ARG_INFO()
-+
-+#ifdef HAVE_LDAP_SASL
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_sasl_bind, 0, 0, 1)
-+ ZEND_ARG_INFO(0, link)
-+ ZEND_ARG_INFO(0, binddn)
-+ ZEND_ARG_INFO(0, password)
-+ ZEND_ARG_INFO(0, sasl_mech)
-+ ZEND_ARG_INFO(0, sasl_realm)
-+ ZEND_ARG_INFO(0, sasl_authz_id)
-+ ZEND_ARG_INFO(0, props)
-+ZEND_END_ARG_INFO()
-+#endif
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_read, 0, 0, 3)
-+ ZEND_ARG_INFO(0, link_identifier)
-+ ZEND_ARG_INFO(0, base_dn)
-+ ZEND_ARG_INFO(0, filter)
-+ ZEND_ARG_INFO(0, attributes)
-+ ZEND_ARG_INFO(0, attrsonly)
-+ ZEND_ARG_INFO(0, sizelimit)
-+ ZEND_ARG_INFO(0, timelimit)
-+ ZEND_ARG_INFO(0, deref)
-+ZEND_END_ARG_INFO()
-
- ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_list, 0, 0, 3)
- ZEND_ARG_INFO(0, link_identifier)
- ZEND_ARG_INFO(0, base_dn)
-@@ -3007,8 +4401,9 @@
- ZEND_ARG_INFO(1, errcode)
- 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
-
-@@ -3027,8 +4422,40 @@
- ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_8859_to_t61, 0, 0, 1)
- ZEND_ARG_INFO(0, value)
- ZEND_END_ARG_INFO()
- #endif
-+
-+#ifdef HAVE_LDAP_EXTENDED_OPERATION_S
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_exop, 0, 0, 5)
-+ ZEND_ARG_INFO(0, link)
-+ ZEND_ARG_INFO(0, reqoid)
-+ ZEND_ARG_INFO(1, reqdata)
-+ ZEND_ARG_INFO(1, repoid)
-+ ZEND_ARG_INFO(1, repdata)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_exop_passwd, 0, 0, 5)
-+ ZEND_ARG_INFO(0, link)
-+ ZEND_ARG_INFO(1, user)
-+ ZEND_ARG_INFO(1, oldpw)
-+ ZEND_ARG_INFO(1, newpw)
-+ ZEND_ARG_INFO(1, newpasswd)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_exop_whoami, 0, 0, 2)
-+ ZEND_ARG_INFO(0, link)
-+ ZEND_ARG_INFO(1, authzid)
-+ZEND_END_ARG_INFO()
-+#endif
-+
-+#ifdef HAVE_LDAP_REFRESH
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_refresh, 0, 0, 4)
-+ ZEND_ARG_INFO(0, link)
-+ ZEND_ARG_INFO(0, dn)
-+ ZEND_ARG_INFO(1, ttl)
-+ ZEND_ARG_INFO(0, newttl)
-+ZEND_END_ARG_INFO()
-+#endif
- /* }}} */
-
- /*
- This is just a small subset of the functionality provided by the LDAP library. All the
-@@ -3091,9 +4518,22 @@
- #endif
- #ifdef HAVE_LDAP_START_TLS_S
- PHP_FE(ldap_start_tls, arginfo_ldap_resource)
- #endif
-+#ifdef HAVE_LDAP_EXTENDED_OPERATION_S
-+ PHP_FE(ldap_exop,
-+ arginfo_ldap_exop)
-+ PHP_FE(ldap_exop_passwd,
-+ arginfo_ldap_exop_passwd)
-+ PHP_FE(ldap_exop_whoami,
-+ arginfo_ldap_exop_whoami)
-+#endif
-+#ifdef HAVE_LDAP_REFRESH
-+ PHP_FE(ldap_refresh,
-+ arginfo_ldap_refresh)
- #endif
-+#endif
-+
-
- #if defined(LDAP_API_FEATURE_X_OPENLDAP) && defined(HAVE_3ARG_SETREBINDPROC)
- PHP_FE(ldap_set_rebind_proc, arginfo_ldap_set_rebind_proc)
- #endif
-@@ -3102,8 +4542,33 @@
- PHP_FE(ldap_t61_to_8859, arginfo_ldap_t61_to_8859)
- PHP_FE(ldap_8859_to_t61, arginfo_ldap_8859_to_t61)
- #endif
-
-+/* routines to handle standard track controls, Pierangelo Masarati */
-+#ifdef LDAP_CONTROL_MANAGEDSAIT
-+ PHP_FE(ldap_ctrl_manageDSAit, NULL)
-+#endif
-+#ifdef LDAP_CONTROL_PAGEDRESULTS
-+ PHP_FE(ldap_ctrl_paged_results, NULL) /* fourth_arg_force_ref */
-+ PHP_FE(ldap_ctrl_paged_results_resp, NULL) /* arg3to4of4_force_ref */
-+#endif
-+#ifdef LDAP_CONTROL_PASSWORDPOLICYREQUEST
-+ PHP_FE(ldap_ctrl_ppolicy, NULL)
-+ PHP_FE(ldap_ctrl_ppolicy_resp, NULL) /* arg3to6of6_force_ref */
-+#endif
-+#ifdef LDAP_CONTROL_NOOP
-+ PHP_FE(ldap_ctrl_noop, NULL)
-+#endif
-+#ifdef LDAP_CONTROL_MANAGEDIT
-+ PHP_FE(ldap_ctrl_manageDIT, NULL)
-+#endif
-+#ifdef LDAP_CONTROL_X_PERMISSIVE_MODIFY
-+ PHP_FE(ldap_ctrl_permissive_modify, NULL)
-+#endif
-+/* end of ando mod */
-+
-+
-+
- #ifdef LDAP_CONTROL_PAGEDRESULTS
- 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
-@@ -3128,8 +4593,10 @@
- STANDARD_MODULE_PROPERTIES_EX
- };
- /* }}} */
-
-+
-+
- /*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
---- ext/ldap/php_ldap.h.orig 2015-03-18 06:33:59.000000000 +0100
-+++ ext/ldap/php_ldap.h 2015-04-13 05:57:02.000000000 +0200
-@@ -28,16 +28,148 @@
- #endif
-
- #include <ldap.h>
-
-+#define HAVE_3ARG_SETREBINDPROC
-+#define HAVE_LDAP_ADD_EXT_S
-+#define HAVE_LDAP_MODIFY_EXT_S
-+#define HAVE_LDAP_COMPARE_EXT_S
-+#define HAVE_LDAP_DELETE_EXT_S
-+#define HAVE_LDAP_PARSE_EXTENDED_RESULT
-+#define HAVE_LDAP_PARSE_PASSWD
-+#define HAVE_LDAP_PARSE_WHOAMI
-+#define HAVE_LDAP_EXTENDED_OPERATION_S
-+#define HAVE_LDAP_PASSWD_S
-+#define HAVE_LDAP_WHOAMI_S
-+#define HAVE_LDAP_REFRESH
-+#define HAVE_LDAP_EXTENDED_OPERATION_S
-+#define HAVE_LDAP_REFRESH
-+#define HAVE_LDAP_EXTENDED_OPERATION_S
-+#define HAVE_LDAP_REFRESH
-+#define HAVE_LDAP_EXTENDED_OPERATION
-+
-+
- extern zend_module_entry ldap_module_entry;
- #define ldap_module_ptr &ldap_module_entry
-
- /* LDAP functions */
- PHP_MINIT_FUNCTION(ldap);
- PHP_MSHUTDOWN_FUNCTION(ldap);
- PHP_MINFO_FUNCTION(ldap);
-
-+#ifdef HAVE_LDAP_EXTENDED_OPERATION
-+
-+#endif
-+
-+#ifdef LDAP_CONTROL_MANAGEDSAIT
-+/* RFC 3296 */
-+PHP_FUNCTION(ldap_ctrl_manageDSAit);
-+#endif
-+#ifdef LDAP_CONTROL_PROXY_AUTHZ
-+/* <draft-weltman-ldapv3-proxy> (a Work in Progress) */
-+PHP_FUNCTION(ldap_ctrl_proxy_authz);
-+#endif
-+#ifdef LDAP_CONTROL_SUBENTRIES
-+/* RFC 3672 */
-+PHP_FUNCTION(ldap_ctrl_subentries);
-+#endif
-+#ifdef LDAP_CONTROL_VALUESRETURNFILTER
-+/* RFC 3876 */
-+PHP_FUNCTION(ldap_ctrl_vlv);
-+#endif
-+#ifdef LDAP_CONTROL_ASSERT
-+/* <draft-zeilenga-ldap-assert> (a Work in Progress) */
-+PHP_FUNCTION(ldap_ctrl_assert);
-+#endif
-+#ifdef LDAP_CONTROL_PRE_READ
-+/* <draft-zeilenga-ldap-readentry> (a Work in Progress) */
-+PHP_FUNCTION(ldap_ctrl_preread);
-+PHP_FUNCTION(ldap_ctrl_postread);
-+#endif
-+#ifdef LDAP_CONTROL_SORTREQUEST
-+/* RFC 2891 */
-+PHP_FUNCTION(ldap_ctrl_sort);
-+PHP_FUNCTION(ldap_ctrl_sort_resp);
-+#endif
-+#ifdef LDAP_CONTROL_PAGEDRESULTS
-+/* RFC 2696 */
-+PHP_FUNCTION(ldap_ctrl_paged_results);
-+PHP_FUNCTION(ldap_ctrl_paged_results_resp);
-+#endif
-+#ifdef LDAP_CONTROL_PASSWORDPOLICYREQUEST
-+/* <draft-behera-ldap-password-policy> (a Work in Progress) */
-+PHP_FUNCTION(ldap_ctrl_ppolicy);
-+PHP_FUNCTION(ldap_ctrl_ppolicy_resp);
-+#endif
-+#ifdef LDAP_CONTROL_NOOP
-+/* <draft-zeilenga-ldap-noop> (a Work in Progress) */
-+PHP_FUNCTION(ldap_ctrl_noop);
-+#endif
-+#ifdef LDAP_CONTROL_NO_SUBORDINATES
-+/* don't know anything about it */
-+#endif
-+#ifdef LDAP_CONTROL_MANAGEDIT
-+/* no spec; partially implemented in OpenLDAP 2.3 */
-+PHP_FUNCTION(ldap_ctrl_manageDIT);
-+#endif
-+#ifdef LDAP_CONTROL_SLURP
-+/* don't know anything about it */
-+#endif
-+#ifdef LDAP_CONTROL_VALSORT
-+/* <> */
-+PHP_FUNCTION(ldap_ctrl_valsort);
-+#endif
-+#ifdef LDAP_CONTROL_SYNC
-+/* <draft-zeilenga-ldup-sync> (a Work in Progress) */
-+PHP_FUNCTION(ldap_ctrl_sync);
-+PHP_FUNCTION(ldap_ctrl_sync_state);
-+PHP_FUNCTION(ldap_ctrl_sync_done);
-+/* TODO: need to handle the SYNC intermediate response message (LDAPIRM) */
-+#endif
-+#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
-+/* <draft-sermersheim-ldap-chaining> (a Work in Progress) */
-+PHP_FUNCTION(ldap_ctrl_chaining);
-+#endif
-+#ifdef LDAP_CONTROL_X_INCREMENTAL_VALUES
-+/* MS Active Directory */
-+PHP_FUNCTION(ldap_ctrl_incremental_values);
-+#endif
-+#ifdef LDAP_CONTROL_X_DOMAIN_SCOPE
-+/* MS Active Directory */
-+PHP_FUNCTION(ldap_ctrl_domain_scope);
-+#endif
-+#ifdef LDAP_CONTROL_X_PERMISSIVE_MODIFY
-+/* MS Active Directory */
-+PHP_FUNCTION(ldap_ctrl_permissive_modify);
-+#endif
-+#ifdef LDAP_CONTROL_X_SEARCH_OPTIONS
-+/* MS Active Directory */
-+PHP_FUNCTION(ldap_ctrl_search_options);
-+#endif
-+#ifdef LDAP_CONTROL_X_TREE_DELETE
-+/* MS Active Directory */
-+PHP_FUNCTION(ldap_ctrl_tree_delete);
-+#endif
-+#ifdef LDAP_CONTROL_X_EXTENDED_DN
-+/* MS Active Directory */
-+PHP_FUNCTION(ldap_ctrl_extended_dn);
-+#endif
-+#ifdef LDAP_CONTROL_DUPENT
-+/* <draft-ietf-ldapext-ldapv3-dupent> (a Work in Progress) */
-+PHP_FUNCTION(ldap_ctrl_dupent);
-+PHP_FUNCTION(ldap_ctrl_dupent_resp);
-+PHP_FUNCTION(ldap_ctrl_dupent_done_resp);
-+#endif
-+#ifdef LDAP_CONTROL_PERSIST_REQUEST
-+/* ? */
-+#endif
-+#ifdef LDAP_CONTROL_VLVREQUEST
-+/* <draft-ietf-ldapext-ldapv3-vlv> (a Work in Progress) */
-+PHP_FUNCTION(ldap_ctrl_vlv);
-+PHP_FUNCTION(ldap_ctrl_vlv_resp);
-+#endif
-+
-+
- ZEND_BEGIN_MODULE_GLOBALS(ldap)
- long num_links;
- long max_links;
- ZEND_END_MODULE_GLOBALS(ldap)
diff --git a/databases/php-ldap/files/ldap-ctrl-exop55.patch b/databases/php-ldap/files/ldap-ctrl-exop55.patch
deleted file mode 100644
index b2856f07852..00000000000
--- a/databases/php-ldap/files/ldap-ctrl-exop55.patch
+++ /dev/null
@@ -1,2300 +0,0 @@
-$NetBSD$
-/*
- * Copyright (c) 2007-2009 Pierangelo Masarati
- * Copyright (c) 2009,2015 Emmanuel Dreyfus
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
- * THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
---- ext/ldap/ldap.c.orig 2015-09-02 18:00:35.000000000 +0200
-+++ ext/ldap/ldap.c 2015-11-08 05:14:15.000000000 +0100
-@@ -66,8 +66,13 @@
- #elif defined(HAVE_LDAP_SASL_SASL_H)
- #include <sasl/sasl.h>
- #endif
-
-+/* XXX Not detected by configure... */
-+#ifdef LDAP_EXOP_REFRESH
-+#define HAVE_LDAP_REFRESH 1
-+#endif
-+
- typedef struct {
- LDAP *link;
- #if defined(LDAP_API_FEATURE_X_OPENLDAP) && defined(HAVE_3ARG_SETREBINDPROC)
- zval *rebindproc;
-@@ -88,31 +93,46 @@
- #ifdef COMPILE_DL_LDAP
- ZEND_GET_MODULE(ldap)
- #endif
-
-+
-+/* {{{ proto void _close_ldap_link()
-+ close a connection and free LDAP resources */
- static void _close_ldap_link(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */
- {
- ldap_linkdata *ld = (ldap_linkdata *)rsrc->ptr;
-
-- ldap_unbind_s(ld->link);
--#if defined(LDAP_API_FEATURE_X_OPENLDAP) && defined(HAVE_3ARG_SETREBINDPROC)
-+ /* ldap_unbind_s() is deprecated;
-+ * the distinction between ldap_unbind() and ldap_unbind_s() is moot */
-+#ifdef LDAP_API_FEATURE_X_OPENLDAP
-+ ldap_unbind_ext(ld->link, NULL, NULL);
-+#ifdef HAVE_3ARG_SETREBINDPROC
-+
- if (ld->rebindproc != NULL) {
- zval_dtor(ld->rebindproc);
- FREE_ZVAL(ld->rebindproc);
- }
- #endif
-+#else /* ! LDAP_API_FEATURE_X_OPENLDAP */
-+ ldap_unbind_s(ld->link);
-+#endif /* ! LDAP_API_FEATURE_X_OPENLDAP */
-+
- efree(ld);
- LDAPG(num_links)--;
- }
- /* }}} */
-
-+/* {{{ proto void _free_ldap_result()
-+ free the result of an LDAP operation */
- static void _free_ldap_result(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */
- {
- LDAPMessage *result = (LDAPMessage *)rsrc->ptr;
- ldap_msgfree(result);
- }
- /* }}} */
-
-+/* {{{ proto void _free_ldap_result_entry()
-+ free an entry resulting from an LDAP search operation */
- static void _free_ldap_result_entry(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */
- {
- ldap_resultentry *entry = (ldap_resultentry *)rsrc->ptr;
-
-@@ -203,8 +223,21 @@
- REGISTER_LONG_CONSTANT("GSLC_SSL_ONEWAY_AUTH", GSLC_SSL_ONEWAY_AUTH, CONST_PERSISTENT | CONST_CS);
- REGISTER_LONG_CONSTANT("GSLC_SSL_TWOWAY_AUTH", GSLC_SSL_TWOWAY_AUTH, CONST_PERSISTENT | CONST_CS);
- #endif
-
-+#ifdef LDAP_CONTROL_PASSWORDPOLICYREQUEST
-+ REGISTER_LONG_CONSTANT("PP_passwordExpired", PP_passwordExpired, CONST_PERSISTENT | CONST_CS);
-+ REGISTER_LONG_CONSTANT("PP_accountLocked", PP_accountLocked, CONST_PERSISTENT | CONST_CS);
-+ REGISTER_LONG_CONSTANT("PP_changeAfterReset", PP_changeAfterReset, CONST_PERSISTENT | CONST_CS);
-+ REGISTER_LONG_CONSTANT("PP_passwordModNotAllowed", PP_passwordModNotAllowed, CONST_PERSISTENT | CONST_CS);
-+ REGISTER_LONG_CONSTANT("PP_mustSupplyOldPassword", PP_mustSupplyOldPassword, CONST_PERSISTENT | CONST_CS);
-+ REGISTER_LONG_CONSTANT("PP_insufficientPasswordQuality", PP_insufficientPasswordQuality, CONST_PERSISTENT | CONST_CS);
-+ REGISTER_LONG_CONSTANT("PP_passwordTooShort", PP_passwordTooShort, CONST_PERSISTENT | CONST_CS);
-+ REGISTER_LONG_CONSTANT("PP_passwordTooYoung", PP_passwordTooYoung, CONST_PERSISTENT | CONST_CS);
-+ REGISTER_LONG_CONSTANT("PP_passwordInHistory", PP_passwordInHistory, CONST_PERSISTENT | CONST_CS);
-+ REGISTER_LONG_CONSTANT("PP_noError", PP_noError, CONST_PERSISTENT | CONST_CS);
-+#endif /* LDAP_CONTROL_PASSWORDPOLICYREQUEST */
-+
- 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);
-
-@@ -285,15 +318,176 @@
- DISPLAY_INI_ENTRIES();
- }
- /* }}} */
-
-+
-+/* {{{ proto int _php_parse_referrals_resp()
-+ parse an array of LDAP referrals into a zval array */
-+static int _php_parse_referrals_resp(char ***lreferralsp, zval **referrals)
-+{
-+ int num_referrals = 0;
-+
-+ if (*lreferralsp != NULL) {
-+ char **refp = *lreferralsp;
-+
-+ while (*refp) {
-+ add_next_index_string(*referrals, *refp, 1);
-+ refp++;
-+ num_referrals++;
-+ }
-+#ifdef LDAP_API_FEATURE_X_OPENLDAP
-+ ber_memvfree((void **)*lreferralsp);
-+#else
-+ ldap_value_free(*lreferralsp);
-+#endif
-+ *lreferralsp = NULL;
-+ }
-+
-+ return num_referrals;
-+}
-+/* }}} */
-+
-+/* {{{ proto int _php_parse_controls()
-+ parse an array of zvals into an array of LDAP controls */
-+static int _php_parse_controls(zval **ctrls, LDAPControl ***lctrlsp)
-+{
-+ LDAPControl *lctrl, **lctrls, **lctrlp;
-+ zval **ctrlval, **val;
-+ int ncontrols;
-+ char error = 0;
-+
-+
-+ if ((Z_TYPE_PP(ctrls) != IS_ARRAY) || !(ncontrols = zend_hash_num_elements(Z_ARRVAL_PP(ctrls)))) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Expected non-empty array value");
-+ return 0;
-+ }
-+
-+ lctrls = safe_emalloc((1 + ncontrols), sizeof(*lctrls), 0);
-+ *lctrls = NULL;
-+ lctrlp = lctrls;
-+ zend_hash_internal_pointer_reset(Z_ARRVAL_PP(ctrls));
-+ while (zend_hash_get_current_data(Z_ARRVAL_PP(ctrls), (void**)&ctrlval) == SUCCESS) {
-+ if (Z_TYPE_PP(ctrlval) != IS_ARRAY) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "The array value must contain only arrays, where each array is a control");
-+ error = 1;
-+ break;
-+ }
-+ if (zend_hash_find(Z_ARRVAL_PP(ctrlval), "oid", sizeof("oid"), (void **) &val) == FAILURE) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Control must have an oid key");
-+ error = 1;
-+ break;
-+ }
-+ lctrl = *lctrlp = emalloc(sizeof(**lctrlp));
-+ convert_to_string_ex(val);
-+ lctrl->ldctl_oid = Z_STRVAL_PP(val);
-+ if (zend_hash_find(Z_ARRVAL_PP(ctrlval), "value", sizeof("value"), (void **) &val) == SUCCESS) {
-+ convert_to_string_ex(val);
-+ lctrl->ldctl_value.bv_val = Z_STRVAL_PP(val);
-+ lctrl->ldctl_value.bv_len = Z_STRLEN_PP(val);
-+ } else {
-+ lctrl->ldctl_value.bv_val = NULL;
-+ lctrl->ldctl_value.bv_len = 0;
-+ }
-+ if (zend_hash_find(Z_ARRVAL_PP(ctrlval), "iscritical", sizeof("iscritical"), (void **) &val) == SUCCESS) {
-+ convert_to_boolean_ex(val);
-+ lctrl->ldctl_iscritical = Z_BVAL_PP(val);
-+ } else {
-+ lctrl->ldctl_iscritical = 0;
-+ }
-+
-+ ++lctrlp;
-+ *lctrlp = NULL;
-+ zend_hash_move_forward(Z_ARRVAL_PP(ctrls));
-+ }
-+ if (!error) {
-+ *lctrlsp = lctrls;
-+ }
-+ return ncontrols;
-+}
-+/* }}} */
-+
-+/* {{{ proto void _php_free_controls()
-+ frees an array of LDAP controls as parsed (and malloc'ed) by _php_parse_controls */
-+static void _php_free_controls(LDAPControl ***lctrlsp)
-+{
-+ LDAPControl **lctrlp;
-+
-+ for (lctrlp = *lctrlsp; *lctrlp; lctrlp++) {
-+ efree(*lctrlp);
-+ }
-+ efree(*lctrlsp);
-+ *lctrlsp = NULL;
-+}
-+/* }}} */
-+
-+/* {{{ proto void _php_parse_controls_resp()
-+ parse an array of LDAP controls into a zval array */
-+static int _php_parse_controls_resp(LDAPControl ***lctrlsp, zval **ctrls)
-+{
-+ int num_ctrls = 0;
-+
-+ if (*lctrlsp != NULL) {
-+ int error = 0;
-+ LDAPControl **ctrlp = *lctrlsp;
-+
-+ while (*ctrlp) {
-+ zval *ctrlval = NULL;
-+
-+ if ( (*ctrlp)->ldctl_oid == NULL ) {
-+ error = 1;
-+ break;
-+ }
-+
-+ MAKE_STD_ZVAL(ctrlval);
-+ array_init(ctrlval);
-+
-+ add_assoc_string(ctrlval, "oid", (*ctrlp)->ldctl_oid, 1);
-+ if ( (*ctrlp)->ldctl_value.bv_len ) {
-+ add_assoc_stringl(ctrlval, "value", (*ctrlp)->ldctl_value.bv_val, (*ctrlp)->ldctl_value.bv_len, 1);
-+ }
-+
-+ /* As per <draft-ietf-ldapbis-protocol>:
-+ *
-+ * 4.1.11
-+
-+ The criticality field only has meaning in controls attached to
-+ request messages (except UnbindRequest). For controls attached to
-+ response messages and the UnbindRequest, the criticality field SHOULD
-+ be FALSE, and MUST be ignored by the receiving protocol peer.
-+
-+ */
-+
-+ add_next_index_zval(*ctrls, ctrlval);
-+
-+ num_ctrls++;
-+ ctrlp++;
-+ }
-+ ldap_controls_free(*lctrlsp);
-+ *lctrlsp = NULL;
-+
-+ if (error) {
-+ /* ... */
-+ return -1;
-+ }
-+ }
-+
-+ return num_ctrls;
-+}
-+/* }}} */
-+
- /* {{{ proto resource ldap_connect([string host [, int port [, string wallet [, string wallet_passwd [, int authmode]]]]])
- Connect to an LDAP server */
- PHP_FUNCTION(ldap_connect)
- {
- char *host = NULL;
- int hostlen;
-- long port = 389; /* Default port */
-+ int port =
-+#ifdef LDAP_API_FEATURE_X_OPENLDAP
-+ LDAP_PORT
-+#else /* ! LDAP_API_FEATURE_X_OPENLDAP */
-+ 389 /* Default port */
-+#endif /* ! LDAP_API_FEATURE_X_OPENLDAP */
-+ ;
- #ifdef HAVE_ORALDAP
- char *wallet = NULL, *walletpasswd = NULL;
- int walletlen = 0, walletpasswdlen = 0;
- long authmode = GSLC_SSL_NO_AUTH;
-@@ -327,23 +521,41 @@
-
- ld = ecalloc(1, sizeof(ldap_linkdata));
-
- #ifdef LDAP_API_FEATURE_X_OPENLDAP
-- if (host != NULL && strchr(host, '/')) {
-- int rc;
-+ /* OpenLDAP provides a specific call to detect valid LDAP URIs;
-+ * ldap_init()/ldap_open() is deprecated, use ldap_initialize() instead.
-+ */
-+ {
-+ int rc;
-+ char *url = host;
-+
-+ if (!ldap_is_ldap_url(url)) {
-+ int urllen = hostlen + sizeof( "ldap://:65535" );
-+
-+ if (port <= 0 || port > 65535) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid port number: %ld", port);
-+ RETURN_FALSE;
-+ }
-+
-+ url = emalloc(urllen);
-+ snprintf( url, urllen, "ldap://%s:%d", host ? host : "", port );
-+ }
-
-- rc = ldap_initialize(&ldap, host);
-+ rc = ldap_initialize(&ldap, url);
- if (rc != LDAP_SUCCESS) {
- efree(ld);
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not create session handle: %s", ldap_err2string(rc));
- RETURN_FALSE;
- }
-- } else {
-- ldap = ldap_init(host, port);
-+
-+ if (url != host) {
-+ efree(url);
-+ }
- }
--#else
-+#else /* ! LDAP_API_FEATURE_X_OPENLDAP */
- ldap = ldap_open(host, port);
--#endif
-+#endif /* ! LDAP_API_FEATURE_X_OPENLDAP */
-
- if (ldap == NULL) {
- efree(ld);
- RETURN_FALSE;
-@@ -429,17 +641,33 @@
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Password contains a null byte");
- RETURN_FALSE;
- }
-
-- if ((rc = ldap_bind_s(ld->link, ldap_bind_dn, ldap_bind_pw, LDAP_AUTH_SIMPLE)) != LDAP_SUCCESS) {
-+#ifdef LDAP_API_FEATURE_X_OPENLDAP
-+ {
-+ struct berval cred;
-+
-+ /* ldap_bind_s() is deprecated; use ldap_sasl_bind_s() instead */
-+ cred.bv_val = ldap_bind_pw;
-+ cred.bv_len = ldap_bind_pw ? ldap_bind_pwlen : 0;
-+ rc = ldap_sasl_bind_s(ld->link, ldap_bind_dn, LDAP_SASL_SIMPLE, &cred,
-+ NULL, NULL, /* no controls right now */
-+ NULL); /* we don't care about the server's credentials */
-+ }
-+#else
-+ rc = ldap_bind_s(ld->link, ldap_bind_dn, ldap_bind_pw, LDAP_AUTH_SIMPLE);
-+#endif
-+ if ( rc != LDAP_SUCCESS) {
-+
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to bind to server: %s", ldap_err2string(rc));
- RETURN_FALSE;
- } else {
- RETURN_TRUE;
- }
- }
- /* }}} */
-
-+/* {{{ SASL bind stuff */
- #ifdef HAVE_LDAP_SASL
- typedef struct {
- char *mech;
- char *realm;
-@@ -510,8 +738,10 @@
- break;
- case SASL_CB_USER:
- p = ctx->authzid;
- break;
-+ case SASL_CB_ECHOPROMPT:
-+ case SASL_CB_NOECHOPROMPT:
- case SASL_CB_PASS:
- p = ctx->passwd;
- break;
- }
-@@ -562,8 +792,9 @@
- _php_sasl_freedefs(ctx);
- }
- /* }}} */
- #endif /* HAVE_LDAP_SASL */
-+/* }}} */
-
- /* {{{ proto bool ldap_unbind(resource link)
- Unbind from LDAP directory */
- PHP_FUNCTION(ldap_unbind)
-@@ -1259,9 +1490,14 @@
- for (i = 0; i<count; i++) {
- add_index_string(return_value, i, ldap_value[i], 1);
- }
-
-+#ifdef LDAP_API_FEATURE_X_OPENLDAP
-+ /* ldap_value_free() is deprecated */
-+ ber_memvfree((void **)ldap_value);
-+#else /* ! LDAP_API_FEATURE_X_OPENLDAP */
- ldap_value_free(ldap_value);
-+#endif /* ! LDAP_API_FEATURE_X_OPENLDAP */
- }
- /* }}} */
-
- /* {{{ proto string ldap_dn2ufn(string dn)
-@@ -1292,38 +1528,67 @@
- /* added to fix use of ldap_modify_add for doing an ldap_add, gerrit thomson. */
- #define PHP_LD_FULL_ADD 0xff
- /* {{{ php_ldap_do_modify
- */
--static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper)
-+static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper, int ext)
- {
-- zval *link, *entry, **value, **ivalue;
-+ zval *link, *entry, **value, **ivalue, **sctrls, **cctrls;
- ldap_linkdata *ld;
- char *dn;
- LDAPMod **ldap_mods;
- 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 */
-+ int rc, msgid, myargcount = ZEND_NUM_ARGS();
-+ LDAPMessage *ldap_res;
-+ LDAPControl **lsctrls = NULL, **lcctrls = NULL;
-+ if (ext) {
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsaZZ", &link, &dn, &dn_len, &entry, &sctrls, &cctrls) != SUCCESS)
-+ WRONG_PARAM_COUNT;
-+ } else {
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsa", &link, &dn, &dn_len, &entry) != SUCCESS)
-+ WRONG_PARAM_COUNT;
-+ }
-
-- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsa", &link, &dn, &dn_len, &entry) != SUCCESS) {
-- return;
-- }
-+ if (Z_TYPE_PP(&entry) != IS_ARRAY) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Expected Array as the last element");
-+ RETURN_FALSE;
-+ }
-
-- ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
-
-- num_attribs = zend_hash_num_elements(Z_ARRVAL_P(entry));
-- ldap_mods = safe_emalloc((num_attribs+1), sizeof(LDAPMod *), 0);
-- num_berval = safe_emalloc(num_attribs, sizeof(int), 0);
-- zend_hash_internal_pointer_reset(Z_ARRVAL_P(entry));
-
- /* added by gerrit thomson to fix ldap_add using ldap_mod_add */
- if (oper == PHP_LD_FULL_ADD) {
- oper = LDAP_MOD_ADD;
- is_full_add = 1;
- }
- /* end additional , gerrit thomson */
-
-+ if (myargcount > 3) {
-+ if (is_full_add) {
-+#ifndef HAVE_LDAP_ADD_EXT_S
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "ldap_add_ext not available");
-+ RETURN_FALSE;
-+#endif /* ! HAVE_LDAP_ADD_EXT_S */
-+
-+ } else {
-+#ifndef HAVE_LDAP_MODIFY_EXT_S
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "ldap_modify_ext not available");
-+ RETURN_FALSE;
-+#endif /* ! HAVE_LDAP_MODIFY_EXT_S */
-+ }
-+ }
-+
-+ ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
-+
-+ num_attribs = zend_hash_num_elements(Z_ARRVAL_P(entry));
-+ ldap_mods = safe_emalloc((num_attribs+1), sizeof(LDAPMod *), 0);
-+ num_berval = safe_emalloc(num_attribs, sizeof(int), 0);
-+ zend_hash_internal_pointer_reset(Z_ARRVAL_P(entry));
-+
-+
- for (i = 0; i < num_attribs; i++) {
- ldap_mods[i] = emalloc(sizeof(LDAPMod));
- ldap_mods[i]->mod_op = oper | LDAP_MOD_BVALUES;
- ldap_mods[i]->mod_type = NULL;
-@@ -1381,19 +1646,78 @@
- zend_hash_move_forward(Z_ARRVAL_P(entry));
- }
- ldap_mods[num_attribs] = NULL;
-
-+ if (ext) {
-+ switch (myargcount) {
-+ case 5:
-+ if (_php_parse_controls(cctrls, &lcctrls) == 0) {
-+ RETVAL_FALSE;
-+ goto errexit;
-+ }
-+
-+ case 4:
-+ if (_php_parse_controls(sctrls, &lsctrls) == 0) {
-+ RETVAL_FALSE;
-+ goto errexit;
-+ }
-+ }
-+ }
-+
- /* 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) {
-- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Add: %s", ldap_err2string(i));
-- RETVAL_FALSE;
-- } else RETVAL_TRUE;
-+#ifdef HAVE_LDAP_ADD_EXT_S
-+ if (ext) {
-+ rc = ldap_add_ext(ld->link, dn, ldap_mods, lsctrls, lcctrls, &msgid);
-+
-+ } else {
-+ rc = ldap_add_ext_s(ld->link, dn, ldap_mods, NULL, NULL);
-+ }
-+#else /* ! HAVE_LDAP_ADD_EXT_S */
-+ rc = ldap_add_s(ld->link, dn, ldap_mods);
-+#endif /* ! HAVE_LDAP_ADD_EXT_S */
-+
- } else {
-- if ((i = ldap_modify_ext_s(ld->link, dn, ldap_mods, NULL, NULL)) != LDAP_SUCCESS) {
-- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Modify: %s", ldap_err2string(i));
-- RETVAL_FALSE;
-- } else RETVAL_TRUE;
-+#ifdef HAVE_LDAP_MODIFY_EXT_S
-+ if (ext) {
-+ rc = ldap_modify_ext(ld->link, dn, ldap_mods, lsctrls, lcctrls, &msgid);
-+
-+ } else {
-+ rc = ldap_modify_ext_s(ld->link, dn, ldap_mods, NULL, NULL);
-+ }
-+#else /* ! HAVE_LDAP_MODIFY_EXT_S */
-+ rc = ldap_modify_s(ld->link, dn, ldap_mods);
-+#endif /* ! HAVE_LDAP_MODIFY_EXT_S */
-+ }
-+
-+ if (rc != LDAP_SUCCESS) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s: %s", is_full_add ? "Add" : "Modify", ldap_err2string(i));
-+ RETVAL_FALSE;
-+
-+ } else {
-+ if (ext) {
-+ rc = ldap_result(ld->link, msgid, LDAP_MSG_ALL, NULL, &ldap_res);
-+ if ((is_full_add && rc != LDAP_RES_ADD) || (!is_full_add && rc != LDAP_RES_MODIFY)) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s: unable to collect result", is_full_add ? "Add" : "Modify");
-+ RETVAL_FALSE;
-+
-+ } else {
-+ int lerr;
-+
-+ ZEND_REGISTER_RESOURCE(return_value, ldap_res, le_result);
-+ rc = ldap_parse_result(ld->link, ldap_res, &lerr, NULL, NULL, NULL, NULL, 0);
-+ if (rc == LDAP_SUCCESS) {
-+ rc = lerr;
-+ }
-+
-+ if (rc != LDAP_SUCCESS) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s failed: %s", is_full_add ? "Add" : "Modify", ldap_err2string(rc));
-+ }
-+ }
-+
-+ } else {
-+ RETVAL_TRUE;
-+ }
- }
-
- errexit:
- for (i = 0; i < num_attribs; i++) {
-@@ -1406,46 +1730,57 @@
- }
- efree(num_berval);
- efree(ldap_mods);
-
-+ if (ext) {
-+ if (lsctrls) {
-+ _php_free_controls(&lsctrls);
-+ }
-+ if (lcctrls) {
-+ _php_free_controls(&lcctrls);
-+ }
-+ }
-+
- return;
- }
- /* }}} */
-
- /* {{{ proto bool ldap_add(resource link, string dn, array entry)
- Add entries to LDAP directory */
- 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);
-+ /* 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, 0);
- }
- /* }}} */
-
--/* three functions for attribute base modifications, gerrit Thomson */
-+/* {{{ Three functions for attribute base modifications, gerrit Thomson */
-
- /* {{{ proto bool ldap_mod_replace(resource link, string dn, array entry)
- 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);
- }
- /* }}} */
-
- /* {{{ proto bool ldap_mod_add(resource link, string dn, array entry)
- 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);
- }
- /* }}} */
-
- /* {{{ proto bool ldap_mod_del(resource link, string dn, array entry)
-+
- 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);
- }
- /* }}} */
-+/* }}} */
-
- /* {{{ proto bool ldap_delete(resource link, string dn)
- Delete an entry from a directory */
- PHP_FUNCTION(ldap_delete)
-@@ -1869,38 +2204,109 @@
- RETURN_STRING(ldap_err2string(ld_errno), 1);
- }
- /* }}} */
-
--/* {{{ proto bool ldap_compare(resource link, string dn, string attr, string value)
-- Determine if an entry has a specific value for one of its attributes */
--PHP_FUNCTION(ldap_compare)
-+/* {{{ proto void php_ldap_do_compare */
-+void php_ldap_do_compare(INTERNAL_FUNCTION_PARAMETERS, int ext)
- {
-- zval *link;
-- char *dn, *attr, *value;
-+ zval *link, *dn, *attr, *value, **sctrls, **cctrls;
-+ char *ldap_dn, *ldap_attr;
- int dn_len, attr_len, value_len;
- ldap_linkdata *ld;
-- int errno;
-+ int rc, msgid, lerr, myargcount = ZEND_NUM_ARGS();
-+ LDAPMessage *ldap_res;
-+ LDAPControl **lsctrls = NULL, **lcctrls = NULL;
-
-- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsss", &link, &dn, &dn_len, &attr, &attr_len, &value, &value_len) != SUCCESS) {
-- return;
-+ if (ext) {
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsss|ZZ", &link, &dn, &dn_len, &attr, &attr_len, &value, &value_len, &sctrls, &cctrls) != SUCCESS) {
-+ WRONG_PARAM_COUNT;
-+ }
-+ } else {
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsss", &link, &dn, &dn_len, &attr, &attr_len, &value, &value_len) != SUCCESS) {
-+ WRONG_PARAM_COUNT;
-+ }
- }
-
- ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
-
-- errno = ldap_compare_s(ld->link, dn, attr, value);
--
-- switch (errno) {
-- case LDAP_COMPARE_TRUE:
-- RETURN_TRUE;
-- break;
-+ if (ext) {
-+ struct berval ldap_bvalue;
-+ switch (myargcount) {
-+ case 6:
-+ _php_parse_controls(cctrls, &lcctrls);
-+ case 5:
-+ _php_parse_controls(sctrls, &lsctrls);
-+ }
-
-- case LDAP_COMPARE_FALSE:
-+ ldap_bvalue.bv_val = Z_STRVAL_PP(&value);
-+ ldap_bvalue.bv_len = Z_STRLEN_PP(&value);
-+ rc = ldap_compare_ext(ld->link, ldap_dn, ldap_attr, &ldap_bvalue, lsctrls, lcctrls, &msgid);
-+ if (lsctrls) {
-+ _php_free_controls(&lsctrls);
-+ }
-+ if (lcctrls) {
-+ _php_free_controls(&lcctrls);
-+ }
-+ if (rc != LDAP_SUCCESS) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Compare: %s", ldap_err2string(rc));
- RETURN_FALSE;
-- break;
-+ }
-+
-+ rc = ldap_result(ld->link, msgid, LDAP_MSG_ALL, NULL, &ldap_res);
-+ if (rc != LDAP_RES_COMPARE) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Compare: unable to get result");
-+ RETURN_FALSE;
-+ }
-+
-+ ZEND_REGISTER_RESOURCE(return_value, ldap_res, le_result);
-+ rc = ldap_parse_result(ld->link, ldap_res, &lerr, NULL, NULL, NULL, NULL, 0);
-+ if (rc == LDAP_SUCCESS) {
-+ rc = lerr;
-+ }
-+
-+ switch (rc) {
-+ case LDAP_COMPARE_TRUE:
-+ case LDAP_COMPARE_FALSE:
-+ break;
-+
-+ default:
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Compare failed: %s", ldap_err2string(rc));
-+ break;
-+ }
-+
-+ } else {
-+#ifdef HAVE_LDAP_COMPARE_EXT_S
-+ struct berval ldap_bvalue;
-+
-+ ldap_bvalue.bv_val = Z_STRVAL_PP(&value);
-+ ldap_bvalue.bv_len = Z_STRLEN_PP(&value);
-+ rc = ldap_compare_ext_s(ld->link, ldap_dn, ldap_attr, &ldap_bvalue, NULL, NULL);
-+#else /* ! HAVE_LDAP_COMPARE_EXT_S */
-+ char *ldap_value;
-+
-+ ldap_value = Z_STRVAL_PP(&value);
-+ rc = ldap_compare_s(ld->link, ldap_dn, ldap_attr, ldap_value);
-+#endif /* ! HAVE_LDAP_COMPARE_EXT_S */
-+
-+ switch (rc) {
-+ case LDAP_COMPARE_TRUE:
-+ RETURN_TRUE;
-+ break;
-+
-+ case LDAP_COMPARE_FALSE:
-+ RETURN_FALSE;
-+ break;
-+ }
-+
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Compare: %s", ldap_err2string(rc));
-+ RETURN_LONG(-1);
- }
--
-- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Compare: %s", ldap_err2string(errno));
-- RETURN_LONG(-1);
-+}
-+/* {{{ proto bool ldap_compare(resource link, string dn, string attr, string valu)
-+ Determine if an entry has a specific value for one of its attributes */
-+PHP_FUNCTION(ldap_compare)
-+{
-+ php_ldap_do_compare(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
- }
- /* }}} */
-
- /* {{{ proto bool ldap_sort(resource link, resource result, string sortfilter)
-@@ -1932,59 +2338,233 @@
- RETURN_TRUE;
- }
- /* }}} */
-
--#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP
--/* {{{ proto bool ldap_get_option(resource link, int option, mixed retval)
-- Get the current value of various session-wide parameters */
--PHP_FUNCTION(ldap_get_option)
-+/* {{{ Extended API that returns result instead of just bool
-+ * to allow further manipulation by the ldap_parse_*() funcs,
-+ * Pierangelo Masarati */
-+
-+/* {{{ proto result ldap_bind_ext(resource link [, string dn, string password])
-+ Bind to LDAP directory */
-+PHP_FUNCTION(ldap_bind_ext)
- {
-- zval *link, *retval;
-+ zval *link;
-+ char *ldap_bind_dn = NULL, *ldap_bind_pw = NULL;
-+ int ldap_bind_dnlen, ldap_bind_pwlen;
- ldap_linkdata *ld;
-- long option;
--
-- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rlz", &link, &option, &retval) != SUCCESS) {
-- return;
-+ int rc, msgid, lerr;
-+ LDAPMessage *ldap_res;
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|ss", &link, &ldap_bind_dn, &ldap_bind_dnlen, &ldap_bind_pw, &ldap_bind_pwlen) == FAILURE) {
-+
-+ RETURN_FALSE;
- }
-
- ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
-
-- switch (option) {
-- /* options with int value */
-- case LDAP_OPT_DEREF:
-- case LDAP_OPT_SIZELIMIT:
-- case LDAP_OPT_TIMELIMIT:
-- case LDAP_OPT_PROTOCOL_VERSION:
-- case LDAP_OPT_ERROR_NUMBER:
-- case LDAP_OPT_REFERRALS:
--#ifdef LDAP_OPT_RESTART
-- case LDAP_OPT_RESTART:
-+#ifdef LDAP_API_FEATURE_X_OPENLDAP
-+ {
-+ struct berval cred;
-+
-+ /* ldap_bind() is deprecated; use ldap_sasl_bind() instead */
-+ cred.bv_val = ldap_bind_pw;
-+ cred.bv_len = ldap_bind_pw ? ldap_bind_pwlen : 0;
-+
-+ rc = ldap_sasl_bind(ld->link, ldap_bind_dn, LDAP_SASL_SIMPLE, &cred,
-+ NULL, NULL, /* no controls right now */
-+ &msgid);
-+ if (rc != LDAP_SUCCESS) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to bind: %s", ldap_err2string(rc));
-+ RETURN_FALSE;
-+ }
-+ }
-+#else
-+ msgid = ldap_bind(ld->link, ldap_bind_dn, ldap_bind_pw, LDAP_AUTH_SIMPLE);
-+ if (msgid == -1) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to bind");
-+ RETURN_FALSE;
-+ }
- #endif
-- {
-- int val;
-
-- if (ldap_get_option(ld->link, option, &val)) {
-- RETURN_FALSE;
-- }
-- zval_dtor(retval);
-- ZVAL_LONG(retval, val);
-- } break;
--#ifdef LDAP_OPT_NETWORK_TIMEOUT
-- case LDAP_OPT_NETWORK_TIMEOUT:
-- {
-- struct timeval *timeout = NULL;
-+ rc = ldap_result(ld->link, msgid, LDAP_MSG_ALL, NULL, &ldap_res);
-+ if (rc != LDAP_RES_BIND) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to get bind result: %s", ldap_err2string(rc));
-+ RETURN_FALSE;
-+ }
-
-- if (ldap_get_option(ld->link, LDAP_OPT_NETWORK_TIMEOUT, (void *) &timeout)) {
-- if (timeout) {
-- ldap_memfree(timeout);
-- }
-- RETURN_FALSE;
-- }
-- if (!timeout) {
-- RETURN_FALSE;
-- }
-- zval_dtor(retval);
-- ZVAL_LONG(retval, timeout->tv_sec);
-+ ZEND_REGISTER_RESOURCE(return_value, ldap_res, le_result);
-+ rc = ldap_parse_result(ld->link, ldap_res, &lerr, NULL, NULL, NULL, NULL, 0);
-+ if (rc == LDAP_SUCCESS) {
-+ rc = lerr;
-+ }
-+
-+
-+ if (rc != LDAP_SUCCESS) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to bind to server: %s", ldap_err2string(rc));
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto result ldap_add_ext(resource link, string dn, array entry)
-+ Add entries to LDAP directory; returns result */
-+PHP_FUNCTION(ldap_add_ext)
-+{
-+ php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_LD_FULL_ADD, 1);
-+}
-+/* }}} */
-+
-+/* {{{ proto result ldap_mod_replace_ext(resource link, string dn, array entry)
-+ Replace attribute values with new ones */
-+PHP_FUNCTION(ldap_mod_replace_ext)
-+{
-+ php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_MOD_REPLACE, 1);
-+}
-+/* }}} */
-+
-+
-+/* {{{ proto result ldap_mod_add_ext(resource link, string dn, array entry)
-+ Add attribute values to current */
-+PHP_FUNCTION(ldap_mod_add_ext)
-+{
-+ php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_MOD_ADD, 1);
-+}
-+/* }}} */
-+
-+/* {{{ proto result ldap_mod_del_ext(resource link, string dn, array entry)
-+ Delete attribute values */
-+PHP_FUNCTION(ldap_mod_del_ext)
-+{
-+ php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_MOD_DELETE, 1);
-+}
-+/* }}} */
-+
-+/* {{{ proto result ldap_delete_ext(resource link, string dn)
-+ Delete an entry from a directory */
-+PHP_FUNCTION(ldap_delete_ext)
-+{
-+ zval **link, **dn, **sctrls, **cctrls;
-+ ldap_linkdata *ld;
-+ char *ldap_dn;
-+ int rc, dn_len, msgid, lerr, myargcount = ZEND_NUM_ARGS();
-+ LDAPMessage *ldap_res;
-+ LDAPControl **lsctrls = NULL, **lcctrls = NULL;
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|ZZ", &link, &dn, &dn_len, &sctrls, &cctrls) == FAILURE) {
-+ WRONG_PARAM_COUNT;
-+ }
-+
-+ switch (myargcount) {
-+ case 4:
-+ _php_parse_controls(cctrls, &lcctrls);
-+
-+ case 3:
-+ _php_parse_controls(sctrls, &lsctrls);
-+ }
-+
-+ ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, link, -1, "ldap link", le_link);
-+
-+ convert_to_string_ex(dn);
-+ ldap_dn = Z_STRVAL_PP(dn);
-+
-+#ifdef HAVE_LDAP_DELETE_EXT_S
-+ rc = ldap_delete_ext_s(ld->link, ldap_dn, NULL, NULL);
-+#else /* ! HAVE_LDAP_DELETE_EXT_S */
-+ rc = ldap_delete_s(ld->link, ldap_dn);
-+#endif /* ! HAVE_LDAP_DELETE_EXT_S */
-+ if (lsctrls) {
-+ _php_free_controls(&lsctrls);
-+ }
-+ if (lcctrls) {
-+ _php_free_controls(&lcctrls);
-+ }
-+ if (rc != LDAP_SUCCESS) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Delete: %s", ldap_err2string(rc));
-+ RETURN_FALSE;
-+ }
-+
-+ rc = ldap_result(ld->link, msgid, LDAP_MSG_ALL, NULL, &ldap_res);
-+ if (rc != LDAP_RES_DELETE) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Delete: unable to get result");
-+ RETURN_FALSE;
-+ }
-+
-+ ZEND_REGISTER_RESOURCE(return_value, ldap_res, le_result);
-+ rc = ldap_parse_result(ld->link, ldap_res, &lerr, NULL, NULL, NULL, NULL, 0);
-+ if (rc == LDAP_SUCCESS) {
-+ rc = lerr;
-+ }
-+
-+ if (rc != LDAP_SUCCESS) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Delete failed: %s", ldap_err2string(rc));
-+ }
-+}
-+/* }}} */
-+
-+/* }}} End of extended API, Pierangelo Masarati */
-+
-+
-+/* {{{ proto result ldap_compare_ext(resource link, string dn, string attr, string value)
-+ Determine if an entry has a specific value for one of its attributes */
-+PHP_FUNCTION(ldap_compare_ext)
-+{
-+ php_ldap_do_compare(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
-+}
-+/* }}} */
-+
-+/* }}} End of extended API, Pierangelo Masarati */
-+
-+
-+#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10
-+/* {{{ proto bool ldap_get_option(resource link, int option, mixed retval)
-+ Get the current value of various session-wide parameters */
-+PHP_FUNCTION(ldap_get_option)
-+{
-+ zval *link, *retval;
-+ ldap_linkdata *ld;
-+ long option;
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rlz", &link, &option, &retval) != SUCCESS) {
-+ return;
-+ }
-+
-+ ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
-+
-+ switch (option) {
-+ /* options with int value */
-+ case LDAP_OPT_DEREF:
-+ case LDAP_OPT_SIZELIMIT:
-+ case LDAP_OPT_TIMELIMIT:
-+ case LDAP_OPT_PROTOCOL_VERSION:
-+ case LDAP_OPT_ERROR_NUMBER:
-+ case LDAP_OPT_REFERRALS:
-+#ifdef LDAP_OPT_RESTART
-+ case LDAP_OPT_RESTART:
-+#endif
-+ {
-+ int val;
-+
-+ if (ldap_get_option(ld->link, option, &val)) {
-+ RETURN_FALSE;
-+ }
-+ zval_dtor(retval);
-+ ZVAL_LONG(retval, val);
-+ } break;
-+#ifdef LDAP_OPT_NETWORK_TIMEOUT
-+ case LDAP_OPT_NETWORK_TIMEOUT:
-+ {
-+ struct timeval *timeout = NULL;
-+
-+ if (ldap_get_option(ld->link, LDAP_OPT_NETWORK_TIMEOUT, (void *) &timeout)) {
-+ if (timeout) {
-+ ldap_memfree(timeout);
-+ }
-+ RETURN_FALSE;
-+ }
-+ if (!timeout) {
-+ RETURN_FALSE;
-+ }
-+ zval_dtor(retval);
-+ ZVAL_LONG(retval, timeout->tv_sec);
- ldap_memfree(timeout);
- } break;
- #elif defined(LDAP_X_OPT_CONNECT_TIMEOUT)
- case LDAP_X_OPT_CONNECT_TIMEOUT:
-@@ -2207,21 +2787,23 @@
- }
- /* }}} */
-
- #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;
- ldap_linkdata *ld;
- LDAPMessage *ldap_result;
-- char **lreferrals, **refp;
-+ LDAPControl **lserverctrls;
-+ char **lreferrals;
- char *lmatcheddn, *lerrmsg;
- int rc, lerrcode, myargcount = ZEND_NUM_ARGS();
-+ /* int matcheddn_len, errmsg_len; */
-
-- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rrz|zzz", &link, &result, &errcode, &matcheddn, &errmsg, &referrals) != SUCCESS) {
-- return;
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rrz|zzzz", &link, &result, &errcode, &matcheddn, &errmsg, &referrals, &serverctrls) != SUCCESS) {
-+ WRONG_PARAM_COUNT;
- }
-
- ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
- ZEND_FETCH_RESOURCE(ldap_result, LDAPMessage *, &result, -1, "ldap result", le_result);
-@@ -2229,9 +2811,9 @@
- rc = ldap_parse_result(ld->link, ldap_result, &lerrcode,
- 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));
- RETURN_FALSE;
-@@ -2241,19 +2823,15 @@
- ZVAL_LONG(errcode, lerrcode);
-
- /* Reverse -> fall through */
- switch (myargcount) {
-+ case 7:
-+ /* use arg #7 as the array of controls returned by the server */
-+ zval_dtor(serverctrls);
-+ array_init(serverctrls);
-+ _php_parse_controls_resp(&lserverctrls, &serverctrls);
- case 6:
-- zval_dtor(referrals);
-- array_init(referrals);
-- if (lreferrals != NULL) {
-- refp = lreferrals;
-- while (*refp) {
-- add_next_index_string(referrals, *refp, 1);
-- refp++;
-- }
-- ldap_value_free(lreferrals);
-- }
-+ _php_parse_referrals_resp(&lreferrals, &referrals);
- case 5:
- zval_dtor(errmsg);
- if (lerrmsg == NULL) {
- ZVAL_EMPTY_STRING(errmsg);
-@@ -2274,8 +2852,142 @@
- }
- /* }}} */
- #endif
-
-+/* {{{ Extended operation response parsing, Pierangelo Masarati */
-+#ifdef HAVE_LDAP_PARSE_EXTENDED_RESULT
-+/* {{{ proto bool ldap_parse_exop(resource link, resource result [, string retoid [, string retdata]])
-+ Extract information from extended operation result */
-+PHP_FUNCTION(ldap_parse_exop)
-+{
-+ zval *link, *result, *retoid, *retdata;
-+ ldap_linkdata *ld;
-+ LDAPMessage *ldap_result;
-+ char *lretoid;
-+ struct berval *lretdata;
-+ int rc, myargcount = ZEND_NUM_ARGS();
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rr|zz", &link, &result, &retoid, &retdata) == SUCCESS) {
-+ WRONG_PARAM_COUNT;
-+ }
-+
-+ ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
-+ ZEND_FETCH_RESOURCE(ldap_result, LDAPMessage *, &result, -1, "ldap result", le_result);
-+
-+ rc = ldap_parse_extended_result(ld->link, ldap_result,
-+ myargcount > 2 ? &lretoid: NULL,
-+ myargcount > 3 ? &lretdata: NULL,
-+ 0);
-+ if (rc != LDAP_SUCCESS) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to parse extended operation result: %s", ldap_err2string(rc));
-+ RETURN_FALSE;
-+ }
-+
-+ /* Reverse -> fall through */
-+ switch (myargcount) {
-+ case 4:
-+ /* use arg #4 as the data returned by the server */
-+ zval_dtor(retdata);
-+ if (lretdata == NULL) {
-+ ZVAL_EMPTY_STRING(retdata);
-+ } else {
-+ ZVAL_STRINGL(retdata, lretdata->bv_val, lretdata->bv_len, 1);
-+ ldap_memfree(lretdata->bv_val);
-+ ldap_memfree(lretdata);
-+ }
-+ case 3:
-+ zval_dtor(retoid);
-+ if (lretoid == NULL) {
-+ ZVAL_EMPTY_STRING(retoid);
-+ } else {
-+ ZVAL_STRING(retoid, lretoid, 1);
-+ ldap_memfree(lretoid);
-+ }
-+ }
-+ RETURN_TRUE;
-+}
-+/* }}} */
-+
-+#ifdef HAVE_LDAP_PARSE_PASSWD
-+/* {{{ proto bool ldap_parse_exop_passwd(resource link, resource result, string newpasswd)
-+ Extract information from RFC 3062 password modify extended operation result */
-+PHP_FUNCTION(ldap_parse_exop_passwd)
-+{
-+ zval **link, **result, **newpasswd;
-+ ldap_linkdata *ld;
-+ LDAPMessage *ldap_result;
-+ struct berval lnewpasswd;
-+ int rc, myargcount = ZEND_NUM_ARGS();
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZZ", &link, &result, &newpasswd) != SUCCESS) {
-+ WRONG_PARAM_COUNT;
-+ }
-+
-+ ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, link, -1, "ldap link", le_link);
-+ ZEND_FETCH_RESOURCE(ldap_result, LDAPMessage *, result, -1, "ldap result", le_result);
-+
-+ rc = ldap_parse_passwd(ld->link, ldap_result, &lnewpasswd);
-+ if (rc != LDAP_SUCCESS) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to parse passwd modify extended operation result: %s", ldap_err2string(rc));
-+ RETURN_FALSE;
-+ }
-+
-+ zval_dtor(*newpasswd);
-+ if (lnewpasswd.bv_len == 0) {
-+ ZVAL_EMPTY_STRING(*newpasswd);
-+ } else {
-+ ZVAL_STRINGL(*newpasswd, lnewpasswd.bv_val, lnewpasswd.bv_len, 1);
-+ ldap_memfree(lnewpasswd.bv_val);
-+ }
-+
-+ RETURN_TRUE;
-+}
-+#else
-+/* TODO: implement based on ldap_parse_exop() */
-+/* }}} */
-+#endif
-+
-+#ifdef HAVE_LDAP_PARSE_WHOAMI
-+/* {{{ proto bool ldap_parse_exop_whoami(resource link, resource result, string authzid)
-+ Extract information from <draft-zeilenga-ldap-authzid> whoami extended operation result (a Work in Progress) */
-+PHP_FUNCTION(ldap_parse_exop_whoami)
-+{
-+ zval **link, **result, **authzid;
-+ ldap_linkdata *ld;
-+ LDAPMessage *ldap_result;
-+ struct berval *lauthzid;
-+ int rc, myargcount = ZEND_NUM_ARGS();
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZZ", &link, &result, &authzid) != SUCCESS) {
-+ WRONG_PARAM_COUNT;
-+ }
-+
-+ ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, link, -1, "ldap link", le_link);
-+ ZEND_FETCH_RESOURCE(ldap_result, LDAPMessage *, result, -1, "ldap result", le_result);
-+
-+ rc = ldap_parse_whoami(ld->link, ldap_result, &lauthzid );
-+ if (rc != LDAP_SUCCESS) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to parse whoami extended operation result: %s", ldap_err2string(rc));
-+ RETURN_FALSE;
-+ }
-+
-+ zval_dtor(*authzid);
-+ if (lauthzid == NULL) {
-+ ZVAL_EMPTY_STRING(*authzid);
-+ } else {
-+ ZVAL_STRINGL(*authzid, lauthzid->bv_val, lauthzid->bv_len, 1);
-+ ldap_memfree(lauthzid->bv_val);
-+ ldap_memfree(lauthzid);
-+ }
-+ RETURN_TRUE;
-+}
-+#else
-+/* TODO: implement based on ldap_parse_extended_result() */
-+/* }}} */
-+#endif
-+/* }}} */
-+#endif
-+
- /* {{{ proto resource ldap_first_reference(resource link, resource result)
- Return first reference */
- PHP_FUNCTION(ldap_first_reference)
- {
-@@ -2758,53 +3470,735 @@
- }
- /* }}} */
- #endif
-
--/* {{{ arginfo */
--ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_connect, 0, 0, 0)
-- ZEND_ARG_INFO(0, hostname)
-- ZEND_ARG_INFO(0, port)
--#ifdef HAVE_ORALDAP
-- ZEND_ARG_INFO(0, wallet)
-- ZEND_ARG_INFO(0, wallet_passwd)
-- ZEND_ARG_INFO(0, authmode)
--#endif
--ZEND_END_ARG_INFO()
-+/* {{{ Extended operations, Pierangelo Masarati */
-+#ifdef HAVE_LDAP_EXTENDED_OPERATION_S
-+/* {{{ proto ? ldap_exop(resource link, string reqoid [, string reqdata [, string retoid [, string retdata]]])
-+ Extended operation */
-+PHP_FUNCTION(ldap_exop)
-+{
-+ zval **link, **reqoid, **reqdata, **retoid, **retdata;
-+ char *lreqoid, *lretoid = NULL;
-+ struct berval lreqdata, *lretdata = NULL;
-+ ldap_linkdata *ld;
-+ LDAP *ldap;
-+ LDAPMessage *ldap_res;
-+ int rc, msgid, myargcount = ZEND_NUM_ARGS();
-+ /* int reqoid_len, reqdata_len, retdata_len, retoid_len, retdat_len; */
-
--ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_resource, 0, 0, 1)
-- ZEND_ARG_INFO(0, link_identifier)
--ZEND_END_ARG_INFO()
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZ|ZZZ", &link, &reqoid, &reqdata, &retoid, &retdata) != SUCCESS) {
-+ WRONG_PARAM_COUNT;
-+ }
-
--ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_bind, 0, 0, 1)
-- ZEND_ARG_INFO(0, link_identifier)
-- ZEND_ARG_INFO(0, bind_rdn)
-- ZEND_ARG_INFO(0, bind_password)
--ZEND_END_ARG_INFO()
-+ if (Z_TYPE_PP(link) == IS_NULL) {
-+ ldap = NULL;
-+ } else {
-+ ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, link, -1, "ldap link", le_link);
-+ ldap = ld->link;
-+ }
-
--#ifdef HAVE_LDAP_SASL
--ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_sasl_bind, 0, 0, 1)
-- ZEND_ARG_INFO(0, link)
-- ZEND_ARG_INFO(0, binddn)
-- ZEND_ARG_INFO(0, password)
-- ZEND_ARG_INFO(0, sasl_mech)
-- ZEND_ARG_INFO(0, sasl_realm)
-- ZEND_ARG_INFO(0, sasl_authz_id)
-- ZEND_ARG_INFO(0, props)
--ZEND_END_ARG_INFO()
--#endif
-+ switch (myargcount) {
-+ case 5:
-+ case 4:
-+ case 3:
-+ convert_to_string_ex(reqdata);
-+ lreqdata.bv_val = Z_STRVAL_PP(reqdata);
-+ lreqdata.bv_len = Z_STRLEN_PP(reqdata);
-+ /* fallthru */
-+ case 2:
-+ convert_to_string_ex(reqoid);
-+ lreqoid = Z_STRVAL_PP(reqoid);
-+ }
-+
-+ if (myargcount > 3) {
-+ /* synchronous call */
-+ rc = ldap_extended_operation_s(ld->link, lreqoid,
-+ lreqdata.bv_len > 0 ? &lreqdata: NULL,
-+ NULL,
-+ NULL,
-+ &lretoid,
-+ myargcount > 4 ? &lretdata : NULL );
-+ if (rc != LDAP_SUCCESS ) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Extended operation %s failed: %s (%d)", lreqoid, ldap_err2string(rc), rc);
-+ RETURN_FALSE;
-+ }
-
--ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_read, 0, 0, 3)
-- ZEND_ARG_INFO(0, link_identifier)
-- ZEND_ARG_INFO(0, base_dn)
-- ZEND_ARG_INFO(0, filter)
-- ZEND_ARG_INFO(0, attributes)
-- ZEND_ARG_INFO(0, attrsonly)
-- ZEND_ARG_INFO(0, sizelimit)
-- ZEND_ARG_INFO(0, timelimit)
-- ZEND_ARG_INFO(0, deref)
--ZEND_END_ARG_INFO()
-+ /* Reverse -> fall through */
-+ switch (myargcount) {
-+ case 5:
-+ /* use arg #4 as the data returned by the server */
-+ zval_dtor(*retdata);
-+ if (lretdata == NULL) {
-+ ZVAL_EMPTY_STRING(*retdata);
-+ } else {
-+ ZVAL_STRINGL(*retdata, lretdata->bv_val, lretdata->bv_len, 1);
-+ ldap_memfree(lretdata->bv_val);
-+ ldap_memfree(lretdata);
-+ }
-+ case 4:
-+ zval_dtor(*retoid);
-+ if (lretoid == NULL) {
-+ ZVAL_EMPTY_STRING(*retoid);
-+ } else {
-+ ZVAL_STRING(*retoid, lretoid, 1);
-+ ldap_memfree(lretoid);
-+ }
-+ }
-
--ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_list, 0, 0, 3)
-+ RETURN_TRUE;
-+ }
-+
-+ /* asynchronous call */
-+ rc = ldap_extended_operation(ld->link, lreqoid,
-+ lreqdata.bv_len > 0 ? &lreqdata: NULL,
-+ NULL, NULL, &msgid);
-+ if (rc != LDAP_SUCCESS ) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Extended operation %s failed: %s (%d)", lreqoid, ldap_err2string(rc), rc);
-+ RETURN_FALSE;
-+ }
-+
-+ rc = ldap_result(ld->link, msgid, 1 /* LDAP_MSG_ALL */, NULL, &ldap_res);
-+ if (rc == -1) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Extended operation %s failed", lreqoid);
-+ RETURN_FALSE;
-+ }
-+
-+ /* return a PHP control object */
-+ array_init(return_value);
-+
-+ ZEND_REGISTER_RESOURCE(return_value, ldap_res, le_result);
-+}
-+/* }}} */
-+
-+#ifdef HAVE_LDAP_PASSWD_S
-+/* {{{ proto ? ldap_exop_passwd(resource link [, string user [, string oldpw [, string newpw [, string newpasswd ]]]])
-+ Passwd modify extended operation */
-+PHP_FUNCTION(ldap_exop_passwd)
-+{
-+ zval **link, **user, **newpw, **oldpw, **newpasswd;
-+ struct berval luser, loldpw, lnewpw, lnewpasswd;
-+ ldap_linkdata *ld;
-+ LDAP *ldap;
-+ LDAPMessage *ldap_res;
-+ int rc, msgid, myargcount = ZEND_NUM_ARGS();
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z|ZZZZ", &link, &user, &oldpw, &newpw, &newpasswd) == FAILURE) {
-+ WRONG_PARAM_COUNT;
-+ }
-+
-+ if (Z_TYPE_PP(link) == IS_NULL) {
-+ ldap = NULL;
-+ } else {
-+ ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, link, -1, "ldap link", le_link);
-+ ldap = ld->link;
-+ }
-+
-+ luser.bv_len = 0;
-+ loldpw.bv_len = 0;
-+ lnewpw.bv_len = 0;
-+
-+ switch (myargcount) {
-+ case 5:
-+ case 4:
-+ convert_to_string_ex(newpw);
-+ lnewpw.bv_val = Z_STRVAL_PP(newpw);
-+ lnewpw.bv_len = Z_STRLEN_PP(newpw);
-+
-+ case 3:
-+ convert_to_string_ex(oldpw);
-+ loldpw.bv_val = Z_STRVAL_PP(oldpw);
-+ loldpw.bv_len = Z_STRLEN_PP(oldpw);
-+
-+ case 2:
-+ convert_to_string_ex(user);
-+ luser.bv_val = Z_STRVAL_PP(user);
-+ luser.bv_len = Z_STRLEN_PP(user);
-+ }
-+
-+ if (myargcount > 4 || lnewpw.bv_len > 0) {
-+ /* synchronous call */
-+ rc = ldap_passwd_s(ld->link, &luser,
-+ loldpw.bv_len > 0 ? &loldpw : NULL,
-+ /* loldpw.bv_len > 0 ? &loldpw : NULL, */
-+ lnewpw.bv_len > 0 ? &lnewpw : NULL,
-+ &lnewpasswd, NULL, NULL);
-+ if (rc != LDAP_SUCCESS ) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Passwd modify extended operation failed: %s (%d)", ldap_err2string(rc), rc);
-+ RETURN_FALSE;
-+ }
-+
-+ if (myargcount > 4) {
-+ zval_dtor(*newpasswd);
-+ if (lnewpasswd.bv_len == 0) {
-+ ZVAL_EMPTY_STRING(*newpasswd);
-+ } else {
-+ ZVAL_STRINGL(*newpasswd, lnewpasswd.bv_val, lnewpasswd.bv_len, 1);
-+ }
-+ }
-+
-+ ldap_memfree(lnewpasswd.bv_val);
-+
-+ RETURN_TRUE;
-+ }
-+
-+ /* asynchronous call */
-+ rc = ldap_passwd(ld->link, &luser,
-+ loldpw.bv_len > 0 ? &loldpw : NULL,
-+ lnewpw.bv_len > 0 ? &lnewpw : NULL,
-+ NULL, NULL, &msgid);
-+ if (rc != LDAP_SUCCESS ) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Passwd modify extended operation failed: %s (%d)", ldap_err2string(rc), rc);
-+ RETURN_FALSE;
-+ }
-+
-+ rc = ldap_result(ld->link, msgid, 1 /* LDAP_MSG_ALL */, NULL, &ldap_res);
-+ if (rc == -1) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Passwd modify extended operation failed");
-+ RETURN_FALSE;
-+ }
-+
-+ /* return a PHP control object */
-+ array_init(return_value);
-+
-+ ZEND_REGISTER_RESOURCE(return_value, ldap_res, le_result);
-+}
-+#else
-+/* TODO: implement based on ldap_extended_operation_s() */
-+/* }}} */
-+#endif
-+
-+#ifdef HAVE_LDAP_WHOAMI_S
-+/* {{{ proto bool ldap_exop_whoami(resource link [, string authzid])
-+ Whoami extended operation */
-+PHP_FUNCTION(ldap_exop_whoami)
-+{
-+ zval **link, **authzid;
-+ struct berval *lauthzid;
-+ ldap_linkdata *ld;
-+ LDAP *ldap;
-+ LDAPMessage *ldap_res;
-+ int rc, msgid, myargcount = ZEND_NUM_ARGS();
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z|Z", &link, &authzid) == FAILURE) {
-+ WRONG_PARAM_COUNT;
-+ }
-+
-+ if (Z_TYPE_PP(link) == IS_NULL) {
-+ ldap = NULL;
-+ } else {
-+ ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, link, -1, "ldap link", le_link);
-+ ldap = ld->link;
-+ }
-+
-+ if (myargcount == 2) {
-+ /* synchronous call */
-+ rc = ldap_whoami_s(ld->link, &lauthzid, NULL, NULL);
-+ if (rc != LDAP_SUCCESS ) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Whoami extended operation failed: %s (%d)", ldap_err2string(rc), rc);
-+ RETURN_FALSE;
-+ }
-+
-+ zval_dtor(*authzid);
-+ if (lauthzid == NULL) {
-+ ZVAL_EMPTY_STRING(*authzid);
-+ } else {
-+ ZVAL_STRINGL(*authzid, lauthzid->bv_val, lauthzid->bv_len, 1);
-+ ldap_memfree(lauthzid->bv_val);
-+ ldap_memfree(lauthzid);
-+ }
-+
-+ RETURN_TRUE;
-+ }
-+
-+ /* asynchronous call */
-+ rc = ldap_whoami(ld->link, NULL, NULL, &msgid);
-+ if (rc != LDAP_SUCCESS ) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Whoami extended operation failed: %s (%d)", ldap_err2string(rc), rc);
-+ RETURN_FALSE;
-+ }
-+
-+ rc = ldap_result(ld->link, msgid, 1 /* LDAP_MSG_ALL */, NULL, &ldap_res);
-+ if (rc == -1) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Whoami extended operation failed");
-+ RETURN_FALSE;
-+ }
-+
-+ /* return a PHP control object */
-+ array_init(return_value);
-+
-+ ZEND_REGISTER_RESOURCE(return_value, ldap_res, le_result);
-+}
-+#else
-+/* TODO: implement based on ldap_extended_operation_s() */
-+#endif
-+/* }}} */
-+#endif
-+/* }}} */
-+
-+/* {{{ LDAP controls encoding/decoding, Pierangelo Masarati */
-+/* {{{ php_set_no_value_server_ctrl
-+ */
-+void php_set_no_value_server_ctrl(INTERNAL_FUNCTION_PARAMETERS, const char *oid, const char *msg)
-+{
-+ zval **link, **iscritical;
-+ ldap_linkdata *ld;
-+ LDAP *ldap;
-+ LDAPControl ctrl = { 0 }, *ctrlsp[2];
-+ int rc, myargcount = ZEND_NUM_ARGS();
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z|Z", &link, &iscritical) != SUCCESS) {
-+ WRONG_PARAM_COUNT;
-+ }
-+
-+ if (Z_TYPE_PP(link) == IS_NULL) {
-+ ldap = NULL;
-+
-+ } else {
-+ ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, link, -1, "ldap link", le_link);
-+ ldap = ld->link;
-+ }
-+
-+ if (myargcount == 2) {
-+ convert_to_boolean_ex(iscritical);
-+ ctrl.ldctl_iscritical = Z_BVAL_PP(iscritical);
-+ }
-+
-+ ctrl.ldctl_oid = (char *)oid;
-+
-+ if (ldap) {
-+ /* directly set the option */
-+ ctrlsp[0] = &ctrl;
-+ ctrlsp[1] = NULL;
-+
-+ rc = ldap_set_option(ldap, LDAP_OPT_SERVER_CONTROLS, ctrlsp);
-+ if (rc != LDAP_SUCCESS) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to set %s control: %s (%d)", msg, ldap_err2string(rc), rc);
-+ RETURN_FALSE;
-+ }
-+
-+ } else {
-+ /* return a PHP control object */
-+ array_init(return_value);
-+
-+ add_assoc_string(return_value, "oid", ctrl.ldctl_oid, 1);
-+ if (ctrl.ldctl_iscritical) {
-+ add_assoc_bool(return_value, "iscritical", ctrl.ldctl_iscritical);
-+ }
-+ }
-+
-+ RETURN_TRUE;
-+}
-+/* }}} */
-+
-+#ifdef LDAP_CONTROL_MANAGEDSAIT
-+/* {{{ proto bool ldap_ctrl_manageDSAit(resource link [, bool iscritical])
-+ Inject manageDSAit control */
-+PHP_FUNCTION(ldap_ctrl_manageDSAit)
-+{
-+ php_set_no_value_server_ctrl(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_CONTROL_MANAGEDSAIT, "manageDSAit");
-+}
-+/* }}} */
-+#endif
-+
-+#ifdef LDAP_CONTROL_PAGEDRESULTS
-+/* {{{ proto bool ldap_ctrl_paged_results(resource link, int pagesize [, bool iscritical [, string cookie]])
-+ Inject paged results control*/
-+PHP_FUNCTION(ldap_ctrl_paged_results)
-+{
-+ zval **link, **pagesize, **iscritical, **cookie;
-+ int lpagesize = 0;
-+ struct berval lcookie = { 0, NULL };
-+ ldap_linkdata *ld;
-+ LDAP *ldap;
-+ BerElement *ber = NULL;
-+ LDAPControl ctrl, *ctrlsp[2];
-+ int rc, myargcount = ZEND_NUM_ARGS();
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZ|ZZ", &link, &pagesize, &iscritical, &cookie) != SUCCESS) {
-+ WRONG_PARAM_COUNT;
-+ }
-+
-+ if (Z_TYPE_PP(link) == IS_NULL) {
-+ ldap = NULL;
-+ } else {
-+ ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, link, -1, "ldap link", le_link);
-+ ldap = ld->link;
-+ }
-+
-+ ber = ber_alloc_t(LBER_USE_DER);
-+ if (ber == NULL) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to alloc BER encoding resources for paged results control");
-+ RETURN_FALSE;
-+ }
-+
-+ ctrl.ldctl_iscritical = 0;
-+
-+ switch (myargcount) {
-+ case 4:
-+ convert_to_string_ex(cookie);
-+ lcookie.bv_val = Z_STRVAL_PP(cookie);
-+ lcookie.bv_len = Z_STRLEN_PP(cookie);
-+ /* fallthru */
-+ case 3:
-+ convert_to_boolean_ex(iscritical);
-+ ctrl.ldctl_iscritical = Z_BVAL_PP(iscritical);
-+ /* fallthru */
-+ }
-+ convert_to_long_ex(pagesize);
-+ lpagesize = Z_LVAL_PP(pagesize);
-+
-+ ber_printf(ber, "{iO}", lpagesize, &lcookie );
-+ rc = ber_flatten2( ber, &ctrl.ldctl_value, 0 );
-+ if ( rc == -1 ) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to BER encode paged results control");
-+ RETURN_FALSE;
-+ }
-+
-+ ctrl.ldctl_oid = LDAP_CONTROL_PAGEDRESULTS;
-+
-+ if (ldap) {
-+ /* directly set the option */
-+ ctrlsp[0] = &ctrl;
-+ ctrlsp[1] = NULL;
-+
-+ rc = ldap_set_option(ldap, LDAP_OPT_SERVER_CONTROLS, ctrlsp);
-+ if (rc != LDAP_SUCCESS) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to set paged results control: %s (%d)", ldap_err2string(rc), rc);
-+ RETURN_FALSE;
-+ }
-+
-+ } else {
-+ /* return a PHP control object */
-+ array_init(return_value);
-+
-+ add_assoc_string(return_value, "oid", ctrl.ldctl_oid, 1);
-+ if ( ctrl.ldctl_value.bv_len ) {
-+ add_assoc_stringl(return_value, "value", ctrl.ldctl_value.bv_val, ctrl.ldctl_value.bv_len, 1);
-+ }
-+ if (ctrl.ldctl_iscritical) {
-+ add_assoc_bool(return_value, "iscritical", ctrl.ldctl_iscritical);
-+ }
-+ }
-+
-+ if (ber != NULL) {
-+ ber_free(ber, 1);
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto bool ldap_ctrl_paged_results_resp(resource link, resource result [, string cookie [, int estimated]])
-+ Extract paged results control response */
-+PHP_FUNCTION(ldap_ctrl_paged_results_resp)
-+{
-+ zval **link, **result, **cookie, **estimated;
-+ struct berval lcookie;
-+ int lestimated;
-+ ldap_linkdata *ld;
-+ LDAPMessage *ldap_result;
-+ LDAPControl **lserverctrls, *lctrl;
-+ BerElement *ber;
-+ ber_tag_t tag;
-+ int rc, lerrcode, myargcount = ZEND_NUM_ARGS();
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZ|ZZ", &link, &result, &cookie, &estimated) != SUCCESS) {
-+ WRONG_PARAM_COUNT;
-+ }
-+
-+ ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, link, -1, "ldap link", le_link);
-+ ZEND_FETCH_RESOURCE(ldap_result, LDAPMessage *, result, -1, "ldap result", le_result);
-+
-+ rc = ldap_parse_result(ld->link,
-+ ldap_result,
-+ &lerrcode,
-+ NULL, /* matcheddn */
-+ NULL, /* errmsg */
-+ NULL, /* referrals */
-+ &lserverctrls,
-+ 0);
-+
-+ if (rc != LDAP_SUCCESS) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to parse result: %s (%d)", ldap_err2string(rc), rc);
-+ RETURN_FALSE;
-+ }
-+
-+ if (lerrcode != LDAP_SUCCESS) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Result is: %s (%d)", ldap_err2string(lerrcode), lerrcode);
-+ RETURN_FALSE;
-+ }
-+
-+ if (lserverctrls == NULL) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "No server controls in result");
-+ RETURN_FALSE;
-+ }
-+
-+ lctrl = ldap_find_control(LDAP_CONTROL_PAGEDRESULTS, lserverctrls);
-+ if (lctrl == NULL) {
-+ ldap_controls_free(lserverctrls);
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "No paged results control response in result");
-+ RETURN_FALSE;
-+ }
-+
-+ ber = ber_init(&lctrl->ldctl_value);
-+ if (ber == NULL) {
-+ ldap_controls_free(lserverctrls);
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to alloc BER decoding resources for paged results control response");
-+ RETURN_FALSE;
-+ }
-+
-+ tag = ber_scanf(ber, "{io}", &lestimated, &lcookie );
-+ (void)ber_free(ber, 1);
-+
-+ if (tag == LBER_ERROR) {
-+ ldap_controls_free(lserverctrls);
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to decode paged results control response");
-+ RETURN_FALSE;
-+ }
-+
-+ if (lestimated < 0) {
-+ ldap_controls_free(lserverctrls);
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid paged results control response value");
-+ RETURN_FALSE;
-+ }
-+
-+ ldap_controls_free(lserverctrls);
-+
-+ if (myargcount == 4) {
-+ zval_dtor(*estimated);
-+ ZVAL_LONG(*estimated, lestimated);
-+ }
-+
-+ zval_dtor(*cookie);
-+ if (lcookie.bv_len == 0) {
-+ ZVAL_EMPTY_STRING(*cookie);
-+ } else {
-+ ZVAL_STRINGL(*cookie, lcookie.bv_val, lcookie.bv_len, 1);
-+ }
-+ ldap_memfree(lcookie.bv_val);
-+
-+ RETURN_TRUE;
-+}
-+/* }}} */
-+#endif
-+
-+#ifdef LDAP_CONTROL_PASSWORDPOLICYREQUEST
-+/* {{{ proto bool ldap_ctrl_ppolicy(resource link [, bool iscritical])
-+ Inject password policy control */
-+PHP_FUNCTION(ldap_ctrl_ppolicy)
-+{
-+ php_set_no_value_server_ctrl(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_CONTROL_PASSWORDPOLICYREQUEST, "passwordPolicy");
-+}
-+/* }}} */
-+
-+/* {{{ proto bool ldap_ctrl_ppolicy_resp(resource link, resource result [, expire [, grace [, error[, errmsg]]]])
-+ Extract password policy control response */
-+PHP_FUNCTION(ldap_ctrl_ppolicy_resp)
-+{
-+ zval **link, **result, **ppexpire, **ppgrace, **pperror, **pperrmsg;
-+ int lexpire, lgrace;
-+ LDAPPasswordPolicyError lerror;
-+ ldap_linkdata *ld;
-+ LDAPMessage *ldap_result;
-+ LDAPControl **lserverctrls, *lctrl;
-+ int rc, pperrmsg_len, lerrcode, myargcount = ZEND_NUM_ARGS();
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZ|ZZZZ", &link, &result, &ppexpire, &ppgrace, &pperror, &pperrmsg) != SUCCESS) {
-+ WRONG_PARAM_COUNT;
-+ }
-+
-+ ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, link, -1, "ldap link", le_link);
-+ ZEND_FETCH_RESOURCE(ldap_result, LDAPMessage *, result, -1, "ldap result", le_result);
-+
-+ rc = ldap_parse_result(ld->link,
-+ ldap_result,
-+ &lerrcode,
-+ NULL, /* matcheddn */
-+ NULL, /* errmsg */
-+ NULL, /* referrals */
-+ &lserverctrls,
-+ 0);
-+
-+ if (rc != LDAP_SUCCESS) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to parse result: %s (%d)", ldap_err2string(rc), rc);
-+ RETURN_FALSE;
-+ }
-+
-+ if (lerrcode != LDAP_SUCCESS && lerrcode != LDAP_INVALID_CREDENTIALS) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Result is: %s (%d)", ldap_err2string(lerrcode), lerrcode);
-+ RETURN_FALSE;
-+ }
-+
-+ if (lserverctrls == NULL) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "No server controls in result");
-+ RETURN_FALSE;
-+ }
-+
-+ lctrl = ldap_find_control(LDAP_CONTROL_PASSWORDPOLICYRESPONSE, lserverctrls);
-+ if (lctrl == NULL) {
-+ ldap_controls_free(lserverctrls);
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "No password policy control response in result");
-+ RETURN_FALSE;
-+ }
-+
-+ lerrcode = ldap_parse_passwordpolicy_control(ld->link, lctrl, &lexpire, &lgrace, &lerror);
-+ ldap_controls_free(lserverctrls);
-+ if (lerrcode != LDAP_SUCCESS) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to parse password policy control response: %s (%d)", ldap_err2string(lerrcode), lerrcode);
-+ RETURN_FALSE;
-+ }
-+
-+ switch (myargcount) {
-+ case 6:
-+ zval_dtor(*pperrmsg);
-+ ZVAL_STRING(*pperrmsg, (char *)ldap_passwordpolicy_err2txt(lerror), 1);
-+
-+ case 5:
-+ zval_dtor(*pperror);
-+ ZVAL_LONG(*pperror, (long)lerror);
-+
-+ case 4:
-+ zval_dtor(*ppgrace);
-+ ZVAL_LONG(*ppgrace, (long)lgrace);
-+ }
-+
-+ zval_dtor(*ppexpire);
-+ ZVAL_LONG(*ppexpire, (long)lexpire);
-+
-+ RETURN_TRUE;
-+}
-+/* }}} */
-+#endif
-+
-+#ifdef LDAP_CONTROL_NOOP
-+/* {{{ proto bool ldap_ctrl_noop(resource link, bool iscritical)
-+ Inject control*/
-+PHP_FUNCTION(ldap_ctrl_noop)
-+{
-+ php_set_no_value_server_ctrl(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_CONTROL_NOOP, "no-op");
-+}
-+/* }}} */
-+#endif
-+
-+#ifdef LDAP_CONTROL_MANAGEDIT
-+/* {{{ proto bool ldap_ctrl_manageDIT(resource link [, bool iscritical])
-+ Inject control*/
-+PHP_FUNCTION(ldap_ctrl_manageDIT)
-+{
-+ php_set_no_value_server_ctrl(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_CONTROL_MANAGEDIT, "manageDIT");
-+}
-+/* }}} */
-+#endif
-+
-+#ifdef LDAP_CONTROL_X_PERMISSIVE_MODIFY
-+/* {{{ proto bool ldap_ctrl_permissive_modify(resource link [, bool iscritical])
-+ Inject control*/
-+PHP_FUNCTION(ldap_ctrl_permissive_modify)
-+{
-+ php_set_no_value_server_ctrl(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_CONTROL_X_PERMISSIVE_MODIFY, "permissive modify");
-+}
-+/* }}} */
-+#endif
-+/* }}} */
-+
-+#ifdef HAVE_LDAP_REFRESH
-+/* {{{ proto ? ldap_refresh(resource link , string dn , int ttl, [int *newttl])
-+ DDS refresh extended operation */
-+PHP_FUNCTION(ldap_refresh)
-+{
-+ zval **link, **dn, **ttl, **newttl;
-+ struct berval ldn;
-+ ber_int_t lttl;
-+ ber_int_t lnewttl;
-+ ldap_linkdata *ld;
-+ LDAP *ldap;
-+ LDAPMessage *ldap_res;
-+ int rc, msgid, myargcount = ZEND_NUM_ARGS();
-+
-+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZZ|Z", &link, &dn, &ttl, &newttl) != SUCCESS) {
-+ WRONG_PARAM_COUNT;
-+ }
-+
-+ if (Z_TYPE_PP(link) == IS_NULL) {
-+ ldap = NULL;
-+ } else {
-+ ZEND_FETCH_RESOURCE(ld, ldap_linkdata *,
-+ link, -1, "ldap link", le_link);
-+ ldap = ld->link;
-+ }
-+
-+ ldn.bv_len = 0;
-+ convert_to_string_ex(dn);
-+ ldn.bv_val = Z_STRVAL_PP(dn);
-+ ldn.bv_len = Z_STRLEN_PP(dn);
-+
-+ convert_to_long_ex(ttl);
-+ lttl = (ber_int_t)Z_LVAL_PP(ttl);
-+
-+ /* asynchronous call */
-+ rc = ldap_refresh_s(ld->link, &ldn, lttl, &lnewttl, NULL, NULL);
-+ if (rc != LDAP_SUCCESS ) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING,
-+ "Refresh extended operation failed: %s (%d)",
-+ ldap_err2string(rc), rc);
-+ RETURN_FALSE;
-+ }
-+
-+ if (myargcount == 4) {
-+ zval_dtor(*newttl);
-+ ZVAL_LONG(*newttl, (long)lnewttl);
-+ }
-+ RETURN_TRUE;
-+}
-+#else
-+/* TODO: implement based on ldap_extended_operation_s() */
-+/* }}} */
-+#endif
-+
-+/* {{{ arginfo */
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_connect, 0, 0, 0)
-+ ZEND_ARG_INFO(0, hostname)
-+ ZEND_ARG_INFO(0, port)
-+#ifdef HAVE_ORALDAP
-+ ZEND_ARG_INFO(0, wallet)
-+ ZEND_ARG_INFO(0, wallet_passwd)
-+ ZEND_ARG_INFO(0, authmode)
-+#endif
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_resource, 0, 0, 1)
-+ ZEND_ARG_INFO(0, link_identifier)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_bind, 0, 0, 1)
-+ ZEND_ARG_INFO(0, link_identifier)
-+ ZEND_ARG_INFO(0, bind_rdn)
-+ ZEND_ARG_INFO(0, bind_password)
-+ZEND_END_ARG_INFO()
-+
-+#ifdef HAVE_LDAP_SASL
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_sasl_bind, 0, 0, 1)
-+ ZEND_ARG_INFO(0, link)
-+ ZEND_ARG_INFO(0, binddn)
-+ ZEND_ARG_INFO(0, password)
-+ ZEND_ARG_INFO(0, sasl_mech)
-+ ZEND_ARG_INFO(0, sasl_realm)
-+ ZEND_ARG_INFO(0, sasl_authz_id)
-+ ZEND_ARG_INFO(0, props)
-+ZEND_END_ARG_INFO()
-+#endif
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_read, 0, 0, 3)
-+ ZEND_ARG_INFO(0, link_identifier)
-+ ZEND_ARG_INFO(0, base_dn)
-+ ZEND_ARG_INFO(0, filter)
-+ ZEND_ARG_INFO(0, attributes)
-+ ZEND_ARG_INFO(0, attrsonly)
-+ ZEND_ARG_INFO(0, sizelimit)
-+ ZEND_ARG_INFO(0, timelimit)
-+ ZEND_ARG_INFO(0, deref)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_list, 0, 0, 3)
- ZEND_ARG_INFO(0, link_identifier)
- ZEND_ARG_INFO(0, base_dn)
- ZEND_ARG_INFO(0, filter)
- ZEND_ARG_INFO(0, attributes)
-@@ -3007,8 +4401,9 @@
- ZEND_ARG_INFO(1, errcode)
- 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
-
-@@ -3027,8 +4422,40 @@
- ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_8859_to_t61, 0, 0, 1)
- ZEND_ARG_INFO(0, value)
- ZEND_END_ARG_INFO()
- #endif
-+
-+#ifdef HAVE_LDAP_EXTENDED_OPERATION_S
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_exop, 0, 0, 5)
-+ ZEND_ARG_INFO(0, link)
-+ ZEND_ARG_INFO(0, reqoid)
-+ ZEND_ARG_INFO(1, reqdata)
-+ ZEND_ARG_INFO(1, repoid)
-+ ZEND_ARG_INFO(1, repdata)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_exop_passwd, 0, 0, 5)
-+ ZEND_ARG_INFO(0, link)
-+ ZEND_ARG_INFO(1, user)
-+ ZEND_ARG_INFO(1, oldpw)
-+ ZEND_ARG_INFO(1, newpw)
-+ ZEND_ARG_INFO(1, newpasswd)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_exop_whoami, 0, 0, 2)
-+ ZEND_ARG_INFO(0, link)
-+ ZEND_ARG_INFO(1, authzid)
-+ZEND_END_ARG_INFO()
-+#endif
-+
-+#ifdef HAVE_LDAP_REFRESH
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_refresh, 0, 0, 4)
-+ ZEND_ARG_INFO(0, link)
-+ ZEND_ARG_INFO(0, dn)
-+ ZEND_ARG_INFO(1, ttl)
-+ ZEND_ARG_INFO(0, newttl)
-+ZEND_END_ARG_INFO()
-+#endif
- /* }}} */
-
- /*
- This is just a small subset of the functionality provided by the LDAP library. All the
-@@ -3091,9 +4518,22 @@
- #endif
- #ifdef HAVE_LDAP_START_TLS_S
- PHP_FE(ldap_start_tls, arginfo_ldap_resource)
- #endif
-+#ifdef HAVE_LDAP_EXTENDED_OPERATION_S
-+ PHP_FE(ldap_exop,
-+ arginfo_ldap_exop)
-+ PHP_FE(ldap_exop_passwd,
-+ arginfo_ldap_exop_passwd)
-+ PHP_FE(ldap_exop_whoami,
-+ arginfo_ldap_exop_whoami)
-+#endif
-+#ifdef HAVE_LDAP_REFRESH
-+ PHP_FE(ldap_refresh,
-+ arginfo_ldap_refresh)
- #endif
-+#endif
-+
-
- #if defined(LDAP_API_FEATURE_X_OPENLDAP) && defined(HAVE_3ARG_SETREBINDPROC)
- PHP_FE(ldap_set_rebind_proc, arginfo_ldap_set_rebind_proc)
- #endif
-@@ -3102,8 +4542,33 @@
- PHP_FE(ldap_t61_to_8859, arginfo_ldap_t61_to_8859)
- PHP_FE(ldap_8859_to_t61, arginfo_ldap_8859_to_t61)
- #endif
-
-+/* routines to handle standard track controls, Pierangelo Masarati */
-+#ifdef LDAP_CONTROL_MANAGEDSAIT
-+ PHP_FE(ldap_ctrl_manageDSAit, NULL)
-+#endif
-+#ifdef LDAP_CONTROL_PAGEDRESULTS
-+ PHP_FE(ldap_ctrl_paged_results, NULL) /* fourth_arg_force_ref */
-+ PHP_FE(ldap_ctrl_paged_results_resp, NULL) /* arg3to4of4_force_ref */
-+#endif
-+#ifdef LDAP_CONTROL_PASSWORDPOLICYREQUEST
-+ PHP_FE(ldap_ctrl_ppolicy, NULL)
-+ PHP_FE(ldap_ctrl_ppolicy_resp, NULL) /* arg3to6of6_force_ref */
-+#endif
-+#ifdef LDAP_CONTROL_NOOP
-+ PHP_FE(ldap_ctrl_noop, NULL)
-+#endif
-+#ifdef LDAP_CONTROL_MANAGEDIT
-+ PHP_FE(ldap_ctrl_manageDIT, NULL)
-+#endif
-+#ifdef LDAP_CONTROL_X_PERMISSIVE_MODIFY
-+ PHP_FE(ldap_ctrl_permissive_modify, NULL)
-+#endif
-+/* end of ando mod */
-+
-+
-+
- #ifdef LDAP_CONTROL_PAGEDRESULTS
- 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
-@@ -3128,8 +4593,10 @@
- STANDARD_MODULE_PROPERTIES_EX
- };
- /* }}} */
-
-+
-+
- /*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
---- ext/ldap/php_ldap.h.orig 2015-03-18 10:45:50.000000000 +0100
-+++ ext/ldap/php_ldap.h 2015-04-12 11:22:11.000000000 +0200
-@@ -28,16 +28,148 @@
- #endif
-
- #include <ldap.h>
-
-+#define HAVE_3ARG_SETREBINDPROC
-+#define HAVE_LDAP_ADD_EXT_S
-+#define HAVE_LDAP_MODIFY_EXT_S
-+#define HAVE_LDAP_COMPARE_EXT_S
-+#define HAVE_LDAP_DELETE_EXT_S
-+#define HAVE_LDAP_PARSE_EXTENDED_RESULT
-+#define HAVE_LDAP_PARSE_PASSWD
-+#define HAVE_LDAP_PARSE_WHOAMI
-+#define HAVE_LDAP_EXTENDED_OPERATION_S
-+#define HAVE_LDAP_PASSWD_S
-+#define HAVE_LDAP_WHOAMI_S
-+#define HAVE_LDAP_REFRESH
-+#define HAVE_LDAP_EXTENDED_OPERATION_S
-+#define HAVE_LDAP_REFRESH
-+#define HAVE_LDAP_EXTENDED_OPERATION_S
-+#define HAVE_LDAP_REFRESH
-+#define HAVE_LDAP_EXTENDED_OPERATION
-+
-+
- extern zend_module_entry ldap_module_entry;
- #define ldap_module_ptr &ldap_module_entry
-
- /* LDAP functions */
- PHP_MINIT_FUNCTION(ldap);
- PHP_MSHUTDOWN_FUNCTION(ldap);
- PHP_MINFO_FUNCTION(ldap);
-
-+#ifdef HAVE_LDAP_EXTENDED_OPERATION
-+
-+#endif
-+
-+#ifdef LDAP_CONTROL_MANAGEDSAIT
-+/* RFC 3296 */
-+PHP_FUNCTION(ldap_ctrl_manageDSAit);
-+#endif
-+#ifdef LDAP_CONTROL_PROXY_AUTHZ
-+/* <draft-weltman-ldapv3-proxy> (a Work in Progress) */
-+PHP_FUNCTION(ldap_ctrl_proxy_authz);
-+#endif
-+#ifdef LDAP_CONTROL_SUBENTRIES
-+/* RFC 3672 */
-+PHP_FUNCTION(ldap_ctrl_subentries);
-+#endif
-+#ifdef LDAP_CONTROL_VALUESRETURNFILTER
-+/* RFC 3876 */
-+PHP_FUNCTION(ldap_ctrl_vlv);
-+#endif
-+#ifdef LDAP_CONTROL_ASSERT
-+/* <draft-zeilenga-ldap-assert> (a Work in Progress) */
-+PHP_FUNCTION(ldap_ctrl_assert);
-+#endif
-+#ifdef LDAP_CONTROL_PRE_READ
-+/* <draft-zeilenga-ldap-readentry> (a Work in Progress) */
-+PHP_FUNCTION(ldap_ctrl_preread);
-+PHP_FUNCTION(ldap_ctrl_postread);
-+#endif
-+#ifdef LDAP_CONTROL_SORTREQUEST
-+/* RFC 2891 */
-+PHP_FUNCTION(ldap_ctrl_sort);
-+PHP_FUNCTION(ldap_ctrl_sort_resp);
-+#endif
-+#ifdef LDAP_CONTROL_PAGEDRESULTS
-+/* RFC 2696 */
-+PHP_FUNCTION(ldap_ctrl_paged_results);
-+PHP_FUNCTION(ldap_ctrl_paged_results_resp);
-+#endif
-+#ifdef LDAP_CONTROL_PASSWORDPOLICYREQUEST
-+/* <draft-behera-ldap-password-policy> (a Work in Progress) */
-+PHP_FUNCTION(ldap_ctrl_ppolicy);
-+PHP_FUNCTION(ldap_ctrl_ppolicy_resp);
-+#endif
-+#ifdef LDAP_CONTROL_NOOP
-+/* <draft-zeilenga-ldap-noop> (a Work in Progress) */
-+PHP_FUNCTION(ldap_ctrl_noop);
-+#endif
-+#ifdef LDAP_CONTROL_NO_SUBORDINATES
-+/* don't know anything about it */
-+#endif
-+#ifdef LDAP_CONTROL_MANAGEDIT
-+/* no spec; partially implemented in OpenLDAP 2.3 */
-+PHP_FUNCTION(ldap_ctrl_manageDIT);
-+#endif
-+#ifdef LDAP_CONTROL_SLURP
-+/* don't know anything about it */
-+#endif
-+#ifdef LDAP_CONTROL_VALSORT
-+/* <> */
-+PHP_FUNCTION(ldap_ctrl_valsort);
-+#endif
-+#ifdef LDAP_CONTROL_SYNC
-+/* <draft-zeilenga-ldup-sync> (a Work in Progress) */
-+PHP_FUNCTION(ldap_ctrl_sync);
-+PHP_FUNCTION(ldap_ctrl_sync_state);
-+PHP_FUNCTION(ldap_ctrl_sync_done);
-+/* TODO: need to handle the SYNC intermediate response message (LDAPIRM) */
-+#endif
-+#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
-+/* <draft-sermersheim-ldap-chaining> (a Work in Progress) */
-+PHP_FUNCTION(ldap_ctrl_chaining);
-+#endif
-+#ifdef LDAP_CONTROL_X_INCREMENTAL_VALUES
-+/* MS Active Directory */
-+PHP_FUNCTION(ldap_ctrl_incremental_values);
-+#endif
-+#ifdef LDAP_CONTROL_X_DOMAIN_SCOPE
-+/* MS Active Directory */
-+PHP_FUNCTION(ldap_ctrl_domain_scope);
-+#endif
-+#ifdef LDAP_CONTROL_X_PERMISSIVE_MODIFY
-+/* MS Active Directory */
-+PHP_FUNCTION(ldap_ctrl_permissive_modify);
-+#endif
-+#ifdef LDAP_CONTROL_X_SEARCH_OPTIONS
-+/* MS Active Directory */
-+PHP_FUNCTION(ldap_ctrl_search_options);
-+#endif
-+#ifdef LDAP_CONTROL_X_TREE_DELETE
-+/* MS Active Directory */
-+PHP_FUNCTION(ldap_ctrl_tree_delete);
-+#endif
-+#ifdef LDAP_CONTROL_X_EXTENDED_DN
-+/* MS Active Directory */
-+PHP_FUNCTION(ldap_ctrl_extended_dn);
-+#endif
-+#ifdef LDAP_CONTROL_DUPENT
-+/* <draft-ietf-ldapext-ldapv3-dupent> (a Work in Progress) */
-+PHP_FUNCTION(ldap_ctrl_dupent);
-+PHP_FUNCTION(ldap_ctrl_dupent_resp);
-+PHP_FUNCTION(ldap_ctrl_dupent_done_resp);
-+#endif
-+#ifdef LDAP_CONTROL_PERSIST_REQUEST
-+/* ? */
-+#endif
-+#ifdef LDAP_CONTROL_VLVREQUEST
-+/* <draft-ietf-ldapext-ldapv3-vlv> (a Work in Progress) */
-+PHP_FUNCTION(ldap_ctrl_vlv);
-+PHP_FUNCTION(ldap_ctrl_vlv_resp);
-+#endif
-+
-+
- ZEND_BEGIN_MODULE_GLOBALS(ldap)
- long num_links;
- long max_links;
- ZEND_END_MODULE_GLOBALS(ldap)
diff --git a/databases/php-ldap/files/ldap-ctrl-exop56.patch b/databases/php-ldap/files/ldap-ctrl-exop56.patch
index 07a3d5b2743..5eeb8423fd3 100644
--- a/databases/php-ldap/files/ldap-ctrl-exop56.patch
+++ b/databases/php-ldap/files/ldap-ctrl-exop56.patch
@@ -1,69 +1,6 @@
---- ext/ldap/ldap.c.orig 2015-03-19 01:19:30.000000000 +0100
-+++ ext/ldap/ldap.c 2015-04-13 05:51:05.000000000 +0200
-@@ -66,8 +66,13 @@
- #elif defined(HAVE_LDAP_SASL_SASL_H)
- #include <sasl/sasl.h>
- #endif
-
-+/* XXX Not detected by configure... */
-+#ifdef LDAP_EXOP_REFRESH
-+#define HAVE_LDAP_REFRESH 1
-+#endif
-+
- #define PHP_LDAP_ESCAPE_FILTER 0x01
- #define PHP_LDAP_ESCAPE_DN 0x02
-
- typedef struct {
-@@ -91,31 +96,46 @@
- #ifdef COMPILE_DL_LDAP
- ZEND_GET_MODULE(ldap)
- #endif
-
-+
-+/* {{{ proto void _close_ldap_link()
-+ close a connection and free LDAP resources */
- static void _close_ldap_link(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */
- {
- ldap_linkdata *ld = (ldap_linkdata *)rsrc->ptr;
-
-- ldap_unbind_s(ld->link);
--#if defined(LDAP_API_FEATURE_X_OPENLDAP) && defined(HAVE_3ARG_SETREBINDPROC)
-+ /* ldap_unbind_s() is deprecated;
-+ * the distinction between ldap_unbind() and ldap_unbind_s() is moot */
-+#ifdef LDAP_API_FEATURE_X_OPENLDAP
-+ ldap_unbind_ext(ld->link, NULL, NULL);
-+#ifdef HAVE_3ARG_SETREBINDPROC
-+
- if (ld->rebindproc != NULL) {
- zval_dtor(ld->rebindproc);
- FREE_ZVAL(ld->rebindproc);
- }
- #endif
-+#else /* ! LDAP_API_FEATURE_X_OPENLDAP */
-+ ldap_unbind_s(ld->link);
-+#endif /* ! LDAP_API_FEATURE_X_OPENLDAP */
-+
- efree(ld);
- LDAPG(num_links)--;
- }
- /* }}} */
-
-+/* {{{ proto void _free_ldap_result()
-+ free the result of an LDAP operation */
- static void _free_ldap_result(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */
- {
- LDAPMessage *result = (LDAPMessage *)rsrc->ptr;
- ldap_msgfree(result);
- }
- /* }}} */
-
-+/* {{{ proto void _free_ldap_result_entry()
-+ free an entry resulting from an LDAP search operation */
- static void _free_ldap_result_entry(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */
- {
- ldap_resultentry *entry = (ldap_resultentry *)rsrc->ptr;
-
-@@ -206,8 +226,21 @@
+--- ext/ldap/ldap.c.orig 2017-01-19 01:17:47.000000000 +0100
++++ ext/ldap/ldap.c 2017-05-07 10:06:29.000000000 +0200
+@@ -230,8 +230,21 @@
REGISTER_LONG_CONSTANT("GSLC_SSL_ONEWAY_AUTH", GSLC_SSL_ONEWAY_AUTH, CONST_PERSISTENT | CONST_CS);
REGISTER_LONG_CONSTANT("GSLC_SSL_TWOWAY_AUTH", GSLC_SSL_TWOWAY_AUTH, CONST_PERSISTENT | CONST_CS);
#endif
@@ -85,12 +22,11 @@
REGISTER_LONG_CONSTANT("LDAP_ESCAPE_DN", PHP_LDAP_ESCAPE_DN, CONST_PERSISTENT | CONST_CS);
le_link = zend_register_list_destructors_ex(_close_ldap_link, NULL, "ldap link", module_number);
-@@ -291,15 +324,176 @@
+@@ -315,8 +328,162 @@
DISPLAY_INI_ENTRIES();
}
/* }}} */
-+
+/* {{{ proto int _php_parse_referrals_resp()
+ parse an array of LDAP referrals into a zval array */
+static int _php_parse_referrals_resp(char ***lreferralsp, zval **referrals)
@@ -249,105 +185,7 @@
Connect to an LDAP server */
PHP_FUNCTION(ldap_connect)
{
- char *host = NULL;
- int hostlen;
-- long port = 389; /* Default port */
-+ int port =
-+#ifdef LDAP_API_FEATURE_X_OPENLDAP
-+ LDAP_PORT
-+#else /* ! LDAP_API_FEATURE_X_OPENLDAP */
-+ 389 /* Default port */
-+#endif /* ! LDAP_API_FEATURE_X_OPENLDAP */
-+ ;
- #ifdef HAVE_ORALDAP
- char *wallet = NULL, *walletpasswd = NULL;
- int walletlen = 0, walletpasswdlen = 0;
- long authmode = GSLC_SSL_NO_AUTH;
-@@ -333,23 +527,41 @@
-
- ld = ecalloc(1, sizeof(ldap_linkdata));
-
- #ifdef LDAP_API_FEATURE_X_OPENLDAP
-- if (host != NULL && strchr(host, '/')) {
-- int rc;
-+ /* OpenLDAP provides a specific call to detect valid LDAP URIs;
-+ * ldap_init()/ldap_open() is deprecated, use ldap_initialize() instead.
-+ */
-+ {
-+ int rc;
-+ char *url = host;
-+
-+ if (!ldap_is_ldap_url(url)) {
-+ int urllen = hostlen + sizeof( "ldap://:65535" );
-+
-+ if (port <= 0 || port > 65535) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid port number: %ld", port);
-+ RETURN_FALSE;
-+ }
-+
-+ url = emalloc(urllen);
-+ snprintf( url, urllen, "ldap://%s:%d", host ? host : "", port );
-+ }
-
-- rc = ldap_initialize(&ldap, host);
-+ rc = ldap_initialize(&ldap, url);
- if (rc != LDAP_SUCCESS) {
- efree(ld);
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not create session handle: %s", ldap_err2string(rc));
- RETURN_FALSE;
- }
-- } else {
-- ldap = ldap_init(host, port);
-+
-+ if (url != host) {
-+ efree(url);
-+ }
- }
--#else
-+#else /* ! LDAP_API_FEATURE_X_OPENLDAP */
- ldap = ldap_open(host, port);
--#endif
-+#endif /* ! LDAP_API_FEATURE_X_OPENLDAP */
-
- if (ldap == NULL) {
- efree(ld);
- RETURN_FALSE;
-@@ -435,17 +647,33 @@
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Password contains a null byte");
- RETURN_FALSE;
- }
-
-- if ((rc = ldap_bind_s(ld->link, ldap_bind_dn, ldap_bind_pw, LDAP_AUTH_SIMPLE)) != LDAP_SUCCESS) {
-+#ifdef LDAP_API_FEATURE_X_OPENLDAP
-+ {
-+ struct berval cred;
-+
-+ /* ldap_bind_s() is deprecated; use ldap_sasl_bind_s() instead */
-+ cred.bv_val = ldap_bind_pw;
-+ cred.bv_len = ldap_bind_pw ? ldap_bind_pwlen : 0;
-+ rc = ldap_sasl_bind_s(ld->link, ldap_bind_dn, LDAP_SASL_SIMPLE, &cred,
-+ NULL, NULL, /* no controls right now */
-+ NULL); /* we don't care about the server's credentials */
-+ }
-+#else
-+ rc = ldap_bind_s(ld->link, ldap_bind_dn, ldap_bind_pw, LDAP_AUTH_SIMPLE);
-+#endif
-+ if ( rc != LDAP_SUCCESS) {
-+
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to bind to server: %s", ldap_err2string(rc));
- RETURN_FALSE;
- } else {
- RETURN_TRUE;
- }
- }
- /* }}} */
-
-+/* {{{ SASL bind stuff */
- #ifdef HAVE_LDAP_SASL
- typedef struct {
- char *mech;
- char *realm;
-@@ -568,8 +796,9 @@
+@@ -639,8 +806,9 @@
_php_sasl_freedefs(ctx);
}
/* }}} */
@@ -357,22 +195,7 @@
/* {{{ proto bool ldap_unbind(resource link)
Unbind from LDAP directory */
PHP_FUNCTION(ldap_unbind)
-@@ -1265,9 +1494,14 @@
- for (i = 0; i<count; i++) {
- add_index_string(return_value, i, ldap_value[i], 1);
- }
-
-+#ifdef LDAP_API_FEATURE_X_OPENLDAP
-+ /* ldap_value_free() is deprecated */
-+ ber_memvfree((void **)ldap_value);
-+#else /* ! LDAP_API_FEATURE_X_OPENLDAP */
- ldap_value_free(ldap_value);
-+#endif /* ! LDAP_API_FEATURE_X_OPENLDAP */
- }
- /* }}} */
-
- /* {{{ proto string ldap_dn2ufn(string dn)
-@@ -1298,38 +1532,67 @@
+@@ -1369,38 +1537,52 @@
/* added to fix use of ldap_modify_add for doing an ldap_add, gerrit thomson. */
#define PHP_LD_FULL_ADD 0xff
/* {{{ php_ldap_do_modify
@@ -381,7 +204,7 @@
+static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper, int ext)
{
- zval *link, *entry, **value, **ivalue;
-+ zval *link, *entry, **value, **ivalue, **sctrls, **cctrls;
++ zval *link, *entry, **value, **ivalue, **sctrls, **cctrls;;
ldap_linkdata *ld;
char *dn;
LDAPMod **ldap_mods;
@@ -390,6 +213,9 @@
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) {
+- return;
+ int rc, msgid, myargcount = ZEND_NUM_ARGS();
+ LDAPMessage *ldap_res;
+ LDAPControl **lsctrls = NULL, **lcctrls = NULL;
@@ -399,15 +225,7 @@
+ } else {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsa", &link, &dn, &dn_len, &entry) != SUCCESS)
+ WRONG_PARAM_COUNT;
-+ }
-
-- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsa", &link, &dn, &dn_len, &entry) != SUCCESS) {
-- return;
-- }
-+ if (Z_TYPE_PP(&entry) != IS_ARRAY) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Expected Array as the last element");
-+ RETURN_FALSE;
-+ }
+ }
- ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
@@ -415,6 +233,10 @@
- ldap_mods = safe_emalloc((num_attribs+1), sizeof(LDAPMod *), 0);
- num_berval = safe_emalloc(num_attribs, sizeof(int), 0);
- zend_hash_internal_pointer_reset(Z_ARRVAL_P(entry));
++ if (Z_TYPE_PP(&entry) != IS_ARRAY) {
++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Expected Array as the last element");
++ RETURN_FALSE;
++ }
/* added by gerrit thomson to fix ldap_add using ldap_mod_add */
if (oper == PHP_LD_FULL_ADD) {
@@ -423,20 +245,6 @@
}
/* end additional , gerrit thomson */
-+ if (myargcount > 3) {
-+ if (is_full_add) {
-+#ifndef HAVE_LDAP_ADD_EXT_S
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "ldap_add_ext not available");
-+ RETURN_FALSE;
-+#endif /* ! HAVE_LDAP_ADD_EXT_S */
-+
-+ } else {
-+#ifndef HAVE_LDAP_MODIFY_EXT_S
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "ldap_modify_ext not available");
-+ RETURN_FALSE;
-+#endif /* ! HAVE_LDAP_MODIFY_EXT_S */
-+ }
-+ }
+
+ ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
+
@@ -450,7 +258,7 @@
ldap_mods[i] = emalloc(sizeof(LDAPMod));
ldap_mods[i]->mod_op = oper | LDAP_MOD_BVALUES;
ldap_mods[i]->mod_type = NULL;
-@@ -1387,19 +1650,78 @@
+@@ -1458,19 +1640,84 @@
zend_hash_move_forward(Z_ARRVAL_P(entry));
}
ldap_mods[num_attribs] = NULL;
@@ -473,36 +281,42 @@
+
/* 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, NULL, NULL)) != LDAP_SUCCESS) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Add: %s", ldap_err2string(i));
- RETVAL_FALSE;
- } else RETVAL_TRUE;
-+#ifdef HAVE_LDAP_ADD_EXT_S
+ if (ext) {
+ rc = ldap_add_ext(ld->link, dn, ldap_mods, lsctrls, lcctrls, &msgid);
+
+ } else {
+ rc = ldap_add_ext_s(ld->link, dn, ldap_mods, NULL, NULL);
+ }
-+#else /* ! HAVE_LDAP_ADD_EXT_S */
-+ rc = ldap_add_s(ld->link, dn, ldap_mods);
-+#endif /* ! HAVE_LDAP_ADD_EXT_S */
+
} else {
- if ((i = ldap_modify_ext_s(ld->link, dn, ldap_mods, NULL, NULL)) != LDAP_SUCCESS) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Modify: %s", ldap_err2string(i));
- RETVAL_FALSE;
-- } else RETVAL_TRUE;
-+#ifdef HAVE_LDAP_MODIFY_EXT_S
+- } else RETVAL_TRUE;
++
++ if (ext) {
++ rc = ldap_modify_ext(ld->link, dn, ldap_mods, lsctrls, lcctrls, &msgid);
++
++ } else {
++ rc = ldap_modify_ext_s(ld->link, dn, ldap_mods, NULL, NULL);
++ }
++ }
++
++ if (rc != LDAP_SUCCESS) {
++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s: %s", is_full_add ? "Add" : "Modify", ldap_err2string(i));
++ RETVAL_FALSE;
++
++ } else {
+ if (ext) {
+ rc = ldap_modify_ext(ld->link, dn, ldap_mods, lsctrls, lcctrls, &msgid);
+
+ } else {
+ rc = ldap_modify_ext_s(ld->link, dn, ldap_mods, NULL, NULL);
+ }
-+#else /* ! HAVE_LDAP_MODIFY_EXT_S */
-+ rc = ldap_modify_s(ld->link, dn, ldap_mods);
-+#endif /* ! HAVE_LDAP_MODIFY_EXT_S */
+ }
+
+ if (rc != LDAP_SUCCESS) {
@@ -537,10 +351,10 @@
errexit:
for (i = 0; i < num_attribs; i++) {
-@@ -1412,46 +1734,57 @@
+@@ -1483,8 +1730,17 @@
}
efree(num_berval);
- efree(ldap_mods);
+ efree(ldap_mods);
+ if (ext) {
+ if (lsctrls) {
@@ -555,20 +369,18 @@
}
/* }}} */
- /* {{{ proto bool ldap_add(resource link, string dn, array entry)
+@@ -1492,9 +1748,9 @@
Add entries to LDAP directory */
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 */
+ /* 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);
-+ /* 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, 0);
}
/* }}} */
--/* three functions for attribute base modifications, gerrit Thomson */
-+/* {{{ Three functions for attribute base modifications, gerrit Thomson */
-
+ /* three functions for attribute base modifications, gerrit Thomson */
+@@ -1502,25 +1758,25 @@
/* {{{ proto bool ldap_mod_replace(resource link, string dn, array entry)
Replace attribute values with new ones */
PHP_FUNCTION(ldap_mod_replace)
@@ -588,7 +400,6 @@
/* }}} */
/* {{{ proto bool ldap_mod_del(resource link, string dn, array entry)
-+
Delete attribute values */
PHP_FUNCTION(ldap_mod_del)
{
@@ -596,21 +407,18 @@
+ php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_MOD_DELETE, 0);
}
/* }}} */
-+/* }}} */
/* {{{ proto bool ldap_delete(resource link, string dn)
- Delete an entry from a directory */
- PHP_FUNCTION(ldap_delete)
-@@ -1875,38 +2208,109 @@
+@@ -1946,42 +2202,104 @@
RETURN_STRING(ldap_err2string(ld_errno), 1);
}
/* }}} */
-/* {{{ proto bool ldap_compare(resource link, string dn, string attr, string value)
- Determine if an entry has a specific value for one of its attributes */
--PHP_FUNCTION(ldap_compare)
+-PHP_FUNCTION(ldap_compare)
+/* {{{ proto void php_ldap_do_compare */
-+void php_ldap_do_compare(INTERNAL_FUNCTION_PARAMETERS, int ext)
++static void php_ldap_do_compare(INTERNAL_FUNCTION_PARAMETERS, int ext)
{
- zval *link;
- char *dn, *attr, *value;
@@ -622,6 +430,7 @@
+ int rc, msgid, lerr, myargcount = ZEND_NUM_ARGS();
+ LDAPMessage *ldap_res;
+ LDAPControl **lsctrls = NULL, **lcctrls = NULL;
+ struct berval lvalue;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsss", &link, &dn, &dn_len, &attr, &attr_len, &value, &value_len) != SUCCESS) {
- return;
@@ -635,14 +444,12 @@
+ }
}
+- lvalue.bv_val = value;
+- lvalue.bv_len = value_len;
+-
ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
-- errno = ldap_compare_s(ld->link, dn, attr, value);
--
-- switch (errno) {
-- case LDAP_COMPARE_TRUE:
-- RETURN_TRUE;
-- break;
+- errno = ldap_compare_ext_s(ld->link, dn, attr, &lvalue, NULL, NULL);
+ if (ext) {
+ struct berval ldap_bvalue;
+ switch (myargcount) {
@@ -652,7 +459,10 @@
+ _php_parse_controls(sctrls, &lsctrls);
+ }
-- case LDAP_COMPARE_FALSE:
+- switch (errno) {
+- case LDAP_COMPARE_TRUE:
+- RETURN_TRUE;
+- break;
+ ldap_bvalue.bv_val = Z_STRVAL_PP(&value);
+ ldap_bvalue.bv_len = Z_STRLEN_PP(&value);
+ rc = ldap_compare_ext(ld->link, ldap_dn, ldap_attr, &ldap_bvalue, lsctrls, lcctrls, &msgid);
@@ -664,14 +474,17 @@
+ }
+ if (rc != LDAP_SUCCESS) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Compare: %s", ldap_err2string(rc));
- RETURN_FALSE;
-- break;
++ RETURN_FALSE;
+
+- case LDAP_COMPARE_FALSE:
+ }
+
+ rc = ldap_result(ld->link, msgid, LDAP_MSG_ALL, NULL, &ldap_res);
+ if (rc != LDAP_RES_COMPARE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Compare: unable to get result");
-+ RETURN_FALSE;
+ RETURN_FALSE;
+- break;
+- }
+ }
+
+ ZEND_REGISTER_RESOURCE(return_value, ldap_res, le_result);
@@ -691,24 +504,19 @@
+ }
+
+ } else {
-+#ifdef HAVE_LDAP_COMPARE_EXT_S
+ struct berval ldap_bvalue;
+
+ ldap_bvalue.bv_val = Z_STRVAL_PP(&value);
+ ldap_bvalue.bv_len = Z_STRLEN_PP(&value);
+ rc = ldap_compare_ext_s(ld->link, ldap_dn, ldap_attr, &ldap_bvalue, NULL, NULL);
-+#else /* ! HAVE_LDAP_COMPARE_EXT_S */
-+ char *ldap_value;
-+
-+ ldap_value = Z_STRVAL_PP(&value);
-+ rc = ldap_compare_s(ld->link, ldap_dn, ldap_attr, ldap_value);
-+#endif /* ! HAVE_LDAP_COMPARE_EXT_S */
+
+ switch (rc) {
+ case LDAP_COMPARE_TRUE:
+ RETURN_TRUE;
+ break;
-+
+
+- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Compare: %s", ldap_err2string(errno));
+- RETURN_LONG(-1);
+ case LDAP_COMPARE_FALSE:
+ RETURN_FALSE;
+ break;
@@ -716,10 +524,7 @@
+
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Compare: %s", ldap_err2string(rc));
+ RETURN_LONG(-1);
- }
--
-- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Compare: %s", ldap_err2string(errno));
-- RETURN_LONG(-1);
++ }
+}
+/* {{{ proto bool ldap_compare(resource link, string dn, string attr, string valu)
+ Determine if an entry has a specific value for one of its attributes */
@@ -730,7 +535,7 @@
/* }}} */
/* {{{ proto bool ldap_sort(resource link, resource result, string sortfilter)
-@@ -1938,59 +2342,233 @@
+@@ -2013,69 +2331,241 @@
RETURN_TRUE;
}
/* }}} */
@@ -738,7 +543,15 @@
-#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP
-/* {{{ proto bool ldap_get_option(resource link, int option, mixed retval)
- Get the current value of various session-wide parameters */
--PHP_FUNCTION(ldap_get_option)
+-PHP_FUNCTION(ldap_get_option)
+-{
+- zval *link, *retval;
+- ldap_linkdata *ld;
+- long option;
+
+- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rlz", &link, &option, &retval) != SUCCESS) {
+- return;
++
+/* {{{ Extended API that returns result instead of just bool
+ * to allow further manipulation by the ldap_parse_*() funcs,
+ * Pierangelo Masarati */
@@ -746,36 +559,21 @@
+/* {{{ proto result ldap_bind_ext(resource link [, string dn, string password])
+ Bind to LDAP directory */
+PHP_FUNCTION(ldap_bind_ext)
- {
-- zval *link, *retval;
++ {
+ zval *link;
+ char *ldap_bind_dn = NULL, *ldap_bind_pw = NULL;
+ int ldap_bind_dnlen, ldap_bind_pwlen;
- ldap_linkdata *ld;
-- long option;
--
-- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rlz", &link, &option, &retval) != SUCCESS) {
-- return;
++ ldap_linkdata *ld;
+ int rc, msgid, lerr;
+ LDAPMessage *ldap_res;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|ss", &link, &ldap_bind_dn, &ldap_bind_dnlen, &ldap_bind_pw, &ldap_bind_pwlen) == FAILURE) {
+
+ RETURN_FALSE;
- }
-
- ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
-
-- switch (option) {
-- /* options with int value */
-- case LDAP_OPT_DEREF:
-- case LDAP_OPT_SIZELIMIT:
-- case LDAP_OPT_TIMELIMIT:
-- case LDAP_OPT_PROTOCOL_VERSION:
-- case LDAP_OPT_ERROR_NUMBER:
-- case LDAP_OPT_REFERRALS:
--#ifdef LDAP_OPT_RESTART
-- case LDAP_OPT_RESTART:
++ }
++
++ ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
++
+#ifdef LDAP_API_FEATURE_X_OPENLDAP
+ {
+ struct berval cred;
@@ -798,9 +596,40 @@
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to bind");
+ RETURN_FALSE;
+ }
- #endif
++ #endif
++
++ rc = ldap_result(ld->link, msgid, LDAP_MSG_ALL, NULL, &ldap_res);
++ if (rc != LDAP_RES_BIND) {
++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to get bind result: %s", ldap_err2string(rc));
++ RETURN_FALSE;
++ }
++
++ ZEND_REGISTER_RESOURCE(return_value, ldap_res, le_result);
++ rc = ldap_parse_result(ld->link, ldap_res, &lerr, NULL, NULL, NULL, NULL, 0);
++ if (rc == LDAP_SUCCESS) {
++ rc = lerr;
+ }
+
+- ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
+
+- switch (option) {
+- /* options with int value */
+- case LDAP_OPT_DEREF:
+- case LDAP_OPT_SIZELIMIT:
+- case LDAP_OPT_TIMELIMIT:
+- case LDAP_OPT_PROTOCOL_VERSION:
+- case LDAP_OPT_ERROR_NUMBER:
+- case LDAP_OPT_REFERRALS:
+-#ifdef LDAP_OPT_RESTART
+- case LDAP_OPT_RESTART:
+-#endif
- {
- int val;
++ if (rc != LDAP_SUCCESS) {
++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to bind to server: %s", ldap_err2string(rc));
++ }
++}
++/* }}} */
- if (ldap_get_option(ld->link, option, &val)) {
- RETURN_FALSE;
@@ -812,44 +641,31 @@
- case LDAP_OPT_NETWORK_TIMEOUT:
- {
- struct timeval *timeout = NULL;
-+ rc = ldap_result(ld->link, msgid, LDAP_MSG_ALL, NULL, &ldap_res);
-+ if (rc != LDAP_RES_BIND) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to get bind result: %s", ldap_err2string(rc));
-+ RETURN_FALSE;
-+ }
++/* {{{ proto result ldap_add_ext(resource link, string dn, array entry)
++ Add entries to LDAP directory; returns result */
++PHP_FUNCTION(ldap_add_ext)
++{
++ php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_LD_FULL_ADD, 1);
++}
++/* }}} */
- if (ldap_get_option(ld->link, LDAP_OPT_NETWORK_TIMEOUT, (void *) &timeout)) {
- if (timeout) {
- ldap_memfree(timeout);
- }
- RETURN_FALSE;
-- }
+- }
- if (!timeout) {
- RETURN_FALSE;
- }
- zval_dtor(retval);
- ZVAL_LONG(retval, timeout->tv_sec);
-+ ZEND_REGISTER_RESOURCE(return_value, ldap_res, le_result);
-+ rc = ldap_parse_result(ld->link, ldap_res, &lerr, NULL, NULL, NULL, NULL, 0);
-+ if (rc == LDAP_SUCCESS) {
-+ rc = lerr;
-+ }
-+
-+
-+ if (rc != LDAP_SUCCESS) {
-+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to bind to server: %s", ldap_err2string(rc));
-+ }
-+}
-+/* }}} */
-+
-+/* {{{ proto result ldap_add_ext(resource link, string dn, array entry)
-+ Add entries to LDAP directory; returns result */
-+PHP_FUNCTION(ldap_add_ext)
-+{
-+ php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_LD_FULL_ADD, 1);
-+}
-+/* }}} */
-+
+- ldap_memfree(timeout);
+- } break;
+-#elif defined(LDAP_X_OPT_CONNECT_TIMEOUT)
+- case LDAP_X_OPT_CONNECT_TIMEOUT:
+- {
+- int timeout;
+/* {{{ proto result ldap_mod_replace_ext(resource link, string dn, array entry)
+ Replace attribute values with new ones */
+PHP_FUNCTION(ldap_mod_replace_ext)
@@ -857,7 +673,10 @@
+ php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_MOD_REPLACE, 1);
+}
+/* }}} */
-+
+
+- if (ldap_get_option(ld->link, LDAP_X_OPT_CONNECT_TIMEOUT, &timeout)) {
+- RETURN_FALSE;
+- }
+
+/* {{{ proto result ldap_mod_add_ext(resource link, string dn, array entry)
+ Add attribute values to current */
@@ -903,11 +722,7 @@
+ convert_to_string_ex(dn);
+ ldap_dn = Z_STRVAL_PP(dn);
+
-+#ifdef HAVE_LDAP_DELETE_EXT_S
+ rc = ldap_delete_ext_s(ld->link, ldap_dn, NULL, NULL);
-+#else /* ! HAVE_LDAP_DELETE_EXT_S */
-+ rc = ldap_delete_s(ld->link, ldap_dn);
-+#endif /* ! HAVE_LDAP_DELETE_EXT_S */
+ if (lsctrls) {
+ _php_free_controls(&lsctrls);
+ }
@@ -1002,19 +817,29 @@
+ }
+ zval_dtor(retval);
+ ZVAL_LONG(retval, timeout->tv_sec);
- ldap_memfree(timeout);
++ ldap_memfree(timeout);
++ } break;
++#elif defined(LDAP_X_OPT_CONNECT_TIMEOUT)
++ case LDAP_X_OPT_CONNECT_TIMEOUT:
++ {
++ int timeout;
++
++ if (ldap_get_option(ld->link, LDAP_X_OPT_CONNECT_TIMEOUT, &timeout)) {
++ RETURN_FALSE;
++ }
+ zval_dtor(retval);
+ ZVAL_LONG(retval, (timeout / 1000));
} break;
- #elif defined(LDAP_X_OPT_CONNECT_TIMEOUT)
- case LDAP_X_OPT_CONNECT_TIMEOUT:
-@@ -2213,21 +2791,23 @@
+ #endif
+@@ -2320,20 +2810,21 @@
}
/* }}} */
#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]]]])
++/* {{{ proto bool ldap_parse_result(resource link, resource result, int errcode, string matcheddn, string errmsg, array referrals, array serverctls)
Extract information from result */
- PHP_FUNCTION(ldap_parse_result)
+ PHP_FUNCTION(ldap_parse_result)
{
- zval *link, *result, *errcode, *matcheddn, *errmsg, *referrals;
+ zval *link, *result, *errcode, *matcheddn, *errmsg, *referrals, *serverctrls;
@@ -1025,17 +850,14 @@
+ char **lreferrals;
char *lmatcheddn, *lerrmsg;
int rc, lerrcode, myargcount = ZEND_NUM_ARGS();
-+ /* int matcheddn_len, errmsg_len; */
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rrz|zzz", &link, &result, &errcode, &matcheddn, &errmsg, &referrals) != SUCCESS) {
-- return;
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rrz|zzzz", &link, &result, &errcode, &matcheddn, &errmsg, &referrals, &serverctrls) != SUCCESS) {
-+ WRONG_PARAM_COUNT;
+ return;
}
ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
- ZEND_FETCH_RESOURCE(ldap_result, LDAPMessage *, &result, -1, "ldap result", le_result);
-@@ -2235,9 +2815,9 @@
+@@ -2342,9 +2833,9 @@
rc = ldap_parse_result(ld->link, ldap_result, &lerrcode,
myargcount > 3 ? &lmatcheddn : NULL,
myargcount > 4 ? &lerrmsg : NULL,
@@ -1046,7 +868,7 @@
if (rc != LDAP_SUCCESS) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to parse result: %s", ldap_err2string(rc));
RETURN_FALSE;
-@@ -2247,19 +2827,15 @@
+@@ -2354,19 +2845,15 @@
ZVAL_LONG(errcode, lerrcode);
/* Reverse -> fall through */
@@ -1065,14 +887,14 @@
- add_next_index_string(referrals, *refp, 1);
- refp++;
- }
-- ldap_value_free(lreferrals);
+- ldap_memvfree((void**)lreferrals);
- }
+ _php_parse_referrals_resp(&lreferrals, &referrals);
case 5:
zval_dtor(errmsg);
if (lerrmsg == NULL) {
ZVAL_EMPTY_STRING(errmsg);
-@@ -2280,8 +2856,142 @@
+@@ -2387,8 +2874,142 @@
}
/* }}} */
#endif
@@ -1215,7 +1037,29 @@
Return first reference */
PHP_FUNCTION(ldap_first_reference)
{
-@@ -2841,53 +3551,735 @@
+@@ -2636,9 +3257,9 @@
+ }
+ /* }}} */
+ #endif
+
+-static void php_ldap_do_escape(const zend_bool *map, const char *value, size_t valuelen, char **result, size_t *resultlen)
++void php_ldap_do_escape(const zend_bool *map, const char *value, size_t valuelen, char **result, size_t *resultlen)
+ {
+ char hex[] = "0123456789abcdef";
+ int i, p = 0;
+ size_t len = 0;
+@@ -2664,9 +3285,9 @@
+
+ (*result)[p++] = '\0';
+ }
+
+-static void php_ldap_escape_map_set_chars(zend_bool *map, const char *chars, const int charslen, char escape)
++void php_ldap_escape_map_set_chars(zend_bool *map, const char *chars, const int charslen, char escape)
+ {
+ int i = 0;
+ while (i < charslen) {
+ map[(unsigned char) chars[i++]] = escape;
+@@ -2948,58 +3569,740 @@
}
/* }}} */
#endif
@@ -1244,37 +1088,18 @@
+ LDAPMessage *ldap_res;
+ int rc, msgid, myargcount = ZEND_NUM_ARGS();
+ /* int reqoid_len, reqdata_len, retdata_len, retoid_len, retdat_len; */
-
--ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_resource, 0, 0, 1)
-- ZEND_ARG_INFO(0, link_identifier)
--ZEND_END_ARG_INFO()
++
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZ|ZZZ", &link, &reqoid, &reqdata, &retoid, &retdata) != SUCCESS) {
+ WRONG_PARAM_COUNT;
+ }
-
--ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_bind, 0, 0, 1)
-- ZEND_ARG_INFO(0, link_identifier)
-- ZEND_ARG_INFO(0, bind_rdn)
-- ZEND_ARG_INFO(0, bind_password)
--ZEND_END_ARG_INFO()
++
+ if (Z_TYPE_PP(link) == IS_NULL) {
+ ldap = NULL;
+ } else {
+ ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, link, -1, "ldap link", le_link);
+ ldap = ld->link;
+ }
-
--#ifdef HAVE_LDAP_SASL
--ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_sasl_bind, 0, 0, 1)
-- ZEND_ARG_INFO(0, link)
-- ZEND_ARG_INFO(0, binddn)
-- ZEND_ARG_INFO(0, password)
-- ZEND_ARG_INFO(0, sasl_mech)
-- ZEND_ARG_INFO(0, sasl_realm)
-- ZEND_ARG_INFO(0, sasl_authz_id)
-- ZEND_ARG_INFO(0, props)
--ZEND_END_ARG_INFO()
--#endif
++
+ switch (myargcount) {
+ case 5:
+ case 4:
@@ -1300,17 +1125,7 @@
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Extended operation %s failed: %s (%d)", lreqoid, ldap_err2string(rc), rc);
+ RETURN_FALSE;
+ }
-
--ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_read, 0, 0, 3)
-- ZEND_ARG_INFO(0, link_identifier)
-- ZEND_ARG_INFO(0, base_dn)
-- ZEND_ARG_INFO(0, filter)
-- ZEND_ARG_INFO(0, attributes)
-- ZEND_ARG_INFO(0, attrsonly)
-- ZEND_ARG_INFO(0, sizelimit)
-- ZEND_ARG_INFO(0, timelimit)
-- ZEND_ARG_INFO(0, deref)
--ZEND_END_ARG_INFO()
++
+ /* Reverse -> fall through */
+ switch (myargcount) {
+ case 5:
@@ -1332,11 +1147,13 @@
+ ldap_memfree(lretoid);
+ }
+ }
-
--ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_list, 0, 0, 3)
++
+ RETURN_TRUE;
+ }
-+
+
+-ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_resource, 0, 0, 1)
+- ZEND_ARG_INFO(0, link_identifier)
+-ZEND_END_ARG_INFO()
+ /* asynchronous call */
+ rc = ldap_extended_operation(ld->link, lreqoid,
+ lreqdata.bv_len > 0 ? &lreqdata: NULL,
@@ -1345,20 +1162,52 @@
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Extended operation %s failed: %s (%d)", lreqoid, ldap_err2string(rc), rc);
+ RETURN_FALSE;
+ }
-+
+
+-ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_bind, 0, 0, 1)
+- ZEND_ARG_INFO(0, link_identifier)
+- ZEND_ARG_INFO(0, bind_rdn)
+- ZEND_ARG_INFO(0, bind_password)
+-ZEND_END_ARG_INFO()
+ rc = ldap_result(ld->link, msgid, 1 /* LDAP_MSG_ALL */, NULL, &ldap_res);
+ if (rc == -1) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Extended operation %s failed", lreqoid);
+ RETURN_FALSE;
+ }
-+
+
+-#ifdef HAVE_LDAP_SASL
+-ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_sasl_bind, 0, 0, 1)
+- ZEND_ARG_INFO(0, link)
+- ZEND_ARG_INFO(0, binddn)
+- ZEND_ARG_INFO(0, password)
+- ZEND_ARG_INFO(0, sasl_mech)
+- ZEND_ARG_INFO(0, sasl_realm)
+- ZEND_ARG_INFO(0, sasl_authz_id)
+- ZEND_ARG_INFO(0, props)
+-ZEND_END_ARG_INFO()
+-#endif
+ /* return a PHP control object */
+ array_init(return_value);
-+
+
+-ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_read, 0, 0, 3)
+- ZEND_ARG_INFO(0, link_identifier)
+- ZEND_ARG_INFO(0, base_dn)
+- ZEND_ARG_INFO(0, filter)
+- ZEND_ARG_INFO(0, attributes)
+- ZEND_ARG_INFO(0, attrsonly)
+- ZEND_ARG_INFO(0, sizelimit)
+- ZEND_ARG_INFO(0, timelimit)
+- ZEND_ARG_INFO(0, deref)
+-ZEND_END_ARG_INFO()
+ ZEND_REGISTER_RESOURCE(return_value, ldap_res, le_result);
+}
+/* }}} */
-+
+
+-ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_list, 0, 0, 3)
+- ZEND_ARG_INFO(0, link_identifier)
+- ZEND_ARG_INFO(0, base_dn)
+- ZEND_ARG_INFO(0, filter)
+- ZEND_ARG_INFO(0, attributes)
+- ZEND_ARG_INFO(0, attrsonly)
+#ifdef HAVE_LDAP_PASSWD_S
+/* {{{ proto ? ldap_exop_passwd(resource link [, string user [, string oldpw [, string newpw [, string newpasswd ]]]])
+ Passwd modify extended operation */
@@ -1987,11 +1836,16 @@
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_list, 0, 0, 3)
- ZEND_ARG_INFO(0, link_identifier)
- ZEND_ARG_INFO(0, base_dn)
- ZEND_ARG_INFO(0, filter)
- ZEND_ARG_INFO(0, attributes)
-@@ -3090,8 +4482,9 @@
++ ZEND_ARG_INFO(0, link_identifier)
++ ZEND_ARG_INFO(0, base_dn)
++ ZEND_ARG_INFO(0, filter)
++ ZEND_ARG_INFO(0, attributes)
++ ZEND_ARG_INFO(0, attrsonly)
+ ZEND_ARG_INFO(0, sizelimit)
+ ZEND_ARG_INFO(0, timelimit)
+ ZEND_ARG_INFO(0, deref)
+ ZEND_END_ARG_INFO()
+@@ -3197,8 +4500,9 @@
ZEND_ARG_INFO(1, errcode)
ZEND_ARG_INFO(1, matcheddn)
ZEND_ARG_INFO(1, errmsg)
@@ -2001,7 +1855,7 @@
#endif
#endif
-@@ -3116,8 +4509,40 @@
+@@ -3223,8 +4527,40 @@
ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_8859_to_t61, 0, 0, 1)
ZEND_ARG_INFO(0, value)
ZEND_END_ARG_INFO()
@@ -2039,10 +1893,10 @@
+ZEND_END_ARG_INFO()
+#endif
/* }}} */
-
+
/*
- This is just a small subset of the functionality provided by the LDAP library. All the
-@@ -3180,9 +4605,22 @@
+ This is just a small subset of the functionality provided by the LDAP library. All the
+@@ -3287,10 +4623,23 @@
#endif
#ifdef HAVE_LDAP_START_TLS_S
PHP_FE(ldap_start_tls, arginfo_ldap_resource)
@@ -2058,14 +1912,15 @@
+#ifdef HAVE_LDAP_REFRESH
+ PHP_FE(ldap_refresh,
+ arginfo_ldap_refresh)
- #endif
+#endif
-+
+ #endif
++
#if defined(LDAP_API_FEATURE_X_OPENLDAP) && defined(HAVE_3ARG_SETREBINDPROC)
PHP_FE(ldap_set_rebind_proc, arginfo_ldap_set_rebind_proc)
#endif
-@@ -3193,8 +4631,33 @@
+
+@@ -3300,8 +4649,33 @@
PHP_FE(ldap_t61_to_8859, arginfo_ldap_t61_to_8859)
PHP_FE(ldap_8859_to_t61, arginfo_ldap_8859_to_t61)
#endif
@@ -2099,7 +1954,7 @@
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
-@@ -3219,8 +4682,10 @@
+@@ -3326,8 +4700,10 @@
STANDARD_MODULE_PROPERTIES_EX
};
/* }}} */
@@ -2110,18 +1965,13 @@
* Local variables:
* tab-width: 4
* c-basic-offset: 4
---- ext/ldap/php_ldap.h.orig 2015-03-19 01:19:30.000000000 +0100
-+++ ext/ldap/php_ldap.h 2015-04-13 05:48:10.000000000 +0200
-@@ -28,16 +28,148 @@
+--- ext/ldap/php_ldap.h.orig 2017-01-19 01:17:47.000000000 +0100
++++ ext/ldap/php_ldap.h 2017-05-07 10:03:31.000000000 +0200
+@@ -28,16 +28,139 @@
#endif
#include <ldap.h>
-+#define HAVE_3ARG_SETREBINDPROC
-+#define HAVE_LDAP_ADD_EXT_S
-+#define HAVE_LDAP_MODIFY_EXT_S
-+#define HAVE_LDAP_COMPARE_EXT_S
-+#define HAVE_LDAP_DELETE_EXT_S
+#define HAVE_LDAP_PARSE_EXTENDED_RESULT
+#define HAVE_LDAP_PARSE_PASSWD
+#define HAVE_LDAP_PARSE_WHOAMI
@@ -2129,10 +1979,6 @@
+#define HAVE_LDAP_PASSWD_S
+#define HAVE_LDAP_WHOAMI_S
+#define HAVE_LDAP_REFRESH
-+#define HAVE_LDAP_EXTENDED_OPERATION_S
-+#define HAVE_LDAP_REFRESH
-+#define HAVE_LDAP_EXTENDED_OPERATION_S
-+#define HAVE_LDAP_REFRESH
+#define HAVE_LDAP_EXTENDED_OPERATION
+
+