-Relay backend automatically sets up a rewrite-remap overlay that maps
-the virtual naming context to a real naming context that is available
-in the same server
+Relay backend sets up a relay virtual database that allows
+to access other databases in the same instance of slapd
+through different naming contexts and remapping attribute
+values.
+
+The DN rewrite, filter rewrite and attributeType/objectClass
+mapping is done by means of the rewrite-remap overlay.
+
+The database containing the real naming context can be
+explicitly selected by means of the "relay" directive,
+which must contain the naming context of the target
+database. This also causes the rewrite-remap overlay
+to be automatically instantiated. If the optional keyword
+"massage" is present, the rewrite-remap overlay is
+automatically configured to map the virtual to the real
+naming context and vice-versa; in this case, the "suffix"
+directive must precede the "relay" directive.
+
+Otherwise, the rewrite-remap overlay must be explicitly
+instantiated, by using the "overlay" directive, as
+illustrated below. This allows much more freedom in target
+database selection and DN rewriting.
+
+If the "relay" directive is not present, the backend is
+not bound to a single target database; on the contrary,
+the target database is selected on a per-operation basis.
+
+This allows, for instance, to relay one database for
+authentication and anothe for search/modify, or allows
+to use one target for persons and another for groups
+and so on.
# automatically massage from virtual to real naming context
database relay
suffix "dc=virtual,dc=naming,dc=context"
-relay "dc=real,dc=naming,dc=context"
+relay "dc=real,dc=naming,dc=context" massage
-# explicitly massage
+# explicitly massage (same as above)
database relay
suffix "dc=virtual,dc=naming,dc=context"
overlay rewrite-remap
-suffixmassage "dc=virtual,dc=naming,dc=context" "dc=real,dc=naming,dc=context"
+suffixmassage "dc=virtual,dc=naming,dc=context" \
+ "dc=real,dc=naming,dc=context"
-# old fashioned suffixalias...
+# old fashioned suffixalias, applied also to DN-valued attributes
+# from virtual to real naming context, but not the reverse...
database relay
suffix "dc=virtual,dc=naming,dc=context"
overlay rewrite-remap
rewriteEngine on
rewriteContext default
rewriteRule "(.*)dc=virtual,dc=naming,dc=context$" \
- "\1dc=real,dc=naming,dc=context"
+ "$1dc=real,dc=naming,dc=context"
#include <stdio.h>
-#include <ac/string.h>
-#include <ac/socket.h>
-
#include "slap.h"
#include "back-relay.h"
-#include "lutil.h"
int
relay_back_db_config(
if ( ri == NULL ) {
fprintf( stderr, "%s: line %d: relay backend info is null!\n",
fname, lineno );
- return( 1 );
+ return 1;
}
/* real naming context */
if ( strcasecmp( argv[0], "relay" ) == 0 ) {
struct berval dn, ndn, pdn;
int rc;
- char *cargv[ 4 ];
- if (argc != 2) {
+ if ( argc < 2 ) {
+ fprintf( stderr,
+ "%s: line %d: missing relay suffix in \"relay <dn> [massage]\" line\n",
+ fname, lineno );
+ return 1;
+
+ } else if ( argc > 3 ) {
fprintf( stderr,
- "%s: line %d: missing relay suffix in \"relay <dn>\" line\n",
+ "%s: line %d: too many args in \"relay <dn> [massage]\" line\n",
fname, lineno );
- return( 1 );
+ return 1;
}
dn.bv_val = argv[ 1 ];
}
if ( overlay_config( be, "rewrite-remap" ) ) {
- fprintf( stderr, "unable to install "
+ fprintf( stderr, "%s: line %d: unable to install "
"rewrite-remap overlay "
- "in back-relay \"%s\" => \"%s\"\n",
- be->be_suffix[0].bv_val,
- ri->ri_bd->be_suffix[0].bv_val ?
- ri->ri_bd->be_suffix[0].bv_val : "<unknown>" );
+ "in back-relay\n",
+ fname, lineno );
return 1;
}
- cargv[ 0 ] = "suffixmassage";
- cargv[ 1 ] = be->be_suffix[0].bv_val;
- cargv[ 2 ] = ri->ri_bd->be_suffix[0].bv_val;
- cargv[ 3 ] = NULL;
-
- if ( be->be_config( be, "back-relay", 1, 3, cargv ) ) {
- return 1;
+ if ( argc == 3 ) {
+ char *cargv[ 4 ];
+
+ if ( strcmp( argv[2], "massage" ) ) {
+ fprintf( stderr, "%s: line %d: "
+ "unknown directive \"%s\" "
+ "in \"relay <dn> [massage]\" line\n",
+ fname, lineno, argv[2] );
+ return 1;
+ }
+
+ if ( be->be_suffix[0].bv_val == NULL ) {
+ fprintf( stderr, "%s: line %d: "
+ "relay line must come after \"suffix\"\n",
+ fname, lineno );
+ return 1;
+ }
+
+ cargv[ 0 ] = "suffixmassage";
+ cargv[ 1 ] = be->be_suffix[0].bv_val;
+ cargv[ 2 ] = ri->ri_bd->be_suffix[0].bv_val;
+ cargv[ 3 ] = NULL;
+
+ if ( be->be_config( be, "back-relay", 1, 3, cargv ) ) {
+ return 1;
+ }
}
/* anything else */
#include <stdio.h>
-#include <ac/string.h>
-#include <ac/socket.h>
-
#include "slap.h"
#include "back-relay.h"
#include <stdio.h>
-#include <ac/string.h>
-#include <ac/socket.h>
-
#include "slap.h"
#include "back-relay.h"
if ( bd && bd->be_unbind ) {
BackendDB *be = op->o_bd;
+ slap_callback cb;
+
+ cb.sc_next = op->o_callback;
+ cb.sc_response = relay_back_swap_bd;
+ cb.sc_cleanup = relay_back_swap_bd;
+ cb.sc_private = op->o_bd;
+ op->o_callback = &cb;
op->o_bd = bd;
rc = ( bd->be_unbind )( op, rs );
if ( bd->be_compare ) {
BackendDB *be = op->o_bd;
+ slap_callback cb;
+
+ cb.sc_next = op->o_callback;
+ cb.sc_response = relay_back_swap_bd;
+ cb.sc_cleanup = relay_back_swap_bd;
+ cb.sc_private = op->o_bd;
+ op->o_callback = &cb;
op->o_bd = bd;
rc = ( bd->be_compare )( op, rs );
if ( bd->be_modify ) {
BackendDB *be = op->o_bd;
+ slap_callback cb;
+
+ cb.sc_next = op->o_callback;
+ cb.sc_response = relay_back_swap_bd;
+ cb.sc_cleanup = relay_back_swap_bd;
+ cb.sc_private = op->o_bd;
+ op->o_callback = &cb;
op->o_bd = bd;
rc = ( bd->be_modify )( op, rs );
if ( bd->be_modrdn ) {
BackendDB *be = op->o_bd;
+ slap_callback cb;
+
+ cb.sc_next = op->o_callback;
+ cb.sc_response = relay_back_swap_bd;
+ cb.sc_cleanup = relay_back_swap_bd;
+ cb.sc_private = op->o_bd;
+ op->o_callback = &cb;
op->o_bd = bd;
rc = ( bd->be_modrdn )( op, rs );
if ( bd->be_add ) {
BackendDB *be = op->o_bd;
+ slap_callback cb;
+
+ cb.sc_next = op->o_callback;
+ cb.sc_response = relay_back_swap_bd;
+ cb.sc_cleanup = relay_back_swap_bd;
+ cb.sc_private = op->o_bd;
+ op->o_callback = &cb;
op->o_bd = bd;
rc = ( bd->be_add )( op, rs );
if ( bd->be_delete ) {
BackendDB *be = op->o_bd;
+ slap_callback cb;
+
+ cb.sc_next = op->o_callback;
+ cb.sc_response = relay_back_swap_bd;
+ cb.sc_cleanup = relay_back_swap_bd;
+ cb.sc_private = op->o_bd;
+ op->o_callback = &cb;
op->o_bd = bd;
rc = ( bd->be_delete )( op, rs );
if ( bd->be_abandon ) {
BackendDB *be = op->o_bd;
+ slap_callback cb;
+
+ cb.sc_next = op->o_callback;
+ cb.sc_response = relay_back_swap_bd;
+ cb.sc_cleanup = relay_back_swap_bd;
+ cb.sc_private = op->o_bd;
+ op->o_callback = &cb;
op->o_bd = bd;
rc = ( bd->be_abandon )( op, rs );
if ( bd->be_cancel ) {
BackendDB *be = op->o_bd;
+ slap_callback cb;
+
+ cb.sc_next = op->o_callback;
+ cb.sc_response = relay_back_swap_bd;
+ cb.sc_cleanup = relay_back_swap_bd;
+ cb.sc_private = op->o_bd;
+ op->o_callback = &cb;
op->o_bd = bd;
rc = ( bd->be_cancel )( op, rs );
if ( bd->be_extended ) {
BackendDB *be = op->o_bd;
+ slap_callback cb;
+
+ cb.sc_next = op->o_callback;
+ cb.sc_response = relay_back_swap_bd;
+ cb.sc_cleanup = relay_back_swap_bd;
+ cb.sc_private = op->o_bd;
+ op->o_callback = &cb;
op->o_bd = bd;
rc = ( bd->be_extended )( op, rs );
if ( bd->be_chk_referrals ) {
BackendDB *be = op->o_bd;
+ slap_callback cb;
+
+ cb.sc_next = op->o_callback;
+ cb.sc_response = relay_back_swap_bd;
+ cb.sc_cleanup = relay_back_swap_bd;
+ cb.sc_private = op->o_bd;
+ op->o_callback = &cb;
op->o_bd = bd;
rc = ( bd->be_chk_referrals )( op, rs );