Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:19929 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 61247 invoked by uid 1010); 8 Nov 2005 23:18:15 -0000 Delivered-To: ezmlm-scan-internals@lists.php.net Delivered-To: ezmlm-internals@lists.php.net Received: (qmail 61232 invoked from network); 8 Nov 2005 23:18:15 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 8 Nov 2005 23:18:15 -0000 X-Host-Fingerprint: 194.244.21.114 ns1.sys-net.it Linux 2.4 in cluster Received: from ([194.244.21.114:39100] helo=mail.sys-net.it) by pb1.pair.com (ecelerity 2.0 beta r(6323M)) with SMTP id 7C/A5-09491-73231734 for ; Tue, 08 Nov 2005 18:18:15 -0500 Received: from 192.168.1.199 (host40-89.pool8172.interbusiness.it [81.72.89.40]) (authenticated bits=0) by mail.sys-net.it (8.13.3/8.13.3) with ESMTP id jA8NHOu5006585 (version=TLSv1/SSLv3 cipher=RC4-MD5 bits=128 verify=NOT); Wed, 9 Nov 2005 00:17:25 +0100 To: Jani Taskinen Cc: venaas@php.net, internals@lists.php.net In-Reply-To: References: <1131485315.3327.15.camel@ando> Content-Type: multipart/mixed; boundary="=-gvxhgzK1dazhT7uZh7M5" Date: Wed, 09 Nov 2005 00:22:57 +0100 Message-ID: <1131492177.3327.25.camel@ando> Mime-Version: 1.0 X-Mailer: Evolution 2.0.2 (2.0.2-22) X-Greylist: Sender succeeded SMTP AUTH authentication, not delayed by milter-greylist-2.0.1 (mail.sys-net.it [194.244.21.114]); Wed, 09 Nov 2005 00:17:26 +0100 (CET) X-SysNet-MailScanner-Information: postmaster@sys-net.it X-SysNet-MailScanner: X-MailScanner-From: ando@sys-net.it Subject: Re: [PHP-DEV] LDAP controls in response From: ando@sys-net.it (Pierangelo Masarati) --=-gvxhgzK1dazhT7uZh7M5 Content-Type: text/plain Content-Transfer-Encoding: 7bit On Wed, 2005-11-09 at 00:37 +0200, Jani Taskinen wrote: > I quickly glanced through your patch and if you don't mind, > can you please separate the warning-fixes and functionality patch? > (one patch for fixes, one for adding new stuff :) > > It's a bit too much to try and see what was added and what is supposed > to silence some warning. Sure. I quickly separated them by editing the patch, so you'll likely get some fuzz message because of wrong line count. They should apply in any order, though, because there was no code overlapping. I successfully did warnings, controls. Sincerely, p. Ing. Pierangelo Masarati Responsabile Open Solution SysNet s.n.c. Via Dossi, 8 - 27100 Pavia - ITALIA http://www.sys-net.it ------------------------------------------ Office: +39.02.23998309 Mobile: +39.333.4963172 Email: pierangelo.masarati@sys-net.it ------------------------------------------ --=-gvxhgzK1dazhT7uZh7M5 Content-Disposition: attachment; filename=php-ldap-warnings.txt Content-Type: text/x-patch; name=php-ldap-warnings.txt; charset=utf-8 Content-Transfer-Encoding: 7bit Index: ext/ldap/ldap.c =================================================================== RCS file: /repository/php-src/ext/ldap/ldap.c,v retrieving revision 1.162 diff -u -r1.162 ldap.c --- ext/ldap/ldap.c 22 Aug 2005 12:22:08 -0000 1.162 +++ ext/ldap/ldap.c 8 Nov 2005 21:04:05 -0000 @@ -191,7 +191,9 @@ { ldap_linkdata *ld = (ldap_linkdata *)rsrc->ptr; - ldap_unbind_s(ld->link); + /* ldap_unbind_s() is deprecated; + * the distinction between ldap_unbind() and ldap_unbind_s() is moot */ + ldap_unbind_ext(ld->link, NULL, NULL); #if defined(LDAP_API_FEATURE_X_OPENLDAP) && defined(HAVE_3ARG_SETREBINDPROC) if (ld->rebindproc != NULL) { zval_dtor(ld->rebindproc); @@ -370,7 +445,11 @@ { char *host = NULL; int hostlen; +#ifdef LDAP_API_FEATURE_X_OPENLDAP + long port = LDAP_PORT; +#else long port = 389; /* Default port */ +#endif #ifdef HAVE_ORALDAP char *wallet, *walletpasswd; int walletlen, walletpasswdlen; @@ -406,17 +485,33 @@ ld = ecalloc(1, sizeof(ldap_linkdata)); #ifdef LDAP_API_FEATURE_X_OPENLDAP - if (host != NULL && strchr(host, '/')) { - int rc; + /* OpenLDAP provides a specific call to detect valid LDAP URIs */ + { + int rc; + char *url = host; + + if (!ldap_is_ldap_url(url)) { + int urllen = hostlen + sizeof( "ldap://:65535" ); + + if (port < 0 || port > 65535) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid port number: %ld", port); + RETURN_FALSE; + } + + url = emalloc(urllen); + snprintf( url, urllen, "ldap://%s:%ld", host ? host : "", port ? port : LDAP_PORT ); + } - rc = ldap_initialize(&ldap, host); + rc = ldap_initialize(&ldap, url); if (rc != LDAP_SUCCESS) { efree(ld); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not create session handle: %s", ldap_err2string(rc)); RETURN_FALSE; } - } else { - ldap = ldap_init(host, port); + + if (url != host) { + efree(url); + } } #else ldap = ldap_open(host, port); @@ -479,7 +574,21 @@ ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link); - if ((rc = ldap_bind_s(ld->link, ldap_bind_dn, ldap_bind_pw, LDAP_AUTH_SIMPLE)) != LDAP_SUCCESS) { +#ifdef LDAP_API_FEATURE_X_OPENLDAP + { + struct berval cred; + + /* ldap_bind_s() is deprecated; use ldap_sasl_bind_s() instead */ + cred.bv_val = ldap_bind_pw; + cred.bv_len = ldap_bind_pw ? ldap_bind_pwlen : 0; + rc = ldap_sasl_bind_s(ld->link, ldap_bind_dn, LDAP_SASL_SIMPLE, &cred, + NULL, NULL, /* no controls right now */ + NULL); /* we don't care about the server's credentials */ + } +#else + rc = ldap_bind_s(ld->link, ldap_bind_dn, ldap_bind_pw, LDAP_AUTH_SIMPLE); +#endif + if ( rc != LDAP_SUCCESS) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to bind to server: %s", ldap_err2string(rc)); RETURN_FALSE; } else { @@ -1030,7 +1139,6 @@ BerElement *ber; char *attribute; size_t attr_len; - char **ldap_value; char *dn; if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &link, &result) == FAILURE) { @@ -1061,16 +1169,18 @@ attribute = ldap_first_attribute(ldap, ldap_result_entry, &ber); while (attribute != NULL) { - ldap_value = ldap_get_values(ldap, ldap_result_entry, attribute); - num_values = ldap_count_values(ldap_value); + struct berval **ldap_value; + + ldap_value = ldap_get_values_len(ldap, ldap_result_entry, attribute); + num_values = ldap_count_values_len(ldap_value); MAKE_STD_ZVAL(tmp2); array_init(tmp2); add_assoc_long(tmp2, "count", num_values); for (i = 0; i < num_values; i++) { - add_index_string(tmp2, i, ldap_value[i], 1); + add_index_stringl(tmp2, i, ldap_value[i]->bv_val, ldap_value[i]->bv_len, 1); } - ldap_value_free(ldap_value); + ldap_value_free_len(ldap_value); attr_len = strlen(attribute); zend_hash_update(Z_ARRVAL_P(tmp1), php_strtolower(attribute, attr_len), attr_len+1, (void *) &tmp2, sizeof(zval *), NULL); @@ -1177,7 +1287,6 @@ ldap_linkdata *ld; ldap_resultentry *resultentry; char *attribute; - char **ldap_value; int i, num_values, num_attrib; BerElement *ber; @@ -1193,16 +1302,18 @@ attribute = ldap_first_attribute(ld->link, resultentry->data, &ber); while (attribute != NULL) { - ldap_value = ldap_get_values(ld->link, resultentry->data, attribute); - num_values = ldap_count_values(ldap_value); + struct berval **ldap_value; + + ldap_value = ldap_get_values_len(ld->link, resultentry->data, attribute); + num_values = ldap_count_values_len(ldap_value); MAKE_STD_ZVAL(tmp); array_init(tmp); add_assoc_long(tmp, "count", num_values); for (i = 0; i < num_values; i++) { - add_index_string(tmp, i, ldap_value[i], 1); + add_index_stringl(tmp, i, ldap_value[i]->bv_val, ldap_value[i]->bv_len, 1); } - ldap_value_free(ldap_value); + ldap_value_free_len(ldap_value); zend_hash_update(Z_ARRVAL_P(return_value), attribute, strlen(attribute)+1, (void *) &tmp, sizeof(zval *), NULL); add_index_string(return_value, num_attrib, attribute, 1); @@ -1231,7 +1342,7 @@ ldap_linkdata *ld; ldap_resultentry *resultentry; char *attribute; - char **ldap_value; + struct berval **ldap_value; int i, num_values; if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &link, &result_entry, &attr) == FAILURE) { @@ -1244,21 +1355,21 @@ convert_to_string_ex(attr); attribute = Z_STRVAL_PP(attr); - if ((ldap_value = ldap_get_values(ld->link, resultentry->data, attribute)) == NULL) { + if ((ldap_value = ldap_get_values_len(ld->link, resultentry->data, attribute)) == NULL) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot get the value(s) of attribute %s", ldap_err2string(_get_lderrno(ld->link))); RETURN_FALSE; } - num_values = ldap_count_values(ldap_value); + num_values = ldap_count_values_len(ldap_value); array_init(return_value); for (i = 0; ibv_val, ldap_value[i]->bv_len, 1); } add_assoc_long(return_value, "count", num_values); - ldap_value_free(ldap_value); + ldap_value_free_len(ldap_value); } /* }}} */ @@ -1363,7 +1474,11 @@ add_index_string(return_value, i, ldap_value[i], 1); } +#ifdef LDAP_API_FEATURE_X_OPENLDAP + ber_memvfree((void **)ldap_value); +#else ldap_value_free(ldap_value); +#endif } /* }}} */ --=-gvxhgzK1dazhT7uZh7M5 Content-Disposition: attachment; filename=php-ldap-result-controls.1.txt Content-Type: text/x-patch; name=php-ldap-result-controls.1.txt; charset=utf-8 Content-Transfer-Encoding: 7bit Index: ext/ldap/ldap.c =================================================================== RCS file: /repository/php-src/ext/ldap/ldap.c,v retrieving revision 1.162 diff -u -r1.162 ldap.c --- ext/ldap/ldap.c 22 Aug 2005 12:22:08 -0000 1.162 +++ ext/ldap/ldap.c 8 Nov 2005 21:04:05 -0000 @@ -215,6 +217,79 @@ efree(entry); } +static int _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; + } + + add_assoc_long(*referrals, "count", num_referrals); + + return num_referrals; +} + +static int _parse_server_controls_resp(LDAPControl ***lserverctrlsp, zval **serverctrls) +{ + int num_serverctrls = 0; + + if (*lserverctrlsp != NULL) { + int error = 0; + LDAPControl **ctrlp = *lserverctrlsp; + + 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); + } + if ((*ctrlp)->ldctl_iscritical) { + add_assoc_bool(ctrlval, "iscritical", (*ctrlp)->ldctl_iscritical); + } + + add_next_index_zval(*serverctrls, ctrlval); + + num_serverctrls++; + ctrlp++; + } + ldap_controls_free(*lserverctrlsp); + *lserverctrlsp = NULL; + + if (error) { + /* ... */ + return -1; + } + } + + if (num_serverctrls != -1) { + add_assoc_long(*serverctrls, "count", num_serverctrls); + } + + return num_serverctrls; +} + /* {{{ PHP_INI_BEGIN */ PHP_INI_BEGIN() @@ -1933,14 +2048,15 @@ 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 (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 +2067,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,17 +2079,15 @@ /* 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); + _parse_server_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_value_free(lreferrals); - } + _parse_referrals_resp(&lreferrals, referrals); case 5: zval_dtor(*errmsg); if (lerrmsg == NULL) { @@ -2057,32 +2171,38 @@ Extract information from reference entry */ PHP_FUNCTION(ldap_parse_reference) { - zval **link, **result_entry, **referrals; + zval **link, **result_entry, **referrals, **serverctrls; ldap_linkdata *ld; ldap_resultentry *resultentry; - char **lreferrals, **refp; + char **lreferrals; + LDAPControl **lserverctrls; + int myargcount = ZEND_NUM_ARGS(); - if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &link, &result_entry, &referrals) == FAILURE) { + if (myargcount < 3 || myargcount > 4 || zend_get_parameters_ex(4, &link, &result_entry, &referrals, &serverctrls) == FAILURE) { WRONG_PARAM_COUNT; } ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, link, -1, "ldap link", le_link); ZEND_FETCH_RESOURCE(resultentry, ldap_resultentry *, result_entry, -1, "ldap result entry", le_result_entry); - if (ldap_parse_reference(ld->link, resultentry->data, &lreferrals, NULL /* &serverctrls */, 0) != LDAP_SUCCESS) { + if (ldap_parse_reference(ld->link, resultentry->data, &lreferrals, &lserverctrls, 0) != LDAP_SUCCESS) { RETURN_FALSE; } - zval_dtor(*referrals); - array_init(*referrals); - if (lreferrals != NULL) { - refp = lreferrals; - while (*refp) { - add_next_index_string(*referrals, *refp, 1); - refp++; - } - ldap_value_free(lreferrals); + + /* Reverse -> fall through */ + switch (myargcount) { + case 4: + /* use arg #4 as the array of controls returned by the server */ + zval_dtor(*serverctrls); + array_init(*serverctrls); + _parse_server_controls_resp(&lserverctrls, serverctrls); + case 3: + zval_dtor(*referrals); + array_init(*referrals); + _parse_referrals_resp(&lreferrals, referrals); } + RETURN_TRUE; } /* }}} */ --=-gvxhgzK1dazhT7uZh7M5--