]> git.sur5r.net Git - openldap/commitdiff
glue/rwm fixes from HEAD
authorHoward Chu <hyc@openldap.org>
Wed, 3 Jan 2007 09:55:03 +0000 (09:55 +0000)
committerHoward Chu <hyc@openldap.org>
Wed, 3 Jan 2007 09:55:03 +0000 (09:55 +0000)
ITS#3971, #4458, #4638, #4689

servers/slapd/backglue.c
servers/slapd/overlays/rwm.c
servers/slapd/overlays/rwmmap.c
servers/slapd/slap.h

index c44f6fbd30d65b29e0ea0af72adb569642ee3a02..f0ab5ca02dadc5bbd6231aee7ada458dc32fa8d7 100644 (file)
@@ -87,6 +87,15 @@ typedef struct glue_state {
        int nctrls;
 } glue_state;
 
+static int
+glue_op_cleanup( Operation *op, SlapReply *rs )
+{
+       /* This is not a final result */
+       if (rs->sr_type == REP_RESULT )
+               rs->sr_type = REP_GLUE_RESULT;
+       return SLAP_CB_CONTINUE;
+}
+
 static int
 glue_op_response ( Operation *op, SlapReply *rs )
 {
@@ -192,6 +201,7 @@ glue_op_func ( Operation *op, SlapReply *rs )
        case LDAP_REQ_DELETE: which = op_delete; break;
        case LDAP_REQ_MODIFY: which = op_modify; break;
        case LDAP_REQ_MODRDN: which = op_modrdn; break;
+       case LDAP_REQ_EXTENDED: which = op_extended; break;
        default: assert( 0 ); break;
        }
 
@@ -316,7 +326,7 @@ glue_op_search ( Operation *op, SlapReply *rs )
        int i;
        long stoptime = 0, starttime;
        glue_state gs = {NULL, NULL, NULL, 0, 0, 0, 0};
-       slap_callback cb = { NULL, glue_op_response, NULL, NULL };
+       slap_callback cb = { NULL, glue_op_response, glue_op_cleanup, NULL };
        int scope0, tlimit0;
        struct berval dn, ndn, *pdn;
 
@@ -1019,6 +1029,7 @@ glue_sub_init()
        glue.on_bi.bi_op_modrdn = glue_op_func;
        glue.on_bi.bi_op_add = glue_op_func;
        glue.on_bi.bi_op_delete = glue_op_func;
+       glue.on_bi.bi_extended = glue_op_func;
 
        glue.on_bi.bi_chk_referrals = glue_chk_referrals;
        glue.on_bi.bi_chk_controls = glue_chk_controls;
index 8533363828d7b3a71cba493276929f590e19083c..533ec2f7190aa80ba963789d460fec2f05c6f609 100644 (file)
 #include "slap.h"
 #include "rwm.h"
 
+typedef struct rwm_op_state {
+       ber_tag_t r_tag;
+       struct berval ro_dn;
+       struct berval ro_ndn;
+       struct berval r_dn;
+       struct berval r_ndn;
+       OpRequest o_request;
+} rwm_op_state;
+
 static int
-rwm_op_dn_massage( Operation *op, SlapReply *rs, void *cookie )
+rwm_db_destroy( BackendDB *be );
+
+typedef struct rwm_op_cb {
+       slap_callback cb;
+       rwm_op_state ros;
+} rwm_op_cb;
+
+static int
+rwm_op_cleanup( Operation *op, SlapReply *rs )
+{
+       slap_callback   *cb = op->o_callback;
+       rwm_op_state *ros = cb->sc_private;
+
+       if ( rs->sr_type == REP_RESULT || rs->sr_type == REP_EXTENDED ||
+               op->o_abandon || rs->sr_err == SLAPD_ABANDON ) {
+
+               op->o_req_dn = ros->ro_dn;
+               op->o_req_ndn = ros->ro_ndn;
+
+               if ( !BER_BVISEMPTY( &ros->r_dn )) ch_free( ros->r_dn.bv_val );
+               if ( !BER_BVISEMPTY( &ros->r_ndn )) ch_free( ros->r_ndn.bv_val );
+
+               switch( ros->r_tag ) {
+               case LDAP_REQ_COMPARE:
+                       if ( op->orc_ava->aa_value.bv_val != ros->orc_ava->aa_value.bv_val )
+                               op->o_tmpfree( op->orc_ava->aa_value.bv_val, op->o_tmpmemctx );
+                       op->orc_ava = ros->orc_ava;
+                       break;
+               case LDAP_REQ_MODIFY:
+                       slap_mods_free( op->orm_modlist, 1 );
+                       op->orm_modlist = ros->orm_modlist;
+                       break;
+               case LDAP_REQ_MODRDN:
+                       if ( op->orr_newSup != ros->orr_newSup ) {
+                               ch_free( op->orr_newSup->bv_val );
+                               ch_free( op->orr_nnewSup->bv_val );
+                               op->o_tmpfree( op->orr_newSup, op->o_tmpmemctx );
+                               op->o_tmpfree( op->orr_nnewSup, op->o_tmpmemctx );
+                               op->orr_newSup = ros->orr_newSup;
+                               op->orr_nnewSup = ros->orr_nnewSup;
+                       }
+                       break;
+               case LDAP_REQ_SEARCH:
+                       ch_free( op->ors_attrs );
+                       filter_free_x( op, op->ors_filter );
+                       ch_free( op->ors_filterstr.bv_val );
+                       op->ors_attrs = ros->ors_attrs;
+                       op->ors_filter = ros->ors_filter;
+                       op->ors_filterstr = ros->ors_filterstr;
+                       break;
+               case LDAP_REQ_EXTENDED:
+                       if ( op->ore_reqdata != ros->ore_reqdata ) {
+                               ber_bvfree( op->ore_reqdata );
+                               op->ore_reqdata = ros->ore_reqdata;
+                       }
+                       break;
+               default:        break;
+               }
+               op->o_callback = op->o_callback->sc_next;
+               op->o_tmpfree( cb, op->o_tmpmemctx );
+       }
+
+       return SLAP_CB_CONTINUE;
+}
+
+static rwm_op_cb *
+rwm_callback_get( Operation *op, SlapReply *rs )
+{
+       rwm_op_cb       *roc = NULL;
+
+       roc = op->o_tmpalloc( sizeof( struct rwm_op_cb ), op->o_tmpmemctx );
+       roc->cb.sc_cleanup = rwm_op_cleanup;
+       roc->cb.sc_response = NULL;
+       roc->cb.sc_next = op->o_callback;
+       roc->cb.sc_private = &roc->ros;
+       roc->ros.r_tag = op->o_tag;
+       roc->ros.ro_dn = op->o_req_dn;
+       roc->ros.ro_ndn = op->o_req_ndn;
+       roc->ros.o_request = op->o_request;
+       BER_BVZERO( &roc->ros.r_dn );
+       BER_BVZERO( &roc->ros.r_ndn );
+
+       return roc;
+}
+
+static int
+rwm_op_dn_massage( Operation *op, SlapReply *rs, void *cookie,
+       rwm_op_state *ros )
 {
        slap_overinst           *on = (slap_overinst *) op->o_bd->bd_info;
        struct ldaprwmap        *rwmap = 
@@ -74,12 +170,12 @@ rwm_op_dn_massage( Operation *op, SlapReply *rs, void *cookie )
        }
 
        if ( op->o_req_dn.bv_val != op->o_req_ndn.bv_val ) {
-               op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx );
                op->o_req_dn = dn;
