}
return rc;
}
+
+/* restore the nrdn/rdn pointers after a txn reset */
+void mdb_dn2id_wrestore (
+ Operation *op,
+ IdScopes *isc
+)
+{
+ MDB_val key, data;
+ diskNode *d;
+ int rc, n, nrlen;
+ char *ptr;
+
+ /* We only need to restore up to the n-1th element,
+ * the nth element will be replaced anyway
+ */
+ key.mv_size = sizeof(ID);
+ for ( n=0; n<isc->numrdns-1; n++ ) {
+ key.mv_data = &isc->scopes[n+1].mid;
+ rc = mdb_cursor_get( isc->mc, &key, &data, MDB_SET );
+ if ( rc )
+ continue;
+ /* we can't use this data directly since its nrlen
+ * is missing the high bit setting, so copy it and
+ * set it properly. we just copy enough to satisfy
+ * mdb_dup_compare.
+ */
+ d = data.mv_data;
+ nrlen = ((d->nrdnlen[0] & 0x7f) << 8) | d->nrdnlen[1];
+ ptr = op->o_tmpalloc( nrlen+2, op->o_tmpmemctx );
+ memcpy( ptr, data.mv_data, nrlen+2 );
+ key.mv_data = &isc->scopes[n].mid;
+ data.mv_data = ptr;
+ data.mv_size = 1;
+ *ptr |= 0x80;
+ mdb_cursor_get( isc->mc, &key, &data, MDB_GET_BOTH );
+
+ /* now we're back to where we wanted to be */
+ d = data.mv_data;
+ isc->nrdns[n].bv_val = d->nrdn;
+ isc->rdns[n].bv_val = d->nrdn+isc->nrdns[n].bv_len+1;
+ }
+}
}
static int
-mdb_waitfixup( Operation *op, ww_ctx *ww, MDB_cursor *mci, MDB_cursor *mcd, ID2 *scopes )
+mdb_waitfixup( Operation *op, ww_ctx *ww, MDB_cursor *mci, MDB_cursor *mcd, IdScopes *isc )
{
+ MDB_val key;
int rc = 0;
ww->flag = 0;
mdb_txn_renew( ww->txn );
mdb_cursor_renew( ww->txn, mci );
mdb_cursor_renew( ww->txn, mcd );
- if ( scopes[0].mid > 1 ) {
- MDB_val key;
- int i;
- key.mv_size = sizeof(ID);
- for ( i=1; i<scopes[0].mid; i++ ) {
- if ( !scopes[i].mval.mv_data )
- continue;
- key.mv_data = &scopes[i].mid;
- mdb_cursor_get( mcd, &key, &scopes[i].mval, MDB_SET );
- }
- }
+ key.mv_size = sizeof(ID);
+ if ( ww->mcd ) { /* scope-based search using dn2id_walk */
+ MDB_val data;
- if ( ww->mcd ) {
- MDB_val key, data;
+ if ( isc->numrdns )
+ mdb_dn2id_wrestore( op, isc );
- key.mv_size = sizeof(ID);
key.mv_data = &ww->key;
data = ww->data;
rc = mdb_cursor_get( mcd, &key, &data, MDB_GET_BOTH );
}
op->o_tmpfree( ww->data.mv_data, op->o_tmpmemctx );
ww->data.mv_data = NULL;
+ } else if ( isc->scopes[0].mid > 1 ) { /* candidate-based search */
+ int i;
+ for ( i=1; i<isc->scopes[0].mid; i++ ) {
+ if ( !isc->scopes[i].mval.mv_data )
+ continue;
+ key.mv_data = &isc->scopes[i].mid;
+ mdb_cursor_get( mcd, &key, &isc->scopes[i].mval, MDB_SET );
+ }
}
return rc;
}
rs->sr_ref = NULL;
if ( wwctx.flag ) {
- rs->sr_err = mdb_waitfixup( op, &wwctx, mci, mcd, scopes );
+ rs->sr_err = mdb_waitfixup( op, &wwctx, mci, mcd, &isc );
if ( rs->sr_err ) {
send_ldap_result( op, rs );
goto done;
goto done;
}
if ( wwctx.flag ) {
- rs->sr_err = mdb_waitfixup( op, &wwctx, mci, mcd, scopes );
+ rs->sr_err = mdb_waitfixup( op, &wwctx, mci, mcd, &isc );
if ( rs->sr_err ) {
send_ldap_result( op, rs );
goto done;