]> git.sur5r.net Git - openldap/commitdiff
another round at rwm; now add and compare are nearly complete; error handling is...
authorPierangelo Masarati <ando@openldap.org>
Tue, 9 Mar 2004 07:06:20 +0000 (07:06 +0000)
committerPierangelo Masarati <ando@openldap.org>
Tue, 9 Mar 2004 07:06:20 +0000 (07:06 +0000)
servers/slapd/overlays/rwm.c
servers/slapd/overlays/rwm.h
servers/slapd/overlays/rwmconf.c
servers/slapd/overlays/rwmmap.c

index 21430a77e2447b11b91a37fdb9a8fd5599deab76..24fcb2ca165334d6a2d01f4a72ade4ec8fd9199c 100644 (file)
@@ -76,83 +76,205 @@ rwm_op_dn_massage( Operation *op, SlapReply *rs, void *cookie )
 }
 
 static int
-rwm_bind( Operation *op, SlapReply *rs )
+rwm_add( Operation *op, SlapReply *rs )
 {
-       int     rc;
+       slap_overinst           *on = (slap_overinst *) op->o_bd->bd_info;
+       struct ldaprwmap        *rwmap = 
+                       (struct ldaprwmap *)on->on_bi.bi_private;
+
+       int                     rc,
+                               i,
+                               isupdate;
+       Attribute               **ap = NULL;
 
 #ifdef ENABLE_REWRITE
-       rc = rwm_op_dn_massage( op, rs, "bindDn" );
+       rc = rwm_op_dn_massage( op, rs, "addDn" );
 #else
        rc = 1;
        rc = rwm_op_dn_massage( op, rs, &rc );
 #endif
        if ( rc != LDAP_SUCCESS ) {
-               return rc;
+               op->o_bd->bd_info = (BackendInfo *)on->on_info;
+               send_ldap_error( op, rs, rc, "addDn massage error" );
+               return -1;
        }
 
+       /* Count number of attributes in entry */ 
+       isupdate = be_isupdate( op->o_bd, &op->o_ndn );
+       for ( i = 0, ap = &op->oq_add.rs_e->e_attrs; *ap; ) {
+               struct berval   mapped;
+               Attribute       *a;
+
+               if ( !isupdate && (*ap)->a_desc->ad_type->sat_no_user_mod ) {
+                       goto cleanup_attr;
+               }
+
+               rwm_map( &rwmap->rwm_at, &(*ap)->a_desc->ad_cname,
+                               &mapped, RWM_MAP );
+               if ( mapped.bv_val == NULL || mapped.bv_val[0] == '\0' ) {
+                       goto cleanup_attr;
+               }
+
+               if ( (*ap)->a_desc->ad_type->sat_syntax
+                               == slap_schema.si_syn_distinguishedName )
+               {
+                       /*
+                        * FIXME: rewrite could fail; in this case
+                        * the operation should give up, right?
+                        */
+#ifdef ENABLE_REWRITE
+                       rc = rwm_dnattr_rewrite( op, rs, "addDn",
+                                       (*ap)->a_vals );
+#else
+                       rc = 1;
+                       rc = rwm_op_dn_massage( op, rs, &rc,
+                                       (*ap)->a_vals );
+#endif
+                       if ( rc ) {
+                               goto cleanup_attr;
+                       }
+               }
+
+               ap = &(*ap)->a_next;
+               continue;
+
+cleanup_attr:;
+               /* FIXME: leaking attribute/values? */
+               a = *ap;
+
+               *ap = (*ap)->a_next;
+               ber_bvarray_free( a->a_vals );
+               ber_bvarray_free( a->a_nvals );
+               ch_free( a );
+       }
+
+
+       /* TODO: map attribute types, values of DN-valued attributes ... */
        return SLAP_CB_CONTINUE;
 }
 
 static int
-rwm_add( Operation *op, SlapReply *rs )
+rwm_bind( Operation *op, SlapReply *rs )
 {
-       int     rc;
+       slap_overinst           *on = (slap_overinst *) op->o_bd->bd_info;
+       int                     rc;
 
 #ifdef ENABLE_REWRITE
-       rc = rwm_op_dn_massage( op, rs, "addDn" );
+       rc = rwm_op_dn_massage( op, rs, "bindDn" );
 #else
        rc = 1;
        rc = rwm_op_dn_massage( op, rs, &rc );
 #endif
        if ( rc != LDAP_SUCCESS ) {
-               return rc;
+               op->o_bd->bd_info = (BackendInfo *)on->on_info;
+               send_ldap_error( op, rs, rc, "bindDn massage error" );
+               return -1;
        }
 
-       /* TODO: rewrite attribute types, values of DN-valued attributes ... */
        return SLAP_CB_CONTINUE;
 }
 
 static int