+               ros->r_dn  = dn;
        } else {
                op->o_req_dn = ndn;
        }
-       op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx );
+       ros->r_ndn = ndn;
        op->o_req_ndn = ndn;
 
        return LDAP_SUCCESS;
@@ -98,11 +194,13 @@ rwm_op_add( Operation *op, SlapReply *rs )
        char                    *olddn = op->o_req_dn.bv_val;
        int                     isupdate;
 
+       rwm_op_cb *roc = rwm_callback_get( op, rs );
+
 #ifdef ENABLE_REWRITE
-       rc = rwm_op_dn_massage( op, rs, "addDN" );
+       rc = rwm_op_dn_massage( op, rs, "addDN", &roc->ros );
 #else /* ! ENABLE_REWRITE */
        rc = 1;
-       rc = rwm_op_dn_massage( op, rs, &rc );
+       rc = rwm_op_dn_massage( op, rs, &rc, &roc->ros );
 #endif /* ! ENABLE_REWRITE */
        if ( rc != LDAP_SUCCESS ) {
                op->o_bd->bd_info = (BackendInfo *)on->on_info;
@@ -222,7 +320,8 @@ cleanup_attr:;
                attr_free( a );
        }
 
-       /* TODO: map attribute types, values of DN-valued attributes ... */
+       op->o_callback = &roc->cb;
+
        return SLAP_CB_CONTINUE;
 }
 
@@ -258,11 +357,13 @@ rwm_op_bind( Operation *op, SlapReply *rs )
        slap_overinst           *on = (slap_overinst *) op->o_bd->bd_info;
        int                     rc;
 
+       rwm_op_cb *roc = rwm_callback_get( op, rs );
+
 #ifdef ENABLE_REWRITE
-       rc = rwm_op_dn_massage( op, rs, "bindDN" );
+       rc = rwm_op_dn_massage( op, rs, "bindDN", &roc->ros );
 #else /* ! ENABLE_REWRITE */
        rc = 1;
-       rc = rwm_op_dn_massage( op, rs, &rc );
+       rc = rwm_op_dn_massage( op, rs, &rc, &roc->ros );
 #endif /* ! ENABLE_REWRITE */
        if ( rc != LDAP_SUCCESS ) {
                op->o_bd->bd_info = (BackendInfo *)on->on_info;
@@ -270,6 +371,8 @@ rwm_op_bind( Operation *op, SlapReply *rs )
                return -1;
        }
 
+       op->o_callback = &roc->cb;
+
        return SLAP_CB_CONTINUE;
 }
 
@@ -295,14 +398,15 @@ rwm_op_compare( Operation *op, SlapReply *rs )
                        (struct ldaprwmap *)on->on_bi.bi_private;
 
        int                     rc;
-       struct berval           mapped_at = BER_BVNULL,
-                               mapped_vals[2] = { BER_BVNULL, BER_BVNULL };
+       struct berval mapped_vals[2] = { BER_BVNULL, BER_BVNULL };
+
+       rwm_op_cb *roc = rwm_callback_get( op, rs );
 
 #ifdef ENABLE_REWRITE
-       rc = rwm_op_dn_massage( op, rs, "compareDN" );
+       rc = rwm_op_dn_massage( op, rs, "compareDN", &roc->ros );
 #else /* ! ENABLE_REWRITE */
        rc = 1;
