1 /* rwm.c - rewrite/remap operations */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 2003-2006 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>.
24 #include <ac/string.h>
29 typedef struct rwm_op_state {
38 rwm_db_destroy( BackendDB *be );
40 typedef struct rwm_op_cb {
46 rwm_op_cleanup( Operation *op, SlapReply *rs )
48 slap_callback *cb = op->o_callback;
49 rwm_op_state *ros = cb->sc_private;
51 if ( rs->sr_type == REP_RESULT || op->o_abandon ||
52 rs->sr_err == SLAPD_ABANDON ) {
54 op->o_req_dn = ros->ro_dn;
55 op->o_req_ndn = ros->ro_ndn;
57 if ( !BER_BVISEMPTY( &ros->r_dn )) ch_free( ros->r_dn.bv_val );
58 if ( !BER_BVISEMPTY( &ros->r_ndn )) ch_free( ros->r_ndn.bv_val );
61 case LDAP_REQ_COMPARE:
62 if ( op->orc_ava->aa_value.bv_val != ros->orc_ava->aa_value.bv_val )
63 op->o_tmpfree( op->orc_ava->aa_value.bv_val, op->o_tmpmemctx );
64 op->orc_ava = ros->orc_ava;
67 slap_mods_free( op->orm_modlist, 1 );
68 op->orm_modlist = ros->orm_modlist;
71 if ( op->orr_newSup != ros->orr_newSup ) {
72 ch_free( op->orr_newSup->bv_val );
73 ch_free( op->orr_nnewSup->bv_val );
74 op->o_tmpfree( op->orr_newSup, op->o_tmpmemctx );
75 op->o_tmpfree( op->orr_nnewSup, op->o_tmpmemctx );
76 op->orr_newSup = ros->orr_newSup;
77 op->orr_nnewSup = ros->orr_nnewSup;
81 ch_free( op->ors_attrs );
82 filter_free_x( op, op->ors_filter );
83 ch_free( op->ors_filterstr.bv_val );
84 op->ors_attrs = ros->ors_attrs;
85 op->ors_filter = ros->ors_filter;
86 op->ors_filterstr = ros->ors_filterstr;
88 case LDAP_REQ_EXTENDED:
89 if ( op->ore_reqdata != ros->ore_reqdata ) {
90 ber_bvfree( op->ore_reqdata );
91 op->ore_reqdata = ros->ore_reqdata;
96 op->o_callback = op->o_callback->sc_next;
97 op->o_tmpfree( cb, op->o_tmpmemctx );
100 return SLAP_CB_CONTINUE;
104 rwm_callback_get( Operation *op, SlapReply *rs )
106 rwm_op_cb *roc = NULL;
108 roc = op->o_tmpalloc( sizeof( struct rwm_op_cb ), op->o_tmpmemctx );
109 roc->cb.sc_cleanup = rwm_op_cleanup;
110 roc->cb.sc_response = NULL;
111 roc->cb.sc_next = op->o_callback;
112 roc->cb.sc_private = &roc->ros;
113 roc->ros.ro_dn = op->o_req_dn;
114 roc->ros.ro_ndn = op->o_req_ndn;
115 roc->ros.o_request = op->o_request;
116 BER_BVZERO( &roc->ros.r_dn );
117 BER_BVZERO( &roc->ros.r_ndn );
124 rwm_op_dn_massage( Operation *op, SlapReply *rs, void *cookie,
127 slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
128 struct ldaprwmap *rwmap =
129 (struct ldaprwmap *)on->on_bi.bi_private;
131 struct berval dn = BER_BVNULL,
137 * Rewrite the dn if needed
140 #ifdef ENABLE_REWRITE
141 dc.conn = op->o_conn;
143 dc.ctx = (char *)cookie;
144 #else /* ! ENABLE_REWRITE */
145 dc.tofrom = ((int *)cookie)[0];
147 #endif /* ! ENABLE_REWRITE */
149 /* NOTE: in those cases where only the ndn is available,
150 * and the caller sets op->o_req_dn = op->o_req_ndn,
151 * only rewrite the op->o_req_ndn and use it as
152 * op->o_req_dn as well */
154 if ( op->o_req_dn.bv_val != op->o_req_ndn.bv_val ) {
156 rc = rwm_dn_massage_pretty_normalize( &dc, &op->o_req_dn, &dn, &ndn );
158 rc = rwm_dn_massage_normalize( &dc, &op->o_req_ndn, &ndn );
161 if ( rc != LDAP_SUCCESS ) {
165 if ( ( op->o_req_dn.bv_val != op->o_req_ndn.bv_val && dn.bv_val == op->o_req_dn.bv_val )
166 || ndn.bv_val == op->o_req_ndn.bv_val )
171 if ( op->o_req_dn.bv_val != op->o_req_ndn.bv_val ) {
184 rwm_op_add( 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;
192 Attribute **ap = NULL;
193 char *olddn = op->o_req_dn.bv_val;
196 rwm_op_cb *roc = rwm_callback_get( op, rs );
198 #ifdef ENABLE_REWRITE
199 rc = rwm_op_dn_massage( op, rs, "addDN", &roc->ros );
200 #else /* ! ENABLE_REWRITE */
202 rc = rwm_op_dn_massage( op, rs, &rc, &roc->ros );
203 #endif /* ! ENABLE_REWRITE */
204 if ( rc != LDAP_SUCCESS ) {
205 op->o_bd->bd_info = (BackendInfo *)on->on_info;
206 send_ldap_error( op, rs, rc, "addDN massage error" );
210 if ( olddn != op->o_req_dn.bv_val ) {
211 ber_bvreplace( &op->ora_e->e_name, &op->o_req_dn );
212 ber_bvreplace( &op->ora_e->e_nname, &op->o_req_ndn );
215 /* Count number of attributes in entry */
216 isupdate = be_shadow_update( op );
217 for ( i = 0, ap = &op->oq_add.rs_e->e_attrs; *ap; ) {
220 if ( (*ap)->a_desc == slap_schema.si_ad_objectClass ||
221 (*ap)->a_desc == slap_schema.si_ad_structuralObjectClass )
225 for ( last = 0; !BER_BVISNULL( &(*ap)->a_vals[ last ] ); last++ )
228 for ( j = 0; !BER_BVISNULL( &(*ap)->a_vals[ j ] ); j++ ) {
229 struct ldapmapping *mapping = NULL;
231 ( void )rwm_mapping( &rwmap->rwm_oc, &(*ap)->a_vals[ j ],
233 if ( mapping == NULL ) {
234 if ( rwmap->rwm_at.drop_missing ) {
235 /* FIXME: we allow to remove objectClasses as well;
236 * if the resulting entry is inconsistent, that's
237 * the relayed database's business...
239 ch_free( (*ap)->a_vals[ j ].bv_val );
241 (*ap)->a_vals[ j ] = (*ap)->a_vals[ last ];
243 BER_BVZERO( &(*ap)->a_vals[ last ] );
249 ch_free( (*ap)->a_vals[ j ].bv_val );
250 ber_dupbv( &(*ap)->a_vals[ j ], &mapping->m_dst );
254 } else if ( !isupdate && !get_relax( op ) && (*ap)->a_desc->ad_type->sat_no_user_mod )
259 struct ldapmapping *mapping = NULL;
261 ( void )rwm_mapping( &rwmap->rwm_at, &(*ap)->a_desc->ad_cname,
263 if ( mapping == NULL ) {
264 if ( rwmap->rwm_at.drop_missing ) {
269 if ( (*ap)->a_desc->ad_type->sat_syntax == slap_schema.si_syn_distinguishedName
270 || ( mapping != NULL && mapping->m_dst_ad->ad_type->sat_syntax == slap_schema.si_syn_distinguishedName ) )
273 * FIXME: rewrite could fail; in this case
274 * the operation should give up, right?
276 #ifdef ENABLE_REWRITE
277 rc = rwm_dnattr_rewrite( op, rs, "addAttrDN",
279 (*ap)->a_nvals ? &(*ap)->a_nvals : NULL );
280 #else /* ! ENABLE_REWRITE */
282 rc = rwm_dnattr_rewrite( op, rs, &rc, (*ap)->a_vals,
283 (*ap)->a_nvals ? &(*ap)->a_nvals : NULL );
284 #endif /* ! ENABLE_REWRITE */
289 } else if ( (*ap)->a_desc == slap_schema.si_ad_ref ) {
290 #ifdef ENABLE_REWRITE
291 rc = rwm_referral_rewrite( op, rs, "referralAttrDN",
293 (*ap)->a_nvals ? &(*ap)->a_nvals : NULL );
294 #else /* ! ENABLE_REWRITE */
296 rc = rwm_referral_rewrite( op, rs, &rc, (*ap)->a_vals,
297 (*ap)->a_nvals ? &(*ap)->a_nvals : NULL );
298 #endif /* ! ENABLE_REWRITE */
299 if ( rc != LDAP_SUCCESS ) {
304 if ( mapping != NULL ) {
305 assert( mapping->m_dst_ad != NULL );
306 (*ap)->a_desc = mapping->m_dst_ad;
315 /* FIXME: leaking attribute/values? */
322 op->o_callback = &roc->cb;
324 return SLAP_CB_CONTINUE;
327 #ifdef ENABLE_REWRITE
329 rwm_conn_init( BackendDB *be, Connection *conn )
331 slap_overinst *on = (slap_overinst *) be->bd_info;
332 struct ldaprwmap *rwmap =
333 (struct ldaprwmap *)on->on_bi.bi_private;
335 ( void )rewrite_session_init( rwmap->rwm_rw, conn );
337 return SLAP_CB_CONTINUE;
341 rwm_conn_destroy( BackendDB *be, Connection *conn )
343 slap_overinst *on = (slap_overinst *) be->bd_info;
344 struct ldaprwmap *rwmap =
345 (struct ldaprwmap *)on->on_bi.bi_private;
347 ( void )rewrite_session_delete( rwmap->rwm_rw, conn );
349 return SLAP_CB_CONTINUE;
351 #endif /* ENABLE_REWRITE */
354 rwm_op_bind( Operation *op, SlapReply *rs )
356 slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
359 rwm_op_cb *roc = rwm_callback_get( op, rs );
361 #ifdef ENABLE_REWRITE
362 rc = rwm_op_dn_massage( op, rs, "bindDN", &roc->ros );
363 #else /* ! ENABLE_REWRITE */
365 rc = rwm_op_dn_massage( op, rs, &rc, &roc->ros );
366 #endif /* ! ENABLE_REWRITE */
367 if ( rc != LDAP_SUCCESS ) {
368 op->o_bd->bd_info = (BackendInfo *)on->on_info;
369 send_ldap_error( op, rs, rc, "bindDN massage error" );
373 op->o_callback = &roc->cb;
375 return SLAP_CB_CONTINUE;
379 rwm_op_unbind( Operation *op, SlapReply *rs )
381 slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
382 struct ldaprwmap *rwmap =
383 (struct ldaprwmap *)on->on_bi.bi_private;
385 #ifdef ENABLE_REWRITE
386 rewrite_session_delete( rwmap->rwm_rw, op->o_conn );
387 #endif /* ENABLE_REWRITE */
389 return SLAP_CB_CONTINUE;
393 rwm_op_compare( Operation *op, SlapReply *rs )
395 slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
396 struct ldaprwmap *rwmap =
397 (struct ldaprwmap *)on->on_bi.bi_private;
400 struct berval mapped_vals[2] = { BER_BVNULL, BER_BVNULL };
402 rwm_op_cb *roc = rwm_callback_get( op, rs );
404 #ifdef ENABLE_REWRITE
405 rc = rwm_op_dn_massage( op, rs, "compareDN", &roc->ros );
406 #else /* ! ENABLE_REWRITE */
408 rc = rwm_op_dn_massage( op, rs, &rc, &roc->ros );
409 #endif /* ! ENABLE_REWRITE */
410 if ( rc != LDAP_SUCCESS ) {
411 op->o_bd->bd_info = (BackendInfo *)on->on_info;
412 send_ldap_error( op, rs, rc, "compareDN massage error" );
416 /* if the attribute is an objectClass, try to remap its value */
417 if ( op->orc_ava->aa_desc == slap_schema.si_ad_objectClass
418 || op->orc_ava->aa_desc == slap_schema.si_ad_structuralObjectClass )
420 rwm_map( &rwmap->rwm_oc, &op->orc_ava->aa_value,
421 &mapped_vals[0], RWM_MAP );
422 if ( BER_BVISNULL( &mapped_vals[0] ) || BER_BVISEMPTY( &mapped_vals[0] ) )
424 op->o_bd->bd_info = (BackendInfo *)on->on_info;
425 send_ldap_error( op, rs, LDAP_OTHER, "compare objectClass map error" );
428 } else if ( mapped_vals[0].bv_val != op->orc_ava->aa_value.bv_val ) {
429 ber_dupbv_x( &op->orc_ava->aa_value, &mapped_vals[0],
434 struct ldapmapping *mapping = NULL;
435 AttributeDescription *ad = op->orc_ava->aa_desc;
437 ( void )rwm_mapping( &rwmap->rwm_at, &op->orc_ava->aa_desc->ad_cname,
439 if ( mapping == NULL ) {
440 if ( rwmap->rwm_at.drop_missing ) {
441 op->o_bd->bd_info = (BackendInfo *)on->on_info;
442 send_ldap_error( op, rs, LDAP_OTHER, "compare attributeType map error" );
447 assert( mapping->m_dst_ad != NULL );
448 ad = mapping->m_dst_ad;
451 if ( op->orc_ava->aa_desc->ad_type->sat_syntax == slap_schema.si_syn_distinguishedName
452 || ( mapping != NULL && mapping->m_dst_ad->ad_type->sat_syntax == slap_schema.si_syn_distinguishedName ) )
454 struct berval *mapped_valsp[2];
456 mapped_valsp[0] = &mapped_vals[0];
457 mapped_valsp[1] = &mapped_vals[1];
459 mapped_vals[0] = op->orc_ava->aa_value;
461 #ifdef ENABLE_REWRITE
462 rc = rwm_dnattr_rewrite( op, rs, "compareAttrDN", NULL, mapped_valsp );
463 #else /* ! ENABLE_REWRITE */
465 rc = rwm_dnattr_rewrite( op, rs, &rc, NULL, mapped_valsp );
466 #endif /* ! ENABLE_REWRITE */
468 if ( rc != LDAP_SUCCESS ) {
469 op->o_bd->bd_info = (BackendInfo *)on->on_info;
470 send_ldap_error( op, rs, rc, "compareAttrDN massage error" );
474 if ( mapped_vals[ 0 ].bv_val != op->orc_ava->aa_value.bv_val ) {
475 /* NOTE: if we get here, rwm_dnattr_rewrite()
476 * already freed the old value, so now
478 ber_dupbv_x( &op->orc_ava->aa_value, &mapped_vals[0],
480 ber_memfree_x( mapped_vals[ 0 ].bv_val, NULL );
483 op->orc_ava->aa_desc = ad;
486 op->o_callback = &roc->cb;
488 return SLAP_CB_CONTINUE;
492 rwm_op_delete( Operation *op, SlapReply *rs )
494 slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
497 rwm_op_cb *roc = rwm_callback_get( op, rs );
499 #ifdef ENABLE_REWRITE
500 rc = rwm_op_dn_massage( op, rs, "deleteDN", &roc->ros );
501 #else /* ! ENABLE_REWRITE */
503 rc = rwm_op_dn_massage( op, rs, &rc, &roc->ros );
504 #endif /* ! ENABLE_REWRITE */
505 if ( rc != LDAP_SUCCESS ) {
506 op->o_bd->bd_info = (BackendInfo *)on->on_info;
507 send_ldap_error( op, rs, rc, "deleteDN massage error" );
511 op->o_callback = &roc->cb;
513 return SLAP_CB_CONTINUE;
517 rwm_op_modify( Operation *op, SlapReply *rs )
519 slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
520 struct ldaprwmap *rwmap =
521 (struct ldaprwmap *)on->on_bi.bi_private;
527 rwm_op_cb *roc = rwm_callback_get( op, rs );
529 #ifdef ENABLE_REWRITE
530 rc = rwm_op_dn_massage( op, rs, "modifyDN", &roc->ros );
531 #else /* ! ENABLE_REWRITE */
533 rc = rwm_op_dn_massage( op, rs, &rc, &roc->ros );
534 #endif /* ! ENABLE_REWRITE */
535 if ( rc != LDAP_SUCCESS ) {
536 op->o_bd->bd_info = (BackendInfo *)on->on_info;
537 send_ldap_error( op, rs, rc, "modifyDN massage error" );
541 isupdate = be_shadow_update( op );
542 for ( mlp = &op->oq_modify.rs_modlist; *mlp; ) {
545 struct ldapmapping *mapping = NULL;
547 /* duplicate the modlist */
548 ml = ch_malloc( sizeof( Modifications ));
552 if ( ml->sml_desc == slap_schema.si_ad_objectClass
553 || ml->sml_desc == slap_schema.si_ad_structuralObjectClass )
557 } else if ( !isupdate && !get_relax( op ) && ml->sml_desc->ad_type->sat_no_user_mod )
564 drop_missing = rwm_mapping( &rwmap->rwm_at,
565 &ml->sml_desc->ad_cname,
567 if ( drop_missing || ( mapping != NULL && BER_BVISNULL( &mapping->m_dst ) ) )
573 if ( ml->sml_values != NULL ) {
577 for ( num = 0; !BER_BVISNULL( &ml->sml_values[ num ] ); num++ )
580 bva = ch_malloc( (num+1) * sizeof( struct berval ));
581 for (i=0; i<num; i++)
582 ber_dupbv( &bva[i], &ml->sml_values[i] );
583 BER_BVZERO( &bva[i] );
584 ml->sml_values = bva;
586 if ( ml->sml_nvalues ) {
587 bva = ch_malloc( (num+1) * sizeof( struct berval ));
588 for (i=0; i<num; i++)
589 ber_dupbv( &bva[i], &ml->sml_nvalues[i] );
590 BER_BVZERO( &bva[i] );
591 ml->sml_nvalues = bva;
599 for ( j = 0; !BER_BVISNULL( &ml->sml_values[ j ] ); j++ ) {
600 struct ldapmapping *oc_mapping = NULL;
602 ( void )rwm_mapping( &rwmap->rwm_oc, &ml->sml_values[ j ],
603 &oc_mapping, RWM_MAP );
604 if ( oc_mapping == NULL ) {
605 if ( rwmap->rwm_at.drop_missing ) {
606 /* FIXME: we allow to remove objectClasses as well;
607 * if the resulting entry is inconsistent, that's
608 * the relayed database's business...
611 ch_free( ml->sml_values[ j ].bv_val );
612 ml->sml_values[ j ] = ml->sml_values[ last ];
614 BER_BVZERO( &ml->sml_values[ last ] );
620 ch_free( ml->sml_values[ j ].bv_val );
621 ber_dupbv( &ml->sml_values[ j ], &oc_mapping->m_dst );
626 if ( ml->sml_desc->ad_type->sat_syntax == slap_schema.si_syn_distinguishedName
627 || ( mapping != NULL && mapping->m_dst_ad->ad_type->sat_syntax == slap_schema.si_syn_distinguishedName ) )
629 #ifdef ENABLE_REWRITE
630 rc = rwm_dnattr_rewrite( op, rs, "modifyAttrDN",
632 ml->sml_nvalues ? &ml->sml_nvalues : NULL );
633 #else /* ! ENABLE_REWRITE */
635 rc = rwm_dnattr_rewrite( op, rs, &rc,
637 ml->sml_nvalues ? &ml->sml_nvalues : NULL );
638 #endif /* ! ENABLE_REWRITE */
640 } else if ( ml->sml_desc == slap_schema.si_ad_ref ) {
641 #ifdef ENABLE_REWRITE
642 rc = rwm_referral_rewrite( op, rs,
645 ml->sml_nvalues ? &ml->sml_nvalues : NULL );
646 #else /* ! ENABLE_REWRITE */
648 rc = rwm_referral_rewrite( op, rs, &rc,
650 ml->sml_nvalues ? &ml->sml_nvalues : NULL );
651 #endif /* ! ENABLE_REWRITE */
652 if ( rc != LDAP_SUCCESS ) {
657 if ( rc != LDAP_SUCCESS ) {
664 if ( mapping != NULL ) {
665 /* use new attribute description */
666 assert( mapping->m_dst_ad != NULL );
667 ml->sml_desc = mapping->m_dst_ad;
675 *mlp = (*mlp)->sml_next;
676 slap_mod_free( &ml->sml_mod, 0 );
680 op->o_callback = &roc->cb;
682 return SLAP_CB_CONTINUE;
686 rwm_op_modrdn( Operation *op, SlapReply *rs )
688 slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
689 struct ldaprwmap *rwmap =
690 (struct ldaprwmap *)on->on_bi.bi_private;
694 rwm_op_cb *roc = rwm_callback_get( op, rs );
696 if ( op->orr_newSup ) {
698 struct berval nnewSup = BER_BVNULL;
699 struct berval newSup = BER_BVNULL;
702 * Rewrite the new superior, if defined and required
705 #ifdef ENABLE_REWRITE
706 dc.conn = op->o_conn;
708 dc.ctx = "newSuperiorDN";
709 #else /* ! ENABLE_REWRITE */
712 #endif /* ! ENABLE_REWRITE */
713 newSup = *op->orr_newSup;
714 nnewSup = *op->orr_nnewSup;
715 rc = rwm_dn_massage_pretty_normalize( &dc, op->orr_newSup, &newSup, &nnewSup );
716 if ( rc != LDAP_SUCCESS ) {
717 op->o_bd->bd_info = (BackendInfo *)on->on_info;
718 send_ldap_error( op, rs, rc, "newSuperiorDN massage error" );
722 if ( op->orr_newSup->bv_val != newSup.bv_val ) {
723 op->orr_newSup = op->o_tmpalloc( sizeof( struct berval ),
725 op->orr_nnewSup = op->o_tmpalloc( sizeof( struct berval ),
727 *op->orr_newSup = newSup;
728 *op->orr_nnewSup = nnewSup;
733 * Rewrite the dn, if needed
735 #ifdef ENABLE_REWRITE
736 rc = rwm_op_dn_massage( op, rs, "renameDN", &roc->ros );
737 #else /* ! ENABLE_REWRITE */
739 rc = rwm_op_dn_massage( op, rs, &rc, &roc->ros );
740 #endif /* ! ENABLE_REWRITE */
741 if ( rc != LDAP_SUCCESS ) {
742 op->o_bd->bd_info = (BackendInfo *)on->on_info;
743 send_ldap_error( op, rs, rc, "renameDN massage error" );
744 if ( op->orr_newSup != roc->ros.orr_newSup ) {
745 ch_free( op->orr_newSup->bv_val );
746 ch_free( op->orr_nnewSup->bv_val );
747 op->o_tmpfree( op->orr_newSup, op->o_tmpmemctx );
748 op->o_tmpfree( op->orr_nnewSup, op->o_tmpmemctx );
749 op->orr_newSup = roc->ros.orr_newSup;
750 op->orr_nnewSup = roc->ros.orr_nnewSup;
755 /* TODO: rewrite newRDN, attribute types,
756 * values of DN-valued attributes ... */
758 op->o_callback = &roc->cb;
760 return SLAP_CB_CONTINUE;
765 rwm_swap_attrs( Operation *op, SlapReply *rs )
767 slap_callback *cb = op->o_callback;
768 rwm_op_state *ros = cb->sc_private;
770 rs->sr_attrs = ros->ors_attrs;
772 return SLAP_CB_CONTINUE;
776 rwm_op_search( Operation *op, SlapReply *rs )
778 slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
779 struct ldaprwmap *rwmap =
780 (struct ldaprwmap *)on->on_bi.bi_private;
785 struct berval fstr = BER_BVNULL;
788 AttributeName *an = NULL;
792 rwm_op_cb *roc = rwm_callback_get( op, rs );
794 #ifdef ENABLE_REWRITE
795 rc = rewrite_session_var_set( rwmap->rwm_rw, op->o_conn,
796 "searchFilter", op->ors_filterstr.bv_val );
797 if ( rc == LDAP_SUCCESS )
798 rc = rwm_op_dn_massage( op, rs, "searchDN", &roc->ros );
799 #else /* ! ENABLE_REWRITE */
801 rc = rwm_op_dn_massage( op, rs, &rc, &roc->ros );
802 #endif /* ! ENABLE_REWRITE */
803 if ( rc != LDAP_SUCCESS ) {
804 text = "searchDN massage error";
809 * Rewrite the dn if needed
812 #ifdef ENABLE_REWRITE
813 dc.conn = op->o_conn;
815 dc.ctx = "searchFilterAttrDN";
816 #else /* ! ENABLE_REWRITE */
819 #endif /* ! ENABLE_REWRITE */
821 rc = rwm_filter_map_rewrite( op, &dc, op->ors_filter, &fstr );
822 if ( rc != LDAP_SUCCESS ) {
823 text = "searchFilter/searchFilterAttrDN massage error";
827 f = str2filter_x( op, fstr.bv_val );
830 text = "massaged filter parse error";
835 op->ors_filterstr = fstr;
837 rc = rwm_map_attrnames( &rwmap->rwm_at, &rwmap->rwm_oc,
838 op->ors_attrs, &an, RWM_MAP );
839 if ( rc != LDAP_SUCCESS ) {
840 text = "attribute list mapping error";
845 roc->cb.sc_response = rwm_swap_attrs;
847 op->o_callback = &roc->cb;
849 return SLAP_CB_CONTINUE;
857 filter_free_x( op, f );
860 if ( !BER_BVISNULL( &fstr ) ) {
861 ch_free( fstr.bv_val );
864 op->oq_search = roc->ros.oq_search;
866 op->o_bd->bd_info = (BackendInfo *)on->on_info;
867 send_ldap_error( op, rs, rc, text );
874 rwm_exop_passwd( Operation *op, SlapReply *rs )
876 slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
880 struct berval id = BER_BVNULL,
883 BerElement *ber = NULL;
885 if ( !BER_BVISNULL( &op->o_req_ndn ) ) {
889 if ( !SLAP_ISGLOBALOVERLAY( op->o_bd ) ) {
890 rs->sr_err = LDAP_OTHER;
894 rs->sr_err = slap_passwd_parse( op->ore_reqdata, &id,
895 &pwold, &pwnew, &rs->sr_text );
896 if ( rs->sr_err != LDAP_SUCCESS ) {
900 if ( !BER_BVISNULL( &id ) ) {
901 rs->sr_err = dnPrettyNormal( NULL, &id, &op->o_req_dn,
902 &op->o_req_ndn, op->o_tmpmemctx );
903 if ( rs->sr_err != LDAP_SUCCESS ) {
904 rs->sr_text = "Invalid DN";
909 ber_dupbv_x( &op->o_req_dn, &op->o_dn, op->o_tmpmemctx );
910 ber_dupbv_x( &op->o_req_ndn, &op->o_ndn, op->o_tmpmemctx );
913 roc = rwm_callback_get( op, rs );
915 #ifdef ENABLE_REWRITE
916 rc = rwm_op_dn_massage( op, rs, "extendedDN", &roc->ros );
917 #else /* ! ENABLE_REWRITE */
919 rc = rwm_op_dn_massage( op, rs, &rc, &roc->ros );
920 #endif /* ! ENABLE_REWRITE */
921 if ( rc != LDAP_SUCCESS ) {
922 op->o_bd->bd_info = (BackendInfo *)on->on_info;
923 send_ldap_error( op, rs, rc, "extendedDN massage error" );
927 ber = ber_alloc_t( LBER_USE_DER );
929 rs->sr_err = LDAP_OTHER;
930 rs->sr_text = "No memory";
933 ber_printf( ber, "{" );
934 if ( !BER_BVISNULL( &id )) {
935 ber_printf( ber, "tO", LDAP_TAG_EXOP_MODIFY_PASSWD_ID,
938 if ( !BER_BVISNULL( &pwold )) {
939 ber_printf( ber, "tO", LDAP_TAG_EXOP_MODIFY_PASSWD_OLD, &pwold );
941 if ( !BER_BVISNULL( &pwnew )) {
942 ber_printf( ber, "tO", LDAP_TAG_EXOP_MODIFY_PASSWD_NEW, &pwnew );
944 ber_printf( ber, "N}" );
945 ber_flatten( ber, &op->ore_reqdata );
948 op->o_callback = &roc->cb;
950 return SLAP_CB_CONTINUE;
955 BI_op_extended *extended;
957 { BER_BVC(LDAP_EXOP_MODIFY_PASSWD), rwm_exop_passwd },
962 rwm_extended( Operation *op, SlapReply *rs )
964 slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
970 for ( i = 0; exop_table[i].extended != NULL; i++ ) {
971 if ( bvmatch( &exop_table[i].oid, &op->oq_extended.rs_reqoid ) )
973 rc = exop_table[i].extended( op, rs );
978 case SLAP_CB_CONTINUE:
983 send_ldap_result( op, rs );
990 roc = rwm_callback_get( op, rs );
992 #ifdef ENABLE_REWRITE
993 rc = rwm_op_dn_massage( op, rs, "extendedDN", &roc->ros );
994 #else /* ! ENABLE_REWRITE */
996 rc = rwm_op_dn_massage( op, rs, &rc, &roc->ros );
997 #endif /* ! ENABLE_REWRITE */
998 if ( rc != LDAP_SUCCESS ) {
999 op->o_bd->bd_info = (BackendInfo *)on->on_info;
1000 send_ldap_error( op, rs, rc, "extendedDN massage error" );
1004 /* TODO: rewrite/map extended data ? ... */
1005 op->o_callback = &roc->cb;
1007 return SLAP_CB_CONTINUE;
1011 rwm_matched( Operation *op, SlapReply *rs )
1013 slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
1014 struct ldaprwmap *rwmap =
1015 (struct ldaprwmap *)on->on_bi.bi_private;
1017 struct berval dn, mdn;
1021 if ( rs->sr_matched == NULL ) {
1022 return SLAP_CB_CONTINUE;
1026 #ifdef ENABLE_REWRITE
1027 dc.conn = op->o_conn;
1029 dc.ctx = "matchedDN";
1030 #else /* ! ENABLE_REWRITE */
1033 #endif /* ! ENABLE_REWRITE */
1034 ber_str2bv( rs->sr_matched, 0, 0, &dn );
1036 rc = rwm_dn_massage_pretty( &dc, &dn, &mdn );
1037 if ( rc != LDAP_SUCCESS ) {
1039 rs->sr_text = "Rewrite error";
1043 if ( mdn.bv_val != dn.bv_val ) {
1044 if ( rs->sr_flags & REP_MATCHED_MUSTBEFREED ) {
1045 ch_free( (void *)rs->sr_matched );
1048 rs->sr_flags |= REP_MATCHED_MUSTBEFREED;
1050 rs->sr_matched = mdn.bv_val;
1053 return SLAP_CB_CONTINUE;
1057 rwm_attrs( Operation *op, SlapReply *rs, Attribute** a_first, int stripEntryDN )
1059 slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
1060 struct ldaprwmap *rwmap =
1061 (struct ldaprwmap *)on->on_bi.bi_private;
1069 * Rewrite the dn attrs, if needed
1072 #ifdef ENABLE_REWRITE
1073 dc.conn = op->o_conn;
1075 #else /* ! ENABLE_REWRITE */
1078 #endif /* ! ENABLE_REWRITE */
1080 /* FIXME: the entries are in the remote mapping form;
1081 * so we need to select those attributes we are willing
1082 * to return, and remap them accordingly */
1084 /* FIXME: in principle, one could map an attribute
1085 * on top of another, which already exists.
1086 * As such, in the end there might exist more than
1087 * one instance of an attribute.
1088 * We should at least check if this occurs, and issue
1089 * an error (because multiple instances of attrs in
1090 * response are not valid), or merge the values (what
1091 * about duplicate values?) */
1092 isupdate = be_shadow_update( op );
1093 for ( ap = a_first; *ap; ) {
1094 struct ldapmapping *mapping = NULL;
1099 if ( SLAP_OPATTRS( rs->sr_attr_flags ) && is_at_operational( (*ap)->a_desc->ad_type ) )
1104 if ( op->ors_attrs != NULL &&
1105 !SLAP_USERATTRS( rs->sr_attr_flags ) &&
1106 !ad_inlist( (*ap)->a_desc, op->ors_attrs ) )
1111 drop_missing = rwm_mapping( &rwmap->rwm_at,
1112 &(*ap)->a_desc->ad_cname, &mapping, RWM_REMAP );
1113 if ( drop_missing || ( mapping != NULL && BER_BVISEMPTY( &mapping->m_dst ) ) )
1118 if ( mapping != NULL ) {
1119 (*ap)->a_desc = mapping->m_dst_ad;
1123 if ( (*ap)->a_desc == slap_schema.si_ad_entryDN ) {
1124 if ( stripEntryDN ) {
1125 /* will be generated by frontend */
1129 } else if ( !isupdate
1131 && (*ap)->a_desc->ad_type->sat_no_user_mod
1132 && (*ap)->a_desc->ad_type != slap_schema.si_at_undefined )
1137 for ( last = 0; !BER_BVISNULL( &(*ap)->a_vals[last] ); last++ )
1141 /* empty? leave it in place because of attrsonly and vlv */
1146 if ( (*ap)->a_desc == slap_schema.si_ad_objectClass
1147 || (*ap)->a_desc == slap_schema.si_ad_structuralObjectClass )
1151 for ( bv = (*ap)->a_vals; !BER_BVISNULL( bv ); bv++ ) {
1152 struct berval mapped;
1154 rwm_map( &rwmap->rwm_oc, &bv[0], &mapped, RWM_REMAP );
1155 if ( BER_BVISNULL( &mapped ) || BER_BVISEMPTY( &mapped ) ) {
1156 ch_free( bv[0].bv_val );
1157 BER_BVZERO( &bv[0] );
1158 if ( &(*ap)->a_vals[last] > &bv[0] ) {
1159 bv[0] = (*ap)->a_vals[last];
1160 BER_BVZERO( &(*ap)->a_vals[last] );
1165 } else if ( mapped.bv_val != bv[0].bv_val ) {
1167 * FIXME: after LBER_FREEing
1168 * the value is replaced by
1169 * ch_alloc'ed memory
1171 ber_bvreplace( &bv[0], &mapped );
1176 * It is necessary to try to rewrite attributes with
1177 * dn syntax because they might be used in ACLs as
1178 * members of groups; since ACLs are applied to the
1179 * rewritten stuff, no dn-based subject clause could
1180 * be used at the ldap backend side (see
1181 * http://www.OpenLDAP.org/faq/data/cache/452.html)
1182 * The problem can be overcome by moving the dn-based
1183 * ACLs to the target directory server, and letting
1184 * everything pass thru the ldap backend. */
1185 /* FIXME: handle distinguishedName-like syntaxes, like
1186 * nameAndOptionalUID */
1187 } else if ( (*ap)->a_desc->ad_type->sat_syntax == slap_schema.si_syn_distinguishedName
1188 || ( mapping != NULL && mapping->m_src_ad->ad_type->sat_syntax == slap_schema.si_syn_distinguishedName ) )
1190 #ifdef ENABLE_REWRITE
1191 dc.ctx = "searchAttrDN";
1192 #endif /* ENABLE_REWRITE */
1193 rc = rwm_dnattr_result_rewrite( &dc, (*ap)->a_vals );
1194 if ( rc != LDAP_SUCCESS ) {
1198 } else if ( (*ap)->a_desc == slap_schema.si_ad_ref ) {
1199 #ifdef ENABLE_REWRITE
1200 dc.ctx = "searchAttrDN";
1201 #endif /* ENABLE_REWRITE */
1202 rc = rwm_referral_result_rewrite( &dc, (*ap)->a_vals );
1203 if ( rc != LDAP_SUCCESS ) {
1208 if ( mapping != NULL ) {
1209 /* rewrite the attribute description */
1210 assert( mapping->m_dst_ad != NULL );
1211 (*ap)->a_desc = mapping->m_dst_ad;
1215 ap = &(*ap)->a_next;
1220 *ap = (*ap)->a_next;
1229 rwm_send_entry( Operation *op, SlapReply *rs )
1231 slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
1232 struct ldaprwmap *rwmap =
1233 (struct ldaprwmap *)on->on_bi.bi_private;
1237 struct berval dn = BER_BVNULL,
1242 assert( rs->sr_entry != NULL );
1245 * Rewrite the dn of the result, if needed
1248 #ifdef ENABLE_REWRITE
1249 dc.conn = op->o_conn;
1251 dc.ctx = "searchEntryDN";
1252 #else /* ! ENABLE_REWRITE */
1255 #endif /* ! ENABLE_REWRITE */
1258 flags = rs->sr_flags;
1259 if ( !( rs->sr_flags & REP_ENTRY_MODIFIABLE ) ) {
1260 /* FIXME: all we need to duplicate are:
1263 * - attributes that are requested
1264 * - no values if attrsonly is set
1269 rc = LDAP_NO_MEMORY;
1273 flags &= ~REP_ENTRY_MUSTRELEASE;
1274 flags |= ( REP_ENTRY_MODIFIABLE | REP_ENTRY_MUSTBEFREED );
1278 * Note: this may fail if the target host(s) schema differs
1279 * from the one known to the meta, and a DN with unknown
1280 * attributes is returned.
1284 rc = rwm_dn_massage_pretty_normalize( &dc, &e->e_name, &dn, &ndn );
1285 if ( rc != LDAP_SUCCESS ) {
1290 if ( e->e_name.bv_val != dn.bv_val ) {
1291 ch_free( e->e_name.bv_val );
1292 ch_free( e->e_nname.bv_val );
1298 /* TODO: map entry attribute types, objectclasses
1299 * and dn-valued attribute values */
1301 /* FIXME: the entries are in the remote mapping form;
1302 * so we need to select those attributes we are willing
1303 * to return, and remap them accordingly */
1304 (void)rwm_attrs( op, rs, &e->e_attrs, 1 );
1306 if ( rs->sr_flags & REP_ENTRY_MUSTRELEASE ) {
1307 be_entry_release_rw( op, rs->sr_entry, 0 );
1311 rs->sr_flags = flags;
1313 return SLAP_CB_CONTINUE;
1316 if ( e != NULL && e != rs->sr_entry ) {
1317 if ( e->e_name.bv_val == dn.bv_val ) {
1318 BER_BVZERO( &e->e_name );
1321 if ( e->e_nname.bv_val == ndn.bv_val ) {
1322 BER_BVZERO( &e->e_nname );
1328 if ( !BER_BVISNULL( &dn ) ) {
1329 ch_free( dn.bv_val );
1332 if ( !BER_BVISNULL( &ndn ) ) {
1333 ch_free( ndn.bv_val );
1340 rwm_operational( Operation *op, SlapReply *rs )
1342 /* FIXME: the entries are in the remote mapping form;
1343 * so we need to select those attributes we are willing
1344 * to return, and remap them accordingly */
1345 if ( rs->sr_operational_attrs ) {
1346 rwm_attrs( op, rs, &rs->sr_operational_attrs, 1 );
1349 return SLAP_CB_CONTINUE;
1353 /* don't use this; it cannot be reverted, and leaves op->o_req_dn
1354 * rewritten for subsequent operations; fine for plain suffixmassage,
1355 * but destroys everything else */
1357 rwm_chk_referrals( Operation *op, SlapReply *rs )
1359 slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
1362 #ifdef ENABLE_REWRITE
1363 rc = rwm_op_dn_massage( op, rs, "referralCheckDN" );
1364 #else /* ! ENABLE_REWRITE */
1366 rc = rwm_op_dn_massage( op, rs, &rc );
1367 #endif /* ! ENABLE_REWRITE */
1368 if ( rc != LDAP_SUCCESS ) {
1369 op->o_bd->bd_info = (BackendInfo *)on->on_info;
1370 send_ldap_error( op, rs, rc, "referralCheckDN massage error" );
1374 return SLAP_CB_CONTINUE;
1386 #ifdef ENABLE_REWRITE
1387 slap_overinst *on = (slap_overinst *) be->bd_info;
1388 struct ldaprwmap *rwmap =
1389 (struct ldaprwmap *)on->on_bi.bi_private;
1391 return rewrite_parse( rwmap->rwm_rw,
1392 fname, lineno, argc, argv );
1394 #else /* !ENABLE_REWRITE */
1395 fprintf( stderr, "%s: line %d: rewrite capabilities "
1396 "are not enabled\n", fname, lineno );
1397 #endif /* !ENABLE_REWRITE */
1403 rwm_suffixmassage_config(
1410 slap_overinst *on = (slap_overinst *) be->bd_info;
1411 struct ldaprwmap *rwmap =
1412 (struct ldaprwmap *)on->on_bi.bi_private;
1414 struct berval bvnc, nvnc, pvnc, brnc, nrnc, prnc;
1416 #ifdef ENABLE_REWRITE
1418 #endif /* ENABLE_REWRITE */
1423 * suffixmassage [<suffix>] <massaged suffix>
1425 * the [<suffix>] field must be defined as a valid suffix
1426 * for the current database;
1427 * the <massaged suffix> shouldn't have already been
1428 * defined as a valid suffix for the current server
1431 if ( be->be_suffix == NULL ) {
1432 fprintf( stderr, "%s: line %d: "
1433 " \"suffixMassage [<suffix>]"
1434 " <massaged suffix>\" without "
1435 "<suffix> part requires database "
1436 "suffix be defined first.\n",
1440 bvnc = be->be_suffix[ 0 ];
1443 } else if ( argc == 3 ) {
1444 ber_str2bv( argv[ 1 ], 0, 0, &bvnc );
1448 fprintf( stderr, "%s: line %d: syntax is"
1449 " \"suffixMassage [<suffix>]"
1450 " <massaged suffix>\"\n",
1455 if ( dnPrettyNormal( NULL, &bvnc, &pvnc, &nvnc, NULL ) != LDAP_SUCCESS ) {
1456 fprintf( stderr, "%s: line %d: suffix DN %s is invalid\n",
1457 fname, lineno, bvnc.bv_val );
1461 ber_str2bv( argv[ massaged ], 0, 0, &brnc );
1462 if ( dnPrettyNormal( NULL, &brnc, &prnc, &nrnc, NULL ) != LDAP_SUCCESS ) {
1463 fprintf( stderr, "%s: line %d: suffix DN %s is invalid\n",
1464 fname, lineno, brnc.bv_val );
1465 free( nvnc.bv_val );
1466 free( pvnc.bv_val );
1470 #ifdef ENABLE_REWRITE
1472 * The suffix massaging is emulated
1473 * by means of the rewrite capabilities
1475 rc = rwm_suffix_massage_config( rwmap->rwm_rw,
1476 &pvnc, &nvnc, &prnc, &nrnc );
1477 free( nvnc.bv_val );
1478 free( pvnc.bv_val );
1479 free( nrnc.bv_val );
1480 free( prnc.bv_val );
1484 #else /* !ENABLE_REWRITE */
1485 ber_bvarray_add( &rwmap->rwm_suffix_massage, &pvnc );
1486 ber_bvarray_add( &rwmap->rwm_suffix_massage, &nvnc );
1488 ber_bvarray_add( &rwmap->rwm_suffix_massage, &prnc );
1489 ber_bvarray_add( &rwmap->rwm_suffix_massage, &nrnc );
1490 #endif /* !ENABLE_REWRITE */
1503 slap_overinst *on = (slap_overinst *) be->bd_info;
1504 struct ldaprwmap *rwmap =
1505 (struct ldaprwmap *)on->on_bi.bi_private;
1507 /* objectclass/attribute mapping */
1508 return rwm_map_config( &rwmap->rwm_oc,
1510 fname, lineno, argc, argv );
1514 rwm_response( Operation *op, SlapReply *rs )
1516 slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
1517 struct ldaprwmap *rwmap =
1518 (struct ldaprwmap *)on->on_bi.bi_private;
1522 if ( op->o_tag == LDAP_REQ_SEARCH && rs->sr_type == REP_SEARCH ) {
1523 return rwm_send_entry( op, rs );
1526 switch( op->o_tag ) {
1527 case LDAP_REQ_SEARCH:
1530 case LDAP_REQ_DELETE:
1531 case LDAP_REQ_MODRDN:
1532 case LDAP_REQ_MODIFY:
1533 case LDAP_REQ_COMPARE:
1534 case LDAP_REQ_EXTENDED:
1539 * Rewrite the dn of the referrals, if needed
1542 #ifdef ENABLE_REWRITE
1543 dc.conn = op->o_conn;
1545 dc.ctx = "referralDN";
1546 #else /* ! ENABLE_REWRITE */
1549 #endif /* ! ENABLE_REWRITE */
1550 rc = rwm_referral_result_rewrite( &dc, rs->sr_ref );
1551 if ( rc != LDAP_SUCCESS ) {
1556 rc = rwm_matched( op, rs );
1560 rc = SLAP_CB_CONTINUE;
1575 slap_overinst *on = (slap_overinst *) be->bd_info;
1576 struct ldaprwmap *rwmap =
1577 (struct ldaprwmap *)on->on_bi.bi_private;
1582 if ( strncasecmp( argv[ 0 ], "rwm-", STRLENOF( "rwm-" ) ) == 0 ) {
1584 argv[ 0 ] = &argv0[ STRLENOF( "rwm-" ) ];
1587 if ( strncasecmp( argv[0], "rewrite", STRLENOF("rewrite") ) == 0 ) {
1588 rc = rwm_rw_config( be, fname, lineno, argc, argv );
1590 } else if ( strcasecmp( argv[0], "map" ) == 0 ) {
1591 rc = rwm_m_config( be, fname, lineno, argc, argv );
1593 } else if ( strcasecmp( argv[0], "suffixmassage" ) == 0 ) {
1594 rc = rwm_suffixmassage_config( be, fname, lineno, argc, argv );
1596 } else if ( strcasecmp( argv[0], "t-f-support" ) == 0 ) {
1599 "%s: line %d: \"t-f-support {no|yes|discover}\" needs 1 argument.\n",
1604 if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) {
1605 rwmap->rwm_flags &= ~(RWM_F_SUPPORT_T_F|RWM_F_SUPPORT_T_F_DISCOVER);
1607 } else if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) {
1608 rwmap->rwm_flags |= RWM_F_SUPPORT_T_F;
1610 /* TODO: not implemented yet */
1611 } else if ( strcasecmp( argv[ 1 ], "discover" ) == 0 ) {
1613 "%s: line %d: \"discover\" not supported yet "
1614 "in \"t-f-support {no|yes|discover}\".\n",
1618 rwmap->rwm_flags |= RWM_F_SUPPORT_T_F_DISCOVER;
1623 "%s: line %d: unknown value \"%s\" for \"t-f-support {no|yes|discover}\".\n",
1624 fname, lineno, argv[ 1 ] );
1629 rc = SLAP_CONF_UNKNOWN;
1643 slap_overinst *on = (slap_overinst *) be->bd_info;
1644 struct ldapmapping *mapping = NULL;
1645 struct ldaprwmap *rwmap;
1646 #ifdef ENABLE_REWRITE
1648 #endif /* ENABLE_REWRITE */
1651 rwmap = (struct ldaprwmap *)ch_calloc( 1, sizeof( struct ldaprwmap ) );
1653 #ifdef ENABLE_REWRITE
1654 rwmap->rwm_rw = rewrite_info_init( REWRITE_MODE_USE_DEFAULT );
1655 if ( rwmap->rwm_rw == NULL ) {
1660 /* this rewriteContext by default must be null;
1661 * rules can be added if required */
1662 rargv[ 0 ] = "rewriteContext";
1663 rargv[ 1 ] = "searchFilter";
1665 rewrite_parse( rwmap->rwm_rw, "<suffix massage>", 1, 2, rargv );
1667 rargv[ 0 ] = "rewriteContext";
1668 rargv[ 1 ] = "default";
1670 rewrite_parse( rwmap->rwm_rw, "<suffix massage>", 2, 2, rargv );
1671 #endif /* ENABLE_REWRITE */
1673 if ( rwm_map_init( &rwmap->rwm_oc, &mapping ) != LDAP_SUCCESS ||
1674 rwm_map_init( &rwmap->rwm_at, &mapping ) != LDAP_SUCCESS )
1681 on->on_bi.bi_private = (void *)rwmap;
1684 (void)rwm_db_destroy( be );
1694 slap_overinst *on = (slap_overinst *) be->bd_info;
1697 if ( on->on_bi.bi_private ) {
1698 struct ldaprwmap *rwmap =
1699 (struct ldaprwmap *)on->on_bi.bi_private;
1701 #ifdef ENABLE_REWRITE
1702 if ( rwmap->rwm_rw ) {
1703 rewrite_info_delete( &rwmap->rwm_rw );
1705 #else /* !ENABLE_REWRITE */
1706 if ( rwmap->rwm_suffix_massage ) {
1707 ber_bvarray_free( rwmap->rwm_suffix_massage );
1709 #endif /* !ENABLE_REWRITE */
1711 avl_free( rwmap->rwm_oc.remap, rwm_mapping_dst_free );
1712 avl_free( rwmap->rwm_oc.map, rwm_mapping_free );
1713 avl_free( rwmap->rwm_at.remap, rwm_mapping_dst_free );
1714 avl_free( rwmap->rwm_at.map, rwm_mapping_free );
1722 static slap_overinst rwm = { { NULL } };
1724 #if SLAPD_OVER_RWM == SLAPD_MOD_DYNAMIC
1726 #endif /* SLAPD_OVER_RWM == SLAPD_MOD_DYNAMIC */
1728 rwm_initialize( void )
1730 memset( &rwm, 0, sizeof( slap_overinst ) );
1732 rwm.on_bi.bi_type = "rwm";
1733 rwm.on_bi.bi_flags =
1734 SLAPO_BFLAG_SINGLE |
1737 rwm.on_bi.bi_db_init = rwm_db_init;
1738 rwm.on_bi.bi_db_config = rwm_db_config;
1739 rwm.on_bi.bi_db_destroy = rwm_db_destroy;
1741 rwm.on_bi.bi_op_bind = rwm_op_bind;
1742 rwm.on_bi.bi_op_search = rwm_op_search;
1743 rwm.on_bi.bi_op_compare = rwm_op_compare;
1744 rwm.on_bi.bi_op_modify = rwm_op_modify;
1745 rwm.on_bi.bi_op_modrdn = rwm_op_modrdn;
1746 rwm.on_bi.bi_op_add = rwm_op_add;
1747 rwm.on_bi.bi_op_delete = rwm_op_delete;
1748 rwm.on_bi.bi_op_unbind = rwm_op_unbind;
1749 rwm.on_bi.bi_extended = rwm_extended;
1751 rwm.on_bi.bi_operational = rwm_operational;
1752 rwm.on_bi.bi_chk_referrals = 0 /* rwm_chk_referrals */ ;
1754 #ifdef ENABLE_REWRITE
1755 rwm.on_bi.bi_connection_init = rwm_conn_init;
1756 rwm.on_bi.bi_connection_destroy = rwm_conn_destroy;
1757 #endif /* ENABLE_REWRITE */
1759 rwm.on_response = rwm_response;
1761 return overlay_register( &rwm );
1764 #if SLAPD_OVER_RWM == SLAPD_MOD_DYNAMIC
1766 init_module( int argc, char *argv[] )
1768 return rwm_initialize();
1770 #endif /* SLAPD_OVER_RWM == SLAPD_MOD_DYNAMIC */
1772 #endif /* SLAPD_OVER_RWM */