-rwm_delete( Operation *op, SlapReply *rs )
+rwm_compare( Operation *op, SlapReply *rs )
 {
-       int     rc;
+       slap_overinst           *on = (slap_overinst *) op->o_bd->bd_info;
+       struct ldaprwmap        *rwmap = 
+                       (struct ldaprwmap *)on->on_bi.bi_private;
+
+       int                     rc;
+       struct berval           mapped_at = { 0, NULL },
+                               mapped_vals[2] = { { 0, NULL }, { 0, NULL } };
 
 #ifdef ENABLE_REWRITE
-       rc = rwm_op_dn_massage( op, rs, "deleteDn" );
+       rc = rwm_op_dn_massage( op, rs, "compareDn" );
 #else
        rc = 1;
        rc = rwm_op_dn_massage( op, rs, &rc );
 #endif
        if ( rc != LDAP_SUCCESS ) {
-               return rc;
+               op->o_bd->bd_info = (BackendInfo *)on->on_info;
+               send_ldap_error( op, rs, rc, "compareDn massage error" );
+               return -1;
+       }
+
+       /* if the attribute is an objectClass, try to remap its value */
+       if ( op->orc_ava->aa_desc == slap_schema.si_ad_objectClass
+                       || op->orc_ava->aa_desc == slap_schema.si_ad_structuralObjectClass )
+       {
+               rwm_map( &rwmap->rwm_oc, &op->orc_ava->aa_value,
+                               &mapped_vals[0], RWM_MAP );
+               if ( mapped_vals[0].bv_val == NULL
+                               || mapped_vals[0].bv_val[0] == '\0')
+               {
+                       op->o_bd->bd_info = (BackendInfo *)on->on_info;
+                       send_ldap_error( op, rs, LDAP_OTHER, "compare objectClass map error" );
+                       return -1;
+
+               } else if ( mapped_vals[0].bv_val != op->orc_ava->aa_value.bv_val ) {
+                       free( op->orc_ava->aa_value.bv_val );
+                       op->orc_ava->aa_value = mapped_vals[0];
+               }
+               mapped_at = op->orc_ava->aa_desc->ad_cname;
+
+       } else {
+               rwm_map( &rwmap->rwm_at,
+                               &op->orc_ava->aa_desc->ad_cname,
+                               &mapped_at,
+                               RWM_MAP );
+               if ( mapped_at.bv_val == NULL 
+                               || mapped_at.bv_val[0] == '\0')
+               {
+                       op->o_bd->bd_info = (BackendInfo *)on->on_info;
+                       send_ldap_error( op, rs, LDAP_OTHER, "compare attributeType map error" );
+                       return -1;
+               }
+               if ( op->orc_ava->aa_desc->ad_type->sat_syntax == slap_schema.si_syn_distinguishedName )
+               {
+                       mapped_vals[0] = op->orc_ava->aa_value;
+                       rc = rwm_dnattr_rewrite( op, rs, "compareAttrDN", mapped_vals );
+                       if ( rc != LDAP_SUCCESS ) {
+                               op->o_bd->bd_info = (BackendInfo *)on->on_info;
+                               send_ldap_error( op, rs, rc, "compareAttrDN massage error" );
+                               return -1;
+                       }
+
+                       if ( mapped_vals[0].bv_val != op->orc_ava->aa_value.bv_val ) {
+                               free( op->orc_ava->aa_value.bv_val );
+                               op->orc_ava->aa_value = mapped_vals[0];
+                       }
+               }
        }
 
+       /* TODO: rewrite attribute types, values of DN-valued attributes ... */
        return SLAP_CB_CONTINUE;
 }
 
 static int
-rwm_modrdn( Operation *op, SlapReply *rs )
+rwm_delete( Operation *op, SlapReply *rs )
 {
-       int     rc;
+       slap_overinst           *on = (slap_overinst *) op->o_bd->bd_info;
+       int                     rc;
 
 #ifdef ENABLE_REWRITE
-       rc = rwm_op_dn_massage( op, rs, "renameDn" );
+       rc = rwm_op_dn_massage( op, rs, "deleteDn" );
 #else
        rc = 1;
        rc = rwm_op_dn_massage( op, rs, &rc );
 #endif
        if ( rc != LDAP_SUCCESS ) {
+               op->o_bd->bd_info = (BackendInfo *)on->on_info;
+               send_ldap_error( op, rs, rc, "deleteDn massage error" );
                return rc;
        }
 
-       /* TODO: rewrite attribute types, values of DN-valued attributes ... */
        return SLAP_CB_CONTINUE;
 }
 
 static int
 rwm_modify( Operation *op, SlapReply *rs )
 {
-       int     rc;
+       slap_overinst           *on = (slap_overinst *) op->o_bd->bd_info;
+       int                     rc;
 
 #ifdef ENABLE_REWRITE
        rc = rwm_op_dn_massage( op, rs, "modifyDn" );
@@ -161,6 +283,8 @@ rwm_modify( Operation *op, SlapReply *rs )
        rc = rwm_op_dn_massage( op, rs, &rc );
 #endif
        if ( rc != LDAP_SUCCESS ) {
+               op->o_bd->bd_info = (BackendInfo *)on->on_info;
+               send_ldap_error( op, rs, rc, "modifyDn massage error" );
                return rc;
        }
 
@@ -169,17 +293,20 @@ rwm_modify( Operation *op, SlapReply *rs )
 }
 
 static int
