]> git.ipfire.org Git - thirdparty/openldap.git/commitdiff
Enable addition of targets to back-asyncmeta via cn=config
authorNadezhda Ivanova <nivanova@symas.com>
Tue, 13 Apr 2021 12:12:34 +0000 (15:12 +0300)
committerQuanah Gibson-Mount <quanah@openldap.org>
Thu, 29 Jul 2021 15:05:36 +0000 (15:05 +0000)
servers/slapd/back-asyncmeta/add.c
servers/slapd/back-asyncmeta/back-asyncmeta.h
servers/slapd/back-asyncmeta/bind.c
servers/slapd/back-asyncmeta/compare.c
servers/slapd/back-asyncmeta/config.c
servers/slapd/back-asyncmeta/conn.c
servers/slapd/back-asyncmeta/delete.c
servers/slapd/back-asyncmeta/init.c
servers/slapd/back-asyncmeta/modify.c
servers/slapd/back-asyncmeta/modrdn.c
servers/slapd/back-asyncmeta/search.c

index f672467e8b517ccd2ff719e63301e02eb62e0800..eb606ad4ce469385bba7670746d66193ac54f3e7 100644 (file)
@@ -255,6 +255,13 @@ asyncmeta_back_add( Operation *op, SlapReply *rs )
                      op->o_log_prefix, op->o_time, current_time );
        }
 
+       if ( mi->mi_ntargets == 0 ) {
+               rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
+               rs->sr_text = "No targets are configured for this database";
+               send_ldap_result(op, rs);
+               return rs->sr_err;
+       }
+
        asyncmeta_new_bm_context(op, rs, &bc, mi->mi_ntargets, mi );
        if (bc == NULL) {
                rs->sr_err = LDAP_OTHER;
index bae9be3edbdb28b9381a19313d013bbfa97e72a3..fcc0d69b2532f8c93719f1cba2063fc84a130ae8 100644 (file)
@@ -771,6 +771,12 @@ asyncmeta_return_bind_errors(a_metaconn_t *mc,
                             void         *ctx,
                             int          dolock);
 
+int
+asyncmeta_db_has_pending_ops(a_metainfo_t *mi);
+
+int
+asyncmeta_db_has_mscs(a_metainfo_t *mi);
+
 /* The the maximum time in seconds after a result has been received on a connection,
  * after which it can be reset if a sender error occurs. Should this be configurable? */
 #define META_BACK_RESULT_INTERVAL (2)
index 739fbf7b6313184b2a2ac869ab37bcbac7147377..261384545e5ba8eda7c1042561d86d2662df4e52 100644 (file)
@@ -65,9 +65,8 @@ asyncmeta_back_bind( Operation *op, SlapReply *rs )
                        gotit = 0,
                        isroot = 0;
 
-       SlapReply       *candidates;
+       SlapReply       *candidates = NULL;
 
-       candidates = op->o_tmpcalloc(mi->mi_ntargets, sizeof(SlapReply),op->o_tmpmemctx);
        rs->sr_err = LDAP_SUCCESS;
 
        Debug( LDAP_DEBUG_ARGS, "%s asyncmeta_back_bind: dn=\"%s\".\n",
@@ -92,6 +91,16 @@ asyncmeta_back_bind( Operation *op, SlapReply *rs )
                return rs->sr_err;
        }
 
+
+       if ( mi->mi_ntargets == 0 ) {
+               rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
+               rs->sr_text = "No targets are configured for this database";
+               send_ldap_result(op, rs);
+               return rs->sr_err;
+       }
+
+       candidates = op->o_tmpcalloc(mi->mi_ntargets, sizeof(SlapReply),op->o_tmpmemctx);
+
        /* we need asyncmeta_getconn() not send result even on error,
         * because we want to intercept the error and make it
         * invalidCredentials */
index 6448197ff3d7f1aee903ed418f761639dd47d41c..f59690eec325f13b09771cc485f549bdbb6ac605 100644 (file)
@@ -197,6 +197,14 @@ asyncmeta_back_compare( Operation *op, SlapReply *rs )
                Debug( asyncmeta_debug, "==> asyncmeta_back_compare[%s]: o_time:[%ld], current time: [%ld]\n",
                       op->o_log_prefix, op->o_time, current_time );
        }
