From ba6ac023ad20c1a37e2ec8d796e86ef73571a7de Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Thu, 30 Dec 2004 17:45:07 +0000 Subject: [PATCH] works now --- servers/slapd/back-meta/back-meta.h | 1 + servers/slapd/back-meta/compare.c | 18 +++ servers/slapd/back-meta/config.c | 28 ++++- servers/slapd/back-meta/map.c | 172 +++++++++++++++++++++++++--- servers/slapd/back-meta/search.c | 37 +++--- tests/scripts/test030-relay | 6 +- 6 files changed, 222 insertions(+), 40 deletions(-) diff --git a/servers/slapd/back-meta/back-meta.h b/servers/slapd/back-meta/back-meta.h index 7fa8ff2921..47d7351dcb 100644 --- a/servers/slapd/back-meta/back-meta.h +++ b/servers/slapd/back-meta/back-meta.h @@ -144,6 +144,7 @@ extern int suffix_massage_config( struct rewrite_info *info, struct berval *pvnc, struct berval *nvnc, struct berval *prnc, struct berval *nrnc); #endif /* ENABLE_REWRITE */ +extern int ldap_back_referral_result_rewrite( dncookie *dc, BerVarray a_vals ); extern int ldap_dnattr_rewrite( dncookie *dc, BerVarray a_vals ); extern int ldap_dnattr_result_rewrite( dncookie *dc, BerVarray a_vals ); diff --git a/servers/slapd/back-meta/compare.c b/servers/slapd/back-meta/compare.c index f5468c2449..cd3b9b1fc0 100644 --- a/servers/slapd/back-meta/compare.c +++ b/servers/slapd/back-meta/compare.c @@ -114,6 +114,21 @@ meta_back_compare( Operation *op, SlapReply *rs ) if ( mapped_attr.bv_val == NULL || mapped_attr.bv_val[0] == '\0' ) { continue; } + + if ( op->oq_compare.rs_ava->aa_desc->ad_type->sat_syntax == slap_schema.si_syn_distinguishedName ) + { + dc.ctx = "compareAttrDN"; + + switch ( ldap_back_dn_massage( &dc, &op->oq_compare.rs_ava->aa_value, &mapped_value ) ) + { + case LDAP_UNWILLING_TO_PERFORM: + rc = 1; + goto finish; + + default: + break; + } + } } /* @@ -123,13 +138,16 @@ meta_back_compare( Operation *op, SlapReply *rs ) */ msgid[ i ] = ldap_compare( lc->conns[ i ].ld, mdn.bv_val, mapped_attr.bv_val, mapped_value.bv_val ); + if ( mdn.bv_val != op->o_req_dn.bv_val ) { free( mdn.bv_val ); mdn.bv_val = NULL; } + if ( mapped_attr.bv_val != op->oq_compare.rs_ava->aa_desc->ad_cname.bv_val ) { free( mapped_attr.bv_val ); } + if ( mapped_value.bv_val != op->oq_compare.rs_ava->aa_value.bv_val ) { free( mapped_value.bv_val ); } diff --git a/servers/slapd/back-meta/config.c b/servers/slapd/back-meta/config.c index 90c53350d3..aec82d070f 100644 --- a/servers/slapd/back-meta/config.c +++ b/servers/slapd/back-meta/config.c @@ -771,10 +771,10 @@ suffix_massage_config( ch_free( rargv[ 2 ] ); rargv[ 0 ] = "rewriteContext"; - rargv[ 1 ] = "searchResult"; + rargv[ 1 ] = "searchEntryDN"; rargv[ 2 ] = NULL; rewrite_parse( info, "", ++line, 2, rargv ); - + rargv[ 0 ] = "rewriteRule"; rargv[ 1 ] = suffix_massage_regexize( prnc->bv_val ); rargv[ 2 ] = suffix_massage_patternize( pvnc->bv_val ); @@ -784,20 +784,40 @@ suffix_massage_config( ch_free( rargv[ 1 ] ); ch_free( rargv[ 2 ] ); + /* backward compatibility */ + rargv[ 0 ] = "rewriteContext"; + rargv[ 1 ] = "searchResult"; + rargv[ 2 ] = "alias"; + rargv[ 3 ] = "searchEntryDN"; + rargv[ 4 ] = NULL; + rewrite_parse( info, "", ++line, 4, rargv ); + rargv[ 0 ] = "rewriteContext"; rargv[ 1 ] = "matchedDN"; rargv[ 2 ] = "alias"; - rargv[ 3 ] = "searchResult"; + rargv[ 3 ] = "searchEntryDN"; rargv[ 4 ] = NULL; rewrite_parse( info, "", ++line, 4, rargv ); rargv[ 0 ] = "rewriteContext"; rargv[ 1 ] = "searchAttrDN"; rargv[ 2 ] = "alias"; - rargv[ 3 ] = "searchResult"; + rargv[ 3 ] = "searchEntryDN"; rargv[ 4 ] = NULL; rewrite_parse( info, "", ++line, 4, rargv ); + /* NOTE: this corresponds to #undef'ining RWM_REFERRAL_REWRITE; + * see servers/slapd/overlays/rwm.h for details */ + rargv[ 0 ] = "rewriteContext"; + rargv[ 1 ] = "referralAttrDN"; + rargv[ 2 ] = NULL; + rewrite_parse( info, "", ++line, 2, rargv ); + + rargv[ 0 ] = "rewriteContext"; + rargv[ 1 ] = "referralDN"; + rargv[ 2 ] = NULL; + rewrite_parse( info, "", ++line, 2, rargv ); + return 0; } #endif /* ENABLE_REWRITE */ diff --git a/servers/slapd/back-meta/map.c b/servers/slapd/back-meta/map.c index e6a6c7b4be..a76c5f0f85 100644 --- a/servers/slapd/back-meta/map.c +++ b/servers/slapd/back-meta/map.c @@ -209,7 +209,7 @@ map_attr_value( dncookie fdc = *dc; #ifdef ENABLE_REWRITE - fdc.ctx = "searchFilter"; + fdc.ctx = "searchFilterAttrDN"; #endif switch ( ldap_back_dn_massage( &fdc, value, &vtmp ) ) { @@ -245,8 +245,8 @@ map_attr_value( return 0; } -int -ldap_back_filter_map_rewrite( +static int +ldap_back_int_filter_map_rewrite( dncookie *dc, Filter *f, struct berval *fstr, @@ -421,7 +421,7 @@ ldap_back_filter_map_rewrite( for ( p = f->f_list; p != NULL; p = p->f_next ) { len = fstr->bv_len; - if ( ldap_back_filter_map_rewrite( dc, p, &vtmp, remap ) ) + if ( ldap_back_int_filter_map_rewrite( dc, p, &vtmp, remap ) ) { return -1; } @@ -469,26 +469,163 @@ ldap_back_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 ); + switch ( f->f_result ) { + case LDAP_COMPARE_FALSE: + ber_str2bv( "(?=false)", STRLENOF( "(?=false)" ), 1, fstr ); + break; + case LDAP_COMPARE_TRUE: + ber_str2bv( "(?=true)", STRLENOF( "(?=true)" ), 1, fstr ); + break; + case SLAPD_COMPARE_UNDEFINED: + ber_str2bv( "(?=undefined)", STRLENOF( "(?=undefined)" ), 1, fstr ); + break; + default: + ber_str2bv( "(?=error)", STRLENOF( "(?=error)" ), 1, fstr ); + break; + } break; default: - ber_str2bv( "(?=unknown)", sizeof("(?=unknown)")-1, 1, fstr ); + ber_str2bv( "(?=unknown)", STRLENOF( "(?=unknown)" ), 1, fstr ); break; } return 0; } +int +ldap_back_filter_map_rewrite( + dncookie *dc, + Filter *f, + struct berval *fstr, + int remap ) +{ + int rc; + dncookie fdc; + struct berval ftmp; + + rc = ldap_back_int_filter_map_rewrite( dc, f, fstr, remap ); + +#ifdef ENABLE_REWRITE + if ( rc != LDAP_SUCCESS ) { + return rc; + } + + fdc = *dc; + ftmp = *fstr; + + fdc.ctx = "searchFilter"; + + switch ( rewrite_session( fdc.rwmap->rwm_rw, fdc.ctx, + ( !BER_BVISEMPTY( &ftmp ) ? ftmp.bv_val : "" ), + fdc.conn, &fstr->bv_val ) ) + { + case REWRITE_REGEXEC_OK: + if ( !BER_BVISNULL( fstr ) ) { + fstr->bv_len = strlen( fstr->bv_val ); + } else { + *fstr = ftmp; + } + Debug( LDAP_DEBUG_ARGS, + "[rw] %s: \"%s\" -> \"%s\"\n", + fdc.ctx, ftmp.bv_val, fstr->bv_val ); + rc = LDAP_SUCCESS; + break; + + case REWRITE_REGEXEC_UNWILLING: + if ( fdc.rs ) { + fdc.rs->sr_err = LDAP_UNWILLING_TO_PERFORM; + fdc.rs->sr_text = "Operation not allowed"; + } + rc = LDAP_UNWILLING_TO_PERFORM; + break; + + case REWRITE_REGEXEC_ERR: + if ( fdc.rs ) { + fdc.rs->sr_err = LDAP_OTHER; + fdc.rs->sr_text = "Rewrite error"; + } + rc = LDAP_OTHER; + break; + } +#endif /* ENABLE_REWRITE */ + + return rc; +} + +int +ldap_back_referral_result_rewrite( + dncookie *dc, + BerVarray a_vals +) +{ + int i, last; + + assert( dc ); + assert( a_vals ); + + for ( last = 0; !BER_BVISNULL( &a_vals[ last ] ); last++ ) + ; + last--; + + for ( i = 0; !BER_BVISNULL( &a_vals[ i ] ); i++ ) { + struct berval dn, olddn; + int rc; + LDAPURLDesc *ludp; + + rc = ldap_url_parse( a_vals[ i ].bv_val, &ludp ); + if ( rc != LDAP_URL_SUCCESS ) { + /* leave attr untouched if massage failed */ + continue; + } + + ber_str2bv( ludp->lud_dn, 0, 0, &olddn ); + + rc = ldap_back_dn_massage( dc, &olddn, &dn ); + switch ( rc ) { + case LDAP_UNWILLING_TO_PERFORM: + /* + * FIXME: need to check if it may be considered + * legal to trim values when adding/modifying; + * it should be when searching (e.g. ACLs). + */ + LBER_FREE( a_vals[ i ].bv_val ); + if ( last > i ) { + a_vals[ i ] = a_vals[ last ]; + } + BER_BVZERO( &a_vals[ last ] ); + last--; + i--; + break; + + default: + /* leave attr untouched if massage failed */ + if ( !BER_BVISNULL( &dn ) && olddn.bv_val != dn.bv_val ) + { + char *newurl; + + ludp->lud_dn = dn.bv_val; + newurl = ldap_url_desc2str( ludp ); + if ( newurl == NULL ) { + /* FIXME: leave attr untouched + * even if ldap_url_desc2str failed... */ + break; + } + + LBER_FREE( a_vals[ i ].bv_val ); + ber_str2bv( newurl, 0, 1, &a_vals[ i ] ); + LDAP_FREE( newurl ); + ludp->lud_dn = olddn.bv_val; + } + break; + } + + ldap_free_urldesc( ludp ); + } + + return 0; +} + /* * I don't like this much, but we need two different * functions because different heap managers may be @@ -558,12 +695,11 @@ ldap_dnattr_result_rewrite( * legal to trim values when adding/modifying; * it should be when searching (e.g. ACLs). */ - LBER_FREE( &a_vals[i].bv_val ); + LBER_FREE( a_vals[i].bv_val ); if ( last > i ) { a_vals[i] = a_vals[last]; } - a_vals[last].bv_val = NULL; - a_vals[last].bv_len = 0; + BER_BVZERO( &a_vals[last] ); last--; break; diff --git a/servers/slapd/back-meta/search.c b/servers/slapd/back-meta/search.c index 0939194cc4..68883a0e4b 100644 --- a/servers/slapd/back-meta/search.c +++ b/servers/slapd/back-meta/search.c @@ -380,11 +380,6 @@ new_candidate:; char **references = NULL; int cnt; - /* - * FIXME: should we collect references - * and send them alltogether at the end? - */ - rc = ldap_parse_reference( lsc->ld, res, &references, &rs->sr_ctrls, 1 ); res = NULL; @@ -397,24 +392,35 @@ new_candidate:; continue; } +#ifdef ENABLE_REWRITE + dc.ctx = "referralDN"; +#else /* ! ENABLE_REWRITE */ + dc.tofrom = 0; + dc.normalized = 0; +#endif /* ! ENABLE_REWRITE */ for ( cnt = 0; references[ cnt ]; cnt++ ) - /* NO OP */ ; - - rs->sr_ref = ch_calloc( cnt + 1, sizeof( struct berval ) ); + ; + + rs->sr_ref = ch_calloc( sizeof( struct berval ), cnt + 1 ); for ( cnt = 0; references[ cnt ]; cnt++ ) { - rs->sr_ref[ cnt ].bv_val = references[ cnt ]; - rs->sr_ref[ cnt ].bv_len = strlen( references[ cnt ] ); + ber_str2bv( references[ cnt ], 0, 1, &rs->sr_ref[ cnt ] ); } + BER_BVZERO( &rs->sr_ref[ cnt ] ); + + ( void )ldap_back_referral_result_rewrite( &dc, rs->sr_ref ); - /* ignore return value by now */ - ( void )send_search_reference( op, rs ); + if ( rs->sr_ref != NULL && !BER_BVISNULL( &rs->sr_ref[ 0 ] ) ) { + /* ignore return value by now */ + ( void )send_search_reference( op, rs ); + + ber_bvarray_free( rs->sr_ref ); + rs->sr_ref = NULL; + } /* cleanup */ if ( references ) { ldap_value_free( references ); - ch_free( rs->sr_ref ); - rs->sr_ref = NULL; } if ( rs->sr_ctrls ) { @@ -677,6 +683,9 @@ meta_send_entry( } else if ( attr->a_desc->ad_type->sat_syntax == slap_schema.si_syn_distinguishedName ) { ldap_dnattr_result_rewrite( &dc, attr->a_vals ); + + } else if ( attr->a_desc == slap_schema.si_ad_ref ) { + ldap_back_referral_result_rewrite( &dc, attr->a_vals ); } if ( last && attr->a_desc->ad_type->sat_equality && diff --git a/tests/scripts/test030-relay b/tests/scripts/test030-relay index 0e0c11a83b..e7e457caed 100755 --- a/tests/scripts/test030-relay +++ b/tests/scripts/test030-relay @@ -38,13 +38,11 @@ else RELAYS="$RELAYS ldap" fi -# back-meta - disable by now, needs work to line up with rwm +# back-meta if test $BACKMETA = metano ; then echo "meta backend not available, test skipped" else - # RELAYS="$RELAYS meta" - echo "==> back-meta disabled by now, needs work" - echo "" + RELAYS="$RELAYS meta" fi first=1 -- 2.39.5