-rwm_compare( Operation *op, SlapReply *rs )
+rwm_modrdn( Operation *op, SlapReply *rs )
 {
-       int     rc;
+       slap_overinst           *on = (slap_overinst *) op->o_bd->bd_info;
+       int                     rc;
 
 #ifdef ENABLE_REWRITE
-       rc = rwm_op_dn_massage( op, rs, "compareDn" );
+       rc = rwm_op_dn_massage( op, rs, "renameDn" );
 #else
        rc = 1;
        rc = rwm_op_dn_massage( op, rs, &rc );
 #endif
        if ( rc != LDAP_SUCCESS ) {
+               op->o_bd->bd_info = (BackendInfo *)on->on_info;
+               send_ldap_error( op, rs, rc, "renameDn massage error" );
                return rc;
        }
 
@@ -190,7 +317,8 @@ rwm_compare( Operation *op, SlapReply *rs )
 static int
 rwm_search( Operation *op, SlapReply *rs )
 {
-       int     rc;
+       slap_overinst           *on = (slap_overinst *) op->o_bd->bd_info;
+       int                     rc;
 
 #ifdef ENABLE_REWRITE
        rc = rwm_op_dn_massage( op, rs, "searchDn" );
@@ -199,6 +327,8 @@ rwm_search( Operation *op, SlapReply *rs )
        rc = rwm_op_dn_massage( op, rs, &rc );
 #endif
        if ( rc != LDAP_SUCCESS ) {
+               op->o_bd->bd_info = (BackendInfo *)on->on_info;
+               send_ldap_error( op, rs, rc, "searchDn massage error" );
                return rc;
        }
 
@@ -209,7 +339,8 @@ rwm_search( Operation *op, SlapReply *rs )
 static int
 rwm_extended( Operation *op, SlapReply *rs )
 {
-       int     rc;
+       slap_overinst           *on = (slap_overinst *) op->o_bd->bd_info;
+       int                     rc;
 
 #ifdef ENABLE_REWRITE
        rc = rwm_op_dn_massage( op, rs, "extendedDn" );
@@ -218,6 +349,8 @@ rwm_extended( Operation *op, SlapReply *rs )
        rc = rwm_op_dn_massage( op, rs, &rc );
 #endif
        if ( rc != LDAP_SUCCESS ) {
+               op->o_bd->bd_info = (BackendInfo *)on->on_info;
+               send_ldap_error( op, rs, rc, "extendedDn massage error" );
                return rc;
        }
 
index c50c1b8fbea8a8047f7306df32c6d8a33e16e887..c3d2cc2745183bb576fad78fd328ea407f28396c 100644 (file)
@@ -39,8 +39,25 @@ struct ldapmap {
 };
 
 struct ldapmapping {
-       struct berval src;
-       struct berval dst;
+       int                     m_flags;
+#define        RWMMAP_F_NONE           0x00
+#define        RWMMAP_F_IS_OC          0x01
+#define RWMMAP_F_FREE_SRC      0x10
+#define RWMMAP_F_FREE_DST      0x20
+       struct berval           m_src;
+       union {
+               AttributeDescription    *m_s_ad;
+               ObjectClass             *m_s_oc;
+       } m_src_ref;
+#define m_src_ad       m_src_ref.m_s_ad
+#define m_src_oc       m_src_ref.m_s_oc
+       struct berval           m_dst;
+       union {
+               AttributeDescription    *m_d_ad;
+               ObjectClass             *m_d_oc;
+       } m_dst_ref;
+#define m_dst_ad       m_dst_ref.m_d_ad
+#define m_dst_oc       m_dst_ref.m_d_oc
 };
 
 struct ldaprwmap {
@@ -85,8 +102,8 @@ int rwm_mapping_dup (void *, void *);
 void rwm_map_init ( struct ldapmap *lm, struct ldapmapping ** );
 void rwm_map ( struct ldapmap *map, struct berval *s, struct berval *m,
        int remap );
-#define BACKLDAP_MAP   0
-#define BACKLDAP_REMAP 1
+#define RWM_MAP        0
+#define RWM_REMAP      1
 char *
 rwm_map_filter(
                struct ldapmap *at_map,
@@ -126,7 +143,12 @@ extern int rwm_suffix_massage_config( struct rewrite_info *info,
                struct berval *pvnc, struct berval *nvnc,
                struct berval *prnc, struct berval *nrnc);
 #endif /* ENABLE_REWRITE */
-extern int rwm_dnattr_rewrite( dncookie *dc, BerVarray a_vals );
+extern int rwm_dnattr_rewrite(
+       Operation               *op,
+       SlapReply               *rs,
+       void                    *cookie,
+       BerVarray               a_vals
+       );
 extern int rwm_dnattr_result_rewrite( dncookie *dc, BerVarray a_vals );
 
 LDAP_END_DECL
index 103524281fd36441adf4fe62a2243fcc97cec852..d664b4a9520dc742cd00ee1710118a8e918decef 100644 (file)
@@ -93,6 +93,7 @@ rwm_map_config(
                fprintf( stderr,
                        "%s: line %d: objectclass attribute cannot be mapped\n",
                        fname, lineno );
+               return 1;
        }
 
        mapping = (struct ldapmapping *)ch_calloc( 2,
@@ -103,17 +104,21 @@ rwm_map_config(
                        fname, lineno );
                return 1;
        }
-       ber_str2bv( src, 0, 1, &mapping->src );
-       ber_str2bv( dst, 0, 1, &mapping->dst );
-       mapping[1].src = mapping->dst;
-       mapping[1].dst = mapping->src;
+       ber_str2bv( src, 0, 1, &mapping[0].m_src );
+       ber_str2bv( dst, 0, 1, &mapping[0].m_dst );
+       mapping[1].m_src = mapping[0].m_dst;
+       mapping[1].m_dst = mapping[0].m_src;
+
+       mapping[0].m_flags = RWMMAP_F_NONE;
+       mapping[1].m_flags = RWMMAP_F_NONE;
 
        /*
         * schema check
         */
        if ( is_oc ) {
                if ( src[0] != '\0' ) {
-                       if ( oc_bvfind( &mapping->src ) == NULL ) {
+                       mapping[0].m_src_oc = oc_bvfind( &mapping[0].m_src );
+                       if ( mapping[0].m_src_oc == NULL ) {
                                fprintf( stderr,
        "%s: line %d: warning, source objectClass '%s' "
        "should be defined in schema\n",
@@ -122,22 +127,38 @@ rwm_map_config(
                                /*
                                 * FIXME: this should become an err
                                 */
+                               mapping[0].m_src_oc = ch_malloc( sizeof( ObjectClass ) );
+                               memset( mapping[0].m_src_oc, 0, sizeof( ObjectClass ) );
+                               mapping[0].m_src_oc->soc_cname = mapping[0].m_src;
+                               mapping[0].m_flags |= RWMMAP_F_FREE_SRC;
                        }
+                       mapping[1].m_dst_oc = mapping[0].m_src_oc;
                }
 
-               if ( oc_bvfind( &mapping->dst ) == NULL ) {
+               mapping[0].m_dst_oc = oc_bvfind( &mapping[0].m_dst );
+               if ( mapping[0].m_dst_oc == NULL ) {
                        fprintf( stderr,
        "%s: line %d: warning, destination objectClass '%s' "
        "is not defined in schema\n",
                                fname, lineno, dst );
+
+                       mapping[0].m_dst_oc = ch_malloc( sizeof( ObjectClass ) );
+                       memset( mapping[0].m_dst_oc, 0, sizeof( ObjectClass ) );
+                       mapping[0].m_dst_oc->soc_cname = mapping[0].m_dst;
+                       mapping[0].m_flags |= RWMMAP_F_FREE_DST;
                }
+               mapping[1].m_src_oc = mapping[0].m_dst_oc;
+
+               mapping[0].m_flags |= RWMMAP_F_IS_OC;
+               mapping[1].m_flags |= RWMMAP_F_IS_OC;
+
        } else {
                int                     rc;
                const char              *text = NULL;
-               AttributeDescription    *ad = NULL;
 
                if ( src[0] != '\0' ) {
-                       rc = slap_bv2ad( &mapping->src, &ad, &text );
+                       rc = slap_bv2ad( &mapping[0].m_src,
+                                       &mapping[0].m_src_ad, &text );
                        if ( rc != LDAP_SUCCESS ) {
                                fprintf( stderr,
        "%s: line %d: warning, source attributeType '%s' "
@@ -146,19 +167,32 @@ rwm_map_config(
 
                                /*
                                 * FIXME: this should become an err
+                                *
+                                * FIXME: or, we should create a fake ad
+                                * and add it here.
                                 */
-                       }
 
-                       ad = NULL;
+                               mapping[0].m_src_ad = ch_malloc( sizeof( AttributeDescription ) );
+                               memset( mapping[0].m_src_ad, 0, sizeof( AttributeDescription ) );
+                               mapping[0].m_src_ad->ad_cname = mapping[0].m_src;
+                               mapping[1].m_flags |= RWMMAP_F_FREE_SRC;
+                       }
+                       mapping[1].m_dst_ad = mapping[0].m_src_ad;
                }
 
-               rc = slap_bv2ad( &mapping->dst, &ad, &text );
+               rc = slap_bv2ad( &mapping[0].m_dst, &mapping[0].m_dst_ad, &text );
                if ( rc != LDAP_SUCCESS ) {
                        fprintf( stderr,
        "%s: line %d: warning, destination attributeType '%s' "
        "is not defined in schema\n",
                                fname, lineno, dst );
+
+                       mapping[0].m_dst_ad = ch_malloc( sizeof( AttributeDescription ) );
+                       memset( mapping[0].m_dst_ad, 0, sizeof( AttributeDescription ) );
+                       mapping[0].m_dst_ad->ad_cname = mapping[0].m_dst;
+                       mapping[1].m_flags |= RWMMAP_F_FREE_SRC;
                }
+               mapping[1].m_src_ad = mapping[0].m_dst_ad;
        }
 
        if ( (src[0] != '\0' && avl_find( map->map, (caddr_t)mapping, rwm_mapping_cmp ) != NULL)
@@ -172,7 +206,7 @@ rwm_map_config(
        }
 
        if ( src[0] != '\0' ) {
-               avl_insert( &map->map, (caddr_t)mapping,
+               avl_insert( &map->map, (caddr_t)&mapping[0],
                                        rwm_mapping_cmp, rwm_mapping_dup );
        }
        avl_insert( &map->remap, (caddr_t)&mapping[1],
@@ -182,9 +216,7 @@ rwm_map_config(
 
 error_return:;
        if ( mapping ) {
-               ch_free( mapping->src.bv_val );
-               ch_free( mapping->dst.bv_val );
-               ch_free( mapping );
+               mapping_free( mapping );
        }
 
        return 1;
index 11cbbef65dd4d33e7f4408e9b605ab3c23fb2aaa..5ecb959f1d827606646bbab46131ffbb5a02e655 100644 (file)
 #include "../../../libraries/libldap/ldap-int.h"
 
 int
-rwm_mapping_cmp ( const void *c1, const void *c2 )
+rwm_mapping_cmp( const void *c1, const void *c2 )
 {
        struct ldapmapping *map1 = (struct ldapmapping *)c1;
        struct ldapmapping *map2 = (struct ldapmapping *)c2;
-       int rc = map1->src.bv_len - map2->src.bv_len;
-       if (rc) return rc;
-       return ( strcasecmp(map1->src.bv_val, map2->src.bv_val) );
+       int rc = map1->m_src.bv_len - map2->m_src.bv_len;
+       if ( rc ) {
+               return rc;
+       }
+       return strcasecmp( map1->m_src.bv_val, map2->m_src.bv_val );
 }
 
 int
-rwm_mapping_dup ( void *c1, void *c2 )
+rwm_mapping_dup( void *c1, void *c2 )
 {
        struct ldapmapping *map1 = (struct ldapmapping *)c1;
        struct ldapmapping *map2 = (struct ldapmapping *)c2;
+       int rc = map1->m_src.bv_len - map2->m_src.bv_len;
+
+       if ( rc ) {
+               return 0;
+       }
 
-       return( ( strcasecmp(map1->src.bv_val, map2->src.bv_val) == 0 ) ? -1 : 0 );
+       return ( ( strcasecmp( map1->m_src.bv_val, map2->m_src.bv_val ) == 0 ) ? -1 : 0 );
 }
 
 void
-rwm_map_init ( struct ldapmap *lm, struct ldapmapping **m )
+rwm_map_init( struct ldapmap *lm, struct ldapmapping **m )
 {
        struct ldapmapping *mapping;
 
@@ -70,10 +77,11 @@ rwm_map_init ( struct ldapmap *lm, struct ldapmapping **m )
                return;
        }
 
-       ber_str2bv( "objectclass", sizeof("objectclass")-1, 1, &mapping->src);
-       ber_dupbv( &mapping->dst, &mapping->src );
-       mapping[1].src = mapping->src;
-       mapping[1].dst = mapping->dst;
+       ber_str2bv( "objectClass", sizeof("objectClass") - 1, 1,
+                       &mapping->m_src);
+       ber_dupbv( &mapping->m_dst, &mapping->m_src );
+       mapping[1].m_src = mapping->m_src;
+       mapping[1].m_dst = mapping->m_dst;
 
        avl_insert( &lm->map, (caddr_t)mapping, 
                        rwm_mapping_cmp, rwm_mapping_dup );
@@ -83,29 +91,32 @@ rwm_map_init ( struct ldapmap *lm, struct ldapmapping **m )
 }
 
 void
-rwm_map ( struct ldapmap *map, struct berval *s, struct berval *bv,
-       int remap )
+rwm_map( struct ldapmap *map, struct berval *s, struct berval *bv, int remap )
 {
        Avlnode *tree;
        struct ldapmapping *mapping, fmapping;
 
-       if (remap == BACKLDAP_REMAP)
+       if (remap == RWM_REMAP) {
                tree = map->remap;
-       else
+       } else {
                tree = map->map;
+       }
 
        bv->bv_len = 0;
        bv->bv_val = NULL;
-       fmapping.src = *s;
-       mapping = (struct ldapmapping *)avl_find( tree, (caddr_t)&fmapping, rwm_mapping_cmp );
-       if (mapping != NULL) {
-               if ( mapping->dst.bv_val )
-                       *bv = mapping->dst;
+       fmapping.m_src = *s;
+       mapping = (struct ldapmapping *)avl_find( tree, (caddr_t)&fmapping,
+                       rwm_mapping_cmp );
+       if ( mapping != NULL ) {
+               if ( mapping->m_dst.bv_val ) {
+                       *bv = mapping->m_dst;
+               }
                return;
        }
 
-       if (!map->drop_missing)
+       if ( !map->drop_missing ) {
                *bv = *s;
+       }
 
        return;
 }
@@ -122,28 +133,30 @@ rwm_map_attrs(
        char **na;
        struct berval mapped;
 
-       if (an == NULL) {
+       if ( an == NULL ) {
                *mapped_attrs = NULL;
                return LDAP_SUCCESS;
        }
 
-       for (i = 0; an[i].an_name.bv_val; i++) {
+       for ( i = 0; an[i].an_name.bv_val; i++ ) {
                /*  */
        }
 
-       na = (char **)ch_calloc( i + 1, sizeof(char *) );
+       na = (char **)ch_calloc( i + 1, sizeof( char * ) );
        if (na == NULL) {
                *mapped_attrs = NULL;
                return LDAP_NO_MEMORY;
        }
 
-       for (i = j = 0; an[i].an_name.bv_val; i++) {
-               rwm_map(at_map, &an[i].an_name, &mapped, remap);
-               if (mapped.bv_val != NULL && mapped.bv_val != '\0')
+       for ( i = j = 0; an[i].an_name.bv_val; i++ ) {
+               rwm_map( at_map, &an[i].an_name, &mapped, remap );
+               if ( mapped.bv_val != NULL && mapped.bv_val != '\0' ) {
                        na[j++] = mapped.bv_val;
+               }
        }
-       if (j == 0 && i != 0)
+       if ( j == 0 && i != 0 ) {
                na[j++] = LDAP_NO_ATTRS;
+       }
        na[j] = NULL;
 
        *mapped_attrs = na;
@@ -167,8 +180,11 @@ map_attr_value(
                /*
                 * FIXME: are we sure we need to search oc_map if at_map fails?
                 */
-               rwm_map( &dc->rwmap->rwm_oc, &ad->ad_cname, mapped_attr, remap );
-               if ( mapped_attr->bv_val == NULL || mapped_attr->bv_val[0] == '\0' ) {
+               rwm_map( &dc->rwmap->rwm_oc, &ad->ad_cname, mapped_attr,
+                               remap );
+               if ( mapped_attr->bv_val == NULL
+                               || mapped_attr->bv_val[0] == '\0' )
+               {
                        *mapped_attr = ad->ad_cname;
                }
        }
@@ -199,7 +215,9 @@ map_attr_value(
                        return -1;
                }
 
-       } else if ( ad == slap_schema.si_ad_objectClass || ad == slap_schema.si_ad_structuralObjectClass ) {
+       } else if ( ad == slap_schema.si_ad_objectClass
+                       || ad == slap_schema.si_ad_structuralObjectClass )
+       {
                rwm_map( &dc->rwmap->rwm_oc, value, &vtmp, remap );
                if ( vtmp.bv_val == NULL || vtmp.bv_val[0] == '\0' ) {
                        vtmp = *value;
@@ -227,12 +245,20 @@ rwm_filter_map_rewrite(
 {
        int             i;
        Filter          *p;
-       struct berval   atmp;
-       struct berval   vtmp;
+       struct berval   atmp,
+                       vtmp,
+                       tmp;
+       static struct berval
+                       ber_bvfalse = BER_BVC( "(?=false)" ),
+                       ber_bvtrue = BER_BVC( "(?=true)" ),
+                       ber_bvundefined = BER_BVC( "(?=undefined)" ),
+                       ber_bverror = BER_BVC( "(?=error)" ),
+                       ber_bvunknown = BER_BVC( "(?=unknown)" ),
+                       ber_bvnone = BER_BVC( "(?=none)" );
        ber_len_t       len;
 
        if ( f == NULL ) {
-               ber_str2bv( "No filter!", sizeof("No filter!")-1, 1, fstr );
+               ber_dupbv( fstr, &ber_bvnone );
                return -1;
        }
 
@@ -245,7 +271,7 @@ rwm_filter_map_rewrite(
                }
 
                fstr->bv_len = atmp.bv_len + vtmp.bv_len
-                       + ( sizeof("(=)") - 1 );
+                       + ( sizeof( "(=)" ) - 1 );
                fstr->bv_val = malloc( fstr->bv_len + 1 );
 
                snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=%s)",
@@ -262,7 +288,7 @@ rwm_filter_map_rewrite(
                }
 
                fstr->bv_len = atmp.bv_len + vtmp.bv_len
-                       + ( sizeof("(>=)") - 1 );
+                       + ( sizeof( "(>=)" ) - 1 );
                fstr->bv_val = malloc( fstr->bv_len + 1 );
 
                snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s>=%s)",
@@ -279,7 +305,7 @@ rwm_filter_map_rewrite(
                }
 
                fstr->bv_len = atmp.bv_len + vtmp.bv_len
-                       + ( sizeof("(<=)") - 1 );
+                       + ( sizeof( "(<=)" ) - 1 );
                fstr->bv_val = malloc( fstr->bv_len + 1 );
 
                snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s<=%s)",
@@ -296,7 +322,7 @@ rwm_filter_map_rewrite(
                }
 
                fstr->bv_len = atmp.bv_len + vtmp.bv_len
-                       + ( sizeof("(~=)") - 1 );
+                       + ( sizeof( "(~=)" ) - 1 );
                fstr->bv_val = malloc( fstr->bv_len + 1 );
 
                snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s~=%s)",
@@ -314,7 +340,7 @@ rwm_filter_map_rewrite(
 
                /* cannot be a DN ... */
 
-               fstr->bv_len = atmp.bv_len + ( sizeof("(=*)") - 1 );
+               fstr->bv_len = atmp.bv_len + ( sizeof( "(=*)" ) - 1 );
                fstr->bv_val = malloc( fstr->bv_len + 128 );
 
                snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=*)",
@@ -374,7 +400,7 @@ rwm_filter_map_rewrite(
                        return -1;
                }
 
-               fstr->bv_len = atmp.bv_len + ( sizeof("(=*)") - 1 );
+               fstr->bv_len = atmp.bv_len + ( sizeof( "(=*)" ) - 1 );
                fstr->bv_val = malloc( fstr->bv_len + 1 );
 
                snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=*)",
@@ -384,7 +410,7 @@ rwm_filter_map_rewrite(
        case LDAP_FILTER_AND:
        case LDAP_FILTER_OR:
        case LDAP_FILTER_NOT:
-               fstr->bv_len = sizeof("(%)") - 1;
+               fstr->bv_len = sizeof( "(%)" ) - 1;
                fstr->bv_val = malloc( fstr->bv_len + 128 );
 
                snprintf( fstr->bv_val, fstr->bv_len + 1, "(%c)",
@@ -427,9 +453,9 @@ rwm_filter_map_rewrite(
                        
 
                fstr->bv_len = atmp.bv_len +
-                       ( f->f_mr_dnattrs ? sizeof(":dn")-1 : 0 ) +
-                       ( f->f_mr_rule_text.bv_len ? f->f_mr_rule_text.bv_len+1 : 0 ) +
-                       vtmp.bv_len + ( sizeof("(:=)") - 1 );
+                       ( f->f_mr_dnattrs ? sizeof( ":dn" ) - 1 : 0 ) +
+                       ( f->f_mr_rule_text.bv_len ? f->f_mr_rule_text.bv_len + 1 : 0 ) +
+                       vtmp.bv_len + ( sizeof( "(:=)" ) - 1 );
                fstr->bv_val = malloc( fstr->bv_len + 1 );
 
                snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s%s%s%s:=%s)",
@@ -442,20 +468,29 @@ rwm_filter_map_rewrite(
                } break;
 
        case SLAPD_FILTER_COMPUTED:
-               ber_str2bv(
-                       f->f_result == LDAP_COMPARE_FALSE ? "(?=false)" :
-                       f->f_result == LDAP_COMPARE_TRUE ? "(?=true)" :
-                       f->f_result == SLAPD_COMPARE_UNDEFINED ? "(?=undefined)" :
-                       "(?=error)",
-                       f->f_result == LDAP_COMPARE_FALSE ? sizeof("(?=false)")-1 :
-                       f->f_result == LDAP_COMPARE_TRUE ? sizeof("(?=true)")-1 :
-                       f->f_result == SLAPD_COMPARE_UNDEFINED ? sizeof("(?=undefined)")-1 :
-                       sizeof("(?=error)")-1,
-                       1, fstr );
-               break;
+               switch ( f->f_result ) {
+               case LDAP_COMPARE_FALSE:
+                       tmp = ber_bvfalse;
+                       break;
 
+               case LDAP_COMPARE_TRUE:
+                       tmp = ber_bvtrue;
+                       break;
+                       
+               case SLAPD_COMPARE_UNDEFINED:
+                       tmp = ber_bvundefined;
+                       break;
+                       
+               default:
+                       tmp = ber_bverror;
+                       break;
+               }
+
+               ber_dupbv( fstr, &tmp );
+               break;
+               
        default:
-               ber_str2bv( "(?=unknown)", sizeof("(?=unknown)")-1, 1, fstr );
+               ber_dupbv( fstr, &ber_bvunknown );
                break;
        }
 
@@ -471,18 +506,39 @@ rwm_filter_map_rewrite(
  */
 int
 rwm_dnattr_rewrite(
-       dncookie                *dc,
+       Operation               *op,
+       SlapReply               *rs,
+       void                    *cookie,
        BerVarray               a_vals
-)
+       )
 {
-       struct berval   bv;
-       int             i, last;
+       slap_overinst           *on = (slap_overinst *) op->o_bd->bd_info;
+       struct ldaprwmap        *rwmap = 
+                       (struct ldaprwmap *)on->on_bi.bi_private;
+
+       struct berval           bv;
+       int                     i, last;
+
+       dncookie                dc;
+
+       /*
+        * Rewrite the bind dn if needed
+        */
+       dc.rwmap = rwmap;
+#ifdef ENABLE_REWRITE
+       dc.conn = op->o_conn;
+       dc.rs = rs;
+       dc.ctx = (char *)cookie;
+#else
+       dc.tofrom = ((int *)cookie)[0];
+       dc.normalized = 0;
+#endif
 
        for ( last = 0; a_vals[last].bv_val != NULL; last++ );
        last--;
 
        for ( i = 0; a_vals[i].bv_val != NULL; i++ ) {
-               switch ( rwm_dn_massage( dc, &a_vals[i], &bv ) ) {
+               switch ( rwm_dn_massage( &dc, &a_vals[i], &bv ) ) {
                case LDAP_UNWILLING_TO_PERFORM:
                        /*
                         * FIXME: need to check if it may be considered 
@@ -557,9 +613,43 @@ void
 rwm_mapping_free( void *v_mapping )
 {
        struct ldapmapping *mapping = v_mapping;
-       ch_free( mapping->src.bv_val );
-       ch_free( mapping->dst.bv_val );
+
+       if ( mapping[0].m_src.bv_val ) {
+               ch_free( mapping[0].m_src.bv_val );
+       }
+
+       if ( mapping[0].m_flags & RWMMAP_F_FREE_SRC ) {
+               if ( mapping[0].m_flags & RWMMAP_F_IS_OC ) {
+                       if ( mapping[0].m_src_oc ) {
+                               ch_free( mapping[0].m_src_oc );
+                       }
+
+               } else {
+                       if ( mapping[0].m_src_ad ) {
+                               ch_free( mapping[0].m_src_ad );
+                       }
+               }
+       }
+
+       if ( mapping[0].m_dst.bv_val ) {
+               ch_free( mapping[0].m_dst.bv_val );
+       }
+
+       if ( mapping[0].m_flags & RWMMAP_F_FREE_DST ) {
+               if ( mapping[0].m_flags & RWMMAP_F_IS_OC ) {
+                       if ( mapping[0].m_dst_oc ) {
+                               ch_free( mapping[0].m_dst_oc );
+                       }
+
+               } else {
+                       if ( mapping[0].m_dst_ad ) {
+                               ch_free( mapping[0].m_dst_ad );
+                       }
+               }
+       }
+
        ch_free( mapping );
+
 }
 
 #endif /* SLAPD_OVER_RWM */