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)