From: Kurt Zeilenga Date: Wed, 2 Oct 2002 19:14:02 +0000 (+0000) Subject: ITS #2121 submitted by Dave Steck with minor changes. X-Git-Tag: NO_SLAP_OP_BLOCKS~933 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=491e75548c0e09c60bcb09bc8a1e67e57f800088;p=openldap ITS #2121 submitted by Dave Steck 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 --- diff --git a/include/ldap.h b/include/ldap.h index 5f7f8ab407..626e03746d 100644 --- a/include/ldap.h +++ b/include/ldap.h @@ -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 diff --git a/libraries/libldap/error.c b/libraries/libldap/error.c index 45f9eec86e..7aa9d46667 100644 --- a/libraries/libldap/error.c +++ b/libraries/libldap/error.c @@ -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 */ diff --git a/libraries/libldap/getvalues.c b/libraries/libldap/getvalues.c index 34ee28da56..43e159f190 100644 --- a/libraries/libldap/getvalues.c +++ b/libraries/libldap/getvalues.c @@ -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; +} + diff --git a/libraries/libldap/ldap-int.h b/libraries/libldap/ldap-int.h index 01fe78bac1..b0c2bd9361 100644 --- a/libraries/libldap/ldap-int.h +++ b/libraries/libldap/ldap-int.h @@ -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 */ diff --git a/libraries/libldap/options.c b/libraries/libldap/options.c index 45ceae125f..45ec0e5f75 100644 --- a/libraries/libldap/options.c +++ b/libraries/libldap/options.c @@ -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 ) diff --git a/libraries/libldap/unbind.c b/libraries/libldap/unbind.c index 45b77f6528..e09ef637be 100644 --- a/libraries/libldap/unbind.c +++ b/libraries/libldap/unbind.c @@ -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;