From: Pierangelo Masarati Date: Sat, 28 May 2005 14:29:08 +0000 (+0000) Subject: allow to muck with referrals while chasing... X-Git-Tag: OPENLDAP_AC_BP~593 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=eb005a987208ebd7409a9837a6e5880f04e74d64;p=openldap allow to muck with referrals while chasing... --- diff --git a/include/ldap.h b/include/ldap.h index 833c486fbd..2c5adba328 100644 --- a/include/ldap.h +++ b/include/ldap.h @@ -726,6 +726,17 @@ ldap_set_rebind_proc LDAP_P(( LDAP_REBIND_PROC *rebind_proc, void *params )); +/* V3 referral selection Function Callback Prototype */ +typedef int (LDAP_NEXTREF_PROC) LDAP_P(( + LDAP *ld, char ***refsp, int *cntp, + void *params )); + +LDAP_F( int ) +ldap_set_nextref_proc LDAP_P(( + LDAP *ld, + LDAP_NEXTREF_PROC *nextref_proc, + void *params )); + /* * in controls.c: */ diff --git a/libraries/libldap/ldap-int.h b/libraries/libldap/ldap-int.h index 593f1060cd..504b5d5b35 100644 --- a/libraries/libldap/ldap-int.h +++ b/libraries/libldap/ldap-int.h @@ -198,6 +198,8 @@ struct ldapoptions { /* LDAP rebind callback function */ LDAP_REBIND_PROC *ldo_rebind_proc; void *ldo_rebind_params; + LDAP_NEXTREF_PROC *ldo_nextref_proc; + void *ldo_nextref_params; LDAP_BOOLEANS ldo_booleans; /* boolean options */ }; @@ -311,8 +313,10 @@ struct ldap { #define ld_sctrls ld_options.ldo_sctrls #define ld_cctrls ld_options.ldo_cctrls -#define ld_rebind_proc ld_options.ldo_rebind_proc +#define ld_rebind_proc ld_options.ldo_rebind_proc #define ld_rebind_params ld_options.ldo_rebind_params +#define ld_nextref_proc ld_options.ldo_nextref_proc +#define ld_nextref_params ld_options.ldo_nextref_params #define ld_version ld_options.ldo_version diff --git a/libraries/libldap/options.c b/libraries/libldap/options.c index fae53f0f21..6f678680cf 100644 --- a/libraries/libldap/options.c +++ b/libraries/libldap/options.c @@ -28,6 +28,9 @@ #define LDAP_OPT_REBIND_PROC 0x4e814d #define LDAP_OPT_REBIND_PARAMS 0x4e814e +#define LDAP_OPT_NEXTREF_PROC 0x4e815d +#define LDAP_OPT_NEXTREF_PARAMS 0x4e815e + static const LDAPAPIFeatureInfo features[] = { #ifdef LDAP_API_FEATURE_X_OPENLDAP { /* OpenLDAP Extensions API Feature */ @@ -454,6 +457,14 @@ ldap_set_option( case LDAP_OPT_REBIND_PARAMS: { lo->ldo_rebind_params = (void *)invalue; } return LDAP_OPT_SUCCESS; + + /* Only accessed from inside this function by ldap_set_nextref_proc() */ + case LDAP_OPT_NEXTREF_PROC: { + lo->ldo_nextref_proc = (LDAP_NEXTREF_PROC *)invalue; + } return LDAP_OPT_SUCCESS; + case LDAP_OPT_NEXTREF_PARAMS: { + lo->ldo_nextref_params = (void *)invalue; + } return LDAP_OPT_SUCCESS; } if(invalue == NULL) { @@ -670,3 +681,14 @@ ldap_set_rebind_proc( LDAP *ld, LDAP_REBIND_PROC *proc, void *params ) rc = ldap_set_option( ld, LDAP_OPT_REBIND_PARAMS, (void *)params ); return rc; } + +int +ldap_set_nextref_proc( LDAP *ld, LDAP_NEXTREF_PROC *proc, void *params ) +{ + int rc; + rc = ldap_set_option( ld, LDAP_OPT_NEXTREF_PROC, (void *)proc ); + if( rc != LDAP_OPT_SUCCESS ) return rc; + + rc = ldap_set_option( ld, LDAP_OPT_NEXTREF_PARAMS, (void *)params ); + return rc; +} diff --git a/libraries/libldap/request.c b/libraries/libldap/request.c index 41caa7f7b5..089bf61cbe 100644 --- a/libraries/libldap/request.c +++ b/libraries/libldap/request.c @@ -657,6 +657,36 @@ ldap_free_request( LDAP *ld, LDAPRequest *lr ) ldap_free_request_int( ld, lr ); } +/* + * call first time with *cntp = -1 + * when returns *cntp == -1, no referrals are left + * + * NOTE: may replace *refsp, or shuffle the contents + * of the original array. + */ +static int ldap_int_nextref( + LDAP *ld, + char ***refsp, + int *cntp, + void *params ) +{ + assert( refsp != NULL ); + assert( *refsp != NULL ); + assert( cntp != NULL ); + + if ( *cntp < -1 ) { + *cntp = -1; + return -1; + } + + (*cntp)++; + + if ( (*refsp)[ *cntp ] == NULL ) { + *cntp = -1; + } + + return 0; +} /* * Chase v3 referrals @@ -718,8 +748,18 @@ ldap_chase_v3referrals( LDAP *ld, LDAPRequest *lr, char **refs, int sref, char * refarray = refs; refs = NULL; + + if ( ld->ld_nextref_proc == NULL ) { + ld->ld_nextref_proc = ldap_int_nextref; + } + /* parse out & follow referrals */ - for( i=0; refarray[i] != NULL; i++) { + i = -1; + for ( ld->ld_nextref_proc( ld, &refarray, &i, ld->ld_nextref_params ); + i != -1; + ld->ld_nextref_proc( ld, &refarray, &i, ld->ld_nextref_params ) ) + { + /* Parse the referral URL */ if (( rc = ldap_url_parse_ext( refarray[i], &srv)) != LDAP_SUCCESS) { ld->ld_errno = rc;