+
+       if ( mi->mi_ntargets == 0 ) {
+               rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
+               rs->sr_text = "No targets are configured for this database";
+               send_ldap_result(op, rs);
+               return rs->sr_err;
+       }
+
        asyncmeta_new_bm_context(op, rs, &bc, mi->mi_ntargets, mi );
        if (bc == NULL) {
                rs->sr_err = LDAP_OTHER;
index 05ec953655a0a4bddadffedef998302c77c520bd..aabac8abd5d4e086d9c72357df9fde701e17418b 100644 (file)
@@ -456,11 +456,21 @@ static ConfigOCs a_metaocs[] = {
 static int
 asyncmeta_ldadd( CfEntryInfo *p, Entry *e, ConfigArgs *c )
 {
+       a_metainfo_t    *mi;
+
        if ( p->ce_type != Cft_Database || !p->ce_be ||
                p->ce_be->be_cf_ocs != a_metaocs )
                return LDAP_CONSTRAINT_VIOLATION;
 
        c->be = p->ce_be;
+       mi = ( a_metainfo_t * )c->be->be_private;
+
+       if ( asyncmeta_db_has_pending_ops ( mi ) > 0 ) {
+               snprintf( c->cr_msg, sizeof( c->cr_msg ),
+                         "cannot modify a working database" );
+               Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
+               return 1;
+       }
        return LDAP_SUCCESS;
 }
 
@@ -486,12 +496,15 @@ asyncmeta_cfadd( Operation *op, SlapReply *rs, Entry *p, ConfigArgs *c )
 
 static int
 asyncmeta_back_new_target(
-       a_metatarget_t  **mtp )
+       a_metatarget_t  **mtp,
+       a_metainfo_t     *mi )
 {
        a_metatarget_t          *mt;
 
        *mtp = NULL;
+       int i;
 
+       assert ( mi != NULL );
        mt = ch_calloc( sizeof( a_metatarget_t ), 1 );
 
        ldap_pvt_thread_mutex_init( &mt->mt_uri_mutex );
@@ -504,6 +517,18 @@ asyncmeta_back_new_target(
 
        *mtp = mt;
 
+       for ( i = 0; i < mi->mi_num_conns; i++ ) {
+               a_metaconn_t *mc = &mi->mi_conns[i];
+               mc->mc_conns = ch_realloc( mc->mc_conns, sizeof( a_metasingleconn_t ) * mi->mi_ntargets);
+               memset( &(mc->mc_conns[mi->mi_ntargets-1]), 0, sizeof( a_metasingleconn_t ) );
+       }
+       /* If this is the first target, start the timeout loop */
+       if ( mi->mi_ntargets == 1 ) {
+               ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
+               mi->mi_task = ldap_pvt_runqueue_insert( &slapd_rq, 1,
+                                                       asyncmeta_timeout_loop, mi, "asyncmeta_timeout_loop", mi->mi_suffix.bv_val );
+               ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
+       }
        return 0;
 }
 
@@ -1026,6 +1051,13 @@ asyncmeta_back_cf_gen( ConfigArgs *c )
                }
        }
 
