mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-02-23 14:09:39 +08:00
add back-config support to back-relay
This commit is contained in:
parent
22bda833ec
commit
61787df79b
@ -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 <real naming context> [massage]
|
||||
.B relay <real naming context>
|
||||
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
|
||||
|
@ -13,8 +13,8 @@
|
||||
## top-level directory of the distribution or, alternatively, at
|
||||
## <http://www.OpenLDAP.org/license.html>.
|
||||
|
||||
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
|
||||
|
@ -1,181 +0,0 @@
|
||||
/* config.c - relay backend configuration file routine */
|
||||
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
|
||||
*
|
||||
* 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
|
||||
* <http://www.OpenLDAP.org/license.html>.
|
||||
*/
|
||||
/* ACKNOWLEDGEMENTS:
|
||||
* This work was initially developed by Pierangelo Masaratifor inclusion
|
||||
* in OpenLDAP Software.
|
||||
*/
|
||||
|
||||
#include "portable.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#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 <dn> [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 <dn> [massage]\" line.\n",
|
||||
fname, lineno );
|
||||
return 1;
|
||||
|
||||
default:
|
||||
Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR,
|
||||
"%s: line %d: extra cruft "
|
||||
"in \"relay <dn> [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 <dn> [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 <dn> [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 <dn> [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 <dn> [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;
|
||||
}
|
||||
|
@ -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 <dn>\"\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 <dn>\" 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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user