1 /* rwm.c - rewrite/remap operations */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 2003-2004 The OpenLDAP Foundation.
6 * Portions Copyright 2003 Pierangelo Masarati.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted only as authorized by the OpenLDAP
13 * A copy of this license is available in the file LICENSE in the
14 * top-level directory of the distribution or, alternatively, at
15 * <http://www.OpenLDAP.org/license.html>.
28 rwm_op_dn_massage( Operation *op, SlapReply *rs, void *cookie )
30 slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
31 struct ldaprwmap *rwmap =
32 (struct ldaprwmap *)on->on_bi.bi_private;
34 struct berval dn = BER_BVNULL,
40 * Rewrite the bind dn if needed
46 dc.ctx = (char *)cookie;
48 dc.tofrom = ((int *)cookie)[0];
52 rc = rwm_dn_massage( &dc, &op->o_req_dn, &dn, &ndn );
53 if ( rc != LDAP_SUCCESS ) {
57 if ( dn.bv_val == op->o_req_dn.bv_val ) {
61 op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx );
62 op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx );
71 rwm_add( Operation *op, SlapReply *rs )
73 slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
74 struct ldaprwmap *rwmap =
75 (struct ldaprwmap *)on->on_bi.bi_private;
80 Attribute **ap = NULL;
83 rc = rwm_op_dn_massage( op, rs, "addDn" );
86 rc = rwm_op_dn_massage( op, rs, &rc );
88 if ( rc != LDAP_SUCCESS ) {
89 op->o_bd->bd_info = (BackendInfo *)on->on_info;
90 send_ldap_error( op, rs, rc, "addDn massage error" );
94 /* Count number of attributes in entry */
95 isupdate = be_shadow_update( op );
96 for ( i = 0, ap = &op->oq_add.rs_e->e_attrs; *ap; ) {
100 if ( !isupdate && (*ap)->a_desc->ad_type->sat_no_user_mod ) {
104 rwm_map( &rwmap->rwm_at, &(*ap)->a_desc->ad_cname,
106 if ( BER_BVISNULL( &mapped ) || BER_BVISEMPTY( &mapped ) ) {
110 if ( (*ap)->a_desc->ad_type->sat_syntax
111 == slap_schema.si_syn_distinguishedName )
114 * FIXME: rewrite could fail; in this case
115 * the operation should give up, right?
117 #ifdef ENABLE_REWRITE
118 rc = rwm_dnattr_rewrite( op, rs, "addDn", (*ap)->a_vals, NULL );
121 rc = rwm_dnattr_rewrite( op, rs, &rc, (*ap)->a_vals, NULL );
132 /* FIXME: leaking attribute/values? */
139 /* TODO: map attribute types, values of DN-valued attributes ... */
140 return SLAP_CB_CONTINUE;
144 rwm_bind( Operation *op, SlapReply *rs )
146 slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
147 struct ldaprwmap *rwmap =
148 (struct ldaprwmap *)on->on_bi.bi_private;
151 #ifdef ENABLE_REWRITE
152 ( void )rewrite_session_delete( rwmap->rwm_rw, op->o_conn );
153 ( void )rewrite_session_init( rwmap->rwm_rw, op->o_conn );
155 rc = rwm_op_dn_massage( op, rs, "bindDn" );
158 rc = rwm_op_dn_massage( op, rs, &rc );
160 if ( rc != LDAP_SUCCESS ) {
161 op->o_bd->bd_info = (BackendInfo *)on->on_info;
162 send_ldap_error( op, rs, rc, "bindDn massage error" );
166 return SLAP_CB_CONTINUE;
170 rwm_unbind( Operation *op, SlapReply *rs )
172 slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
173 struct ldaprwmap *rwmap =
174 (struct ldaprwmap *)on->on_bi.bi_private;
176 #ifdef ENABLE_REWRITE
177 rewrite_session_delete( rwmap->rwm_rw, op->o_conn );
180 return SLAP_CB_CONTINUE;
184 rwm_compare( Operation *op, SlapReply *rs )
186 slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
187 struct ldaprwmap *rwmap =
188 (struct ldaprwmap *)on->on_bi.bi_private;
191 struct berval mapped_at = BER_BVNULL,
192 mapped_vals[2] = { BER_BVNULL, BER_BVNULL };
194 #ifdef ENABLE_REWRITE
195 rc = rwm_op_dn_massage( op, rs, "compareDn" );
198 rc = rwm_op_dn_massage( op, rs, &rc );
200 if ( rc != LDAP_SUCCESS ) {
201 op->o_bd->bd_info = (BackendInfo *)on->on_info;
202 send_ldap_error( op, rs, rc, "compareDn massage error" );
206 /* if the attribute is an objectClass, try to remap its value */
207 if ( op->orc_ava->aa_desc == slap_schema.si_ad_objectClass
208 || op->orc_ava->aa_desc == slap_schema.si_ad_structuralObjectClass )
210 rwm_map( &rwmap->rwm_oc, &op->orc_ava->aa_value,
211 &mapped_vals[0], RWM_MAP );
212 if ( BER_BVISNULL( &mapped_vals[0] ) || BER_BVISEMPTY( &mapped_vals[0] ) )
214 op->o_bd->bd_info = (BackendInfo *)on->on_info;
215 send_ldap_error( op, rs, LDAP_OTHER, "compare objectClass map error" );
218 } else if ( mapped_vals[0].bv_val != op->orc_ava->aa_value.bv_val ) {
219 free( op->orc_ava->aa_value.bv_val );
220 op->orc_ava->aa_value = mapped_vals[0];
222 mapped_at = op->orc_ava->aa_desc->ad_cname;
225 rwm_map( &rwmap->rwm_at, &op->orc_ava->aa_desc->ad_cname,
226 &mapped_at, RWM_MAP );
227 if ( BER_BVISNULL( &mapped_at ) || BER_BVISEMPTY( &mapped_at ) )
229 op->o_bd->bd_info = (BackendInfo *)on->on_info;
230 send_ldap_error( op, rs, LDAP_OTHER, "compare attributeType map error" );
233 if ( op->orc_ava->aa_desc->ad_type->sat_syntax == slap_schema.si_syn_distinguishedName )
235 mapped_vals[0] = op->orc_ava->aa_value;
237 #ifdef ENABLE_REWRITE
238 rc = rwm_dnattr_rewrite( op, rs, "compareAttrDN", mapped_vals, NULL );
241 rc = rwm_dnattr_rewrite( op, rs, &rc, mapped_vals, NULL );
244 if ( rc != LDAP_SUCCESS ) {
245 op->o_bd->bd_info = (BackendInfo *)on->on_info;
246 send_ldap_error( op, rs, rc, "compareAttrDN massage error" );
250 if ( mapped_vals[0].bv_val != op->orc_ava->aa_value.bv_val ) {
251 free( op->orc_ava->aa_value.bv_val );
252 op->orc_ava->aa_value = mapped_vals[0];
257 return SLAP_CB_CONTINUE;
261 rwm_delete( Operation *op, SlapReply *rs )
263 slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
266 #ifdef ENABLE_REWRITE
267 rc = rwm_op_dn_massage( op, rs, "deleteDn" );
270 rc = rwm_op_dn_massage( op, rs, &rc );
272 if ( rc != LDAP_SUCCESS ) {
273 op->o_bd->bd_info = (BackendInfo *)on->on_info;
274 send_ldap_error( op, rs, rc, "deleteDn massage error" );
278 return SLAP_CB_CONTINUE;
282 rwm_modify( Operation *op, SlapReply *rs )
284 slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
285 struct ldaprwmap *rwmap =
286 (struct ldaprwmap *)on->on_bi.bi_private;
292 #ifdef ENABLE_REWRITE
293 rc = rwm_op_dn_massage( op, rs, "modifyDn" );
296 rc = rwm_op_dn_massage( op, rs, &rc );
298 if ( rc != LDAP_SUCCESS ) {
299 op->o_bd->bd_info = (BackendInfo *)on->on_info;
300 send_ldap_error( op, rs, rc, "modifyDn massage error" );
304 isupdate = be_shadow_update( op );
305 for ( mlp = &op->oq_modify.rs_modlist; *mlp; ) {
308 if ( !isupdate && (*mlp)->sml_desc->ad_type->sat_no_user_mod ) {
312 *mlp = (*mlp)->sml_next;
313 slap_mod_free( &ml->sml_mod, 0 );
319 if ( (*mlp)->sml_desc == slap_schema.si_ad_objectClass
320 || (*mlp)->sml_desc == slap_schema.si_ad_structuralObjectClass ) {
324 struct ldapmapping *m;
327 drop_missing = rwm_mapping( &rwmap->rwm_at, &(*mlp)->sml_desc->ad_cname, &m, RWM_MAP );
328 if ( drop_missing || ( m != NULL && BER_BVISNULL( &m->m_dst ) ) )
333 *mlp = (*mlp)->sml_next;
334 slap_mod_free( &ml->sml_mod, 0 );
341 /* use new attribute description */
342 assert( m->m_dst_ad );
343 (*mlp)->sml_desc = m->m_dst_ad;
347 if ( (*mlp)->sml_values != NULL ) {
351 for ( last = 0; !BER_BVISNULL( &(*mlp)->sml_values[last] ); last++ )
355 for ( j = 0; !BER_BVISNULL( &(*mlp)->sml_values[j] ); j++ ) {
356 struct berval mapped = BER_BVNULL;
358 rwm_map( &rwmap->rwm_oc,
359 &(*mlp)->sml_values[j],
361 if ( BER_BVISNULL( &mapped ) || BER_BVISEMPTY( &mapped ) ) {
362 /* FIXME: we allow to remove objectClasses as well;
363 * if the resulting entry is inconsistent, that's
364 * the relayed database's business...
370 *mlp = (*mlp)->sml_next;
371 slap_mod_free( &ml->sml_mod, 0 );
377 (*mlp)->sml_values[j] = (*mlp)->sml_values[last];
378 BER_BVZERO( &(*mlp)->sml_values[last] );
383 ch_free( (*mlp)->sml_values[j].bv_val );
384 ber_dupbv( &(*mlp)->sml_values[j], &mapped );
389 if ( (*mlp)->sml_desc->ad_type->sat_syntax ==
390 slap_schema.si_syn_distinguishedName )
392 #ifdef ENABLE_REWRITE
393 rc = rwm_dnattr_rewrite( op, rs, "modifyDn",
394 (*mlp)->sml_values, &(*mlp)->sml_nvalues );
397 rc = rwm_dnattr_rewrite( op, rs, &rc,
398 (*mlp)->sml_values, &(*mlp)->sml_nvalues );
402 if ( rc != LDAP_SUCCESS ) {
406 *mlp = (*mlp)->sml_next;
407 slap_mod_free( &ml->sml_mod, 0 );
415 mlp = &(*mlp)->sml_next;
418 /* TODO: rewrite attribute types, values of DN-valued attributes ... */
419 return SLAP_CB_CONTINUE;
423 rwm_modrdn( Operation *op, SlapReply *rs )
425 slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
428 #ifdef ENABLE_REWRITE
429 rc = rwm_op_dn_massage( op, rs, "renameDn" );
432 rc = rwm_op_dn_massage( op, rs, &rc );
434 if ( rc != LDAP_SUCCESS ) {
435 op->o_bd->bd_info = (BackendInfo *)on->on_info;
436 send_ldap_error( op, rs, rc, "renameDn massage error" );
440 /* TODO: rewrite attribute types, values of DN-valued attributes ... */
441 return SLAP_CB_CONTINUE;
445 rwm_swap_attrs( Operation *op, SlapReply *rs )
447 slap_callback *cb = op->o_callback;
448 AttributeName *an = (AttributeName *)cb->sc_private;
452 return SLAP_CB_CONTINUE;
456 rwm_search( Operation *op, SlapReply *rs )
458 slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
459 struct ldaprwmap *rwmap =
460 (struct ldaprwmap *)on->on_bi.bi_private;
465 struct berval fstr = BER_BVNULL;
469 AttributeName *an = NULL;
473 #ifdef ENABLE_REWRITE
474 rc = rwm_op_dn_massage( op, rs, "searchDn" );
477 rc = rwm_op_dn_massage( op, rs, &rc );
479 if ( rc != LDAP_SUCCESS ) {
480 text = "searchDn massage error";
485 * Rewrite the bind dn if needed
488 #ifdef ENABLE_REWRITE
489 dc.conn = op->o_conn;
491 dc.ctx = "searchFilterAttrDN";
497 rc = rwm_filter_map_rewrite( &dc, op->ors_filter, &fstr );
498 if ( rc != LDAP_SUCCESS ) {
499 text = "searchFilter/searchFilterAttrDN massage error";
503 f = str2filter_x( op, fstr.bv_val );
506 text = "massaged filter parse error";
510 if ( !BER_BVISNULL( &op->ors_filterstr ) ) {
511 ch_free( op->ors_filterstr.bv_val );
514 if( op->ors_filter ) {
515 filter_free_x( op, op->ors_filter );
519 op->ors_filterstr = fstr;
521 rc = rwm_map_attrnames( &rwmap->rwm_at, &rwmap->rwm_oc,
522 op->ors_attrs, &an, RWM_MAP );
523 if ( rc != LDAP_SUCCESS ) {
524 text = "attribute list mapping error";
528 cb = (slap_callback *)ch_malloc( sizeof( slap_callback ) );
534 cb->sc_response = rwm_swap_attrs;
535 cb->sc_cleanup = NULL;
536 cb->sc_private = (void *)op->ors_attrs;
537 cb->sc_next = op->o_callback;
542 /* TODO: rewrite/map filter & attrs */
543 return SLAP_CB_CONTINUE;
551 filter_free_x( op, f );
554 if ( !BER_BVISNULL( &fstr ) ) {
555 ch_free( fstr.bv_val );
558 op->o_bd->bd_info = (BackendInfo *)on->on_info;
559 send_ldap_error( op, rs, rc, text );
566 rwm_extended( Operation *op, SlapReply *rs )
568 slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
571 #ifdef ENABLE_REWRITE
572 rc = rwm_op_dn_massage( op, rs, "extendedDn" );
575 rc = rwm_op_dn_massage( op, rs, &rc );
577 if ( rc != LDAP_SUCCESS ) {
578 op->o_bd->bd_info = (BackendInfo *)on->on_info;
579 send_ldap_error( op, rs, rc, "extendedDn massage error" );
583 /* TODO: rewrite/map extended data ? ... */
588 rwm_matched( Operation *op, SlapReply *rs )
590 slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
591 struct ldaprwmap *rwmap =
592 (struct ldaprwmap *)on->on_bi.bi_private;
594 struct berval dn, mdn;
598 if ( rs->sr_matched == NULL ) {
599 return SLAP_CB_CONTINUE;
603 #ifdef ENABLE_REWRITE
604 dc.conn = op->o_conn;
606 dc.ctx = "matchedDN";
611 ber_str2bv( rs->sr_matched, 0, 0, &dn );
612 rc = rwm_dn_massage( &dc, &dn, &mdn, NULL );
613 if ( rc != LDAP_SUCCESS ) {
615 rs->sr_text = "Rewrite error";
619 if ( mdn.bv_val != dn.bv_val ) {
620 if ( rs->sr_flags & REP_MATCHED_MUSTBEFREED ) {
621 ch_free( (void *)rs->sr_matched );
624 rs->sr_flags |= REP_MATCHED_MUSTBEFREED;
626 rs->sr_matched = mdn.bv_val;
629 return SLAP_CB_CONTINUE;
633 rwm_send_entry( Operation *op, SlapReply *rs )
635 slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
636 struct ldaprwmap *rwmap =
637 (struct ldaprwmap *)on->on_bi.bi_private;
640 struct berval dn = BER_BVNULL,
646 assert( rs->sr_entry );
651 * Rewrite the dn of the result, if needed
654 #ifdef ENABLE_REWRITE
655 dc.conn = op->o_conn;
657 dc.ctx = "searchResult";
663 if ( !( rs->sr_flags & REP_ENTRY_MODIFIABLE ) ) {
664 /* FIXME: all we need to duplicate are:
667 * - attributes that are requested
668 * - no values if attrsonly is set
677 rs->sr_flags |= ( REP_ENTRY_MODIFIABLE | REP_ENTRY_MUSTBEFREED );
681 * Note: this may fail if the target host(s) schema differs
682 * from the one known to the meta, and a DN with unknown
683 * attributes is returned.
685 rc = rwm_dn_massage( &dc, &e->e_name, &dn, &ndn );
686 if ( rc != LDAP_SUCCESS ) {
690 if ( e->e_name.bv_val != dn.bv_val ) {
691 free( e->e_name.bv_val );
692 free( e->e_nname.bv_val );
698 /* TODO: map entry attribute types, objectclasses
699 * and dn-valued attribute values */
701 /* FIXME: the entries are in the remote mapping form;
702 * so we need to select those attributes we are willing
703 * to return, and remap them accordingly */
705 for ( ap = &e->e_attrs; *ap; ) {
706 struct ldapmapping *m;
710 if ( op->ors_attrs != NULL && !ad_inlist( (*ap)->a_desc, op->ors_attrs ) ) {
720 drop_missing = rwm_mapping( &rwmap->rwm_at,
721 &(*ap)->a_desc->ad_cname, &m, RWM_REMAP );
722 if ( drop_missing || ( m != NULL && BER_BVISEMPTY( &m->m_dst ) ) ) {
732 /* no subschemaSubentry */
733 if ( (*ap)->a_desc == slap_schema.si_ad_subschemaSubentry ) {
736 * We eat target's subschemaSubentry because
737 * a search for this value is likely not
738 * to resolve to the appropriate backend;
739 * later, the local subschemaSubentry is
751 for ( last = 0; !BER_BVISNULL( &(*ap)->a_vals[last] ); last++ )
755 /* empty? for now, we leave it in place */
760 if ( (*ap)->a_desc == slap_schema.si_ad_objectClass
761 || (*ap)->a_desc == slap_schema.si_ad_structuralObjectClass )
765 for ( bv = (*ap)->a_vals; !BER_BVISNULL( bv ); bv++ ) {
766 struct berval mapped;
768 rwm_map( &rwmap->rwm_oc, &bv[0], &mapped, RWM_REMAP );
769 if ( BER_BVISNULL( &mapped ) || BER_BVISEMPTY( &mapped ) ) {
770 ch_free( bv[0].bv_val );
771 BER_BVZERO( &bv[0] );
772 if ( &(*ap)->a_vals[last] > &bv[0] ) {
773 bv[0] = (*ap)->a_vals[last];
774 BER_BVZERO( &(*ap)->a_vals[last] );
779 } else if ( mapped.bv_val != bv[0].bv_val ) {
781 * FIXME: after LBER_FREEing
782 * the value is replaced by
785 free( bv[0].bv_val );
786 ber_dupbv( &bv[0], &mapped );
791 * It is necessary to try to rewrite attributes with
792 * dn syntax because they might be used in ACLs as
793 * members of groups; since ACLs are applied to the
794 * rewritten stuff, no dn-based subject clause could
795 * be used at the ldap backend side (see
796 * http://www.OpenLDAP.org/faq/data/cache/452.html)
797 * The problem can be overcome by moving the dn-based
798 * ACLs to the target directory server, and letting
799 * everything pass thru the ldap backend.
801 } else if ( (*ap)->a_desc->ad_type->sat_syntax ==
802 slap_schema.si_syn_distinguishedName )
804 rc = rwm_dnattr_result_rewrite( &dc, (*ap)->a_vals );
805 if ( rc != LDAP_SUCCESS ) {
817 /* rewrite the attribute description */
818 assert( m->m_dst_ad );
819 (*ap)->a_desc = m->m_dst_ad;
829 return SLAP_CB_CONTINUE;
832 if ( !BER_BVISNULL( &dn ) ) {
833 ch_free( dn.bv_val );
836 if ( !BER_BVISNULL( &ndn ) ) {
837 ch_free( ndn.bv_val );
840 if ( e != NULL && e != rs->sr_entry ) {
856 #ifdef ENABLE_REWRITE
857 slap_overinst *on = (slap_overinst *) be->bd_info;
858 struct ldaprwmap *rwmap =
859 (struct ldaprwmap *)on->on_bi.bi_private;
861 return rewrite_parse( rwmap->rwm_rw,
862 fname, lineno, argc, argv );
864 #else /* !ENABLE_REWRITE */
865 fprintf( stderr, "%s: line %d: rewrite capabilities "
866 "are not enabled\n", fname, lineno );
867 #endif /* !ENABLE_REWRITE */
873 rwm_suffixmassage_config(
881 slap_overinst *on = (slap_overinst *) be->bd_info;
882 struct ldaprwmap *rwmap =
883 (struct ldaprwmap *)on->on_bi.bi_private;
885 struct berval bvnc, nvnc, pvnc, brnc, nrnc, prnc;
886 #ifdef ENABLE_REWRITE
888 #endif /* ENABLE_REWRITE */
893 * suffixmassage <suffix> <massaged suffix>
895 * the <suffix> field must be defined as a valid suffix
896 * (or suffixAlias?) for the current database;
897 * the <massaged suffix> shouldn't have already been
898 * defined as a valid suffix or suffixAlias for the
902 fprintf( stderr, "%s: line %d: syntax is"
903 " \"suffixMassage <suffix>"
904 " <massaged suffix>\"\n",
909 ber_str2bv( argv[1], 0, 0, &bvnc );
910 if ( dnPrettyNormal( NULL, &bvnc, &pvnc, &nvnc, NULL ) != LDAP_SUCCESS ) {
911 fprintf( stderr, "%s: line %d: suffix DN %s is invalid\n",
912 fname, lineno, bvnc.bv_val );
916 ber_str2bv( argv[2], 0, 0, &brnc );
917 if ( dnPrettyNormal( NULL, &brnc, &prnc, &nrnc, NULL ) != LDAP_SUCCESS ) {
918 fprintf( stderr, "%s: line %d: suffix DN %s is invalid\n",
919 fname, lineno, brnc.bv_val );
925 #ifdef ENABLE_REWRITE
927 * The suffix massaging is emulated
928 * by means of the rewrite capabilities
930 rc = rwm_suffix_massage_config( rwmap->rwm_rw,
931 &pvnc, &nvnc, &prnc, &nrnc );
939 #else /* !ENABLE_REWRITE */
940 ber_bvarray_add( &rwmap->rwm_suffix_massage, &pvnc );
941 ber_bvarray_add( &rwmap->rwm_suffix_massage, &nvnc );
943 ber_bvarray_add( &rwmap->rwm_suffix_massage, &prnc );
944 ber_bvarray_add( &rwmap->rwm_suffix_massage, &nrnc );
945 #endif /* !ENABLE_REWRITE */
959 slap_overinst *on = (slap_overinst *) be->bd_info;
960 struct ldaprwmap *rwmap =
961 (struct ldaprwmap *)on->on_bi.bi_private;
963 /* objectclass/attribute mapping */
964 return rwm_map_config( &rwmap->rwm_oc,
966 fname, lineno, argc, argv );
970 rwm_response( Operation *op, SlapReply *rs )
974 if ( op->o_tag == LDAP_REQ_SEARCH && rs->sr_type == REP_SEARCH ) {
975 return rwm_send_entry( op, rs );
978 switch( op->o_tag ) {
979 case LDAP_REQ_SEARCH:
980 /* Note: the operation attrs are remapped */
981 if ( op->ors_attrs != NULL && op->ors_attrs != rs->sr_attrs )
983 ch_free( op->ors_attrs );
984 op->ors_attrs = rs->sr_attrs;
990 case LDAP_REQ_DELETE:
991 case LDAP_REQ_MODRDN:
992 case LDAP_REQ_MODIFY:
993 case LDAP_REQ_COMPARE:
994 case LDAP_REQ_EXTENDED:
995 rc = rwm_matched( op, rs );
999 rc = SLAP_CB_CONTINUE;
1018 if ( strncasecmp( argv[ 0 ], "rwm-", STRLENOF( "rwm-" ) ) == 0 ) {
1020 argv[ 0 ] = &argv0[ STRLENOF( "rwm-" ) ];
1023 if ( strncasecmp( argv[0], "rewrite", STRLENOF("rewrite") ) == 0 ) {
1024 rc = rwm_rw_config( be, fname, lineno, argc, argv );
1026 } else if ( strcasecmp( argv[0], "map" ) == 0 ) {
1027 rc = rwm_m_config( be, fname, lineno, argc, argv );
1029 } else if ( strcasecmp( argv[0], "suffixmassage" ) == 0 ) {
1030 rc = rwm_suffixmassage_config( be, fname, lineno, argc, argv );
1033 rc = SLAP_CONF_UNKNOWN;
1048 slap_overinst *on = (slap_overinst *) be->bd_info;
1049 struct ldapmapping *mapping = NULL;
1050 struct ldaprwmap *rwmap;
1052 rwmap = (struct ldaprwmap *)ch_malloc(sizeof(struct ldaprwmap));
1053 memset(rwmap, 0, sizeof(struct ldaprwmap));
1055 #ifdef ENABLE_REWRITE
1056 rwmap->rwm_rw = rewrite_info_init( REWRITE_MODE_USE_DEFAULT );
1057 if ( rwmap->rwm_rw == NULL ) {
1065 /* this rewriteContext by default must be null;
1066 * rules can be added if required */
1067 rargv[ 0 ] = "rewriteContext";
1068 rargv[ 1 ] = "searchFilter";
1070 rewrite_parse( rwmap->rwm_rw, "<suffix massage>", 1, 2, rargv );
1072 rargv[ 0 ] = "rewriteContext";
1073 rargv[ 1 ] = "default";
1075 rewrite_parse( rwmap->rwm_rw, "<suffix massage>", 2, 2, rargv );
1078 #endif /* ENABLE_REWRITE */
1080 if ( rwm_map_init( &rwmap->rwm_oc, &mapping ) != LDAP_SUCCESS ||
1081 rwm_map_init( &rwmap->rwm_at, &mapping ) != LDAP_SUCCESS )
1086 on->on_bi.bi_private = (void *)rwmap;
1096 slap_overinst *on = (slap_overinst *) be->bd_info;
1099 if ( on->on_bi.bi_private ) {
1100 struct ldaprwmap *rwmap =
1101 (struct ldaprwmap *)on->on_bi.bi_private;
1103 #ifdef ENABLE_REWRITE
1104 if (rwmap->rwm_rw) {
1105 rewrite_info_delete( &rwmap->rwm_rw );
1107 #else /* !ENABLE_REWRITE */
1108 if ( rwmap->rwm_suffix_massage ) {
1109 ber_bvarray_free( rwmap->rwm_suffix_massage );
1111 #endif /* !ENABLE_REWRITE */
1113 avl_free( rwmap->rwm_oc.remap, NULL );
1114 avl_free( rwmap->rwm_oc.map, rwm_mapping_free );
1115 avl_free( rwmap->rwm_at.remap, NULL );
1116 avl_free( rwmap->rwm_at.map, rwm_mapping_free );
1122 static slap_overinst rwm = { { NULL } };
1127 memset( &rwm, 0, sizeof(slap_overinst) );
1129 rwm.on_bi.bi_type = "rwm";
1130 rwm.on_bi.bi_db_init = rwm_over_init;
1131 rwm.on_bi.bi_db_config = rwm_config;
1132 rwm.on_bi.bi_db_destroy = rwm_destroy;
1134 rwm.on_bi.bi_op_bind = rwm_bind;
1135 rwm.on_bi.bi_op_search = rwm_search;
1136 rwm.on_bi.bi_op_compare = rwm_compare;
1137 rwm.on_bi.bi_op_modify = rwm_modify;
1138 rwm.on_bi.bi_op_modrdn = rwm_modrdn;
1139 rwm.on_bi.bi_op_add = rwm_add;
1140 rwm.on_bi.bi_op_delete = rwm_delete;
1141 rwm.on_bi.bi_op_unbind = rwm_unbind;
1142 rwm.on_bi.bi_extended = rwm_extended;
1144 rwm.on_response = rwm_response;
1146 return overlay_register( &rwm );
1149 #if SLAPD_OVER_RWM == SLAPD_MOD_DYNAMIC
1150 int init_module(int argc, char *argv[]) {
1155 #endif /* SLAPD_OVER_RWM */