Skip to content

Commit 513bbba

Browse files
author
Côme Chilliet
committed
Merge branch 'pull-request/2608'
* pull-request/2608: Test ldap_exop_passwd with less parameters to be sure it works Changed API to avoid using passing result by reference Removed unused variables left over by LDAP EXOP patch Removed TSRMLS_CC instances left over by LDAP EXOP patch Swapped position of retoid and retdata as retoid is almost never used Removed two step syntax for EXOP helpers, one call workflow is enough Improved ldap_exop test to encode&decode a passwd EXOP to test sending/recieving data Removed TODOs regarding implementing passwd and whoami exops based on ldap_exop Added constants for standard EXOPs Removed ldap_refresh function as I’m not sure how to fix/use/test it Fixed ldap_exop and ldap_parse_exop. Only tested them for whoami exop. (see test file) Fixed ldap_parse_exop_whoami and ldap_parse_exop_passwd and added test for them Fixed ldap_exop_whoami and added a test for it Fixed ldap_exop_passwd and added tests for it Fixed building errors in LDAP EXOP Added EXOP features based on patch from http://cvsweb.netbsd.org/bsdweb.cgi/pkgsrc/databases/php-ldap/files/ldap-ctrl-exop56.patch
2 parents e1f1ee1 + 209c9ba commit 513bbba

File tree

8 files changed

+511
-1
lines changed

8 files changed

+511
-1
lines changed

ext/ldap/config.m4

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ if test "$PHP_LDAP" != "no"; then
204204

205205
dnl Solaris 2.8 claims to be 2004 API, but doesn't have
206206
dnl ldap_parse_reference() nor ldap_start_tls_s()
207-
AC_CHECK_FUNCS([ldap_parse_result ldap_parse_reference ldap_start_tls_s ldap_control_find])
207+
AC_CHECK_FUNCS([ldap_parse_result ldap_parse_reference ldap_start_tls_s ldap_control_find ldap_parse_extended_result ldap_extended_operation ldap_extended_operation_s ldap_passwd_s ldap_whoami_s])
208208

209209
dnl
210210
dnl SASL check

