diff options
author | manu <manu@pkgsrc.org> | 2017-05-12 08:28:12 +0000 |
---|---|---|
committer | manu <manu@pkgsrc.org> | 2017-05-12 08:28:12 +0000 |
commit | cc52de5cac5068e58be3ac3ad480c539c01edb4d (patch) | |
tree | f1867d61899f919ecbb9f8ea873925db6103e7e3 /databases | |
parent | 07027b7728597f06f5d243bcacac31836398dfea (diff) | |
download | pkgsrc-cc52de5cac5068e58be3ac3ad480c539c01edb4d.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')
-rw-r--r-- | databases/php-ldap/files/ldap-ctrl-exop54.patch | 2271 | ||||
-rw-r--r-- | databases/php-ldap/files/ldap-ctrl-exop55.patch | 2300 | ||||
-rw-r--r-- | databases/php-ldap/files/ldap-ctrl-exop56.patch | 628 |
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 + + |