pkgsrc-Changes archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

CVS commit: pkgsrc/databases/php-ldap



Module Name:    pkgsrc
Committed By:   manu
Date:           Wed Jul 19 16:20:07 UTC 2017

Modified Files:
        pkgsrc/databases/php-ldap: Makefile
Added Files:
        pkgsrc/databases/php-ldap/files: ldap-ctrl-exop70.patch
            ldap-ctrl-exop71.patch

Log Message:
Add php70 and php71 patches for the exop option

The LDAP controls and extended operations (EXOP) has been merged upstream
with some modifications. The patches backports upstream code to php70
and php71, with additionnal EXOP REFRESH support that is missing for now.


To generate a diff of this commit:
cvs rdiff -u -r1.27 -r1.28 pkgsrc/databases/php-ldap/Makefile
cvs rdiff -u -r0 -r1.1 pkgsrc/databases/php-ldap/files/ldap-ctrl-exop70.patch \
    pkgsrc/databases/php-ldap/files/ldap-ctrl-exop71.patch

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: pkgsrc/databases/php-ldap/Makefile
diff -u pkgsrc/databases/php-ldap/Makefile:1.27 pkgsrc/databases/php-ldap/Makefile:1.28
--- pkgsrc/databases/php-ldap/Makefile:1.27     Sat Apr  2 09:05:22 2016
+++ pkgsrc/databases/php-ldap/Makefile  Wed Jul 19 16:20:07 2017
@@ -1,6 +1,7 @@
-# $NetBSD: Makefile,v 1.27 2016/04/02 09:05:22 taca Exp $
+# $NetBSD: Makefile,v 1.28 2017/07/19 16:20:07 manu Exp $
 
 MODNAME=               ldap
+PKGREVISION=           1
 CATEGORIES+=           databases
 COMMENT=               PHP extension for LDAP database access
 

Added files:

Index: pkgsrc/databases/php-ldap/files/ldap-ctrl-exop70.patch
diff -u /dev/null pkgsrc/databases/php-ldap/files/ldap-ctrl-exop70.patch:1.1
--- /dev/null   Wed Jul 19 16:20:07 2017
+++ pkgsrc/databases/php-ldap/files/ldap-ctrl-exop70.patch      Wed Jul 19 16:20:07 2017
@@ -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
+@@ -22,8 +22,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
+@@ -239,8 +239,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);
+ 
+@@ -2184,11 +2262,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:
+@@ -2455,8 +2563,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)
+ {
+@@ -3035,8 +3204,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)
+@@ -3310,8 +3716,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
+@@ -3374,8 +3822,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)
Index: pkgsrc/databases/php-ldap/files/ldap-ctrl-exop71.patch
diff -u /dev/null pkgsrc/databases/php-ldap/files/ldap-ctrl-exop71.patch:1.1
--- /dev/null   Wed Jul 19 16:20:07 2017
+++ pkgsrc/databases/php-ldap/files/ldap-ctrl-exop71.patch      Wed Jul 19 16:20:07 2017
@@ -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)



Home | Main Index | Thread Index | Old Index