-       rc = rwm_op_dn_massage( op, rs, &rc );
+       rc = rwm_op_dn_massage( op, rs, &rc, &roc->ros );
 #endif /* ! ENABLE_REWRITE */
        if ( rc != LDAP_SUCCESS ) {
                op->o_bd->bd_info = (BackendInfo *)on->on_info;
@@ -323,9 +427,9 @@ rwm_op_compare( Operation *op, SlapReply *rs )
                        return -1;
 
                } else if ( mapped_vals[0].bv_val != op->orc_ava->aa_value.bv_val ) {
-                       ber_bvreplace_x( &op->orc_ava->aa_value, &mapped_vals[0], op->o_tmpmemctx );
+                       ber_dupbv_x( &op->orc_ava->aa_value, &mapped_vals[0],
+                               op->o_tmpmemctx );
                }
-               mapped_at = op->orc_ava->aa_desc->ad_cname;
 
        } else {
                struct ldapmapping      *mapping = NULL;
@@ -373,13 +477,15 @@ rwm_op_compare( Operation *op, SlapReply *rs )
                                 * already freed the old value, so now 
                                 * it's invalid */
                                ber_dupbv_x( &op->orc_ava->aa_value, &mapped_vals[0],
-                                               op->o_tmpmemctx );
+                                       op->o_tmpmemctx );
                                ber_memfree_x( mapped_vals[ 0 ].bv_val, NULL );
                        }
                }
                op->orc_ava->aa_desc = ad;
        }
 
+       op->o_callback = &roc->cb;
+
        return SLAP_CB_CONTINUE;
 }
 
@@ -389,11 +495,13 @@ rwm_op_delete( Operation *op, SlapReply *rs )
        slap_overinst           *on = (slap_overinst *) op->o_bd->bd_info;
        int                     rc;
 
+       rwm_op_cb *roc = rwm_callback_get( op, rs );
+
 #ifdef ENABLE_REWRITE
-       rc = rwm_op_dn_massage( op, rs, "deleteDN" );
+       rc = rwm_op_dn_massage( op, rs, "deleteDN", &roc->ros );
 #else /* ! ENABLE_REWRITE */
        rc = 1;
-       rc = rwm_op_dn_massage( op, rs, &rc );
+       rc = rwm_op_dn_massage( op, rs, &rc, &roc->ros );
 #endif /* ! ENABLE_REWRITE */
        if ( rc != LDAP_SUCCESS ) {
                op->o_bd->bd_info = (BackendInfo *)on->on_info;
@@ -401,6 +509,8 @@ rwm_op_delete( Operation *op, SlapReply *rs )
                return -1;
        }
 
+       op->o_callback = &roc->cb;
+
        return SLAP_CB_CONTINUE;
 }
 
@@ -415,11 +525,13 @@ rwm_op_modify( Operation *op, SlapReply *rs )
        Modifications           **mlp;
        int                     rc;
 
+       rwm_op_cb *roc = rwm_callback_get( op, rs );
+
 #ifdef ENABLE_REWRITE
-       rc = rwm_op_dn_massage( op, rs, "modifyDN" );
+       rc = rwm_op_dn_massage( op, rs, "modifyDN", &roc->ros );
 #else /* ! ENABLE_REWRITE */
        rc = 1;