ext/ldap/config.w32

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ if (PHP_LDAP != "no") {
2121
AC_DEFINE('HAVE_LDAP_SASL_SASL_H', 1);
2222
AC_DEFINE('LDAP_DEPRECATED', 1);
2323
AC_DEFINE('HAVE_LDAP_CONTROL_FIND', 1);
24+
AC_DEFINE('HAVE_LDAP_PARSE_EXTENDED_RESULT', 1);
25+
AC_DEFINE('HAVE_LDAP_EXTENDED_OPERATION_S', 1);
26+
AC_DEFINE('HAVE_LDAP_PASSWD_S', 1);
27+
AC_DEFINE('HAVE_LDAP_WHOAMI_S', 1);
28+
AC_DEFINE('HAVE_LDAP_EXTENDED_OPERATION', 1);
2429

2530
} else {
2631
WARNING("ldap not enabled; libraries and headers not found");

ext/ldap/ldap.c

Lines changed: 312 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,14 @@ PHP_MINIT_FUNCTION(ldap)
283283
REGISTER_LONG_CONSTANT("LDAP_ESCAPE_FILTER", PHP_LDAP_ESCAPE_FILTER, CONST_PERSISTENT | CONST_CS);
284284
REGISTER_LONG_CONSTANT("LDAP_ESCAPE_DN", PHP_LDAP_ESCAPE_DN, CONST_PERSISTENT | CONST_CS);
285285

286+
#ifdef HAVE_LDAP_EXTENDED_OPERATION_S
287+
REGISTER_STRING_CONSTANT("LDAP_EXOP_START_TLS", LDAP_EXOP_START_TLS, CONST_PERSISTENT | CONST_CS);
288+
REGISTER_STRING_CONSTANT("LDAP_EXOP_MODIFY_PASSWD", LDAP_EXOP_MODIFY_PASSWD, CONST_PERSISTENT | CONST_CS);
289+
REGISTER_STRING_CONSTANT("LDAP_EXOP_REFRESH", LDAP_EXOP_REFRESH, CONST_PERSISTENT | CONST_CS);
290+
REGISTER_STRING_CONSTANT("LDAP_EXOP_WHO_AM_I", LDAP_EXOP_WHO_AM_I, CONST_PERSISTENT | CONST_CS);
291+
REGISTER_STRING_CONSTANT("LDAP_EXOP_TURN", LDAP_EXOP_TURN, CONST_PERSISTENT | CONST_CS);
292+
#endif
293+
286294
le_link = zend_register_list_destructors_ex(_close_ldap_link, NULL, "ldap link", module_number);
287295
le_result = zend_register_list_destructors_ex(_free_ldap_result, NULL, "ldap result", module_number);
288296
le_result_entry = zend_register_list_destructors_ex(_free_ldap_result_entry, NULL, "ldap result entry", module_number);
@@ -2564,6 +2572,67 @@ PHP_FUNCTION(ldap_parse_result)
25642572
/* }}} */
25652573
#endif
25662574

2575+
/* {{{ Extended operation response parsing, Pierangelo Masarati */
2576+
#ifdef HAVE_LDAP_PARSE_EXTENDED_RESULT
2577+
/* {{{ proto bool ldap_parse_exop(resource link, resource result [, string retdata [, string retoid]])
2578+
Extract information from extended operation result */
2579+
PHP_FUNCTION(ldap_parse_exop)
2580+
{
2581+
zval *link, *result, *retdata, *retoid;
2582+
ldap_linkdata *ld;
2583+
LDAPMessage *ldap_result;
2584+
char *lretoid;
2585+
struct berval *lretdata;
2586+
int rc, myargcount = ZEND_NUM_ARGS();
2587+
2588+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "rr|z/z/", &link, &result, &retdata, &retoid) != SUCCESS) {
2589+
WRONG_PARAM_COUNT;
2590+
}
2591+
2592+
if ((ld = (ldap_linkdata *)zend_fetch_resource(Z_RES_P(link), "ldap link", le_link)) == NULL) {
2593+
RETURN_FALSE;
2594+
}
2595+
2596+
if ((ldap_result = (LDAPMessage *)zend_fetch_resource(Z_RES_P(result), "ldap result", le_result)) == NULL) {
2597+
RETURN_FALSE;
2598+
}
2599+
2600+
rc = ldap_parse_extended_result(ld->link, ldap_result,
2601+
myargcount > 3 ? &lretoid: NULL,
2602+
myargcount > 2 ? &lretdata: NULL,
2603+
0);
2604+
if (rc != LDAP_SUCCESS) {
2605+
php_error_docref(NULL, E_WARNING, "Unable to parse extended operation result: %s", ldap_err2string(rc));
2606+
RETURN_FALSE;
2607+
}
2608+
2609+
/* Reverse -> fall through */
2610+
switch (myargcount) {
2611+
case 4:
2612+
zval_dtor(retoid);
2613+
if (lretoid == NULL) {
2614+
ZVAL_EMPTY_STRING(retoid);
2615+
} else {
2616+
ZVAL_STRING(retoid, lretoid);
2617+
ldap_memfree(lretoid);
2618+
}
2619+
case 3:
2620+
/* use arg #3 as the data returned by the server */
2621+
zval_dtor(retdata);
2622+
if (lretdata == NULL) {
2623+
ZVAL_EMPTY_STRING(retdata);
2624+
} else {
2625+
ZVAL_STRINGL(retdata, lretdata->bv_val, lretdata->bv_len);
2626+
ldap_memfree(lretdata->bv_val);
2627+
ldap_memfree(lretdata);
2628+
}
2629+
}
2630+
RETURN_TRUE;
2631+
}
2632+
/* }}} */
2633+
#endif
2634+
/* }}} */
2635+
25672636
/* {{{ proto resource ldap_first_reference(resource link, resource result)
25682637
Return first reference */
25692638
PHP_FUNCTION(ldap_first_reference)
@@ -3150,6 +3219,203 @@ PHP_FUNCTION(ldap_control_paged_result_response)
31503219
/* }}} */
31513220
#endif
31523221

