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;
}
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 );
*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;
}
}
}
+ 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;
}
return rc;
} else if ( c->op == LDAP_MOD_DELETE ) {
+
switch( c->type ) {
/* Base attrs */
case LDAP_BACK_CFG_DNCACHE_TTL:
/* 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:
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:
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
/* 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.
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;
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:
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:
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>\"",
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 ));
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;
}