-       rc = rwm_op_dn_massage( op, rs, &rc );
+       rc = rwm_op_dn_massage( op, rs, &rc, &roc->ros );
 #endif /* ! ENABLE_REWRITE */
        if ( rc != LDAP_SUCCESS ) {
                op->o_bd->bd_info = (BackendInfo *)on->on_info;
@@ -433,8 +545,13 @@ rwm_op_modify( Operation *op, SlapReply *rs )
                Modifications           *ml;
                struct ldapmapping      *mapping = NULL;
 
-               if ( (*mlp)->sml_desc == slap_schema.si_ad_objectClass 
-                               || (*mlp)->sml_desc == slap_schema.si_ad_structuralObjectClass )
+               /* duplicate the modlist */
+               ml = ch_malloc( sizeof( Modifications ));
+               *ml = **mlp;
+               *mlp = ml;
+
+               if ( ml->sml_desc == slap_schema.si_ad_objectClass 
+                               || ml->sml_desc == slap_schema.si_ad_structuralObjectClass )
                {
                        is_oc = 1;
 
@@ -446,7 +563,7 @@ rwm_op_modify( Operation *op, SlapReply *rs )
                        int                     drop_missing;
 
                        drop_missing = rwm_mapping( &rwmap->rwm_at,
-                                       &(*mlp)->sml_desc->ad_cname,
+                                       &ml->sml_desc->ad_cname,
                                        &mapping, RWM_MAP );
                        if ( drop_missing || ( mapping != NULL && BER_BVISNULL( &mapping->m_dst ) ) )
                        {
@@ -454,18 +571,36 @@ rwm_op_modify( Operation *op, SlapReply *rs )
                        }
                }
 
-               if ( (*mlp)->sml_values != NULL ) {
+               if ( ml->sml_values != NULL ) {
+                       int i, num;
+                       struct berval *bva;
+
+                       for ( num = 0; !BER_BVISNULL( &ml->sml_values[ num ] ); num++ )
+                               /* count values */ ;
+
+                       bva = ch_malloc( (num+1) * sizeof( struct berval ));
+                       for (i=0; i<num; i++)
+                               ber_dupbv( &bva[i], &ml->sml_values[i] );
+                       BER_BVZERO( &bva[i] );
+                       ml->sml_values = bva;
+
+                       if ( ml->sml_nvalues ) {
+                               bva = ch_malloc( (num+1) * sizeof( struct berval ));
+                               for (i=0; i<num; i++)
+                                       ber_dupbv( &bva[i], &ml->sml_nvalues[i] );
+                               BER_BVZERO( &bva[i] );
+                               ml->sml_nvalues = bva;
+                       }
+
                        if ( is_oc ) {
                                int     last, j;
 
-                               for ( last = 0; !BER_BVISNULL( &(*mlp)->sml_values[ last ] ); last++ )
-                                       /* count values */ ;
-                               last--;
+                               last = num-1;
 
-                               for ( j = 0; !BER_BVISNULL( &(*mlp)->sml_values[ j ] ); j++ ) {
+                               for ( j = 0; !BER_BVISNULL( &ml->sml_values[ j ] ); j++ ) {
                                        struct ldapmapping      *oc_mapping = NULL;
                
-                                       ( void )rwm_mapping( &rwmap->rwm_oc, &(*mlp)->sml_values[ j ],
+                                       ( void )rwm_mapping( &rwmap->rwm_oc, &ml->sml_values[ j ],
                                                        &oc_mapping, RWM_MAP );
                                        if ( oc_mapping == NULL ) {
                                                if ( rwmap->rwm_at.drop_missing ) {
@@ -473,47 +608,47 @@ rwm_op_modify( Operation *op, SlapReply *rs )
                                                         * if the resulting entry is inconsistent, that's
                                                         * the relayed database's business...
                                                         */
-                                                       ch_free( (*mlp)->sml_values[ j ].bv_val );
                                                        if ( last > j ) {
-                                                               (*mlp)->sml_values[ j ] = (*mlp)->sml_values[ last ];
+                                                               ch_free( ml->sml_values[ j ].bv_val );
+                                                               ml->sml_values[ j ] = ml->sml_values[ last ];
                                                        }
-                                                       BER_BVZERO( &(*mlp)->sml_values[ last ] );
+                                                       BER_BVZERO( &ml->sml_values[ last ] );
                                                        last--;
                                                        j--;
                                                }
        
                                        } else {
-                                               ch_free( (*mlp)->sml_values[ j ].bv_val );
-                                               ber_dupbv( &(*mlp)->sml_values[ j ], &oc_mapping->m_dst );
+                                               ch_free( ml->sml_values[ j ].bv_val );
+                                               ber_dupbv( &ml->sml_values[ j ], &oc_mapping->m_dst );
                                        }
                                }
 
                        } else {
-                               if ( (*mlp)->sml_desc->ad_type->sat_syntax == slap_schema.si_syn_distinguishedName
+                               if ( ml->sml_desc->ad_type->sat_syntax == slap_schema.si_syn_distinguishedName
                                                || ( mapping != NULL && mapping->m_dst_ad->ad_type->sat_syntax == slap_schema.si_syn_distinguishedName ) )
                                {
 #ifdef ENABLE_REWRITE
                                        rc = rwm_dnattr_rewrite( op, rs, "modifyAttrDN",
-                                                       (*mlp)->sml_values,
-                                                       (*mlp)->sml_nvalues ? &(*mlp)->sml_nvalues : NULL );
+                                                       ml->sml_values,
+                                                       ml->sml_nvalues ? &ml->sml_nvalues : NULL );
 #else /* ! ENABLE_REWRITE */
                                        rc = 1;
                                        rc = rwm_dnattr_rewrite( op, rs, &rc, 
-                                                       (*mlp)->sml_values,
-                                                       (*mlp)->sml_nvalues ? &(*mlp)->sml_nvalues : NULL );
+                                                       ml->sml_values,
+                                                       ml->sml_nvalues ? &ml->sml_nvalues : NULL );
 #endif /* ! ENABLE_REWRITE */
 
-                               } else if ( (*mlp)->sml_desc == slap_schema.si_ad_ref ) {
+                               } else if ( ml->sml_desc == slap_schema.si_ad_ref ) {
 #ifdef ENABLE_REWRITE
                                        rc = rwm_referral_rewrite( op, rs,
                                                        "referralAttrDN",
-                                                       (*mlp)->sml_values,
-                                                       (*mlp)->sml_nvalues ? &(*mlp)->sml_nvalues : NULL );
+                                                       ml->sml_values,
+                                                       ml->sml_nvalues ? &ml->sml_nvalues : NULL );
 #else /* ! ENABLE_REWRITE */
                                        rc = 1;
                                        rc = rwm_referral_rewrite( op, rs, &rc,
-                                                       (*mlp)->sml_values,
-                                                       (*mlp)->sml_nvalues ? &(*mlp)->sml_nvalues : NULL );
+                                                       ml->sml_values,
+                                                       ml->sml_nvalues ? &ml->sml_nvalues : NULL );
 #endif /* ! ENABLE_REWRITE */
                                        if ( rc != LDAP_SUCCESS ) {
                                                goto cleanup_mod;
@@ -530,10 +665,10 @@ next_mod:;
                if ( mapping != NULL ) {
                        /* use new attribute description */
                        assert( mapping->m_dst_ad != NULL );
-                       (*mlp)->sml_desc = mapping->m_dst_ad;
+                       ml->sml_desc = mapping->m_dst_ad;
                }
 
-               mlp = &(*mlp)->sml_next;
+               mlp = &ml->sml_next;
                continue;
 
 cleanup_mod:;
@@ -543,6 +678,8 @@ cleanup_mod:;
                free( ml );
        }
 
+       op->o_callback = &roc->cb;
+
        return SLAP_CB_CONTINUE;
 }
 
@@ -555,6 +692,8 @@ rwm_op_modrdn( Operation *op, SlapReply *rs )
        
        int                     rc;
 
+       rwm_op_cb *roc = rwm_callback_get( op, rs );
+
        if ( op->orr_newSup ) {
                dncookie        dc;
                struct berval   nnewSup = BER_BVNULL;
@@ -582,8 +721,10 @@ rwm_op_modrdn( Operation *op, SlapReply *rs )
                }
 
                if ( op->orr_newSup->bv_val != newSup.bv_val ) {
-                       op->o_tmpfree( op->orr_newSup->bv_val, op->o_tmpmemctx );
-                       op->o_tmpfree( op->orr_nnewSup->bv_val, op->o_tmpmemctx );
+                       op->orr_newSup = op->o_tmpalloc( sizeof( struct berval ),
+                               op->o_tmpmemctx );
+                       op->orr_nnewSup = op->o_tmpalloc( sizeof( struct berval ),
+                               op->o_tmpmemctx );
                        *op->orr_newSup = newSup;
                        *op->orr_nnewSup = nnewSup;
                }
@@ -593,61 +734,43 @@ rwm_op_modrdn( Operation *op, SlapReply *rs )
         * Rewrite the dn, if needed
         */
 #ifdef ENABLE_REWRITE
-       rc = rwm_op_dn_massage( op, rs, "renameDN" );
+       rc = rwm_op_dn_massage( op, rs, "renameDN", &roc->ros );
 #else /* ! ENABLE_REWRITE */
        rc = 1;
-       rc = rwm_op_dn_massage( op, rs, &rc );
+       rc = rwm_op_dn_massage( op, rs, &rc, &roc->ros );
 #endif /* ! ENABLE_REWRITE */
        if ( rc != LDAP_SUCCESS ) {
                op->o_bd->bd_info = (BackendInfo *)on->on_info;
                send_ldap_error( op, rs, rc, "renameDN massage error" );
+               if ( op->orr_newSup != roc->ros.orr_newSup ) {
+                       ch_free( op->orr_newSup->bv_val );
+                       ch_free( op->orr_nnewSup->bv_val );
+                       op->o_tmpfree( op->orr_newSup, op->o_tmpmemctx );
+                       op->o_tmpfree( op->orr_nnewSup, op->o_tmpmemctx );
+                       op->orr_newSup = roc->ros.orr_newSup;
+                       op->orr_nnewSup = roc->ros.orr_nnewSup;
+               }
                return -1;
        }
 
        /* TODO: rewrite newRDN, attribute types, 
         * values of DN-valued attributes ... */
-       return SLAP_CB_CONTINUE;
-}
 
-static slap_callback   rwm_cb;
+       op->o_callback = &roc->cb;
 
-static void
-rwm_keyfree(
-       void            *key,
-       void            *data )
-{
-       ber_memfree_x( data, NULL );
+       return SLAP_CB_CONTINUE;
 }
 
-static slap_callback *
-rwm_callback_get( Operation *op )
-{
-       void            *data = NULL;
-
-       if ( op->o_threadctx == NULL ) {
-               return &rwm_cb;
-       }
-
-       ldap_pvt_thread_pool_getkey( op->o_threadctx,
-                       rwm_keyfree, &data, NULL );
-       if ( data == NULL ) {
-               data = ch_calloc( sizeof( slap_callback ), 1 );
-               ldap_pvt_thread_pool_setkey( op->o_threadctx,
-                               rwm_keyfree, data, rwm_keyfree );
-       }
-
-       return (slap_callback *)data;
-}
 
 static int
 rwm_swap_attrs( Operation *op, SlapReply *rs )
 {
        slap_callback   *cb = op->o_callback;
-       AttributeName   *an = (AttributeName *)cb->sc_private;
+       rwm_op_state *ros = cb->sc_private;
 
-       rs->sr_attrs = an;
+       rs->sr_attrs = ros->ors_attrs;
        
-       return SLAP_CB_CONTINUE;
+       return SLAP_CB_CONTINUE;
 }
 
 static int
@@ -663,19 +786,20 @@ rwm_op_search( Operation *op, SlapReply *rs )
        struct berval           fstr = BER_BVNULL;
        Filter                  *f = NULL;
 
-       slap_callback           *cb = NULL;
        AttributeName           *an = NULL;
 
        char                    *text = NULL;
 
+       rwm_op_cb *roc = rwm_callback_get( op, rs );
+
 #ifdef ENABLE_REWRITE
        rc = rewrite_session_var_set( rwmap->rwm_rw, op->o_conn,
                "searchFilter", op->ors_filterstr.bv_val );
        if ( rc == LDAP_SUCCESS )
-               rc = rwm_op_dn_massage( op, rs, "searchDN" );
+               rc = rwm_op_dn_massage( op, rs, "searchDN", &roc->ros );
 #else /* ! ENABLE_REWRITE */
        rc = 1;
-       rc = rwm_op_dn_massage( op, rs, &rc );
+       rc = rwm_op_dn_massage( op, rs, &rc, &roc->ros );
 #endif /* ! ENABLE_REWRITE */
        if ( rc != LDAP_SUCCESS ) {
                text = "searchDN massage error";
@@ -708,14 +832,6 @@ rwm_op_search( Operation *op, SlapReply *rs )
                goto error_return;
        }
 
-       if ( !BER_BVISNULL( &op->ors_filterstr ) ) {
-               ch_free( op->ors_filterstr.bv_val );
-       }
-
-       if( op->ors_filter ) {
-               filter_free_x( op, op->ors_filter );
-       }
-
        op->ors_filter = f;
        op->ors_filterstr = fstr;
 
@@ -726,15 +842,10 @@ rwm_op_search( Operation *op, SlapReply *rs )
                goto error_return;
        }
 
-       cb = rwm_callback_get( op );
-
-       cb->sc_response = rwm_swap_attrs;
-       cb->sc_cleanup = NULL;
-       cb->sc_private = (void *)op->ors_attrs;
-       cb->sc_next = op->o_callback;
-
-       op->o_callback = cb;
        op->ors_attrs = an;
+       roc->cb.sc_response = rwm_swap_attrs;
+
+       op->o_callback = &roc->cb;
 
        return SLAP_CB_CONTINUE;
 
@@ -751,6 +862,8 @@ error_return:;
                ch_free( fstr.bv_val );
        }
 
