2633d9211a
A code repetition caused add and modify operations to be done twice.
1909 lines
55 KiB
Diff
1909 lines
55 KiB
Diff
--- ext/ldap/ldap.c.orig 2017-01-19 01:17:47.000000000 +0100
|
|
+++ ext/ldap/ldap.c 2017-05-31 16:03:19.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
|
|
|
|
+#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 */
|
|
+
|
|
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);
|
|
|
|
le_link = zend_register_list_destructors_ex(_close_ldap_link, NULL, "ldap link", module_number);
|
|
@@ -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)
|
|
+{
|
|
+ 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)
|
|
{
|
|
@@ -639,8 +806,9 @@
|
|
_php_sasl_freedefs(ctx);
|
|
}
|
|
/* }}} */
|
|
#endif /* HAVE_LDAP_SASL */
|
|
+/* }}} */
|
|
|
|
/* {{{ proto bool ldap_unbind(resource link)
|
|
Unbind from LDAP directory */
|
|
PHP_FUNCTION(ldap_unbind)
|
|
@@ -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
|
|
*/
|
|
-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 */
|
|
-
|
|
- 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;
|
|
+ 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;
|
|
}
|
|
|
|
- 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));
|
|
+ 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) {
|
|
oper = LDAP_MOD_ADD;
|
|
is_full_add = 1;
|
|
}
|
|
/* end additional , gerrit thomson */
|
|
|
|
+
|
|
+ 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;
|
|
@@ -1458,19 +1640,71 @@
|
|
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_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;
|
|
+ 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 {
|
|
- 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;
|
|
+
|
|
+ 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_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++) {
|
|
@@ -1483,8 +1717,17 @@
|
|
}
|
|
efree(num_berval);
|
|
efree(ldap_mods);
|
|
|
|
+ if (ext) {
|
|
+ if (lsctrls) {
|
|
+ _php_free_controls(&lsctrls);
|
|
+ }
|
|
+ if (lcctrls) {
|
|
+ _php_free_controls(&lcctrls);
|
|
+ }
|
|
+ }
|
|
+
|
|
return;
|
|
}
|
|
/* }}} */
|
|
|
|
@@ -1492,9 +1735,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 */
|
|
- php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_LD_FULL_ADD);
|
|
+ php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_LD_FULL_ADD, 0);
|
|
}
|
|
/* }}} */
|
|
|
|
/* three functions for attribute base modifications, gerrit Thomson */
|
|
@@ -1502,25 +1745,25 @@
|
|
/* {{{ 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)
|
|
@@ -1946,42 +2189,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)
|
|
+/* {{{ proto void php_ldap_do_compare */
|
|
+static 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;
|
|
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;
|
|
+ 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;
|
|
+ }
|
|
}
|
|
|
|
- lvalue.bv_val = value;
|
|
- lvalue.bv_len = value_len;
|
|
-
|
|
ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
|
|
|
|
- errno = ldap_compare_ext_s(ld->link, dn, attr, &lvalue, NULL, NULL);
|
|
+ if (ext) {
|
|
+ struct berval ldap_bvalue;
|
|
+ switch (myargcount) {
|
|
+ case 6:
|
|
+ _php_parse_controls(cctrls, &lcctrls);
|
|
+ case 5:
|
|
+ _php_parse_controls(sctrls, &lsctrls);
|
|
+ }
|
|
|
|
- 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);
|
|
+ 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;
|
|
|
|
- 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;
|
|
- break;
|
|
- }
|
|
+ }
|
|
+
|
|
+ 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 {
|
|
+ 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);
|
|
+
|
|
+ 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(errno));
|
|
- RETURN_LONG(-1);
|
|
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Compare: %s", ldap_err2string(rc));
|
|
+ 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)
|
|
@@ -2013,17 +2318,189 @@
|
|
RETURN_TRUE;
|
|
}
|
|
/* }}} */
|
|
|
|
-#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP
|
|
+
|
|
+
|
|
+/* {{{ 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;
|
|
+ char *ldap_bind_dn = NULL, *ldap_bind_pw = NULL;
|
|
+ int ldap_bind_dnlen, ldap_bind_pwlen;
|
|
+ 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);
|
|
+
|
|
+#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
|
|
+
|
|
+ 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;
|
|
+ }
|
|
+
|
|
+
|
|
+ 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);
|
|
+
|
|
+ rc = ldap_delete_ext_s(ld->link, ldap_dn, NULL, NULL);
|
|
+ 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)
|
|
+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;
|
|
}
|
|
|
|
@@ -2058,9 +2535,9 @@
|
|
if (timeout) {
|
|
ldap_memfree(timeout);
|
|
}
|
|
RETURN_FALSE;
|
|
- }
|
|
+ }
|
|
if (!timeout) {
|
|
RETURN_FALSE;
|
|
}
|
|
zval_dtor(retval);
|
|
@@ -2320,20 +2797,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 serverctls)
|
|
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();
|
|
|
|
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rrz|zzz", &link, &result, &errcode, &matcheddn, &errmsg, &referrals) != SUCCESS) {
|
|
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rrz|zzzz", &link, &result, &errcode, &matcheddn, &errmsg, &referrals, &serverctrls) != SUCCESS) {
|
|
return;
|
|
}
|
|
|
|
ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
|
|
@@ -2342,9 +2820,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;
|
|
@@ -2354,19 +2832,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_memvfree((void**)lreferrals);
|
|
- }
|
|
+ _php_parse_referrals_resp(&lreferrals, &referrals);
|
|
case 5:
|
|
zval_dtor(errmsg);
|
|
if (lerrmsg == NULL) {
|
|
ZVAL_EMPTY_STRING(errmsg);
|
|
@@ -2387,8 +2861,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)
|
|
{
|
|
@@ -2636,9 +3244,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 +3272,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,8 +3556,690 @@
|
|
}
|
|
/* }}} */
|
|
#endif
|
|
|
|
+/* {{{ 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; */
|
|
+
|
|
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZ|ZZZ", &link, &reqoid, &reqdata, &retoid, &retdata) != 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;
|
|
+ }
|
|
+
|
|
+ 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;
|
|
+ }
|
|
+
|
|
+ /* 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)
|
|
@@ -3197,8 +4487,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
|
|
|
|
@@ -3223,8 +4514,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
|
|
@@ -3287,10 +4610,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)
|
|
+ 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
|
|
|
|
@@ -3300,8 +4636,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
|
|
@@ -3326,8 +4687,10 @@
|
|
STANDARD_MODULE_PROPERTIES_EX
|
|
};
|
|
/* }}} */
|
|
|
|
+
|
|
+
|
|
/*
|
|
* Local variables:
|
|
* tab-width: 4
|
|
* c-basic-offset: 4
|
|
--- ext/ldap/php_ldap.h.orig 2017-01-19 01:17:47.000000000 +0100
|
|
+++ ext/ldap/php_ldap.h 2017-05-31 16:02:46.000000000 +0200
|
|
@@ -28,16 +28,139 @@
|
|
#endif
|
|
|
|
#include <ldap.h>
|
|
|
|
+#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
|
|
+
|
|
+
|
|
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)
|