+       if ( c->op != SLAP_CONFIG_EMIT && asyncmeta_db_has_pending_ops ( mi ) > 0 ) {
+               snprintf( c->cr_msg, sizeof( c->cr_msg ),
+                         "cannot modify a working database" );
+               Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
+               return 1;
+       }
+
        if ( c->op == SLAP_CONFIG_EMIT ) {
                struct berval bv = BER_BVNULL;
 
@@ -1520,6 +1552,7 @@ asyncmeta_back_cf_gen( ConfigArgs *c )
                }
                return rc;
        } else if ( c->op == LDAP_MOD_DELETE ) {
+
                switch( c->type ) {
                /* Base attrs */
                case LDAP_BACK_CFG_DNCACHE_TTL:
@@ -1544,8 +1577,15 @@ asyncmeta_back_cf_gen( ConfigArgs *c )
 
                /* common attrs */
                case LDAP_BACK_CFG_BIND_TIMEOUT:
-                       mc->mc_bind_timeout.tv_sec = 0;
-                       mc->mc_bind_timeout.tv_usec = 0;
+                       if ( asyncmeta_db_has_mscs ( mi ) > 0 ) {
+                               snprintf( c->cr_msg, sizeof( c->cr_msg ),
+                                         "cannot modify this attribute if there are established target connections" );
+                               Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
+                               rc = 1;
+                       } else {
+                               mc->mc_bind_timeout.tv_sec = 0;
+                               mc->mc_bind_timeout.tv_usec = 0;
+                       }
                        break;
 
                case LDAP_BACK_CFG_CANCEL:
@@ -1567,7 +1607,14 @@ asyncmeta_back_cf_gen( ConfigArgs *c )
                        break;
 
                case LDAP_BACK_CFG_NETWORK_TIMEOUT:
-                       mc->mc_network_timeout = 0;
+                       if ( asyncmeta_db_has_mscs ( mi ) > 0 ) {
+                               snprintf( c->cr_msg, sizeof( c->cr_msg ),
+                                         "cannot modify this attribute if there are established target connections" );
+                               Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
+                               rc = 1;
+                       } else {
+                               mc->mc_network_timeout = 0;
+                       }
                        break;
 
                case LDAP_BACK_CFG_NOREFS:
@@ -1604,7 +1651,14 @@ asyncmeta_back_cf_gen( ConfigArgs *c )
                        break;
 
                case LDAP_BACK_CFG_VERSION:
-                       mc->mc_version = 0;
+                       if ( asyncmeta_db_has_mscs ( mi ) > 0 ) {
+                               snprintf( c->cr_msg, sizeof( c->cr_msg ),
+                                         "cannot modify this attribute if there are established target connections" );
+                               Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
+                               rc = 1;
+                       } else {
+                               mc->mc_version = 0;
+                       }
                        break;
 
 #ifdef SLAP_CONTROL_X_SESSION_TRACKING
@@ -1625,9 +1679,16 @@ asyncmeta_back_cf_gen( ConfigArgs *c )
 
                /* target attrs */
                case LDAP_BACK_CFG_URI:
-                       if ( mt->mt_uri ) {
-                               ch_free( mt->mt_uri );
-                               mt->mt_uri = NULL;
+                       if ( asyncmeta_db_has_mscs ( mi ) > 0 ) {
+                               snprintf( c->cr_msg, sizeof( c->cr_msg ),
+                                         "cannot modify this attribute if there are established target connections" );
+                               Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
+                               rc = 1;
+                       } else {
+                               if ( mt->mt_uri ) {
+                                       ch_free( mt->mt_uri );
+                                       mt->mt_uri = NULL;
+                               }
                        }
                        /* FIXME: should have a way to close all cached
                         * connections associated with this target.
@@ -1638,44 +1699,66 @@ asyncmeta_back_cf_gen( ConfigArgs *c )
                        BerVarray *bvp;
 
                        bvp = &mt->mt_idassert_authz;
-                       if ( c->valx < 0 ) {
-                               if ( *bvp != NULL ) {
-                                       ber_bvarray_free( *bvp );
-                                       *bvp = NULL;
-                               }
-
+                       if ( asyncmeta_db_has_mscs ( mi ) > 0 ) {
+                               snprintf( c->cr_msg, sizeof( c->cr_msg ),
+                                         "cannot modify this attribute if there are established target connections" );
+                               Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
+                               rc = 1;
                        } else {
-                               if ( *bvp == NULL ) {
-                                       rc = 1;
-                                       break;
-                               }
+                               if ( c->valx < 0 ) {
+                                       if ( *bvp != NULL ) {
+                                               ber_bvarray_free( *bvp );
+                                               *bvp = NULL;
+                                       }
 
-                               for ( i = 0; !BER_BVISNULL( &((*bvp)[ i ]) ); i++ )
-                                       ;
+                               } else {
+                                       if ( *bvp == NULL ) {
+                                               rc = 1;
+                                               break;
+                                       }
 
-                               if ( i >= c->valx ) {
-                                       rc = 1;
-                                       break;
-                               }
-                               ber_memfree( ((*bvp)[ c->valx ]).bv_val );
-                               for ( i = c->valx; !BER_BVISNULL( &((*bvp)[ i + 1 ]) ); i++ ) {
-                                       (*bvp)[ i ] = (*bvp)[ i + 1 ];
+                                       for ( i = 0; !BER_BVISNULL( &((*bvp)[ i ]) ); i++ )
+                                               ;
+
+                                       if ( i >= c->valx ) {
+                                               rc = 1;
+                                               break;
+                                       }
+                                       ber_memfree( ((*bvp)[ c->valx ]).bv_val );
+                                       for ( i = c->valx; !BER_BVISNULL( &((*bvp)[ i + 1 ]) ); i++ ) {
+                                               (*bvp)[ i ] = (*bvp)[ i + 1 ];
+                                       }
+                                       BER_BVZERO( &((*bvp)[ i ]) );
                                }
-                               BER_BVZERO( &((*bvp)[ i ]) );
                        }
-                       } break;
+               }
+                       break;
 
                case LDAP_BACK_CFG_IDASSERT_BIND:
-                       bindconf_free( &mt->mt_idassert.si_bc );
-                       memset( &mt->mt_idassert, 0, sizeof( slap_idassert_t ) );
+                       if ( asyncmeta_db_has_mscs ( mi ) > 0 ) {
+                               snprintf( c->cr_msg, sizeof( c->cr_msg ),
+                                         "cannot modify this attribute if there are established target connections" );
+                               Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
+                               rc = 1;
+                       } else {
+                               bindconf_free( &mt->mt_idassert.si_bc );
+                               memset( &mt->mt_idassert, 0, sizeof( slap_idassert_t ) );
+                       }
                        break;
 
                case LDAP_BACK_CFG_SUFFIXM:
-                       if ( mt->mt_lsuffixm.bv_val ) {
-                               ch_free( mt->mt_lsuffixm.bv_val );
-                               ch_free( mt->mt_rsuffixm.bv_val );
-                               BER_BVZERO( &mt->mt_lsuffixm );
-                               BER_BVZERO( &mt->mt_rsuffixm );
+                       if ( asyncmeta_db_has_mscs ( mi ) > 0 ) {
+                               snprintf( c->cr_msg, sizeof( c->cr_msg ),
+                                         "cannot modify this attribute if there are established target connections" );
+                               Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
+                               rc = 1;
+                       } else {
+                               if ( mt->mt_lsuffixm.bv_val ) {
+                                       ch_free( mt->mt_lsuffixm.bv_val );
+                                       ch_free( mt->mt_rsuffixm.bv_val );
+                                       BER_BVZERO( &mt->mt_lsuffixm );
+                                       BER_BVZERO( &mt->mt_rsuffixm );
+                               }
                        }
                        break;
 
@@ -1729,7 +1812,10 @@ asyncmeta_back_cf_gen( ConfigArgs *c )
                        break;
 
                case LDAP_BACK_CFG_MAX_TARGET_CONNS:
-                       mi->mi_max_target_conns = 0;
+                       snprintf( c->cr_msg, sizeof( c->cr_msg ),
+                                 "max-target-conns cannot be modified at runtime" );
+                       Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
+                       rc = 1;
                        break;
 
                case LDAP_BACK_CFG_MAX_TIMEOUT_OPS:
@@ -1737,9 +1823,16 @@ asyncmeta_back_cf_gen( ConfigArgs *c )
                        break;
 
                case LDAP_BACK_CFG_KEEPALIVE:
-                       mt->mt_tls.sb_keepalive.sk_idle = 0;
-                       mt->mt_tls.sb_keepalive.sk_probes = 0;
-                       mt->mt_tls.sb_keepalive.sk_interval = 0;
+                       if ( asyncmeta_db_has_mscs ( mi ) > 0 ) {
+                               snprintf( c->cr_msg, sizeof( c->cr_msg ),
+                                         "cannot modify this attribute if there are established target connections" );
+                               Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
+                               rc = 1;
+                       } else {
+                               mt->mt_tls.sb_keepalive.sk_idle = 0;
+                               mt->mt_tls.sb_keepalive.sk_probes = 0;
+                               mt->mt_tls.sb_keepalive.sk_interval = 0;
+                       }
                        break;
 
                case LDAP_BACK_CFG_TCP_USER_TIMEOUT:
@@ -1814,7 +1907,7 @@ asyncmeta_back_cf_gen( ConfigArgs *c )
                        return 1;
                }
 
-               if ( asyncmeta_back_new_target( &mi->mi_targets[ i ] ) != 0 ) {
+               if ( asyncmeta_back_new_target( &mi->mi_targets[ i ], mi ) != 0 ) {
                        snprintf( c->cr_msg, sizeof( c->cr_msg ),
                                "unable to init server"
                                " in \"%s <protocol>://<server>[:port]/<naming context>\"",
index 8a43cab6490ea2bba627ddacd10513478189ae69..2d52e2fb40eda8a40bd5687b8fb776cf3e6ab3b1 100644 (file)
@@ -1182,3 +1182,41 @@ void asyncmeta_log_conns(a_metainfo_t *mi)
 
        }
 }
+
+int
+asyncmeta_db_has_pending_ops(a_metainfo_t *mi)
+{
+       int i;
+       if (mi->mi_ntargets == 0) {
+               return 0;
+       }
+
+       for (i = 0; i < mi->mi_num_conns; i++) {
+               if (mi->mi_conns[i].pending_ops > 0) {
+                       return mi->mi_conns[i].pending_ops;
+               }
+       }
+
+       return 0;
+}
+
+
+int
+asyncmeta_db_has_mscs(a_metainfo_t *mi)
+{
+       int i, j;
+       if (mi->mi_ntargets == 0) {
+               return 0;
+       }
+
+       for (i = 0; i < mi->mi_num_conns; i++) {
+               for (j = 0; j < mi->mi_ntargets; j++) {
+                       if (mi->mi_conns[i].mc_conns[j].msc_ld != NULL ||
+                           mi->mi_conns[i].mc_conns[j].msc_ldr != NULL ) {
+                               return 1;
+                       }
+               }
+       }
+
+       return 0;
+}
index 6f7ee9d291b49577f4a5fa213e11852df6cc020c..fb6b06ea8c58a43ab8aadf9a022326048b62c793 100644 (file)
@@ -190,6 +190,13 @@ asyncmeta_back_delete( Operation *op, SlapReply *rs )
                      op->o_log_prefix, op->o_time, current_time );
        }
 
+       if ( mi->mi_ntargets == 0 ) {
+               rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
+               rs->sr_text = "No targets are configured for this database";
+               send_ldap_result(op, rs);
+               return rs->sr_err;
+       }
+
        asyncmeta_new_bm_context(op, rs, &bc, mi->mi_ntargets, mi );
        if (bc == NULL) {
                rs->sr_err = LDAP_OTHER;
index a45fc3b66eb6dfa895cd12f0649a4cb27061888a..87b9bec0f4c7f4244d7a6111a899c531aa99fc2e 100644 (file)
@@ -241,23 +241,20 @@ asyncmeta_back_db_open(
        int             i;
 
        if ( mi->mi_ntargets == 0 ) {
-               /* Dynamically added, nothing to check here until
-                * some targets get added
-                */
-               if ( slapMode & SLAP_SERVER_RUNNING )
-                       return 0;
 
                Debug( LDAP_DEBUG_ANY,
                        "asyncmeta_back_db_open: no targets defined\n" );
-               return 1;
        }
+
        mi->mi_num_conns = 0;
        for ( i = 0; i < mi->mi_ntargets; i++ ) {
                a_metatarget_t  *mt = mi->mi_targets[ i ];
                if ( asyncmeta_target_finish( mi, mt,
-                       "asyncmeta_back_db_open", msg, sizeof( msg )))
+                                             "asyncmeta_back_db_open", msg, sizeof( msg ))) {
                        return 1;
+               }
        }
