From 61787df79b47300ce0ea5b1a242f42440bf2e532 Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Mon, 6 Aug 2007 23:22:19 +0000 Subject: [PATCH] add back-config support to back-relay --- doc/man/man5/slapd-relay.5 | 100 +++++------ servers/slapd/back-relay/Makefile.in | 4 +- servers/slapd/back-relay/config.c | 181 -------------------- servers/slapd/back-relay/init.c | 117 ++++++++++++- servers/slapd/back-relay/proto-back-relay.h | 1 - servers/slapd/bconfig.c | 1 + tests/data/slapd-relay.conf | 8 +- 7 files changed, 175 insertions(+), 237 deletions(-) delete mode 100644 servers/slapd/back-relay/config.c diff --git a/doc/man/man5/slapd-relay.5 b/doc/man/man5/slapd-relay.5 index 6723cc4bc8..b59d215c30 100644 --- a/doc/man/man5/slapd-relay.5 +++ b/doc/man/man5/slapd-relay.5 @@ -12,8 +12,8 @@ running in the same instance into a virtual naming context, with attributeType and objectClass manipulation, if required. It requires the -.B rwm -.BR overlay . +.BR slapo-rwm (5) +overlay. .LP This backend and the above mentioned overlay are experimental. .SH CONFIGURATION @@ -26,27 +26,30 @@ Other database options are described in the .BR slapd.conf (5) manual page; only the .B suffix -directive is required by the +directive is allowed by the .I relay backend. .TP -.B relay [massage] +.B relay The naming context of the database that is presented under a virtual naming context. The presence of this directive implies that one specific database, i.e. the one serving the .BR "real naming context" , will be presented under a virtual naming context. -This directive automatically instantiates the -.IR "rwm overlay" . -If the optional -.B massage -keyword is present, the suffix massaging is automatically -configured as well; otherwise, specific massaging instructions -are required by means of the -.I rewrite -directives described in -.BR slapo-rwm (5). + +.SH MASSAGING +The +.B relay +database does not automatically rewrite the naming context +of requests and responses. +For this purpose, the +.BR slapo-rwm (5) +overlay must be explicitly instantiated, and configured +as appropriate. +Usually, the +.B rwm-suffixmassage +directive suffices if only naming context rewriting is required. .SH ACCESS RULES One important issue is that access rules are based on the identity @@ -88,29 +91,26 @@ Another possibility is to map the same operation to different databases based on details of the virtual naming context, e.g. groups on one database and persons on another. .LP -.SH CAVEATS -The -.B rwm overlay -is experimental. -.LP .SH EXAMPLES To implement a plain virtual naming context mapping that refers to a single database, use .LP .nf - database relay - suffix "dc=virtual,dc=naming,dc=context" - relay "dc=real,dc=naming,dc=context" massage + database relay + suffix "dc=virtual,dc=naming,dc=context" + relay "dc=real,dc=naming,dc=context" + overlay rwm + rwm-suffixmassage "dc=real,dc=naming,dc=context" .fi .LP To implement a plain virtual naming context mapping that looks up the real naming context for each operation, use .LP .nf - database relay - suffix "dc=virtual,dc=naming,dc=context" - overlay rwm - suffixmassage "dc=real,dc=naming,dc=context" + database relay + suffix "dc=virtual,dc=naming,dc=context" + overlay rwm + rwm-suffixmassage "dc=real,dc=naming,dc=context" .fi .LP This is useful, for instance, to relay different databases that @@ -122,39 +122,43 @@ the virtual to the real naming context, but not the results back from the real to the virtual naming context, use .LP .nf - database relay - suffix "dc=virtual,dc=naming,dc=context" - relay "dc=real,dc=naming,dc=context" - rewriteEngine on - rewriteContext default - rewriteRule "dc=virtual,dc=naming,dc=context" - "dc=real,dc=naming,dc=context" ":@" - rewriteContext searchFilter - rewriteContext searchEntryDN - rewriteContext searchAttrDN - rewriteContext matchedDN + database relay + suffix "dc=virtual,dc=naming,dc=context" + relay "dc=real,dc=naming,dc=context" + overlay rwm + rwm-rewriteEngine on + rwm-rewriteContext default + rwm-rewriteRule "dc=virtual,dc=naming,dc=context" + "dc=real,dc=naming,dc=context" ":@" + rwm-rewriteContext searchFilter + rwm-rewriteContext searchEntryDN + rwm-rewriteContext searchAttrDN + rwm-rewriteContext matchedDN .fi .LP -Note that the virtual database is bound to a single real database, -so the -.B rwm overlay -is automatically instantiated, but the rewrite rules -are written explicitly to map all the virtual to real -naming context data flow, but none of the real to virtual. +Note that the +.BR slapo-rwm (5) +overlay is instantiated, but the rewrite rules are written explicitly, +rather than automatically as with the +.B rwm-suffixmassage +statement, to map all the virtual to real naming context data flow, +but none of the real to virtual. .LP Access rules: .LP .nf - database bdb - suffix "dc=example,dc=com" + database bdb + suffix "dc=example,dc=com" # skip... access to dn.subtree="dc=example,dc=com" by dn.exact="cn=Supervisor,dc=example,dc=com" write by * read - database relay - suffix "o=Example,c=US" - relay "dc=example,dc=com" massage + database relay + suffix "o=Example,c=US" + relay "dc=example,dc=com" + overlay rwm + rwm-suffixmassage "dc=example,dc=com" # skip ... access to dn.subtree="o=Example,c=US" by dn.exact="cn=Supervisor,dc=example,dc=com" write diff --git a/servers/slapd/back-relay/Makefile.in b/servers/slapd/back-relay/Makefile.in index 6ef139cbaf..75a6a81eff 100644 --- a/servers/slapd/back-relay/Makefile.in +++ b/servers/slapd/back-relay/Makefile.in @@ -13,8 +13,8 @@ ## top-level directory of the distribution or, alternatively, at ## . -SRCS = init.c config.c op.c -OBJS = init.lo config.lo op.lo +SRCS = init.c op.c +OBJS = init.lo op.lo LDAP_INCDIR= ../../../include LDAP_LIBDIR= ../../../libraries diff --git a/servers/slapd/back-relay/config.c b/servers/slapd/back-relay/config.c deleted file mode 100644 index ce471af234..0000000000 --- a/servers/slapd/back-relay/config.c +++ /dev/null @@ -1,181 +0,0 @@ -/* config.c - relay backend configuration file routine */ -/* This work is part of OpenLDAP Software . - * - * Copyright 2004-2007 The OpenLDAP Foundation. - * Portions Copyright 2004 Pierangelo Masarati. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted only as authorized by the OpenLDAP - * Public License. - * - * A copy of this license is available in the file LICENSE in the - * top-level directory of the distribution or, alternatively, at - * . - */ -/* ACKNOWLEDGEMENTS: - * This work was initially developed by Pierangelo Masaratifor inclusion - * in OpenLDAP Software. - */ - -#include "portable.h" - -#include - -#include "slap.h" -#include "back-relay.h" - -int -relay_back_db_config( - BackendDB *be, - const char *fname, - int lineno, - int argc, - char **argv ) -{ - relay_back_info *ri = (struct relay_back_info *)be->be_private; - - if ( ri == NULL ) { - Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR, - "%s: line %d: relay backend info is null.\n", - fname, lineno ); - return 1; - } - - /* real naming context */ - if ( strcasecmp( argv[ 0 ], "relay" ) == 0 ) { - struct berval dn, ndn, pdn; - int rc; - BackendDB *bd; - - if ( !BER_BVISNULL( &ri->ri_realsuffix ) ) { - Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR, - "%s: line %d: " - "relay dn already specified.\n", - fname, lineno ); - return 1; - } - - switch ( argc ) { - case 3: - if ( strcmp( argv[ 2 ], "massage" ) != 0 ) { - Log3( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR, - "%s: line %d: " - "unknown arg[#2]=\"%s\" " - "in \"relay [massage]\" line\n", - fname, lineno, argv[ 2 ] ); - return 1; - } - - if ( be->be_nsuffix == NULL ) { - Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR, - "%s: line %d: " - "\"relay\" directive " - "must appear after \"suffix\".\n", - fname, lineno ); - return 1; - } - - if ( !BER_BVISNULL( &be->be_nsuffix[ 1 ] ) ) { - Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR, - "%s: line %d: " - "relaying of multiple suffix " - "database not supported.\n", - fname, lineno ); - return 1; - } - /* fallthru */ - - case 2: - break; - - case 1: - Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR, - "%s: line %d: missing relay suffix " - "in \"relay [massage]\" line.\n", - fname, lineno ); - return 1; - - default: - Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR, - "%s: line %d: extra cruft " - "in \"relay [massage]\" line.\n", - fname, lineno ); - return 1; - } - - /* The man page says that the "relay" directive - * automatically instantiates slapo-rwm; I don't - * like this very much any more, I'd prefer to - * have automatic instantiation only when "massage" - * is specified, so one has better control on - * where the overlay gets instantiated, but this - * would break compatibility. One can still control - * where the overlay is instantiated by moving - * around the "relay" directive, although this could - * make slapd.conf a bit confusing. */ - if ( overlay_config( be, "rwm", -1, NULL ) ) { - Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR, - "%s: line %d: unable to install " - "rwm overlay " - "in \"relay [massage]\" line\n", - fname, lineno ); - return 1; - } - - dn.bv_val = argv[ 1 ]; - dn.bv_len = strlen( argv[ 1 ] ); - rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn, NULL ); - if ( rc != LDAP_SUCCESS ) { - Log3( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR, - "%s: line %d: " - "relay dn \"%s\" is invalid " - "in \"relay [massage]\" line\n", - fname, lineno, argv[ 1 ] ); - return 1; - } - - bd = select_backend( &ndn, 1 ); - if ( bd == NULL ) { - Log3( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR, - "%s: line %d: " - "cannot find database " - "of relay dn \"%s\" " - "in \"relay [massage]\" line\n", - fname, lineno, argv[ 1 ] ); - rc = 1; - goto relay_done; - - } else if ( bd->be_private == be->be_private ) { - Log3( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR, - "%s: line %d: " - "relay dn \"%s\" would call self " - "in \"relay [massage]\" line\n", - fname, lineno, pdn.bv_val ); - rc = 1; - goto relay_done; - } - - ri->ri_realsuffix = ndn; - - if ( argc == 3 ) { - char *cargv[ 4 ]; - - cargv[ 0 ] = "rwm-suffixmassage"; - cargv[ 1 ] = be->be_suffix[0].bv_val; - cargv[ 2 ] = pdn.bv_val; - cargv[ 3 ] = NULL; - - rc = be->be_config( be, fname, lineno, 3, cargv ); - } - -relay_done:; - ch_free( pdn.bv_val ); - - return rc; - } - - /* anything else */ - return SLAP_CONF_UNKNOWN; -} - diff --git a/servers/slapd/back-relay/init.c b/servers/slapd/back-relay/init.c index fa4af71085..f5c4241013 100644 --- a/servers/slapd/back-relay/init.c +++ b/servers/slapd/back-relay/init.c @@ -27,6 +27,113 @@ #include "config.h" #include "back-relay.h" +static ConfigDriver relay_back_cf; + +static ConfigTable relaycfg[] = { + { "relay", "relay", 2, 2, 0, + ARG_MAGIC|ARG_DN, + relay_back_cf, "( OLcfgDbAt:5.1 " + "NAME 'olcRelay' " + "DESC 'Relay DN' " + "SYNTAX OMsDN " + "SINGLE-VALUE )", + NULL, NULL }, + { NULL } +}; + +static ConfigOCs relayocs[] = { + { "( OLcfgDbOc:5.1 " + "NAME 'olcRelayConfig' " + "DESC 'Relay backend configuration' " + "SUP olcDatabaseConfig " + "MAY ( olcRelay " + ") )", + Cft_Database, relaycfg}, + { NULL, 0, NULL } +}; + +static int +relay_back_cf( ConfigArgs *c ) +{ + relay_back_info *ri = ( relay_back_info * )c->be->be_private; + int rc = 0; + + if ( c->op == SLAP_CONFIG_EMIT ) { + if ( ri != NULL && !BER_BVISNULL( &ri->ri_realsuffix ) ) { + value_add_one( &c->rvalue_vals, &ri->ri_realsuffix ); + return 0; + } + return 1; + + } else if ( c->op == LDAP_MOD_DELETE ) { + if ( !BER_BVISNULL( &ri->ri_realsuffix ) ) { + ch_free( ri->ri_realsuffix.bv_val ); + BER_BVZERO( &ri->ri_realsuffix ); + ri->ri_bd = NULL; + return 0; + } + return 1; + + } else { + BackendDB *bd; + + assert( ri != NULL ); + assert( BER_BVISNULL( &ri->ri_realsuffix ) ); + + if ( c->be->be_nsuffix == NULL ) { + snprintf( c->cr_msg, sizeof( c->cr_msg), + "\"relay\" directive " + "must appear after \"suffix\"" ); + Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR, + "%s: %s.\n", c->log, c->cr_msg ); + rc = 1; + goto relay_done; + } + + if ( !BER_BVISNULL( &c->be->be_nsuffix[ 1 ] ) ) { + snprintf( c->cr_msg, sizeof( c->cr_msg), + "relaying of multiple suffix " + "database not supported" ); + Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR, + "%s: %s.\n", c->log, c->cr_msg ); + rc = 1; + goto relay_done; + } + + bd = select_backend( &c->value_ndn, 1 ); + if ( bd == NULL ) { + snprintf( c->cr_msg, sizeof( c->cr_msg), + "cannot find database " + "of relay dn \"%s\" " + "in \"olcRelay \"\n", + c->value_dn.bv_val ); + Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR, + "%s: %s.\n", c->log, c->cr_msg ); + rc = 1; + goto relay_done; + + } else if ( bd->be_private == c->be->be_private ) { + snprintf( c->cr_msg, sizeof( c->cr_msg), + "relay dn \"%s\" would call self " + "in \"relay \" line\n", + c->value_dn.bv_val ); + Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR, + "%s: %s.\n", c->log, c->cr_msg ); + rc = 1; + goto relay_done; + } + + ri->ri_realsuffix = c->value_ndn; + BER_BVZERO( &c->value_ndn ); + +relay_done:; + ch_free( c->value_dn.bv_val ); + ch_free( c->value_ndn.bv_val ); + } + + return rc; +} + int relay_back_initialize( BackendInfo *bi ) { @@ -37,10 +144,10 @@ relay_back_initialize( BackendInfo *bi ) bi->bi_destroy = 0; bi->bi_db_init = relay_back_db_init; - bi->bi_db_config = relay_back_db_config; + bi->bi_db_config = config_generic_wrapper; bi->bi_db_open = relay_back_db_open; #if 0 - bi->bi_db_close =relay_back_db_close; + bi->bi_db_close = relay_back_db_close; #endif bi->bi_db_destroy = relay_back_db_destroy; @@ -66,7 +173,9 @@ relay_back_initialize( BackendInfo *bi ) bi->bi_connection_init = relay_back_connection_init; bi->bi_connection_destroy = relay_back_connection_destroy; - return 0; + bi->bi_cf_ocs = relayocs; + + return config_register_schema( relaycfg, relayocs ); } int @@ -85,6 +194,8 @@ relay_back_db_init( Backend *be, ConfigReply *cr) BER_BVZERO( &ri->ri_realsuffix ); ri->ri_massage = 0; + be->be_cf_ocs = be->bd_info->bi_cf_ocs; + be->be_private = (void *)ri; return 0; diff --git a/servers/slapd/back-relay/proto-back-relay.h b/servers/slapd/back-relay/proto-back-relay.h index 97ba1c5564..c3945e3145 100644 --- a/servers/slapd/back-relay/proto-back-relay.h +++ b/servers/slapd/back-relay/proto-back-relay.h @@ -27,7 +27,6 @@ LDAP_BEGIN_DECL extern BI_init relay_back_initialize; extern BI_db_init relay_back_db_init; -extern BI_db_config relay_back_db_config; extern BI_db_open relay_back_db_open; extern BI_db_close relay_back_db_close; extern BI_db_destroy relay_back_db_destroy; diff --git a/servers/slapd/bconfig.c b/servers/slapd/bconfig.c index 61d44b6758..d5464fc335 100644 --- a/servers/slapd/bconfig.c +++ b/servers/slapd/bconfig.c @@ -222,6 +222,7 @@ static OidRec OidMacros[] = { * OLcfg{Bk|Db}{Oc|At}:2 -> back-ldif * OLcfg{Bk|Db}{Oc|At}:3 -> back-ldap * OLcfg{Bk|Db}{Oc|At}:4 -> back-monitor + * OLcfg{Bk|Db}{Oc|At}:5 -> back-relay */ /* diff --git a/tests/data/slapd-relay.conf b/tests/data/slapd-relay.conf index fdcef70b66..e7ec3e17aa 100644 --- a/tests/data/slapd-relay.conf +++ b/tests/data/slapd-relay.conf @@ -50,7 +50,9 @@ rootpw secret database @RELAY@ suffix "o=Example,c=US" ### back-relay can automatically instantiate the rwm overlay -#relay-relay#relay "dc=example,dc=com" massage +#relay-relay#relay "dc=example,dc=com" +#relay-relay#overlay rwm +#relay-relay#rwm-suffixmassage "dc=example,dc=com" #relay-relay#rwm-map objectClass groupOfNames groupOfUniqueNames #relay-relay#rwm-map objectClass uidObject dcObject #relay-relay#rwm-map attribute member uniqueMember @@ -86,7 +88,9 @@ suffix "o=Esempio,c=IT" database @RELAY@ suffix "o=Beispiel,c=DE" ### back-relay can automatically instantiate the rwm overlay -#relay-relay#relay "dc=example,dc=com" massage +#relay-relay#relay "dc=example,dc=com" +#relay-relay#overlay rwm +#relay-relay#rwm-suffixmassage "dc=example,dc=com" ### back-ldap needs explicit instantiation of the rwm overlay #relay-ldap#uri "@URI1@" #relay-ldap#overlay rwm -- 2.39.5