+       op->oq_search = roc->ros.oq_search;
+
        op->o_bd->bd_info = (BackendInfo *)on->on_info;
        send_ldap_error( op, rs, rc, text );
 
@@ -758,17 +871,130 @@ error_return:;
 
 }
 
+static int
+rwm_exop_passwd( Operation *op, SlapReply *rs )
+{
+       slap_overinst           *on = (slap_overinst *) op->o_bd->bd_info;
+       int                     rc;
+       rwm_op_cb *roc;
+
+       struct berval   id = BER_BVNULL,
+                       pwold = BER_BVNULL,
+                       pwnew = BER_BVNULL;
+       BerElement *ber = NULL;
+
+       if ( !BER_BVISNULL( &op->o_req_ndn ) ) {
+               return LDAP_SUCCESS;
+       }
+
+       if ( !SLAP_ISGLOBALOVERLAY( op->o_bd ) ) {
+               rs->sr_err = LDAP_OTHER;
+               return rs->sr_err;
+       }
+
+       rs->sr_err = slap_passwd_parse( op->ore_reqdata, &id,
+               &pwold, &pwnew, &rs->sr_text );
+       if ( rs->sr_err != LDAP_SUCCESS ) {
+               return rs->sr_err;
+       }
+
+       if ( !BER_BVISNULL( &id ) ) {
+               rs->sr_err = dnPrettyNormal( NULL, &id, &op->o_req_dn,
+                               &op->o_req_ndn, op->o_tmpmemctx );
+               if ( rs->sr_err != LDAP_SUCCESS ) {
+                       rs->sr_text = "Invalid DN";
+                       return rs->sr_err;
+               }
+
+       } else {
+               ber_dupbv_x( &op->o_req_dn, &op->o_dn, op->o_tmpmemctx );
+               ber_dupbv_x( &op->o_req_ndn, &op->o_ndn, op->o_tmpmemctx );
+       }
+
+       roc = rwm_callback_get( op, rs );
+
+#ifdef ENABLE_REWRITE
+       rc = rwm_op_dn_massage( op, rs, "extendedDN", &roc->ros );
+#else /* ! ENABLE_REWRITE */
+       rc = 1;
+       rc = rwm_op_dn_massage( op, rs, &rc, &roc->ros );
+#endif /* ! ENABLE_REWRITE */
+       if ( rc != LDAP_SUCCESS ) {
+               op->o_bd->bd_info = (BackendInfo *)on->on_info;
+               send_ldap_error( op, rs, rc, "extendedDN massage error" );
+               return -1;
+       }
+
+       ber = ber_alloc_t( LBER_USE_DER );
+       if ( !ber ) {
+               rs->sr_err = LDAP_OTHER;
+               rs->sr_text = "No memory";
+               return rs->sr_err;
+       }
+       ber_printf( ber, "{" );
+       if ( !BER_BVISNULL( &id )) {
+               ber_printf( ber, "tO", LDAP_TAG_EXOP_MODIFY_PASSWD_ID, 
+                       &op->o_req_dn );
+       }
+       if ( !BER_BVISNULL( &pwold )) {
+               ber_printf( ber, "tO", LDAP_TAG_EXOP_MODIFY_PASSWD_OLD, &pwold );
+       }
+       if ( !BER_BVISNULL( &pwnew )) {
+               ber_printf( ber, "tO", LDAP_TAG_EXOP_MODIFY_PASSWD_NEW, &pwnew );
+       }
+       ber_printf( ber, "N}" );
+       ber_flatten( ber, &op->ore_reqdata );
+       ber_free( ber, 1 );
+
+       op->o_callback = &roc->cb;
+
+       return SLAP_CB_CONTINUE;
+}
+
+static struct exop {
+       struct berval   oid;
+       BI_op_extended  *extended;
+} exop_table[] = {
+       { BER_BVC(LDAP_EXOP_MODIFY_PASSWD),     rwm_exop_passwd },
+       { BER_BVNULL, NULL }
+};
+
 static int
 rwm_extended( Operation *op, SlapReply *rs )
 {
        slap_overinst           *on = (slap_overinst *) op->o_bd->bd_info;
        int                     rc;
+       rwm_op_cb *roc;
+
+       int     i;
+
+       for ( i = 0; exop_table[i].extended != NULL; i++ ) {
+               if ( bvmatch( &exop_table[i].oid, &op->oq_extended.rs_reqoid ) )
+               {
+                       rc = exop_table[i].extended( op, rs );
+                       switch ( rc ) {
+                       case LDAP_SUCCESS:
+                               break;
+
+                       case SLAP_CB_CONTINUE:
+                       case SLAPD_ABANDON:
+                               return rc;
+
+                       default:
+                               send_ldap_result( op, rs );
+                               return rc;
+                       }
+                       break;
+               }
+       }
+
+       roc = rwm_callback_get( op, rs );
 
 #ifdef ENABLE_REWRITE
-       rc = rwm_op_dn_massage( op, rs, "extendedDN" );
+       rc = rwm_op_dn_massage( op, rs, "extendedDN", &roc->ros );
 #else /* ! ENABLE_REWRITE */
        rc = 1;
-       rc = rwm_op_dn_massage( op, rs, &rc );
+       rc = rwm_op_dn_massage( op, rs, &rc, &roc->ros );
 #endif /* ! ENABLE_REWRITE */
        if ( rc != LDAP_SUCCESS ) {
                op->o_bd->bd_info = (BackendInfo *)on->on_info;
@@ -777,6 +1003,8 @@ rwm_extended( Operation *op, SlapReply *rs )
        }
 
        /* TODO: rewrite/map extended data ? ... */
+       op->o_callback = &roc->cb;
+
        return SLAP_CB_CONTINUE;
 }
 