+
        mi->mi_num_conns = (mi->mi_max_target_conns == 0) ? META_BACK_CFG_MAX_TARGET_CONNS : mi->mi_max_target_conns;
        assert(mi->mi_num_conns > 0);
        mi->mi_conns = ch_calloc( mi->mi_num_conns, sizeof( a_metaconn_t ));
@@ -265,15 +262,25 @@ asyncmeta_back_db_open(
                a_metaconn_t *mc = &mi->mi_conns[i];
                ldap_pvt_thread_mutex_init( &mc->mc_om_mutex);
                mc->mc_authz_target = META_BOUND_NONE;
-               mc->mc_conns = ch_calloc( mi->mi_ntargets, sizeof( a_metasingleconn_t ));
+
+               if ( mi->mi_ntargets > 0 ) {
+                       mc->mc_conns = ch_calloc( mi->mi_ntargets, sizeof( a_metasingleconn_t ));
+               } else {
+                       mc->mc_conns = NULL;
+               }
+
                mc->mc_info = mi;
                LDAP_STAILQ_INIT( &mc->mc_om_list );
        }
-       mi->mi_suffix = be->be_suffix[0];
-       ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
-       mi->mi_task = ldap_pvt_runqueue_insert( &slapd_rq, 1,
-               asyncmeta_timeout_loop, mi, "asyncmeta_timeout_loop", mi->mi_suffix.bv_val );
-       ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
+       
+       ber_dupbv ( &mi->mi_suffix, &be->be_suffix[0] );
+
+       if ( mi->mi_ntargets > 0 ) {
+               ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
+               mi->mi_task = ldap_pvt_runqueue_insert( &slapd_rq, 1,
+                                                       asyncmeta_timeout_loop, mi, "asyncmeta_timeout_loop", mi->mi_suffix.bv_val );
+               ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
+       }
        return 0;
 }
 
