]> git.ipfire.org Git - thirdparty/openldap.git/commitdiff
ITS#9015 syncprov: fix for zero-length suffix
authorHoward Chu <hyc@openldap.org>
Mon, 14 Sep 2020 23:35:52 +0000 (00:35 +0100)
committerQuanah Gibson-Mount <quanah@openldap.org>
Wed, 16 Sep 2020 17:51:05 +0000 (17:51 +0000)
If the "" glue entry exists and lacks a contextCSN, must perform
an additional search to be sure the DB is otherwise empty. If so,
skip creating the contextCSN.

servers/slapd/overlays/syncprov.c

index acc93a7603383206d65e875f6b6a42fd92fc3d70..c228c5da600da0aa7e5ccab95b7d500435cdebc7 100644 (file)
@@ -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 );