1 /* rwmmap.c - rewrite/mapping routines */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 1999-2005 The OpenLDAP Foundation.
6 * Portions Copyright 1999-2003 Howard Chu.
7 * Portions Copyright 2000-2003 Pierangelo Masarati.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted only as authorized by the OpenLDAP
14 * A copy of this license is available in the file LICENSE in the
15 * top-level directory of the distribution or, alternatively, at
16 * <http://www.OpenLDAP.org/license.html>.
19 * This work was initially developed by the Howard Chu for inclusion
20 * in OpenLDAP Software and subsequently enhanced by Pierangelo
30 #include <ac/string.h>
31 #include <ac/socket.h>
36 #undef ldap_debug /* silence a warning in ldap-int.h */
37 #include "../../../libraries/libldap/ldap-int.h"
40 rwm_mapping_cmp( const void *c1, const void *c2 )
42 struct ldapmapping *map1 = (struct ldapmapping *)c1;
43 struct ldapmapping *map2 = (struct ldapmapping *)c2;
44 int rc = map1->m_src.bv_len - map2->m_src.bv_len;
50 return strcasecmp( map1->m_src.bv_val, map2->m_src.bv_val );
54 rwm_mapping_dup( void *c1, void *c2 )
56 struct ldapmapping *map1 = (struct ldapmapping *)c1;
57 struct ldapmapping *map2 = (struct ldapmapping *)c2;
58 int rc = map1->m_src.bv_len - map2->m_src.bv_len;
64 return ( ( strcasecmp( map1->m_src.bv_val, map2->m_src.bv_val ) == 0 ) ? -1 : 0 );
68 rwm_map_init( struct ldapmap *lm, struct ldapmapping **m )
70 struct ldapmapping *mapping;
78 mapping = (struct ldapmapping *)ch_calloc( 2,
79 sizeof( struct ldapmapping ) );
80 if ( mapping == NULL ) {
81 return LDAP_NO_MEMORY;
84 /* FIXME: I don't think this is needed any more... */
85 rc = slap_str2ad( "objectClass", &mapping->m_src_ad, &text );
86 if ( rc != LDAP_SUCCESS ) {
90 mapping->m_dst_ad = mapping->m_src_ad;
91 ber_dupbv( &mapping->m_dst, &mapping->m_src_ad->ad_cname );
92 ber_dupbv( &mapping->m_dst, &mapping->m_src );
94 mapping[1].m_src = mapping->m_src;
95 mapping[1].m_dst = mapping->m_dst;
97 avl_insert( &lm->map, (caddr_t)mapping,
98 rwm_mapping_cmp, rwm_mapping_dup );
99 avl_insert( &lm->remap, (caddr_t)&mapping[1],
100 rwm_mapping_cmp, rwm_mapping_dup );
108 rwm_mapping( struct ldapmap *map, struct berval *s, struct ldapmapping **m, int remap )
111 struct ldapmapping fmapping;
115 if ( remap == RWM_REMAP ) {
123 *m = (struct ldapmapping *)avl_find( tree, (caddr_t)&fmapping,
127 return map->drop_missing;
134 rwm_map( struct ldapmap *map, struct berval *s, struct berval *bv, int remap )
136 struct ldapmapping *mapping;
139 ( void )rwm_mapping( map, s, &mapping, remap );
140 if ( mapping != NULL ) {
141 if ( !BER_BVISNULL( &mapping->m_dst ) ) {
142 *bv = mapping->m_dst;
147 if ( !map->drop_missing ) {
153 * Map attribute names in place
157 struct ldapmap *at_map,
158 struct ldapmap *oc_map,
174 for ( i = 0; !BER_BVISNULL( &an[i].an_name ); i++ )
176 *anp = ch_malloc( ( i + 1 )* sizeof( AttributeName ) );
177 if ( *anp == NULL ) {
178 return LDAP_NO_MEMORY;
181 for ( i = 0, j = 0; !BER_BVISNULL( &an[i].an_name ); i++ ) {
182 struct ldapmapping *m;
183 int at_drop_missing = 0,
186 if ( an[i].an_desc ) {
188 /* FIXME: better leave as is? */
192 at_drop_missing = rwm_mapping( at_map, &an[i].an_name, &m, remap );
193 if ( at_drop_missing || ( m && BER_BVISNULL( &m->m_dst ) ) ) {
204 if ( remap == RWM_MAP ) {
205 (*anp)[j].an_name = m->m_dst;
206 (*anp)[j].an_desc = m->m_dst_ad;
208 (*anp)[j].an_name = m->m_src;
209 (*anp)[j].an_desc = m->m_src_ad;
216 } else if ( an[i].an_oc ) {
218 /* FIXME: better leave as is? */
222 oc_drop_missing = rwm_mapping( oc_map, &an[i].an_name, &m, remap );
224 if ( oc_drop_missing || ( m && BER_BVISNULL( &m->m_dst ) ) ) {
235 if ( remap == RWM_MAP ) {
236 (*anp)[j].an_name = m->m_dst;
237 (*anp)[j].an_oc = m->m_dst_oc;
239 (*anp)[j].an_name = m->m_src;
240 (*anp)[j].an_oc = m->m_src_oc;
244 at_drop_missing = rwm_mapping( at_map, &an[i].an_name, &m, remap );
246 if ( at_drop_missing || !m ) {
248 oc_drop_missing = rwm_mapping( oc_map, &an[i].an_name, &m, remap );
250 /* if both at_map and oc_map required to drop missing,
252 if ( oc_drop_missing && at_drop_missing ) {
256 /* if no oc_map mapping was found and at_map required
257 * to drop missing, then do it; otherwise, at_map wins
258 * and an is considered an attr and is left unchanged */
260 if ( at_drop_missing ) {
268 if ( BER_BVISNULL( &m->m_dst ) ) {
273 if ( remap == RWM_MAP ) {
274 (*anp)[j].an_name = m->m_dst;
275 (*anp)[j].an_oc = m->m_dst_oc;
277 (*anp)[j].an_name = m->m_src;
278 (*anp)[j].an_oc = m->m_src_oc;
284 if ( !BER_BVISNULL( &m->m_dst ) ) {
286 if ( remap == RWM_MAP ) {
287 (*anp)[j].an_name = m->m_dst;
288 (*anp)[j].an_desc = m->m_dst_ad;
290 (*anp)[j].an_name = m->m_src;
291 (*anp)[j].an_desc = m->m_src_ad;
299 if ( j == 0 && i != 0 ) {
300 memset( &(*anp)[0], 0, sizeof( AttributeName ) );
301 BER_BVSTR( &(*anp)[0].an_name, LDAP_NO_ATTRS );
303 memset( &(*anp)[j], 0, sizeof( AttributeName ) );
310 struct ldapmap *at_map,
320 *mapped_attrs = NULL;
324 for ( i = 0; !BER_BVISNULL( &an[ i ].an_name ); i++ ) {
328 na = (char **)ch_calloc( i + 1, sizeof( char * ) );
330 *mapped_attrs = NULL;
331 return LDAP_NO_MEMORY;
334 for ( i = j = 0; !BER_BVISNULL( &an[i].an_name ); i++ ) {
335 struct ldapmapping *mapping;
337 if ( rwm_mapping( at_map, &an[i].an_name, &mapping, remap ) ) {
342 na[ j++ ] = an[ i ].an_name.bv_val;
344 } else if ( !BER_BVISNULL( &mapping->m_dst ) ) {
345 na[ j++ ] = mapping->m_dst.bv_val;
349 if ( j == 0 && i != 0 ) {
350 na[ j++ ] = LDAP_NO_ATTRS;
363 AttributeDescription **adp,
364 struct berval *mapped_attr,
365 struct berval *value,
366 struct berval *mapped_value,
369 struct berval vtmp = BER_BVNULL;
371 AttributeDescription *ad = *adp;
372 struct ldapmapping *mapping = NULL;
374 rwm_mapping( &dc->rwmap->rwm_at, &ad->ad_cname, &mapping, remap );
375 if ( mapping == NULL ) {
376 if ( dc->rwmap->rwm_at.drop_missing ) {
380 *mapped_attr = ad->ad_cname;
383 *mapped_attr = mapping->m_dst;
386 if ( value != NULL ) {
387 assert( mapped_value != NULL );
389 if ( ad->ad_type->sat_syntax == slap_schema.si_syn_distinguishedName )
394 #ifdef ENABLE_REWRITE
395 fdc.ctx = "searchFilterAttrDN";
396 #endif /* ENABLE_REWRITE */
399 rc = rwm_dn_massage_normalize( &fdc, value, &vtmp );
402 if ( vtmp.bv_val != value->bv_val ) {
407 case LDAP_UNWILLING_TO_PERFORM:
413 } else if ( ad == slap_schema.si_ad_objectClass
414 || ad == slap_schema.si_ad_structuralObjectClass )
416 rwm_map( &dc->rwmap->rwm_oc, value, &vtmp, remap );
417 if ( BER_BVISNULL( &vtmp ) || BER_BVISEMPTY( &vtmp ) ) {
425 filter_escape_value( &vtmp, mapped_value );
428 ch_free( vtmp.bv_val );
432 if ( mapping != NULL ) {
433 assert( mapping->m_dst_ad != NULL );
434 *adp = mapping->m_dst_ad;
441 rwm_int_filter_map_rewrite(
444 struct berval *fstr )
452 ber_bvfalse = BER_BVC( "(?=false)" ),
453 ber_bvtrue = BER_BVC( "(?=true)" ),
454 ber_bvundefined = BER_BVC( "(?=undefined)" ),
455 ber_bverror = BER_BVC( "(?=error)" ),
456 ber_bvunknown = BER_BVC( "(?=unknown)" ),
457 ber_bvnone = BER_BVC( "(?=none)" );
461 ber_dupbv( fstr, &ber_bvnone );
465 switch ( f->f_choice ) {
466 case LDAP_FILTER_EQUALITY:
467 if ( map_attr_value( dc, &f->f_av_desc, &atmp,
468 &f->f_av_value, &vtmp, RWM_MAP ) )
473 fstr->bv_len = atmp.bv_len + vtmp.bv_len + STRLENOF( "(=)" );
474 fstr->bv_val = ch_malloc( fstr->bv_len + 1 );
476 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=%s)",
477 atmp.bv_val, vtmp.bv_val );
479 ch_free( vtmp.bv_val );
483 if ( map_attr_value( dc, &f->f_av_desc, &atmp,
484 &f->f_av_value, &vtmp, RWM_MAP ) )
489 fstr->bv_len = atmp.bv_len + vtmp.bv_len + STRLENOF( "(>=)" );
490 fstr->bv_val = ch_malloc( fstr->bv_len + 1 );
492 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s>=%s)",
493 atmp.bv_val, vtmp.bv_val );
495 ch_free( vtmp.bv_val );
499 if ( map_attr_value( dc, &f->f_av_desc, &atmp,
500 &f->f_av_value, &vtmp, RWM_MAP ) )
505 fstr->bv_len = atmp.bv_len + vtmp.bv_len + STRLENOF( "(<=)" );
506 fstr->bv_val = ch_malloc( fstr->bv_len + 1 );
508 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s<=%s)",
509 atmp.bv_val, vtmp.bv_val );
511 ch_free( vtmp.bv_val );
514 case LDAP_FILTER_APPROX:
515 if ( map_attr_value( dc, &f->f_av_desc, &atmp,
516 &f->f_av_value, &vtmp, RWM_MAP ) )
521 fstr->bv_len = atmp.bv_len + vtmp.bv_len + STRLENOF( "(~=)" );
522 fstr->bv_val = ch_malloc( fstr->bv_len + 1 );
524 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s~=%s)",
525 atmp.bv_val, vtmp.bv_val );
527 ch_free( vtmp.bv_val );
530 case LDAP_FILTER_SUBSTRINGS:
531 if ( map_attr_value( dc, &f->f_sub_desc, &atmp,
532 NULL, NULL, RWM_MAP ) )
537 /* cannot be a DN ... */
539 fstr->bv_len = atmp.bv_len + STRLENOF( "(=*)" );
540 fstr->bv_val = ch_malloc( fstr->bv_len + 128 );
542 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=*)",
545 if ( !BER_BVISNULL( &f->f_sub_initial ) ) {
548 filter_escape_value( &f->f_sub_initial, &vtmp );
550 fstr->bv_len += vtmp.bv_len;
551 fstr->bv_val = ch_realloc( fstr->bv_val, fstr->bv_len + 1 );
553 snprintf( &fstr->bv_val[len - 2], vtmp.bv_len + 3,
554 /* "(attr=" */ "%s*)",
557 ch_free( vtmp.bv_val );
560 if ( f->f_sub_any != NULL ) {
561 for ( i = 0; !BER_BVISNULL( &f->f_sub_any[i] ); i++ ) {
563 filter_escape_value( &f->f_sub_any[i], &vtmp );
565 fstr->bv_len += vtmp.bv_len + 1;
566 fstr->bv_val = ch_realloc( fstr->bv_val, fstr->bv_len + 1 );
568 snprintf( &fstr->bv_val[len - 1], vtmp.bv_len + 3,
569 /* "(attr=[init]*[any*]" */ "%s*)",
571 ch_free( vtmp.bv_val );
575 if ( !BER_BVISNULL( &f->f_sub_final ) ) {
578 filter_escape_value( &f->f_sub_final, &vtmp );
580 fstr->bv_len += vtmp.bv_len;
581 fstr->bv_val = ch_realloc( fstr->bv_val, fstr->bv_len + 1 );
583 snprintf( &fstr->bv_val[len - 1], vtmp.bv_len + 3,
584 /* "(attr=[init*][any*]" */ "%s)",
587 ch_free( vtmp.bv_val );
592 case LDAP_FILTER_PRESENT:
593 if ( map_attr_value( dc, &f->f_desc, &atmp,
594 NULL, NULL, RWM_MAP ) )
599 fstr->bv_len = atmp.bv_len + STRLENOF( "(=*)" );
600 fstr->bv_val = ch_malloc( fstr->bv_len + 1 );
602 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=*)",
606 case LDAP_FILTER_AND:
608 case LDAP_FILTER_NOT:
609 fstr->bv_len = STRLENOF( "(%)" );
610 fstr->bv_val = ch_malloc( fstr->bv_len + 128 );
612 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%c)",
613 f->f_choice == LDAP_FILTER_AND ? '&' :
614 f->f_choice == LDAP_FILTER_OR ? '|' : '!' );
616 for ( p = f->f_list; p != NULL; p = p->f_next ) {
619 if ( rwm_int_filter_map_rewrite( dc, p, &vtmp ) )
624 fstr->bv_len += vtmp.bv_len;
625 fstr->bv_val = ch_realloc( fstr->bv_val, fstr->bv_len + 1 );
627 snprintf( &fstr->bv_val[len-1], vtmp.bv_len + 2,
628 /*"("*/ "%s)", vtmp.bv_val );
630 ch_free( vtmp.bv_val );
635 case LDAP_FILTER_EXT: {
636 if ( f->f_mr_desc ) {
637 if ( map_attr_value( dc, &f->f_mr_desc, &atmp,
638 &f->f_mr_value, &vtmp, RWM_MAP ) )
644 BER_BVSTR( &atmp, "" );
645 filter_escape_value( &f->f_mr_value, &vtmp );
649 fstr->bv_len = atmp.bv_len +
650 ( f->f_mr_dnattrs ? STRLENOF( ":dn" ) : 0 ) +
651 ( f->f_mr_rule_text.bv_len ? f->f_mr_rule_text.bv_len + 1 : 0 ) +
652 vtmp.bv_len + STRLENOF( "(:=)" );
653 fstr->bv_val = ch_malloc( fstr->bv_len + 1 );
655 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s%s%s%s:=%s)",
657 f->f_mr_dnattrs ? ":dn" : "",
658 !BER_BVISEMPTY( &f->f_mr_rule_text ) ? ":" : "",
659 !BER_BVISEMPTY( &f->f_mr_rule_text ) ? f->f_mr_rule_text.bv_val : "",
661 ch_free( vtmp.bv_val );
665 case SLAPD_FILTER_COMPUTED:
666 switch ( f->f_result ) {
667 case LDAP_COMPARE_FALSE:
671 case LDAP_COMPARE_TRUE:
675 case SLAPD_COMPARE_UNDEFINED:
676 tmp = ber_bvundefined;
684 ber_dupbv( fstr, &tmp );
688 ber_dupbv( fstr, &ber_bvunknown );
696 rwm_filter_map_rewrite(
699 struct berval *fstr )
705 rc = rwm_int_filter_map_rewrite( dc, f, fstr );
707 #ifdef ENABLE_REWRITE
708 if ( rc != LDAP_SUCCESS ) {
715 fdc.ctx = "searchFilter";
717 switch ( rewrite_session( fdc.rwmap->rwm_rw, fdc.ctx,
718 ( !BER_BVISEMPTY( &ftmp ) ? ftmp.bv_val : "" ),
719 fdc.conn, &fstr->bv_val ) )
721 case REWRITE_REGEXEC_OK:
722 if ( !BER_BVISNULL( fstr ) ) {
723 fstr->bv_len = strlen( fstr->bv_val );
724 ch_free( ftmp.bv_val );
730 Debug( LDAP_DEBUG_ARGS,
731 "[rw] %s: \"%s\" -> \"%s\"\n",
732 fdc.ctx, ftmp.bv_val, fstr->bv_val );
736 case REWRITE_REGEXEC_UNWILLING:
738 fdc.rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
739 fdc.rs->sr_text = "Operation not allowed";
741 rc = LDAP_UNWILLING_TO_PERFORM;
744 case REWRITE_REGEXEC_ERR:
746 fdc.rs->sr_err = LDAP_OTHER;
747 fdc.rs->sr_text = "Rewrite error";
753 #endif /* ENABLE_REWRITE */
758 * I don't like this much, but we need two different
759 * functions because different heap managers may be
760 * in use in back-ldap/meta to reduce the amount of
761 * calls to malloc routines, and some of the free()
762 * routines may be macros with args
765 rwm_referral_rewrite(
770 BerVarray *pa_nvals )
772 slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
773 struct ldaprwmap *rwmap =
774 (struct ldaprwmap *)on->on_bi.bi_private;
779 struct berval dn = BER_BVNULL,
785 * Rewrite the dn if needed
788 #ifdef ENABLE_REWRITE
789 dc.conn = op->o_conn;
791 dc.ctx = (char *)cookie;
792 #else /* ! ENABLE_REWRITE */
793 dc.tofrom = ((int *)cookie)[0];
795 #endif /* ! ENABLE_REWRITE */
797 for ( last = 0; !BER_BVISNULL( &a_vals[last] ); last++ )
801 if ( pa_nvals != NULL ) {
802 if ( *pa_nvals == NULL ) {
803 *pa_nvals = ch_malloc( ( last + 2 ) * sizeof(struct berval) );
804 memset( *pa_nvals, 0, ( last + 2 ) * sizeof(struct berval) );
808 for ( i = 0; !BER_BVISNULL( &a_vals[i] ); i++ ) {
809 struct berval olddn, oldval;
814 rc = ldap_url_parse( oldval.bv_val, &ludp );
815 if ( rc != LDAP_URL_SUCCESS ) {
816 /* leave attr untouched if massage failed */
817 if ( pa_nvals && BER_BVISNULL( &(*pa_nvals)[i] ) ) {
818 ber_dupbv( &(*pa_nvals)[i], &oldval );
823 /* FIXME: URLs like "ldap:///dc=suffix" if passed
824 * thru ldap_url_parse() and ldap_url_desc2str()
825 * get rewritten as "ldap:///dc=suffix??base";
826 * we don't want this to occur... */
827 if ( ludp->lud_scope == LDAP_SCOPE_BASE ) {
828 ludp->lud_scope = LDAP_SCOPE_DEFAULT;
831 ber_str2bv( ludp->lud_dn, 0, 0, &olddn );
836 rc = rwm_dn_massage_pretty_normalize( &dc, &olddn,
839 rc = rwm_dn_massage_pretty( &dc, &olddn, &dn );
843 case LDAP_UNWILLING_TO_PERFORM:
845 * FIXME: need to check if it may be considered
846 * legal to trim values when adding/modifying;
847 * it should be when searching (e.g. ACLs).
849 ch_free( a_vals[i].bv_val );
851 a_vals[i] = a_vals[last];
853 (*pa_nvals)[i] = (*pa_nvals)[last];
856 BER_BVZERO( &a_vals[last] );
858 BER_BVZERO( &(*pa_nvals)[last] );
864 if ( !BER_BVISNULL( &dn ) && dn.bv_val != olddn.bv_val ) {
867 ludp->lud_dn = dn.bv_val;
868 newurl = ldap_url_desc2str( ludp );
869 ludp->lud_dn = olddn.bv_val;
870 ch_free( dn.bv_val );
871 if ( newurl == NULL ) {
872 /* FIXME: leave attr untouched
873 * even if ldap_url_desc2str failed...
878 ber_str2bv( newurl, 0, 1, &a_vals[i] );
882 ludp->lud_dn = ndn.bv_val;
883 newurl = ldap_url_desc2str( ludp );
884 ludp->lud_dn = olddn.bv_val;
885 ch_free( ndn.bv_val );
886 if ( newurl == NULL ) {
887 /* FIXME: leave attr untouched
888 * even if ldap_url_desc2str failed...
890 ch_free( a_vals[i].bv_val );
895 if ( !BER_BVISNULL( &(*pa_nvals)[i] ) ) {
896 ch_free( (*pa_nvals)[i].bv_val );
898 ber_str2bv( newurl, 0, 1, &(*pa_nvals)[i] );
902 ch_free( oldval.bv_val );
903 ludp->lud_dn = olddn.bv_val;
908 /* leave attr untouched if massage failed */
909 if ( pa_nvals && BER_BVISNULL( &(*pa_nvals)[i] ) ) {
910 ber_dupbv( &(*pa_nvals)[i], &a_vals[i] );
914 ldap_free_urldesc( ludp );
921 * I don't like this much, but we need two different
922 * functions because different heap managers may be
923 * in use in back-ldap/meta to reduce the amount of
924 * calls to malloc routines, and some of the free()
925 * routines may be macros with args
933 BerVarray *pa_nvals )
935 slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
936 struct ldaprwmap *rwmap =
937 (struct ldaprwmap *)on->on_bi.bi_private;
942 struct berval dn = BER_BVNULL,
950 if ( pa_nvals == NULL || *pa_nvals == NULL ) {
957 * Rewrite the dn if needed
960 #ifdef ENABLE_REWRITE
961 dc.conn = op->o_conn;
963 dc.ctx = (char *)cookie;
964 #else /* ! ENABLE_REWRITE */
965 dc.tofrom = ((int *)cookie)[0];
967 #endif /* ! ENABLE_REWRITE */
969 for ( last = 0; !BER_BVISNULL( &in[last] ); last++ );
971 if ( pa_nvals != NULL ) {
972 if ( *pa_nvals == NULL ) {
973 *pa_nvals = ch_malloc( ( last + 2 ) * sizeof(struct berval) );
974 memset( *pa_nvals, 0, ( last + 2 ) * sizeof(struct berval) );
978 for ( i = 0; !BER_BVISNULL( &in[i] ); i++ ) {
984 ndn = (*pa_nvals)[i];
985 rc = rwm_dn_massage_pretty_normalize( &dc, &in[i], &dn, &ndn );
987 rc = rwm_dn_massage_pretty( &dc, &in[i], &dn );
991 rc = rwm_dn_massage_normalize( &dc, &in[i], &ndn );
995 case LDAP_UNWILLING_TO_PERFORM:
997 * FIXME: need to check if it may be considered
998 * legal to trim values when adding/modifying;
999 * it should be when searching (e.g. ACLs).
1001 ch_free( in[i].bv_val );
1004 if ( a_vals && pa_nvals ) {
1005 (*pa_nvals)[i] = (*pa_nvals)[last];
1008 BER_BVZERO( &in[last] );
1009 if ( a_vals && pa_nvals ) {
1010 BER_BVZERO( &(*pa_nvals)[last] );
1017 if ( !BER_BVISNULL( &dn ) && dn.bv_val != a_vals[i].bv_val ) {
1018 ch_free( a_vals[i].bv_val );
1022 if ( !BER_BVISNULL( &(*pa_nvals)[i] ) ) {
1023 ch_free( (*pa_nvals)[i].bv_val );
1025 (*pa_nvals)[i] = ndn;
1030 if ( !BER_BVISNULL( &ndn ) && ndn.bv_val != (*pa_nvals)[i].bv_val ) {
1031 ch_free( (*pa_nvals)[i].bv_val );
1032 (*pa_nvals)[i] = ndn;
1038 /* leave attr untouched if massage failed */
1039 if ( a_vals && pa_nvals && BER_BVISNULL( &(*pa_nvals)[i] ) ) {
1040 dnNormalize( 0, NULL, NULL, &a_vals[i], &(*pa_nvals)[i], NULL );
1050 rwm_referral_result_rewrite(
1057 for ( last = 0; !BER_BVISNULL( &a_vals[last] ); last++ );
1060 for ( i = 0; !BER_BVISNULL( &a_vals[i] ); i++ ) {
1061 struct berval dn, olddn;
1065 rc = ldap_url_parse( a_vals[i].bv_val, &ludp );
1066 if ( rc != LDAP_URL_SUCCESS ) {
1067 /* leave attr untouched if massage failed */
1071 /* FIXME: URLs like "ldap:///dc=suffix" if passed
1072 * thru ldap_url_parse() and ldap_url_desc2str()
1073 * get rewritten as "ldap:///dc=suffix??base";
1074 * we don't want this to occur... */
1075 if ( ludp->lud_scope == LDAP_SCOPE_BASE ) {
1076 ludp->lud_scope = LDAP_SCOPE_DEFAULT;
1079 ber_str2bv( ludp->lud_dn, 0, 0, &olddn );
1082 rc = rwm_dn_massage_pretty( dc, &olddn, &dn );
1084 case LDAP_UNWILLING_TO_PERFORM:
1086 * FIXME: need to check if it may be considered
1087 * legal to trim values when adding/modifying;
1088 * it should be when searching (e.g. ACLs).
1090 ch_free( a_vals[i].bv_val );
1092 a_vals[i] = a_vals[last];
1094 BER_BVZERO( &a_vals[last] );
1100 /* leave attr untouched if massage failed */
1101 if ( !BER_BVISNULL( &dn ) && olddn.bv_val != dn.bv_val ) {
1104 ludp->lud_dn = dn.bv_val;
1105 newurl = ldap_url_desc2str( ludp );
1106 if ( newurl == NULL ) {
1107 /* FIXME: leave attr untouched
1108 * even if ldap_url_desc2str failed...
1113 ch_free( a_vals[i].bv_val );
1114 ber_str2bv( newurl, 0, 1, &a_vals[i] );
1115 LDAP_FREE( newurl );
1116 ludp->lud_dn = olddn.bv_val;
1121 ldap_free_urldesc( ludp );
1128 rwm_dnattr_result_rewrite(
1135 for ( last = 0; !BER_BVISNULL( &a_vals[last] ); last++ );
1138 for ( i = 0; !BER_BVISNULL( &a_vals[i] ); i++ ) {
1143 rc = rwm_dn_massage_pretty( dc, &a_vals[i], &dn );
1145 case LDAP_UNWILLING_TO_PERFORM:
1147 * FIXME: need to check if it may be considered
1148 * legal to trim values when adding/modifying;
1149 * it should be when searching (e.g. ACLs).
1151 ch_free( a_vals[i].bv_val );
1153 a_vals[i] = a_vals[last];
1155 BER_BVZERO( &a_vals[last] );
1160 /* leave attr untouched if massage failed */
1161 if ( !BER_BVISNULL( &dn ) && a_vals[i].bv_val != dn.bv_val ) {
1162 ch_free( a_vals[i].bv_val );
1173 rwm_mapping_free( void *v_mapping )
1175 struct ldapmapping *mapping = v_mapping;
1177 if ( !BER_BVISNULL( &mapping[0].m_src ) ) {
1178 ch_free( mapping[0].m_src.bv_val );
1181 if ( mapping[0].m_flags & RWMMAP_F_FREE_SRC ) {
1182 if ( mapping[0].m_flags & RWMMAP_F_IS_OC ) {
1183 if ( mapping[0].m_src_oc ) {
1184 ch_free( mapping[0].m_src_oc );
1188 if ( mapping[0].m_src_ad ) {
1189 ch_free( mapping[0].m_src_ad );
1194 if ( !BER_BVISNULL( &mapping[0].m_dst ) ) {
1195 ch_free( mapping[0].m_dst.bv_val );
1198 if ( mapping[0].m_flags & RWMMAP_F_FREE_DST ) {
1199 if ( mapping[0].m_flags & RWMMAP_F_IS_OC ) {
1200 if ( mapping[0].m_dst_oc ) {
1201 ch_free( mapping[0].m_dst_oc );
1205 if ( mapping[0].m_dst_ad ) {
1206 ch_free( mapping[0].m_dst_ad );
1215 #endif /* SLAPD_OVER_RWM */