1 /* rwm.c - rewrite/remap operations */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 2003 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>.
26 rwm_op_dn_massage( Operation *op, SlapReply *rs, void *cookie )
28 slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
29 struct ldaprwmap *rwmap =
30 (struct ldaprwmap *)on->on_bi.bi_private;
32 struct berval dn, ndn, mdn = { 0, NULL };
37 * Rewrite the bind dn if needed
43 dc.ctx = (char *)cookie;
45 dc.tofrom = ((int *)cookie)[0];
49 rc = rwm_dn_massage( &dc, &op->o_req_dn, &mdn );
50 if ( rc != LDAP_SUCCESS ) {
54 if ( mdn.bv_val == op->o_req_dn.bv_val ) {
58 rc = dnPrettyNormal( NULL, &mdn, &dn, &ndn, op->o_tmpmemctx );
59 if ( rc != LDAP_SUCCESS ) {
63 if ( mdn.bv_val != dn.bv_val ) {
64 ch_free( mdn.bv_val );
67 op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx );
68 op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx );
77 rwm_bind( Operation *op, SlapReply *rs )
82 rc = rwm_op_dn_massage( op, rs, "bindDn" );
85 rc = rwm_op_dn_massage( op, rs, &rc );
87 if ( rc != LDAP_SUCCESS ) {
91 return SLAP_CB_CONTINUE;
95 rwm_add( Operation *op, SlapReply *rs )
100 rc = rwm_op_dn_massage( op, rs, "addDn" );
103 rc = rwm_op_dn_massage( op, rs, &rc );
105 if ( rc != LDAP_SUCCESS ) {
109 /* TODO: rewrite attribute types, values of DN-valued attributes ... */
110 return SLAP_CB_CONTINUE;
114 rwm_delete( Operation *op, SlapReply *rs )
118 #ifdef ENABLE_REWRITE
119 rc = rwm_op_dn_massage( op, rs, "deleteDn" );
122 rc = rwm_op_dn_massage( op, rs, &rc );
124 if ( rc != LDAP_SUCCESS ) {
128 return SLAP_CB_CONTINUE;
132 rwm_modrdn( Operation *op, SlapReply *rs )
136 #ifdef ENABLE_REWRITE
137 rc = rwm_op_dn_massage( op, rs, "renameDn" );
140 rc = rwm_op_dn_massage( op, rs, &rc );
142 if ( rc != LDAP_SUCCESS ) {
146 /* TODO: rewrite attribute types, values of DN-valued attributes ... */
147 return SLAP_CB_CONTINUE;
151 rwm_modify( Operation *op, SlapReply *rs )
155 #ifdef ENABLE_REWRITE
156 rc = rwm_op_dn_massage( op, rs, "modifyDn" );
159 rc = rwm_op_dn_massage( op, rs, &rc );
161 if ( rc != LDAP_SUCCESS ) {
165 /* TODO: rewrite attribute types, values of DN-valued attributes ... */
166 return SLAP_CB_CONTINUE;
170 rwm_compare( Operation *op, SlapReply *rs )
174 #ifdef ENABLE_REWRITE
175 rc = rwm_op_dn_massage( op, rs, "compareDn" );
178 rc = rwm_op_dn_massage( op, rs, &rc );
180 if ( rc != LDAP_SUCCESS ) {
184 /* TODO: rewrite attribute types, values of DN-valued attributes ... */
185 return SLAP_CB_CONTINUE;
189 rwm_search( Operation *op, SlapReply *rs )
193 #ifdef ENABLE_REWRITE
194 rc = rwm_op_dn_massage( op, rs, "searchDn" );
197 rc = rwm_op_dn_massage( op, rs, &rc );
199 if ( rc != LDAP_SUCCESS ) {
203 /* TODO: rewrite/map filter & attrs */
204 return SLAP_CB_CONTINUE;
208 rwm_extended( Operation *op, SlapReply *rs )
212 #ifdef ENABLE_REWRITE
213 rc = rwm_op_dn_massage( op, rs, "extendedDn" );
216 rc = rwm_op_dn_massage( op, rs, &rc );
218 if ( rc != LDAP_SUCCESS ) {
222 /* TODO: rewrite/map extended data ? ... */
227 rwm_matched( Operation *op, SlapReply *rs )
229 slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
230 struct ldaprwmap *rwmap =
231 (struct ldaprwmap *)on->on_bi.bi_private;
233 struct berval dn, mdn;
236 if ( rs->sr_matched == NULL ) {
237 return SLAP_CB_CONTINUE;
241 #ifdef ENABLE_REWRITE
242 dc.conn = op->o_conn;
244 dc.ctx = "matchedDn";
249 ber_str2bv( rs->sr_matched, 0, 0, &dn );
250 rwm_dn_massage( &dc, &dn, &mdn );
252 if ( mdn.bv_val != dn.bv_val ) {
253 if ( rs->sr_flags & REP_MATCHED_MUSTBEFREED ) {
254 ch_free( (void *)rs->sr_matched );
256 rs->sr_flags |= REP_MATCHED_MUSTBEFREED;
258 rs->sr_matched = mdn.bv_val;
261 return SLAP_CB_CONTINUE;
265 rwm_send_entry( Operation *op, SlapReply *rs )
267 slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
268 struct ldaprwmap *rwmap =
269 (struct ldaprwmap *)on->on_bi.bi_private;
272 struct berval dn = { 0, NULL }, ndn = { 0, NULL };
274 int rc = SLAP_CB_CONTINUE;
276 assert( rs->sr_entry );
281 * Rewrite the dn of the result, if needed
284 #ifdef ENABLE_REWRITE
285 dc.conn = op->o_conn;
287 dc.ctx = "searchResultDN";
292 if ( rwm_dn_massage( &dc, &e->e_name, &dn ) ) {
296 if ( e->e_name.bv_val == dn.bv_val ) {
297 return SLAP_CB_CONTINUE;
301 * Note: this may fail if the target host(s) schema differs
302 * from the one known to the meta, and a DN with unknown
303 * attributes is returned.
305 if ( dnNormalize( 0, NULL, NULL, &dn, &ndn, NULL ) != LDAP_SUCCESS ) {
306 if ( dn.bv_val != e->e_name.bv_val ) {
307 ch_free( dn.bv_val );
309 rc = LDAP_INVALID_DN_SYNTAX;
313 if ( !( rs->sr_flags & REP_ENTRY_MODIFIABLE ) ) {
318 rs->sr_flags |= ( REP_ENTRY_MODIFIABLE | REP_ENTRY_MUSTBEFREED );
321 free( e->e_name.bv_val );
322 free( e->e_nname.bv_val );
329 /* TODO: map entry attribute types, objectclasses
330 * and dn-valued attribute values */
332 return SLAP_CB_CONTINUE;
335 if ( dn.bv_val && ( dn.bv_val != e->e_name.bv_val ) ) {
336 ch_free( dn.bv_val );
340 ch_free( ndn.bv_val );
355 #ifdef ENABLE_REWRITE
356 slap_overinst *on = (slap_overinst *) be->bd_info;
357 struct ldaprwmap *rwmap =
358 (struct ldaprwmap *)on->on_bi.bi_private;
360 return rewrite_parse( rwmap->rwm_rw,
361 fname, lineno, argc, argv );
363 #else /* !ENABLE_REWRITE */
364 fprintf( stderr, "%s: line %d: rewrite capabilities "
365 "are not enabled\n", fname, lineno );
366 #endif /* !ENABLE_REWRITE */
372 rwm_suffixmassage_config(
380 slap_overinst *on = (slap_overinst *) be->bd_info;
381 struct ldaprwmap *rwmap =
382 (struct ldaprwmap *)on->on_bi.bi_private;
384 struct berval bvnc, nvnc, pvnc, brnc, nrnc, prnc;
385 #ifdef ENABLE_REWRITE
387 #endif /* ENABLE_REWRITE */
392 * suffixmassage <suffix> <massaged suffix>
394 * the <suffix> field must be defined as a valid suffix
395 * (or suffixAlias?) for the current database;
396 * the <massaged suffix> shouldn't have already been
397 * defined as a valid suffix or suffixAlias for the
401 fprintf( stderr, "%s: line %d: syntax is"
402 " \"suffixMassage <suffix>"
403 " <massaged suffix>\"\n",
408 ber_str2bv( argv[1], 0, 0, &bvnc );
409 if ( dnPrettyNormal( NULL, &bvnc, &pvnc, &nvnc, NULL ) != LDAP_SUCCESS ) {
410 fprintf( stderr, "%s: line %d: suffix DN %s is invalid\n",
411 fname, lineno, bvnc.bv_val );
415 ber_str2bv( argv[2], 0, 0, &brnc );
416 if ( dnPrettyNormal( NULL, &brnc, &prnc, &nrnc, NULL ) != LDAP_SUCCESS ) {
417 fprintf( stderr, "%s: line %d: suffix DN %s is invalid\n",
418 fname, lineno, brnc.bv_val );
424 #ifdef ENABLE_REWRITE
426 * The suffix massaging is emulated
427 * by means of the rewrite capabilities
429 rc = suffix_massage_config( rwmap->rwm_rw,
430 &pvnc, &nvnc, &prnc, &nrnc );
438 #else /* !ENABLE_REWRITE */
439 ber_bvarray_add( &rwmap->rwm_suffix_massage, &pvnc );
440 ber_bvarray_add( &rwmap->rwm_suffix_massage, &nvnc );
442 ber_bvarray_add( &rwmap->rwm_suffix_massage, &prnc );
443 ber_bvarray_add( &rwmap->rwm_suffix_massage, &nrnc );
444 #endif /* !ENABLE_REWRITE */
458 slap_overinst *on = (slap_overinst *) be->bd_info;
459 struct ldaprwmap *rwmap =
460 (struct ldaprwmap *)on->on_bi.bi_private;
462 /* objectclass/attribute mapping */
463 return rwm_map_config( &rwmap->rwm_oc,
465 fname, lineno, argc, argv );
469 rwm_response( Operation *op, SlapReply *rs )
473 if ( op->o_tag == LDAP_REQ_SEARCH && rs->sr_type == REP_SEARCH ) {
474 return rwm_send_entry( op, rs );
477 switch( op->o_tag ) {
480 case LDAP_REQ_DELETE:
481 case LDAP_REQ_MODRDN:
482 case LDAP_REQ_MODIFY:
483 case LDAP_REQ_COMPARE:
484 case LDAP_REQ_SEARCH:
485 case LDAP_REQ_EXTENDED:
486 rc = rwm_matched( op, rs );
489 rc = SLAP_CB_CONTINUE;
507 if ( strncasecmp( argv[0], "rewrite", sizeof("rewrite") - 1) == 0 ) {
508 rc = rwm_rw_config( be, fname, lineno, argc, argv );
510 } else if (strcasecmp( argv[0], "map" ) == 0 ) {
511 rc = rwm_m_config( be, fname, lineno, argc, argv );
513 } else if (strcasecmp( argv[0], "suffixmassage" ) == 0 ) {
514 rc = rwm_suffixmassage_config( be, fname, lineno, argc, argv );
517 rc = SLAP_CONF_UNKNOWN;
528 slap_overinst *on = (slap_overinst *) be->bd_info;
529 struct ldapmapping *mapping = NULL;
530 struct ldaprwmap *rwmap;
532 rwmap = (struct ldaprwmap *)ch_malloc(sizeof(struct ldaprwmap));
533 memset(rwmap, 0, sizeof(struct ldaprwmap));
535 #ifdef ENABLE_REWRITE
536 rwmap->rwm_rw = rewrite_info_init( REWRITE_MODE_USE_DEFAULT );
537 if ( rwmap->rwm_rw == NULL ) {
541 #endif /* ENABLE_REWRITE */
543 rwm_map_init( &rwmap->rwm_oc, &mapping );
544 rwm_map_init( &rwmap->rwm_at, &mapping );
546 on->on_bi.bi_private = (void *)rwmap;
556 slap_overinst *on = (slap_overinst *) be->bd_info;
559 if ( on->on_bi.bi_private ) {
560 struct ldaprwmap *rwmap =
561 (struct ldaprwmap *)on->on_bi.bi_private;
563 #ifdef ENABLE_REWRITE
565 rewrite_info_delete( &rwmap->rwm_rw );
567 #else /* !ENABLE_REWRITE */
568 if ( rwmap->lrwm_suffix_massage ) {
569 ber_bvarray_free( rwmap->rwm_suffix_massage );
571 #endif /* !ENABLE_REWRITE */
573 avl_free( rwmap->rwm_oc.remap, NULL );
574 avl_free( rwmap->rwm_oc.map, mapping_free );
575 avl_free( rwmap->rwm_at.remap, NULL );
576 avl_free( rwmap->rwm_at.map, mapping_free );
582 static slap_overinst rwm = { { NULL } };
587 memset( &rwm, 0, sizeof(slap_overinst) );
589 rwm.on_bi.bi_type = "rewrite-remap";
590 rwm.on_bi.bi_db_init = rwm_init;
591 rwm.on_bi.bi_db_config = rwm_config;
592 rwm.on_bi.bi_db_destroy = rwm_destroy;
594 rwm.on_bi.bi_op_bind = rwm_bind;
595 rwm.on_bi.bi_op_search = rwm_search;
596 rwm.on_bi.bi_op_compare = rwm_compare;
597 rwm.on_bi.bi_op_modify = rwm_modify;
598 rwm.on_bi.bi_op_modrdn = rwm_modrdn;
599 rwm.on_bi.bi_op_add = rwm_add;
600 rwm.on_bi.bi_op_delete = rwm_delete;
601 rwm.on_bi.bi_extended = rwm_extended;
603 rwm.on_response = rwm_response;
605 return overlay_register( &rwm );