From 62bf31e9664464a1df0e0cf83f8bbb4d047f10c8 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Thu, 3 Feb 2022 00:49:52 +0000 Subject: [PATCH] ITS#9584 bconfig: protect cf entries with rwlock Since not all config writes pause the server, must prevent searches from seeing intermediate states. --- servers/slapd/bconfig.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/servers/slapd/bconfig.c b/servers/slapd/bconfig.c index 693cfa3206..730d9b5712 100644 --- a/servers/slapd/bconfig.c +++ b/servers/slapd/bconfig.c @@ -76,6 +76,7 @@ typedef struct { BackendDB cb_db; /* underlying database */ int cb_got_ldif; int cb_use_ldif; + ldap_pvt_thread_rdwr_t cb_rwlock; } CfBackInfo; static CfBackInfo cfBackInfo; @@ -5761,6 +5762,8 @@ config_back_add( Operation *op, SlapReply *rs ) if ( slap_pause_server() < 0 ) dopause = 0; + ldap_pvt_thread_rdwr_wlock( &cfb->cb_rwlock ); + /* Strategy: * 1) check for existence of entry * 2) check for sibling renumbering @@ -5825,6 +5828,7 @@ config_back_add( Operation *op, SlapReply *rs ) } out2:; + ldap_pvt_thread_rdwr_wunlock( &cfb->cb_rwlock ); if ( dopause ) slap_unpause_server(); @@ -6341,6 +6345,7 @@ config_back_modify( Operation *op, SlapReply *rs ) if ( slap_pause_server() < 0 ) do_pause = 0; } + ldap_pvt_thread_rdwr_wlock( &cfb->cb_rwlock ); /* Strategy: * 1) perform the Modify on the cached Entry. @@ -6384,6 +6389,7 @@ config_back_modify( Operation *op, SlapReply *rs ) } } + ldap_pvt_thread_rdwr_wunlock( &cfb->cb_rwlock ); if ( do_pause ) slap_unpause_server(); out: @@ -6551,6 +6557,8 @@ config_back_modrdn( Operation *op, SlapReply *rs ) if ( slap_pause_server() < 0 ) dopause = 0; + ldap_pvt_thread_rdwr_wlock( &cfb->cb_rwlock ); + if ( ce->ce_type == Cft_Schema ) { req_modrdn_s modr = op->oq_modrdn; struct berval rdn; @@ -6629,6 +6637,8 @@ config_back_modrdn( Operation *op, SlapReply *rs ) } } + ldap_pvt_thread_rdwr_wunlock( &cfb->cb_rwlock ); + if ( dopause ) slap_unpause_server(); out: @@ -6691,6 +6701,8 @@ config_back_delete( Operation *op, SlapReply *rs ) if ( slap_pause_server() < 0 ) dopause = 0; + ldap_pvt_thread_rdwr_wlock( &cfb->cb_rwlock ); + if ( ce->ce_type == Cft_Overlay ){ overlay_remove( ce->ce_be, (slap_overinst *)ce->ce_bi, op ); } else if ( ce->ce_type == Cft_Misc ) { @@ -6709,8 +6721,7 @@ config_back_delete( Operation *op, SlapReply *rs ) if ( !oc_at ) { rs->sr_err = LDAP_OTHER; rs->sr_text = "objectclass not found"; - if ( dopause ) slap_unpause_server(); - goto out; + goto out2; } for ( i=0; !BER_BVISNULL(&oc_at->a_nvals[i]); i++ ) { co.co_name = &oc_at->a_nvals[i]; @@ -6727,8 +6738,7 @@ config_back_delete( Operation *op, SlapReply *rs ) /* FIXME: We should return a helpful error message * here */ } - if ( dopause ) slap_unpause_server(); - goto out; + goto out2; } break; } @@ -6736,8 +6746,7 @@ config_back_delete( Operation *op, SlapReply *rs ) if ( ce->ce_be == frontendDB || ce->ce_be == op->o_bd ){ rs->sr_err = LDAP_UNWILLING_TO_PERFORM; rs->sr_text = "Cannot delete config or frontend database"; - if ( dopause ) slap_unpause_server(); - goto out; + goto out2; } if ( ce->ce_be->bd_info->bi_db_close ) { ce->ce_be->bd_info->bi_db_close( ce->ce_be, NULL ); @@ -6798,6 +6807,8 @@ config_back_delete( Operation *op, SlapReply *rs ) ce->ce_entry->e_private=NULL; entry_free(ce->ce_entry); ch_free(ce); +out2: + ldap_pvt_thread_rdwr_wunlock( &cfb->cb_rwlock ); if ( dopause ) slap_unpause_server(); } else { rs->sr_err = LDAP_UNWILLING_TO_PERFORM; @@ -6820,6 +6831,7 @@ config_back_search( Operation *op, SlapReply *rs ) cfb = (CfBackInfo *)op->o_bd->be_private; + ldap_pvt_thread_rdwr_rlock( &cfb->cb_rwlock ); ce = config_find_base( cfb->cb_root, &op->o_req_ndn, &last ); if ( !ce ) { if ( last ) @@ -6854,6 +6866,7 @@ config_back_search( Operation *op, SlapReply *rs ) } out: + ldap_pvt_thread_rdwr_runlock( &cfb->cb_rwlock ); send_ldap_result( op, rs ); return rs->sr_err; } @@ -7590,6 +7603,8 @@ config_back_db_destroy( BackendDB *be, ConfigReply *cr ) ch_free( cfdir.bv_val ); + ldap_pvt_thread_rdwr_destroy( &cfb->cb_rwlock ); + ldap_avl_free( CfOcTree, NULL ); if ( cfb->cb_db.bd_info ) { @@ -7624,6 +7639,8 @@ config_back_db_init( BackendDB *be, ConfigReply* cr ) ber_dupbv( &dn, &be->be_rootdn ); ber_bvarray_add( &be->be_nsuffix, &dn ); + ldap_pvt_thread_rdwr_init( &cfb->cb_rwlock ); + /* Hide from namingContexts */ SLAP_BFLAGS(be) |= SLAP_BFLAG_CONFIG;