From 6ee6739b4834d4e9ace0ff0f3874405eada69746 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Sat, 19 Jun 2010 03:15:41 +0000 Subject: [PATCH] Add suffixmassage processing --- servers/slapd/syncrepl.c | 113 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 105 insertions(+), 8 deletions(-) diff --git a/servers/slapd/syncrepl.c b/servers/slapd/syncrepl.c index 5ff05ced3d..2bba5fdef5 100644 --- a/servers/slapd/syncrepl.c +++ b/servers/slapd/syncrepl.c @@ -33,6 +33,7 @@ #ifdef ENABLE_REWRITE #include "rewrite.h" +#define SUFFIXM_CTX "" #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 = ⊅ } 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 -- 2.39.5