mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-12-21 15:19:34 -05:00
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:
parent
5b591d0dec
commit
491e75548c
6 changed files with 100 additions and 11 deletions
|
|
@ -108,8 +108,9 @@ LDAP_BEGIN_DECL
|
||||||
#define LDAP_OPT_DEBUG_LEVEL 0x5001 /* debug level */
|
#define LDAP_OPT_DEBUG_LEVEL 0x5001 /* debug level */
|
||||||
#define LDAP_OPT_TIMEOUT 0x5002 /* default timeout */
|
#define LDAP_OPT_TIMEOUT 0x5002 /* default timeout */
|
||||||
#define LDAP_OPT_REFHOPLIMIT 0x5003 /* ref hop limit */
|
#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_URI 0x5006
|
||||||
|
#define LDAP_OPT_REFERRAL_URLS 0x5007 /* Referral URLs */
|
||||||
|
|
||||||
/* OpenLDAP TLS options */
|
/* OpenLDAP TLS options */
|
||||||
#define LDAP_OPT_X_TLS 0x6000
|
#define LDAP_OPT_X_TLS 0x6000
|
||||||
|
|
|
||||||
|
|
@ -161,6 +161,7 @@ ldap_err2string( int err )
|
||||||
void
|
void
|
||||||
ldap_perror( LDAP *ld, LDAP_CONST char *str )
|
ldap_perror( LDAP *ld, LDAP_CONST char *str )
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
const struct ldaperror *e;
|
const struct ldaperror *e;
|
||||||
#ifdef NEW_LOGGING
|
#ifdef NEW_LOGGING
|
||||||
LDAP_LOG ( OPERATION, ENTRY, "ldap_perror\n", 0,0,0 );
|
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 );
|
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 );
|
fflush( stderr );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -282,6 +290,10 @@ ldap_parse_result(
|
||||||
LDAP_FREE( ld->ld_matched );
|
LDAP_FREE( ld->ld_matched );
|
||||||
ld->ld_matched = NULL;
|
ld->ld_matched = NULL;
|
||||||
}
|
}
|
||||||
|
if ( ld->ld_referrals ) {
|
||||||
|
LDAP_VFREE( ld->ld_referrals );
|
||||||
|
ld->ld_referrals = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* parse results */
|
/* parse results */
|
||||||
|
|
||||||
|
|
@ -298,13 +310,7 @@ ldap_parse_result(
|
||||||
if( tag != LBER_ERROR ) {
|
if( tag != LBER_ERROR ) {
|
||||||
/* peek for referrals */
|
/* peek for referrals */
|
||||||
if( ber_peek_tag(ber, &len) == LDAP_TAG_REFERRAL ) {
|
if( ber_peek_tag(ber, &len) == LDAP_TAG_REFERRAL ) {
|
||||||
if( referralsp != NULL ) {
|
tag = ber_scanf( ber, "v", &ld->ld_referrals );
|
||||||
tag = ber_scanf( ber, "v", referralsp );
|
|
||||||
|
|
||||||
} else {
|
|
||||||
/* no place to put them so skip 'em */
|
|
||||||
tag = ber_scanf( ber, "x" );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -366,6 +372,10 @@ ldap_parse_result(
|
||||||
*errmsgp = LDAP_STRDUP( ld->ld_error );
|
*errmsgp = LDAP_STRDUP( ld->ld_error );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( referralsp != NULL) {
|
||||||
|
*referralsp = ldap_value_dup( ld->ld_referrals );
|
||||||
|
}
|
||||||
|
|
||||||
/* Find the next result... */
|
/* Find the next result... */
|
||||||
for ( lm = lm->lm_chain; lm != NULL; lm = lm->lm_chain ) {
|
for ( lm = lm->lm_chain; lm != NULL; lm = lm->lm_chain ) {
|
||||||
/* skip over entries and references */
|
/* skip over entries and references */
|
||||||
|
|
|
||||||
|
|
@ -175,3 +175,39 @@ ldap_value_free_len( struct berval **vals )
|
||||||
{
|
{
|
||||||
ber_bvecfree( 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -295,6 +295,7 @@ struct ldap {
|
||||||
ber_int_t ld_errno;
|
ber_int_t ld_errno;
|
||||||
char *ld_error;
|
char *ld_error;
|
||||||
char *ld_matched;
|
char *ld_matched;
|
||||||
|
char **ld_referrals;
|
||||||
ber_len_t ld_msgid;
|
ber_len_t ld_msgid;
|
||||||
|
|
||||||
/* do not mess with these */
|
/* 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,
|
LDAP_F (int) ldap_int_tls_start LDAP_P(( LDAP *ld,
|
||||||
LDAPConn *conn, LDAPURLDesc *srv ));
|
LDAPConn *conn, LDAPURLDesc *srv ));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* in getvalues.c
|
||||||
|
*/
|
||||||
|
LDAP_F (char **) ldap_value_dup LDAP_P((
|
||||||
|
char *const *vals ));
|
||||||
|
|
||||||
LDAP_END_DECL
|
LDAP_END_DECL
|
||||||
|
|
||||||
#endif /* _LDAP_INT_H */
|
#endif /* _LDAP_INT_H */
|
||||||
|
|
|
||||||
|
|
@ -250,6 +250,20 @@ ldap_get_option(
|
||||||
|
|
||||||
return LDAP_OPT_SUCCESS;
|
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: {
|
case LDAP_OPT_API_FEATURE_INFO: {
|
||||||
LDAPAPIFeatureInfo *info = (LDAPAPIFeatureInfo *) outvalue;
|
LDAPAPIFeatureInfo *info = (LDAPAPIFeatureInfo *) outvalue;
|
||||||
int i;
|
int i;
|
||||||
|
|
@ -316,8 +330,9 @@ ldap_set_option(
|
||||||
* problem. Thus, we introduce a fix here.
|
* problem. Thus, we introduce a fix here.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (option == LDAP_OPT_DEBUG_LEVEL)
|
if (option == LDAP_OPT_DEBUG_LEVEL) {
|
||||||
dbglvl = (int *) invalue;
|
dbglvl = (int *) invalue;
|
||||||
|
}
|
||||||
|
|
||||||
if( lo->ldo_valid != LDAP_INITIALIZED ) {
|
if( lo->ldo_valid != LDAP_INITIALIZED ) {
|
||||||
ldap_int_initialize(lo, dbglvl);
|
ldap_int_initialize(lo, dbglvl);
|
||||||
|
|
@ -573,6 +588,21 @@ ldap_set_option(
|
||||||
ld->ld_matched = LDAP_STRDUP(err);
|
ld->ld_matched = LDAP_STRDUP(err);
|
||||||
} return LDAP_OPT_SUCCESS;
|
} 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:
|
case LDAP_OPT_API_FEATURE_INFO:
|
||||||
/* read-only */
|
/* read-only */
|
||||||
break;
|
break;
|
||||||
|
|
@ -584,7 +614,7 @@ ldap_set_option(
|
||||||
default:
|
default:
|
||||||
#ifdef HAVE_TLS
|
#ifdef HAVE_TLS
|
||||||
if ( ldap_pvt_tls_set_option( ld, option, (void *)invalue ) == 0 )
|
if ( ldap_pvt_tls_set_option( ld, option, (void *)invalue ) == 0 )
|
||||||
return LDAP_OPT_SUCCESS;
|
return LDAP_OPT_SUCCESS;
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_CYRUS_SASL
|
#ifdef HAVE_CYRUS_SASL
|
||||||
if ( ldap_int_sasl_set_option( ld, option, (void *)invalue ) == 0 )
|
if ( ldap_int_sasl_set_option( ld, option, (void *)invalue ) == 0 )
|
||||||
|
|
|
||||||
|
|
@ -110,6 +110,11 @@ ldap_ld_free(
|
||||||
ld->ld_matched = NULL;
|
ld->ld_matched = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( ld->ld_referrals != NULL) {
|
||||||
|
LDAP_VFREE(ld->ld_referrals);
|
||||||
|
ld->ld_referrals = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if ( ld->ld_abandoned != NULL ) {
|
if ( ld->ld_abandoned != NULL ) {
|
||||||
LDAP_FREE( ld->ld_abandoned );
|
LDAP_FREE( ld->ld_abandoned );
|
||||||
ld->ld_abandoned = NULL;
|
ld->ld_abandoned = NULL;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue