]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/overlays/rwm.c
more about ITS#5940
[openldap] / servers / slapd / overlays / rwm.c
index 37ddd04e78de946da96d36c44f916ba27975812b..8f81e040b5d647692275f228056652383dc8b0c0 100644 (file)
@@ -2,7 +2,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 2003-2008 The OpenLDAP Foundation.
+ * Copyright 2003-2009 The OpenLDAP Foundation.
  * Portions Copyright 2003 Pierangelo Masarati.
  * All rights reserved.
  *
@@ -96,6 +96,12 @@ rwm_op_rollback( Operation *op, SlapReply *rs, rwm_op_state *ros )
                        op->orr_newSup = ros->orr_newSup;
                        op->orr_nnewSup = ros->orr_nnewSup;
                }
+               if ( op->orr_newrdn.bv_val != ros->orr_newrdn.bv_val ) {
+                       ch_free( op->orr_newrdn.bv_val );
+                       ch_free( op->orr_nnewrdn.bv_val );
+                       op->orr_newrdn = ros->orr_newrdn;
+                       op->orr_nnewrdn = ros->orr_nnewrdn;
+               }
                break;
        case LDAP_REQ_SEARCH:
                ch_free( ros->mapped_attrs );
@@ -684,11 +690,11 @@ rwm_op_modrdn( Operation *op, SlapReply *rs )
                        (struct ldaprwmap *)on->on_bi.bi_private;
        
        int                     rc;
+       dncookie                dc;
 
        rwm_op_cb               *roc = rwm_callback_get( op, rs );
 
        if ( op->orr_newSup ) {
-               dncookie        dc;
                struct berval   nnewSup = BER_BVNULL;
                struct berval   newSup = BER_BVNULL;
 
@@ -718,6 +724,32 @@ rwm_op_modrdn( Operation *op, SlapReply *rs )
                }
        }
 
+       /*
+        * Rewrite the newRDN, if needed
+        */
+       {
+               struct berval   newrdn = BER_BVNULL;
+               struct berval   nnewrdn = BER_BVNULL;
+
+               dc.rwmap = rwmap;
+               dc.conn = op->o_conn;
+               dc.rs = rs;
+               dc.ctx = "newRDN";
+               newrdn = op->orr_newrdn;
+               nnewrdn = op->orr_nnewrdn;
+               rc = rwm_dn_massage_pretty_normalize( &dc, &op->orr_newrdn, &newrdn, &nnewrdn );
+               if ( rc != LDAP_SUCCESS ) {
+                       op->o_bd->bd_info = (BackendInfo *)on->on_info;
+                       send_ldap_error( op, rs, rc, "newRDN massage error" );
+                       goto err;
+               }
+
+               if ( op->orr_newrdn.bv_val != newrdn.bv_val ) {
+                       op->orr_newrdn = newrdn;
+                       op->orr_nnewrdn = nnewrdn;
+               }
+       }
+
        /*
         * Rewrite the dn, if needed
         */
@@ -725,6 +757,15 @@ rwm_op_modrdn( Operation *op, SlapReply *rs )
        if ( rc != LDAP_SUCCESS ) {
                op->o_bd->bd_info = (BackendInfo *)on->on_info;
                send_ldap_error( op, rs, rc, "renameDN massage error" );
+               goto err;
+       }
+
+       op->o_callback = &roc->cb;
+
+       rc = SLAP_CB_CONTINUE;
+
+       if ( 0 ) {
+err:;
                if ( op->orr_newSup != roc->ros.orr_newSup ) {
                        ch_free( op->orr_newSup->bv_val );
                        ch_free( op->orr_nnewSup->bv_val );
@@ -733,15 +774,16 @@ rwm_op_modrdn( Operation *op, SlapReply *rs )
                        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 (hopefully not used in RDN)... */
 
-       op->o_callback = &roc->cb;
+               if ( op->orr_newrdn.bv_val != roc->ros.orr_newrdn.bv_val ) {
+                       ch_free( op->orr_newrdn.bv_val );
+                       ch_free( op->orr_nnewrdn.bv_val );
+                       op->orr_newrdn = roc->ros.orr_newrdn;
+                       op->orr_nnewrdn = roc->ros.orr_nnewrdn;
+               }
+       }
 
-       return SLAP_CB_CONTINUE;
+       return rc;
 }
 
 
