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:
*/
/* 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 */
};
#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
#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 */
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) {
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;
+}
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
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;