]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/referral.c
Don't use 'shtool mkln' as ln(1) replacement.
[openldap] / servers / slapd / referral.c
index 178761ee7a3d75794d09458ac743be2cff7ca99c..1293c32a354951aa2c58b5b4b88b9f7a85925ad5 100644 (file)
@@ -1,7 +1,7 @@
 /* referral.c - muck with referrals */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2001 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -17,6 +17,8 @@
 #include <ac/time.h>
 #include <ac/unistd.h>
 
+#include <ldap_pvt.h>
+
 #include "slap.h"
 
 /*
@@ -28,10 +30,11 @@ static char * referral_dn_muck(
        const char * baseDN,
        const char * targetDN )
 {
-       char *tmp;
-       char *nrefDN = NULL;
-       char *nbaseDN = NULL;
-       char *ntargetDN = NULL;
+       int rc;
+       struct berval bvin;
+       struct berval nrefDN = { 0, NULL };
+       struct berval nbaseDN = { 0, NULL };
+       struct berval ntargetDN = { 0, NULL };
 
        if( !baseDN ) {
                /* no base, return target */
@@ -39,10 +42,12 @@ static char * referral_dn_muck(
        }
 
        if( refDN ) {
-               nrefDN = dn_validate( tmp = ch_strdup( refDN ) );
-               if( !nrefDN ) {
+               bvin.bv_val = (char *)refDN;
+               bvin.bv_len = strlen( refDN );
+
+               rc = dnPretty2( NULL, &bvin, &nrefDN );
+               if( rc != LDAP_SUCCESS ) {
                        /* Invalid refDN */
-                       ch_free( tmp );
                        return NULL;
                }
        }
@@ -52,71 +57,74 @@ static char * referral_dn_muck(
                 *      if refDN present return refDN
                 *  else return baseDN
                 */
-               return nrefDN ? nrefDN : ch_strdup( baseDN );
+               return nrefDN.bv_len ? nrefDN.bv_val : ch_strdup( baseDN );
        }
 
-       ntargetDN = dn_validate( tmp = ch_strdup( targetDN ) );
-       if( !ntargetDN ) {
-               ch_free( tmp );
-               ch_free( nrefDN );
+       bvin.bv_val = (char *)targetDN;
+       bvin.bv_len = strlen( targetDN );
+
+       rc = dnPretty2( NULL, &bvin, &ntargetDN );
+       if( rc != LDAP_SUCCESS ) {
+               /* Invalid targetDN */
+               ch_free( nrefDN.bv_val );
                return NULL;
        }
 
-       if( nrefDN ) {
-               nbaseDN = dn_validate( tmp = ch_strdup( baseDN ) );
-               if( !nbaseDN ) {
+       if( nrefDN.bv_len ) {
+               bvin.bv_val = (char *)baseDN;
+               bvin.bv_len = strlen( baseDN );
+
+               rc = dnPretty2( NULL, &bvin, &nbaseDN );
+               if( rc != LDAP_SUCCESS ) {
                        /* Invalid baseDN */
-                       ch_free( ntargetDN );
-                       ch_free( nrefDN );
-                       ch_free( tmp );
+                       ch_free( nrefDN.bv_val );
+                       ch_free( ntargetDN.bv_val );
                        return NULL;
                }
 
-               if( strcasecmp( nbaseDN, nrefDN ) == 0 ) {
-                       ch_free( nrefDN );
-                       ch_free( nbaseDN );
-                       return ntargetDN;
+               if( dn_match( &nbaseDN, &nrefDN ) == 0 ) {
+                       ch_free( nrefDN.bv_val );
+                       ch_free( nbaseDN.bv_val );
+                       return ntargetDN.bv_val;
                }
 
                {
-                       /*
-                        * FIXME: string based mucking
-                        */
-                       char *muck;
-                       size_t reflen, baselen, targetlen, mucklen;
-
-                       reflen = strlen( nrefDN );
-                       baselen = strlen( nbaseDN );
-                       targetlen = strlen( ntargetDN );
-
-                       if( targetlen < baselen ) {
-                               ch_free( nrefDN );
-                               ch_free( nbaseDN );
-                               return ntargetDN;
+                       struct berval muck;
+
+                       if( ntargetDN.bv_len < nbaseDN.bv_len ) {
+                               ch_free( nrefDN.bv_val );
+                               ch_free( nbaseDN.bv_val );
+                               return ntargetDN.bv_val;
                        }
 
-                       if( strcasecmp( &ntargetDN[targetlen-baselen], nbaseDN ) ) {
+                       rc = strcasecmp(
+                               &ntargetDN.bv_val[ntargetDN.bv_len-nbaseDN.bv_len],
+                               nbaseDN.bv_val );
+                       if( rc ) {
                                /* target not subordinate to base */
-                               ch_free( nrefDN );
-                               ch_free( nbaseDN );
-                               return ntargetDN;
+                               ch_free( nrefDN.bv_val );
+                               ch_free( nbaseDN.bv_val );
+                               return ntargetDN.bv_val;
                        }
 
-                       mucklen = targetlen + reflen - baselen;
-                       muck = ch_malloc( 1 + mucklen );
+                       muck.bv_len = ntargetDN.bv_len + nrefDN.bv_len - nbaseDN.bv_len;
+                       muck.bv_val = ch_malloc( muck.bv_len + 1 );
 
-                       strncpy( muck, ntargetDN, targetlen-baselen );
-                       strcpy( &muck[targetlen-baselen], nrefDN );
+                       strncpy( muck.bv_val, ntargetDN.bv_val,
+                               ntargetDN.bv_len-nbaseDN.bv_len );
+                       strcpy( &muck.bv_val[ntargetDN.bv_len-nbaseDN.bv_len],
+                               nrefDN.bv_val );
 
-                       ch_free( nrefDN );
-                       ch_free( nbaseDN );
-                       ch_free( ntargetDN );
+                       ch_free( nrefDN.bv_val );
+                       ch_free( nbaseDN.bv_val );
+                       ch_free( ntargetDN.bv_val );
 
-                       return muck;
+                       return muck.bv_val;
                }
        }
 
-       return ntargetDN;
+       ch_free( nrefDN.bv_val );
+       return ntargetDN.bv_val;
 }
 
 
@@ -211,31 +219,32 @@ int validate_global_referral( const char *url )
        return rc;
 }
 
-struct berval ** referral_rewrite(
-       struct berval **in,
-       const char *base,
-       const char *target,
+BerVarray referral_rewrite(
+       BerVarray in,
+       struct berval *base,
+       struct berval *target,
        int scope )
 {
-       int i, j;
-       struct berval **refs;
+       int i;
+       BerVarray refs;
+       struct berval *iv, *jv;
 
        if( in == NULL ) return NULL;
 
-       for( i=0; in[i] != NULL ; i++ ) {
+       for( i=0; in[i].bv_val != NULL ; i++ ) {
                /* just count them */
        }
 
        if( i < 1 ) return NULL;
 
-       refs = ch_malloc( (i+1) * sizeof( struct berval ) );
+       refs = ch_malloc( (i+1) * sizeof( struct berval ) );
 
-       for( i=0,j=0; in[i] != NULL ; i++ ) {
+       for( iv=in,jv=refs; iv->bv_val != NULL ; iv++ ) {
                LDAPURLDesc *url;
-               int rc = ldap_url_parse_ext( in[i]->bv_val, &url );
+               int rc = ldap_url_parse_ext( iv->bv_val, &url );
 
                if( rc == LDAP_URL_ERR_BADSCHEME ) {
-                       refs[j++] = ber_bvdup( in[i] );
+                       ber_dupbv( jv++, iv );
                        continue;
 
                } else if( rc != LDAP_URL_SUCCESS ) {
@@ -245,7 +254,9 @@ struct berval ** referral_rewrite(
                {
                        char *dn = url->lud_dn;
                        url->lud_dn = referral_dn_muck(
-                               ( dn && *dn ) ? dn : NULL, base, target ); 
+                               ( dn && *dn ) ? dn : NULL,
+                               base ? base->bv_val : NULL,
+                               target ? target->bv_val : NULL ); 
 
                        ldap_memfree( dn );
                }
@@ -254,38 +265,35 @@ struct berval ** referral_rewrite(
                        url->lud_scope = scope;
                }
 
-               refs[j] = ch_malloc( sizeof( struct berval ) );
-
-               refs[j]->bv_val = ldap_url_desc2str( url );
-               refs[j]->bv_len = strlen( refs[j]->bv_val );
+               jv->bv_val = ldap_url_desc2str( url );
+               jv->bv_len = strlen( jv->bv_val );
 
                ldap_free_urldesc( url );
-               j++;
+               jv++;
        }
 
-       if( j == 0 ) {
+       if( jv == refs ) {
                ch_free( refs );
                refs = NULL;
 
        } else {
-               refs[j] = NULL;
+               jv->bv_val = NULL;
        }
 
        return refs;
 }
 
 
-struct berval **get_entry_referrals(
+BerVarray get_entry_referrals(
        Backend *be,
        Connection *conn,
        Operation *op,
-       Entry *e,
-       const char *dn,
-       int scope )
+       Entry *e )
 {
        Attribute *attr;
-       struct berval **refs;
-       unsigned i, j;
+       BerVarray refs;
+       unsigned i;
+       struct berval *iv, *jv;
 
        AttributeDescription *ad_ref = slap_schema.si_ad_ref;
 
@@ -293,41 +301,40 @@ struct berval **get_entry_referrals(
 
        if( attr == NULL ) return NULL;
 
-       for( i=0; attr->a_vals[i] != NULL; i++ ) {
+       for( i=0; attr->a_vals[i].bv_val != NULL; i++ ) {
                /* count references */
        }
 
        if( i < 1 ) return NULL;
 
-       refs = ch_malloc( (i + 1) * sizeof(struct berval *));
+       refs = ch_malloc( (i + 1) * sizeof(struct berval));
 
-       for( i=0, j=0; attr->a_vals[i] != NULL; i++ ) {
+       for( iv=attr->a_vals, jv=refs; iv->bv_val != NULL; iv++ ) {
                unsigned k;
-               struct berval *ref = ber_bvdup( attr->a_vals[i] );
+               ber_dupbv( jv, iv );
 
                /* trim the label */
-               for( k=0; k<ref->bv_len; k++ ) {
-                       if( isspace(ref->bv_val[k]) ) {
-                               ref->bv_val[k] = '\0';
-                               ref->bv_len = k;
+               for( k=0; k<jv->bv_len; k++ ) {
+                       if( isspace(jv->bv_val[k]) ) {
+                               jv->bv_val[k] = '\0';
+                               jv->bv_len = k;
                                break;
                        }
                }
 
-               if(     ref->bv_len > 0 ) {
-                       refs[j++] = ref;
-
+               if(     jv->bv_len > 0 ) {
+                       jv++;
                } else {
-                       ber_bvfree( ref );
+                       free( jv->bv_val );
                }
        }
 
-       if( j == 0 ) {
-               ber_bvecfree( refs );
+       if( jv == refs ) {
+               free( refs );
                refs = NULL;
 
        } else {
-               refs[j] = NULL;
+               jv->bv_val = NULL;
        }
 
        /* we should check that a referral value exists... */