dnl SLAPD Overlay Options
AC_ARG_WITH(xxslapoverlays,[
SLAPD Overlay Options:])
+OL_ARG_WITH(chain,[ --with-chain LDAP Chain Response no|yes|mod], no,
+ [no yes mod])
+OL_ARG_WITH(denyop,[ --with-denyop Deny Operation overlay no|yes|mod], no,
+ [no yes mod])
OL_ARG_WITH(dyngroup,[ --with-dyngroup Dynamic Group overlay no|yes|mod], no,
[no yes mod])
OL_ARG_WITH(proxycache,[ --with-proxycache Proxy Cache overlay no|yes|mod], no,
if test $ol_enable_rewrite = yes ; then
AC_MSG_WARN([slapd disabled, ignoring --enable-rewrite argument])
fi
+ dnl overlays
+ if test $ol_with_chain != no ; then
+ AC_MSG_WARN([slapd disabled, ignoring --with-chain argument])
+ fi
+ if test $ol_with_denyop != no ; then
+ AC_MSG_WARN([slapd disabled, ignoring --with-denyop argument])
+ fi
if test $ol_with_dyngroup != no ; then
AC_MSG_WARN([slapd disabled, ignoring --with-dyngroup argument])
fi
ol_enable_rewrite=no
+ ol_with_chain=no
+ ol_with_denyop=no
ol_with_dyngroup=no
ol_with_proxycache=no
ol_with_rwm=no
BUILD_SHELL_DYNAMIC=static
BUILD_SQL_DYNAMIC=static
+BUILD_CHAIN=no
+BUILD_DENYOP=no
BUILD_DYNGROUP=no
BUILD_PROXYCACHE=no
BUILD_RWM=no
ol_with_relay_module=static
ol_with_shell_module=static
ol_with_sql_module=static
+ if test $ol_with_chain = mod ; then
+ AC_MSG_WARN([building static chain overlay])
+ ol_with_chain=yes
+ fi
+ if test $ol_with_denyop = mod ; then
+ AC_MSG_WARN([building static denyop overlay])
+ ol_with_denyop=yes
+ fi
if test $ol_with_dyngroup = mod ; then
AC_MSG_WARN([building static dyngroup overlay])
ol_with_dyngroup=yes
fi
fi
+if test "$ol_with_chain" != no ; then
+ BUILD_CHAIN=$ol_with_chain
+ if test "$ol_with_chain" = mod ; then
+ MFLAG=SLAPD_MOD_DYNAMIC
+ SLAPD_DYNAMIC_OVERLAYS="$SLAPD_DYNAMIC_OVERLAYS chain.la"
+ else
+ MFLAG=SLAPD_MOD_STATIC
+ fi
+ AC_DEFINE_UNQUOTED(SLAPD_OVER_CHAIN,$MFLAG,[define for Dynamic Group overlay])
+fi
+
+if test "$ol_with_denyop" != no ; then
+ BUILD_DENYOP=$ol_with_denyop
+ if test "$ol_with_denyop" = mod ; then
+ MFLAG=SLAPD_MOD_DYNAMIC
+ SLAPD_DYNAMIC_OVERLAYS="$SLAPD_DYNAMIC_OVERLAYS denyop.la"
+ else
+ MFLAG=SLAPD_MOD_STATIC
+ fi
+ AC_DEFINE_UNQUOTED(SLAPD_OVER_DENYOP,$MFLAG,[define for Dynamic Group overlay])
+fi
+
if test "$ol_with_dyngroup" != no ; then
BUILD_DYNGROUP=$ol_with_dyngroup
if test "$ol_with_dyngroup" = mod ; then
AC_SUBST(BUILD_LIBS_DYNAMIC)
AC_SUBST(BUILD_SLAPD)
+dnl slapi
AC_SUBST(BUILD_SLAPI)
AC_SUBST(SLAPD_SLAPI_DEPEND)
+dnl backends
AC_SUBST(BUILD_BDB)
AC_SUBST(BUILD_DNSSRV)
AC_SUBST(BUILD_HDB)
AC_SUBST(BUILD_PERL)
AC_SUBST(BUILD_SHELL)
AC_SUBST(BUILD_SQL)
+dnl backend modules
AC_SUBST(BUILD_BDB_DYNAMIC)
AC_SUBST(BUILD_DNSSRV_DYNAMIC)
AC_SUBST(BUILD_HDB_DYNAMIC)
AC_SUBST(BUILD_RELAY_DYNAMIC)
AC_SUBST(BUILD_SHELL_DYNAMIC)
AC_SUBST(BUILD_SQL_DYNAMIC)
+dnl overlays
+ AC_SUBST(BUILD_CHAIN)
+ AC_SUBST(BUILD_DENYOP)
AC_SUBST(BUILD_DYNGROUP)
AC_SUBST(BUILD_PROXYCACHE)
AC_SUBST(BUILD_RWM)
instance into a virtual naming context, with attributeType
and objectClass manipulation, if required.
It requires the
-.B rewrite-remap
+.B rwm
.BR overlay .
.LP
This backend and the above mentioned overlay are experimental.
The presence of the directive implies that one single database
will be presented under a virtual naming context.
This directive automatically instantiates the
-.B rewrite-remap
+.B rwm
.BR overlay .
If the optional
.B massage
.LP
.SH Caveats
The
-.B rewrite-remap overlay
+.B rwm overlay
is far from complete.
.LP
.SH EXAMPLES
.nf
database relay
suffix "dc=virtual,dc=naming,dc=context"
- overlay rewrite-remap
+ overlay rwm
suffixmassage "dc=virtual,dc=naming,dc=context"
"dc=real,dc=naming,dc=context"
.fi
.LP
Note that the virtual database is bound to a single real database,
so the
-.B rewrite-remap overlay
+.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.
SRCS = init.c config.c search.c bind.c unbind.c add.c compare.c \
delete.c modify.c modrdn.c \
- suffixmassage.c map.c extended.c chain.c
+ suffixmassage.c map.c extended.c
OBJS = init.lo config.lo search.lo bind.lo unbind.lo add.lo compare.lo \
delete.lo modify.lo modrdn.lo \
- suffixmassage.lo map.lo extended.lo chain.lo
+ suffixmassage.lo map.lo extended.lo
LDAP_INCDIR= ../../../include
LDAP_LIBDIR= ../../../libraries
extern int ldap_dnattr_rewrite( dncookie *dc, BerVarray a_vals );
extern int ldap_dnattr_result_rewrite( dncookie *dc, BerVarray a_vals );
-extern int ldap_chain_setup();
-
#ifdef LDAP_BACK_PROXY_AUTHZ
extern int
ldap_back_proxy_authz_ctrl(
+++ /dev/null
-/* chain.c - chain LDAP operations */
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 2003-2004 The OpenLDAP Foundation.
- * Portions Copyright 2003 Howard Chu.
- * 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 the Howard Chu for inclusion
- * in OpenLDAP Software.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/string.h>
-#include <ac/socket.h>
-
-#include "slap.h"
-#include "back-ldap.h"
-
-static int
-ldap_chain_response( Operation *op, SlapReply *rs )
-{
- slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
- void *private = op->o_bd->be_private;
- slap_callback *sc = op->o_callback;
- LDAPControl **prev = op->o_ctrls;
- LDAPControl **ctrls = NULL, authz;
- int i, nctrls, rc;
- int cache = op->o_do_not_cache;
- char *authzid = NULL;
- BerVarray ref;
- struct berval ndn = op->o_ndn;
-
- if ( rs->sr_err != LDAP_REFERRAL )
- return SLAP_CB_CONTINUE;
-
- /* currently we assume only one referral destination.
- * we'll have to parse this in the future.
- */
- ref = rs->sr_ref;
- rs->sr_ref = NULL;
-
- op->o_bd->be_private = on->on_bi.bi_private;
- op->o_callback = NULL;
-
- /* Chaining is performed by a privileged user on behalf
- * of a normal user, using the ProxyAuthz control. However,
- * Binds are done separately, on an anonymous session.
- */
- if ( op->o_tag != LDAP_REQ_BIND ) {
- for (i=0; prev && prev[i]; i++);
- nctrls = i;
-
- /* Add an extra NULL slot */
- if (!prev) i++;
-
- ctrls = op->o_tmpalloc((i+1)*sizeof(LDAPControl *),
- op->o_tmpmemctx);
- for (i=0; i <nctrls; i++)
- ctrls[i] = prev[i];
- ctrls[nctrls] = &authz;
- ctrls[nctrls+1] = NULL;
- authz.ldctl_oid = LDAP_CONTROL_PROXY_AUTHZ;
- authz.ldctl_iscritical = 1;
- authz.ldctl_value = op->o_dn;
- if ( op->o_dn.bv_len ) {
- authzid = op->o_tmpalloc( op->o_dn.bv_len+4,
- op->o_tmpmemctx );
- strcpy(authzid, "dn: ");
- strcpy(authzid+4, op->o_dn.bv_val);
- authz.ldctl_value.bv_len = op->o_dn.bv_len + 4;
- authz.ldctl_value.bv_val = authzid;
- }
- op->o_ctrls = ctrls;
- op->o_ndn = op->o_bd->be_rootndn;
- }
-
- switch( op->o_tag ) {
- case LDAP_REQ_BIND: {
- struct berval rndn = op->o_req_ndn;
- Connection *conn = op->o_conn;
- op->o_req_ndn = slap_empty_bv;
- op->o_conn = NULL;
- rc = ldap_back_bind( op, rs );
- op->o_req_ndn = rndn;
- op->o_conn = conn;
- }
- break;
- case LDAP_REQ_ADD:
- rc = ldap_back_add( op, rs );
- break;
- case LDAP_REQ_DELETE:
- rc = ldap_back_delete( op, rs );
- break;
- case LDAP_REQ_MODRDN:
- rc = ldap_back_modrdn( op, rs );
- break;
- case LDAP_REQ_MODIFY:
- rc = ldap_back_modify( op, rs );
- break;
- case LDAP_REQ_COMPARE:
- rc = ldap_back_compare( op, rs );
- break;
- case LDAP_REQ_SEARCH:
- rc = ldap_back_search( op, rs );
- break;
- case LDAP_REQ_EXTENDED:
- rc = ldap_back_extended( op, rs );
- break;
- default:
- rc = SLAP_CB_CONTINUE;
- break;
- }
- op->o_do_not_cache = cache;
- op->o_ctrls = prev;
- op->o_bd->be_private = private;
- op->o_callback = sc;
- op->o_ndn = ndn;
- if ( ctrls ) op->o_tmpfree( ctrls, op->o_tmpmemctx );
- if ( authzid ) op->o_tmpfree( authzid, op->o_tmpmemctx );
- rs->sr_ref = ref;
-
- return rc;
-}
-
-static int ldap_chain_config(
- BackendDB *be,
- const char *fname,
- int lineno,
- int argc,
- char **argv
-)
-{
- slap_overinst *on = (slap_overinst *) be->bd_info;
- void *private = be->be_private;
- int rc;
-
- be->be_private = on->on_bi.bi_private;
- rc = ldap_back_db_config( be, fname, lineno, argc, argv );
- be->be_private = private;
- return rc;
-}
-
-static int ldap_chain_init(
- BackendDB *be
-)
-{
- slap_overinst *on = (slap_overinst *) be->bd_info;
- void *private = be->be_private;
- int rc;
-
- be->be_private = NULL;
- rc = ldap_back_db_init( be );
- on->on_bi.bi_private = be->be_private;
- be->be_private = private;
- return rc;
-}
-
-static int ldap_chain_destroy(
- BackendDB *be
-)
-{
- slap_overinst *on = (slap_overinst *) be->bd_info;
- void *private = be->be_private;
- int rc;
-
- be->be_private = on->on_bi.bi_private;
- rc = ldap_back_db_destroy( be );
- on->on_bi.bi_private = be->be_private;
- be->be_private = private;
- return rc;
-}
-
-static slap_overinst ldapchain;
-
-int ldap_chain_setup()
-{
- ldapchain.on_bi.bi_type = "chain";
- ldapchain.on_bi.bi_db_init = ldap_chain_init;
- ldapchain.on_bi.bi_db_config = ldap_chain_config;
- ldapchain.on_bi.bi_db_destroy = ldap_chain_destroy;
- ldapchain.on_response = ldap_chain_response;
-
- return overlay_register( &ldapchain );
-}
bi->bi_connection_init = 0;
bi->bi_connection_destroy = ldap_back_conn_destroy;
- ldap_chain_setup();
-
return 0;
}
ri->ri_realsuffix = ndn;
- if ( overlay_config( be, "rewrite-remap" ) ) {
+ if ( overlay_config( be, "rwm" ) ) {
fprintf( stderr, "%s: line %d: unable to install "
- "rewrite-remap overlay "
- "in back-relay "
+ "rwm overlay "
"in \"relay <dn> [massage]\" line\n",
fname, lineno );
return 1;
## top-level directory of the distribution or, alternatively, at
## <http://www.OpenLDAP.org/license.html>.
-SRCS = overlays.c dyngroup.c pcache.c \
- rwm.c rwmconf.c rwmdn.c rwmmap.c denyop.c
-OBJS = overlays.lo dyngroup.lo pcache.lo \
- rwm.lo rwmconf.lo rwmdn.lo rwmmap.lo denyop.lo
+SRCS = overlays.c \
+ chain.c \
+ denyop.c \
+ dyngroup.c \
+ pcache.c \
+ rwm.c rwmconf.c rwmdn.c rwmmap.c
+OBJS = overlays.lo \
+ chain.c \
+ denyop.lo \
+ dyngroup.lo \
+ pcache.lo \
+ rwm.lo rwmconf.lo rwmdn.lo rwmmap.lo
LDAP_INCDIR= ../../../include
LDAP_LIBDIR= ../../../libraries
XINCPATH = -I.. -I$(srcdir)/..
XDEFS = $(MODULES_CPPFLAGS)
+chain.la : chain.lo $(@PLAT@_LINK_LIBS)
+ $(LTLINK_MOD) -module -o $@ chain.lo version.lo $(LINK_LIBS)
+
+denyop.la : denyop.lo $(@PLAT@_LINK_LIBS)
+ $(LTLINK_MOD) -module -o $@ denyop.lo version.lo $(LINK_LIBS)
+
dyngroup.la : dyngroup.lo $(@PLAT@_LINK_LIBS)
$(LTLINK_MOD) -module -o $@ dyngroup.lo version.lo $(LINK_LIBS)
rwm.la : rwm.lo $(@PLAT@_LINK_LIBS)
$(LTLINK_MOD) -module -o $@ rwm.lo rwmconf.lo rwmdn.lo rwmmap.lo version.lo $(LINK_LIBS)
-denyop.la : denyop.lo $(@PLAT@_LINK_LIBS)
- $(LTLINK_MOD) -module -o $@ denyop.lo version.lo $(LINK_LIBS)
-
install-local: $(PROGRAMS)
@if test -n "$?" ; then \
$(MKDIR) $(DESTDIR)$(moduledir); \
--- /dev/null
+/* chain.c - chain LDAP operations */
+/* $OpenLDAP$ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 2003-2004 The OpenLDAP Foundation.
+ * Portions Copyright 2003 Howard Chu.
+ * 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 the Howard Chu for inclusion
+ * in OpenLDAP Software.
+ */
+
+#include "portable.h"
+
+#if defined(SLAPD_LDAP)
+
+#ifdef SLAPD_OVER_CHAIN
+
+#include <stdio.h>
+
+#include <ac/string.h>
+#include <ac/socket.h>
+
+#include "slap.h"
+#include "../back-ldap/back-ldap.h"
+
+static int
+ldap_chain_response( Operation *op, SlapReply *rs )
+{
+ slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
+ void *private = op->o_bd->be_private;
+ slap_callback *sc = op->o_callback;
+ LDAPControl **prev = op->o_ctrls;
+ LDAPControl **ctrls = NULL, authz;
+ int i, nctrls, rc;
+ int cache = op->o_do_not_cache;
+ char *authzid = NULL;
+ BerVarray ref;
+ struct berval ndn = op->o_ndn;
+
+ if ( rs->sr_err != LDAP_REFERRAL )
+ return SLAP_CB_CONTINUE;
+
+ /* currently we assume only one referral destination.
+ * we'll have to parse this in the future.
+ */
+ ref = rs->sr_ref;
+ rs->sr_ref = NULL;
+
+ op->o_bd->be_private = on->on_bi.bi_private;
+ op->o_callback = NULL;
+
+ /* Chaining is performed by a privileged user on behalf
+ * of a normal user, using the ProxyAuthz control. However,
+ * Binds are done separately, on an anonymous session.
+ */
+ if ( op->o_tag != LDAP_REQ_BIND ) {
+ for (i=0; prev && prev[i]; i++);
+ nctrls = i;
+
+ /* Add an extra NULL slot */
+ if (!prev) i++;
+
+ ctrls = op->o_tmpalloc((i+1)*sizeof(LDAPControl *),
+ op->o_tmpmemctx);
+ for (i=0; i <nctrls; i++)
+ ctrls[i] = prev[i];
+ ctrls[nctrls] = &authz;
+ ctrls[nctrls+1] = NULL;
+ authz.ldctl_oid = LDAP_CONTROL_PROXY_AUTHZ;
+ authz.ldctl_iscritical = 1;
+ authz.ldctl_value = op->o_dn;
+ if ( op->o_dn.bv_len ) {
+ authzid = op->o_tmpalloc( op->o_dn.bv_len+4,
+ op->o_tmpmemctx );
+ strcpy(authzid, "dn: ");
+ strcpy(authzid+4, op->o_dn.bv_val);
+ authz.ldctl_value.bv_len = op->o_dn.bv_len + 4;
+ authz.ldctl_value.bv_val = authzid;
+ }
+ op->o_ctrls = ctrls;
+ op->o_ndn = op->o_bd->be_rootndn;
+ }
+
+ switch( op->o_tag ) {
+ case LDAP_REQ_BIND: {
+ struct berval rndn = op->o_req_ndn;
+ Connection *conn = op->o_conn;
+ op->o_req_ndn = slap_empty_bv;
+ op->o_conn = NULL;
+ rc = ldap_back_bind( op, rs );
+ op->o_req_ndn = rndn;
+ op->o_conn = conn;
+ }
+ break;
+ case LDAP_REQ_ADD:
+ rc = ldap_back_add( op, rs );
+ break;
+ case LDAP_REQ_DELETE:
+ rc = ldap_back_delete( op, rs );
+ break;
+ case LDAP_REQ_MODRDN:
+ rc = ldap_back_modrdn( op, rs );
+ break;
+ case LDAP_REQ_MODIFY:
+ rc = ldap_back_modify( op, rs );
+ break;
+ case LDAP_REQ_COMPARE:
+ rc = ldap_back_compare( op, rs );
+ break;
+ case LDAP_REQ_SEARCH:
+ rc = ldap_back_search( op, rs );
+ break;
+ case LDAP_REQ_EXTENDED:
+ rc = ldap_back_extended( op, rs );
+ break;
+ default:
+ rc = SLAP_CB_CONTINUE;
+ break;
+ }
+ op->o_do_not_cache = cache;
+ op->o_ctrls = prev;
+ op->o_bd->be_private = private;
+ op->o_callback = sc;
+ op->o_ndn = ndn;
+ if ( ctrls ) op->o_tmpfree( ctrls, op->o_tmpmemctx );
+ if ( authzid ) op->o_tmpfree( authzid, op->o_tmpmemctx );
+ rs->sr_ref = ref;
+
+ return rc;
+}
+
+static int ldap_chain_config(
+ BackendDB *be,
+ const char *fname,
+ int lineno,
+ int argc,
+ char **argv
+)
+{
+ slap_overinst *on = (slap_overinst *) be->bd_info;
+ void *private = be->be_private;
+ char *argv0 = NULL;
+ int rc;
+
+ be->be_private = on->on_bi.bi_private;
+ if ( strncasecmp( argv[ 0 ], "chain-", sizeof( "chain-" ) - 1 ) == 0 ) {
+ argv0 = argv[ 0 ];
+ argv[ 0 ] = &argv[ 0 ][ sizeof( "chain-" ) - 1 ];
+ }
+ rc = ldap_back_db_config( be, fname, lineno, argc, argv );
+ if ( argv0 ) {
+ argv[ 0 ] = argv0;
+ }
+
+ be->be_private = private;
+ return rc;
+}
+
+static int ldap_chain_init(
+ BackendDB *be
+)
+{
+ slap_overinst *on = (slap_overinst *) be->bd_info;
+ void *private = be->be_private;
+ int rc;
+
+ be->be_private = NULL;
+ rc = ldap_back_db_init( be );
+ on->on_bi.bi_private = be->be_private;
+ be->be_private = private;
+ return rc;
+}
+
+static int ldap_chain_destroy(
+ BackendDB *be
+)
+{
+ slap_overinst *on = (slap_overinst *) be->bd_info;
+ void *private = be->be_private;
+ int rc;
+
+ be->be_private = on->on_bi.bi_private;
+ rc = ldap_back_db_destroy( be );
+ on->on_bi.bi_private = be->be_private;
+ be->be_private = private;
+ return rc;
+}
+
+static slap_overinst ldapchain;
+
+int chain_init()
+{
+ ldapchain.on_bi.bi_type = "chain";
+ ldapchain.on_bi.bi_db_init = ldap_chain_init;
+ ldapchain.on_bi.bi_db_config = ldap_chain_config;
+ ldapchain.on_bi.bi_db_destroy = ldap_chain_destroy;
+ ldapchain.on_response = ldap_chain_response;
+
+ return overlay_register( &ldapchain );
+}
+
+#if SLAPD_OVER_CHAIN == SLAPD_MOD_DYNAMIC
+int init_module(int argc, char *argv[]) {
+ return chain_init();
+}
+#endif /* SLAPD_OVER_CHAIN == SLAPD_MOD_DYNAMIC */
+
+#endif /* SLAPD_OVER_CHAIN */
+
+#endif /* ! defined(SLAPD_LDAP) */
static slap_overinst denyop;
-int denyop_init() {
+int
+denyop_init() {
memset( &denyop, 0, sizeof( slap_overinst ) );
denyop.on_bi.bi_type = "denyop";
denyop.on_bi.bi_db_init = denyop_over_init;
}
#if SLAPD_OVER_DENYOP == SLAPD_MOD_DYNAMIC
-int init_module(int argc, char *argv[]) {
+int
+init_module(int argc, char *argv[]) {
return denyop_init();
}
#endif
#include "slap.h"
+#if SLAPD_OVER_CHAIN == SLAPD_MOD_STATIC
+extern int chain_init();
+#endif
+#if SLAPD_OVER_DENYOP == SLAPD_MOD_STATIC
+extern int denyop_init();
+#endif
#if SLAPD_OVER_DYNGROUP == SLAPD_MOD_STATIC
extern int dyngroup_init();
#endif
char *name;
int (*func)();
} funcs[] = {
+#if SLAPD_OVER_CHAIN == SLAPD_MOD_STATIC
+ { "LDAP Chain Response", chain_init },
+#endif
+#if SLAPD_OVER_DENYOP == SLAPD_MOD_STATIC
+ { "Deny Operation", denyop_init },
+#endif
#if SLAPD_OVER_DYNGROUP == SLAPD_MOD_STATIC
{ "Dynamic Group", dyngroup_init },
#endif
{
memset( &rwm, 0, sizeof(slap_overinst) );
- rwm.on_bi.bi_type = "rewrite-remap";
+ rwm.on_bi.bi_type = "rwm";
rwm.on_bi.bi_db_init = rwm_over_init;
rwm.on_bi.bi_db_config = rwm_config;
rwm.on_bi.bi_db_destroy = rwm_destroy;