ITS #2121 submitted by Dave Steck <dsteck@novell.com> with minor changes.

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
This commit is contained in:
Kurt Zeilenga 2002-10-02 19:14:02 +00:00
parent 5b591d0dec
commit 491e75548c
6 changed files with 100 additions and 11 deletions

View file

@ -108,8 +108,9 @@ LDAP_BEGIN_DECL
#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

View file

@ -161,6 +161,7 @@ ldap_err2string( int err )
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 );
@ -187,6 +188,13 @@ ldap_perror( LDAP *ld, LDAP_CONST char *str )
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 );
}
@ -282,6 +290,10 @@ ldap_parse_result(
LDAP_FREE( ld->ld_matched );
ld->ld_matched = NULL;
}
if ( ld->ld_referrals ) {
LDAP_VFREE( ld->ld_referrals );
ld->ld_referrals = NULL;
}
/* parse results */
@ -298,13 +310,7 @@ ldap_parse_result(
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 );
}
}
@ -366,6 +372,10 @@ ldap_parse_result(
*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 */

View file

@ -175,3 +175,39 @@ ldap_value_free_len( struct berval **vals )
{
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;
}

View file

@ -295,6 +295,7 @@ struct ldap {
ber_int_t ld_errno;
char *ld_error;
char *ld_matched;
char **ld_referrals;
ber_len_t ld_msgid;
/* do not mess with these */
@ -574,6 +575,12 @@ LDAP_F (int) ldap_int_tls_config LDAP_P(( LDAP *ld,
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 */

View file

@ -250,6 +250,20 @@ ldap_get_option(
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;
@ -316,8 +330,9 @@ ldap_set_option(
* 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);
@ -573,6 +588,21 @@ ldap_set_option(
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;
@ -584,7 +614,7 @@ ldap_set_option(
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 )

View file

@ -110,6 +110,11 @@ ldap_ld_free(
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;