[PHP-DEV] [PATCH] LDAP module patch (adding new functionality).
by Ignacio Arenaza other posts by this author
Apr 9 2006 2:20PM messages near this date
Re: [PHP-DEV] Implementing PHP CGI on top of NETFile FTP/Web Server
|
Re: [PHP-DEV] [PATCH] LDAP module patch (adding new functionality).
Hi,
I have modified the ldap module to be able to use Paged Results (see
RFC 2696).
In order to do that, I have modified ldap_parse_result to provide the
server controls to the user. This is where paged results control
returned from the server are, specifically the cookie value. Without
this value you can't do paged results at all.
The values returned in this extension control are BER-encoded (see
ITU's X.690 recommendation) so I have created two new functions that
wrap around ber_printf() and ber_scanf(), to allow for the
encodig/decoding of these values.
I have tested these modifications with W2003 AD and OpenLDAP 2.1.x
servers, using a linux PHP client linked with OpenLDAP libraries (I
don't have access to neither Netscape's nor Oracle's libraries to test
them).
I have made diffs against current CVS versions as of today,
2006.04.09, 23:15 CET DST) for PHP_4_3, PHP_4_4, PHP_5_0, PHP_5_1
and HEAD branches. I'm sending them attached.
I hope this could be added to the standard version of PHP in the near
future.
Thanks in advance for your time.
Saludos. I�aki.
--
School of Management
Mondragon University
20560 O�ati - Spain
+34 943 718009 (ext. 225)
GPG Key available at public keyservers
Index: ext/ldap/ldap.c
===================================================================
RCS file: /repository/php-src/ext/ldap/ldap.c,v
retrieving revision 1.130.2.13
diff -u -r1.130.2.13 ldap.c
--- ext/ldap/ldap.c 8 May 2005 16:06:24 -0000 1.130.2.13
+++ ext/ldap/ldap.c 9 Apr 2006 20:46:51 -0000
@@ -74,7 +74,7 @@
ZEND_DECLARE_MODULE_GLOBALS(ldap)
static unsigned char third_argument_force_ref[] = { 3, BYREF_NONE, BYREF_NONE, BYREF_FORCE
};
-static unsigned char arg3to6of6_force_ref[] = { 6, BYREF_NONE, BYREF_NONE, BYREF_FORCE, BYR
EF_FORCE, BYREF_FORCE, BYREF_FORCE };
+static unsigned char arg3to7of7_force_ref[] = { 7, BYREF_NONE, BYREF_NONE, BYREF_FORCE, BYR
EF_FORCE, BYREF_FORCE, BYREF_FORCE, BYREF_FORCE };
static int le_link, le_result, le_result_entry, le_ber_entry;
@@ -131,8 +131,10 @@
PHP_FE(ldap_parse_reference, third_argument_force_ref)
#endif
#ifdef HAVE_LDAP_PARSE_RESULT
- PHP_FE(ldap_parse_result, arg3to6of6_force_ref)
+ PHP_FE(ldap_parse_result, arg3to7of7_force_ref)
#endif
+ PHP_FE(ldap_ber_printf, NULL)
+ PHP_FE(ldap_ber_scanf, NULL)
#ifdef HAVE_LDAP_START_TLS_S
PHP_FE(ldap_start_tls, NULL)
#endif
@@ -1759,18 +1761,19 @@
/* }}} */
#ifdef HAVE_LDAP_PARSE_RESULT
-/* {{{ proto bool ldap_parse_result(resource link, resource result, int errcode, string mat
cheddn, string errmsg, array referrals)
+/* {{{ proto bool ldap_parse_result(resource link, resource result, int errcode, string mat
cheddn, string errmsg, array referrals, array serverctrls)
Extract information from result */
PHP_FUNCTION(ldap_parse_result)
{
- zval **link, **result, **errcode, **matcheddn, **errmsg, **referrals;
+ zval **link, **result, **errcode, **matcheddn, **errmsg, **referrals, **serverctrls;
ldap_linkdata *ld;
LDAPMessage *ldap_result;
+ LDAPControl **lserverctrls, **ctrlp, *ctrl;
char **lreferrals, **refp;
char *lmatcheddn, *lerrmsg;
int rc, lerrcode, myargcount = ZEND_NUM_ARGS();
- if (myargcount < 3 || myargcount > 6 || zend_get_parameters_ex(myargcount, &link, &result,
&errcode, &matcheddn, &errmsg, &referrals) == FAILURE) {
+ if (myargcount < 3 || myargcount > 7 || zend_get_parameters_ex(myargcount, &link, &result,
&errcode, &matcheddn, &errmsg, &referrals, &serverctrls) == FAILURE) {
WRONG_PARAM_COUNT;
}
@@ -1781,7 +1784,7 @@
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));
@@ -1793,6 +1796,29 @@
/* Reverse -> fall through */
switch (myargcount) {
+ case 7 :
+ zval_dtor(*serverctrls);
+
+ if (lserverctrls != NULL) {
+ array_init(*serverctrls);
+ ctrlp = lserverctrls;
+
+ while (*ctrlp != NULL) {
+ zval *ctrl_array;
+
+ ctrl = *ctrlp;
+ MAKE_STD_ZVAL(ctrl_array);
+ array_init(ctrl_array);
+
+ add_assoc_string(ctrl_array, "oid", ctrl-> ldctl_oid,1);
+ add_assoc_bool(ctrl_array, "iscritical", ctrl-> ldctl_iscritical);
+ add_assoc_stringl(ctrl_array, "value", ctrl-> ldctl_value.bv_val,
+ ctrl-> ldctl_value.bv_len,1);
+ add_next_index_zval (*serverctrls, ctrl_array);
+ ctrlp++;
+ }
+ ldap_controls_free (lserverctrls);
+ }
case 6:
zval_dtor(*referrals);
array_init(*referrals);
@@ -1826,6 +1852,303 @@
/* }}} */
#endif
+/* {{{ proto string ldap_ber_printf(string format [, mixed arg1 [, mixed ...]])
+ Creates a BER encoded string of the values/types specified in the format string. Return
s the BER encoded string, or 'false' if the enconding failed */
+PHP_FUNCTION(ldap_ber_printf)
+{
+ zval ***args;
+ int argc, curarg, rc;
+ char *format;
+ char fmt_buf[5], *err_msg;
+ unsigned int format_length, pos;
+ BerElement *ber;
+ struct berval bv_str, *bv_retval;
+
+ argc = ZEND_NUM_ARGS();
+
+ if (argc < 1) {
+ WRONG_PARAM_COUNT;
+ }
+
+ args = (zval ***)safe_emalloc(argc, sizeof(zval *), 0);
+
+ if (zend_get_parameters_array_ex(argc, args) == FAILURE) {
+ efree(args);
+ WRONG_PARAM_COUNT;
+ }
+
+ convert_to_string_ex(args[0]);
+ format = Z_STRVAL_PP(args[0]);
+ format_length = Z_STRLEN_PP(args[0]);
+
+ ber = ber_alloc_t(LBER_USE_DER);
+ if (ber == NULL) {
+ efree(args);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to allocate enough memory");
+ RETURN_FALSE;
+ }
+
+ err_msg = NULL;
+ pos = 0;
+ curarg = 1;
+ while (pos < format_length) {
+ switch(format[pos]) {
+ case '{' :
+ case '}' :
+ case '[' :
+ case ']' :
+ case 'n' :
+ snprintf (fmt_buf, sizeof(fmt_buf), "%c", format[pos]);
+ rc = ber_printf(ber, fmt_buf);
+ break;
+ default:
+ if (curarg > = argc) {
+ err_msg = "Too few arguments";
+ goto ber_printf_errexit;
+ }
+ else {
+ switch(format[pos]) {
+ case 'b' :
+ convert_to_boolean_ex(args[curarg]);
+ rc = ber_printf(ber, "b", Z_LVAL_PP(args[curarg]));
+ curarg++;
+ break;
+ case 'e' :
+ case 'i' :
+ case 't' :
+ snprintf (fmt_buf, sizeof(fmt_buf), "%c", format[pos]);
+ convert_to_long_ex(args[curarg]);
+ rc = ber_printf(ber, fmt_buf, Z_LVAL_PP(args[curarg]));
+ curarg++;
+ break;
+ case 'B' :
+ convert_to_string_ex(args[curarg]);
+ rc = ber_printf(ber, "B", Z_STRVAL_PP(args[curarg]),
+ 8 * Z_STRLEN_PP(args[curarg]));
+ curarg++;
+ break;
+ case 's' :
+ convert_to_string_ex(args[curarg]);
+ rc = ber_printf(ber, "s", Z_STRVAL_PP(args[curarg]));
+ curarg++;
+ break;
+ case 'o' :
+ convert_to_string_ex(args[curarg]);
+ rc = ber_printf(ber, "o", Z_STRVAL_PP(args[curarg]),
+ Z_STRLEN_PP(args[curarg]));
+ curarg++;
+ break;
+ case 'O' :
+ convert_to_string_ex(args[curarg]);
+ bv_str.bv_val = Z_STRVAL_PP(args[curarg]);
+ bv_str.bv_len = Z_STRLEN_PP(args[curarg]);
+ rc = ber_printf(ber, "O", &bv_str);
+ curarg++;
+ break;
+ case 'v' :
+ case 'V' :
+ err_msg = "Unsupported format specifier by now: '%c'";
+ goto ber_printf_errexit;
+ break;
+ case 'W' : /* This is an OpenLDAP extension only
+ * not present on draft-ietf-ldapext-ldap-c-api-*.txt
+ */
+ default:
+ err_msg = "Unkown format specifier: '%c'";
+ goto ber_printf_errexit;
+ } /* switch */
+ } /* else */
+ } /* switch */
+ if (rc == -1) {
+ err_msg = "Unable to process some values. Check you format string and values";
+ goto ber_printf_errexit;
+ }
+ pos++;
+ }
+
+ if (ber_flatten (ber, &bv_retval) == -1) {
+ goto ber_printf_errexit;
+ }
+
+ RETVAL_STRINGL(bv_retval-> bv_val, bv_retval->bv_len, 1);
+ ber_bvfree(bv_retval);
+ ber_free(ber,0);
+ efree(args);
+ return;
+
+ber_printf_errexit:
+ ber_free(ber,0);
+ efree(args);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, err_msg, format[pos] );
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto int ldap_ber_scanf(string berval, string format [, mixed arg1 [, mixed ...]])
+ The complimentary function to ber_printf */
+PHP_FUNCTION(ldap_ber_scanf)
+{
+ zval ***args;
+ int argc, i, curarg, int_val;
+ char *format, *err_msg, *string;
+ char fmt_buf[5];
+ unsigned int format_length, pos;
+ BerElement *ber;
+ ber_tag_t rc, tag;
+ ber_len_t ber_len;
+ struct berval bv_str, *bv_ptr;
+
+
+ argc = ZEND_NUM_ARGS();
+ if (argc < 2) {
+ WRONG_PARAM_COUNT;
+ }
+
+ args = (zval ***) safe_emalloc(sizeof(zval **), argc, 0);
+ if (zend_get_parameters_array_ex(argc, args) == FAILURE) {
+ efree(args);
+ WRONG_PARAM_COUNT;
+ }
+
+ /* If any variables are passed, make sure they are all passed by reference */
+ if ((argc - 2) > 0) {
+ for (i = 2; i < argc; i++){
+ if ( ! PZVAL_IS_REF(*args[i])) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING,
+ "Parameter %d must be passed by reference", i);
+ RETURN_LONG(0);
+ }
+ }
+ }
+
+ err_msg = NULL;
+
+ convert_to_string_ex(args[0]);
+ convert_to_string_ex(args[1]);
+
+ bv_str.bv_val = Z_STRVAL_PP(args[0]);
+ bv_str.bv_len = Z_STRLEN_PP(args[0]);
+ ber = ber_init(&bv_str);
+ if (ber == NULL) {
+ efree(args);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING,
+ "Unable to allocate enough memory or invalid BER data");
+ RETURN_LONG(0);
+ }
+
+ format=Z_STRVAL_PP(args[1]);
+ format_length=Z_STRLEN_PP(args[1]);
+
+ pos = 0;
+ curarg = 2;
+ while (pos < format_length) {
+ switch(format[pos]) {
+ case '{' :
+ case '}' :
+ case '[' :
+ case ']' :
+ case 'n' :
+ snprintf (fmt_buf, sizeof(fmt_buf), "%c", format[pos]);
+ rc = ber_scanf(ber, fmt_buf);
+ break;
+ default:
+ if (curarg > = argc) {
+ err_msg = "Too few arguments";
+ goto ber_scanf_errexit;
+ }
+ else {
+ switch(format[pos]) {
+ case 'a' :
+ rc = ber_scanf(ber, "a", &string);
+ if (rc != LBER_ERROR) {
+ zval_dtor(*args[curarg]);
+ ZVAL_STRING(*args[curarg], string, 1);
+ ber_memfree(string);
+ curarg++;
+ }
+ break;
+ case 'O' :
+ rc = ber_scanf(ber, "O", &bv_ptr);
+ if (rc != LBER_ERROR) {
+ zval_dtor(*args[curarg]);
+ ZVAL_STRINGL(*args[curarg], bv_ptr-> bv_val,
+ bv_ptr-> bv_len, 1);
+ ber_bvfree(bv_ptr);
+ curarg++;
+ }
+ break;
+ case 'b' :
+ rc = ber_scanf(ber, "b", &int_val);
+ if (rc != LBER_ERROR) {
+ zval_dtor(*args[curarg]);
+ ZVAL_BOOL(*args[curarg], int_val);
+ curarg++;
+ }
+ break;
+ case 'e' :
+ case 'i' :
+ snprintf (fmt_buf, sizeof(fmt_buf), "%c", format[pos]);
+ rc = ber_scanf(ber, fmt_buf, &int_val);
+ if (rc != LBER_ERROR) {
+ zval_dtor(*args[curarg]);
+ ZVAL_LONG(*args[curarg], int_val);
+ curarg++;
+ }
+ break;
+ case 'B' :
+ rc = ber_scanf(ber, "B", &string, &ber_len);
+ if (rc != LBER_ERROR) {
+ /* ber_len is in bits, _not_ in bytes, so beware!
+ */
+ zval_dtor(*args[curarg]);
+ ZVAL_STRINGL(*args[curarg], string, (ber_len+7)/8, 1);
+ ber_memfree(string);
+ curarg++;
+ }
+ break;
+ case 't' :
+ rc = ber_scanf(ber, "t", &tag);
+ if (rc != LBER_ERROR) {
+ zval_dtor(*args[curarg]);
+ ZVAL_LONG(*args[curarg], tag);
+ curarg++;
+ }
+ break;
+ case 'x' :
+ rc = ber_scanf(ber, "x");
+ break;
+ case 'v' :
+ case 'V' :
+ err_msg = "Unsupported format specifier by now: '%c'";
+ goto ber_scanf_errexit;
+ break;
+ case 'l' :
+ case 's' : /* This is an OpenLDAP extension only
+ * not present on draft-ietf-ldapext-ldap-c-api-*.txt
+ */
+ default:
+ err_msg = "Unkown format specifier: '%c'";
+ goto ber_scanf_errexit;
+ }
+ }
+ }
+ if (rc == LBER_ERROR) {
+ err_msg = "Unable to process some values. Check you format string and values";
+ goto ber_scanf_errexit;
+ }
+ pos++;
+ }
+ RETURN_LONG(curarg - 2);
+
+ber_scanf_errexit:
+ ber_free(ber,0);
+ efree(args);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, err_msg, format[pos] );
+ RETURN_LONG(0);
+}
+/* }}} */
+
+
/* {{{ proto resource ldap_first_reference(resource link, resource result)
Return first reference */
PHP_FUNCTION(ldap_first_reference)
Index: ext/ldap/php_ldap.h
===================================================================
RCS file: /repository/php-src/ext/ldap/php_ldap.h,v
retrieving revision 1.25.8.2
diff -u -r1.25.8.2 php_ldap.h
--- ext/ldap/php_ldap.h 8 May 2005 16:06:25 -0000 1.25.8.2
+++ ext/ldap/php_ldap.h 9 Apr 2006 20:46:51 -0000
@@ -53,6 +53,8 @@
PHP_FUNCTION(ldap_get_values);
PHP_FUNCTION(ldap_get_values_len);
PHP_FUNCTION(ber_free);
+PHP_FUNCTION(ldap_ber_printf);
+PHP_FUNCTION(ldap_ber_scanf);
PHP_FUNCTION(ldap_get_dn);
PHP_FUNCTION(ldap_explode_dn);
PHP_FUNCTION(ldap_dn2ufn);
Index: ext/ldap/ldap.c
===================================================================
RCS file: /repository/php-src/ext/ldap/ldap.c,v
retrieving revision 1.130.2.13.2.1
diff -u -r1.130.2.13.2.1 ldap.c
--- ext/ldap/ldap.c 1 Jan 2006 13:46:54 -0000 1.130.2.13.2.1
+++ ext/ldap/ldap.c 9 Apr 2006 20:45:37 -0000
@@ -74,7 +74,7 @@
ZEND_DECLARE_MODULE_GLOBALS(ldap)
static unsigned char third_argument_force_ref[] = { 3, BYREF_NONE, BYREF_NONE, BYREF_FORCE
};
-static unsigned char arg3to6of6_force_ref[] = { 6, BYREF_NONE, BYREF_NONE, BYREF_FORCE, BYR
EF_FORCE, BYREF_FORCE, BYREF_FORCE };
+static unsigned char arg3to7of7_force_ref[] = { 7, BYREF_NONE, BYREF_NONE, BYREF_FORCE, BYR
EF_FORCE, BYREF_FORCE, BYREF_FORCE, BYREF_FORCE };
static int le_link, le_result, le_result_entry, le_ber_entry;
@@ -131,8 +131,10 @@
PHP_FE(ldap_parse_reference, third_argument_force_ref)
#endif
#ifdef HAVE_LDAP_PARSE_RESULT
- PHP_FE(ldap_parse_result, arg3to6of6_force_ref)
+ PHP_FE(ldap_parse_result, arg3to7of7_force_ref)
#endif
+ PHP_FE(ldap_ber_printf, NULL)
+ PHP_FE(ldap_ber_scanf, NULL)
#ifdef HAVE_LDAP_START_TLS_S
PHP_FE(ldap_start_tls, NULL)
#endif
@@ -1759,18 +1761,19 @@
/* }}} */
#ifdef HAVE_LDAP_PARSE_RESULT
-/* {{{ proto bool ldap_parse_result(resource link, resource result, int errcode, string mat
cheddn, string errmsg, array referrals)
+/* {{{ proto bool ldap_parse_result(resource link, resource result, int errcode, string mat
cheddn, string errmsg, array referrals, array serverctrls)
Extract information from result */
PHP_FUNCTION(ldap_parse_result)
{
- zval **link, **result, **errcode, **matcheddn, **errmsg, **referrals;
+ zval **link, **result, **errcode, **matcheddn, **errmsg, **referrals, **serverctrls;
ldap_linkdata *ld;
LDAPMessage *ldap_result;
+ LDAPControl **lserverctrls, **ctrlp, *ctrl;
char **lreferrals, **refp;
char *lmatcheddn, *lerrmsg;
int rc, lerrcode, myargcount = ZEND_NUM_ARGS();
- if (myargcount < 3 || myargcount > 6 || zend_get_parameters_ex(myargcount, &link, &result,
&errcode, &matcheddn, &errmsg, &referrals) == FAILURE) {
+ if (myargcount < 3 || myargcount > 7 || zend_get_parameters_ex(myargcount, &link, &result,
&errcode, &matcheddn, &errmsg, &referrals, &serverctrls) == FAILURE) {
WRONG_PARAM_COUNT;
}
@@ -1781,7 +1784,7 @@
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));
@@ -1793,6 +1796,29 @@
/* Reverse -> fall through */
switch (myargcount) {
+ case 7 :
+ zval_dtor(*serverctrls);
+
+ if (lserverctrls != NULL) {
+ array_init(*serverctrls);
+ ctrlp = lserverctrls;
+
+ while (*ctrlp != NULL) {
+ zval *ctrl_array;
+
+ ctrl = *ctrlp;
+ MAKE_STD_ZVAL(ctrl_array);
+ array_init(ctrl_array);
+
+ add_assoc_string(ctrl_array, "oid", ctrl-> ldctl_oid,1);
+ add_assoc_bool(ctrl_array, "iscritical", ctrl-> ldctl_iscritical);
+ add_assoc_stringl(ctrl_array, "value", ctrl-> ldctl_value.bv_val,
+ ctrl-> ldctl_value.bv_len,1);
+ add_next_index_zval (*serverctrls, ctrl_array);
+ ctrlp++;
+ }
+ ldap_controls_free (lserverctrls);
+ }
case 6:
zval_dtor(*referrals);
array_init(*referrals);
@@ -1826,6 +1852,303 @@
/* }}} */
#endif
+/* {{{ proto string ldap_ber_printf(string format [, mixed arg1 [, mixed ...]])
+ Creates a BER encoded string of the values/types specified in the format string. Return
s the BER encoded string, or 'false' if the enconding failed */
+PHP_FUNCTION(ldap_ber_printf)
+{
+ zval ***args;
+ int argc, curarg, rc;
+ char *format;
+ char fmt_buf[5], *err_msg;
+ unsigned int format_length, pos;
+ BerElement *ber;
+ struct berval bv_str, *bv_retval;
+
+ argc = ZEND_NUM_ARGS();
+
+ if (argc < 1) {
+ WRONG_PARAM_COUNT;
+ }
+
+ args = (zval ***)safe_emalloc(argc, sizeof(zval *), 0);
+
+ if (zend_get_parameters_array_ex(argc, args) == FAILURE) {
+ efree(args);
+ WRONG_PARAM_COUNT;
+ }
+
+ convert_to_string_ex(args[0]);
+ format = Z_STRVAL_PP(args[0]);
+ format_length = Z_STRLEN_PP(args[0]);
+
+ ber = ber_alloc_t(LBER_USE_DER);
+ if (ber == NULL) {
+ efree(args);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to allocate enough memory");
+ RETURN_FALSE;
+ }
+
+ err_msg = NULL;
+ pos = 0;
+ curarg = 1;
+ while (pos < format_length) {
+ switch(format[pos]) {
+ case '{' :
+ case '}' :
+ case '[' :
+ case ']' :
+ case 'n' :
+ snprintf (fmt_buf, sizeof(fmt_buf), "%c", format[pos]);
+ rc = ber_printf(ber, fmt_buf);
+ break;
+ default:
+ if (curarg > = argc) {
+ err_msg = "Too few arguments";
+ goto ber_printf_errexit;
+ }
+ else {
+ switch(format[pos]) {
+ case 'b' :
+ convert_to_boolean_ex(args[curarg]);
+ rc = ber_printf(ber, "b", Z_LVAL_PP(args[curarg]));
+ curarg++;
+ break;
+ case 'e' :
+ case 'i' :
+ case 't' :
+ snprintf (fmt_buf, sizeof(fmt_buf), "%c", format[pos]);
+ convert_to_long_ex(args[curarg]);
+ rc = ber_printf(ber, fmt_buf, Z_LVAL_PP(args[curarg]));
+ curarg++;
+ break;
+ case 'B' :
+ convert_to_string_ex(args[curarg]);
+ rc = ber_printf(ber, "B", Z_STRVAL_PP(args[curarg]),
+ 8 * Z_STRLEN_PP(args[curarg]));
+ curarg++;
+ break;
+ case 's' :
+ convert_to_string_ex(args[curarg]);
+ rc = ber_printf(ber, "s", Z_STRVAL_PP(args[curarg]));
+ curarg++;
+ break;
+ case 'o' :
+ convert_to_string_ex(args[curarg]);
+ rc = ber_printf(ber, "o", Z_STRVAL_PP(args[curarg]),
+ Z_STRLEN_PP(args[curarg]));
+ curarg++;
+ break;
+ case 'O' :
+ convert_to_string_ex(args[curarg]);
+ bv_str.bv_val = Z_STRVAL_PP(args[curarg]);
+ bv_str.bv_len = Z_STRLEN_PP(args[curarg]);
+ rc = ber_printf(ber, "O", &bv_str);
+ curarg++;
+ break;
+ case 'v' :
+ case 'V' :
+ err_msg = "Unsupported format specifier by now: '%c'";
+ goto ber_printf_errexit;
+ break;
+ case 'W' : /* This is an OpenLDAP extension only
+ * not present on draft-ietf-ldapext-ldap-c-api-*.txt
+ */
+ default:
+ err_msg = "Unkown format specifier: '%c'";
+ goto ber_printf_errexit;
+ } /* switch */
+ } /* else */
+ } /* switch */
+ if (rc == -1) {
+ err_msg = "Unable to process some values. Check you format string and values";
+ goto ber_printf_errexit;
+ }
+ pos++;
+ }
+
+ if (ber_flatten (ber, &bv_retval) == -1) {
+ goto ber_printf_errexit;
+ }
+
+ RETVAL_STRINGL(bv_retval-> bv_val, bv_retval->bv_len, 1);
+ ber_bvfree(bv_retval);
+ ber_free(ber,0);
+ efree(args);
+ return;
+
+ber_printf_errexit:
+ ber_free(ber,0);
+ efree(args);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, err_msg, format[pos] );
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto int ldap_ber_scanf(string berval, string format [, mixed arg1 [, mixed ...]])
+ The complimentary function to ber_printf */
+PHP_FUNCTION(ldap_ber_scanf)
+{
+ zval ***args;
+ int argc, i, curarg, int_val;
+ char *format, *err_msg, *string;
+ char fmt_buf[5];
+ unsigned int format_length, pos;
+ BerElement *ber;
+ ber_tag_t rc, tag;
+ ber_len_t ber_len;
+ struct berval bv_str, *bv_ptr;
+
+
+ argc = ZEND_NUM_ARGS();
+ if (argc < 2) {
+ WRONG_PARAM_COUNT;
+ }
+
+ args = (zval ***) safe_emalloc(sizeof(zval **), argc, 0);
+ if (zend_get_parameters_array_ex(argc, args) == FAILURE) {
+ efree(args);
+ WRONG_PARAM_COUNT;
+ }
+
+ /* If any variables are passed, make sure they are all passed by reference */
+ if ((argc - 2) > 0) {
+ for (i = 2; i < argc; i++){
+ if ( ! PZVAL_IS_REF(*args[i])) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING,
+ "Parameter %d must be passed by reference", i);
+ RETURN_LONG(0);
+ }
+ }
+ }
+
+ err_msg = NULL;
+
+ convert_to_string_ex(args[0]);
+ convert_to_string_ex(args[1]);
+
+ bv_str.bv_val = Z_STRVAL_PP(args[0]);
+ bv_str.bv_len = Z_STRLEN_PP(args[0]);
+ ber = ber_init(&bv_str);
+ if (ber == NULL) {
+ efree(args);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING,
+ "Unable to allocate enough memory or invalid BER data");
+ RETURN_LONG(0);
+ }
+
+ format=Z_STRVAL_PP(args[1]);
+ format_length=Z_STRLEN_PP(args[1]);
+
+ pos = 0;
+ curarg = 2;
+ while (pos < format_length) {
+ switch(format[pos]) {
+ case '{' :
+ case '}' :
+ case '[' :
+ case ']' :
+ case 'n' :
+ snprintf (fmt_buf, sizeof(fmt_buf), "%c", format[pos]);
+ rc = ber_scanf(ber, fmt_buf);
+ break;
+ default:
+ if (curarg > = argc) {
+ err_msg = "Too few arguments";
+ goto ber_scanf_errexit;
+ }
+ else {
+ switch(format[pos]) {
+ case 'a' :
+ rc = ber_scanf(ber, "a", &string);
+ if (rc != LBER_ERROR) {
+ zval_dtor(*args[curarg]);
+ ZVAL_STRING(*args[curarg], string, 1);
+ ber_memfree(string);
+ curarg++;
+ }
+ break;
+ case 'O' :
+ rc = ber_scanf(ber, "O", &bv_ptr);
+ if (rc != LBER_ERROR) {
+ zval_dtor(*args[curarg]);
+ ZVAL_STRINGL(*args[curarg], bv_ptr-> bv_val,
+ bv_ptr-> bv_len, 1);
+ ber_bvfree(bv_ptr);
+ curarg++;
+ }
+ break;
+ case 'b' :
+ rc = ber_scanf(ber, "b", &int_val);
+ if (rc != LBER_ERROR) {
+ zval_dtor(*args[curarg]);
+ ZVAL_BOOL(*args[curarg], int_val);
+ curarg++;
+ }
+ break;
+ case 'e' :
+ case 'i' :
+ snprintf (fmt_buf, sizeof(fmt_buf), "%c", format[pos]);
+ rc = ber_scanf(ber, fmt_buf, &int_val);
+ if (rc != LBER_ERROR) {
+ zval_dtor(*args[curarg]);
+ ZVAL_LONG(*args[curarg], int_val);
+ curarg++;
+ }
+ break;
+ case 'B' :
+ rc = ber_scanf(ber, "B", &string, &ber_len);
+ if (rc != LBER_ERROR) {
+ /* ber_len is in bits, _not_ in bytes, so beware!
+ */
+ zval_dtor(*args[curarg]);
+ ZVAL_STRINGL(*args[curarg], string, (ber_len+7)/8, 1);
+ ber_memfree(string);
+ curarg++;
+ }
+ break;
+ case 't' :
+ rc = ber_scanf(ber, "t", &tag);
+ if (rc != LBER_ERROR) {
+ zval_dtor(*args[curarg]);
+ ZVAL_LONG(*args[curarg], tag);
+ curarg++;
+ }
+ break;
+ case 'x' :
+ rc = ber_scanf(ber, "x");
+ break;
+ case 'v' :
+ case 'V' :
+ err_msg = "Unsupported format specifier by now: '%c'";
+ goto ber_scanf_errexit;
+ break;
+ case 'l' :
+ case 's' : /* This is an OpenLDAP extension only
+ * not present on draft-ietf-ldapext-ldap-c-api-*.txt
+ */
+ default:
+ err_msg = "Unkown format specifier: '%c'";
+ goto ber_scanf_errexit;
+ }
+ }
+ }
+ if (rc == LBER_ERROR) {
+ err_msg = "Unable to process some values. Check you format string and values";
+ goto ber_scanf_errexit;
+ }
+ pos++;
+ }
+ RETURN_LONG(curarg - 2);
+
+ber_scanf_errexit:
+ ber_free(ber,0);
+ efree(args);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, err_msg, format[pos] );
+ RETURN_LONG(0);
+}
+/* }}} */
+
+
/* {{{ proto resource ldap_first_reference(resource link, resource result)
Return first reference */
PHP_FUNCTION(ldap_first_reference)
Index: ext/ldap/php_ldap.h
===================================================================
RCS file: /repository/php-src/ext/ldap/php_ldap.h,v
retrieving revision 1.25.8.2.2.1
diff -u -r1.25.8.2.2.1 php_ldap.h
--- ext/ldap/php_ldap.h 1 Jan 2006 13:46:54 -0000 1.25.8.2.2.1
+++ ext/ldap/php_ldap.h 9 Apr 2006 20:45:37 -0000
@@ -53,6 +53,8 @@
PHP_FUNCTION(ldap_get_values);
PHP_FUNCTION(ldap_get_values_len);
PHP_FUNCTION(ber_free);
+PHP_FUNCTION(ldap_ber_printf);
+PHP_FUNCTION(ldap_ber_scanf);
PHP_FUNCTION(ldap_get_dn);
PHP_FUNCTION(ldap_explode_dn);
PHP_FUNCTION(ldap_dn2ufn);
Index: ext/ldap/ldap.c
===================================================================
RCS file: /repository/php-src/ext/ldap/ldap.c,v
retrieving revision 1.154.2.7
diff -u -r1.154.2.7 ldap.c
--- ext/ldap/ldap.c 9 Jul 2005 01:00:11 -0000 1.154.2.7
+++ ext/ldap/ldap.c 9 Apr 2006 20:43:52 -0000
@@ -80,7 +80,7 @@
ZEND_DECLARE_MODULE_GLOBALS(ldap)
static
- ZEND_BEGIN_ARG_INFO(arg3to6of6_force_ref, 0)
+ ZEND_BEGIN_ARG_INFO(arg3to7of7_force_ref, 0)
ZEND_ARG_PASS_INFO(0)
ZEND_ARG_PASS_INFO(0)
ZEND_ARG_PASS_INFO(1)
@@ -147,8 +147,10 @@
PHP_FE(ldap_parse_reference, third_arg_force_ref)
#endif
#ifdef HAVE_LDAP_PARSE_RESULT
- PHP_FE(ldap_parse_result, arg3to6of6_force_ref)
+ PHP_FE(ldap_parse_result, arg3to7of7_force_ref)
#endif
+ PHP_FE(ldap_ber_printf, NULL)
+ PHP_FE(ldap_ber_scanf, NULL)
#ifdef HAVE_LDAP_START_TLS_S
PHP_FE(ldap_start_tls, NULL)
#endif
@@ -1929,18 +1931,19 @@
/* }}} */
#ifdef HAVE_LDAP_PARSE_RESULT
-/* {{{ proto bool ldap_parse_result(resource link, resource result, int errcode, string mat
cheddn, string errmsg, array referrals)
+/* {{{ proto bool ldap_parse_result(resource link, resource result, int errcode, string mat
cheddn, string errmsg, array referrals, array serverctrls)
Extract information from result */
PHP_FUNCTION(ldap_parse_result)
{
- zval **link, **result, **errcode, **matcheddn, **errmsg, **referrals;
+ zval **link, **result, **errcode, **matcheddn, **errmsg, **referrals, **serverctrls;
ldap_linkdata *ld;
LDAPMessage *ldap_result;
+ LDAPControl **lserverctrls, **ctrlp, *ctrl;
char **lreferrals, **refp;
char *lmatcheddn, *lerrmsg;
int rc, lerrcode, myargcount = ZEND_NUM_ARGS();
- if (myargcount < 3 || myargcount > 6 || zend_get_parameters_ex(myargcount, &link, &result,
&errcode, &matcheddn, &errmsg, &referrals) == FAILURE) {
+ if (myargcount < 3 || myargcount > 7 || zend_get_parameters_ex(myargcount, &link, &result,
&errcode, &matcheddn, &errmsg, &referrals, &serverctrls) == FAILURE) {
WRONG_PARAM_COUNT;
}
@@ -1951,7 +1954,7 @@
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));
@@ -1963,6 +1966,29 @@
/* Reverse -> fall through */
switch (myargcount) {
+ case 7 :
+ zval_dtor(*serverctrls);
+
+ if (lserverctrls != NULL) {
+ array_init(*serverctrls);
+ ctrlp = lserverctrls;
+
+ while (*ctrlp != NULL) {
+ zval *ctrl_array;
+
+ ctrl = *ctrlp;
+ MAKE_STD_ZVAL(ctrl_array);
+ array_init(ctrl_array);
+
+ add_assoc_string(ctrl_array, "oid", ctrl-> ldctl_oid,1);
+ add_assoc_bool(ctrl_array, "iscritical", ctrl-> ldctl_iscritical);
+ add_assoc_stringl(ctrl_array, "value", ctrl-> ldctl_value.bv_val,
+ ctrl-> ldctl_value.bv_len,1);
+ add_next_index_zval (*serverctrls, ctrl_array);
+ ctrlp++;
+ }
+ ldap_controls_free (lserverctrls);
+ }
case 6:
zval_dtor(*referrals);
array_init(*referrals);
@@ -1996,6 +2022,303 @@
/* }}} */
#endif
+/* {{{ proto string ldap_ber_printf(string format [, mixed arg1 [, mixed ...]])
+ Creates a BER encoded string of the values/types specified in the format string. Return
s the BER encoded string, or 'false' if the enconding failed */
+PHP_FUNCTION(ldap_ber_printf)
+{
+ zval ***args;
+ int argc, curarg, rc;
+ char *format;
+ char fmt_buf[5], *err_msg;
+ unsigned int format_length, pos;
+ BerElement *ber;
+ struct berval bv_str, *bv_retval;
+
+ argc = ZEND_NUM_ARGS();
+
+ if (argc < 1) {
+ WRONG_PARAM_COUNT;
+ }
+
+ args = (zval ***)safe_emalloc(argc, sizeof(zval *), 0);
+
+ if (zend_get_parameters_array_ex(argc, args) == FAILURE) {
+ efree(args);
+ WRONG_PARAM_COUNT;
+ }
+
+ convert_to_string_ex(args[0]);
+ format = Z_STRVAL_PP(args[0]);
+ format_length = Z_STRLEN_PP(args[0]);
+
+ ber = ber_alloc_t(LBER_USE_DER);
+ if (ber == NULL) {
+ efree(args);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to allocate enough memory");
+ RETURN_FALSE;
+ }
+
+ err_msg = NULL;
+ pos = 0;
+ curarg = 1;
+ while (pos < format_length) {
+ switch(format[pos]) {
+ case '{' :
+ case '}' :
+ case '[' :
+ case ']' :
+ case 'n' :
+ snprintf (fmt_buf, sizeof(fmt_buf), "%c", format[pos]);
+ rc = ber_printf(ber, fmt_buf);
+ break;
+ default:
+ if (curarg > = argc) {
+ err_msg = "Too few arguments";
+ goto ber_printf_errexit;
+ }
+ else {
+ switch(format[pos]) {
+ case 'b' :
+ convert_to_boolean_ex(args[curarg]);
+ rc = ber_printf(ber, "b", Z_LVAL_PP(args[curarg]));
+ curarg++;
+ break;
+ case 'e' :
+ case 'i' :
+ case 't' :
+ snprintf (fmt_buf, sizeof(fmt_buf), "%c", format[pos]);
+ convert_to_long_ex(args[curarg]);
+ rc = ber_printf(ber, fmt_buf, Z_LVAL_PP(args[curarg]));
+ curarg++;
+ break;
+ case 'B' :
+ convert_to_string_ex(args[curarg]);
+ rc = ber_printf(ber, "B", Z_STRVAL_PP(args[curarg]),
+ 8 * Z_STRLEN_PP(args[curarg]));
+ curarg++;
+ break;
+ case 's' :
+ convert_to_string_ex(args[curarg]);
+ rc = ber_printf(ber, "s", Z_STRVAL_PP(args[curarg]));
+ curarg++;
+ break;
+ case 'o' :
+ convert_to_string_ex(args[curarg]);
+ rc = ber_printf(ber, "o", Z_STRVAL_PP(args[curarg]),
+ Z_STRLEN_PP(args[curarg]));
+ curarg++;
+ break;
+ case 'O' :
+ convert_to_string_ex(args[curarg]);
+ bv_str.bv_val = Z_STRVAL_PP(args[curarg]);
+ bv_str.bv_len = Z_STRLEN_PP(args[curarg]);
+ rc = ber_printf(ber, "O", &bv_str);
+ curarg++;
+ break;
+ case 'v' :
+ case 'V' :
+ err_msg = "Unsupported format specifier by now: '%c'";
+ goto ber_printf_errexit;
+ break;
+ case 'W' : /* This is an OpenLDAP extension only
+ * not present on draft-ietf-ldapext-ldap-c-api-*.txt
+ */
+ default:
+ err_msg = "Unkown format specifier: '%c'";
+ goto ber_printf_errexit;
+ } /* switch */
+ } /* else */
+ } /* switch */
+ if (rc == -1) {
+ err_msg = "Unable to process some values. Check you format string and values";
+ goto ber_printf_errexit;
+ }
+ pos++;
+ }
+
+ if (ber_flatten (ber, &bv_retval) == -1) {
+ goto ber_printf_errexit;
+ }
+
+ RETVAL_STRINGL(bv_retval-> bv_val, bv_retval->bv_len, 1);
+ ber_bvfree(bv_retval);
+ ber_free(ber,0);
+ efree(args);
+ return;
+
+ber_printf_errexit:
+ ber_free(ber,0);
+ efree(args);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, err_msg, format[pos] );
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto int ldap_ber_scanf(string berval, string format [, mixed arg1 [, mixed ...]])
+ The complimentary function to ber_printf */
+PHP_FUNCTION(ldap_ber_scanf)
+{
+ zval ***args;
+ int argc, i, curarg, int_val;
+ char *format, *err_msg, *string;
+ char fmt_buf[5];
+ unsigned int format_length, pos;
+ BerElement *ber;
+ ber_tag_t rc, tag;
+ ber_len_t ber_len;
+ struct berval bv_str, *bv_ptr;
+
+
+ argc = ZEND_NUM_ARGS();
+ if (argc < 2) {
+ WRONG_PARAM_COUNT;
+ }
+
+ args = (zval ***) safe_emalloc(sizeof(zval **), argc, 0);
+ if (zend_get_parameters_array_ex(argc, args) == FAILURE) {
+ efree(args);
+ WRONG_PARAM_COUNT;
+ }
+
+ /* If any variables are passed, make sure they are all passed by reference */
+ if ((argc - 2) > 0) {
+ for (i = 2; i < argc; i++){
+ if ( ! PZVAL_IS_REF(*args[i])) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING,
+ "Parameter %d must be passed by reference", i);
+ RETURN_LONG(0);
+ }
+ }
+ }
+
+ err_msg = NULL;
+
+ convert_to_string_ex(args[0]);
+ convert_to_string_ex(args[1]);
+
+ bv_str.bv_val = Z_STRVAL_PP(args[0]);
+ bv_str.bv_len = Z_STRLEN_PP(args[0]);
+ ber = ber_init(&bv_str);
+ if (ber == NULL) {
+ efree(args);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING,
+ "Unable to allocate enough memory or invalid BER data");
+ RETURN_LONG(0);
+ }
+
+ format=Z_STRVAL_PP(args[1]);
+ format_length=Z_STRLEN_PP(args[1]);
+
+ pos = 0;
+ curarg = 2;
+ while (pos < format_length) {
+ switch(format[pos]) {
+ case '{' :
+ case '}' :
+ case '[' :
+ case ']' :
+ case 'n' :
+ snprintf (fmt_buf, sizeof(fmt_buf), "%c", format[pos]);
+ rc = ber_scanf(ber, fmt_buf);
+ break;
+ default:
+ if (curarg > = argc) {
+ err_msg = "Too few arguments";
+ goto ber_scanf_errexit;
+ }
+ else {
+ switch(format[pos]) {
+ case 'a' :
+ rc = ber_scanf(ber, "a", &string);
+ if (rc != LBER_ERROR) {
+ zval_dtor(*args[curarg]);
+ ZVAL_STRING(*args[curarg], string, 1);
+ ber_memfree(string);
+ curarg++;
+ }
+ break;
+ case 'O' :
+ rc = ber_scanf(ber, "O", &bv_ptr);
+ if (rc != LBER_ERROR) {
+ zval_dtor(*args[curarg]);
+ ZVAL_STRINGL(*args[curarg], bv_ptr-> bv_val,
+ bv_ptr-> bv_len, 1);
+ ber_bvfree(bv_ptr);
+ curarg++;
+ }
+ break;
+ case 'b' :
+ rc = ber_scanf(ber, "b", &int_val);
+ if (rc != LBER_ERROR) {
+ zval_dtor(*args[curarg]);
+ ZVAL_BOOL(*args[curarg], int_val);
+ curarg++;
+ }
+ break;
+ case 'e' :
+ case 'i' :
+ snprintf (fmt_buf, sizeof(fmt_buf), "%c", format[pos]);
+ rc = ber_scanf(ber, fmt_buf, &int_val);
+ if (rc != LBER_ERROR) {
+ zval_dtor(*args[curarg]);
+ ZVAL_LONG(*args[curarg], int_val);
+ curarg++;
+ }
+ break;
+ case 'B' :
+ rc = ber_scanf(ber, "B", &string, &ber_len);
+ if (rc != LBER_ERROR) {
+ /* ber_len is in bits, _not_ in bytes, so beware!
+ */
+ zval_dtor(*args[curarg]);
+ ZVAL_STRINGL(*args[curarg], string, (ber_len+7)/8, 1);
+ ber_memfree(string);
+ curarg++;
+ }
+ break;
+ case 't' :
+ rc = ber_scanf(ber, "t", &tag);
+ if (rc != LBER_ERROR) {
+ zval_dtor(*args[curarg]);
+ ZVAL_LONG(*args[curarg], tag);
+ curarg++;
+ }
+ break;
+ case 'x' :
+ rc = ber_scanf(ber, "x");
+ break;
+ case 'v' :
+ case 'V' :
+ err_msg = "Unsupported format specifier by now: '%c'";
+ goto ber_scanf_errexit;
+ break;
+ case 'l' :
+ case 's' : /* This is an OpenLDAP extension only
+ * not present on draft-ietf-ldapext-ldap-c-api-*.txt
+ */
+ default:
+ err_msg = "Unkown format specifier: '%c'";
+ goto ber_scanf_errexit;
+ }
+ }
+ }
+ if (rc == LBER_ERROR) {
+ err_msg = "Unable to process some values. Check you format string and values";
+ goto ber_scanf_errexit;
+ }
+ pos++;
+ }
+ RETURN_LONG(curarg - 2);
+
+ber_scanf_errexit:
+ ber_free(ber,0);
+ efree(args);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, err_msg, format[pos] );
+ RETURN_LONG(0);
+}
+/* }}} */
+
+
/* {{{ proto resource ldap_first_reference(resource link, resource result)
Return first reference */
PHP_FUNCTION(ldap_first_reference)
Index: ext/ldap/php_ldap.h
===================================================================
RCS file: /repository/php-src/ext/ldap/php_ldap.h,v
retrieving revision 1.30.2.1
diff -u -r1.30.2.1 php_ldap.h
--- ext/ldap/php_ldap.h 8 May 2005 15:44:15 -0000 1.30.2.1
+++ ext/ldap/php_ldap.h 9 Apr 2006 20:43:53 -0000
@@ -56,6 +56,8 @@
PHP_FUNCTION(ldap_get_values);
PHP_FUNCTION(ldap_get_values_len);
PHP_FUNCTION(ber_free);
+PHP_FUNCTION(ldap_ber_printf);
+PHP_FUNCTION(ldap_ber_scanf);
PHP_FUNCTION(ldap_get_dn);
PHP_FUNCTION(ldap_explode_dn);
PHP_FUNCTION(ldap_dn2ufn);
Index: ext/ldap/ldap.c
===================================================================
RCS file: /repository/php-src/ext/ldap/ldap.c,v
retrieving revision 1.161.2.3
diff -u -r1.161.2.3 ldap.c
--- ext/ldap/ldap.c 1 Jan 2006 12:50:08 -0000 1.161.2.3
+++ ext/ldap/ldap.c 9 Apr 2006 20:40:07 -0000
@@ -80,7 +80,7 @@
ZEND_DECLARE_MODULE_GLOBALS(ldap)
static
- ZEND_BEGIN_ARG_INFO(arg3to6of6_force_ref, 0)
+ ZEND_BEGIN_ARG_INFO(arg3to7of7_force_ref, 0)
ZEND_ARG_PASS_INFO(0)
ZEND_ARG_PASS_INFO(0)
ZEND_ARG_PASS_INFO(1)
@@ -147,8 +147,10 @@
PHP_FE(ldap_parse_reference, third_arg_force_ref)
#endif
#ifdef HAVE_LDAP_PARSE_RESULT
- PHP_FE(ldap_parse_result, arg3to6of6_force_ref)
+ PHP_FE(ldap_parse_result, arg3to7of7_force_ref)
#endif
+ PHP_FE(ldap_ber_printf, NULL)
+ PHP_FE(ldap_ber_scanf, NULL)
#ifdef HAVE_LDAP_START_TLS_S
PHP_FE(ldap_start_tls, NULL)
#endif
@@ -1932,18 +1934,19 @@
/* }}} */
#ifdef HAVE_LDAP_PARSE_RESULT
-/* {{{ proto bool ldap_parse_result(resource link, resource result, int errcode, string mat
cheddn, string errmsg, array referrals)
+/* {{{ proto bool ldap_parse_result(resource link, resource result, int errcode, string mat
cheddn, string errmsg, array referrals, array serverctrls)
Extract information from result */
PHP_FUNCTION(ldap_parse_result)
{
- zval **link, **result, **errcode, **matcheddn, **errmsg, **referrals;
+ zval **link, **result, **errcode, **matcheddn, **errmsg, **referrals, **serverctrls;
ldap_linkdata *ld;
LDAPMessage *ldap_result;
+ LDAPControl **lserverctrls, **ctrlp, *ctrl;
char **lreferrals, **refp;
char *lmatcheddn, *lerrmsg;
int rc, lerrcode, myargcount = ZEND_NUM_ARGS();
- if (myargcount < 3 || myargcount > 6 || zend_get_parameters_ex(myargcount, &link, &result,
&errcode, &matcheddn, &errmsg, &referrals) == FAILURE) {
+ if (myargcount < 3 || myargcount > 7 || zend_get_parameters_ex(myargcount, &link, &result,
&errcode, &matcheddn, &errmsg, &referrals, &serverctrls) == FAILURE) {
WRONG_PARAM_COUNT;
}
@@ -1954,7 +1957,7 @@
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));
@@ -1966,6 +1969,29 @@
/* Reverse -> fall through */
switch (myargcount) {
+ case 7 :
+ zval_dtor(*serverctrls);
+
+ if (lserverctrls != NULL) {
+ array_init(*serverctrls);
+ ctrlp = lserverctrls;
+
+ while (*ctrlp != NULL) {
+ zval *ctrl_array;
+
+ ctrl = *ctrlp;
+ MAKE_STD_ZVAL(ctrl_array);
+ array_init(ctrl_array);
+
+ add_assoc_string(ctrl_array, "oid", ctrl-> ldctl_oid,1);
+ add_assoc_bool(ctrl_array, "iscritical", ctrl-> ldctl_iscritical);
+ add_assoc_stringl(ctrl_array, "value", ctrl-> ldctl_value.bv_val,
+ ctrl-> ldctl_value.bv_len,1);
+ add_next_index_zval (*serverctrls, ctrl_array);
+ ctrlp++;
+ }
+ ldap_controls_free (lserverctrls);
+ }
case 6:
zval_dtor(*referrals);
array_init(*referrals);
@@ -1999,6 +2025,303 @@
/* }}} */
#endif
+/* {{{ proto string ldap_ber_printf(string format [, mixed arg1 [, mixed ...]])
+ Creates a BER encoded string of the values/types specified in the format string. Return
s the BER encoded string, or 'false' if the enconding failed */
+PHP_FUNCTION(ldap_ber_printf)
+{
+ zval ***args;
+ int argc, curarg, rc;
+ char *format;
+ char fmt_buf[5], *err_msg;
+ unsigned int format_length, pos;
+ BerElement *ber;
+ struct berval bv_str, *bv_retval;
+
+ argc = ZEND_NUM_ARGS();
+
+ if (argc < 1) {
+ WRONG_PARAM_COUNT;
+ }
+
+ args = (zval ***)safe_emalloc(argc, sizeof(zval *), 0);
+
+ if (zend_get_parameters_array_ex(argc, args) == FAILURE) {
+ efree(args);
+ WRONG_PARAM_COUNT;
+ }
+
+ convert_to_string_ex(args[0]);
+ format = Z_STRVAL_PP(args[0]);
+ format_length = Z_STRLEN_PP(args[0]);
+
+ ber = ber_alloc_t(LBER_USE_DER);
+ if (ber == NULL) {
+ efree(args);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to allocate enough memory");
+ RETURN_FALSE;
+ }
+
+ err_msg = NULL;
+ pos = 0;
+ curarg = 1;
+ while (pos < format_length) {
+ switch(format[pos]) {
+ case '{' :
+ case '}' :
+ case '[' :
+ case ']' :
+ case 'n' :
+ snprintf (fmt_buf, sizeof(fmt_buf), "%c", format[pos]);
+ rc = ber_printf(ber, fmt_buf);
+ break;
+ default:
+ if (curarg > = argc) {
+ err_msg = "Too few arguments";
+ goto ber_printf_errexit;
+ }
+ else {
+ switch(format[pos]) {
+ case 'b' :
+ convert_to_boolean_ex(args[curarg]);
+ rc = ber_printf(ber, "b", Z_LVAL_PP(args[curarg]));
+ curarg++;
+ break;
+ case 'e' :
+ case 'i' :
+ case 't' :
+ snprintf (fmt_buf, sizeof(fmt_buf), "%c", format[pos]);
+ convert_to_long_ex(args[curarg]);
+ rc = ber_printf(ber, fmt_buf, Z_LVAL_PP(args[curarg]));
+ curarg++;
+ break;
+ case 'B' :
+ convert_to_string_ex(args[curarg]);
+ rc = ber_printf(ber, "B", Z_STRVAL_PP(args[curarg]),
+ 8 * Z_STRLEN_PP(args[curarg]));
+ curarg++;
+ break;
+ case 's' :
+ convert_to_string_ex(args[curarg]);
+ rc = ber_printf(ber, "s", Z_STRVAL_PP(args[curarg]));
+ curarg++;
+ break;
+ case 'o' :
+ convert_to_string_ex(args[curarg]);
+ rc = ber_printf(ber, "o", Z_STRVAL_PP(args[curarg]),
+ Z_STRLEN_PP(args[curarg]));
+ curarg++;
+ break;
+ case 'O' :
+ convert_to_string_ex(args[curarg]);
+ bv_str.bv_val = Z_STRVAL_PP(args[curarg]);
+ bv_str.bv_len = Z_STRLEN_PP(args[curarg]);
+ rc = ber_printf(ber, "O", &bv_str);
+ curarg++;
+ break;
+ case 'v' :
+ case 'V' :
+ err_msg = "Unsupported format specifier by now: '%c'";
+ goto ber_printf_errexit;
+ break;
+ case 'W' : /* This is an OpenLDAP extension only
+ * not present on draft-ietf-ldapext-ldap-c-api-*.txt
+ */
+ default:
+ err_msg = "Unkown format specifier: '%c'";
+ goto ber_printf_errexit;
+ } /* switch */
+ } /* else */
+ } /* switch */
+ if (rc == -1) {
+ err_msg = "Unable to process some values. Check you format string and values";
+ goto ber_printf_errexit;
+ }
+ pos++;
+ }
+
+ if (ber_flatten (ber, &bv_retval) == -1) {
+ goto ber_printf_errexit;
+ }
+
+ RETVAL_STRINGL(bv_retval-> bv_val, bv_retval->bv_len, 1);
+ ber_bvfree(bv_retval);
+ ber_free(ber,0);
+ efree(args);
+ return;
+
+ber_printf_errexit:
+ ber_free(ber,0);
+ efree(args);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, err_msg, format[pos] );
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto int ldap_ber_scanf(string berval, string format [, mixed arg1 [, mixed ...]])
+ The complimentary function to ber_printf */
+PHP_FUNCTION(ldap_ber_scanf)
+{
+ zval ***args;
+ int argc, i, curarg, int_val;
+ char *format, *err_msg, *string;
+ char fmt_buf[5];
+ unsigned int format_length, pos;
+ BerElement *ber;
+ ber_tag_t rc, tag;
+ ber_len_t ber_len;
+ struct berval bv_str, *bv_ptr;
+
+
+ argc = ZEND_NUM_ARGS();
+ if (argc < 2) {
+ WRONG_PARAM_COUNT;
+ }
+
+ args = (zval ***) safe_emalloc(sizeof(zval **), argc, 0);
+ if (zend_get_parameters_array_ex(argc, args) == FAILURE) {
+ efree(args);
+ WRONG_PARAM_COUNT;
+ }
+
+ /* If any variables are passed, make sure they are all passed by reference */
+ if ((argc - 2) > 0) {
+ for (i = 2; i < argc; i++){
+ if ( ! PZVAL_IS_REF(*args[i])) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING,
+ "Parameter %d must be passed by reference", i);
+ RETURN_LONG(0);
+ }
+ }
+ }
+
+ err_msg = NULL;
+
+ convert_to_string_ex(args[0]);
+ convert_to_string_ex(args[1]);
+
+ bv_str.bv_val = Z_STRVAL_PP(args[0]);
+ bv_str.bv_len = Z_STRLEN_PP(args[0]);
+ ber = ber_init(&bv_str);
+ if (ber == NULL) {
+ efree(args);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING,
+ "Unable to allocate enough memory or invalid BER data");
+ RETURN_LONG(0);
+ }
+
+ format=Z_STRVAL_PP(args[1]);
+ format_length=Z_STRLEN_PP(args[1]);
+
+ pos = 0;
+ curarg = 2;
+ while (pos < format_length) {
+ switch(format[pos]) {
+ case '{' :
+ case '}' :
+ case '[' :
+ case ']' :
+ case 'n' :
+ snprintf (fmt_buf, sizeof(fmt_buf), "%c", format[pos]);
+ rc = ber_scanf(ber, fmt_buf);
+ break;
+ default:
+ if (curarg > = argc) {
+ err_msg = "Too few arguments";
+ goto ber_scanf_errexit;
+ }
+ else {
+ switch(format[pos]) {
+ case 'a' :
+ rc = ber_scanf(ber, "a", &string);
+ if (rc != LBER_ERROR) {
+ zval_dtor(*args[curarg]);
+ ZVAL_STRING(*args[curarg], string, 1);
+ ber_memfree(string);
+ curarg++;
+ }
+ break;
+ case 'O' :
+ rc = ber_scanf(ber, "O", &bv_ptr);
+ if (rc != LBER_ERROR) {
+ zval_dtor(*args[curarg]);
+ ZVAL_STRINGL(*args[curarg], bv_ptr-> bv_val,
+ bv_ptr-> bv_len, 1);
+ ber_bvfree(bv_ptr);
+ curarg++;
+ }
+ break;
+ case 'b' :
+ rc = ber_scanf(ber, "b", &int_val);
+ if (rc != LBER_ERROR) {
+ zval_dtor(*args[curarg]);
+ ZVAL_BOOL(*args[curarg], int_val);
+ curarg++;
+ }
+ break;
+ case 'e' :
+ case 'i' :
+ snprintf (fmt_buf, sizeof(fmt_buf), "%c", format[pos]);
+ rc = ber_scanf(ber, fmt_buf, &int_val);
+ if (rc != LBER_ERROR) {
+ zval_dtor(*args[curarg]);
+ ZVAL_LONG(*args[curarg], int_val);
+ curarg++;
+ }
+ break;
+ case 'B' :
+ rc = ber_scanf(ber, "B", &string, &ber_len);
+ if (rc != LBER_ERROR) {
+ /* ber_len is in bits, _not_ in bytes, so beware!
+ */
+ zval_dtor(*args[curarg]);
+ ZVAL_STRINGL(*args[curarg], string, (ber_len+7)/8, 1);
+ ber_memfree(string);
+ curarg++;
+ }
+ break;
+ case 't' :
+ rc = ber_scanf(ber, "t", &tag);
+ if (rc != LBER_ERROR) {
+ zval_dtor(*args[curarg]);
+ ZVAL_LONG(*args[curarg], tag);
+ curarg++;
+ }
+ break;
+ case 'x' :
+ rc = ber_scanf(ber, "x");
+ break;
+ case 'v' :
+ case 'V' :
+ err_msg = "Unsupported format specifier by now: '%c'";
+ goto ber_scanf_errexit;
+ break;
+ case 'l' :
+ case 's' : /* This is an OpenLDAP extension only
+ * not present on draft-ietf-ldapext-ldap-c-api-*.txt
+ */
+ default:
+ err_msg = "Unkown format specifier: '%c'";
+ goto ber_scanf_errexit;
+ }
+ }
+ }
+ if (rc == LBER_ERROR) {
+ err_msg = "Unable to process some values. Check you format string and values";
+ goto ber_scanf_errexit;
+ }
+ pos++;
+ }
+ RETURN_LONG(curarg - 2);
+
+ber_scanf_errexit:
+ ber_free(ber,0);
+ efree(args);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, err_msg, format[pos] );
+ RETURN_LONG(0);
+}
+/* }}} */
+
+
/* {{{ proto resource ldap_first_reference(resource link, resource result)
Return first reference */
PHP_FUNCTION(ldap_first_reference)
Index: ext/ldap/php_ldap.h
===================================================================
RCS file: /repository/php-src/ext/ldap/php_ldap.h,v
retrieving revision 1.32.2.1
diff -u -r1.32.2.1 php_ldap.h
--- ext/ldap/php_ldap.h 1 Jan 2006 12:50:08 -0000 1.32.2.1
+++ ext/ldap/php_ldap.h 9 Apr 2006 20:40:07 -0000
@@ -56,6 +56,8 @@
PHP_FUNCTION(ldap_get_values);
PHP_FUNCTION(ldap_get_values_len);
PHP_FUNCTION(ber_free);
+PHP_FUNCTION(ldap_ber_printf);
+PHP_FUNCTION(ldap_ber_scanf);
PHP_FUNCTION(ldap_get_dn);
PHP_FUNCTION(ldap_explode_dn);
PHP_FUNCTION(ldap_dn2ufn);
Index: ext/ldap/ldap.c
===================================================================
RCS file: /repository/php-src/ext/ldap/ldap.c,v
retrieving revision 1.165
diff -u -r1.165 ldap.c
--- ext/ldap/ldap.c 1 Jan 2006 13:09:51 -0000 1.165
+++ ext/ldap/ldap.c 9 Apr 2006 21:15:38 -0000
@@ -80,7 +80,7 @@
ZEND_DECLARE_MODULE_GLOBALS(ldap)
static
- ZEND_BEGIN_ARG_INFO(arg3to6of6_force_ref, 0)
+ ZEND_BEGIN_ARG_INFO(arg3to7of7_force_ref, 0)
ZEND_ARG_PASS_INFO(0)
ZEND_ARG_PASS_INFO(0)
ZEND_ARG_PASS_INFO(1)
@@ -147,8 +147,10 @@
PHP_FE(ldap_parse_reference, third_arg_force_ref)
#endif
#ifdef HAVE_LDAP_PARSE_RESULT
- PHP_FE(ldap_parse_result, arg3to6of6_force_ref)
+ PHP_FE(ldap_parse_result, arg3to7of7_force_ref)
#endif
+ PHP_FE(ldap_ber_printf, NULL)
+ PHP_FE(ldap_ber_scanf, NULL)
#ifdef HAVE_LDAP_START_TLS_S
PHP_FE(ldap_start_tls, NULL)
#endif
@@ -1932,18 +1934,19 @@
/* }}} */
#ifdef HAVE_LDAP_PARSE_RESULT
-/* {{{ proto bool ldap_parse_result(resource link, resource result, int errcode, string mat
cheddn, string errmsg, array referrals)
+/* {{{ proto bool ldap_parse_result(resource link, resource result, int errcode, string mat
cheddn, string errmsg, array referrals, array serverctrls)
Extract information from result */
PHP_FUNCTION(ldap_parse_result)
{
- zval **link, **result, **errcode, **matcheddn, **errmsg, **referrals;
+ zval **link, **result, **errcode, **matcheddn, **errmsg, **referrals, **serverctrls;
ldap_linkdata *ld;
LDAPMessage *ldap_result;
+ LDAPControl **lserverctrls, **ctrlp, *ctrl;
char **lreferrals, **refp;
char *lmatcheddn, *lerrmsg;
int rc, lerrcode, myargcount = ZEND_NUM_ARGS();
- if (myargcount < 3 || myargcount > 6 || zend_get_parameters_ex(myargcount, &link, &result,
&errcode, &matcheddn, &errmsg, &referrals) == FAILURE) {
+ if (myargcount < 3 || myargcount > 7 || zend_get_parameters_ex(myargcount, &link, &result,
&errcode, &matcheddn, &errmsg, &referrals, &serverctrls) == FAILURE) {
WRONG_PARAM_COUNT;
}
@@ -1954,7 +1957,7 @@
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));
@@ -1966,6 +1969,29 @@
/* Reverse -> fall through */
switch (myargcount) {
+ case 7 :
+ zval_dtor(*serverctrls);
+
+ if (lserverctrls != NULL) {
+ array_init(*serverctrls);
+ ctrlp = lserverctrls;
+
+ while (*ctrlp != NULL) {
+ zval *ctrl_array;
+
+ ctrl = *ctrlp;
+ MAKE_STD_ZVAL(ctrl_array);
+ array_init(ctrl_array);
+
+ add_assoc_string(ctrl_array, "oid", ctrl-> ldctl_oid,1);
+ add_assoc_bool(ctrl_array, "iscritical", ctrl-> ldctl_iscritical);
+ add_assoc_stringl(ctrl_array, "value", ctrl-> ldctl_value.bv_val,
+ ctrl-> ldctl_value.bv_len,1);
+ add_next_index_zval (*serverctrls, ctrl_array);
+ ctrlp++;
+ }
+ ldap_controls_free (lserverctrls);
+ }
case 6:
zval_dtor(*referrals);
array_init(*referrals);
@@ -1999,6 +2025,303 @@
/* }}} */
#endif
+/* {{{ proto string ldap_ber_printf(string format [, mixed arg1 [, mixed ...]])
+ Creates a BER encoded string of the values/types specified in the format string. Return
s the BER encoded string, or 'false' if the enconding failed */
+PHP_FUNCTION(ldap_ber_printf)
+{
+ zval ***args;
+ int argc, curarg, rc;
+ char *format;
+ char fmt_buf[5], *err_msg;
+ unsigned int format_length, pos;
+ BerElement *ber;
+ struct berval bv_str, *bv_retval;
+
+ argc = ZEND_NUM_ARGS();
+
+ if (argc < 1) {
+ WRONG_PARAM_COUNT;
+ }
+
+ args = (zval ***)safe_emalloc(argc, sizeof(zval *), 0);
+
+ if (zend_get_parameters_array_ex(argc, args) == FAILURE) {
+ efree(args);
+ WRONG_PARAM_COUNT;
+ }
+
+ convert_to_string_ex(args[0]);
+ format = Z_STRVAL_PP(args[0]);
+ format_length = Z_STRLEN_PP(args[0]);
+
+ ber = ber_alloc_t(LBER_USE_DER);
+ if (ber == NULL) {
+ efree(args);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to allocate enough memory");
+ RETURN_FALSE;
+ }
+
+ err_msg = NULL;
+ pos = 0;
+ curarg = 1;
+ while (pos < format_length) {
+ switch(format[pos]) {
+ case '{' :
+ case '}' :
+ case '[' :
+ case ']' :
+ case 'n' :
+ snprintf (fmt_buf, sizeof(fmt_buf), "%c", format[pos]);
+ rc = ber_printf(ber, fmt_buf);
+ break;
+ default:
+ if (curarg > = argc) {
+ err_msg = "Too few arguments";
+ goto ber_printf_errexit;
+ }
+ else {
+ switch(format[pos]) {
+ case 'b' :
+ convert_to_boolean_ex(args[curarg]);
+ rc = ber_printf(ber, "b", Z_LVAL_PP(args[curarg]));
+ curarg++;
+ break;
+ case 'e' :
+ case 'i' :
+ case 't' :
+ snprintf (fmt_buf, sizeof(fmt_buf), "%c", format[pos]);
+ convert_to_long_ex(args[curarg]);
+ rc = ber_printf(ber, fmt_buf, Z_LVAL_PP(args[curarg]));
+ curarg++;
+ break;
+ case 'B' :
+ convert_to_string_ex(args[curarg]);
+ rc = ber_printf(ber, "B", Z_STRVAL_PP(args[curarg]),
+ 8 * Z_STRLEN_PP(args[curarg]));
+ curarg++;
+ break;
+ case 's' :
+ convert_to_string_ex(args[curarg]);
+ rc = ber_printf(ber, "s", Z_STRVAL_PP(args[curarg]));
+ curarg++;
+ break;
+ case 'o' :
+ convert_to_string_ex(args[curarg]);
+ rc = ber_printf(ber, "o", Z_STRVAL_PP(args[curarg]),
+ Z_STRLEN_PP(args[curarg]));
+ curarg++;
+ break;
+ case 'O' :
+ convert_to_string_ex(args[curarg]);
+ bv_str.bv_val = Z_STRVAL_PP(args[curarg]);
+ bv_str.bv_len = Z_STRLEN_PP(args[curarg]);
+ rc = ber_printf(ber, "O", &bv_str);
+ curarg++;
+ break;
+ case 'v' :
+ case 'V' :
+ err_msg = "Unsupported format specifier by now: '%c'";
+ goto ber_printf_errexit;
+ break;
+ case 'W' : /* This is an OpenLDAP extension only
+ * not present on draft-ietf-ldapext-ldap-c-api-*.txt
+ */
+ default:
+ err_msg = "Unkown format specifier: '%c'";
+ goto ber_printf_errexit;
+ } /* switch */
+ } /* else */
+ } /* switch */
+ if (rc == -1) {
+ err_msg = "Unable to process some values. Check you format string and values";
+ goto ber_printf_errexit;
+ }
+ pos++;
+ }
+
+ if (ber_flatten (ber, &bv_retval) == -1) {
+ goto ber_printf_errexit;
+ }
+
+ RETVAL_STRINGL(bv_retval-> bv_val, bv_retval->bv_len, 1);
+ ber_bvfree(bv_retval);
+ ber_free(ber,0);
+ efree(args);
+ return;
+
+ber_printf_errexit:
+ ber_free(ber,0);
+ efree(args);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, err_msg, format[pos] );
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto int ldap_ber_scanf(string berval, string format [, mixed arg1 [, mixed ...]])
+ The complimentary function to ber_printf */
+PHP_FUNCTION(ldap_ber_scanf)
+{
+ zval ***args;
+ int argc, i, curarg, int_val;
+ char *format, *err_msg, *string;
+ char fmt_buf[5];
+ unsigned int format_length, pos;
+ BerElement *ber;
+ ber_tag_t rc, tag;
+ ber_len_t ber_len;
+ struct berval bv_str, *bv_ptr;
+
+
+ argc = ZEND_NUM_ARGS();
+ if (argc < 2) {
+ WRONG_PARAM_COUNT;
+ }
+
+ args = (zval ***) safe_emalloc(sizeof(zval **), argc, 0);
+ if (zend_get_parameters_array_ex(argc, args) == FAILURE) {
+ efree(args);
+ WRONG_PARAM_COUNT;
+ }
+
+ /* If any variables are passed, make sure they are all passed by reference */
+ if ((argc - 2) > 0) {
+ for (i = 2; i < argc; i++){
+ if ( ! PZVAL_IS_REF(*args[i])) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING,
+ "Parameter %d must be passed by reference", i);
+ RETURN_LONG(0);
+ }
+ }
+ }
+
+ err_msg = NULL;
+
+ convert_to_string_ex(args[0]);
+ convert_to_string_ex(args[1]);
+
+ bv_str.bv_val = Z_STRVAL_PP(args[0]);
+ bv_str.bv_len = Z_STRLEN_PP(args[0]);
+ ber = ber_init(&bv_str);
+ if (ber == NULL) {
+ efree(args);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING,
+ "Unable to allocate enough memory or invalid BER data");
+ RETURN_LONG(0);
+ }
+
+ format=Z_STRVAL_PP(args[1]);
+ format_length=Z_STRLEN_PP(args[1]);
+
+ pos = 0;
+ curarg = 2;
+ while (pos < format_length) {
+ switch(format[pos]) {
+ case '{' :
+ case '}' :
+ case '[' :
+ case ']' :
+ case 'n' :
+ snprintf (fmt_buf, sizeof(fmt_buf), "%c", format[pos]);
+ rc = ber_scanf(ber, fmt_buf);
+ break;
+ default:
+ if (curarg > = argc) {
+ err_msg = "Too few arguments";
+ goto ber_scanf_errexit;
+ }
+ else {
+ switch(format[pos]) {
+ case 'a' :
+ rc = ber_scanf(ber, "a", &string);
+ if (rc != LBER_ERROR) {
+ zval_dtor(*args[curarg]);
+ ZVAL_STRING(*args[curarg], string, 1);
+ ber_memfree(string);
+ curarg++;
+ }
+ break;
+ case 'O' :
+ rc = ber_scanf(ber, "O", &bv_ptr);
+ if (rc != LBER_ERROR) {
+ zval_dtor(*args[curarg]);
+ ZVAL_STRINGL(*args[curarg], bv_ptr-> bv_val,
+ bv_ptr-> bv_len, 1);
+ ber_bvfree(bv_ptr);
+ curarg++;
+ }
+ break;
+ case 'b' :
+ rc = ber_scanf(ber, "b", &int_val);
+ if (rc != LBER_ERROR) {
+ zval_dtor(*args[curarg]);
+ ZVAL_BOOL(*args[curarg], int_val);
+ curarg++;
+ }
+ break;
+ case 'e' :
+ case 'i' :
+ snprintf (fmt_buf, sizeof(fmt_buf), "%c", format[pos]);
+ rc = ber_scanf(ber, fmt_buf, &int_val);
+ if (rc != LBER_ERROR) {
+ zval_dtor(*args[curarg]);
+ ZVAL_LONG(*args[curarg], int_val);
+ curarg++;
+ }
+ break;
+ case 'B' :
+ rc = ber_scanf(ber, "B", &string, &ber_len);
+ if (rc != LBER_ERROR) {
+ /* ber_len is in bits, _not_ in bytes, so beware!
+ */
+ zval_dtor(*args[curarg]);
+ ZVAL_STRINGL(*args[curarg], string, (ber_len+7)/8, 1);
+ ber_memfree(string);
+ curarg++;
+ }
+ break;
+ case 't' :
+ rc = ber_scanf(ber, "t", &tag);
+ if (rc != LBER_ERROR) {
+ zval_dtor(*args[curarg]);
+ ZVAL_LONG(*args[curarg], tag);
+ curarg++;
+ }
+ break;
+ case 'x' :
+ rc = ber_scanf(ber, "x");
+ break;
+ case 'v' :
+ case 'V' :
+ err_msg = "Unsupported format specifier by now: '%c'";
+ goto ber_scanf_errexit;
+ break;
+ case 'l' :
+ case 's' : /* This is an OpenLDAP extension only
+ * not present on draft-ietf-ldapext-ldap-c-api-*.txt
+ */
+ default:
+ err_msg = "Unkown format specifier: '%c'";
+ goto ber_scanf_errexit;
+ }
+ }
+ }
+ if (rc == LBER_ERROR) {
+ err_msg = "Unable to process some values. Check you format string and values";
+ goto ber_scanf_errexit;
+ }
+ pos++;
+ }
+ RETURN_LONG(curarg - 2);
+
+ber_scanf_errexit:
+ ber_free(ber,0);
+ efree(args);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, err_msg, format[pos] );
+ RETURN_LONG(0);
+}
+/* }}} */
+
+
/* {{{ proto resource ldap_first_reference(resource link, resource result)
Return first reference */
PHP_FUNCTION(ldap_first_reference)
Index: ext/ldap/php_ldap.h
===================================================================
RCS file: /repository/php-src/ext/ldap/php_ldap.h,v
retrieving revision 1.33
diff -u -r1.33 php_ldap.h
--- ext/ldap/php_ldap.h 1 Jan 2006 13:09:51 -0000 1.33
+++ ext/ldap/php_ldap.h 9 Apr 2006 21:15:39 -0000
@@ -56,6 +56,8 @@
PHP_FUNCTION(ldap_get_values);
PHP_FUNCTION(ldap_get_values_len);
PHP_FUNCTION(ber_free);
+PHP_FUNCTION(ldap_ber_printf);
+PHP_FUNCTION(ldap_ber_scanf);
PHP_FUNCTION(ldap_get_dn);
PHP_FUNCTION(ldap_explode_dn);
PHP_FUNCTION(ldap_dn2ufn);
Thread:
Ignacio Arenaza
Marcus Boerger
Marcus Boerger
Marcus Boerger
|