3222+
/* {{{ Extended operations, Pierangelo Masarati */
3223+
#ifdef HAVE_LDAP_EXTENDED_OPERATION_S
3224+
/* {{{ proto ? ldap_exop(resource link, string reqoid [, string reqdata [, string retdata [, string retoid]]])
3225+
Extended operation */
3226+
PHP_FUNCTION(ldap_exop)
3227+
{
3228+
zval *link, *reqoid, *reqdata, *retdata, *retoid;
3229+
char *lreqoid, *lretoid = NULL;
3230+
struct berval lreqdata, *lretdata = NULL;
3231+
ldap_linkdata *ld;
3232+
LDAPMessage *ldap_res;
3233+
int rc, msgid, myargcount = ZEND_NUM_ARGS();
3234+
/* int reqoid_len, reqdata_len, retdata_len, retoid_len, retdat_len; */
3235+
3236+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "rz|zz/z/", &link, &reqoid, &reqdata, &retdata, &retoid) != SUCCESS) {
3237+
WRONG_PARAM_COUNT;
3238+
}
3239+
3240+
if ((ld = (ldap_linkdata *)zend_fetch_resource(Z_RES_P(link), "ldap link", le_link)) == NULL) {
3241+
RETURN_FALSE;
3242+
}
3243+
3244+
switch (myargcount) {
3245+
case 5:
3246+
case 4:
3247+
case 3:
3248+
convert_to_string_ex(reqdata);
3249+
lreqdata.bv_val = Z_STRVAL_P(reqdata);
3250+
lreqdata.bv_len = Z_STRLEN_P(reqdata);
3251+
/* fallthru */
3252+
case 2:
3253+
convert_to_string_ex(reqoid);
3254+
lreqoid = Z_STRVAL_P(reqoid);
3255+
}
3256+
3257+
if (myargcount > 3) {
3258+
/* synchronous call */
3259+
rc = ldap_extended_operation_s(ld->link, lreqoid,
3260+
lreqdata.bv_len > 0 ? &lreqdata: NULL,
3261+
NULL,
3262+
NULL,
3263+
myargcount > 4 ? &lretoid : NULL,
3264+
&lretdata );
3265+
if (rc != LDAP_SUCCESS ) {
3266+
php_error_docref(NULL, E_WARNING, "Extended operation %s failed: %s (%d)", lreqoid, ldap_err2string(rc), rc);
3267+
RETURN_FALSE;
3268+
}
3269+
3270+
/* Reverse -> fall through */
3271+
switch (myargcount) {
3272+
case 5:
3273+
zval_dtor(retoid);
3274+
if (lretoid == NULL) {
3275+
ZVAL_EMPTY_STRING(retoid);
3276+
} else {
3277+
ZVAL_STRING(retoid, lretoid);
3278+
ldap_memfree(lretoid);
3279+
}
3280+
case 4:
3281+
/* use arg #4 as the data returned by the server */
3282+
zval_dtor(retdata);
3283+
if (lretdata == NULL) {
3284+
ZVAL_EMPTY_STRING(retdata);
3285+
} else {
3286+
ZVAL_STRINGL(retdata, lretdata->bv_val, lretdata->bv_len);
3287+
ldap_memfree(lretdata->bv_val);
3288+
ldap_memfree(lretdata);
3289+
}
3290+
}
3291+
3292+
RETURN_TRUE;
3293+
}
3294+
3295+
/* asynchronous call */
3296+
rc = ldap_extended_operation(ld->link, lreqoid,
3297+
lreqdata.bv_len > 0 ? &lreqdata: NULL,
3298+
NULL, NULL, &msgid);
3299+
if (rc != LDAP_SUCCESS ) {
3300+
php_error_docref(NULL, E_WARNING, "Extended operation %s failed: %s (%d)", lreqoid, ldap_err2string(rc), rc);
3301+
RETURN_FALSE;
3302+
}
3303+
3304+
rc = ldap_result(ld->link, msgid, 1 /* LDAP_MSG_ALL */, NULL, &ldap_res);
3305+
if (rc == -1) {
3306+
php_error_docref(NULL, E_WARNING, "Extended operation %s failed", lreqoid);
3307+
RETURN_FALSE;
3308+
}
3309+
3310+
/* return a PHP control object */
3311+
RETVAL_RES(zend_register_resource(ldap_res, le_result));
3312+
}
3313+
/* }}} */
3314+
#endif
3315+
3316+
#ifdef HAVE_LDAP_PASSWD_S
3317+
/* {{{ proto bool|string ldap_exop_passwd(resource link [, string user [, string oldpw [, string newpw ]]])
3318+
Passwd modify extended operation */
3319+
PHP_FUNCTION(ldap_exop_passwd)
3320+
{
3321+
zval *link, *user, *newpw, *oldpw;
3322+
struct berval luser, loldpw, lnewpw, lgenpasswd;
3323+
ldap_linkdata *ld;
3324+
int rc, myargcount = ZEND_NUM_ARGS();
3325+
3326+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|zzz", &link, &user, &oldpw, &newpw) == FAILURE) {
3327+
WRONG_PARAM_COUNT;
3328+
}
3329+
3330+
if ((ld = (ldap_linkdata *)zend_fetch_resource(Z_RES_P(link), "ldap link", le_link)) == NULL) {
3331+
RETURN_FALSE;
3332+
}
3333+
3334+
luser.bv_len = 0;
3335+
loldpw.bv_len = 0;
3336+
lnewpw.bv_len = 0;
3337+
3338+
switch (myargcount) {
3339+
case 4:
3340+
convert_to_string_ex(newpw);
3341+
lnewpw.bv_val = Z_STRVAL_P(newpw);
3342+
lnewpw.bv_len = Z_STRLEN_P(newpw);
3343+
3344+
case 3:
3345+
convert_to_string_ex(oldpw);
3346+
loldpw.bv_val = Z_STRVAL_P(oldpw);
3347+
loldpw.bv_len = Z_STRLEN_P(oldpw);
3348+
3349+
case 2:
3350+
convert_to_string_ex(user);
3351+
luser.bv_val = Z_STRVAL_P(user);
3352+
luser.bv_len = Z_STRLEN_P(user);
3353+
}
3354+
3355+
/* synchronous call */
3356+
rc = ldap_passwd_s(ld->link, &luser,
3357+
loldpw.bv_len > 0 ? &loldpw : NULL,
3358+
lnewpw.bv_len > 0 ? &lnewpw : NULL,
3359+
&lgenpasswd, NULL, NULL);
3360+
if (rc != LDAP_SUCCESS ) {
3361+
php_error_docref(NULL, E_WARNING, "Passwd modify extended operation failed: %s (%d)", ldap_err2string(rc), rc);
3362+
RETURN_FALSE;
3363+
}
3364+
3365+
if (lnewpw.bv_len == 0) {
3366+
if (lgenpasswd.bv_len == 0) {
3367+
RETVAL_EMPTY_STRING();
3368+
} else {
3369+
RETVAL_STRINGL(lgenpasswd.bv_val, lgenpasswd.bv_len);
3370+
}
3371+
} else {
3372+
RETURN_TRUE;
3373+
}
3374+
3375+
ldap_memfree(lgenpasswd.bv_val);
3376+
}
3377+
/* }}} */
3378+
#endif
3379+
3380+
#ifdef HAVE_LDAP_WHOAMI_S
3381+
/* {{{ proto bool|string ldap_exop_whoami(resource link)
3382+
Whoami extended operation */
3383+
PHP_FUNCTION(ldap_exop_whoami)
3384+
{
3385+
zval *link;
3386+
struct berval *lauthzid;
3387+
ldap_linkdata *ld;
3388+
int rc, myargcount = ZEND_NUM_ARGS();
3389+
3390+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &link) == FAILURE) {
3391+
WRONG_PARAM_COUNT;
3392+
}
3393+
3394+
if ((ld = (ldap_linkdata *)zend_fetch_resource(Z_RES_P(link), "ldap link", le_link)) == NULL) {
3395+
RETURN_FALSE;
3396+
}
3397+
3398+
/* synchronous call */
3399+
rc = ldap_whoami_s(ld->link, &lauthzid, NULL, NULL);
3400+
if (rc != LDAP_SUCCESS ) {
3401+
php_error_docref(NULL, E_WARNING, "Whoami extended operation failed: %s (%d)", ldap_err2string(rc), rc);
3402+
RETURN_FALSE;
3403+
}
3404+
3405+
if (lauthzid == NULL) {
3406+
RETVAL_EMPTY_STRING();
3407+
} else {
3408+
RETVAL_STRINGL(lauthzid->bv_val, lauthzid->bv_len);
3409+
ldap_memfree(lauthzid->bv_val);
3410+
ldap_memfree(lauthzid);
3411+
}
3412+
}
3413+
/* }}} */
3414+
#endif
3415+
/* }}} */
3416+
3417+
/* }}} */
3418+
31533419
/* {{{ arginfo */
31543420
ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_connect, 0, 0, 0)
31553421
ZEND_ARG_INFO(0, hostname)
@@ -3425,6 +3691,40 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_8859_to_t61, 0, 0, 1)
34253691
ZEND_ARG_INFO(0, value)
34263692
ZEND_END_ARG_INFO()
34273693
#endif
3694+
3695+
#ifdef HAVE_LDAP_EXTENDED_OPERATION_S
3696+
ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_exop, 0, 0, 5)
3697+
ZEND_ARG_INFO(0, link)
3698+
ZEND_ARG_INFO(0, reqoid)
3699+
ZEND_ARG_INFO(0, reqdata)
3700+
ZEND_ARG_INFO(1, retdata)
3701+
ZEND_ARG_INFO(1, retoid)
3702+
ZEND_END_ARG_INFO()
3703+
#endif
3704+
3705+
#ifdef HAVE_LDAP_PASSWD_S
3706+
ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_exop_passwd, 0, 0, 4)
3707+
ZEND_ARG_INFO(0, link)
3708+
ZEND_ARG_INFO(0, user)
3709+
ZEND_ARG_INFO(0, oldpw)
3710+
ZEND_ARG_INFO(0, newpw)
3711+
ZEND_END_ARG_INFO()
3712+
#endif
3713+
3714+
#ifdef HAVE_LDAP_WHOAMI_S
3715+
ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_exop_whoami, 0, 0, 1)
3716+
ZEND_ARG_INFO(0, link)
3717+
ZEND_END_ARG_INFO()
3718+
#endif
3719+
3720+
#ifdef HAVE_LDAP_PARSE_EXTENDED_RESULT
3721+
ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_parse_exop, 0, 0, 4)
3722+
ZEND_ARG_INFO(0, link)
3723+
ZEND_ARG_INFO(0, result)
3724+
ZEND_ARG_INFO(1, retdata)
3725+
ZEND_ARG_INFO(1, retoid)
3726+
ZEND_END_ARG_INFO()
3727+
#endif
34283728
/* }}} */
34293729