index a6a1f5666a4f4c4ef4defd64d9d8474b16458d40..25faf194fa71608bac206165cd95f1893da01959 100644 (file)
@@ -250,6 +250,13 @@ asyncmeta_back_modify( Operation *op, SlapReply *rs )
                      op->o_log_prefix, op->o_time, current_time );
        }
 
+       if ( mi->mi_ntargets == 0 ) {
+               rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
+               rs->sr_text = "No targets are configured for this database";
+               send_ldap_result(op, rs);
+               return rs->sr_err;
+       }
+
        asyncmeta_new_bm_context(op, rs, &bc, mi->mi_ntargets, mi );
        if (bc == NULL) {
                rs->sr_err = LDAP_OTHER;
index 970566e4dec4ecb0c4d30b1ac0bf33ae3e536db9..a4f42d44080173df9026b3dee4136b89946880aa 100644 (file)
@@ -259,6 +259,14 @@ asyncmeta_back_modrdn( Operation *op, SlapReply *rs )
                Debug(asyncmeta_debug, "==> asyncmeta_back_modrdn[%s]: o_time:[%ld], current time: [%ld]\n",
                      op->o_log_prefix, op->o_time, current_time );
        }
+
+       if ( mi->mi_ntargets == 0 ) {
+               rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
+               rs->sr_text = "No targets are configured for this database";
+               send_ldap_result(op, rs);
+               return rs->sr_err;
+       }
+
        asyncmeta_new_bm_context(op, rs, &bc, mi->mi_ntargets, mi );
        if (bc == NULL) {
                rs->sr_err = LDAP_OTHER;
index 37b9457ff2b0c7b6bd40b8bd4a4781f1fc501c5e..92e76b31b0ef8f1a55a1a39f76bfe7eeb89c70f3 100644 (file)
@@ -687,6 +687,13 @@ asyncmeta_back_search( Operation *op, SlapReply *rs )
        rs_assert_ready( rs );
        rs->sr_flags &= ~REP_ENTRY_MASK; /* paranoia, we can set rs = non-entry */
 
+       if ( mi->mi_ntargets == 0 ) {
+               rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
+               rs->sr_text = "No targets are configured for this database";
+               send_ldap_result(op, rs);
+               return rs->sr_err;
+       }
+
        /*
         * controls are set in ldap_back_dobind()
         *