]> git.sur5r.net Git - openldap/commitdiff
ITS #2121 submitted by Dave Steck <dsteck@novell.com> with minor changes.
authorKurt Zeilenga <kurt@openldap.org>
Wed, 2 Oct 2002 19:14:02 +0000 (19:14 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Wed, 2 Oct 2002 19:14:02 +0000 (19:14 +0000)
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

include/ldap.h
libraries/libldap/error.c
libraries/libldap/getvalues.c
libraries/libldap/ldap-int.h
libraries/libldap/options.c
libraries/libldap/unbind.c

index 5f7f8ab4074e865680e97716a3ab2959d56f435b..626e03746d2218fbe34dccc4c83f70d36777a7f8 100644 (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
index 45f9eec86e4a8542766b7064a11d6c324ea5ce90..7aa9d4666701341d7585a3e20467c186e77a9751 100644 (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 */
index 34ee28da563a40a9706cf1aca713aaea49f2dd3d..43e159f1903818d61e64e1ff964ca461b6405947 100644 (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;
+}
+
index 01fe78bac11cae779cf74593372d9fef0b986b4e..b0c2bd93614cfe0bdbe4c161d74212f5a16be2c6 100644 (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 */
index 45ceae125f6e12c7cb2546da522ad39d53be056a..45ec0e5f75e2480a9aa086a63b685c9676ed8ffa 100644 (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 )
index 45b77f65281a421d0015b702471885f4ada0399f..e09ef637bec0e6f9d8b9db19bc48343b8cedb3ef 100644 (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;