]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/back-meta/search.c
Read config tree from back-ldif
[openldap] / servers / slapd / back-meta / search.c
index 0939194cc4088cc5e3dc0aa77d2813efafb73cd8..3dbd522a8be9a3b305032280a155caaef129ed33 100644 (file)
@@ -1,7 +1,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 1999-2004 The OpenLDAP Foundation.
+ * Copyright 1999-2005 The OpenLDAP Foundation.
  * Portions Copyright 2001-2003 Pierangelo Masarati.
  * Portions Copyright 1999-2003 Howard Chu.
  * All rights reserved.
@@ -71,16 +71,9 @@ meta_back_search( Operation *op, SlapReply *rs )
         * to map attrs and maybe rewrite value
         */
        lc = meta_back_getconn( op, rs, META_OP_ALLOW_MULTIPLE, 
-                       &op->o_req_ndn, NULL );
-       if ( !lc ) {
-               send_ldap_result( op, rs );
-               return -1;
-       }
-
-       if ( !meta_back_dobind( lc, op ) ) {
-               rs->sr_err = LDAP_OTHER;
-               send_ldap_result( op, rs );
-               return -1;
+                       &op->o_req_ndn, NULL, LDAP_BACK_SENDERR );
+       if ( !lc || !meta_back_dobind( lc, op, LDAP_BACK_SENDERR ) ) {
+               return rs->sr_err;
        }
 
        /*
@@ -99,7 +92,7 @@ meta_back_search( Operation *op, SlapReply *rs )
        /*
         * Inits searches
         */
