diff options
Diffstat (limited to 'databases/php-ldap/files/ldap-ctrl-exop71.patch')
-rw-r--r-- | databases/php-ldap/files/ldap-ctrl-exop71.patch | 561 |
1 files changed, 561 insertions, 0 deletions
diff --git a/databases/php-ldap/files/ldap-ctrl-exop71.patch b/databases/php-ldap/files/ldap-ctrl-exop71.patch new file mode 100644 index 00000000000..112aad548f7 --- /dev/null +++ b/databases/php-ldap/files/ldap-ctrl-exop71.patch @@ -0,0 +1,561 @@ +From upstream: +git diff 035a27cbc63d87a6acc761ce51109bcf47f9c27b \ + ed8bfcc6ea60c9d5b8c6b10f9e5175237fe28751 -- ext/ldap/ldap.c \ + ext/ldap/config.m4 ext/ldap/config.w32 + +Addditionnal uncommitted yet modification for ldap_exop_refresh +(NB: previous patch had ldap_refresh with different prototype) + +--- ext/ldap/config.m4.orig ++++ ext/ldap/config.m4 +@@ -203,9 +203,9 @@ + fi + + dnl Solaris 2.8 claims to be 2004 API, but doesn't have + dnl ldap_parse_reference() nor ldap_start_tls_s() +- AC_CHECK_FUNCS([ldap_parse_result ldap_parse_reference ldap_start_tls_s ldap_control_find]) ++ AC_CHECK_FUNCS([ldap_parse_result ldap_parse_reference ldap_start_tls_s ldap_control_find ldap_parse_extended_result ldap_extended_operation ldap_extended_operation_s ldap_passwd_s ldap_whoami_s ldap_refresh_s]) + + dnl + dnl SASL check + dnl +--- ext/ldap/config.w32.orig ++++ ext/ldap/config.w32 +@@ -20,8 +20,14 @@ + AC_DEFINE('HAVE_LDAP_SASL', 1); + AC_DEFINE('HAVE_LDAP_SASL_SASL_H', 1); + AC_DEFINE('LDAP_DEPRECATED', 1); + AC_DEFINE('HAVE_LDAP_CONTROL_FIND', 1); ++ AC_DEFINE('HAVE_LDAP_PARSE_EXTENDED_RESULT', 1); ++ AC_DEFINE('HAVE_LDAP_EXTENDED_OPERATION_S', 1); ++ AC_DEFINE('HAVE_LDAP_PASSWD_S', 1); ++ AC_DEFINE('HAVE_LDAP_WHOAMI_S', 1); ++ AC_DEFINE('HAVE_LDAP_REFRESH_S', 1); ++ AC_DEFINE('HAVE_LDAP_EXTENDED_OPERATION', 1); + + } else { + WARNING("ldap not enabled; libraries and headers not found"); + } +--- ext/ldap/ldap.c.orig ++++ ext/ldap/ldap.c +@@ -288,8 +288,86 @@ + + REGISTER_LONG_CONSTANT("LDAP_ESCAPE_FILTER", PHP_LDAP_ESCAPE_FILTER, CONST_PERSISTENT | CONST_CS); + REGISTER_LONG_CONSTANT("LDAP_ESCAPE_DN", PHP_LDAP_ESCAPE_DN, CONST_PERSISTENT | CONST_CS); + ++#ifdef HAVE_LDAP_EXTENDED_OPERATION_S ++ REGISTER_STRING_CONSTANT("LDAP_EXOP_START_TLS", LDAP_EXOP_START_TLS, CONST_PERSISTENT | CONST_CS); ++ REGISTER_STRING_CONSTANT("LDAP_EXOP_MODIFY_PASSWD", LDAP_EXOP_MODIFY_PASSWD, CONST_PERSISTENT | CONST_CS); ++ REGISTER_STRING_CONSTANT("LDAP_EXOP_REFRESH", LDAP_EXOP_REFRESH, CONST_PERSISTENT | CONST_CS); ++ REGISTER_STRING_CONSTANT("LDAP_EXOP_WHO_AM_I", LDAP_EXOP_WHO_AM_I, CONST_PERSISTENT | CONST_CS); ++ REGISTER_STRING_CONSTANT("LDAP_EXOP_TURN", LDAP_EXOP_TURN, CONST_PERSISTENT | CONST_CS); ++#endif ++ ++/* LDAP Controls */ ++/* standard track controls */ ++#ifdef LDAP_CONTROL_MANAGEDSAIT ++ /* RFC 3296 */ ++ REGISTER_STRING_CONSTANT("LDAP_CONTROL_MANAGEDSAIT", LDAP_CONTROL_MANAGEDSAIT, CONST_PERSISTENT | CONST_CS); ++#endif ++#ifdef LDAP_CONTROL_PROXY_AUTHZ ++ /* RFC 4370 */ ++ REGISTER_STRING_CONSTANT("LDAP_CONTROL_PROXY_AUTHZ", LDAP_CONTROL_PROXY_AUTHZ, CONST_PERSISTENT | CONST_CS); ++#endif ++#ifdef LDAP_CONTROL_SUBENTRIES ++ /* RFC 3672 */ ++ REGISTER_STRING_CONSTANT("LDAP_CONTROL_SUBENTRIES", LDAP_CONTROL_SUBENTRIES, CONST_PERSISTENT | CONST_CS); ++#endif ++#ifdef LDAP_CONTROL_VALUESRETURNFILTER ++ /* RFC 3876 */ ++ REGISTER_STRING_CONSTANT("LDAP_CONTROL_VALUESRETURNFILTER", LDAP_CONTROL_VALUESRETURNFILTER, CONST_PERSISTENT | CONST_CS); ++#endif ++#ifdef LDAP_CONTROL_ASSERT ++ /* RFC 4528 */ ++ REGISTER_STRING_CONSTANT("LDAP_CONTROL_ASSERT", LDAP_CONTROL_ASSERT, CONST_PERSISTENT | CONST_CS); ++ /* RFC 4527 */ ++ REGISTER_STRING_CONSTANT("LDAP_CONTROL_PRE_READ", LDAP_CONTROL_PRE_READ, CONST_PERSISTENT | CONST_CS); ++ REGISTER_STRING_CONSTANT("LDAP_CONTROL_POST_READ", LDAP_CONTROL_POST_READ, CONST_PERSISTENT | CONST_CS); ++#endif ++#ifdef LDAP_CONTROL_SORTREQUEST ++ /* RFC 2891 */ ++ REGISTER_STRING_CONSTANT("LDAP_CONTROL_SORTREQUEST", LDAP_CONTROL_SORTREQUEST, CONST_PERSISTENT | CONST_CS); ++ REGISTER_STRING_CONSTANT("LDAP_CONTROL_SORTRESPONSE", LDAP_CONTROL_SORTRESPONSE, CONST_PERSISTENT | CONST_CS); ++#endif ++/* non-standard track controls */ ++#ifdef LDAP_CONTROL_PAGEDRESULTS ++ /* RFC 2696 */ ++ REGISTER_STRING_CONSTANT("LDAP_CONTROL_PAGEDRESULTS", LDAP_CONTROL_PAGEDRESULTS, CONST_PERSISTENT | CONST_CS); ++#endif ++#ifdef LDAP_CONTROL_AUTHZID_REQUEST ++ /* RFC 3829 */ ++ REGISTER_STRING_CONSTANT("LDAP_CONTROL_AUTHZID_REQUEST", LDAP_CONTROL_AUTHZID_REQUEST, CONST_PERSISTENT | CONST_CS); ++ REGISTER_STRING_CONSTANT("LDAP_CONTROL_AUTHZID_RESPONSE", LDAP_CONTROL_AUTHZID_RESPONSE, CONST_PERSISTENT | CONST_CS); ++#endif ++#ifdef LDAP_CONTROL_SYNC ++ /* LDAP Content Synchronization Operation -- RFC 4533 */ ++ REGISTER_STRING_CONSTANT("LDAP_CONTROL_SYNC", LDAP_CONTROL_SYNC, CONST_PERSISTENT | CONST_CS); ++ REGISTER_STRING_CONSTANT("LDAP_CONTROL_SYNC_STATE", LDAP_CONTROL_SYNC_STATE, CONST_PERSISTENT | CONST_CS); ++ REGISTER_STRING_CONSTANT("LDAP_CONTROL_SYNC_DONE", LDAP_CONTROL_SYNC_DONE, CONST_PERSISTENT | CONST_CS); ++#endif ++#ifdef LDAP_CONTROL_DONTUSECOPY ++ /* LDAP Don't Use Copy Control (RFC 6171) */ ++ REGISTER_STRING_CONSTANT("LDAP_CONTROL_DONTUSECOPY", LDAP_CONTROL_DONTUSECOPY, CONST_PERSISTENT | CONST_CS); ++#endif ++#ifdef LDAP_CONTROL_PASSWORDPOLICYREQUEST ++ /* Password policy Controls */ ++ REGISTER_STRING_CONSTANT("LDAP_CONTROL_PASSWORDPOLICYREQUEST", LDAP_CONTROL_PASSWORDPOLICYREQUEST, CONST_PERSISTENT | CONST_CS); ++ REGISTER_STRING_CONSTANT("LDAP_CONTROL_PASSWORDPOLICYRESPONSE", LDAP_CONTROL_PASSWORDPOLICYRESPONSE, CONST_PERSISTENT | CONST_CS); ++#endif ++#ifdef LDAP_CONTROL_X_INCREMENTAL_VALUES ++ /* MS Active Directory controls */ ++ REGISTER_STRING_CONSTANT("LDAP_CONTROL_X_INCREMENTAL_VALUES", LDAP_CONTROL_X_INCREMENTAL_VALUES, CONST_PERSISTENT | CONST_CS); ++ REGISTER_STRING_CONSTANT("LDAP_CONTROL_X_DOMAIN_SCOPE", LDAP_CONTROL_X_DOMAIN_SCOPE, CONST_PERSISTENT | CONST_CS); ++ REGISTER_STRING_CONSTANT("LDAP_CONTROL_X_PERMISSIVE_MODIFY", LDAP_CONTROL_X_PERMISSIVE_MODIFY, CONST_PERSISTENT | CONST_CS); ++ REGISTER_STRING_CONSTANT("LDAP_CONTROL_X_SEARCH_OPTIONS", LDAP_CONTROL_X_SEARCH_OPTIONS, CONST_PERSISTENT | CONST_CS); ++ REGISTER_STRING_CONSTANT("LDAP_CONTROL_X_TREE_DELETE", LDAP_CONTROL_X_TREE_DELETE, CONST_PERSISTENT | CONST_CS); ++ REGISTER_STRING_CONSTANT("LDAP_CONTROL_X_EXTENDED_DN", LDAP_CONTROL_X_EXTENDED_DN, CONST_PERSISTENT | CONST_CS); ++#endif ++#ifdef LDAP_CONTROL_X_INCREMENTAL_VALUES ++ /* LDAP VLV */ ++ REGISTER_STRING_CONSTANT("LDAP_CONTROL_VLVREQUEST", LDAP_CONTROL_VLVREQUEST, CONST_PERSISTENT | CONST_CS); ++ REGISTER_STRING_CONSTANT("LDAP_CONTROL_VLVRESPONSE", LDAP_CONTROL_VLVRESPONSE, CONST_PERSISTENT | CONST_CS); ++#endif ++ + le_link = zend_register_list_destructors_ex(_close_ldap_link, NULL, "ldap link", module_number); + le_result = zend_register_list_destructors_ex(_free_ldap_result, NULL, "ldap result", module_number); + le_result_entry = zend_register_list_destructors_ex(_free_ldap_result_entry, NULL, "ldap result entry", module_number); + +@@ -2270,11 +2348,41 @@ + zval_ptr_dtor(retval); + ZVAL_STRING(retval, val); + ldap_memfree(val); + } break; +-/* options not implemented + case LDAP_OPT_SERVER_CONTROLS: + case LDAP_OPT_CLIENT_CONTROLS: ++ { ++ zval tmp1; ++ int num_entries; ++ LDAPControl **ctrls = NULL, **ctrlp; ++ ++ if (ldap_get_option(ld->link, option, &ctrls) || ctrls == NULL) { ++ if (ctrls) { ++ ldap_memfree(ctrls); ++ } ++ RETURN_FALSE; ++ } ++ ++ zval_ptr_dtor(retval); ++ array_init(retval); ++ num_entries = 0; ++ ctrlp = ctrls; ++ while (*ctrlp != NULL) ++ { ++ array_init(&tmp1); ++ add_assoc_string(&tmp1, "oid", (*ctrlp)->ldctl_oid); ++ add_assoc_bool(&tmp1, "iscritical", ((*ctrlp)->ldctl_iscritical != 0)); ++ if ((*ctrlp)->ldctl_value.bv_len) { ++ add_assoc_stringl(&tmp1, "value", (*ctrlp)->ldctl_value.bv_val, (*ctrlp)->ldctl_value.bv_len); ++ } ++ zend_hash_index_update(Z_ARRVAL_P(retval), num_entries, &tmp1); ++ num_entries++; ++ ctrlp++; ++ } ++ ldap_controls_free(ctrls); ++ } break; ++/* options not implemented + case LDAP_OPT_API_INFO: + case LDAP_OPT_API_FEATURE_INFO: + */ + default: +@@ -2569,8 +2677,69 @@ + } + /* }}} */ + #endif + ++/* {{{ Extended operation response parsing, Pierangelo Masarati */ ++#ifdef HAVE_LDAP_PARSE_EXTENDED_RESULT ++/* {{{ proto bool ldap_parse_exop(resource link, resource result [, string retdata [, string retoid]]) ++ Extract information from extended operation result */ ++PHP_FUNCTION(ldap_parse_exop) ++{ ++ zval *link, *result, *retdata, *retoid; ++ ldap_linkdata *ld; ++ LDAPMessage *ldap_result; ++ char *lretoid; ++ struct berval *lretdata; ++ int rc, myargcount = ZEND_NUM_ARGS(); ++ ++ if (zend_parse_parameters(ZEND_NUM_ARGS(), "rr|z/z/", &link, &result, &retdata, &retoid) != SUCCESS) { ++ WRONG_PARAM_COUNT; ++ } ++ ++ if ((ld = (ldap_linkdata *)zend_fetch_resource(Z_RES_P(link), "ldap link", le_link)) == NULL) { ++ RETURN_FALSE; ++ } ++ ++ if ((ldap_result = (LDAPMessage *)zend_fetch_resource(Z_RES_P(result), "ldap result", le_result)) == NULL) { ++ RETURN_FALSE; ++ } ++ ++ rc = ldap_parse_extended_result(ld->link, ldap_result, ++ myargcount > 3 ? &lretoid: NULL, ++ myargcount > 2 ? &lretdata: NULL, ++ 0); ++ if (rc != LDAP_SUCCESS) { ++ php_error_docref(NULL, E_WARNING, "Unable to parse extended operation result: %s", ldap_err2string(rc)); ++ RETURN_FALSE; ++ } ++ ++ /* Reverse -> fall through */ ++ switch (myargcount) { ++ case 4: ++ zval_dtor(retoid); ++ if (lretoid == NULL) { ++ ZVAL_EMPTY_STRING(retoid); ++ } else { ++ ZVAL_STRING(retoid, lretoid); ++ ldap_memfree(lretoid); ++ } ++ case 3: ++ /* use arg #3 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); ++ ldap_memfree(lretdata->bv_val); ++ ldap_memfree(lretdata); ++ } ++ } ++ RETURN_TRUE; ++} ++/* }}} */ ++#endif ++/* }}} */ ++ + /* {{{ proto resource ldap_first_reference(resource link, resource result) + Return first reference */ + PHP_FUNCTION(ldap_first_reference) + { +@@ -3156,8 +3325,245 @@ + } + /* }}} */ + #endif + ++/* {{{ Extended operations, Pierangelo Masarati */ ++#ifdef HAVE_LDAP_EXTENDED_OPERATION_S ++/* {{{ proto ? ldap_exop(resource link, string reqoid [, string reqdata [, string retdata [, string retoid]]]) ++ Extended operation */ ++PHP_FUNCTION(ldap_exop) ++{ ++ zval *link, *reqoid, *reqdata, *retdata, *retoid; ++ char *lreqoid, *lretoid = NULL; ++ struct berval lreqdata, *lretdata = NULL; ++ ldap_linkdata *ld; ++ LDAPMessage *ldap_res; ++ int rc, msgid, myargcount = ZEND_NUM_ARGS(); ++ /* int reqoid_len, reqdata_len, retdata_len, retoid_len, retdat_len; */ ++ ++ if (zend_parse_parameters(ZEND_NUM_ARGS(), "rz|zz/z/", &link, &reqoid, &reqdata, &retdata, &retoid) != SUCCESS) { ++ WRONG_PARAM_COUNT; ++ } ++ ++ if ((ld = (ldap_linkdata *)zend_fetch_resource(Z_RES_P(link), "ldap link", le_link)) == NULL) { ++ RETURN_FALSE; ++ } ++ ++ switch (myargcount) { ++ case 5: ++ case 4: ++ case 3: ++ convert_to_string_ex(reqdata); ++ lreqdata.bv_val = Z_STRVAL_P(reqdata); ++ lreqdata.bv_len = Z_STRLEN_P(reqdata); ++ /* fallthru */ ++ case 2: ++ convert_to_string_ex(reqoid); ++ lreqoid = Z_STRVAL_P(reqoid); ++ } ++ ++ if (myargcount > 3) { ++ /* synchronous call */ ++ rc = ldap_extended_operation_s(ld->link, lreqoid, ++ lreqdata.bv_len > 0 ? &lreqdata: NULL, ++ NULL, ++ NULL, ++ myargcount > 4 ? &lretoid : NULL, ++ &lretdata ); ++ if (rc != LDAP_SUCCESS ) { ++ php_error_docref(NULL, E_WARNING, "Extended operation %s failed: %s (%d)", lreqoid, ldap_err2string(rc), rc); ++ RETURN_FALSE; ++ } ++ ++ /* Reverse -> fall through */ ++ switch (myargcount) { ++ case 5: ++ zval_dtor(retoid); ++ if (lretoid == NULL) { ++ ZVAL_EMPTY_STRING(retoid); ++ } else { ++ ZVAL_STRING(retoid, lretoid); ++ ldap_memfree(lretoid); ++ } ++ 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); ++ ldap_memfree(lretdata->bv_val); ++ ldap_memfree(lretdata); ++ } ++ } ++ ++ 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, 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, E_WARNING, "Extended operation %s failed", lreqoid); ++ RETURN_FALSE; ++ } ++ ++ /* return a PHP control object */ ++ RETVAL_RES(zend_register_resource(ldap_res, le_result)); ++} ++/* }}} */ ++#endif ++ ++#ifdef HAVE_LDAP_PASSWD_S ++/* {{{ proto bool|string ldap_exop_passwd(resource link [, string user [, string oldpw [, string newpw ]]]) ++ Passwd modify extended operation */ ++PHP_FUNCTION(ldap_exop_passwd) ++{ ++ zval *link, *user, *newpw, *oldpw; ++ struct berval luser, loldpw, lnewpw, lgenpasswd; ++ ldap_linkdata *ld; ++ int rc, myargcount = ZEND_NUM_ARGS(); ++ ++ if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|zzz", &link, &user, &oldpw, &newpw) == FAILURE) { ++ WRONG_PARAM_COUNT; ++ } ++ ++ if ((ld = (ldap_linkdata *)zend_fetch_resource(Z_RES_P(link), "ldap link", le_link)) == NULL) { ++ RETURN_FALSE; ++ } ++ ++ luser.bv_len = 0; ++ loldpw.bv_len = 0; ++ lnewpw.bv_len = 0; ++ ++ switch (myargcount) { ++ case 4: ++ convert_to_string_ex(newpw); ++ lnewpw.bv_val = Z_STRVAL_P(newpw); ++ lnewpw.bv_len = Z_STRLEN_P(newpw); ++ ++ case 3: ++ convert_to_string_ex(oldpw); ++ loldpw.bv_val = Z_STRVAL_P(oldpw); ++ loldpw.bv_len = Z_STRLEN_P(oldpw); ++ ++ case 2: ++ convert_to_string_ex(user); ++ luser.bv_val = Z_STRVAL_P(user); ++ luser.bv_len = Z_STRLEN_P(user); ++ } ++ ++ /* synchronous call */ ++ rc = ldap_passwd_s(ld->link, &luser, ++ loldpw.bv_len > 0 ? &loldpw : NULL, ++ lnewpw.bv_len > 0 ? &lnewpw : NULL, ++ &lgenpasswd, NULL, NULL); ++ if (rc != LDAP_SUCCESS ) { ++ php_error_docref(NULL, E_WARNING, "Passwd modify extended operation failed: %s (%d)", ldap_err2string(rc), rc); ++ RETURN_FALSE; ++ } ++ ++ if (lnewpw.bv_len == 0) { ++ if (lgenpasswd.bv_len == 0) { ++ RETVAL_EMPTY_STRING(); ++ } else { ++ RETVAL_STRINGL(lgenpasswd.bv_val, lgenpasswd.bv_len); ++ } ++ } else { ++ RETURN_TRUE; ++ } ++ ++ ldap_memfree(lgenpasswd.bv_val); ++} ++/* }}} */ ++#endif ++ ++#ifdef HAVE_LDAP_WHOAMI_S ++/* {{{ proto bool|string ldap_exop_whoami(resource link) ++ Whoami extended operation */ ++PHP_FUNCTION(ldap_exop_whoami) ++{ ++ zval *link; ++ struct berval *lauthzid; ++ ldap_linkdata *ld; ++ int rc, myargcount = ZEND_NUM_ARGS(); ++ ++ if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &link) == FAILURE) { ++ WRONG_PARAM_COUNT; ++ } ++ ++ if ((ld = (ldap_linkdata *)zend_fetch_resource(Z_RES_P(link), "ldap link", le_link)) == NULL) { ++ RETURN_FALSE; ++ } ++ ++ /* synchronous call */ ++ rc = ldap_whoami_s(ld->link, &lauthzid, NULL, NULL); ++ if (rc != LDAP_SUCCESS ) { ++ php_error_docref(NULL, E_WARNING, "Whoami extended operation failed: %s (%d)", ldap_err2string(rc), rc); ++ RETURN_FALSE; ++ } ++ ++ if (lauthzid == NULL) { ++ RETVAL_EMPTY_STRING(); ++ } else { ++ RETVAL_STRINGL(lauthzid->bv_val, lauthzid->bv_len); ++ ldap_memfree(lauthzid->bv_val); ++ ldap_memfree(lauthzid); ++ } ++} ++/* }}} */ ++#endif ++ ++#ifdef HAVE_LDAP_REFRESH_S ++/* {{{ proto int ldap_exop_refresh(resource link , string dn , int ttl) ++ DDS refresh extended operation */ ++PHP_FUNCTION(ldap_exop_refresh) ++{ ++ zval *link, *dn, *ttl; ++ struct berval ldn; ++ ber_int_t lttl; ++ ber_int_t newttl; ++ ldap_linkdata *ld; ++ int rc; ++ ++ if (zend_parse_parameters(ZEND_NUM_ARGS(), "rzz", &link, &dn, &ttl) != SUCCESS) { ++ WRONG_PARAM_COUNT; ++ } ++ ++ if ((ld = (ldap_linkdata *)zend_fetch_resource(Z_RES_P(link), "ldap link", le_link)) == NULL) { ++ RETURN_FALSE; ++ } ++ ++ ldn.bv_len = 0; ++ convert_to_string_ex(dn); ++ ldn.bv_val = Z_STRVAL_P(dn); ++ ldn.bv_len = Z_STRLEN_P(dn); ++ ++ convert_to_long_ex(ttl); ++ lttl = (ber_int_t)Z_LVAL_P(ttl); ++ ++ rc = ldap_refresh_s(ld->link, &ldn, lttl, &newttl, NULL, NULL); ++ if (rc != LDAP_SUCCESS ) { ++ php_error_docref(NULL, E_WARNING, ++ "Refresh extended operation failed: %s (%d)", ++ ldap_err2string(rc), rc); ++ RETURN_FALSE; ++ } ++ ++ RETURN_LONG(newttl); ++} ++/* }}} */ ++#endif ++ ++/* }}} */ ++ + /* {{{ arginfo */ + ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_connect, 0, 0, 0) + ZEND_ARG_INFO(0, hostname) + ZEND_ARG_INFO(0, port) +@@ -3431,8 +3837,50 @@ + 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(0, reqdata) ++ ZEND_ARG_INFO(1, retdata) ++ ZEND_ARG_INFO(1, retoid) ++ZEND_END_ARG_INFO() ++#endif ++ ++#ifdef HAVE_LDAP_PASSWD_S ++ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_exop_passwd, 0, 0, 4) ++ ZEND_ARG_INFO(0, link) ++ ZEND_ARG_INFO(0, user) ++ ZEND_ARG_INFO(0, oldpw) ++ ZEND_ARG_INFO(0, newpw) ++ZEND_END_ARG_INFO() ++#endif ++ ++#ifdef HAVE_LDAP_WHOAMI_S ++ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_exop_whoami, 0, 0, 1) ++ ZEND_ARG_INFO(0, link) ++ZEND_END_ARG_INFO() ++#endif ++ ++#ifdef HAVE_LDAP_REFRESH_S ++ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_exop_refresh, 0, 0, 3) ++ ZEND_ARG_INFO(0, link) ++ ZEND_ARG_INFO(0, dn) ++ ZEND_ARG_INFO(0, ttl) ++ZEND_END_ARG_INFO() ++#endif ++ ++#ifdef HAVE_LDAP_PARSE_EXTENDED_RESULT ++ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_parse_exop, 0, 0, 4) ++ ZEND_ARG_INFO(0, link) ++ ZEND_ARG_INFO(0, result) ++ ZEND_ARG_INFO(1, retdata) ++ ZEND_ARG_INFO(1, retoid) ++ZEND_END_ARG_INFO() ++#endif + /* }}} */ + + /* + This is just a small subset of the functionality provided by the LDAP library. All the +@@ -3495,8 +3943,23 @@ + #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) ++#endif ++#ifdef HAVE_LDAP_PASSWD_S ++ PHP_FE(ldap_exop_passwd, arginfo_ldap_exop_passwd) ++#endif ++#ifdef HAVE_LDAP_WHOAMI_S ++ PHP_FE(ldap_exop_whoami, arginfo_ldap_exop_whoami) ++#endif ++#ifdef HAVE_LDAP_REFRESH_S ++ PHP_FE(ldap_exop_refresh, arginfo_ldap_exop_refresh) ++#endif ++#ifdef HAVE_LDAP_PARSE_EXTENDED_RESULT ++ PHP_FE(ldap_parse_exop, arginfo_ldap_parse_exop) ++#endif + #endif + + #if defined(LDAP_API_FEATURE_X_OPENLDAP) && defined(HAVE_3ARG_SETREBINDPROC) + PHP_FE(ldap_set_rebind_proc, arginfo_ldap_set_rebind_proc) |