Patch to allow referrals to be read on synchronous non-search operations.
Treat referrals the same way as MatchDN or ErrorString values.
Store them in the ld structure and provide an option for ldap_get_option
to retrieve them
#define LDAP_OPT_DEBUG_LEVEL 0x5001 /* debug level */
#define LDAP_OPT_TIMEOUT 0x5002 /* default timeout */
#define LDAP_OPT_REFHOPLIMIT 0x5003 /* ref hop limit */
-#define LDAP_OPT_NETWORK_TIMEOUT 0x5005 /* socket level timeout */
+#define LDAP_OPT_NETWORK_TIMEOUT 0x5005 /* socket level timeout */
#define LDAP_OPT_URI 0x5006
+#define LDAP_OPT_REFERRAL_URLS 0x5007 /* Referral URLs */
/* OpenLDAP TLS options */
#define LDAP_OPT_X_TLS 0x6000
void
ldap_perror( LDAP *ld, LDAP_CONST char *str )
{
+ int i;
const struct ldaperror *e;
#ifdef NEW_LOGGING
LDAP_LOG ( OPERATION, ENTRY, "ldap_perror\n", 0,0,0 );
fprintf( stderr, "\tadditional info: %s\n", ld->ld_error );
}
+ if ( ld->ld_referrals != NULL && ld->ld_referrals[0] != NULL) {
+ fprintf( stderr, "\treferrals:\n" );
+ for (i=0; ld->ld_referrals[i]; i++) {
+ fprintf( stderr, "\t\t%s\n", ld->ld_referrals[i] );
+ }
+ }
+
fflush( stderr );
}
LDAP_FREE( ld->ld_matched );
ld->ld_matched = NULL;
}
+ if ( ld->ld_referrals ) {
+ LDAP_VFREE( ld->ld_referrals );
+ ld->ld_referrals = NULL;
+ }
/* parse results */
if( tag != LBER_ERROR ) {
/* peek for referrals */
if( ber_peek_tag(ber, &len) == LDAP_TAG_REFERRAL ) {
- if( referralsp != NULL ) {
- tag = ber_scanf( ber, "v", referralsp );
-
- } else {
- /* no place to put them so skip 'em */
- tag = ber_scanf( ber, "x" );
- }
+ tag = ber_scanf( ber, "v", &ld->ld_referrals );
}
}
*errmsgp = LDAP_STRDUP( ld->ld_error );
}
+ if( referralsp != NULL) {
+ *referralsp = ldap_value_dup( ld->ld_referrals );
+ }
+
/* Find the next result... */
for ( lm = lm->lm_chain; lm != NULL; lm = lm->lm_chain ) {
/* skip over entries and references */
{
ber_bvecfree( vals );
}
+
+char **
+ldap_value_dup( char *const *vals )
+{
+ char **new;
+ int i;
+
+ if( vals == NULL ) {
+ return NULL;
+ }
+
+ for( i=0; vals[i]; i++ ) {
+ ; /* Count the number of values */
+ }
+
+ if( i == 0 ) {
+ return NULL;
+ }
+
+ new = LDAP_MALLOC( (i+1)*sizeof(char *) ); /* Alloc array of pointers */
+ if( new == NULL ) {
+ return NULL;
+ }
+
+ for( i=0; vals[i]; i++ ) {
+ new[i] = LDAP_STRDUP( vals[i] ); /* Dup each value */
+ if( new[i] == NULL ) {
+ LDAP_VFREE( new );
+ return NULL;
+ }
+ }
+ new[i] = NULL;
+
+ return new;
+}
+
ber_int_t ld_errno;
char *ld_error;
char *ld_matched;
+ char **ld_referrals;
ber_len_t ld_msgid;
/* do not mess with these */
LDAP_F (int) ldap_int_tls_start LDAP_P(( LDAP *ld,
LDAPConn *conn, LDAPURLDesc *srv ));
+/*
+ * in getvalues.c
+ */
+LDAP_F (char **) ldap_value_dup LDAP_P((
+ char *const *vals ));
+
LDAP_END_DECL
#endif /* _LDAP_INT_H */
return LDAP_OPT_SUCCESS;
+ case LDAP_OPT_REFERRAL_URLS:
+ if(ld == NULL) {
+ /* bad param */
+ break;
+ }
+
+ if( ld->ld_referrals == NULL ) {
+ * (char ***) outvalue = NULL;
+ } else {
+ * (char ***) outvalue = ldap_value_dup(ld->ld_referrals);
+ }
+
+ return LDAP_OPT_SUCCESS;
+
case LDAP_OPT_API_FEATURE_INFO: {
LDAPAPIFeatureInfo *info = (LDAPAPIFeatureInfo *) outvalue;
int i;
* problem. Thus, we introduce a fix here.
*/
- if (option == LDAP_OPT_DEBUG_LEVEL)
- dbglvl = (int *) invalue;
+ if (option == LDAP_OPT_DEBUG_LEVEL) {
+ dbglvl = (int *) invalue;
+ }
if( lo->ldo_valid != LDAP_INITIALIZED ) {
ldap_int_initialize(lo, dbglvl);
ld->ld_matched = LDAP_STRDUP(err);
} return LDAP_OPT_SUCCESS;
+ case LDAP_OPT_REFERRAL_URLS: {
+ char *const *referrals = (char *const *) invalue;
+
+ if(ld == NULL) {
+ /* need a struct ldap */
+ break;
+ }
+
+ if( ld->ld_referrals ) {
+ LDAP_VFREE(ld->ld_referrals);
+ }
+
+ ld->ld_referrals = ldap_value_dup(referrals);
+ } return LDAP_OPT_SUCCESS;
+
case LDAP_OPT_API_FEATURE_INFO:
/* read-only */
break;
default:
#ifdef HAVE_TLS
if ( ldap_pvt_tls_set_option( ld, option, (void *)invalue ) == 0 )
- return LDAP_OPT_SUCCESS;
+ return LDAP_OPT_SUCCESS;
#endif
#ifdef HAVE_CYRUS_SASL
if ( ldap_int_sasl_set_option( ld, option, (void *)invalue ) == 0 )
ld->ld_matched = NULL;
}
+ if( ld->ld_referrals != NULL) {
+ LDAP_VFREE(ld->ld_referrals);
+ ld->ld_referrals = NULL;
+ }
+
if ( ld->ld_abandoned != NULL ) {
LDAP_FREE( ld->ld_abandoned );
ld->ld_abandoned = NULL;