1 /* rwm.c - rewrite/remap operations */
3 * Copyright 2003 The OpenLDAP Foundation, All Rights Reserved.
4 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
7 * Copyright 2003, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
9 * Permission is granted to anyone to use this software for any purpose
10 * on any computer system, and to alter it and redistribute it, subject
11 * to the following restrictions:
13 * 1. The author is not responsible for the consequences of use of this
14 * software, no matter how awful, even if they arise from flaws in it.
16 * 2. The origin of this software must not be misrepresented, either by
17 * explicit claim or by omission. Since few users ever read sources,
18 * credits should appear in the documentation.
20 * 3. Altered versions must be plainly marked as such, and must not be
21 * misrepresented as being the original software. Since few users
22 * ever read sources, credits should appear in the documentation.
24 * 4. This notice may not be removed or altered.
35 rwm_op_dn_massage( Operation *op, SlapReply *rs, void *cookie )
37 slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
38 struct ldaprwmap *rwmap =
39 (struct ldaprwmap *)on->on_bi.bi_private;
41 struct berval dn, ndn, mdn = { 0, NULL };
46 * Rewrite the bind dn if needed
52 dc.ctx = (char *)cookie;
54 dc.tofrom = ((int *)cookie)[0];
58 rc = rwm_dn_massage( &dc, &op->o_req_dn, &mdn );
59 if ( rc != LDAP_SUCCESS ) {
63 if ( mdn.bv_val == op->o_req_dn.bv_val ) {
67 rc = dnPrettyNormal( NULL, &mdn, &dn, &ndn, op->o_tmpmemctx );
68 if ( rc != LDAP_SUCCESS ) {
72 if ( mdn.bv_val != dn.bv_val ) {
73 ch_free( mdn.bv_val );
76 op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx );
77 op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx );
86 rwm_bind( Operation *op, SlapReply *rs )
91 rc = rwm_op_dn_massage( op, rs, "bindDn" );
94 rc = rwm_op_dn_massage( op, rs, &rc );
96 if ( rc != LDAP_SUCCESS ) {
100 return SLAP_CB_CONTINUE;
104 rwm_add( Operation *op, SlapReply *rs )
108 #ifdef ENABLE_REWRITE
109 rc = rwm_op_dn_massage( op, rs, "addDn" );
112 rc = rwm_op_dn_massage( op, rs, &rc );
114 if ( rc != LDAP_SUCCESS ) {
118 /* TODO: rewrite attribute types, values of DN-valued attributes ... */
119 return SLAP_CB_CONTINUE;
123 rwm_delete( Operation *op, SlapReply *rs )
127 #ifdef ENABLE_REWRITE
128 rc = rwm_op_dn_massage( op, rs, "deleteDn" );
131 rc = rwm_op_dn_massage( op, rs, &rc );
133 if ( rc != LDAP_SUCCESS ) {
137 return SLAP_CB_CONTINUE;
141 rwm_modrdn( Operation *op, SlapReply *rs )
145 #ifdef ENABLE_REWRITE
146 rc = rwm_op_dn_massage( op, rs, "renameDn" );
149 rc = rwm_op_dn_massage( op, rs, &rc );
151 if ( rc != LDAP_SUCCESS ) {
155 /* TODO: rewrite attribute types, values of DN-valued attributes ... */
156 return SLAP_CB_CONTINUE;
160 rwm_modify( Operation *op, SlapReply *rs )
164 #ifdef ENABLE_REWRITE
165 rc = rwm_op_dn_massage( op, rs, "modifyDn" );
168 rc = rwm_op_dn_massage( op, rs, &rc );
170 if ( rc != LDAP_SUCCESS ) {
174 /* TODO: rewrite attribute types, values of DN-valued attributes ... */
175 return SLAP_CB_CONTINUE;
179 rwm_compare( Operation *op, SlapReply *rs )
183 #ifdef ENABLE_REWRITE
184 rc = rwm_op_dn_massage( op, rs, "compareDn" );
187 rc = rwm_op_dn_massage( op, rs, &rc );
189 if ( rc != LDAP_SUCCESS ) {
193 /* TODO: rewrite attribute types, values of DN-valued attributes ... */
194 return SLAP_CB_CONTINUE;
198 rwm_search( Operation *op, SlapReply *rs )
202 #ifdef ENABLE_REWRITE
203 rc = rwm_op_dn_massage( op, rs, "searchDn" );
206 rc = rwm_op_dn_massage( op, rs, &rc );
208 if ( rc != LDAP_SUCCESS ) {
212 /* TODO: rewrite/map filter & attrs */
213 return SLAP_CB_CONTINUE;
217 rwm_extended( Operation *op, SlapReply *rs )
221 #ifdef ENABLE_REWRITE
222 rc = rwm_op_dn_massage( op, rs, "extendedDn" );
225 rc = rwm_op_dn_massage( op, rs, &rc );
227 if ( rc != LDAP_SUCCESS ) {
231 /* TODO: rewrite/map extended data ? ... */
236 rwm_matched( Operation *op, SlapReply *rs )
238 slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
239 struct ldaprwmap *rwmap =
240 (struct ldaprwmap *)on->on_bi.bi_private;
242 struct berval dn, mdn;
245 if ( rs->sr_matched == NULL ) {
246 return SLAP_CB_CONTINUE;
250 #ifdef ENABLE_REWRITE
251 dc.conn = op->o_conn;
253 dc.ctx = "matchedDn";
258 ber_str2bv( rs->sr_matched, 0, 0, &dn );
259 rwm_dn_massage( &dc, &dn, &mdn );
261 if ( mdn.bv_val != dn.bv_val ) {
262 if ( rs->sr_flags & REP_MATCHED_MUSTBEFREED ) {
263 ch_free( (void *)rs->sr_matched );
265 rs->sr_flags |= REP_MATCHED_MUSTBEFREED;
267 rs->sr_matched = mdn.bv_val;
270 return SLAP_CB_CONTINUE;
274 rwm_send_entry( Operation *op, SlapReply *rs )
276 slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
277 struct ldaprwmap *rwmap =
278 (struct ldaprwmap *)on->on_bi.bi_private;
281 struct berval dn = { 0, NULL }, ndn = { 0, NULL };
283 int rc = SLAP_CB_CONTINUE;
285 assert( rs->sr_entry );
290 * Rewrite the dn of the result, if needed
293 #ifdef ENABLE_REWRITE
294 dc.conn = op->o_conn;
296 dc.ctx = "searchResultDN";
301 if ( rwm_dn_massage( &dc, &e->e_name, &dn ) ) {
305 if ( e->e_name.bv_val == dn.bv_val ) {
306 return SLAP_CB_CONTINUE;
310 * Note: this may fail if the target host(s) schema differs
311 * from the one known to the meta, and a DN with unknown
312 * attributes is returned.
314 if ( dnNormalize( 0, NULL, NULL, &dn, &ndn, NULL ) != LDAP_SUCCESS ) {
315 if ( dn.bv_val != e->e_name.bv_val ) {
316 ch_free( dn.bv_val );
318 rc = LDAP_INVALID_DN_SYNTAX;
322 if ( !( rs->sr_flags & REP_ENTRY_MODIFIABLE ) ) {
327 rs->sr_flags |= ( REP_ENTRY_MODIFIABLE | REP_ENTRY_MUSTBEFREED );
330 free( e->e_name.bv_val );
331 free( e->e_nname.bv_val );
338 /* TODO: map entry attribute types, objectclasses
339 * and dn-valued attribute values */
341 return SLAP_CB_CONTINUE;
344 if ( dn.bv_val && ( dn.bv_val != e->e_name.bv_val ) ) {
345 ch_free( dn.bv_val );
349 ch_free( ndn.bv_val );
364 #ifdef ENABLE_REWRITE
365 slap_overinst *on = (slap_overinst *) be->bd_info;
366 struct ldaprwmap *rwmap =
367 (struct ldaprwmap *)on->on_bi.bi_private;
369 return rewrite_parse( rwmap->rwm_rw,
370 fname, lineno, argc, argv );
372 #else /* !ENABLE_REWRITE */
373 fprintf( stderr, "%s: line %d: rewrite capabilities "
374 "are not enabled\n", fname, lineno );
375 #endif /* !ENABLE_REWRITE */
381 rwm_suffixmassage_config(
389 slap_overinst *on = (slap_overinst *) be->bd_info;
390 struct ldaprwmap *rwmap =
391 (struct ldaprwmap *)on->on_bi.bi_private;
393 struct berval bvnc, nvnc, pvnc, brnc, nrnc, prnc;
394 #ifdef ENABLE_REWRITE
396 #endif /* ENABLE_REWRITE */
401 * suffixmassage <suffix> <massaged suffix>
403 * the <suffix> field must be defined as a valid suffix
404 * (or suffixAlias?) for the current database;
405 * the <massaged suffix> shouldn't have already been
406 * defined as a valid suffix or suffixAlias for the
410 fprintf( stderr, "%s: line %d: syntax is"
411 " \"suffixMassage <suffix>"
412 " <massaged suffix>\"\n",
417 ber_str2bv( argv[1], 0, 0, &bvnc );
418 if ( dnPrettyNormal( NULL, &bvnc, &pvnc, &nvnc, NULL ) != LDAP_SUCCESS ) {
419 fprintf( stderr, "%s: line %d: suffix DN %s is invalid\n",
420 fname, lineno, bvnc.bv_val );
424 ber_str2bv( argv[2], 0, 0, &brnc );
425 if ( dnPrettyNormal( NULL, &brnc, &prnc, &nrnc, NULL ) != LDAP_SUCCESS ) {
426 fprintf( stderr, "%s: line %d: suffix DN %s is invalid\n",
427 fname, lineno, brnc.bv_val );
433 #ifdef ENABLE_REWRITE
435 * The suffix massaging is emulated
436 * by means of the rewrite capabilities
438 rc = suffix_massage_config( rwmap->rwm_rw,
439 &pvnc, &nvnc, &prnc, &nrnc );
447 #else /* !ENABLE_REWRITE */
448 ber_bvarray_add( &rwmap->rwm_suffix_massage, &pvnc );
449 ber_bvarray_add( &rwmap->rwm_suffix_massage, &nvnc );
451 ber_bvarray_add( &rwmap->rwm_suffix_massage, &prnc );
452 ber_bvarray_add( &rwmap->rwm_suffix_massage, &nrnc );
453 #endif /* !ENABLE_REWRITE */
467 slap_overinst *on = (slap_overinst *) be->bd_info;
468 struct ldaprwmap *rwmap =
469 (struct ldaprwmap *)on->on_bi.bi_private;
471 /* objectclass/attribute mapping */
472 return rwm_map_config( &rwmap->rwm_oc,
474 fname, lineno, argc, argv );
478 rwm_response( Operation *op, SlapReply *rs )
482 if ( op->o_tag == LDAP_REQ_SEARCH && rs->sr_type == REP_SEARCH ) {
483 return rwm_send_entry( op, rs );
486 switch( op->o_tag ) {
489 case LDAP_REQ_DELETE:
490 case LDAP_REQ_MODRDN:
491 case LDAP_REQ_MODIFY:
492 case LDAP_REQ_COMPARE:
493 case LDAP_REQ_SEARCH:
494 case LDAP_REQ_EXTENDED:
495 rc = rwm_matched( op, rs );
498 rc = SLAP_CB_CONTINUE;
516 if ( strncasecmp( argv[0], "rewrite", sizeof("rewrite") - 1) == 0 ) {
517 rc = rwm_rw_config( be, fname, lineno, argc, argv );
519 } else if (strcasecmp( argv[0], "map" ) == 0 ) {
520 rc = rwm_m_config( be, fname, lineno, argc, argv );
522 } else if (strcasecmp( argv[0], "suffixmassage" ) == 0 ) {
523 rc = rwm_suffixmassage_config( be, fname, lineno, argc, argv );
535 slap_overinst *on = (slap_overinst *) be->bd_info;
536 struct ldapmapping *mapping = NULL;
537 struct ldaprwmap *rwmap;
539 rwmap = (struct ldaprwmap *)ch_malloc(sizeof(struct ldaprwmap));
540 memset(rwmap, 0, sizeof(struct ldaprwmap));
542 #ifdef ENABLE_REWRITE
543 rwmap->rwm_rw = rewrite_info_init( REWRITE_MODE_USE_DEFAULT );
544 if ( rwmap->rwm_rw == NULL ) {
548 #endif /* ENABLE_REWRITE */
550 rwm_map_init( &rwmap->rwm_oc, &mapping );
551 rwm_map_init( &rwmap->rwm_at, &mapping );
553 on->on_bi.bi_private = (void *)rwmap;
563 slap_overinst *on = (slap_overinst *) be->bd_info;
566 if ( on->on_bi.bi_private ) {
567 struct ldaprwmap *rwmap =
568 (struct ldaprwmap *)on->on_bi.bi_private;
570 #ifdef ENABLE_REWRITE
572 rewrite_info_delete( &rwmap->rwm_rw );
574 #else /* !ENABLE_REWRITE */
575 if ( rwmap->lrwm_suffix_massage ) {
576 ber_bvarray_free( rwmap->rwm_suffix_massage );
578 #endif /* !ENABLE_REWRITE */
580 avl_free( rwmap->rwm_oc.remap, NULL );
581 avl_free( rwmap->rwm_oc.map, mapping_free );
582 avl_free( rwmap->rwm_at.remap, NULL );
583 avl_free( rwmap->rwm_at.map, mapping_free );
589 static slap_overinst rwm = { { NULL } };
594 memset( &rwm, 0, sizeof(slap_overinst) );
596 rwm.on_bi.bi_type = "rewrite-remap";
597 rwm.on_bi.bi_db_init = rwm_init;
598 rwm.on_bi.bi_db_config = rwm_config;
599 rwm.on_bi.bi_db_destroy = rwm_destroy;
601 rwm.on_bi.bi_op_bind = rwm_bind;
602 rwm.on_bi.bi_op_search = rwm_search;
603 rwm.on_bi.bi_op_compare = rwm_compare;
604 rwm.on_bi.bi_op_modify = rwm_modify;
605 rwm.on_bi.bi_op_modrdn = rwm_modrdn;
606 rwm.on_bi.bi_op_add = rwm_add;
607 rwm.on_bi.bi_op_delete = rwm_delete;
608 rwm.on_bi.bi_extended = rwm_extended;
610 rwm.on_response = rwm_response;
612 return overlay_register( &rwm );