]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/back-ldap/search.c
More cleanups for suffixmassage DNs
[openldap] / servers / slapd / back-ldap / search.c
index 6f192f13b88c77912118b089632bc3bc8b2dca5d..3bdd7215afd30254f1095961b88234d84d5d9f3a 100644 (file)
@@ -1,7 +1,7 @@
 /* search.c - ldap backend search function */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /* This is an altered version */
@@ -45,6 +45,7 @@
 
 #include "slap.h"
 #include "back-ldap.h"
+#undef ldap_debug      /* silence a warning in ldap-int.h */
 #include "../../../libraries/libldap/ldap-int.h"
 
 static void ldap_send_entry( Backend *be, Operation *op, struct ldapconn *lc,
@@ -98,7 +99,7 @@ ldap_back_search(
        /* if requested limit higher than hard limit, abort */
        if ( !isroot && tlimit > limit->lms_t_hard ) {
                /* no hard limit means use soft instead */
-               if ( limit->lms_t_hard == 0 ) {
+               if ( limit->lms_t_hard == 0 && tlimit > limit->lms_t_soft ) {
                        tlimit = limit->lms_t_soft;
                        
                /* positive hard limit means abort */
@@ -116,7 +117,7 @@ ldap_back_search(
        /* if requested limit higher than hard limit, abort */
        if ( !isroot && slimit > limit->lms_s_hard ) {
                /* no hard limit means use soft instead */
-               if ( limit->lms_s_hard == 0 ) {
+               if ( limit->lms_s_hard == 0 && slimit > limit->lms_s_soft ) {
                        slimit = limit->lms_s_soft;
                        
                /* positive hard limit means abort */
@@ -149,7 +150,7 @@ ldap_back_search(
                                base->bv_val, conn, &mbase.bv_val ) ) {
        case REWRITE_REGEXEC_OK:
                if ( mbase.bv_val == NULL ) {
-                       mbase.bv_val = ( char * )base->bv_val;
+                       mbase = *base;
                }
 #ifdef NEW_LOGGING
                LDAP_LOG(( "backend", LDAP_LEVEL_DETAIL1,
@@ -185,7 +186,10 @@ ldap_back_search(
                                free( mfilter.bv_val );
                        }
                        mfilter = *filterstr;
+               } else {
+                       mfilter.bv_len = strlen( mfilter.bv_val );
                }
+
 #ifdef NEW_LOGGING
                LDAP_LOG(( "backend", LDAP_LEVEL_DETAIL1,
                                "[rw] searchFilter: \"%s\" -> \"%s\"\n",
@@ -223,13 +227,18 @@ ldap_back_search(
 #endif /* !ENABLE_REWRITE */
        }
 
+#ifdef ENABLE_REWRITE
+       if ( mfilter.bv_val != filterstr->bv_val ) {
+               free( mfilter.bv_val );
+       }
+#endif /* ENABLE_REWRITE */
+
        mapped_attrs = ldap_back_map_attrs(&li->at_map, attrs, 0);
        if ( mapped_attrs == NULL && attrs) {
-               AttributeName *an;
-               for (count=0, an=attrs; an; an=an->an_next,count++);
+               for (count=0; attrs[count].an_name.bv_val; count++);
                mapped_attrs = ch_malloc( (count+1) * sizeof(char *));
-               for (count=0, an=attrs; an; an=an->an_next,count++) {
-                       mapped_attrs[count] = an->an_name.bv_val;
+               for (count=0; attrs[count].an_name.bv_val; count++) {
+                       mapped_attrs[count] = attrs[count].an_name.bv_val;
                }
                mapped_attrs[count] = NULL;
        }
@@ -251,14 +260,8 @@ fail:;
                        rc != -1;
                        rc = ldap_result(lc->ld, LDAP_RES_ANY, 0, &tv, &res))
        {
-               int ab;
-
                /* check for abandon */
-               ldap_pvt_thread_mutex_lock( &op->o_abandonmutex );
-               ab = op->o_abandon;
-               ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex );
-
-               if (ab) {
+               if (op->o_abandon) {
                        ldap_abandon(lc->ld, msgid);
                        rc = 0;
                        goto finish;
@@ -334,27 +337,17 @@ finish:;
                        free( mmatch );
                }
 #endif /* ENABLE_REWRITE */
-               free(match);
+               LDAP_FREE(match);
        }
        if ( err ) {
-               free( err );
+               LDAP_FREE( err );
        }
        if ( mapped_attrs ) {
-               free( mapped_attrs );
-       }
-#ifdef ENABLE_REWRITE
-       if ( mapped_filter != mfilter.bv_val ) {
-               free( mapped_filter );
-       }
-       if ( mfilter.bv_val != filterstr->bv_val ) {
-               free( mfilter.bv_val );
+               ch_free( mapped_attrs );
        }
-#else /* !ENABLE_REWRITE */
        if ( mapped_filter != filterstr->bv_val ) {
-               free( mapped_filter );
+               ch_free( mapped_filter );
        }
-#endif /* !ENABLE_REWRITE */
-       
        if ( mbase.bv_val != base->bv_val ) {
                free( mbase.bv_val );
        }
@@ -381,7 +374,7 @@ ldap_send_entry(
        struct berval *bv, bdn;
        const char *text;
 
-       if ( ber_scanf( &ber, "{o", &bdn ) == LBER_ERROR ) {
+       if ( ber_scanf( &ber, "{m{", &bdn ) == LBER_ERROR ) {
                return;
        }
 #ifdef ENABLE_REWRITE
@@ -394,7 +387,6 @@ ldap_send_entry(
        case REWRITE_REGEXEC_OK:
                if ( ent.e_name.bv_val == NULL ) {
                        ent.e_name = bdn;
-                       
                } else {
 #ifdef NEW_LOGGING
                        LDAP_LOG(( "backend", LDAP_LEVEL_DETAIL1,
@@ -404,8 +396,6 @@ ldap_send_entry(
                        Debug( LDAP_DEBUG_ARGS, "rw> searchResult: \"%s\""
                                        " -> \"%s\"\n%s", bdn.bv_val, ent.e_dn, "" );
 #endif /* !NEW_LOGGING */
-                       free( bdn.bv_val );
-                       bdn.bv_val = NULL;
                        ent.e_name.bv_len = strlen( ent.e_name.bv_val );
                }
                break;
@@ -424,13 +414,14 @@ ldap_send_entry(
        ent.e_private = 0;
        attrp = &ent.e_attrs;
 
-       while ( ber_scanf( &ber, "{{o", &a ) != LBER_ERROR ) {
+       while ( ber_scanf( &ber, "{m", &a ) != LBER_ERROR ) {
                ldap_back_map(&li->at_map, &a, &mapped, 1);
                if (mapped.bv_val == NULL)
                        continue;
                attr = (Attribute *)ch_malloc( sizeof(Attribute) );
                if (attr == NULL)
                        continue;
+               attr->a_flags = 0;
                attr->a_next = 0;
                attr->a_desc = NULL;
                if (slap_bv2ad(&mapped, &attr->a_desc, &text) != LDAP_SUCCESS) {
@@ -438,45 +429,56 @@ ldap_send_entry(
                                        != LDAP_SUCCESS) {
 #ifdef NEW_LOGGING
                                LDAP_LOG(( "backend", LDAP_LEVEL_DETAIL1,
-                                               "slap_str2undef_ad(%s): "
+                                               "slap_bv2undef_ad(%s):  "
                                                "%s\n", mapped.bv_val, text ));
 #else /* !NEW_LOGGING */
                                Debug( LDAP_DEBUG_ANY, 
-                                               "slap_str2undef_ad(%s): "
+                                               "slap_bv2undef_ad(%s):  "
                                                "%s\n%s", mapped.bv_val, text, "" );
 #endif /* !NEW_LOGGING */
-                               
                                ch_free(attr);
                                continue;
                        }
                }
+
+               /* no subschemaSubentry */
+               if ( attr->a_desc == slap_schema.si_ad_subschemaSubentry ) {
+                       ch_free(attr);
+                       continue;
+               }
+               
                if (ber_scanf( &ber, "[W]", &attr->a_vals ) == LBER_ERROR ) {
                        attr->a_vals = &dummy;
-               } else if ( strcasecmp( mapped.bv_val, "objectclass" ) == 0 ) {
+               } else if ( attr->a_desc == slap_schema.si_ad_objectClass
+                               || attr->a_desc == slap_schema.si_ad_structuralObjectClass ) {
                        int i, last;
                        for ( last = 0; attr->a_vals[last].bv_val; last++ ) ;
-                       for ( i = 0; ( bv = &attr->a_vals[i] ); i++ ) {
+                       for ( i = 0, bv = attr->a_vals; bv->bv_val; bv++, i++ ) {
                                ldap_back_map(&li->oc_map, bv, &mapped, 1);
                                if (mapped.bv_val == NULL) {
-                                       free(attr->a_vals[i].bv_val);
-                                       attr->a_vals[i].bv_val = NULL;
+                                       LBER_FREE(bv->bv_val);
+                                       bv->bv_val = NULL;
                                        if (--last < 0)
                                                break;
-                                       attr->a_vals[i] = attr->a_vals[last];
+                                       *bv = attr->a_vals[last];
                                        attr->a_vals[last].bv_val = NULL;
                                        i--;
                                } else if ( mapped.bv_val != bv->bv_val ) {
-                                       ch_free(bv->bv_val);
+                                       /*
+                                        * FIXME: after LBER_FREEing
+                                        * the value is replaced by
+                                        * ch_alloc'ed memory
+                                        */
+                                       LBER_FREE(bv->bv_val);
                                        ber_dupbv( bv, &mapped );
                                }
                        }
 
-#ifdef ENABLE_REWRITE
                /*
                 * It is necessary to try to rewrite attributes with
                 * dn syntax because they might be used in ACLs as
                 * members of groups; since ACLs are applied to the
-                * rewritten stuff, no dn-based subecj clause could
+                * rewritten stuff, no dn-based subject clause could
                 * be used at the ldap backend side (see
                 * http://www.OpenLDAP.org/faq/data/cache/452.html)
                 * The problem can be overcome by moving the dn-based
@@ -486,16 +488,18 @@ ldap_send_entry(
                } else if ( strcmp( attr->a_desc->ad_type->sat_syntax->ssyn_oid,
                                        SLAPD_DN_SYNTAX ) == 0 ) {
                        int i;
-                       for ( i = 0; ( bv = &attr->a_vals[ i ] ); i++ ) {
-                               char *newval;
+                       for ( i = 0, bv = attr->a_vals; bv->bv_val; bv++, i++ ) {
+                               struct berval newval;
                                
+#ifdef ENABLE_REWRITE
                                switch ( rewrite_session( li->rwinfo,
                                                        "searchResult",
                                                        bv->bv_val,
-                                                       lc->conn, &newval )) {
+                                                       lc->conn, 
+                                                       &newval.bv_val )) {
                                case REWRITE_REGEXEC_OK:
                                        /* left as is */
-                                       if ( newval == NULL ) {
+                                       if ( newval.bv_val == NULL ) {
                                                break;
                                        }
 #ifdef NEW_LOGGING
@@ -505,18 +509,16 @@ ldap_send_entry(
                                                        " attr=%s:"
                                                        " \"%s\" -> \"%s\"\n",
                                                        attr->a_desc->ad_type->sat_cname.bv_val,
-                                                       bv->bv_val, newval ));
+                                                       bv->bv_val, 
+                                                       newval.bv_val ));
 #else /* !NEW_LOGGING */
                                        Debug( LDAP_DEBUG_ARGS,
                "rw> searchResult on attr=%s: \"%s\" -> \"%s\"\n",
                                                attr->a_desc->ad_type->sat_cname.bv_val,
-                                               bv->bv_val, newval );
+                                               bv->bv_val, newval.bv_val );
 #endif /* !NEW_LOGGING */
-                                       
                                        free( bv->bv_val );
-                                       bv->bv_val = newval;
-                                       bv->bv_len = strlen( newval );
-                                       
+                                       *bv = newval;
                                        break;
                                        
                                case REWRITE_REGEXEC_UNWILLING:
@@ -529,8 +531,11 @@ ldap_send_entry(
                                         */
                                        break;
                                }
+#else /* !ENABLE_REWRITE */
+                               ldap_back_dn_massage( li, bv, &newval, 0, 0 );
+                               *bv = newval;
+#endif /* !ENABLE_REWRITE */
                        }
-#endif /* ENABLE_REWRITE */
                }
 
                *attrp = attr;
@@ -541,13 +546,12 @@ ldap_send_entry(
                attr = ent.e_attrs;
                ent.e_attrs = attr->a_next;
                if (attr->a_vals != &dummy)
-                       bvarray_free(attr->a_vals);
-               free(attr);
+                       ber_bvarray_free(attr->a_vals);
+               ch_free(attr);
        }
        
-       if ( ent.e_dn )
+       if ( ent.e_dn && ( ent.e_dn != bdn.bv_val ) )
                free( ent.e_dn );
        if ( ent.e_ndn )
                free( ent.e_ndn );
 }
-