]> git.sur5r.net Git - openldap/commitdiff
ITS#8203 more fixes for #8036/#7904.
authorHoward Chu <hyc@openldap.org>
Fri, 24 Jul 2015 17:34:11 +0000 (18:34 +0100)
committerQuanah Gibson-Mount <quanah@openldap.org>
Tue, 28 Jul 2015 15:57:52 +0000 (10:57 -0500)
servers/slapd/back-mdb/dn2id.c
servers/slapd/back-mdb/proto-mdb.h
servers/slapd/back-mdb/search.c

index d1845f710910f9ddd6c3305365076cfb68febe96..43b82ce076df4a317d8979e9ffcc2f06e99df637 100644 (file)
@@ -922,3 +922,45 @@ mdb_dn2id_walk(
        }
        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;
+       }
+}
index 22cdaab72fa21bcd54246578e6011b79e4eea53b..b7f9c632d019d51e35e9e1a02266b17e6b251f08 100644 (file)
@@ -146,6 +146,10 @@ int mdb_dn2id_walk(
        Operation *op,
        struct IdScopes *isc );
 
+void mdb_dn2id_wrestore(
+       Operation *op,
+       struct IdScopes *isc );
+
 MDB_cmp_func mdb_dup_compare;
 
 /*
index 1a99f974dbc84c0ea763c16967aa82ed4ec58eda..14a2c6bc4f9d24e0dbfd401851429b05d36f82f5 100644 (file)
@@ -358,30 +358,22 @@ mdb_writewait( Operation *op, slap_callback *sc )
 }
 
 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 );
@@ -400,6 +392,14 @@ mdb_waitfixup( Operation *op, ww_ctx *ww, MDB_cursor *mci, MDB_cursor *mcd, ID2
                }
                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;
 }
@@ -1049,7 +1049,7 @@ notfound:
                        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;
@@ -1111,7 +1111,7 @@ notfound:
                                        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;