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, ndn, mdn = { 0, NULL };
39 * Rewrite the bind dn if needed
45 dc.ctx = (char *)cookie;
47 dc.tofrom = ((int *)cookie)[0];
51 rc = rwm_dn_massage( &dc, &op->o_req_dn, &mdn );
52 if ( rc != LDAP_SUCCESS ) {
56 if ( mdn.bv_val == op->o_req_dn.bv_val ) {
60 rc = dnPrettyNormal( NULL, &mdn, &dn, &ndn, op->o_tmpmemctx );
61 if ( rc != LDAP_SUCCESS ) {
65 if ( mdn.bv_val != dn.bv_val ) {
66 ch_free( mdn.bv_val );
69 op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx );
70 op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx );
79 rwm_bind( Operation *op, SlapReply *rs )
84 rc = rwm_op_dn_massage( op, rs, "bindDn" );
87 rc = rwm_op_dn_massage( op, rs, &rc );
89 if ( rc != LDAP_SUCCESS ) {
93 return SLAP_CB_CONTINUE;
97 rwm_add( Operation *op, SlapReply *rs )
101 #ifdef ENABLE_REWRITE
102 rc = rwm_op_dn_massage( op, rs, "addDn" );
105 rc = rwm_op_dn_massage( op, rs, &rc );
107 if ( rc != LDAP_SUCCESS ) {
111 /* TODO: rewrite attribute types, values of DN-valued attributes ... */
112 return SLAP_CB_CONTINUE;
116 rwm_delete( Operation *op, SlapReply *rs )
120 #ifdef ENABLE_REWRITE
121 rc = rwm_op_dn_massage( op, rs, "deleteDn" );
124 rc = rwm_op_dn_massage( op, rs, &rc );
126 if ( rc != LDAP_SUCCESS ) {
130 return SLAP_CB_CONTINUE;
134 rwm_modrdn( Operation *op, SlapReply *rs )
138 #ifdef ENABLE_REWRITE
139 rc = rwm_op_dn_massage( op, rs, "renameDn" );
142 rc = rwm_op_dn_massage( op, rs, &rc );
144 if ( rc != LDAP_SUCCESS ) {
148 /* TODO: rewrite attribute types, values of DN-valued attributes ... */
149 return SLAP_CB_CONTINUE;
153 rwm_modify( Operation *op, SlapReply *rs )
157 #ifdef ENABLE_REWRITE
158 rc = rwm_op_dn_massage( op, rs, "modifyDn" );
161 rc = rwm_op_dn_massage( op, rs, &rc );
163 if ( rc != LDAP_SUCCESS ) {
167 /* TODO: rewrite attribute types, values of DN-valued attributes ... */
168 return SLAP_CB_CONTINUE;
172 rwm_compare( Operation *op, SlapReply *rs )
176 #ifdef ENABLE_REWRITE
177 rc = rwm_op_dn_massage( op, rs, "compareDn" );
180 rc = rwm_op_dn_massage( op, rs, &rc );
182 if ( rc != LDAP_SUCCESS ) {
186 /* TODO: rewrite attribute types, values of DN-valued attributes ... */
187 return SLAP_CB_CONTINUE;
191 rwm_search( Operation *op, SlapReply *rs )
195 #ifdef ENABLE_REWRITE
196 rc = rwm_op_dn_massage( op, rs, "searchDn" );
199 rc = rwm_op_dn_massage( op, rs, &rc );
201 if ( rc != LDAP_SUCCESS ) {
205 /* TODO: rewrite/map filter & attrs */
206 return SLAP_CB_CONTINUE;
210 rwm_extended( Operation *op, SlapReply *rs )
214 #ifdef ENABLE_REWRITE
215 rc = rwm_op_dn_massage( op, rs, "extendedDn" );
218 rc = rwm_op_dn_massage( op, rs, &rc );
220 if ( rc != LDAP_SUCCESS ) {
224 /* TODO: rewrite/map extended data ? ... */
229 rwm_matched( Operation *op, SlapReply *rs )
231 slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
232 struct ldaprwmap *rwmap =
233 (struct ldaprwmap *)on->on_bi.bi_private;
235 struct berval dn, mdn;
238 if ( rs->sr_matched == NULL ) {
239 return SLAP_CB_CONTINUE;
243 #ifdef ENABLE_REWRITE
244 dc.conn = op->o_conn;
246 dc.ctx = "matchedDn";
251 ber_str2bv( rs->sr_matched, 0, 0, &dn );
252 rwm_dn_massage( &dc, &dn, &mdn );
254 if ( mdn.bv_val != dn.bv_val ) {
255 if ( rs->sr_flags & REP_MATCHED_MUSTBEFREED ) {
256 ch_free( (void *)rs->sr_matched );
258 rs->sr_flags |= REP_MATCHED_MUSTBEFREED;
260 rs->sr_matched = mdn.bv_val;
263 return SLAP_CB_CONTINUE;
267 rwm_send_entry( Operation *op, SlapReply *rs )
269 slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
270 struct ldaprwmap *rwmap =
271 (struct ldaprwmap *)on->on_bi.bi_private;
274 struct berval dn = { 0, NULL }, ndn = { 0, NULL };
276 int rc = SLAP_CB_CONTINUE;
278 assert( rs->sr_entry );
283 * Rewrite the dn of the result, if needed
286 #ifdef ENABLE_REWRITE
287 dc.conn = op->o_conn;
289 dc.ctx = "searchResultDN";
294 if ( rwm_dn_massage( &dc, &e->e_name, &dn ) ) {
298 if ( e->e_name.bv_val == dn.bv_val ) {
299 return SLAP_CB_CONTINUE;
303 * Note: this may fail if the target host(s) schema differs
304 * from the one known to the meta, and a DN with unknown
305 * attributes is returned.
307 if ( dnNormalize( 0, NULL, NULL, &dn, &ndn, NULL ) != LDAP_SUCCESS ) {
308 if ( dn.bv_val != e->e_name.bv_val ) {
309 ch_free( dn.bv_val );
311 rc = LDAP_INVALID_DN_SYNTAX;
315 if ( !( rs->sr_flags & REP_ENTRY_MODIFIABLE ) ) {
320 rs->sr_flags |= ( REP_ENTRY_MODIFIABLE | REP_ENTRY_MUSTBEFREED );
323 free( e->e_name.bv_val );
324 free( e->e_nname.bv_val );
331 /* TODO: map entry attribute types, objectclasses
332 * and dn-valued attribute values */
334 return SLAP_CB_CONTINUE;
337 if ( dn.bv_val && ( dn.bv_val != e->e_name.bv_val ) ) {
338 ch_free( dn.bv_val );
342 ch_free( ndn.bv_val );
357 #ifdef ENABLE_REWRITE
358 slap_overinst *on = (slap_overinst *) be->bd_info;
359 struct ldaprwmap *rwmap =
360 (struct ldaprwmap *)on->on_bi.bi_private;
362 return rewrite_parse( rwmap->rwm_rw,
363 fname, lineno, argc, argv );
365 #else /* !ENABLE_REWRITE */
366 fprintf( stderr, "%s: line %d: rewrite capabilities "
367 "are not enabled\n", fname, lineno );
368 #endif /* !ENABLE_REWRITE */
374 rwm_suffixmassage_config(
382 slap_overinst *on = (slap_overinst *) be->bd_info;
383 struct ldaprwmap *rwmap =
384 (struct ldaprwmap *)on->on_bi.bi_private;
386 struct berval bvnc, nvnc, pvnc, brnc, nrnc, prnc;
387 #ifdef ENABLE_REWRITE
389 #endif /* ENABLE_REWRITE */
394 * suffixmassage <suffix> <massaged suffix>
396 * the <suffix> field must be defined as a valid suffix
397 * (or suffixAlias?) for the current database;
398 * the <massaged suffix> shouldn't have already been
399 * defined as a valid suffix or suffixAlias for the
403 fprintf( stderr, "%s: line %d: syntax is"
404 " \"suffixMassage <suffix>"
405 " <massaged suffix>\"\n",
410 ber_str2bv( argv[1], 0, 0, &bvnc );
411 if ( dnPrettyNormal( NULL, &bvnc, &pvnc, &nvnc, NULL ) != LDAP_SUCCESS ) {
412 fprintf( stderr, "%s: line %d: suffix DN %s is invalid\n",
413 fname, lineno, bvnc.bv_val );
417 ber_str2bv( argv[2], 0, 0, &brnc );
418 if ( dnPrettyNormal( NULL, &brnc, &prnc, &nrnc, NULL ) != LDAP_SUCCESS ) {
419 fprintf( stderr, "%s: line %d: suffix DN %s is invalid\n",
420 fname, lineno, brnc.bv_val );
426 #ifdef ENABLE_REWRITE
428 * The suffix massaging is emulated
429 * by means of the rewrite capabilities
431 rc = rwm_suffix_massage_config( rwmap->rwm_rw,
432 &pvnc, &nvnc, &prnc, &nrnc );
440 #else /* !ENABLE_REWRITE */
441 ber_bvarray_add( &rwmap->rwm_suffix_massage, &pvnc );
442 ber_bvarray_add( &rwmap->rwm_suffix_massage, &nvnc );
444 ber_bvarray_add( &rwmap->rwm_suffix_massage, &prnc );
445 ber_bvarray_add( &rwmap->rwm_suffix_massage, &nrnc );
446 #endif /* !ENABLE_REWRITE */
460 slap_overinst *on = (slap_overinst *) be->bd_info;
461 struct ldaprwmap *rwmap =
462 (struct ldaprwmap *)on->on_bi.bi_private;
464 /* objectclass/attribute mapping */
465 return rwm_map_config( &rwmap->rwm_oc,
467 fname, lineno, argc, argv );
471 rwm_response( Operation *op, SlapReply *rs )
475 if ( op->o_tag == LDAP_REQ_SEARCH && rs->sr_type == REP_SEARCH ) {
476 return rwm_send_entry( op, rs );
479 switch( op->o_tag ) {
482 case LDAP_REQ_DELETE:
483 case LDAP_REQ_MODRDN:
484 case LDAP_REQ_MODIFY:
485 case LDAP_REQ_COMPARE:
486 case LDAP_REQ_SEARCH:
487 case LDAP_REQ_EXTENDED:
488 rc = rwm_matched( op, rs );
491 rc = SLAP_CB_CONTINUE;
509 if ( strncasecmp( argv[0], "rewrite", sizeof("rewrite") - 1) == 0 ) {
510 rc = rwm_rw_config( be, fname, lineno, argc, argv );
512 } else if (strcasecmp( argv[0], "map" ) == 0 ) {
513 rc = rwm_m_config( be, fname, lineno, argc, argv );
515 } else if (strcasecmp( argv[0], "suffixmassage" ) == 0 ) {
516 rc = rwm_suffixmassage_config( be, fname, lineno, argc, argv );
519 rc = SLAP_CONF_UNKNOWN;
530 slap_overinst *on = (slap_overinst *) be->bd_info;
531 struct ldapmapping *mapping = NULL;
532 struct ldaprwmap *rwmap;
534 rwmap = (struct ldaprwmap *)ch_malloc(sizeof(struct ldaprwmap));
535 memset(rwmap, 0, sizeof(struct ldaprwmap));
537 #ifdef ENABLE_REWRITE
538 rwmap->rwm_rw = rewrite_info_init( REWRITE_MODE_USE_DEFAULT );
539 if ( rwmap->rwm_rw == NULL ) {
543 #endif /* ENABLE_REWRITE */
545 rwm_map_init( &rwmap->rwm_oc, &mapping );
546 rwm_map_init( &rwmap->rwm_at, &mapping );
548 on->on_bi.bi_private = (void *)rwmap;
558 slap_overinst *on = (slap_overinst *) be->bd_info;
561 if ( on->on_bi.bi_private ) {
562 struct ldaprwmap *rwmap =
563 (struct ldaprwmap *)on->on_bi.bi_private;
565 #ifdef ENABLE_REWRITE
567 rewrite_info_delete( &rwmap->rwm_rw );
569 #else /* !ENABLE_REWRITE */
570 if ( rwmap->rwm_suffix_massage ) {
571 ber_bvarray_free( rwmap->rwm_suffix_massage );
573 #endif /* !ENABLE_REWRITE */
575 avl_free( rwmap->rwm_oc.remap, NULL );
576 avl_free( rwmap->rwm_oc.map, rwm_mapping_free );
577 avl_free( rwmap->rwm_at.remap, NULL );
578 avl_free( rwmap->rwm_at.map, rwm_mapping_free );
584 static slap_overinst rwm = { { NULL } };
589 memset( &rwm, 0, sizeof(slap_overinst) );
591 rwm.on_bi.bi_type = "rewrite-remap";
592 rwm.on_bi.bi_db_init = rwm_over_init;
593 rwm.on_bi.bi_db_config = rwm_config;
594 rwm.on_bi.bi_db_destroy = rwm_destroy;
596 rwm.on_bi.bi_op_bind = rwm_bind;
597 rwm.on_bi.bi_op_search = rwm_search;
598 rwm.on_bi.bi_op_compare = rwm_compare;
599 rwm.on_bi.bi_op_modify = rwm_modify;
600 rwm.on_bi.bi_op_modrdn = rwm_modrdn;
601 rwm.on_bi.bi_op_add = rwm_add;
602 rwm.on_bi.bi_op_delete = rwm_delete;
603 rwm.on_bi.bi_extended = rwm_extended;
605 rwm.on_response = rwm_response;
607 return overlay_register( &rwm );
610 #if SLAPD_OVER_RWM == SLAPD_MOD_DYNAMIC
611 int init_module(int argc, char *argv[]) {
616 #endif /* SLAPD_OVER_RWM */