@@ -1788,7 +1830,6 @@ rwm_db_config(
 enum {
        /* rewrite */
        RWM_CF_REWRITE = 1,
-       RWM_CF_SUFFIXMASSAGE,
 
        /* map */
        RWM_CF_MAP,
@@ -1799,8 +1840,10 @@ enum {
 };
 
 static slap_verbmasks t_f_mode[] = {
+       { BER_BVC( "true" ),            RWM_F_SUPPORT_T_F },
        { BER_BVC( "yes" ),             RWM_F_SUPPORT_T_F },
        { BER_BVC( "discover" ),        RWM_F_SUPPORT_T_F_DISCOVER },
+       { BER_BVC( "false" ),           RWM_F_NONE },
        { BER_BVC( "no" ),              RWM_F_NONE },
        { BER_BVNULL,                   0 }
 };
@@ -1810,7 +1853,7 @@ static ConfigDriver rwm_cf_gen;
 static ConfigTable rwmcfg[] = {
        { "rwm-rewrite", "rewrite",
                2, 0, STRLENOF("rwm-rewrite"),
-               ARG_MAGIC|ARG_QUOTE|RWM_CF_REWRITE, rwm_cf_gen,
+               ARG_MAGIC|RWM_CF_REWRITE, rwm_cf_gen,
                "( OLcfgOvAt:16.1 NAME 'olcRwmRewrite' "
                        "DESC 'Rewrites strings' "
                        "EQUALITY caseIgnoreMatch "
@@ -1819,7 +1862,7 @@ static ConfigTable rwmcfg[] = {
                NULL, NULL },
 
        { "rwm-suffixmassage", "[virtual]> <real",
-               2, 3, 0, ARG_MAGIC|RWM_CF_SUFFIXMASSAGE, rwm_cf_gen,
+               2, 3, 0, ARG_MAGIC|RWM_CF_REWRITE, rwm_cf_gen,
                NULL, NULL, NULL },
                
        { "rwm-t-f-support", "true|false|discover",
@@ -1904,6 +1947,53 @@ slap_rewrite_unparse( BerVarray in, BerVarray *out )
        *out = bva;
 }
 
+static int
+rwm_bva_rewrite_add(
+       struct ldaprwmap        *rwmap,
+       const char              *argv[] )
+{
+       char            *line;
+       struct berval   bv;
+
+       line = ldap_charray2str( argv, "\" \"" );
+       if ( line != NULL ) {
+               int     len = strlen( argv[ 0 ] );
+
+               ber_str2bv( line, 0, 0, &bv );
+               AC_MEMCPY( &bv.bv_val[ len ], &bv.bv_val[ len + 1 ],
+                       bv.bv_len - ( len + 1 ) );
+               bv.bv_val[ bv.bv_len - 1 ] = '"';
+               ber_bvarray_add( &rwmap->rwm_bva_rewrite, &bv );
+       }
+
+       return 0;
+}
+
+static int
+rwm_info_init( struct ldaprwmap *rwmap )
+{
+       char                    *rargv[ 3 ];
+
+       rwmap->rwm_rw = rewrite_info_init( REWRITE_MODE_USE_DEFAULT );
+       if ( rwmap->rwm_rw == NULL ) {
+               return -1;
+       }
+
+       /* 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 );
+
+       return 0;
+}
+
 static int
 rwm_cf_gen( ConfigArgs *c )
 {
@@ -1913,6 +2003,7 @@ rwm_cf_gen( ConfigArgs *c )
 
        BackendDB               db;
        char                    *argv0;
+       int                     idx0 = 0;
        int                     rc = 0;
 
        db = *c->be;
@@ -1970,7 +2061,6 @@ rwm_cf_gen( ConfigArgs *c )
                switch ( c->type ) {
                case RWM_CF_REWRITE:
                        if ( c->valx >= 0 ) {
-                               /* single modification is not allowed */
                                rc = 1;
 
                        } else if ( rwmap->rwm_rw != NULL ) {
@@ -1979,6 +2069,8 @@ rwm_cf_gen( ConfigArgs *c )
 
                                ber_bvarray_free( rwmap->rwm_bva_rewrite );
                                rwmap->rwm_bva_rewrite = NULL;
+
+                               rc = rwm_info_init( rwmap );
                        }
                        break;
 
@@ -2017,59 +2109,35 @@ rwm_cf_gen( ConfigArgs *c )
                return rc;
        }
 
+       if ( strncasecmp( c->argv[ 0 ], "olcRwm", STRLENOF( "olcRwm" ) ) == 0 ) {
+               idx0 = 1;
+       }
+
        switch ( c->type ) {
        case RWM_CF_REWRITE:
-               argv0 = c->argv[ 0 ];
-               c->argv[ 0 ] += STRLENOF( "rwm-" );
-               rc = rwm_rw_config( &db, c->fname, c->lineno, c->argc, c->argv );
-               c->argv[ 0 ] = argv0;
-               if ( rc ) {
+               if ( c->valx >= 0 ) {
                        return 1;
+               }
 
-               } else {
-                       char            *line;
-                       struct berval   bv;
-
-                       line = ldap_charray2str( c->argv, "\" \"" );
-                       if ( line != NULL ) {
-                               int     len = strlen( c->argv[ 0 ] );
-
-                               ber_str2bv( line, 0, 0, &bv );
-                               AC_MEMCPY( &bv.bv_val[ len ], &bv.bv_val[ len + 1 ],
-                                       bv.bv_len - ( len + 1 ) );
-                               bv.bv_val[ bv.bv_len - 1 ] = '"';
-                               ber_bvarray_add( &rwmap->rwm_bva_rewrite, &bv );
-                       }
+               argv0 = c->argv[ idx0 ];
+               if ( strncasecmp( argv0, "rwm-", STRLENOF( "rwm-" ) ) != 0 ) {
+                       return 1;
                }
-               break;
+               c->argv[ idx0 ] += STRLENOF( "rwm-" );
+               if ( strcasecmp( c->argv[ idx0 ], "suffixmassage" ) == 0 ) {
+                       rc = rwm_suffixmassage_config( &db, c->fname, c->lineno,
+                               c->argc - idx0, &c->argv[ idx0 ] );
 
-       case RWM_CF_SUFFIXMASSAGE:
-               argv0 = c->argv[ 0 ];
-               c->argv[ 0 ] += STRLENOF( "rwm-" );
-               rc = rwm_suffixmassage_config( &db, c->fname, c->lineno, c->argc, c->argv );
-               c->argv[ 0 ] = argv0;
+               } else {
+                       rc = rwm_rw_config( &db, c->fname, c->lineno,
+                               c->argc - idx0, &c->argv[ idx0 ] );
+               }
+               c->argv[ idx0 ] = argv0;
                if ( rc ) {
                        return 1;
 
                } else {
-                       char            *line;
-                       struct berval   bv;
-
-                       /* FIXME: not optimal; in fact, this keeps track
-                        * of the fact that a set of rules was added
-                        * using the rwm-suffixmassage shortcut, but the
-                        * rules are not clarified */
-
-                       line = ldap_charray2str( c->argv, "\" \"" );
-                       if ( line != NULL ) {
-                               int     len = strlen( c->argv[ 0 ] );
-
-                               ber_str2bv( line, 0, 0, &bv );
-                               AC_MEMCPY( &bv.bv_val[ len ], &bv.bv_val[ len + 1 ],
-                                       bv.bv_len - ( len + 1 ) );
-                               bv.bv_val[ bv.bv_len - 1 ] = '"';
-                               ber_bvarray_add( &rwmap->rwm_bva_rewrite, &bv );
-                       }
+                       rwm_bva_rewrite_add( rwmap, &c->argv[ idx0 ] );
                }
                break;
 
@@ -2085,6 +2153,10 @@ rwm_cf_gen( ConfigArgs *c )
                break;
 
        case RWM_CF_MAP:
+               if ( c->valx >= 0 ) {
+                       return 1;
+               }
+
                argv0 = c->argv[ 0 ];
                c->argv[ 0 ] += STRLENOF( "rwm-" );
                rc = rwm_m_config( &db, c->fname, c->lineno, c->argc, c->argv );
@@ -2127,28 +2199,11 @@ rwm_db_init(
 {
        slap_overinst           *on = (slap_overinst *) be->bd_info;
        struct ldaprwmap        *rwmap;
-       char                    *rargv[ 3 ];
        int                     rc = 0;
 
        rwmap = (struct ldaprwmap *)ch_calloc( 1, sizeof( struct ldaprwmap ) );
 
-       rwmap->rwm_rw = rewrite_info_init( REWRITE_MODE_USE_DEFAULT );
-       if ( rwmap->rwm_rw == NULL ) {
-               rc = -1;
-               goto error_return;
-       }
-
-       /* 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 );
+       rc = rwm_info_init( rwmap );
 
 error_return:;
        on->on_bi.bi_private = (void *)rwmap;