@@ -1150,12 +1378,11 @@ rwm_chk_referrals( Operation *op, SlapReply *rs )
 
 static int
 rwm_rw_config(
-    BackendDB  *be,
-    const char *fname,
-    int                lineno,
-    int                argc,
-    char       **argv
-)
+       BackendDB       *be,
+       const char      *fname,
+       int             lineno,
+       int             argc,
+       char            **argv )
 {
 #ifdef ENABLE_REWRITE
        slap_overinst           *on = (slap_overinst *) be->bd_info;
@@ -1175,12 +1402,11 @@ rwm_rw_config(
 
 static int
 rwm_suffixmassage_config(
-    BackendDB  *be,
-    const char *fname,
-    int                lineno,
-    int                argc,
-    char       **argv
-)
+       BackendDB       *be,
+       const char      *fname,
+       int             lineno,
+       int             argc,
+       char            **argv )
 {
        slap_overinst           *on = (slap_overinst *) be->bd_info;
        struct ldaprwmap        *rwmap = 
@@ -1269,12 +1495,11 @@ rwm_suffixmassage_config(
 
 static int
 rwm_m_config(
-    BackendDB  *be,
-    const char *fname,
-    int                lineno,
-    int                argc,
-    char       **argv
-)
+       BackendDB       *be,
+       const char      *fname,
+       int             lineno,
+       int             argc,
+       char            **argv )
 {
        slap_overinst           *on = (slap_overinst *) be->bd_info;
        struct ldaprwmap        *rwmap = 
@@ -1301,16 +1526,6 @@ rwm_response( Operation *op, SlapReply *rs )
 
        switch( op->o_tag ) {
        case LDAP_REQ_SEARCH:
-               /* Note: the operation attrs are remapped */
-               if ( rs->sr_type == REP_RESULT
-                               && op->ors_attrs != NULL
-                               && op->ors_attrs != rs->sr_attrs )
-               {
-                       ch_free( op->ors_attrs );
-                       op->ors_attrs = rs->sr_attrs;
-               }
-               /* fall thru */
-
        case LDAP_REQ_BIND:
        case LDAP_REQ_ADD:
        case LDAP_REQ_DELETE:
@@ -1352,12 +1567,11 @@ rwm_response( Operation *op, SlapReply *rs )
 
 static int
 rwm_db_config(
-    BackendDB  *be,
-    const char *fname,
-    int                lineno,
-    int                argc,
-    char       **argv
-)
+       BackendDB       *be,
+       const char      *fname,
+       int             lineno,
+       int             argc,
+       char            **argv )
 {
        slap_overinst           *on = (slap_overinst *) be->bd_info;
        struct ldaprwmap        *rwmap = 
@@ -1425,8 +1639,7 @@ rwm_db_config(
 
 static int
 rwm_db_init(
-       BackendDB *be
-)
+       BackendDB       *be )
 {
        slap_overinst           *on = (slap_overinst *) be->bd_info;
        struct ldapmapping      *mapping = NULL;
@@ -1434,14 +1647,15 @@ rwm_db_init(
 #ifdef ENABLE_REWRITE
        char                    *rargv[ 3 ];
 #endif /* ENABLE_REWRITE */
+       int                     rc = 0;
 
        rwmap = (struct ldaprwmap *)ch_calloc( 1, sizeof( struct ldaprwmap ) );
 
 #ifdef ENABLE_REWRITE
        rwmap->rwm_rw = rewrite_info_init( REWRITE_MODE_USE_DEFAULT );
        if ( rwmap->rwm_rw == NULL ) {
-               ch_free( rwmap );
-               return -1;
+               rc = -1;
+               goto error_return;
        }
 
        /* this rewriteContext by default must be null;
@@ -1460,18 +1674,23 @@ rwm_db_init(
        if ( rwm_map_init( &rwmap->rwm_oc, &mapping ) != LDAP_SUCCESS ||
                        rwm_map_init( &rwmap->rwm_at, &mapping ) != LDAP_SUCCESS )
        {
-               return 1;
+               rc = 1;
+               goto error_return;
        }
 
+error_return:;
        on->on_bi.bi_private = (void *)rwmap;
 
-       return 0;
+       if ( rc ) {
+               (void)rwm_db_destroy( be );
+       }
+
+       return rc;
 }
 
 static int
 rwm_db_destroy(
-       BackendDB *be
-)
+       BackendDB       *be )
 {
        slap_overinst   *on = (slap_overinst *) be->bd_info;
        int             rc = 0;
@@ -1503,8 +1722,11 @@ rwm_db_destroy(
 
 static slap_overinst rwm = { { NULL } };
 
+#if SLAPD_OVER_RWM == SLAPD_MOD_DYNAMIC
+static
+#endif /* SLAPD_OVER_RWM == SLAPD_MOD_DYNAMIC */
 int
-rwm_initialize(void)
+rwm_initialize( void )
 {
        memset( &rwm, 0, sizeof( slap_overinst ) );
 
index 5fd7c1f241f17f27872718569aee5fe7a3bb2d3c..337795a70778cc24101e6ecd5d3e50420b400f5c 100644 (file)
@@ -449,6 +449,7 @@ rwm_int_filter_map_rewrite(
 {
        int             i;
        Filter          *p;
+       AttributeDescription *ad;
        struct berval   atmp,
                        vtmp,
                        *tmp;
@@ -475,7 +476,8 @@ rwm_int_filter_map_rewrite(
 
        switch ( f->f_choice ) {
        case LDAP_FILTER_EQUALITY:
-               if ( map_attr_value( dc, &f->f_av_desc, &atmp,
+               ad = f->f_av_desc;
+               if ( map_attr_value( dc, &ad, &atmp,
                                        &f->f_av_value, &vtmp, RWM_MAP ) )
                {
                        goto computed;
@@ -491,7 +493,8 @@ rwm_int_filter_map_rewrite(
                break;
 
        case LDAP_FILTER_GE:
-               if ( map_attr_value( dc, &f->f_av_desc, &atmp,
+               ad = f->f_av_desc;
+               if ( map_attr_value( dc, &ad, &atmp,
                                        &f->f_av_value, &vtmp, RWM_MAP ) )
                {
                        goto computed;
@@ -507,7 +510,8 @@ rwm_int_filter_map_rewrite(
                break;
 
        case LDAP_FILTER_LE:
-               if ( map_attr_value( dc, &f->f_av_desc, &atmp,
+               ad = f->f_av_desc;
+               if ( map_attr_value( dc, &ad, &atmp,
                                        &f->f_av_value, &vtmp, RWM_MAP ) )
                {
                        goto computed;
@@ -523,7 +527,8 @@ rwm_int_filter_map_rewrite(
                break;
 
        case LDAP_FILTER_APPROX:
-               if ( map_attr_value( dc, &f->f_av_desc, &atmp,
+               ad = f->f_av_desc;
+               if ( map_attr_value( dc, &ad, &atmp,
                                        &f->f_av_value, &vtmp, RWM_MAP ) )
                {
                        goto computed;
@@ -539,7 +544,8 @@ rwm_int_filter_map_rewrite(
                break;
 
        case LDAP_FILTER_SUBSTRINGS:
-               if ( map_attr_value( dc, &f->f_sub_desc, &atmp,
+               ad = f->f_sub_desc;
+               if ( map_attr_value( dc, &ad, &atmp,
                                        NULL, NULL, RWM_MAP ) )
                {
                        goto computed;
@@ -601,7 +607,8 @@ rwm_int_filter_map_rewrite(
                break;
 
        case LDAP_FILTER_PRESENT:
-               if ( map_attr_value( dc, &f->f_desc, &atmp,
+               ad = f->f_desc;
+               if ( map_attr_value( dc, &ad, &atmp,
                                        NULL, NULL, RWM_MAP ) )
                {
                        goto computed;
@@ -647,7 +654,8 @@ rwm_int_filter_map_rewrite(
 
        case LDAP_FILTER_EXT: {
                if ( f->f_mr_desc ) {
-                       if ( map_attr_value( dc, &f->f_mr_desc, &atmp,
+                       ad = f->f_mr_desc;
+                       if ( map_attr_value( dc, &ad, &atmp,
                                                &f->f_mr_value, &vtmp, RWM_MAP ) )
                        {
                                goto computed;
index 843e7901311e15308edf947433ca6c995ab0613c..c85940ffaa61b4ec24f9dcbb10f40b4bba5e1db8 100644 (file)
@@ -1942,7 +1942,8 @@ typedef enum slap_reply_e {
        REP_EXTENDED,
        REP_SEARCH,
        REP_SEARCHREF,
-       REP_INTERMEDIATE
+       REP_INTERMEDIATE,
+       REP_GLUE_RESULT
 } slap_reply_t;
 
 typedef struct rep_sasl_s {
@@ -2345,6 +2346,19 @@ typedef struct slap_op_header {
 #endif
 } Opheader;
 
+typedef union slap_op_request {
+       req_add_s oq_add;
+       req_bind_s oq_bind;
+       req_compare_s oq_compare;
+       req_modify_s oq_modify;
+       req_modrdn_s oq_modrdn;
+       req_search_s oq_search;
+       req_abandon_s oq_abandon;
+       req_abandon_s oq_cancel;
+       req_extended_s oq_extended;
+       req_pwdexop_s oq_pwdexop;
+} OpRequest;
+
 typedef struct slap_op {
        Opheader *o_hdr;
 
@@ -2373,18 +2387,7 @@ typedef struct slap_op {
        struct berval   o_req_dn;       /* DN of target of request */
        struct berval   o_req_ndn;
 
-       union o_req_u {
-               req_add_s oq_add;
-               req_bind_s oq_bind;
-               req_compare_s oq_compare;
-               req_modify_s oq_modify;
-               req_modrdn_s oq_modrdn;
-               req_search_s oq_search;
-               req_abandon_s oq_abandon;
-               req_abandon_s oq_cancel;
-               req_extended_s oq_extended;
-               req_pwdexop_s oq_pwdexop;
-       } o_request;
+       OpRequest o_request;
 
 /* short hands for union members */
 #define oq_add o_request.oq_add