diff --git a/servers/slapd/overlays/syncprov.c b/servers/slapd/overlays/syncprov.c index acc93a7603383206d65e875f6b6a42fd92fc3d70..c228c5da600da0aa7e5ccab95b7d500435cdebc7 100644 --- a/servers/slapd/overlays/syncprov.c +++ b/servers/slapd/overlays/syncprov.c @@ -3213,6 +3213,49 @@ syncprov_db_otask( return NULL; } +static int +syncprov_db_ocallback( + Operation *op, + SlapReply *rs +) +{ + if ( rs->sr_type == REP_SEARCH && rs->sr_err == LDAP_SUCCESS ) { + if ( rs->sr_entry->e_name.bv_len ) + op->o_callback->sc_private = (void *)1; + } + return LDAP_SUCCESS; +} + +/* ITS#9015 see if the DB is really empty */ +static void * +syncprov_db_otask2( + void *ptr +) +{ + Operation *op = ptr; + SlapReply rs = {REP_RESULT}; + slap_callback cb = {0}; + int rc; + + cb.sc_response = syncprov_db_ocallback; + + op->o_managedsait = SLAP_CONTROL_CRITICAL; + op->o_callback = &cb; + op->o_tag = LDAP_REQ_SEARCH; + op->ors_scope = LDAP_SCOPE_SUBTREE; + op->ors_limit = NULL; + op->ors_slimit = 1; + op->ors_tlimit = SLAP_NO_LIMIT; + op->ors_attrs = slap_anlist_no_attrs; + op->ors_attrsonly = 1; + op->ors_deref = LDAP_DEREF_NEVER; + op->ors_filter = &generic_filter; + op->ors_filterstr = generic_filterstr; + rc = op->o_bd->be_search( op, &rs ); + if ( rc == LDAP_SIZELIMIT_EXCEEDED || cb.sc_private ) + op->ors_slimit = 2; + return NULL; +} /* Read any existing contextCSN from the underlying db. * Then search for any entries newer than that. If no value exists, @@ -3305,6 +3348,20 @@ syncprov_db_open( /* If the DB is genuinely empty, don't generate one either. */ goto out; } + if ( !si->si_contextdn.bv_len ) { + ldap_pvt_thread_t tid; + /* a glue entry here with no contextCSN might mean an empty DB. + * we need to search for children, to be sure. + */ + op->o_req_dn = be->be_suffix[0]; + op->o_req_ndn = be->be_nsuffix[0]; + op->o_bd->bd_info = (BackendInfo *)on->on_info; + ldap_pvt_thread_create( &tid, 0, syncprov_db_otask2, op ); + ldap_pvt_thread_join( tid, NULL ); + if ( op->ors_slimit == 1 ) + goto out; + } + csn.bv_val = csnbuf; csn.bv_len = sizeof( csnbuf ); slap_get_csn( op, &csn, 0 );