1 /* rwmmap.c - rewrite/mapping routines */
2 /* $OpenLDAP: pkg/ldap/servers/slapd/overlays/rwmmap.c,v 1.31.2.6 2008/02/11 23:26:49 kurt Exp $ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 1999-2008 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
[0].m_src_ad
, &text
);
86 if ( rc
!= LDAP_SUCCESS
) {
91 mapping
[0].m_dst_ad
= mapping
[0].m_src_ad
;
92 ber_dupbv( &mapping
[0].m_src
, &mapping
[0].m_src_ad
->ad_cname
);
93 ber_dupbv( &mapping
[0].m_dst
, &mapping
[0].m_src
);
95 mapping
[1].m_src
= mapping
[0].m_src
;
96 mapping
[1].m_dst
= mapping
[0].m_dst
;
97 mapping
[1].m_src_ad
= mapping
[0].m_src_ad
;
98 mapping
[1].m_dst_ad
= mapping
[1].m_src_ad
;
100 avl_insert( &lm
->map
, (caddr_t
)&mapping
[0],
101 rwm_mapping_cmp
, rwm_mapping_dup
);
102 avl_insert( &lm
->remap
, (caddr_t
)&mapping
[1],
103 rwm_mapping_cmp
, rwm_mapping_dup
);
111 rwm_mapping( struct ldapmap
*map
, struct berval
*s
, struct ldapmapping
**m
, int remap
)
114 struct ldapmapping fmapping
;
122 if ( remap
== RWM_REMAP
) {
130 *m
= (struct ldapmapping
*)avl_find( tree
, (caddr_t
)&fmapping
,
134 return map
->drop_missing
;
141 rwm_map( struct ldapmap
*map
, struct berval
*s
, struct berval
*bv
, int remap
)
143 struct ldapmapping
*mapping
;
145 /* map->map may be NULL when mapping is configured,
146 * but map->remap can't */
147 if ( map
->remap
== NULL
) {
153 ( void )rwm_mapping( map
, s
, &mapping
, remap
);
154 if ( mapping
!= NULL
) {
155 if ( !BER_BVISNULL( &mapping
->m_dst
) ) {
156 *bv
= mapping
->m_dst
;
161 if ( !map
->drop_missing
) {
167 * Map attribute names in place
171 struct ldapmap
*at_map
,
172 struct ldapmap
*oc_map
,
179 assert( anp
!= NULL
);
187 for ( i
= 0; !BER_BVISNULL( &an
[i
].an_name
); i
++ )
189 *anp
= ch_malloc( ( i
+ 1 )* sizeof( AttributeName
) );
190 if ( *anp
== NULL
) {
191 return LDAP_NO_MEMORY
;
194 for ( i
= 0, j
= 0; !BER_BVISNULL( &an
[i
].an_name
); i
++ ) {
195 struct ldapmapping
*m
;
196 int at_drop_missing
= 0,
199 if ( an
[i
].an_desc
) {
201 /* FIXME: better leave as is? */
205 at_drop_missing
= rwm_mapping( at_map
, &an
[i
].an_name
, &m
, remap
);
206 if ( at_drop_missing
|| ( m
&& BER_BVISNULL( &m
->m_dst
) ) ) {
217 if ( remap
== RWM_MAP
) {
218 (*anp
)[j
].an_name
= m
->m_dst
;
219 (*anp
)[j
].an_desc
= m
->m_dst_ad
;
221 (*anp
)[j
].an_name
= m
->m_src
;
222 (*anp
)[j
].an_desc
= m
->m_src_ad
;
229 } else if ( an
[i
].an_oc
) {
231 /* FIXME: better leave as is? */
235 oc_drop_missing
= rwm_mapping( oc_map
, &an
[i
].an_name
, &m
, remap
);
237 if ( oc_drop_missing
|| ( m
&& BER_BVISNULL( &m
->m_dst
) ) ) {
248 if ( remap
== RWM_MAP
) {
249 (*anp
)[j
].an_name
= m
->m_dst
;
250 (*anp
)[j
].an_oc
= m
->m_dst_oc
;
252 (*anp
)[j
].an_name
= m
->m_src
;
253 (*anp
)[j
].an_oc
= m
->m_src_oc
;
257 at_drop_missing
= rwm_mapping( at_map
, &an
[i
].an_name
, &m
, remap
);
259 if ( at_drop_missing
|| !m
) {
260 oc_drop_missing
= rwm_mapping( oc_map
, &an
[i
].an_name
, &m
, remap
);
262 /* if both at_map and oc_map required to drop missing,
264 if ( oc_drop_missing
&& at_drop_missing
) {
268 /* if no oc_map mapping was found and at_map required
269 * to drop missing, then do it; otherwise, at_map wins
270 * and an is considered an attr and is left unchanged */
272 if ( at_drop_missing
) {
280 if ( BER_BVISNULL( &m
->m_dst
) ) {
285 if ( remap
== RWM_MAP
) {
286 (*anp
)[j
].an_name
= m
->m_dst
;
287 (*anp
)[j
].an_oc
= m
->m_dst_oc
;
289 (*anp
)[j
].an_name
= m
->m_src
;
290 (*anp
)[j
].an_oc
= m
->m_src_oc
;
296 if ( !BER_BVISNULL( &m
->m_dst
) ) {
298 if ( remap
== RWM_MAP
) {
299 (*anp
)[j
].an_name
= m
->m_dst
;
300 (*anp
)[j
].an_desc
= m
->m_dst_ad
;
302 (*anp
)[j
].an_name
= m
->m_src
;
303 (*anp
)[j
].an_desc
= m
->m_src_ad
;
311 if ( j
== 0 && i
!= 0 ) {
312 memset( &(*anp
)[0], 0, sizeof( AttributeName
) );
313 BER_BVSTR( &(*anp
)[0].an_name
, LDAP_NO_ATTRS
);
316 memset( &(*anp
)[j
], 0, sizeof( AttributeName
) );
323 struct ldapmap
*at_map
,
326 char ***mapped_attrs
)
332 *mapped_attrs
= NULL
;
336 for ( i
= 0; !BER_BVISNULL( &an
[ i
].an_name
); i
++ )
339 na
= (char **)ch_calloc( i
+ 1, sizeof( char * ) );
341 *mapped_attrs
= NULL
;
342 return LDAP_NO_MEMORY
;
345 for ( i
= j
= 0; !BER_BVISNULL( &an
[i
].an_name
); i
++ ) {
346 struct ldapmapping
*mapping
;
348 if ( rwm_mapping( at_map
, &an
[i
].an_name
, &mapping
, remap
) ) {
353 na
[ j
++ ] = an
[ i
].an_name
.bv_val
;
355 } else if ( !BER_BVISNULL( &mapping
->m_dst
) ) {
356 na
[ j
++ ] = mapping
->m_dst
.bv_val
;
360 if ( j
== 0 && i
!= 0 ) {
361 na
[ j
++ ] = LDAP_NO_ATTRS
;
374 AttributeDescription
**adp
,
375 struct berval
*mapped_attr
,
376 struct berval
*value
,
377 struct berval
*mapped_value
,
380 struct berval vtmp
= BER_BVNULL
;
382 AttributeDescription
*ad
= *adp
;
383 struct ldapmapping
*mapping
= NULL
;
385 rwm_mapping( &dc
->rwmap
->rwm_at
, &ad
->ad_cname
, &mapping
, remap
);
386 if ( mapping
== NULL
) {
387 if ( dc
->rwmap
->rwm_at
.drop_missing
) {
391 *mapped_attr
= ad
->ad_cname
;
394 *mapped_attr
= mapping
->m_dst
;
397 if ( value
!= NULL
) {
398 assert( mapped_value
!= NULL
);
400 if ( ad
->ad_type
->sat_syntax
== slap_schema
.si_syn_distinguishedName
401 || ( mapping
!= NULL
&& mapping
->m_dst_ad
->ad_type
->sat_syntax
== slap_schema
.si_syn_distinguishedName
) )
406 fdc
.ctx
= "searchFilterAttrDN";
409 rc
= rwm_dn_massage_normalize( &fdc
, value
, &vtmp
);
412 if ( vtmp
.bv_val
!= value
->bv_val
) {
417 case LDAP_UNWILLING_TO_PERFORM
:
423 } else if ( ad
->ad_type
->sat_equality
->smr_usage
& SLAP_MR_MUTATION_NORMALIZER
) {
424 if ( ad
->ad_type
->sat_equality
->smr_normalize(
425 (SLAP_MR_DENORMALIZE
|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX
),
426 NULL
, NULL
, value
, &vtmp
, NULL
) )
432 } else if ( ad
== slap_schema
.si_ad_objectClass
433 || ad
== slap_schema
.si_ad_structuralObjectClass
)
435 rwm_map( &dc
->rwmap
->rwm_oc
, value
, &vtmp
, remap
);
436 if ( BER_BVISNULL( &vtmp
) || BER_BVISEMPTY( &vtmp
) ) {
444 filter_escape_value( &vtmp
, mapped_value
);
447 ch_free( vtmp
.bv_val
);
451 if ( mapping
!= NULL
) {
452 assert( mapping
->m_dst_ad
!= NULL
);
453 *adp
= mapping
->m_dst_ad
;
460 rwm_int_filter_map_rewrite(
464 struct berval
*fstr
)
468 AttributeDescription
*ad
;
473 /* better than nothing... */
474 ber_bvfalse
= BER_BVC( "(!(objectClass=*))" ),
475 ber_bvtf_false
= BER_BVC( "(|)" ),
476 /* better than nothing... */
477 ber_bvtrue
= BER_BVC( "(objectClass=*)" ),
478 ber_bvtf_true
= BER_BVC( "(&)" ),
480 /* no longer needed; preserved for completeness */
481 ber_bvundefined
= BER_BVC( "(?=undefined)" ),
483 ber_bverror
= BER_BVC( "(?=error)" ),
484 ber_bvunknown
= BER_BVC( "(?=unknown)" ),
485 ber_bvnone
= BER_BVC( "(?=none)" );
488 assert( fstr
!= NULL
);
492 ber_dupbv( fstr
, &ber_bvnone
);
496 switch ( f
->f_choice
& SLAPD_FILTER_MASK
) {
497 case LDAP_FILTER_EQUALITY
:
499 if ( map_attr_value( dc
, &ad
, &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_len
? vtmp
.bv_val
: "" );
511 ch_free( vtmp
.bv_val
);
516 if ( map_attr_value( dc
, &ad
, &atmp
,
517 &f
->f_av_value
, &vtmp
, RWM_MAP
) )
522 fstr
->bv_len
= atmp
.bv_len
+ vtmp
.bv_len
+ STRLENOF( "(>=)" );
523 fstr
->bv_val
= ch_malloc( fstr
->bv_len
+ 1 );
525 snprintf( fstr
->bv_val
, fstr
->bv_len
+ 1, "(%s>=%s)",
526 atmp
.bv_val
, vtmp
.bv_len
? vtmp
.bv_val
: "" );
528 ch_free( vtmp
.bv_val
);
533 if ( map_attr_value( dc
, &ad
, &atmp
,
534 &f
->f_av_value
, &vtmp
, RWM_MAP
) )
539 fstr
->bv_len
= atmp
.bv_len
+ vtmp
.bv_len
+ STRLENOF( "(<=)" );
540 fstr
->bv_val
= ch_malloc( fstr
->bv_len
+ 1 );
542 snprintf( fstr
->bv_val
, fstr
->bv_len
+ 1, "(%s<=%s)",
543 atmp
.bv_val
, vtmp
.bv_len
? vtmp
.bv_val
: "" );
545 ch_free( vtmp
.bv_val
);
548 case LDAP_FILTER_APPROX
:
550 if ( map_attr_value( dc
, &ad
, &atmp
,
551 &f
->f_av_value
, &vtmp
, RWM_MAP
) )
556 fstr
->bv_len
= atmp
.bv_len
+ vtmp
.bv_len
+ STRLENOF( "(~=)" );
557 fstr
->bv_val
= ch_malloc( fstr
->bv_len
+ 1 );
559 snprintf( fstr
->bv_val
, fstr
->bv_len
+ 1, "(%s~=%s)",
560 atmp
.bv_val
, vtmp
.bv_len
? vtmp
.bv_val
: "" );
562 ch_free( vtmp
.bv_val
);
565 case LDAP_FILTER_SUBSTRINGS
:
567 if ( map_attr_value( dc
, &ad
, &atmp
,
568 NULL
, NULL
, RWM_MAP
) )
573 /* cannot be a DN ... */
575 fstr
->bv_len
= atmp
.bv_len
+ STRLENOF( "(=*)" );
576 fstr
->bv_val
= ch_malloc( fstr
->bv_len
+ 128 );
578 snprintf( fstr
->bv_val
, fstr
->bv_len
+ 1, "(%s=*)",
581 if ( !BER_BVISNULL( &f
->f_sub_initial
) ) {
584 filter_escape_value( &f
->f_sub_initial
, &vtmp
);
586 fstr
->bv_len
+= vtmp
.bv_len
;
587 fstr
->bv_val
= ch_realloc( fstr
->bv_val
, fstr
->bv_len
+ 1 );
589 snprintf( &fstr
->bv_val
[len
- 2], vtmp
.bv_len
+ 3,
590 /* "(attr=" */ "%s*)",
591 vtmp
.bv_len
? vtmp
.bv_val
: "" );
593 ch_free( vtmp
.bv_val
);
596 if ( f
->f_sub_any
!= NULL
) {
597 for ( i
= 0; !BER_BVISNULL( &f
->f_sub_any
[i
] ); i
++ ) {
599 filter_escape_value( &f
->f_sub_any
[i
], &vtmp
);
601 fstr
->bv_len
+= vtmp
.bv_len
+ 1;
602 fstr
->bv_val
= ch_realloc( fstr
->bv_val
, fstr
->bv_len
+ 1 );
604 snprintf( &fstr
->bv_val
[len
- 1], vtmp
.bv_len
+ 3,
605 /* "(attr=[init]*[any*]" */ "%s*)",
606 vtmp
.bv_len
? vtmp
.bv_val
: "" );
607 ch_free( vtmp
.bv_val
);
611 if ( !BER_BVISNULL( &f
->f_sub_final
) ) {
614 filter_escape_value( &f
->f_sub_final
, &vtmp
);
616 fstr
->bv_len
+= vtmp
.bv_len
;
617 fstr
->bv_val
= ch_realloc( fstr
->bv_val
, fstr
->bv_len
+ 1 );
619 snprintf( &fstr
->bv_val
[len
- 1], vtmp
.bv_len
+ 3,
620 /* "(attr=[init*][any*]" */ "%s)",
621 vtmp
.bv_len
? vtmp
.bv_val
: "" );
623 ch_free( vtmp
.bv_val
);
628 case LDAP_FILTER_PRESENT
:
630 if ( map_attr_value( dc
, &ad
, &atmp
,
631 NULL
, NULL
, RWM_MAP
) )
636 fstr
->bv_len
= atmp
.bv_len
+ STRLENOF( "(=*)" );
637 fstr
->bv_val
= ch_malloc( fstr
->bv_len
+ 1 );
639 snprintf( fstr
->bv_val
, fstr
->bv_len
+ 1, "(%s=*)",
643 case LDAP_FILTER_AND
:
645 case LDAP_FILTER_NOT
:
646 fstr
->bv_len
= STRLENOF( "(%)" );
647 fstr
->bv_val
= ch_malloc( fstr
->bv_len
+ 128 );
649 snprintf( fstr
->bv_val
, fstr
->bv_len
+ 1, "(%c)",
650 f
->f_choice
== LDAP_FILTER_AND
? '&' :
651 f
->f_choice
== LDAP_FILTER_OR
? '|' : '!' );
653 for ( p
= f
->f_list
; p
!= NULL
; p
= p
->f_next
) {
658 rc
= rwm_int_filter_map_rewrite( op
, dc
, p
, &vtmp
);
659 if ( rc
!= LDAP_SUCCESS
) {
663 fstr
->bv_len
+= vtmp
.bv_len
;
664 fstr
->bv_val
= ch_realloc( fstr
->bv_val
, fstr
->bv_len
+ 1 );
666 snprintf( &fstr
->bv_val
[len
-1], vtmp
.bv_len
+ 2,
667 /*"("*/ "%s)", vtmp
.bv_len
? vtmp
.bv_val
: "" );
669 ch_free( vtmp
.bv_val
);
674 case LDAP_FILTER_EXT
: {
675 if ( f
->f_mr_desc
) {
677 if ( map_attr_value( dc
, &ad
, &atmp
,
678 &f
->f_mr_value
, &vtmp
, RWM_MAP
) )
684 BER_BVSTR( &atmp
, "" );
685 filter_escape_value( &f
->f_mr_value
, &vtmp
);
689 fstr
->bv_len
= atmp
.bv_len
+
690 ( f
->f_mr_dnattrs
? STRLENOF( ":dn" ) : 0 ) +
691 ( f
->f_mr_rule_text
.bv_len
? f
->f_mr_rule_text
.bv_len
+ 1 : 0 ) +
692 vtmp
.bv_len
+ STRLENOF( "(:=)" );
693 fstr
->bv_val
= ch_malloc( fstr
->bv_len
+ 1 );
695 snprintf( fstr
->bv_val
, fstr
->bv_len
+ 1, "(%s%s%s%s:=%s)",
697 f
->f_mr_dnattrs
? ":dn" : "",
698 !BER_BVISEMPTY( &f
->f_mr_rule_text
) ? ":" : "",
699 !BER_BVISEMPTY( &f
->f_mr_rule_text
) ? f
->f_mr_rule_text
.bv_val
: "",
700 vtmp
.bv_len
? vtmp
.bv_val
: "" );
701 ch_free( vtmp
.bv_val
);
707 filter_free_x( op
, f
);
708 f
->f_choice
= SLAPD_FILTER_COMPUTED
;
709 f
->f_result
= SLAPD_COMPARE_UNDEFINED
;
712 case SLAPD_FILTER_COMPUTED
:
713 switch ( f
->f_result
) {
714 case LDAP_COMPARE_FALSE
:
715 /* FIXME: treat UNDEFINED as FALSE */
716 case SLAPD_COMPARE_UNDEFINED
:
717 if ( dc
->rwmap
->rwm_flags
& RWM_F_SUPPORT_T_F
) {
718 tmp
= &ber_bvtf_false
;
724 case LDAP_COMPARE_TRUE
:
725 if ( dc
->rwmap
->rwm_flags
& RWM_F_SUPPORT_T_F
) {
726 tmp
= &ber_bvtf_true
;
737 ber_dupbv( fstr
, tmp
);
741 ber_dupbv( fstr
, &ber_bvunknown
);
749 rwm_filter_map_rewrite(
753 struct berval
*fstr
)
759 rc
= rwm_int_filter_map_rewrite( op
, dc
, f
, fstr
);
768 fdc
.ctx
= "searchFilter";
770 switch ( rewrite_session( fdc
.rwmap
->rwm_rw
, fdc
.ctx
,
771 ( !BER_BVISEMPTY( &ftmp
) ? ftmp
.bv_val
: "" ),
772 fdc
.conn
, &fstr
->bv_val
) )
774 case REWRITE_REGEXEC_OK
:
775 if ( !BER_BVISNULL( fstr
) ) {
776 fstr
->bv_len
= strlen( fstr
->bv_val
);
777 if ( fstr
->bv_val
!= ftmp
.bv_val
) {
778 ch_free( ftmp
.bv_val
);
785 Debug( LDAP_DEBUG_ARGS
,
786 "[rw] %s: \"%s\" -> \"%s\"\n",
787 fdc
.ctx
, ftmp
.bv_val
, fstr
->bv_val
);
791 case REWRITE_REGEXEC_UNWILLING
:
793 fdc
.rs
->sr_err
= LDAP_UNWILLING_TO_PERFORM
;
794 fdc
.rs
->sr_text
= "Operation not allowed";
796 rc
= LDAP_UNWILLING_TO_PERFORM
;
799 case REWRITE_REGEXEC_ERR
:
801 fdc
.rs
->sr_err
= LDAP_OTHER
;
802 fdc
.rs
->sr_text
= "Rewrite error";
812 * I don't like this much, but we need two different
813 * functions because different heap managers may be
814 * in use in back-ldap/meta to reduce the amount of
815 * calls to malloc routines, and some of the free()
816 * routines may be macros with args
819 rwm_referral_rewrite(
824 BerVarray
*pa_nvals
)
826 slap_overinst
*on
= (slap_overinst
*) op
->o_bd
->bd_info
;
827 struct ldaprwmap
*rwmap
=
828 (struct ldaprwmap
*)on
->on_bi
.bi_private
;
833 struct berval dn
= BER_BVNULL
,
836 assert( a_vals
!= NULL
);
839 * Rewrite the dn if needed
842 dc
.conn
= op
->o_conn
;
844 dc
.ctx
= (char *)cookie
;
846 for ( last
= 0; !BER_BVISNULL( &a_vals
[last
] ); last
++ )
850 if ( pa_nvals
!= NULL
) {
851 if ( *pa_nvals
== NULL
) {
852 *pa_nvals
= ch_malloc( ( last
+ 2 ) * sizeof(struct berval
) );
853 memset( *pa_nvals
, 0, ( last
+ 2 ) * sizeof(struct berval
) );
857 for ( i
= 0; !BER_BVISNULL( &a_vals
[i
] ); i
++ ) {
858 struct berval olddn
= BER_BVNULL
,
864 rc
= ldap_url_parse( oldval
.bv_val
, &ludp
);
865 if ( rc
!= LDAP_URL_SUCCESS
) {
866 /* leave attr untouched if massage failed */
867 if ( pa_nvals
&& BER_BVISNULL( &(*pa_nvals
)[i
] ) ) {
868 ber_dupbv( &(*pa_nvals
)[i
], &oldval
);
873 /* FIXME: URLs like "ldap:///dc=suffix" if passed
874 * thru ldap_url_parse() and ldap_url_desc2str()
875 * get rewritten as "ldap:///dc=suffix??base";
876 * we don't want this to occur... */
877 if ( ludp
->lud_scope
== LDAP_SCOPE_BASE
) {
878 ludp
->lud_scope
= LDAP_SCOPE_DEFAULT
;
881 ber_str2bv( ludp
->lud_dn
, 0, 0, &olddn
);
886 rc
= rwm_dn_massage_pretty_normalize( &dc
, &olddn
,
889 rc
= rwm_dn_massage_pretty( &dc
, &olddn
, &dn
);
893 case LDAP_UNWILLING_TO_PERFORM
:
895 * FIXME: need to check if it may be considered
896 * legal to trim values when adding/modifying;
897 * it should be when searching (e.g. ACLs).
899 ch_free( a_vals
[i
].bv_val
);
901 a_vals
[i
] = a_vals
[last
];
903 (*pa_nvals
)[i
] = (*pa_nvals
)[last
];
906 BER_BVZERO( &a_vals
[last
] );
908 BER_BVZERO( &(*pa_nvals
)[last
] );
914 if ( !BER_BVISNULL( &dn
) && dn
.bv_val
!= olddn
.bv_val
) {
917 ludp
->lud_dn
= dn
.bv_val
;
918 newurl
= ldap_url_desc2str( ludp
);
919 ludp
->lud_dn
= olddn
.bv_val
;
920 ch_free( dn
.bv_val
);
921 if ( newurl
== NULL
) {
922 /* FIXME: leave attr untouched
923 * even if ldap_url_desc2str failed...
928 ber_str2bv( newurl
, 0, 1, &a_vals
[i
] );
932 ludp
->lud_dn
= ndn
.bv_val
;
933 newurl
= ldap_url_desc2str( ludp
);
934 ludp
->lud_dn
= olddn
.bv_val
;
935 ch_free( ndn
.bv_val
);
936 if ( newurl
== NULL
) {
937 /* FIXME: leave attr untouched
938 * even if ldap_url_desc2str failed...
940 ch_free( a_vals
[i
].bv_val
);
945 if ( !BER_BVISNULL( &(*pa_nvals
)[i
] ) ) {
946 ch_free( (*pa_nvals
)[i
].bv_val
);
948 ber_str2bv( newurl
, 0, 1, &(*pa_nvals
)[i
] );
952 ch_free( oldval
.bv_val
);
953 ludp
->lud_dn
= olddn
.bv_val
;
958 /* leave attr untouched if massage failed */
959 if ( pa_nvals
&& BER_BVISNULL( &(*pa_nvals
)[i
] ) ) {
960 ber_dupbv( &(*pa_nvals
)[i
], &a_vals
[i
] );
964 ldap_free_urldesc( ludp
);
971 * I don't like this much, but we need two different
972 * functions because different heap managers may be
973 * in use in back-ldap/meta to reduce the amount of
974 * calls to malloc routines, and some of the free()
975 * routines may be macros with args
983 BerVarray
*pa_nvals
)
985 slap_overinst
*on
= (slap_overinst
*) op
->o_bd
->bd_info
;
986 struct ldaprwmap
*rwmap
=
987 (struct ldaprwmap
*)on
->on_bi
.bi_private
;
992 struct berval dn
= BER_BVNULL
,
1000 if ( pa_nvals
== NULL
|| *pa_nvals
== NULL
) {
1007 * Rewrite the dn if needed
1010 dc
.conn
= op
->o_conn
;
1012 dc
.ctx
= (char *)cookie
;
1014 for ( last
= 0; !BER_BVISNULL( &in
[last
] ); last
++ );
1016 if ( pa_nvals
!= NULL
) {
1017 if ( *pa_nvals
== NULL
) {
1018 *pa_nvals
= ch_malloc( ( last
+ 2 ) * sizeof(struct berval
) );
1019 memset( *pa_nvals
, 0, ( last
+ 2 ) * sizeof(struct berval
) );
1023 for ( i
= 0; !BER_BVISNULL( &in
[i
] ); i
++ ) {
1029 ndn
= (*pa_nvals
)[i
];
1030 rc
= rwm_dn_massage_pretty_normalize( &dc
, &in
[i
], &dn
, &ndn
);
1032 rc
= rwm_dn_massage_pretty( &dc
, &in
[i
], &dn
);
1036 rc
= rwm_dn_massage_normalize( &dc
, &in
[i
], &ndn
);
1040 case LDAP_UNWILLING_TO_PERFORM
:
1042 * FIXME: need to check if it may be considered
1043 * legal to trim values when adding/modifying;
1044 * it should be when searching (e.g. ACLs).
1046 ch_free( in
[i
].bv_val
);
1049 if ( a_vals
&& pa_nvals
) {
1050 (*pa_nvals
)[i
] = (*pa_nvals
)[last
];
1053 BER_BVZERO( &in
[last
] );
1054 if ( a_vals
&& pa_nvals
) {
1055 BER_BVZERO( &(*pa_nvals
)[last
] );
1062 if ( !BER_BVISNULL( &dn
) && dn
.bv_val
!= a_vals
[i
].bv_val
) {
1063 ch_free( a_vals
[i
].bv_val
);
1067 if ( !BER_BVISNULL( &(*pa_nvals
)[i
] ) ) {
1068 ch_free( (*pa_nvals
)[i
].bv_val
);
1070 (*pa_nvals
)[i
] = ndn
;
1075 if ( !BER_BVISNULL( &ndn
) && ndn
.bv_val
!= (*pa_nvals
)[i
].bv_val
) {
1076 ch_free( (*pa_nvals
)[i
].bv_val
);
1077 (*pa_nvals
)[i
] = ndn
;
1083 /* leave attr untouched if massage failed */
1084 if ( a_vals
&& pa_nvals
&& BER_BVISNULL( &(*pa_nvals
)[i
] ) ) {
1085 dnNormalize( 0, NULL
, NULL
, &a_vals
[i
], &(*pa_nvals
)[i
], NULL
);
1095 rwm_referral_result_rewrite(
1101 for ( last
= 0; !BER_BVISNULL( &a_vals
[last
] ); last
++ );
1104 for ( i
= 0; !BER_BVISNULL( &a_vals
[i
] ); i
++ ) {
1110 rc
= ldap_url_parse( a_vals
[i
].bv_val
, &ludp
);
1111 if ( rc
!= LDAP_URL_SUCCESS
) {
1112 /* leave attr untouched if massage failed */
1116 /* FIXME: URLs like "ldap:///dc=suffix" if passed
1117 * thru ldap_url_parse() and ldap_url_desc2str()
1118 * get rewritten as "ldap:///dc=suffix??base";
1119 * we don't want this to occur... */
1120 if ( ludp
->lud_scope
== LDAP_SCOPE_BASE
) {
1121 ludp
->lud_scope
= LDAP_SCOPE_DEFAULT
;
1124 ber_str2bv( ludp
->lud_dn
, 0, 0, &olddn
);
1127 rc
= rwm_dn_massage_pretty( dc
, &olddn
, &dn
);
1129 case LDAP_UNWILLING_TO_PERFORM
:
1131 * FIXME: need to check if it may be considered
1132 * legal to trim values when adding/modifying;
1133 * it should be when searching (e.g. ACLs).
1135 ch_free( a_vals
[i
].bv_val
);
1137 a_vals
[i
] = a_vals
[last
];
1139 BER_BVZERO( &a_vals
[last
] );
1145 /* leave attr untouched if massage failed */
1146 if ( !BER_BVISNULL( &dn
) && olddn
.bv_val
!= dn
.bv_val
) {
1149 ludp
->lud_dn
= dn
.bv_val
;
1150 newurl
= ldap_url_desc2str( ludp
);
1151 if ( newurl
== NULL
) {
1152 /* FIXME: leave attr untouched
1153 * even if ldap_url_desc2str failed...
1158 ch_free( a_vals
[i
].bv_val
);
1159 ber_str2bv( newurl
, 0, 1, &a_vals
[i
] );
1160 LDAP_FREE( newurl
);
1161 ludp
->lud_dn
= olddn
.bv_val
;
1166 ldap_free_urldesc( ludp
);
1173 rwm_dnattr_result_rewrite(
1179 for ( last
= 0; !BER_BVISNULL( &a_vals
[last
] ); last
++ );
1182 for ( i
= 0; !BER_BVISNULL( &a_vals
[i
] ); i
++ ) {
1187 rc
= rwm_dn_massage_pretty( dc
, &a_vals
[i
], &dn
);
1189 case LDAP_UNWILLING_TO_PERFORM
:
1191 * FIXME: need to check if it may be considered
1192 * legal to trim values when adding/modifying;
1193 * it should be when searching (e.g. ACLs).
1195 ch_free( a_vals
[i
].bv_val
);
1197 a_vals
[i
] = a_vals
[last
];
1199 BER_BVZERO( &a_vals
[last
] );
1204 /* leave attr untouched if massage failed */
1205 if ( !BER_BVISNULL( &dn
) && a_vals
[i
].bv_val
!= dn
.bv_val
) {
1206 ch_free( a_vals
[i
].bv_val
);
1217 rwm_mapping_dst_free( void *v_mapping
)
1219 struct ldapmapping
*mapping
= v_mapping
;
1221 if ( BER_BVISEMPTY( &mapping
[0].m_dst
) ) {
1222 rwm_mapping_free( &mapping
[ -1 ] );
1227 rwm_mapping_free( void *v_mapping
)
1229 struct ldapmapping
*mapping
= v_mapping
;
1231 if ( !BER_BVISNULL( &mapping
[0].m_src
) ) {
1232 ch_free( mapping
[0].m_src
.bv_val
);
1235 if ( mapping
[0].m_flags
& RWMMAP_F_FREE_SRC
) {
1236 if ( mapping
[0].m_flags
& RWMMAP_F_IS_OC
) {
1237 if ( mapping
[0].m_src_oc
) {
1238 ch_free( mapping
[0].m_src_oc
);
1242 if ( mapping
[0].m_src_ad
) {
1243 ch_free( mapping
[0].m_src_ad
);
1248 if ( !BER_BVISNULL( &mapping
[0].m_dst
) ) {
1249 ch_free( mapping
[0].m_dst
.bv_val
);
1252 if ( mapping
[0].m_flags
& RWMMAP_F_FREE_DST
) {
1253 if ( mapping
[0].m_flags
& RWMMAP_F_IS_OC
) {
1254 if ( mapping
[0].m_dst_oc
) {
1255 ch_free( mapping
[0].m_dst_oc
);
1259 if ( mapping
[0].m_dst_ad
) {
1260 ch_free( mapping
[0].m_dst_ad
);
1269 #endif /* SLAPD_OVER_RWM */