-       for ( i = 0, lsc = lc->conns; !META_LAST(lsc); ++i, ++lsc ) {
+       for ( i = 0, lsc = lc->mc_conns; !META_LAST( lsc ); ++i, ++lsc ) {
                struct berval   realbase = op->o_req_dn;
                int             realscope = op->ors_scope;
                ber_len_t       suffixlen = 0;
@@ -107,31 +100,31 @@ meta_back_search( Operation *op, SlapReply *rs )
                struct berval   mfilter = BER_BVNULL;
                char            **mapped_attrs = NULL;
 
-               if ( lsc->candidate != META_CANDIDATE ) {
+               if ( lsc->msc_candidate != META_CANDIDATE ) {
                        msgid[ i ] = -1;
                        continue;
                }
 
                /* should we check return values? */
                if ( op->ors_deref != -1 ) {
-                       ldap_set_option( lsc->ld, LDAP_OPT_DEREF,
+                       ldap_set_option( lsc->msc_ld, LDAP_OPT_DEREF,
                                        ( void * )&op->ors_deref);
                }
                if ( op->ors_tlimit != SLAP_NO_LIMIT ) {
-                       ldap_set_option( lsc->ld, LDAP_OPT_TIMELIMIT,
+                       ldap_set_option( lsc->msc_ld, LDAP_OPT_TIMELIMIT,
                                        ( void * )&op->ors_tlimit);
                }
                if ( op->ors_slimit != SLAP_NO_LIMIT ) {
-                       ldap_set_option( lsc->ld, LDAP_OPT_SIZELIMIT,
+                       ldap_set_option( lsc->msc_ld, LDAP_OPT_SIZELIMIT,
                                        ( void * )&op->ors_slimit);
                }
 
-               dc.rwmap = &li->targets[ i ]->rwmap;
+               dc.rwmap = &li->targets[ i ]->mt_rwmap;
 
                /*
                 * modifies the base according to the scope, if required
                 */
-               suffixlen = li->targets[ i ]->suffix.bv_len;
+               suffixlen = li->targets[ i ]->mt_nsuffix.bv_len;
                if ( suffixlen > op->o_req_ndn.bv_len ) {
                        switch ( op->ors_scope ) {
                        case LDAP_SCOPE_SUBTREE:
@@ -141,9 +134,9 @@ meta_back_search( Operation *op, SlapReply *rs )
                                 * illegal bases may be turned into 
                                 * the suffix of the target.
                                 */
-                               if ( dnIsSuffix( &li->targets[ i ]->suffix,
+                               if ( dnIsSuffix( &li->targets[ i ]->mt_nsuffix,
                                                &op->o_req_ndn ) ) {
-                                       realbase = li->targets[ i ]->suffix;
+                                       realbase = li->targets[ i ]->mt_nsuffix;
                                        is_scope++;
 
                                } else {
@@ -157,17 +150,17 @@ meta_back_search( Operation *op, SlapReply *rs )
 
                        case LDAP_SCOPE_ONELEVEL:
                        {
-                               struct berval   rdn = li->targets[ i ]->suffix;
+                               struct berval   rdn = li->targets[ i ]->mt_nsuffix;
                                rdn.bv_len -= op->o_req_ndn.bv_len + STRLENOF( "," );
                                if ( dnIsOneLevelRDN( &rdn )
-                                               && dnIsSuffix( &li->targets[ i ]->suffix, &op->o_req_ndn ) )
+                                               && dnIsSuffix( &li->targets[ i ]->mt_nsuffix, &op->o_req_ndn ) )
                                {
                                        /*
                                         * if there is exactly one level,
                                         * make the target suffix the new
                                         * base, and make scope "base"
                                         */
-                                       realbase = li->targets[ i ]->suffix;
+                                       realbase = li->targets[ i ]->mt_nsuffix;
                                        realscope = LDAP_SCOPE_BASE;
                                        is_scope++;
                                        break;
@@ -242,7 +235,7 @@ meta_back_search( Operation *op, SlapReply *rs )
                /*
                 * Maps required attributes
                 */
-               rc = ldap_back_map_attrs( &li->targets[ i ]->rwmap.rwm_at,
+               rc = ldap_back_map_attrs( &li->targets[ i ]->mt_rwmap.rwm_at,
                                op->ors_attrs, BACKLDAP_MAP,
                                &mapped_attrs );
                if ( rc != LDAP_SUCCESS ) {
@@ -256,26 +249,28 @@ meta_back_search( Operation *op, SlapReply *rs )
                /*
                 * Starts the search
                 */
-               msgid[ i ] = ldap_search( lsc->ld, mbase.bv_val, realscope,
-                               mfilter.bv_val, mapped_attrs,
-                               op->ors_attrsonly ); 
+               rc = ldap_search_ext( lsc->msc_ld,
+                               mbase.bv_val, realscope, mfilter.bv_val,
+                               mapped_attrs, op->ors_attrsonly,
+                               op->o_ctrls, NULL,
+                               NULL, op->ors_slimit, &msgid[ i ] ); 
                if ( mapped_attrs ) {
                        free( mapped_attrs );
                        mapped_attrs = NULL;
                }
                if ( mfilter.bv_val != op->ors_filterstr.bv_val ) {
                        free( mfilter.bv_val );
-                       mfilter.bv_val = NULL;
+                       BER_BVZERO( &mfilter );
                }
                if ( mbase.bv_val != realbase.bv_val ) {
                        free( mbase.bv_val );
-                       mbase.bv_val = NULL;
+                       BER_BVZERO( &mbase );
                }
 
-               if ( msgid[ i ] == -1 ) {
+               if ( rc != LDAP_SUCCESS ) {
                        continue;
                }
-
+               
                ++candidates;
 
 new_candidate:;
@@ -301,14 +296,14 @@ new_candidate:;
                /* check for abandon */
                ab = op->o_abandon;
 
-               for ( i = 0, lsc = lc->conns; !META_LAST(lsc); lsc++, i++ ) {
+               for ( i = 0, lsc = lc->mc_conns; !META_LAST( lsc ); lsc++, i++ ) {
                        if ( msgid[ i ] == -1 ) {
                                continue;
                        }
                        
                        if ( ab ) {
-                               ldap_abandon( lsc->ld, msgid[ i ] );
-                               rc = 0;
+                               ldap_abandon_ext( lsc->msc_ld, msgid[ i ], NULL, NULL );
+                               rc = SLAPD_ABANDON;
                                break;
                        }
 
@@ -327,7 +322,7 @@ new_candidate:;
                         * get a LDAP_TIMELIMIT_EXCEEDED from
                         * one of them ...
                         */
-                       rc = ldap_result( lsc->ld, msgid[ i ],
+                       rc = ldap_result( lsc->msc_ld, msgid[ i ],
                                        0, &tv, &res );
 
                        if ( rc == 0 ) {
@@ -339,6 +334,7 @@ new_candidate:;
                                continue;
 
                        } else if ( rc == -1 ) {
+really_bad:;
                                /* something REALLY bad happened! */
                                ( void )meta_clear_unused_candidates( li,
                                                lc, -1, 0 );
@@ -354,7 +350,7 @@ new_candidate:;
                                goto finish;
 
                        } else if ( rc == LDAP_RES_SEARCH_ENTRY ) {
-                               e = ldap_first_entry( lsc->ld, res );
+                               e = ldap_first_entry( lsc->msc_ld, res );
                                meta_send_entry( op, rs, lc, i, e );
 
                                ldap_msgfree( res );
@@ -380,12 +376,7 @@ new_candidate:;
                                char            **references = NULL;
                                int             cnt;
 
-                               /*
-                                * FIXME: should we collect references
-                                * and send them alltogether at the end?
-                                */
-
-                               rc = ldap_parse_reference( lsc->ld, res,
+                               rc = ldap_parse_reference( lsc->msc_ld, res,
                                                &references, &rs->sr_ctrls, 1 );
                                res = NULL;
 
@@ -397,24 +388,35 @@ new_candidate:;
                                        continue;
                                }
 
+#ifdef ENABLE_REWRITE
+                               dc.ctx = "referralDN";
+#else /* ! ENABLE_REWRITE */
+                               dc.tofrom = 0;
+                               dc.normalized = 0;
+#endif /* ! ENABLE_REWRITE */
                                for ( cnt = 0; references[ cnt ]; cnt++ )
-                                       /* NO OP */ ;
-                               
-                               rs->sr_ref = ch_calloc( cnt + 1, sizeof( struct berval ) );
+                                       ;
+
+                               rs->sr_ref = ch_calloc( sizeof( struct berval ), cnt + 1 );
 
                                for ( cnt = 0; references[ cnt ]; cnt++ ) {
-                                       rs->sr_ref[ cnt ].bv_val = references[ cnt ];
-                                       rs->sr_ref[ cnt ].bv_len = strlen( references[ cnt ] );
+                                       ber_str2bv( references[ cnt ], 0, 1, &rs->sr_ref[ cnt ] );
                                }
+                               BER_BVZERO( &rs->sr_ref[ cnt ] );
 
-                               /* ignore return value by now */
-                               ( void )send_search_reference( op, rs );
+                               ( void )ldap_back_referral_result_rewrite( &dc, rs->sr_ref );
+
+                               if ( rs->sr_ref != NULL && !BER_BVISNULL( &rs->sr_ref[ 0 ] ) ) {
+                                       /* ignore return value by now */
+                                       ( void )send_search_reference( op, rs );
+
+                                       ber_bvarray_free( rs->sr_ref );
+                                       rs->sr_ref = NULL;
+                               }
 
                                /* cleanup */
                                if ( references ) {
                                        ldap_value_free( references );
-                                       ch_free( rs->sr_ref );
-                                       rs->sr_ref = NULL;
                                }
 
                                if ( rs->sr_ctrls ) {
@@ -423,20 +425,25 @@ new_candidate:;
                                }
 
                        } else {
-                               rs->sr_err = ldap_result2error( lsc->ld,
-                                               res, 1 );
+                               if ( ldap_parse_result( lsc->msc_ld, res,
+                                                       &rs->sr_err,
+                                                       NULL, NULL, NULL, NULL, 1 ) )
+                               {
+                                       res = NULL;
+                                       goto really_bad;
+                               }
                                res = NULL;
 
                                sres = slap_map_api2result( rs );
                                if ( err != NULL ) {
                                        free( err );
                                }
-                               ldap_get_option( lsc->ld,
+                               ldap_get_option( lsc->msc_ld,
                                                LDAP_OPT_ERROR_STRING, &err );
                                if ( match.bv_val != NULL ) {
                                        free( match.bv_val );
                                }
-                               ldap_get_option( lsc->ld,
+                               ldap_get_option( lsc->msc_ld,
                                                LDAP_OPT_MATCHED_DN, &match.bv_val );
 
                                Debug( LDAP_DEBUG_ANY,
@@ -462,8 +469,9 @@ new_candidate:;
 
                if ( gotit == 0 ) {
                        tv.tv_sec = 0;
-                        tv.tv_usec = 100000;
+                        tv.tv_usec = 100000;   /* 0.1 s */
                         ldap_pvt_thread_yield();
+
                } else {
                        tv.tv_sec = 0;
                        tv.tv_usec = 0;
@@ -486,7 +494,7 @@ new_candidate:;
        if ( candidate_match == initial_candidates
                        && match.bv_val != NULL && *match.bv_val ) {
                dc.ctx = "matchedDN";
-               dc.rwmap = &li->targets[ last ]->rwmap;
+               dc.rwmap = &li->targets[ last ]->mt_rwmap;
 
                if ( ldap_back_dn_massage( &dc, &match, &mmatch ) ) {
                        mmatch.bv_val = NULL;
@@ -559,7 +567,7 @@ meta_send_entry(
        /*
         * Rewrite the dn of the result, if needed
         */
-       dc.rwmap = &li->targets[ target ]->rwmap;
+       dc.rwmap = &li->targets[ target ]->mt_rwmap;
        dc.conn = op->o_conn;
        dc.rs = rs;
        dc.ctx = "searchResult";
@@ -596,7 +604,7 @@ meta_send_entry(
        while ( ber_scanf( &ber, "{m", &a ) != LBER_ERROR ) {
                int             last = 0;
 
-               ldap_back_map( &li->targets[ target ]->rwmap.rwm_at, 
+               ldap_back_map( &li->targets[ target ]->mt_rwmap.rwm_at, 
                                &a, &mapped, BACKLDAP_REMAP );
                if ( mapped.bv_val == NULL || mapped.bv_val[0] == '\0' ) {
                        continue;
@@ -638,7 +646,7 @@ meta_send_entry(
 
                if ( ber_scanf( &ber, "[W]", &attr->a_vals ) == LBER_ERROR 
                                || attr->a_vals == NULL ) {
-                       attr->a_vals = &slap_dummy_bv;
+                       attr->a_vals = (struct berval *)&slap_dummy_bv;
 
                } else if ( attr->a_desc == slap_schema.si_ad_objectClass
                                || attr->a_desc == slap_schema.si_ad_structuralObjectClass ) {
@@ -646,7 +654,7 @@ meta_send_entry(
                        for ( last = 0; attr->a_vals[ last ].bv_val; ++last );
 
                        for ( bv = attr->a_vals; bv->bv_val; bv++ ) {
-                               ldap_back_map( &li->targets[ target ]->rwmap.rwm_oc,
+                               ldap_back_map( &li->targets[ target ]->mt_rwmap.rwm_oc,
                                                bv, &mapped, BACKLDAP_REMAP );
                                if ( mapped.bv_val == NULL || mapped.bv_val[0] == '\0') {
                                        free( bv->bv_val );
@@ -675,8 +683,12 @@ meta_send_entry(
                 * everything pass thru the ldap backend.
                 */
                } else if ( attr->a_desc->ad_type->sat_syntax ==
-                               slap_schema.si_syn_distinguishedName ) {
+                               slap_schema.si_syn_distinguishedName )
+               {
                        ldap_dnattr_result_rewrite( &dc, attr->a_vals );
+
+               } else if ( attr->a_desc == slap_schema.si_ad_ref ) {
+                       ldap_back_referral_result_rewrite( &dc, attr->a_vals );
                }
 
                if ( last && attr->a_desc->ad_type->sat_equality &&