34303730
/*
@@ -3489,6 +3789,18 @@ const zend_function_entry ldap_functions[] = {
34893789
#ifdef HAVE_LDAP_START_TLS_S
34903790
PHP_FE(ldap_start_tls, arginfo_ldap_resource)
34913791
#endif
3792+
#ifdef HAVE_LDAP_EXTENDED_OPERATION_S
3793+
PHP_FE(ldap_exop, arginfo_ldap_exop)
3794+
#endif
3795+
#ifdef HAVE_LDAP_PASSWD_S
3796+
PHP_FE(ldap_exop_passwd, arginfo_ldap_exop_passwd)
3797+
#endif
3798+
#ifdef HAVE_LDAP_WHOAMI_S
3799+
PHP_FE(ldap_exop_whoami, arginfo_ldap_exop_whoami)
3800+
#endif
3801+
#ifdef HAVE_LDAP_PARSE_EXTENDED_RESULT
3802+
PHP_FE(ldap_parse_exop, arginfo_ldap_parse_exop)
3803+
#endif
34923804
#endif
34933805

34943806
#if defined(LDAP_API_FEATURE_X_OPENLDAP) && defined(HAVE_3ARG_SETREBINDPROC)

ext/ldap/tests/connect.inc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@ function ldap_connect_and_bind($host, $port, $user, $passwd, $protocol_version)
2121
return $link;
2222
}
2323

24+
function test_bind($host, $port, $user, $passwd, $protocol_version) {
25+
$link = ldap_connect($host, $port);
26+
ldap_set_option($link, LDAP_OPT_PROTOCOL_VERSION, $protocol_version);
27+
return ldap_bind($link, $user, $passwd);
28+
}
29+
2430
function insert_dummy_data($link, $base) {
2531
// Create root if not there
2632
$testBase = ldap_read($link, $base, '(objectClass=*)', array('objectClass'));

0 commit comments

Comments
 (0)