]> git.sur5r.net Git - openldap/commitdiff
Add suffixmassage processing
authorHoward Chu <hyc@openldap.org>
Sat, 19 Jun 2010 03:15:41 +0000 (03:15 +0000)
committerHoward Chu <hyc@openldap.org>
Sat, 19 Jun 2010 03:15:41 +0000 (03:15 +0000)
servers/slapd/syncrepl.c

index 5ff05ced3d694fee14288614dcca233730eb19c0..2bba5fdef5dd4dd4a053a0cc7a5193f94362a68f 100644 (file)
@@ -33,6 +33,7 @@
 
 #ifdef ENABLE_REWRITE
 #include "rewrite.h"
+#define SUFFIXM_CTX    "<suffix massage>"
 #endif
 
 struct nonpresent_entry {
@@ -1561,6 +1562,44 @@ deleted:
        return NULL;
 }
 
+#ifdef ENABLE_REWRITE
+static int
+syncrepl_rewrite_dn(
+       syncinfo_t *si,
+       struct berval *dn,
+       struct berval *sdn )
+{
+       char nul;
+       int rc;
+
+       nul = dn->bv_val[dn->bv_len];
+       dn->bv_val[dn->bv_len] = 0;
+       rc = rewrite( si->si_rewrite, SUFFIXM_CTX, dn->bv_val, &sdn->bv_val );
+       dn->bv_val[dn->bv_len] = nul;
+
+       if ( rc == REWRITE_REGEXEC_OK && sdn->bv_val )
+               sdn->bv_len = strlen( sdn->bv_val );
+       return rc;
+}
+#define        REWRITE_VAL(si, ad, bv, bv2)    \
+       BER_BVZERO( &bv2 );     \
+       if ( si->si_rewrite && ad->ad_type->sat_syntax == slap_schema.si_syn_distinguishedName) \
+               syncrepl_rewrite_dn( si, &bv, &bv2); \
+       if ( BER_BVISNULL( &bv2 ))  \
+               ber_dupbv( &bv2, &bv )
+#define REWRITE_DN(si, bv, bv2, dn, ndn) \
+       BER_BVZERO( &bv2 );     \
+       if (si->si_rewrite) \
+               syncrepl_rewrite_dn(si, &bv, &bv2); \
+       rc = dnPrettyNormal( NULL, bv2.bv_val ? &bv2 : &bv, &dn, &ndn, op->o_tmpmemctx ); \
+       ch_free(bv2.bv_val)
+#else
+#define REWRITE_VAL(si, ad, bv, bv2)   ber_dupbv(&bv2, &bv)
+#define REWRITE_DN(si, bv, bv2, dn, ndn) \
+       rc = dnPrettyNormal( NULL, &bv, &dn, &ndn, op->o_tmpmemctx )
+#endif
+
+
 static slap_verbmasks modops[] = {
        { BER_BVC("add"), LDAP_REQ_ADD },
        { BER_BVC("delete"), LDAP_REQ_DELETE },
@@ -1645,7 +1684,7 @@ syncrepl_accesslog_mods(
                if ( colon[2] == ' ' ) {
                        bv.bv_val = colon + 3;
                        bv.bv_len = vals[i].bv_len - ( bv.bv_val - vals[i].bv_val );
-                       ber_dupbv( &bv2, &bv );
+                       REWRITE_VAL( si, ad, bv, bv2 );
                        ber_bvarray_add( &mod->sml_values, &bv2 );
                        mod->sml_numvals++;
                }
@@ -1682,7 +1721,7 @@ syncrepl_message_to_op(
        size_t textlen = sizeof txtbuf;
 
        struct berval   bdn, dn = BER_BVNULL, ndn;
-       struct berval   bv, *bvals = NULL;
+       struct berval   bv, bv2, *bvals = NULL;
        struct berval   rdn = BER_BVNULL, sup = BER_BVNULL,
                prdn = BER_BVNULL, nrdn = BER_BVNULL,
                psup = BER_BVNULL, nsup = BER_BVNULL;
@@ -1713,7 +1752,7 @@ syncrepl_message_to_op(
        op->o_tag = LBER_DEFAULT;
        op->o_bd = si->si_wbe;
 
-       if ( BER_BVISEMPTY( &bdn ) && !BER_BVISEMPTY( &op->o_bd->be_nsuffix[0] ) ) {
+       if ( BER_BVISEMPTY( &bdn )) {
                Debug( LDAP_DEBUG_ANY,
                        "syncrepl_message_to_op: %s got empty dn",
                        si->si_ridtxt, 0, 0 );
@@ -1727,7 +1766,7 @@ syncrepl_message_to_op(
 
                if ( !ber_bvstrcasecmp( &bv, &ls->ls_dn ) ) {
                        bdn = bvals[0];
-                       rc = dnPrettyNormal( NULL, &bdn, &dn, &ndn, op->o_tmpmemctx );
+                       REWRITE_DN( si, bdn, bv2, dn, ndn );
                        if ( rc != LDAP_SUCCESS ) {
                                Debug( LDAP_DEBUG_ANY,
                                        "syncrepl_message_to_op: %s "
@@ -1844,9 +1883,9 @@ syncrepl_message_to_op(
                        goto done;
                }
                if ( !BER_BVISNULL( &sup ) ) {
-                       if ( dnPrettyNormal( NULL, &sup, &psup, &nsup, NULL ) ) {
+                       REWRITE_DN( si, sup, bv2, psup, nsup );
+                       if ( rc )
                                goto done;
-                       }
                        op->orr_newSup = &psup;
                        op->orr_nnewSup = &nsup;
                } else {
@@ -1936,7 +1975,7 @@ syncrepl_message_to_entry(
        char txtbuf[SLAP_TEXT_BUFLEN];
        size_t textlen = sizeof txtbuf;
 
-       struct berval   bdn = BER_BVNULL, dn, ndn;
+       struct berval   bdn = BER_BVNULL, dn, ndn, bv2;
        int             rc, is_ctx;
 
        *modlist = NULL;
@@ -1976,7 +2015,7 @@ syncrepl_message_to_entry(
                return -1;
        }
 
-       rc = dnPrettyNormal( NULL, &bdn, &dn, &ndn, op->o_tmpmemctx );
+       REWRITE_DN( si, bdn, bv2, dn, ndn );
        if ( rc != LDAP_SUCCESS ) {
                /* One of the things that could happen is that the schema
                 * is not lined-up; this could result in unknown attributes.
@@ -2029,6 +2068,26 @@ syncrepl_message_to_entry(
                mod->sml_nvalues = NULL;
                mod->sml_numvals = 0;   /* slap_mods_check will set this */
 
+#ifdef ENABLE_REWRITE
+               if (si->si_rewrite) {
+                       AttributeDescription *ad = NULL;
+                       slap_bv2ad( &tmp.sml_type, &ad, &text );
+                       if ( ad ) {
+                               mod->sml_desc = ad;
+                               mod->sml_type = ad->ad_cname;
+                               if ( ad->ad_type->sat_syntax == slap_schema.si_syn_distinguishedName ) {
+                                       int i;
+                                       for ( i = 0; tmp.sml_values[i].bv_val; i++ ) {
+                                               syncrepl_rewrite_dn( si, &tmp.sml_values[i], &bv2);
+                                               if ( !BER_BVISNULL( &bv2 )) {
+                                                       ber_memfree( tmp.sml_values[i].bv_val );
+                                                       tmp.sml_values[i] = bv2;
+                                               }
+                                       }
+                               }
+                       }
+               }
+#endif
                *modtail = mod;
                modtail = &mod->sml_next;
        }
@@ -3932,7 +3991,37 @@ syncinfo_free( syncinfo_t *sie, int free_all )
        } while ( free_all && si_next );
 }
 
+#ifdef ENABLE_REWRITE
+static int
+config_suffixm( ConfigArgs *c, syncinfo_t *si )
+{
+       char *argvEngine[] = { "rewriteEngine", "on", NULL };
+       char *argvContext[] = { "rewriteContext", SUFFIXM_CTX, NULL };
+       char *argvRule[] = { "rewriteRule", NULL, si->si_suffixm.bv_val, ":", NULL };
+       char *vnc;
+       int rc;
+
+       if ( si->si_rewrite )
+               rewrite_info_delete( &si->si_rewrite );
+       si->si_rewrite = rewrite_info_init( REWRITE_MODE_USE_DEFAULT );
+
+       rc = rewrite_parse( si->si_rewrite, c->fname, c->lineno, 2, argvEngine );
+       if ( rc != LDAP_SUCCESS )
+               return rc;
+
+       rc = rewrite_parse( si->si_rewrite, c->fname, c->lineno, 2, argvContext );
+       if ( rc != LDAP_SUCCESS )
+               return rc;
+
+       vnc = ch_malloc( si->si_base.bv_len + 2 );
+       lutil_strcopy( lutil_strcopy( vnc, si->si_base.bv_val ), "$" );
 
+       argvRule[1] = vnc;
+       rc = rewrite_parse( si->si_rewrite, c->fname, c->lineno, 4, argvRule );
+       ch_free( vnc );
+       return rc;
+}
+#endif
 
 /* NOTE: used & documented in slapd.conf(5) */
 #define IDSTR                  "rid"
@@ -4482,6 +4571,14 @@ parse_syncrepl_line(
 
 #ifdef ENABLE_REWRITE
        if ( si->si_got & GOT_SUFFIXM ) {
+               if (config_suffixm( c, si )) {
+                       ch_free( si->si_suffixm.bv_val );
+                       BER_BVZERO( &si->si_suffixm );
+                       snprintf( c->cr_msg, sizeof( c->cr_msg ),
+                               "Error configuring rewrite engine" );
+                       Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
+                       return -1;
+               }
        }
 #endif