]> git.sur5r.net Git - openldap/commitdiff
ITS#4623 fix from HEAD
authorHoward Chu <hyc@openldap.org>
Thu, 12 Jul 2007 02:36:36 +0000 (02:36 +0000)
committerHoward Chu <hyc@openldap.org>
Thu, 12 Jul 2007 02:36:36 +0000 (02:36 +0000)
servers/slapd/backglue.c
servers/slapd/backover.c
servers/slapd/overlays/syncprov.c
servers/slapd/proto-slap.h

index f0ab5ca02dadc5bbd6231aee7ada458dc32fa8d7..712bc0f51fe55665704cd15184037f19ff98996e 100644 (file)
@@ -610,6 +610,28 @@ glue_close (
        return rc;
 }
 
+static int
+glue_entry_get_rw (
+       Operation               *op,
+       struct berval   *dn,
+       ObjectClass             *oc,
+       AttributeDescription    *ad,
+       int     rw,
+       Entry   **e )
+{
+       BackendDB *b0 = op->o_bd;
+       op->o_bd = glue_back_select( b0, dn );
+       int rc;
+
+       if ( op->o_bd->be_fetch ) {
+               rc = op->o_bd->be_fetch( op, dn, oc, ad, rw, e );
+       } else {
+               rc = LDAP_UNWILLING_TO_PERFORM;
+       }
+       op->o_bd =b0;
+       return rc;
+}
+
 static int
 glue_entry_release_rw (
        Operation *op,
@@ -617,13 +639,10 @@ glue_entry_release_rw (
        int rw
 )
 {
-       BackendDB *b0, b2;
+       BackendDB *b0 = op->o_bd;
        int rc = -1;
 
-       b0 = op->o_bd;
-       b2 = *op->o_bd;
-       b2.bd_info = (BackendInfo *)glue_tool_inst( op->o_bd->bd_info );
-       op->o_bd = glue_back_select (&b2, &e->e_nname);
+       op->o_bd = glue_back_select (b0, &e->e_nname);
 
        if ( op->o_bd->be_release ) {
                rc = op->o_bd->be_release( op, e, rw );
@@ -819,8 +838,6 @@ glue_db_init(
        oi->oi_bi.bi_open = glue_open;
        oi->oi_bi.bi_close = glue_close;
 
-       oi->oi_bi.bi_entry_release_rw = glue_entry_release_rw;
-
        /* Only advertise these if the root DB supports them */
        if ( bi->bi_tool_entry_open )
                oi->oi_bi.bi_tool_entry_open = glue_tool_entry_open;
@@ -1033,6 +1050,9 @@ glue_sub_init()
 
        glue.on_bi.bi_chk_referrals = glue_chk_referrals;
        glue.on_bi.bi_chk_controls = glue_chk_controls;
+       glue.on_bi.bi_entry_get_rw = glue_entry_get_rw;
+       glue.on_bi.bi_entry_release_rw = glue_entry_release_rw;
+
        glue.on_response = glue_response;
 
        return overlay_register( &glue );
index 4bf318972481ccc32b9ae7017967a0f538495c28..923daff801f5b41cdf74c0ed3798647abfaf9918 100644 (file)
@@ -322,6 +322,147 @@ over_access_allowed(
        return rc;
 }
 
+int
+overlay_entry_get_ov(
+       Operation               *op,
+       struct berval   *dn,
+       ObjectClass             *oc,
+       AttributeDescription    *ad,
+       int     rw,
+       Entry   **e,
+       slap_overinst *on )
+{
+       slap_overinfo *oi = on->on_info;
+       BackendDB *be = op->o_bd, db;
+       BackendInfo *bi = op->o_bd->bd_info;
+       int rc = SLAP_CB_CONTINUE;
+
+       for ( ; on; on = on->on_next ) {
+               if ( on->on_bi.bi_entry_get_rw ) {
+                       /* NOTE: do not copy the structure until required */
+                       if ( !SLAP_ISOVERLAY( op->o_bd ) ) {
+                               db = *op->o_bd;
+                               db.be_flags |= SLAP_DBFLAG_OVERLAY;
+                               op->o_bd = &db;
+                       }
+
+                       op->o_bd->bd_info = (BackendInfo *)on;
+                       rc = on->on_bi.bi_entry_get_rw( op, dn,
+                               oc, ad, rw, e );
+                       if ( rc != SLAP_CB_CONTINUE ) break;
+               }
+       }
+
+       if ( rc == SLAP_CB_CONTINUE ) {
+               /* if the database structure was changed, o_bd points to a
+                * copy of the structure; put the original bd_info in place */
+               if ( SLAP_ISOVERLAY( op->o_bd ) ) {
+                       op->o_bd->bd_info = oi->oi_orig;
+               }
+
+               if ( oi->oi_orig->bi_entry_get_rw ) {
+                       rc = oi->oi_orig->bi_entry_get_rw( op, dn,
+                               oc, ad, rw, e );
+               }
+       }
+       /* should not fall thru this far without anything happening... */
+       if ( rc == SLAP_CB_CONTINUE ) {
+               rc = LDAP_UNWILLING_TO_PERFORM;
+       }
+
+       op->o_bd = be;
+       op->o_bd->bd_info = bi;
+
+       return rc;
+}
+
+static int
+over_entry_get_rw(
+       Operation               *op,
+       struct berval   *dn,
+       ObjectClass             *oc,
+       AttributeDescription    *ad,
+       int     rw,
+       Entry   **e )
+{
+       slap_overinfo *oi;
+       slap_overinst *on;
+
+       assert( op->o_bd != NULL );
+
+       oi = op->o_bd->bd_info->bi_private;
+       on = oi->oi_list;
+
+       return overlay_entry_get_ov( op, dn, oc, ad, rw, e, on );
+}
+
+int
+overlay_entry_release_ov(
+       Operation       *op,
+       Entry   *e,
+       int rw,
+       slap_overinst *on )
+{
+       slap_overinfo *oi = on->on_info;
+       BackendDB *be = op->o_bd, db;
+       BackendInfo *bi = op->o_bd->bd_info;
+       int rc = SLAP_CB_CONTINUE;
+
+       for ( ; on; on = on->on_next ) {
+               if ( on->on_bi.bi_entry_release_rw ) {
+                       /* NOTE: do not copy the structure until required */
+                       if ( !SLAP_ISOVERLAY( op->o_bd ) ) {
+                               db = *op->o_bd;
+                               db.be_flags |= SLAP_DBFLAG_OVERLAY;
+                               op->o_bd = &db;
+                       }
+
+                       op->o_bd->bd_info = (BackendInfo *)on;
+                       rc = on->on_bi.bi_entry_release_rw( op, e, rw );
+                       if ( rc != SLAP_CB_CONTINUE ) break;
+               }
+       }
+
+       if ( rc == SLAP_CB_CONTINUE ) {
+               /* if the database structure was changed, o_bd points to a
+                * copy of the structure; put the original bd_info in place */
+               if ( SLAP_ISOVERLAY( op->o_bd ) ) {
+                       op->o_bd->bd_info = oi->oi_orig;
+               }
+
+               if ( oi->oi_orig->bi_entry_release_rw ) {
+                       rc = oi->oi_orig->bi_entry_release_rw( op, e, rw );
+               }
+       }
+       /* should not fall thru this far without anything happening... */
+       if ( rc == SLAP_CB_CONTINUE ) {
+               entry_free( e );
+               rc = 0;
+       }
+
+       op->o_bd = be;
+       op->o_bd->bd_info = bi;
+
+       return rc;
+}
+
+static int
+over_entry_release_rw(
+       Operation       *op,
+       Entry   *e,
+       int rw )
+{
+       slap_overinfo *oi;
+       slap_overinst *on;
+
+       assert( op->o_bd != NULL );
+
+       oi = op->o_bd->bd_info->bi_private;
+       on = oi->oi_list;
+
+       return overlay_entry_release_ov( op, e, rw, on );
+}
+
 static int
 over_acl_group(
        Operation               *op,
@@ -932,6 +1073,8 @@ overlay_config( BackendDB *be, const char *ov )
 
 #ifdef SLAP_OVERLAY_ACCESS
                /* these have specific arglists */
+               bi->bi_entry_get_rw = over_entry_get_rw;
+               bi->bi_entry_release_rw = over_entry_release_rw;
                bi->bi_access_allowed = over_access_allowed;
                bi->bi_acl_group = over_acl_group;
                bi->bi_acl_attribute = over_acl_attribute;
index 3021369f08f6b744d6cf5f2bbf9c04c544a59b13..c3cc0a49659b12a0468e4d225bd53f49ea83ce5c 100644 (file)
@@ -401,6 +401,7 @@ syncprov_findbase( Operation *op, fbase_cookie *fc )
                slap_callback cb = {0};
                Operation fop;
                SlapReply frs = { REP_RESULT };
+               BackendInfo *bi;
                int rc;
 
                fc->fss->s_flags ^= PS_FIND_BASE;
@@ -412,6 +413,7 @@ syncprov_findbase( Operation *op, fbase_cookie *fc )
                fop.o_bd = op->o_bd;
                fop.o_time = op->o_time;
                fop.o_tincr = op->o_tincr;
+               bi = op->o_bd->bd_info;
 
                cb.sc_response = findbase_cb;
                cb.sc_private = fc;
@@ -429,9 +431,8 @@ syncprov_findbase( Operation *op, fbase_cookie *fc )
                fop.ors_filter = &generic_filter;
                fop.ors_filterstr = generic_filterstr;
 
-               fop.o_bd->bd_info = on->on_info->oi_orig;
-               rc = fop.o_bd->be_search( &fop, &frs );
-               fop.o_bd->bd_info = (BackendInfo *)on;
+               rc = overlay_op_walk( &fop, &frs, op_search, on->on_info, on );
+               op->o_bd->bd_info = bi;
        } else {
                ldap_pvt_thread_mutex_unlock( &fc->fss->s_mutex );
                fc->fbase = 1;
@@ -818,7 +819,6 @@ syncprov_qplay( Operation *op, slap_overinst *on, syncops *so )
        int rc = 0;
 
        opc.son = on;
-       op->o_bd->bd_info = (BackendInfo *)on->on_info;
 
        for (;;) {
                ldap_pvt_thread_mutex_lock( &so->s_mutex );
@@ -840,7 +840,7 @@ syncprov_qplay( Operation *op, slap_overinst *on, syncops *so )
                e = NULL;
 
                if ( sr->s_mode != LDAP_SYNC_DELETE ) {
-                       rc = be_entry_get_rw( op, &opc.sndn, NULL, NULL, 0, &e );
+                       rc = overlay_entry_get_ov( op, &opc.sndn, NULL, NULL, 0, &e, on );
                        if ( rc ) {
                                Debug( LDAP_DEBUG_SYNC, "syncprov_qplay: failed to get %s, "
                                        "error (%d), ignoring...\n", opc.sndn.bv_val, rc, 0 );
@@ -852,7 +852,7 @@ syncprov_qplay( Operation *op, slap_overinst *on, syncops *so )
                rc = syncprov_sendresp( op, &opc, so, &e, sr->s_mode );
 
                if ( e ) {
-                       be_entry_release_rw( op, e, 0 );
+                       overlay_entry_release_ov( op, e, 0, on );
                }
 
                ch_free( sr );
@@ -860,7 +860,6 @@ syncprov_qplay( Operation *op, slap_overinst *on, syncops *so )
                if ( rc )
                        break;
        }
-       op->o_bd->bd_info = (BackendInfo *)on;
        return rc;
 }
 
@@ -1060,7 +1059,7 @@ syncprov_matchops( Operation *op, opcookie *opc, int saveit )
 
        fbase_cookie fc;
        syncops *ss, *sprev, *snext;
-       Entry *e;
+       Entry *e = NULL;
        Attribute *a;
        int rc;
        struct berval newdn;
@@ -1082,15 +1081,13 @@ syncprov_matchops( Operation *op, opcookie *opc, int saveit )
                        db = *op->o_bd;
                        op->o_bd = &db;
                }
-               op->o_bd->bd_info = (BackendInfo *)on->on_info;
-               rc = be_entry_get_rw( op, fc.fdn, NULL, NULL, 0, &e );
+               rc = overlay_entry_get_ov( op, fc.fdn, NULL, NULL, 0, &e, on );
                /* If we're sending responses now, make a copy and unlock the DB */
                if ( e && !saveit ) {
                        Entry *e2 = entry_dup( e );
-                       be_entry_release_rw( op, e, 0 );
+                       overlay_entry_release_ov( op, e, 0, on );
                        e = e2;
                }
-               op->o_bd->bd_info = (BackendInfo *)on;
                if ( rc ) {
                        op->o_bd = b0;
                        return;
@@ -2372,7 +2369,7 @@ syncprov_db_open(
        OperationBuffer opbuf = { 0 };
        char ctxcsnbuf[LDAP_LUTIL_CSNSTR_BUFSIZE];
        Operation *op = (Operation *) &opbuf;
-       Entry *e;
+       Entry *e = NULL;
        Attribute *a;
        int rc;
        void *thrctx = NULL;
@@ -2400,9 +2397,8 @@ syncprov_db_open(
 
        ctxcsnbuf[0] = '\0';
 
-       op->o_bd->bd_info = on->on_info->oi_orig;
-       rc = be_entry_get_rw( op, be->be_nsuffix, NULL,
-               slap_schema.si_ad_contextCSN, 0, &e );
+       rc = overlay_entry_get_ov( op, be->be_nsuffix, NULL,
+               slap_schema.si_ad_contextCSN, 0, &e, on );
 
        if ( e ) {
                ldap_pvt_thread_t tid;
@@ -2417,9 +2413,8 @@ syncprov_db_open(
                        si->si_ctxcsnbuf[si->si_ctxcsn.bv_len] = '\0';
                        strcpy( ctxcsnbuf, si->si_ctxcsnbuf );
                }
-               be_entry_release_rw( op, e, 0 );
+               overlay_entry_release_ov( op, e, 0, on );
                if ( !BER_BVISEMPTY( &si->si_ctxcsn ) ) {
-                       op->o_bd->bd_info = (BackendInfo *)on;
                        op->o_req_dn = be->be_suffix[0];
                        op->o_req_ndn = be->be_nsuffix[0];
                        op->ors_scope = LDAP_SCOPE_SUBTREE;
index 6a0c41bb1e1fcfb66091ebd3f94a409ebc6ac176..b31eb08ab1b677b827ca1da86debecb0f115b2a8 100644 (file)
@@ -426,6 +426,19 @@ LDAP_SLAPD_F (int) overlay_op_walk LDAP_P((
        slap_operation_t which,
        slap_overinfo *oi,
        slap_overinst *on ));
+LDAP_SLAPD_F (int) overlay_entry_get_ov LDAP_P((
+       Operation *op,
+       struct berval *dn,
+       ObjectClass *oc,
+       AttributeDescription *ad,
+       int rw,
+       Entry **e,
+       slap_overinst *ov ));
+LDAP_SLAPD_F (int) overlay_entry_release_ov LDAP_P((
+       Operation *op,
+       Entry *e,
+       int rw,
+       slap_overinst *ov ));
 
 /*
  * bconfig.c