]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/overlays/rwm.c
rework be_isupdate accordingly to be_isroot
[openldap] / servers / slapd / overlays / rwm.c
index 97fb002006176b7d7e89cc29a0341b9742c6b02d..56d6294ddc3df058d30f83903c4b4c7e0c8d0838 100644 (file)
@@ -2,7 +2,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 2003 The OpenLDAP Foundation.
+ * Copyright 2003-2004 The OpenLDAP Foundation.
  * Portions Copyright 2003 Pierangelo Masarati.
  * All rights reserved.
  *
@@ -76,83 +76,223 @@ 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 );
+       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_dnattr_rewrite( 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;
+       struct ldaprwmap        *rwmap = 
+                       (struct ldaprwmap *)on->on_bi.bi_private;
+       int                     rc;
 
 #ifdef ENABLE_REWRITE
-       rc = rwm_op_dn_massage( op, rs, "addDn" );
+       ( void )rewrite_session_init( rwmap->rwm_rw, op->o_conn );
+
+       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_unbind( 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;
 
 #ifdef ENABLE_REWRITE
-       rc = rwm_op_dn_massage( op, rs, "deleteDn" );
+       rewrite_session_delete( rwmap->rwm_rw, op->o_conn );
+#endif
+
+       return SLAP_CB_CONTINUE;
+}
+
+static int
+rwm_compare( Operation *op, SlapReply *rs )
+{
+       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, "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 +301,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 +311,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 +335,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 +345,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 +357,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 +367,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;
        }
 
@@ -243,7 +394,7 @@ rwm_matched( Operation *op, SlapReply *rs )
 #ifdef ENABLE_REWRITE
        dc.conn = op->o_conn;
        dc.rs = rs;
-       dc.ctx = "matchedDn";
+       dc.ctx = "matchedDN";
 #else
        dc.tofrom = 0;
        dc.normalized = 0;
@@ -286,7 +437,7 @@ rwm_send_entry( Operation *op, SlapReply *rs )
 #ifdef ENABLE_REWRITE
        dc.conn = op->o_conn;
        dc.rs = NULL; 
-       dc.ctx = "searchResultDN";
+       dc.ctx = "searchResult";
 #else
        dc.tofrom = 0;
        dc.normalized = 0;
@@ -505,8 +656,14 @@ rwm_config(
 )
 {
        int             rc = 0;
+       char            *argv0 = NULL;
+
+       if ( strncasecmp( argv[ 0 ], "rwm-", sizeof( "rwm-" ) - 1 ) == 0 ) {
+               argv0 = argv[ 0 ];
+               argv[ 0 ] = &argv0[ sizeof( "rwm-" ) - 1 ];
+       }
 
-       if ( strncasecmp( argv[0], "rewrite", sizeof("rewrite") - 1) == 0 ) {
+       if ( strncasecmp( argv[0], "rewrite", sizeof("rewrite") - 1 ) == 0 ) {
                rc = rwm_rw_config( be, fname, lineno, argc, argv );
 
        } else if (strcasecmp( argv[0], "map" ) == 0 ) {
@@ -519,6 +676,10 @@ rwm_config(
                rc = SLAP_CONF_UNKNOWN;
        }
 
+       if ( argv0 ) {
+               argv[ 0 ] = argv0;
+       }
+
        return rc;
 }
 
@@ -540,6 +701,23 @@ rwm_over_init(
                ch_free( rwmap );
                return -1;
        }
+
+       {
+               char    *rargv[3];
+
+               /* this rewriteContext by default must be null;
+                * rules can be added if required */
+               rargv[ 0 ] = "rewriteContext";
+               rargv[ 1 ] = "searchFilter";
+               rargv[ 2 ] = NULL;
+               rewrite_parse( rwmap->rwm_rw, "<suffix massage>", 1, 2, rargv );
+
+               rargv[ 0 ] = "rewriteContext";
+               rargv[ 1 ] = "default";
+               rargv[ 2 ] = NULL;
+               rewrite_parse( rwmap->rwm_rw, "<suffix massage>", 2, 2, rargv );
+       }
+       
 #endif /* ENABLE_REWRITE */
 
        rwm_map_init( &rwmap->rwm_oc, &mapping );
@@ -567,15 +745,15 @@ rwm_destroy(
                        rewrite_info_delete( &rwmap->rwm_rw );
                }
 #else /* !ENABLE_REWRITE */
-               if ( rwmap->lrwm_suffix_massage ) {
+               if ( rwmap->rwm_suffix_massage ) {
                        ber_bvarray_free( rwmap->rwm_suffix_massage );
                }
 #endif /* !ENABLE_REWRITE */
 
                avl_free( rwmap->rwm_oc.remap, NULL );
-               avl_free( rwmap->rwm_oc.map, mapping_free );
+               avl_free( rwmap->rwm_oc.map, rwm_mapping_free );
                avl_free( rwmap->rwm_at.remap, NULL );
-               avl_free( rwmap->rwm_at.map, mapping_free );
+               avl_free( rwmap->rwm_at.map, rwm_mapping_free );
        }
 
        return rc;
@@ -588,7 +766,7 @@ rwm_init(void)
 {
        memset( &rwm, 0, sizeof(slap_overinst) );
 
-       rwm.on_bi.bi_type = "rewrite-remap";
+       rwm.on_bi.bi_type = "rwm";
        rwm.on_bi.bi_db_init = rwm_over_init;
        rwm.on_bi.bi_db_config = rwm_config;
        rwm.on_bi.bi_db_destroy = rwm_destroy;
@@ -600,6 +778,7 @@ rwm_init(void)
        rwm.on_bi.bi_op_modrdn = rwm_modrdn;
        rwm.on_bi.bi_op_add = rwm_add;
        rwm.on_bi.bi_op_delete = rwm_delete;
+       rwm.on_bi.bi_op_unbind = rwm_unbind;
        rwm.on_bi.bi_extended = rwm_extended;
 
        rwm.on_response = rwm_response;