Fixed slapd winsock assert (ITS#3983)
Fixed slapd-bdb/hdb paged results deadlock (ITS#3940)
Fixed slapd-bdb/hdb/ldbm searchBase disclose (ITS#3964)
+ Fixed slapd-bdb/hdb bi_dbenv check (ITS#3992)
Fixed slapd-meta generic attribute normalize/pretty (ITS#3956)
Fixed slapd-ldap/meta 'undefined' attribute mutex protection (ITS#3958)
Added slapd-ldap/meta 'proxied' attribute support (ITS#3959)
Fixed slapd-meta matchedDN handling (ITS#3944)
Fixed slapd-monitor hiding issue (ITS#3986)
Fixed slapo-ppolicy lockout status at Bind (ITS#3946)
+ Moved slapo-glue into slapd core
Fixed slaptest cn=config segfault (ITS#3961)
Fixed slaptools logging issue (ITS#3937)
Fixed slaptools fails after db clean (ITS#3970)
#! /bin/sh
-# From configure.in OpenLDAP: pkg/ldap/configure.in,v 1.598 2005/08/27 22:23:35 hyc Exp .
+# From configure.in OpenLDAP: pkg/ldap/configure.in,v 1.560.2.13 2005/08/29 18:46:16 kurt Exp .
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.59.
#
# include <unistd.h>
#endif"
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar OPENLDAP_LIBRELEASE OPENLDAP_LIBVERSION OPENLDAP_RELEASE_DATE top_builddir ldap_subdir CC AR CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE EGREP LN_S ECHO ac_ct_AR RANLIB ac_ct_RANLIB DLLTOOL ac_ct_DLLTOOL AS ac_ct_AS OBJDUMP ac_ct_OBJDUMP CPP LIBTOOL PERLBIN OL_MKDEP OL_MKDEP_FLAGS LTSTATIC LIBOBJS LIBSRCS PLAT WITH_SASL WITH_TLS WITH_MODULES_ENABLED WITH_ACI_ENABLED BUILD_LIBS_DYNAMIC BUILD_SLAPD BUILD_SLAPI SLAPD_SLAPI_DEPEND BUILD_BDB BUILD_DNSSRV BUILD_HDB BUILD_LDAP BUILD_LDBM BUILD_META BUILD_MONITOR BUILD_NULL BUILD_PASSWD BUILD_RELAY BUILD_PERL BUILD_SHELL BUILD_SQL BUILD_ACCESSLOG BUILD_DENYOP BUILD_DYNGROUP BUILD_DYNLIST BUILD_GLUE BUILD_LASTMOD BUILD_PPOLICY BUILD_PROXYCACHE BUILD_REFINT BUILD_RETCODE BUILD_RWM BUILD_SYNCPROV BUILD_TRANSLUCENT BUILD_UNIQUE BUILD_VALSORT BUILD_SLURPD LDAP_LIBS SLAPD_LIBS SLURPD_LIBS LDBM_LIBS LTHREAD_LIBS LUTIL_LIBS WRAP_LIBS SLAPD_MODULES_CPPFLAGS SLAPD_MODULES_LDFLAGS SLAPD_NO_STATIC SLAPD_STATIC_BACKENDS SLAPD_DYNAMIC_BACKENDS SLAPD_STATIC_OVERLAYS SLAPD_DYNAMIC_OVERLAYS PERL_CPPFLAGS SLAPD_PERL_LDFLAGS MOD_PERL_LDFLAGS KRB4_LIBS KRB5_LIBS SASL_LIBS TLS_LIBS MODULES_LIBS SLAPI_LIBS LIBSLAPI LIBSLAPITOOLS AUTH_LIBS SLAPD_SLP_LIBS SLAPD_GMP_LIBS SLAPD_SQL_LDFLAGS SLAPD_SQL_LIBS SLAPD_SQL_INCLUDES LTLIBOBJS'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar OPENLDAP_LIBRELEASE OPENLDAP_LIBVERSION OPENLDAP_RELEASE_DATE top_builddir ldap_subdir CC AR CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE EGREP LN_S ECHO ac_ct_AR RANLIB ac_ct_RANLIB DLLTOOL ac_ct_DLLTOOL AS ac_ct_AS OBJDUMP ac_ct_OBJDUMP CPP LIBTOOL PERLBIN OL_MKDEP OL_MKDEP_FLAGS LTSTATIC LIBOBJS LIBSRCS PLAT WITH_SASL WITH_TLS WITH_MODULES_ENABLED WITH_ACI_ENABLED BUILD_LIBS_DYNAMIC BUILD_SLAPD BUILD_SLAPI SLAPD_SLAPI_DEPEND BUILD_BDB BUILD_DNSSRV BUILD_HDB BUILD_LDAP BUILD_LDBM BUILD_META BUILD_MONITOR BUILD_NULL BUILD_PASSWD BUILD_RELAY BUILD_PERL BUILD_SHELL BUILD_SQL BUILD_ACCESSLOG BUILD_DENYOP BUILD_DYNGROUP BUILD_DYNLIST BUILD_LASTMOD BUILD_PPOLICY BUILD_PROXYCACHE BUILD_REFINT BUILD_RETCODE BUILD_RWM BUILD_SYNCPROV BUILD_TRANSLUCENT BUILD_UNIQUE BUILD_VALSORT BUILD_SLURPD LDAP_LIBS SLAPD_LIBS SLURPD_LIBS LDBM_LIBS LTHREAD_LIBS LUTIL_LIBS WRAP_LIBS SLAPD_MODULES_CPPFLAGS SLAPD_MODULES_LDFLAGS SLAPD_NO_STATIC SLAPD_STATIC_BACKENDS SLAPD_DYNAMIC_BACKENDS SLAPD_STATIC_OVERLAYS SLAPD_DYNAMIC_OVERLAYS PERL_CPPFLAGS SLAPD_PERL_LDFLAGS MOD_PERL_LDFLAGS KRB4_LIBS KRB5_LIBS SASL_LIBS TLS_LIBS MODULES_LIBS SLAPI_LIBS LIBSLAPI LIBSLAPITOOLS AUTH_LIBS SLAPD_SLP_LIBS SLAPD_GMP_LIBS SLAPD_SQL_LDFLAGS SLAPD_SQL_LIBS SLAPD_SQL_INCLUDES LTLIBOBJS'
ac_subst_files=''
# Initialize some variables set by options.
--enable-denyop Deny Operation overlay no|yes|mod [no]
--enable-dyngroup Dynamic Group overlay no|yes|mod [no]
--enable-dynlist Dynamic List overlay no|yes|mod [no]
- --enable-glue Backend Glue overlay no|yes|mod [yes]
--enable-lastmod Last Modification overlay no|yes|mod [no]
--enable-ppolicy Password Policy overlay no|yes|mod [no]
--enable-proxycache Proxy Cache overlay no|yes|mod [no]
denyop \
dyngroup \
dynlist \
- glue \
lastmod \
ppolicy \
proxycache \
fi;
# end --enable-dynlist
-# OpenLDAP --enable-glue
-
- # Check whether --enable-glue or --disable-glue was given.
-if test "${enable_glue+set}" = set; then
- enableval="$enable_glue"
-
- ol_arg=invalid
- for ol_val in no yes mod ; do
- if test "$enableval" = "$ol_val" ; then
- ol_arg="$ol_val"
- fi
- done
- if test "$ol_arg" = "invalid" ; then
- { { echo "$as_me:$LINENO: error: bad value $enableval for --enable-glue" >&5
-echo "$as_me: error: bad value $enableval for --enable-glue" >&2;}
- { (exit 1); exit 1; }; }
- fi
- ol_enable_glue="$ol_arg"
-
-else
- ol_enable_glue=${ol_enable_overlays:-yes}
-fi;
-# end --enable-glue
-
# OpenLDAP --enable-lastmod
# Check whether --enable-lastmod or --disable-lastmod was given.
BUILD_DENYOP=no
BUILD_DYNGROUP=no
BUILD_DYNLIST=no
-BUILD_GLUE=no
BUILD_LASTMOD=no
BUILD_PPOLICY=no
BUILD_PROXYCACHE=no
;;
*-*-irix6*)
# Find out which ABI we are using.
- echo '#line 5715 "configure"' > conftest.$ac_ext
+ echo '#line 5688 "configure"' > conftest.$ac_ext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:7695: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:7668: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:7699: \$? = $ac_status" >&5
+ echo "$as_me:7672: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:7957: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:7930: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:7961: \$? = $ac_status" >&5
+ echo "$as_me:7934: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:8019: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:7992: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:8023: \$? = $ac_status" >&5
+ echo "$as_me:7996: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 10259 "configure"
+#line 10232 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 10357 "configure"
+#line 10330 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
fi
-if test "$ol_enable_glue" != no ; then
- BUILD_GLUE=$ol_enable_glue
- if test "$ol_enable_glue" = mod ; then
- MFLAG=SLAPD_MOD_DYNAMIC
- SLAPD_DYNAMIC_OVERLAYS="$SLAPD_DYNAMIC_OVERLAYS glue.la"
- else
- MFLAG=SLAPD_MOD_STATIC
- SLAPD_STATIC_OVERLAYS="$SLAPD_STATIC_OVERLAYS glue.o"
- fi
-
-cat >>confdefs.h <<_ACEOF
-#define SLAPD_OVER_GLUE $MFLAG
-_ACEOF
-
-fi
-
if test "$ol_enable_lastmod" != no ; then
BUILD_LASTMOD=$ol_enable_lastmod
if test "$ol_enable_lastmod" = mod ; then
-
# Check whether --with-xxinstall or --without-xxinstall was given.
s,@BUILD_DENYOP@,$BUILD_DENYOP,;t t
s,@BUILD_DYNGROUP@,$BUILD_DYNGROUP,;t t
s,@BUILD_DYNLIST@,$BUILD_DYNLIST,;t t
-s,@BUILD_GLUE@,$BUILD_GLUE,;t t
s,@BUILD_LASTMOD@,$BUILD_LASTMOD,;t t
s,@BUILD_PPOLICY@,$BUILD_PPOLICY,;t t
s,@BUILD_PROXYCACHE@,$BUILD_PROXYCACHE,;t t
denyop \
dyngroup \
dynlist \
- glue \
lastmod \
ppolicy \
proxycache \
no, [no yes mod], ol_enable_overlays)
OL_ARG_ENABLE(dynlist,[ --enable-dynlist Dynamic List overlay],
no, [no yes mod], ol_enable_overlays)
-OL_ARG_ENABLE(glue,[ --enable-glue Backend Glue overlay],
- yes, [no yes mod], ol_enable_overlays)
OL_ARG_ENABLE(lastmod,[ --enable-lastmod Last Modification overlay],
no, [no yes mod], ol_enable_overlays)
OL_ARG_ENABLE(ppolicy,[ --enable-ppolicy Password Policy overlay],
BUILD_DENYOP=no
BUILD_DYNGROUP=no
BUILD_DYNLIST=no
-BUILD_GLUE=no
BUILD_LASTMOD=no
BUILD_PPOLICY=no
BUILD_PROXYCACHE=no
AC_DEFINE_UNQUOTED(SLAPD_OVER_DYNLIST,$MFLAG,[define for Dynamic List overlay])
fi
-if test "$ol_enable_glue" != no ; then
- BUILD_GLUE=$ol_enable_glue
- if test "$ol_enable_glue" = mod ; then
- MFLAG=SLAPD_MOD_DYNAMIC
- SLAPD_DYNAMIC_OVERLAYS="$SLAPD_DYNAMIC_OVERLAYS glue.la"
- else
- MFLAG=SLAPD_MOD_STATIC
- SLAPD_STATIC_OVERLAYS="$SLAPD_STATIC_OVERLAYS glue.o"
- fi
- AC_DEFINE_UNQUOTED(SLAPD_OVER_GLUE,$MFLAG,[define for Backend Glue overlay])
-fi
-
if test "$ol_enable_lastmod" != no ; then
BUILD_LASTMOD=$ol_enable_lastmod
if test "$ol_enable_lastmod" = mod ; then
AC_SUBST(BUILD_DENYOP)
AC_SUBST(BUILD_DYNGROUP)
AC_SUBST(BUILD_DYNLIST)
- AC_SUBST(BUILD_GLUE)
AC_SUBST(BUILD_LASTMOD)
AC_SUBST(BUILD_PPOLICY)
AC_SUBST(BUILD_PROXYCACHE)
.\" Copyright 1998-2005 The OpenLDAP Foundation All Rights Reserved.
.\" Copying restrictions apply. See COPYRIGHT/LICENSE.
.\" $OpenLDAP$
-.SH NAME
slapd.conf \- configuration file for slapd, the stand-alone LDAP daemon
.SH SYNOPSIS
ETCDIR/slapd.conf
required for each database definition.
If the suffix of one database is "inside" that of another, the database
with the inner suffix must come first in the configuration file.
+.TP
+.B subordinate [advertise]
+Specify that the current backend database is a subordinate of another
+backend database. A subordinate database may have only one suffix. This
+option may be used to glue multiple databases into a single namingContext.
+If the suffix of the current database is within the namingContext of a
+superior database, searches against the superior database will be
+propagated to the subordinate as well. All of the databases
+associated with a single namingContext should have identical rootdns.
+Behavior of other LDAP operations is unaffected by this setting. In
+particular, it is not possible to use moddn to move an entry from
+one subordinate to another subordinate within the namingContext.
+
+If the optional \fBadvertise\fP flag is supplied, the naming context of
+this database is advertised in the root DSE. The default is to hide this
+database context, so that only the superior context is visible.
+
+If the slap tools
+.BR slapcat (8),
+.BR slapadd (8),
+or
+.BR slapindex (8)
+are used on the superior database, any glued subordinates that support
+these tools are opened as well.
+
+Databases that are glued together should usually be configured with the
+same indices (assuming they support indexing), even for attributes that
+only exist in some of these databases. In general, all of the glued
+databases should be configured as similarly as possible, since the intent
+is to provide the appearance of a single directory.
.HP
.hy 0
.B syncrepl rid=<replica ID>
Dynamic List.
This overlay allows expansion of dynamic groups and more.
.TP
-.B glue
-Backend Glue.
-This overlay glues multiple databases into a single namingContext.
-.TP
.B lastmod
Last Modification.
This overlay maintains a service entry in the database with the DN,
"OpenLDAP Administrator's Guide" contains a longer annotated
example of a configuration file.
The original ETCDIR/slapd.conf is another example.
-.SH OBSOLETED DIRECTIVES
-.TP
-.B subordinate
-This directive was used in OpenLDAP 2.1 and 2.2 to glue a database
-with its superior. The same functionality is now provided by the
-.B glue
-overlay; see
-.BR slapo-glue (5)
-for details.
.SH FILES
.TP
ETCDIR/slapd.conf
.BR slapo\-auditlog (5),
.BR slapo\-chain (5),
.BR slapo\-dynlist (5),
-.BR slapo\-glue (5),
.BR slapo\-lastmod (5),
.BR slapo\-pcache (5),
.BR slapo\-ppolicy (5),
+++ /dev/null
-.TH SLAPO-GLUE 5 "RELEASEDATE" "OpenLDAP LDVERSION"
-.\" Copyright 2004-2005 The OpenLDAP Foundation All Rights Reserved.
-.\" Copying restrictions apply. See COPYRIGHT/LICENSE.
-.\" $OpenLDAP$
-.SH NAME
-slapo-glue \- Backend Glue overlay
-.SH SYNOPSIS
-ETCDIR/slapd.conf
-.SH DESCRIPTION
-The Backend Glue overlay can be used to glue multiple databases into a
-single namingContext. The overlay must be configured on the root database
-of the context, and any other databases must be explicitly configured
-as subordinates of the root database. All of the participating databases
-should have identical rootdns.
-
-All search and write operations will be intercepted by this overlay. Searches
-against the root database will be propagated to all the subordinates. Write
-operations will pass unaltered to the relevant target database.
-
-Note that
-any overlays on the root database configured before this overlay will fail
-to execute. As such, the glue overlay should always be the first overlay
-configured on the root database.
-.SH CONFIGURATION
-These
-.B slapd.conf
-options apply to the Backend Glue overlay.
-They should appear after the
-.B overlay
-directive and before any subsequent
-.B database
-directive.
-.TP
-.B glue-sub <suffix-DN> [async] [advertise]
-Specify the suffix of a database to attach as a subordinate to the root
-database. The specified database must have already been configured. If the
-optional \fBasync\fP keyword is supplied, searches against this database may
-be spawned in a separate thread to run concurrently with other operations
-(currently not implemented). If the optional \fBadvertise\fP flag
-is supplied, the naming context is advertised in the root DSE.
-.SH EXAMPLE
-The following will cause a search from dc=example,dc=com to search
-people as well, but it will not search services.
-.LP
-.RS
-.nf
-database bdb
-suffix "ou=people,dc=example,dc=com"
-
-database bdb
-suffix "ou=services,dc=example,dc=com"
-
-database bdb
-suffix "dc=example,dc=com"
-overlay glue
-glue-sub "ou=people,dc=example,dc=com"
-.fi
-.RE
-.SH NOTES
-Databases that are glued together should usually be configured with
-the same indexes, even for attributes that only exist in some of
-these databases.
-A search for an attribute which is only indexed in some of the glued
-databases must otherwise examine each entry in the search scope in the
-other databases, looking for the attribute.
-
-If the extra indexes assist searches one would prefer not to
-support, these can be disabled with access controls in some of the
-databases.
-E.g.:
-.RS
-access to attrs=cn by * =rcxd
-.RE
-See
-.BR slapd.access (5).
-.SH FILES
-.TP
-ETCDIR/slapd.conf
-default slapd configuration file
-.SH SEE ALSO
-.BR slapd.conf (5).
It opens the given database determined by the database number or
suffix and adds entries corresponding to the provided LDIF to
the database.
-Subordinate databases glued with
-.BR slapo-glue (5)
-are also updated.
+Databases configured as
+.B subordinate
+of this one are also updated.
The LDIF input is read from standard input or the specified file.
.LP
As
It opens the given database determined by the database number or
suffix and writes the corresponding LDIF to standard output or
the specified file.
-Subordinate databases glued with
-.BR slapo-glue (5)
-are also output.
+Databases configured as
+.B subordinate
+of this one are also output.
.LP
The LDIF generated by this tool is suitable for use with
.BR slapadd (8).
It opens the given database determined by the database number or
suffix and updates the indices for all values of all attributes
of all entries.
-Subordinate databases glued with
-.BR slapo-glue (5)
-are also re-indexed.
+Databases configured as
+.B subordinate
+of this one are also re-indexed.
.SH OPTIONS
.TP
.B \-v
/* define for Dynamic List overlay */
#undef SLAPD_OVER_DYNLIST
-/* define for Backend Glue overlay */
-#undef SLAPD_OVER_GLUE
-
/* define for Last Modification overlay */
#undef SLAPD_OVER_LASTMOD
oidm.c starttls.c index.c sets.c referral.c root_dse.c \
sasl.c module.c mra.c mods.c sl_malloc.c zn_malloc.c limits.c \
operational.c matchedValues.c cancel.c syncrepl.c \
- backover.c ctxcsn.c ldapsync.c frontend.c \
+ backglue.c backover.c ctxcsn.c ldapsync.c frontend.c \
slapadd.c slapcat.c slapcommon.c slapdn.c slapindex.c \
slappasswd.c slaptest.c slapauth.c slapacl.c component.c \
aci.c \
oidm.o starttls.o index.o sets.o referral.o root_dse.o \
sasl.o module.o mra.o mods.o sl_malloc.o zn_malloc.o limits.o \
operational.o matchedValues.o cancel.o syncrepl.o \
- backover.o ctxcsn.o ldapsync.o frontend.o \
+ backglue.o backover.o ctxcsn.o ldapsync.o frontend.o \
slapadd.o slapcat.o slapcommon.o slapdn.o slapindex.o \
slappasswd.o slaptest.o slapauth.o slapacl.o component.o \
aci.o \
open_env = 0;
} else {
/* Create a new env that can take the desired settings */
- bdb->bi_dbenv->close( bdb->bi_dbenv, 0 );
- bdb->bi_dbenv = NULL;
+ if ( bdb->bi_dbenv != NULL ) {
+ bdb->bi_dbenv->close( bdb->bi_dbenv, 0 );
+ bdb->bi_dbenv = NULL;
+ }
rc = db_env_create( &bdb->bi_dbenv, 0 );
if( rc != 0 ) {
Debug( LDAP_DEBUG_ANY,
--- /dev/null
+/* backglue.c - backend glue */
+/* $OpenLDAP$ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 2001-2005 The OpenLDAP Foundation.
+ * 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>.
+ */
+
+/*
+ * Functions to glue a bunch of other backends into a single tree.
+ * All of the glued backends must share a common suffix. E.g., you
+ * can glue o=foo and ou=bar,o=foo but you can't glue o=foo and o=bar.
+ *
+ * The purpose of these functions is to allow you to split a single database
+ * into pieces (for load balancing purposes, whatever) but still be able
+ * to treat it as a single database after it's been split. As such, each
+ * of the glued backends should have identical rootdn.
+ * -- Howard Chu
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/string.h>
+#include <ac/socket.h>
+
+#define SLAPD_TOOLS
+#include "slap.h"
+
+typedef struct gluenode {
+ BackendDB *gn_be;
+ struct berval gn_pdn;
+} gluenode;
+
+typedef struct glueinfo {
+ int gi_nodes;
+ struct berval gi_pdn;
+ gluenode gi_n[1];
+} glueinfo;
+
+static slap_overinst glue;
+
+static int glueMode;
+static BackendDB *glueBack;
+
+static slap_response glue_op_response;
+
+/* Just like select_backend, but only for our backends */
+static BackendDB *
+glue_back_select (
+ BackendDB *be,
+ struct berval *dn
+)
+{
+ slap_overinst *on = (slap_overinst *)be->bd_info;
+ glueinfo *gi = (glueinfo *)on->on_bi.bi_private;
+ int i;
+
+ for (i = 0; i<gi->gi_nodes; i++) {
+ assert( gi->gi_n[i].gn_be->be_nsuffix != NULL );
+
+ if (dnIsSuffix(dn, &gi->gi_n[i].gn_be->be_nsuffix[0])) {
+ return gi->gi_n[i].gn_be;
+ }
+ }
+ be->bd_info = on->on_info->oi_orig;
+ return be;
+}
+
+
+typedef struct glue_state {
+ int err;
+ int slimit;
+ int matchlen;
+ char *matched;
+ int nrefs;
+ BerVarray refs;
+} glue_state;
+
+static int
+glue_op_response ( Operation *op, SlapReply *rs )
+{
+ glue_state *gs = op->o_callback->sc_private;
+
+ switch(rs->sr_type) {
+ case REP_SEARCH:
+ if ( gs->slimit != SLAP_NO_LIMIT
+ && rs->sr_nentries >= gs->slimit )
+ {
+ rs->sr_err = gs->err = LDAP_SIZELIMIT_EXCEEDED;
+ return -1;
+ }
+ /* fallthru */
+ case REP_SEARCHREF:
+ return SLAP_CB_CONTINUE;
+
+ default:
+ if (rs->sr_err == LDAP_SUCCESS ||
+ rs->sr_err == LDAP_SIZELIMIT_EXCEEDED ||
+ rs->sr_err == LDAP_TIMELIMIT_EXCEEDED ||
+ rs->sr_err == LDAP_ADMINLIMIT_EXCEEDED ||
+ rs->sr_err == LDAP_NO_SUCH_OBJECT ||
+ gs->err != LDAP_SUCCESS)
+ gs->err = rs->sr_err;
+ if (gs->err == LDAP_SUCCESS && gs->matched) {
+ ch_free (gs->matched);
+ gs->matched = NULL;
+ gs->matchlen = 0;
+ }
+ if (gs->err != LDAP_SUCCESS && rs->sr_matched) {
+ int len;
+ len = strlen (rs->sr_matched);
+ if (len > gs->matchlen) {
+ if (gs->matched)
+ ch_free (gs->matched);
+ gs->matched = ch_strdup (rs->sr_matched);
+ gs->matchlen = len;
+ }
+ }
+ if (rs->sr_ref) {
+ int i, j, k;
+ BerVarray new;
+
+ for (i=0; rs->sr_ref[i].bv_val; i++);
+
+ j = gs->nrefs;
+ if (!j) {
+ new = ch_malloc ((i+1)*sizeof(struct berval));
+ } else {
+ new = ch_realloc(gs->refs,
+ (j+i+1)*sizeof(struct berval));
+ }
+ for (k=0; k<i; j++,k++) {
+ ber_dupbv( &new[j], &rs->sr_ref[k] );
+ }
+ new[j].bv_val = NULL;
+ gs->nrefs = j;
+ gs->refs = new;
+ }
+ }
+ return 0;
+}
+
+static int
+glue_op_func ( Operation *op, SlapReply *rs )
+{
+ slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
+ BackendDB *b0 = op->o_bd;
+ BackendInfo *bi0 = op->o_bd->bd_info;
+ BI_op_modify **func;
+ slap_operation_t which;
+ int rc;
+
+ op->o_bd = glue_back_select (b0, &op->o_req_ndn);
+ b0->bd_info = on->on_info->oi_orig;
+
+ switch(op->o_tag) {
+ case LDAP_REQ_ADD: which = op_add; break;
+ case LDAP_REQ_DELETE: which = op_delete; break;
+ case LDAP_REQ_MODIFY: which = op_modify; break;
+ case LDAP_REQ_MODRDN: which = op_modrdn; break;
+ }
+
+ func = &op->o_bd->bd_info->bi_op_bind;
+ if ( func[which] )
+ rc = func[which]( op, rs );
+ else
+ rc = SLAP_CB_CONTINUE;
+
+ op->o_bd = b0;
+ op->o_bd->bd_info = bi0;
+ return rc;
+}
+
+static int
+glue_chk_referrals ( Operation *op, SlapReply *rs )
+{
+ slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
+ BackendDB *b0 = op->o_bd;
+ BackendInfo *bi0 = op->o_bd->bd_info;
+ int rc;
+
+ op->o_bd = glue_back_select (b0, &op->o_req_ndn);
+ b0->bd_info = on->on_info->oi_orig;
+
+ if ( op->o_bd->bd_info->bi_chk_referrals )
+ rc = ( *op->o_bd->bd_info->bi_chk_referrals )( op, rs );
+ else
+ rc = SLAP_CB_CONTINUE;
+
+ op->o_bd = b0;
+ op->o_bd->bd_info = bi0;
+ return rc;
+}
+
+static int
+glue_chk_controls ( Operation *op, SlapReply *rs )
+{
+ slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
+ BackendDB *b0 = op->o_bd;
+ BackendInfo *bi0 = op->o_bd->bd_info;
+ int rc = SLAP_CB_CONTINUE;
+
+ op->o_bd = glue_back_select (b0, &op->o_req_ndn);
+ b0->bd_info = on->on_info->oi_orig;
+
+ /* if the subordinate database has overlays, the bi_chk_controls()
+ * hook is actually over_aux_chk_controls(); in case it actually
+ * wraps a missing hok, we need to mimic the behavior
+ * of the frontend applied to that database */
+ if ( op->o_bd->bd_info->bi_chk_controls ) {
+ rc = ( *op->o_bd->bd_info->bi_chk_controls )( op, rs );
+ }
+
+
+ if ( rc == SLAP_CB_CONTINUE ) {
+ rc = backend_check_controls( op, rs );
+ }
+
+ op->o_bd = b0;
+ op->o_bd->bd_info = bi0;
+ return rc;
+}
+
+static int
+glue_op_search ( Operation *op, SlapReply *rs )
+{
+ slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
+ glueinfo *gi = (glueinfo *)on->on_bi.bi_private;
+ BackendDB *b0 = op->o_bd;
+ BackendDB *b1 = NULL, *btmp;
+ BackendInfo *bi0 = op->o_bd->bd_info;
+ int i;
+ long stoptime = 0;
+ glue_state gs = {0, 0, 0, NULL, 0, NULL};
+ slap_callback cb = { NULL, glue_op_response, NULL, NULL };
+ int scope0, slimit0, tlimit0;
+ struct berval dn, ndn, *pdn;
+
+ cb.sc_private = &gs;
+
+ cb.sc_next = op->o_callback;
+
+ stoptime = slap_get_time () + op->ors_tlimit;
+
+ op->o_bd = glue_back_select (b0, &op->o_req_ndn);
+ b0->bd_info = on->on_info->oi_orig;
+
+ switch (op->ors_scope) {
+ case LDAP_SCOPE_BASE:
+ rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
+ if (op->o_bd && op->o_bd->be_search) {
+ rs->sr_err = op->o_bd->be_search( op, rs );
+ }
+ return rs->sr_err;
+
+ case LDAP_SCOPE_ONELEVEL:
+ case LDAP_SCOPE_SUBTREE:
+#ifdef LDAP_SCOPE_SUBORDINATE
+ case LDAP_SCOPE_SUBORDINATE: /* FIXME */
+#endif
+
+#if 0
+ if ( op->o_sync ) {
+ if (op->o_bd && op->o_bd->be_search) {
+ rs->sr_err = op->o_bd->be_search( op, rs );
+ } else {
+ send_ldap_error(op, rs, LDAP_UNWILLING_TO_PERFORM,
+ "No search target found");
+ }
+ return rs->sr_err;
+ }
+#endif
+
+ op->o_callback = &cb;
+ rs->sr_err = gs.err = LDAP_UNWILLING_TO_PERFORM;
+ scope0 = op->ors_scope;
+ slimit0 = gs.slimit = op->ors_slimit;
+ tlimit0 = op->ors_tlimit;
+ dn = op->o_req_dn;
+ ndn = op->o_req_ndn;
+ b1 = op->o_bd;
+
+ /*
+ * Execute in reverse order, most general first
+ */
+ for (i = gi->gi_nodes; i >= 0; i--) {
+ if ( i == gi->gi_nodes ) {
+ btmp = b0;
+ pdn = &gi->gi_pdn;
+ } else {
+ btmp = gi->gi_n[i].gn_be;
+ pdn = &gi->gi_n[i].gn_pdn;
+ }
+ if (!btmp || !btmp->be_search)
+ continue;
+ if (!dnIsSuffix(&btmp->be_nsuffix[0], &b1->be_nsuffix[0]))
+ continue;
+ if (tlimit0 != SLAP_NO_LIMIT) {
+ op->ors_tlimit = stoptime - slap_get_time ();
+ if (op->ors_tlimit <= 0) {
+ rs->sr_err = gs.err = LDAP_TIMELIMIT_EXCEEDED;
+ break;
+ }
+ }
+ if (slimit0 != SLAP_NO_LIMIT) {
+ op->ors_slimit = slimit0 - rs->sr_nentries;
+ if (op->ors_slimit < 0) {
+ rs->sr_err = gs.err = LDAP_SIZELIMIT_EXCEEDED;
+ break;
+ }
+ }
+ rs->sr_err = 0;
+ /*
+ * check for abandon
+ */
+ if (op->o_abandon) {
+ goto end_of_loop;
+ }
+ op->o_bd = btmp;
+
+ assert( op->o_bd->be_suffix != NULL );
+ assert( op->o_bd->be_nsuffix != NULL );
+
+ if (scope0 == LDAP_SCOPE_ONELEVEL &&
+ dn_match(pdn, &ndn))
+ {
+ op->ors_scope = LDAP_SCOPE_BASE;
+ op->o_req_dn = op->o_bd->be_suffix[0];
+ op->o_req_ndn = op->o_bd->be_nsuffix[0];
+ rs->sr_err = op->o_bd->be_search(op, rs);
+
+ } else if (scope0 == LDAP_SCOPE_SUBTREE &&
+ dn_match(&op->o_bd->be_nsuffix[0], &ndn))
+ {
+ rs->sr_err = op->o_bd->be_search( op, rs );
+
+ } else if (scope0 == LDAP_SCOPE_SUBTREE &&
+ dnIsSuffix(&op->o_bd->be_nsuffix[0], &ndn))
+ {
+ op->o_req_dn = op->o_bd->be_suffix[0];
+ op->o_req_ndn = op->o_bd->be_nsuffix[0];
+ rs->sr_err = op->o_bd->be_search( op, rs );
+ if ( rs->sr_err == LDAP_NO_SUCH_OBJECT ) {
+ gs.err = LDAP_SUCCESS;
+ }
+
+ } else if (dnIsSuffix(&ndn, &op->o_bd->be_nsuffix[0])) {
+ rs->sr_err = op->o_bd->be_search( op, rs );
+ }
+
+ switch ( gs.err ) {
+
+ /*
+ * Add errors that should result in dropping
+ * the search
+ */
+ case LDAP_SIZELIMIT_EXCEEDED:
+ case LDAP_TIMELIMIT_EXCEEDED:
+ case LDAP_ADMINLIMIT_EXCEEDED:
+ case LDAP_NO_SUCH_OBJECT:
+#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
+ case LDAP_CANNOT_CHAIN:
+#endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
+ goto end_of_loop;
+
+ default:
+ break;
+ }
+ }
+end_of_loop:;
+ op->ors_scope = scope0;
+ op->ors_slimit = slimit0;
+ op->ors_tlimit = tlimit0;
+ op->o_req_dn = dn;
+ op->o_req_ndn = ndn;
+
+ break;
+ }
+ if ( op->o_abandon ) {
+ rs->sr_err = SLAPD_ABANDON;
+ } else {
+ op->o_callback = cb.sc_next;
+ rs->sr_err = gs.err;
+ rs->sr_matched = gs.matched;
+ rs->sr_ref = gs.refs;
+
+ send_ldap_result( op, rs );
+ }
+
+ op->o_bd = b0;
+ op->o_bd->bd_info = bi0;
+ if (gs.matched)
+ free (gs.matched);
+ if (gs.refs)
+ ber_bvarray_free(gs.refs);
+ return rs->sr_err;
+}
+
+static BackendDB toolDB;
+
+static int
+glue_tool_entry_open (
+ BackendDB *b0,
+ int mode
+)
+{
+ slap_overinfo *oi = (slap_overinfo *)b0->bd_info;
+
+ /* We don't know which backend to talk to yet, so just
+ * remember the mode and move on...
+ */
+
+ glueMode = mode;
+ glueBack = NULL;
+ toolDB = *b0;
+ toolDB.bd_info = oi->oi_orig;
+
+ return 0;
+}
+
+static int
+glue_tool_entry_close (
+ BackendDB *b0
+)
+{
+ int rc = 0;
+
+ if (glueBack) {
+ if (!glueBack->be_entry_close)
+ return 0;
+ rc = glueBack->be_entry_close (glueBack);
+ }
+ return rc;
+}
+
+static slap_overinst *
+glue_tool_inst(
+ BackendInfo *bi
+)
+{
+ slap_overinfo *oi = (slap_overinfo *)bi;
+ slap_overinst *on;
+
+ for ( on = oi->oi_list; on; on=on->on_next ) {
+ if ( !strcmp( on->on_bi.bi_type, glue.on_bi.bi_type ))
+ return on;
+ }
+ return NULL;
+}
+
+/* This function will only be called in tool mode */
+static int
+glue_open (
+ BackendInfo *bi
+)
+{
+ slap_overinst *on = glue_tool_inst( bi );
+ glueinfo *gi = on->on_bi.bi_private;
+ static int glueOpened = 0;
+ int i, j, same, bsame = 0, rc = 0;
+
+ if (glueOpened) return 0;
+
+ glueOpened = 1;
+
+ /* If we were invoked in tool mode, open all the underlying backends */
+ if (slapMode & SLAP_TOOL_MODE) {
+ for (i = 0; i<gi->gi_nodes; i++) {
+ same = 0;
+ /* Same type as our main backend? */
+ if ( gi->gi_n[i].gn_be->bd_info == on->on_info->oi_orig )
+ bsame = 1;
+
+ /* Loop thru the bd_info's and make sure we only
+ * invoke their bi_open functions once each.
+ */
+ for ( j = 0; j<i; j++ ) {
+ if ( gi->gi_n[i].gn_be->bd_info ==
+ gi->gi_n[j].gn_be->bd_info ) {
+ same = 1;
+ break;
+ }
+ }
+ /* OK, it's unique and non-NULL, call it. */
+ if ( !same && gi->gi_n[i].gn_be->bd_info->bi_open )
+ rc = gi->gi_n[i].gn_be->bd_info->bi_open(
+ gi->gi_n[i].gn_be->bd_info );
+ /* Let backend.c take care of the rest of startup */
+ if ( !rc )
+ rc = backend_startup_one( gi->gi_n[i].gn_be );
+ if ( rc ) break;
+ }
+ if ( !rc && !bsame && on->on_info->oi_orig->bi_open )
+ rc = on->on_info->oi_orig->bi_open( on->on_info->oi_orig );
+
+ } /* other case is impossible */
+ return rc;
+}
+
+/* This function will only be called in tool mode */
+static int
+glue_close (
+ BackendInfo *bi
+)
+{
+ static int glueClosed = 0;
+ int rc = 0;
+
+ if (glueClosed) return 0;
+
+ glueClosed = 1;
+
+ if (slapMode & SLAP_TOOL_MODE) {
+ rc = backend_shutdown( NULL );
+ }
+ return rc;
+}
+
+static int
+glue_entry_release_rw (
+ Operation *op,
+ Entry *e,
+ int rw
+)
+{
+ BackendDB *b0, b2;
+ int rc = -1;
+
+ b0 = op->o_bd;
+ b2 = *op->o_bd;
+ b2.bd_info = (BackendInfo *)glue_tool_inst( op->o_bd->bd_info );
+ op->o_bd = glue_back_select (&b2, &e->e_nname);
+
+ if ( op->o_bd->be_release ) {
+ rc = op->o_bd->be_release( op, e, rw );
+
+ } else {
+ /* FIXME: mimic be_entry_release_rw
+ * when no be_release() available */
+ /* free entry */
+ entry_free( e );
+ rc = 0;
+ }
+ op->o_bd = b0;
+ return rc;
+}
+
+static ID
+glue_tool_entry_first (
+ BackendDB *b0
+)
+{
+ slap_overinst *on = glue_tool_inst( b0->bd_info );
+ glueinfo *gi = on->on_bi.bi_private;
+ int i;
+
+ /* If we're starting from scratch, start at the most general */
+ if (!glueBack) {
+ if ( toolDB.be_entry_open && toolDB.be_entry_first ) {
+ glueBack = &toolDB;
+ } else {
+ for (i = gi->gi_nodes-1; i >= 0; i--) {
+ if (gi->gi_n[i].gn_be->be_entry_open &&
+ gi->gi_n[i].gn_be->be_entry_first) {
+ glueBack = gi->gi_n[i].gn_be;
+ break;
+ }
+ }
+ }
+ }
+ if (!glueBack || !glueBack->be_entry_open || !glueBack->be_entry_first ||
+ glueBack->be_entry_open (glueBack, glueMode) != 0)
+ return NOID;
+
+ return glueBack->be_entry_first (glueBack);
+}
+
+static ID
+glue_tool_entry_next (
+ BackendDB *b0
+)
+{
+ slap_overinst *on = glue_tool_inst( b0->bd_info );
+ glueinfo *gi = on->on_bi.bi_private;
+ int i;
+ ID rc;
+
+ if (!glueBack || !glueBack->be_entry_next)
+ return NOID;
+
+ rc = glueBack->be_entry_next (glueBack);
+
+ /* If we ran out of entries in one database, move on to the next */
+ while (rc == NOID) {
+ if ( glueBack && glueBack->be_entry_close )
+ glueBack->be_entry_close (glueBack);
+ for (i=0; i<gi->gi_nodes; i++) {
+ if (gi->gi_n[i].gn_be == glueBack)
+ break;
+ }
+ if (i == 0) {
+ glueBack = NULL;
+ break;
+ } else {
+ glueBack = gi->gi_n[i-1].gn_be;
+ rc = glue_tool_entry_first (b0);
+ }
+ }
+ return rc;
+}
+
+static Entry *
+glue_tool_entry_get (
+ BackendDB *b0,
+ ID id
+)
+{
+ if (!glueBack || !glueBack->be_entry_get)
+ return NULL;
+
+ return glueBack->be_entry_get (glueBack, id);
+}
+
+static ID
+glue_tool_entry_put (
+ BackendDB *b0,
+ Entry *e,
+ struct berval *text
+)
+{
+ BackendDB *be, b2;
+ int rc = -1;
+
+ b2 = *b0;
+ b2.bd_info = (BackendInfo *)glue_tool_inst( b0->bd_info );
+ be = glue_back_select (&b2, &e->e_nname);
+ if ( be == &b2 ) be = &toolDB;
+
+ if (!be->be_entry_put)
+ return NOID;
+
+ if (!glueBack) {
+ if ( be->be_entry_open ) {
+ rc = be->be_entry_open (be, glueMode);
+ }
+ if (rc != 0) {
+ return NOID;
+ }
+ } else if (be != glueBack) {
+ /* If this entry belongs in a different branch than the
+ * previous one, close the current database and open the
+ * new one.
+ */
+ if ( glueBack->be_entry_close ) {
+ glueBack->be_entry_close (glueBack);
+ }
+ if ( be->be_entry_open ) {
+ rc = be->be_entry_open (be, glueMode);
+ }
+ if (rc != 0) {
+ return NOID;
+ }
+ }
+ glueBack = be;
+ return be->be_entry_put (be, e, text);
+}
+
+static int
+glue_tool_entry_reindex (
+ BackendDB *b0,
+ ID id
+)
+{
+ if (!glueBack || !glueBack->be_entry_reindex)
+ return -1;
+
+ return glueBack->be_entry_reindex (glueBack, id);
+}
+
+static int
+glue_tool_sync (
+ BackendDB *b0
+)
+{
+ slap_overinst *on = glue_tool_inst( b0->bd_info );
+ glueinfo *gi = on->on_bi.bi_private;
+ BackendInfo *bi = b0->bd_info;
+ int i;
+
+ /* just sync everyone */
+ for (i = 0; i<gi->gi_nodes; i++)
+ if (gi->gi_n[i].gn_be->be_sync)
+ gi->gi_n[i].gn_be->be_sync (gi->gi_n[i].gn_be);
+ b0->bd_info = on->on_info->oi_orig;
+ if ( b0->be_sync )
+ b0->be_sync( b0 );
+ b0->bd_info = bi;
+ return 0;
+}
+
+static int
+glue_db_init(
+ BackendDB *be
+)
+{
+ slap_overinst *on = (slap_overinst *)be->bd_info;
+ slap_overinfo *oi = on->on_info;
+ glueinfo *gi;
+
+ gi = ch_calloc( 1, sizeof(glueinfo));
+ on->on_bi.bi_private = gi;
+ dnParent( be->be_nsuffix, &gi->gi_pdn );
+
+ /* Currently the overlay framework doesn't handle these entry points
+ * but we need them....
+ */
+ oi->oi_bi.bi_open = glue_open;
+ oi->oi_bi.bi_close = glue_close;
+
+ oi->oi_bi.bi_entry_release_rw = glue_entry_release_rw;
+
+ oi->oi_bi.bi_tool_entry_open = glue_tool_entry_open;
+ oi->oi_bi.bi_tool_entry_close = glue_tool_entry_close;
+ oi->oi_bi.bi_tool_entry_first = glue_tool_entry_first;
+ oi->oi_bi.bi_tool_entry_next = glue_tool_entry_next;
+ oi->oi_bi.bi_tool_entry_get = glue_tool_entry_get;
+ oi->oi_bi.bi_tool_entry_put = glue_tool_entry_put;
+ oi->oi_bi.bi_tool_entry_reindex = glue_tool_entry_reindex;
+ oi->oi_bi.bi_tool_sync = glue_tool_sync;
+
+ /*FIXME : need to add support */
+ oi->oi_bi.bi_tool_dn2id_get = 0;
+ oi->oi_bi.bi_tool_id2entry_get = 0;
+ oi->oi_bi.bi_tool_entry_modify = 0;
+
+ SLAP_DBFLAGS( be ) |= SLAP_DBFLAG_GLUE_INSTANCE;
+
+ return 0;
+}
+
+static int
+glue_db_destroy (
+ BackendDB *be
+)
+{
+ slap_overinst *on = (slap_overinst *)be->bd_info;
+ glueinfo *gi = (glueinfo *)on->on_bi.bi_private;
+
+ free (gi);
+ return SLAP_CB_CONTINUE;
+}
+
+static int
+glue_db_close(
+ BackendDB *be
+)
+{
+ slap_overinst *on = (slap_overinst *)be->bd_info;
+
+ on->on_info->oi_bi.bi_db_close = NULL;
+ return 0;
+}
+
+int
+glue_sub_del( BackendDB *b0 )
+{
+ BackendDB *be;
+ int rc = 0;
+
+ /* Find the top backend for this subordinate */
+ be = b0;
+ while ( be=LDAP_STAILQ_NEXT( be, be_next )) {
+ slap_overinfo *oi;
+ slap_overinst *on;
+ glueinfo *gi;
+ int i;
+
+ if ( SLAP_GLUE_SUBORDINATE( be ))
+ continue;
+ if ( !SLAP_GLUE_INSTANCE( be ))
+ continue;
+ if ( !dnIsSuffix( &b0->be_nsuffix[0], &be->be_nsuffix[0] ))
+ continue;
+
+ /* OK, got the right backend, find the overlay */
+ oi = (slap_overinfo *)be->bd_info;
+ for ( on=oi->oi_list; on; on=on->on_next ) {
+ if ( on->on_bi.bi_type == glue.on_bi.bi_type )
+ break;
+ }
+ assert( on != NULL );
+ gi = on->on_bi.bi_private;
+ for ( i=0; i < gi->gi_nodes; i++ ) {
+ if ( gi->gi_n[i].gn_be == b0 ) {
+ int j;
+
+ for (j=i+1; j < gi->gi_nodes; j++)
+ gi->gi_n[j-1] = gi->gi_n[j];
+
+ gi->gi_nodes--;
+ }
+ }
+ }
+ if ( be == NULL )
+ rc = LDAP_NO_SUCH_OBJECT;
+
+ return rc;
+}
+
+typedef struct glue_Addrec {
+ struct glue_Addrec *ga_next;
+ BackendDB *ga_be;
+} glue_Addrec;
+
+/* List of added subordinates */
+static glue_Addrec *ga_list;
+
+/* Attach all the subordinate backends to their superior */
+static int
+glue_sub_attach()
+{
+ glue_Addrec *ga, *gnext = NULL;
+ int rc = 0;
+
+ /* For all the subordinate backends */
+ for ( ga=ga_list; ga != NULL; ga = gnext ) {
+ BackendDB *be;
+
+ gnext = ga->ga_next;
+
+ /* Find the top backend for this subordinate */
+ be = ga->ga_be;
+ while ( be=LDAP_STAILQ_NEXT( be, be_next )) {
+ slap_overinfo *oi;
+ slap_overinst *on;
+ glueinfo *gi;
+
+ if ( SLAP_GLUE_SUBORDINATE( be ))
+ continue;
+ if ( !dnIsSuffix( &ga->ga_be->be_nsuffix[0], &be->be_nsuffix[0] ))
+ continue;
+
+ /* If it's not already configured, set up the overlay */
+ if ( !SLAP_GLUE_INSTANCE( be )) {
+ rc = overlay_config( be, glue.on_bi.bi_type );
+ if ( rc )
+ break;
+ }
+ /* Find the overlay instance */
+ oi = (slap_overinfo *)be->bd_info;
+ for ( on=oi->oi_list; on; on=on->on_next ) {
+ if ( on->on_bi.bi_type == glue.on_bi.bi_type )
+ break;
+ }
+ assert( on != NULL );
+ gi = on->on_bi.bi_private;
+ gi = (glueinfo *)ch_realloc( gi, sizeof(glueinfo) +
+ gi->gi_nodes * sizeof(gluenode));
+ gi->gi_n[gi->gi_nodes].gn_be = ga->ga_be;
+ dnParent( &ga->ga_be->be_nsuffix[0],
+ &gi->gi_n[gi->gi_nodes].gn_pdn );
+ gi->gi_nodes++;
+ on->on_bi.bi_private = gi;
+ break;
+ }
+ if ( !be ) {
+ Debug( LDAP_DEBUG_ANY, "glue: no superior found for sub %s!\n",
+ ga->ga_be->be_suffix[0].bv_val, 0, 0 );
+ rc = LDAP_NO_SUCH_OBJECT;
+ }
+ ch_free( ga );
+ if ( rc ) break;
+ }
+
+ ga_list = gnext;
+
+ return rc;
+}
+
+int
+glue_sub_add( BackendDB *be, int advert, int online )
+{
+ glue_Addrec *ga;
+ int rc = 0;
+
+ SLAP_DBFLAGS( be ) |= SLAP_DBFLAG_GLUE_SUBORDINATE;
+ if ( advert )
+ SLAP_DBFLAGS( be ) |= SLAP_DBFLAG_GLUE_ADVERTISE;
+
+ ga = ch_malloc( sizeof( glue_Addrec ));
+ ga->ga_next = NULL;
+ ga->ga_be = be;
+ if ( ga_list ) {
+ glue_Addrec *g2 = ga_list;
+
+ for ( ; g2 && g2->ga_next; g2=g2->ga_next );
+ g2->ga_next = ga;
+ } else {
+ ga_list = ga;
+ }
+
+ if ( online )
+ rc = glue_sub_attach();
+
+ return rc;
+}
+
+int
+glue_sub_init()
+{
+ int rc;
+
+ glue.on_bi.bi_type = "glue";
+
+ glue.on_bi.bi_db_init = glue_db_init;
+ glue.on_bi.bi_db_close = glue_db_close;
+ glue.on_bi.bi_db_destroy = glue_db_destroy;
+
+ glue.on_bi.bi_op_search = glue_op_search;
+ glue.on_bi.bi_op_modify = glue_op_func;
+ glue.on_bi.bi_op_modrdn = glue_op_func;
+ glue.on_bi.bi_op_add = glue_op_func;
+ glue.on_bi.bi_op_delete = glue_op_func;
+
+ glue.on_bi.bi_chk_referrals = glue_chk_referrals;
+ glue.on_bi.bi_chk_controls = glue_chk_controls;
+
+ rc = overlay_register( &glue );
+ if ( rc ) return rc;
+
+ return glue_sub_attach();
+}
static ConfigDriver config_sizelimit;
static ConfigDriver config_timelimit;
static ConfigDriver config_overlay;
+static ConfigDriver config_subordinate;
static ConfigDriver config_suffix;
static ConfigDriver config_rootdn;
static ConfigDriver config_rootpw;
#endif
"( OLcfgGlAt:63 NAME 'olcSrvtab' "
"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
+ { "subordinate", "[advertise]", 1, 2, 0, ARG_DB|ARG_MAGIC,
+ &config_subordinate, "( OLcfgDbAt:0.15 NAME 'olcSubordinate' "
+ "SYNTAX OMsDirectoryString )", NULL, NULL },
{ "suffix", "suffix", 2, 2, 0, ARG_DB|ARG_DN|ARG_QUOTE|ARG_MAGIC,
&config_suffix, "( OLcfgDbAt:0.10 NAME 'olcSuffix' "
"SYNTAX OMsDN )", NULL, NULL },
"DESC 'OpenLDAP Database-specific options' "
"SUP olcConfig STRUCTURAL "
"MUST olcDatabase "
- "MAY ( olcSuffix $ olcAccess $ olcLastMod $ olcLimits $ "
+ "MAY ( olcSuffix $ olcSubordinate $ olcAccess $ olcLastMod $ olcLimits $ "
"olcMaxDerefDepth $ olcPlugin $ olcReadOnly $ olcReplica $ "
"olcReplogFile $ olcRequires $ olcRestrict $ olcRootDN $ olcRootPW $ "
"olcSchemaDN $ olcSecurity $ olcSizeLimit $ olcSyncrepl $ "
return(0);
}
+static int
+config_subordinate(ConfigArgs *c)
+{
+ int rc = 1;
+ int advertise;
+
+ switch( c->op ) {
+ case SLAP_CONFIG_EMIT:
+ if ( SLAP_GLUE_SUBORDINATE( c->be )) {
+ struct berval bv;
+
+ bv.bv_val = SLAP_GLUE_ADVERTISE( c->be ) ? "advertise" : "TRUE";
+ bv.bv_len = SLAP_GLUE_ADVERTISE( c->be ) ? STRLENOF("advertise") :
+ STRLENOF("TRUE");
+
+ value_add_one( &c->rvalue_vals, &bv );
+ rc = 0;
+ }
+ break;
+ case LDAP_MOD_DELETE:
+ if ( !c->line || strcasecmp( c->line, "advertise" )) {
+ glue_sub_del( c->be );
+ } else {
+ SLAP_DBFLAGS( c->be ) &= ~SLAP_DBFLAG_GLUE_ADVERTISE;
+ }
+ rc = 0;
+ break;
+ case LDAP_MOD_ADD:
+ case SLAP_CONFIG_ADD:
+ advertise = ( c->argc == 2 && !strcasecmp( c->argv[1], "advertise" ));
+ rc = glue_sub_add( c->be, advertise, CONFIG_ONLINE_ADD( c ));
+ break;
+ }
+ return rc;
+}
+
static int
config_suffix(ConfigArgs *c)
{
}
}
+ if ( glue_sub_init( ) != 0 ) {
+ Debug( LDAP_DEBUG_ANY,
+ "subordinate config error\n",
+ 0, 0, 0 );
+
+ goto destroy;
+ }
+
if ( slap_schema_check( ) != 0 ) {
Debug( LDAP_DEBUG_ANY,
"schema prep error\n",
denyop.c \
dyngroup.c \
dynlist.c \
- glue.c \
lastmod.c \
pcache.c \
ppolicy.c \
dynlist.la : dynlist.lo
$(LTLINK_MOD) -module -o $@ dynlist.lo version.lo $(LINK_LIBS)
-glue.la : glue.lo
- $(LTLINK_MOD) -module -o $@ glue.lo version.lo $(LINK_LIBS)
-
lastmod.la : lastmod.lo
$(LTLINK_MOD) -module -o $@ lastmod.lo version.lo $(LINK_LIBS)
+++ /dev/null
-/* glue.c - backend glue overlay */
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 2001-2005 The OpenLDAP Foundation.
- * 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>.
- */
-
-/*
- * Functions to glue a bunch of other backends into a single tree.
- * All of the glued backends must share a common suffix. E.g., you
- * can glue o=foo and ou=bar,o=foo but you can't glue o=foo and o=bar.
- *
- * The purpose of these functions is to allow you to split a single database
- * into pieces (for load balancing purposes, whatever) but still be able
- * to treat it as a single database after it's been split. As such, each
- * of the glued backends should have identical rootdn.
- * -- Howard Chu
- */
-
-#include "portable.h"
-
-#ifdef SLAPD_OVER_GLUE
-
-#include <stdio.h>
-
-#include <ac/string.h>
-#include <ac/socket.h>
-
-#define SLAPD_TOOLS
-#include "slap.h"
-
-typedef struct gluenode {
- BackendDB *gn_be;
- struct berval gn_pdn;
- int gn_async;
-} gluenode;
-
-typedef struct glueinfo {
- int gi_nodes;
- struct berval gi_pdn;
- gluenode gi_n[1];
-} glueinfo;
-
-static slap_overinst glue;
-
-static int glueMode;
-static BackendDB *glueBack;
-
-static slap_response glue_op_response;
-
-/* Just like select_backend, but only for our backends */
-static BackendDB *
-glue_back_select (
- BackendDB *be,
- struct berval *dn
-)
-{
- slap_overinst *on = (slap_overinst *)be->bd_info;
- glueinfo *gi = (glueinfo *)on->on_bi.bi_private;
- int i;
-
- for (i = 0; i<gi->gi_nodes; i++) {
- assert( gi->gi_n[i].gn_be->be_nsuffix != NULL );
-
- if (dnIsSuffix(dn, &gi->gi_n[i].gn_be->be_nsuffix[0])) {
- return gi->gi_n[i].gn_be;
- }
- }
- be->bd_info = on->on_info->oi_orig;
- return be;
-}
-
-
-typedef struct glue_state {
- int err;
- int slimit;
- int matchlen;
- char *matched;
- int nrefs;
- BerVarray refs;
-} glue_state;
-
-static int
-glue_op_response ( Operation *op, SlapReply *rs )
-{
- glue_state *gs = op->o_callback->sc_private;
-
- switch(rs->sr_type) {
- case REP_SEARCH:
- if ( gs->slimit != SLAP_NO_LIMIT
- && rs->sr_nentries >= gs->slimit )
- {
- rs->sr_err = gs->err = LDAP_SIZELIMIT_EXCEEDED;
- return -1;
- }
- /* fallthru */
- case REP_SEARCHREF:
- return SLAP_CB_CONTINUE;
-
- default:
- if (rs->sr_err == LDAP_SUCCESS ||
- rs->sr_err == LDAP_SIZELIMIT_EXCEEDED ||
- rs->sr_err == LDAP_TIMELIMIT_EXCEEDED ||
- rs->sr_err == LDAP_ADMINLIMIT_EXCEEDED ||
- rs->sr_err == LDAP_NO_SUCH_OBJECT ||
- gs->err != LDAP_SUCCESS)
- gs->err = rs->sr_err;
- if (gs->err == LDAP_SUCCESS && gs->matched) {
- ch_free (gs->matched);
- gs->matched = NULL;
- gs->matchlen = 0;
- }
- if (gs->err != LDAP_SUCCESS && rs->sr_matched) {
- int len;
- len = strlen (rs->sr_matched);
- if (len > gs->matchlen) {
- if (gs->matched)
- ch_free (gs->matched);
- gs->matched = ch_strdup (rs->sr_matched);
- gs->matchlen = len;
- }
- }
- if (rs->sr_ref) {
- int i, j, k;
- BerVarray new;
-
- for (i=0; rs->sr_ref[i].bv_val; i++);
-
- j = gs->nrefs;
- if (!j) {
- new = ch_malloc ((i+1)*sizeof(struct berval));
- } else {
- new = ch_realloc(gs->refs,
- (j+i+1)*sizeof(struct berval));
- }
- for (k=0; k<i; j++,k++) {
- ber_dupbv( &new[j], &rs->sr_ref[k] );
- }
- new[j].bv_val = NULL;
- gs->nrefs = j;
- gs->refs = new;
- }
- }
- return 0;
-}
-
-static int
-glue_op_func ( Operation *op, SlapReply *rs )
-{
- slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
- BackendDB *b0 = op->o_bd;
- BackendInfo *bi0 = op->o_bd->bd_info;
- BI_op_modify **func;
- slap_operation_t which;
- int rc;
-
- op->o_bd = glue_back_select (b0, &op->o_req_ndn);
- b0->bd_info = on->on_info->oi_orig;
-
- switch(op->o_tag) {
- case LDAP_REQ_ADD: which = op_add; break;
- case LDAP_REQ_DELETE: which = op_delete; break;
- case LDAP_REQ_MODIFY: which = op_modify; break;
- case LDAP_REQ_MODRDN: which = op_modrdn; break;
- }
-
- func = &op->o_bd->bd_info->bi_op_bind;
- if ( func[which] )
- rc = func[which]( op, rs );
- else
- rc = SLAP_CB_CONTINUE;
-
- op->o_bd = b0;
- op->o_bd->bd_info = bi0;
- return rc;
-}
-
-static int
-glue_chk_referrals ( Operation *op, SlapReply *rs )
-{
- slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
- BackendDB *b0 = op->o_bd;
- BackendInfo *bi0 = op->o_bd->bd_info;
- int rc;
-
- op->o_bd = glue_back_select (b0, &op->o_req_ndn);
- b0->bd_info = on->on_info->oi_orig;
-
- if ( op->o_bd->bd_info->bi_chk_referrals )
- rc = ( *op->o_bd->bd_info->bi_chk_referrals )( op, rs );
- else
- rc = SLAP_CB_CONTINUE;
-
- op->o_bd = b0;
- op->o_bd->bd_info = bi0;
- return rc;
-}
-
-static int
-glue_chk_controls ( Operation *op, SlapReply *rs )
-{
- slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
- BackendDB *b0 = op->o_bd;
- BackendInfo *bi0 = op->o_bd->bd_info;
- int rc = SLAP_CB_CONTINUE;
-
- op->o_bd = glue_back_select (b0, &op->o_req_ndn);
- b0->bd_info = on->on_info->oi_orig;
-
- /* if the subordinate database has overlays, the bi_chk_controls()
- * hook is actually over_aux_chk_controls(); in case it actually
- * wraps a missing hok, we need to mimic the behavior
- * of the frontend applied to that database */
- if ( op->o_bd->bd_info->bi_chk_controls ) {
- rc = ( *op->o_bd->bd_info->bi_chk_controls )( op, rs );
- }
-
-
- if ( rc == SLAP_CB_CONTINUE ) {
- rc = backend_check_controls( op, rs );
- }
-
- op->o_bd = b0;
- op->o_bd->bd_info = bi0;
- return rc;
-}
-
-static int
-glue_op_search ( Operation *op, SlapReply *rs )
-{
- slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
- glueinfo *gi = (glueinfo *)on->on_bi.bi_private;
- BackendDB *b0 = op->o_bd;
- BackendDB *b1 = NULL, *btmp;
- BackendInfo *bi0 = op->o_bd->bd_info;
- int i;
- long stoptime = 0;
- glue_state gs = {0, 0, 0, NULL, 0, NULL};
- slap_callback cb = { NULL, glue_op_response, NULL, NULL };
- int scope0, slimit0, tlimit0;
- struct berval dn, ndn, *pdn;
-
- cb.sc_private = &gs;
-
- cb.sc_next = op->o_callback;
-
- stoptime = slap_get_time () + op->ors_tlimit;
-
- op->o_bd = glue_back_select (b0, &op->o_req_ndn);
- b0->bd_info = on->on_info->oi_orig;
-
- switch (op->ors_scope) {
- case LDAP_SCOPE_BASE:
- rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
- if (op->o_bd && op->o_bd->be_search) {
- rs->sr_err = op->o_bd->be_search( op, rs );
- }
- return rs->sr_err;
-
- case LDAP_SCOPE_ONELEVEL:
- case LDAP_SCOPE_SUBTREE:
-#ifdef LDAP_SCOPE_SUBORDINATE
- case LDAP_SCOPE_SUBORDINATE: /* FIXME */
-#endif
-
-#if 0
- if ( op->o_sync ) {
- if (op->o_bd && op->o_bd->be_search) {
- rs->sr_err = op->o_bd->be_search( op, rs );
- } else {
- send_ldap_error(op, rs, LDAP_UNWILLING_TO_PERFORM,
- "No search target found");
- }
- return rs->sr_err;
- }
-#endif
-
- op->o_callback = &cb;
- rs->sr_err = gs.err = LDAP_UNWILLING_TO_PERFORM;
- scope0 = op->ors_scope;
- slimit0 = gs.slimit = op->ors_slimit;
- tlimit0 = op->ors_tlimit;
- dn = op->o_req_dn;
- ndn = op->o_req_ndn;
- b1 = op->o_bd;
-
- /*
- * Execute in reverse order, most general first
- */
- for (i = gi->gi_nodes; i >= 0; i--) {
- if ( i == gi->gi_nodes ) {
- btmp = b0;
- pdn = &gi->gi_pdn;
- } else {
- btmp = gi->gi_n[i].gn_be;
- pdn = &gi->gi_n[i].gn_pdn;
- }
- if (!btmp || !btmp->be_search)
- continue;
- if (!dnIsSuffix(&btmp->be_nsuffix[0], &b1->be_nsuffix[0]))
- continue;
- if (tlimit0 != SLAP_NO_LIMIT) {
- op->ors_tlimit = stoptime - slap_get_time ();
- if (op->ors_tlimit <= 0) {
- rs->sr_err = gs.err = LDAP_TIMELIMIT_EXCEEDED;
- break;
- }
- }
- if (slimit0 != SLAP_NO_LIMIT) {
- op->ors_slimit = slimit0 - rs->sr_nentries;
- if (op->ors_slimit < 0) {
- rs->sr_err = gs.err = LDAP_SIZELIMIT_EXCEEDED;
- break;
- }
- }
- rs->sr_err = 0;
- /*
- * check for abandon
- */
- if (op->o_abandon) {
- goto end_of_loop;
- }
- op->o_bd = btmp;
-
- assert( op->o_bd->be_suffix != NULL );
- assert( op->o_bd->be_nsuffix != NULL );
-
- if (scope0 == LDAP_SCOPE_ONELEVEL &&
- dn_match(pdn, &ndn))
- {
- op->ors_scope = LDAP_SCOPE_BASE;
- op->o_req_dn = op->o_bd->be_suffix[0];
- op->o_req_ndn = op->o_bd->be_nsuffix[0];
- rs->sr_err = op->o_bd->be_search(op, rs);
-
- } else if (scope0 == LDAP_SCOPE_SUBTREE &&
- dn_match(&op->o_bd->be_nsuffix[0], &ndn))
- {
- rs->sr_err = op->o_bd->be_search( op, rs );
-
- } else if (scope0 == LDAP_SCOPE_SUBTREE &&
- dnIsSuffix(&op->o_bd->be_nsuffix[0], &ndn))
- {
- op->o_req_dn = op->o_bd->be_suffix[0];
- op->o_req_ndn = op->o_bd->be_nsuffix[0];
- rs->sr_err = op->o_bd->be_search( op, rs );
- if ( rs->sr_err == LDAP_NO_SUCH_OBJECT ) {
- gs.err = LDAP_SUCCESS;
- }
-
- } else if (dnIsSuffix(&ndn, &op->o_bd->be_nsuffix[0])) {
- rs->sr_err = op->o_bd->be_search( op, rs );
- }
-
- switch ( gs.err ) {
-
- /*
- * Add errors that should result in dropping
- * the search
- */
- case LDAP_SIZELIMIT_EXCEEDED:
- case LDAP_TIMELIMIT_EXCEEDED:
- case LDAP_ADMINLIMIT_EXCEEDED:
- case LDAP_NO_SUCH_OBJECT:
-#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
- case LDAP_CANNOT_CHAIN:
-#endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
- goto end_of_loop;
-
- default:
- break;
- }
- }
-end_of_loop:;
- op->ors_scope = scope0;
- op->ors_slimit = slimit0;
- op->ors_tlimit = tlimit0;
- op->o_req_dn = dn;
- op->o_req_ndn = ndn;
-
- break;
- }
- if ( op->o_abandon ) {
- rs->sr_err = SLAPD_ABANDON;
- } else {
- op->o_callback = cb.sc_next;
- rs->sr_err = gs.err;
- rs->sr_matched = gs.matched;
- rs->sr_ref = gs.refs;
-
- send_ldap_result( op, rs );
- }
-
- op->o_bd = b0;
- op->o_bd->bd_info = bi0;
- if (gs.matched)
- free (gs.matched);
- if (gs.refs)
- ber_bvarray_free(gs.refs);
- return rs->sr_err;
-}
-
-static BackendDB toolDB;
-
-static int
-glue_tool_entry_open (
- BackendDB *b0,
- int mode
-)
-{
- slap_overinfo *oi = (slap_overinfo *)b0->bd_info;
-
- /* We don't know which backend to talk to yet, so just
- * remember the mode and move on...
- */
-
- glueMode = mode;
- glueBack = NULL;
- toolDB = *b0;
- toolDB.bd_info = oi->oi_orig;
-
- return 0;
-}
-
-static int
-glue_tool_entry_close (
- BackendDB *b0
-)
-{
- int rc = 0;
-
- if (glueBack) {
- if (!glueBack->be_entry_close)
- return 0;
- rc = glueBack->be_entry_close (glueBack);
- }
- return rc;
-}
-
-static slap_overinst *
-glue_tool_inst(
- BackendInfo *bi
-)
-{
- slap_overinfo *oi = (slap_overinfo *)bi;
- slap_overinst *on;
-
- for ( on = oi->oi_list; on; on=on->on_next ) {
- if ( !strcmp( on->on_bi.bi_type, glue.on_bi.bi_type ))
- return on;
- }
- return NULL;
-}
-
-/* This function will only be called in tool mode */
-static int
-glue_open (
- BackendInfo *bi
-)
-{
- slap_overinst *on = glue_tool_inst( bi );
- glueinfo *gi = on->on_bi.bi_private;
- static int glueOpened = 0;
- int i, j, same, bsame = 0, rc = 0;
-
- if (glueOpened) return 0;
-
- glueOpened = 1;
-
- /* If we were invoked in tool mode, open all the underlying backends */
- if (slapMode & SLAP_TOOL_MODE) {
- for (i = 0; i<gi->gi_nodes; i++) {
- same = 0;
- /* Same type as our main backend? */
- if ( gi->gi_n[i].gn_be->bd_info == on->on_info->oi_orig )
- bsame = 1;
-
- /* Loop thru the bd_info's and make sure we only
- * invoke their bi_open functions once each.
- */
- for ( j = 0; j<i; j++ ) {
- if ( gi->gi_n[i].gn_be->bd_info ==
- gi->gi_n[j].gn_be->bd_info ) {
- same = 1;
- break;
- }
- }
- /* OK, it's unique and non-NULL, call it. */
- if ( !same && gi->gi_n[i].gn_be->bd_info->bi_open )
- rc = gi->gi_n[i].gn_be->bd_info->bi_open(
- gi->gi_n[i].gn_be->bd_info );
- /* Let backend.c take care of the rest of startup */
- if ( !rc )
- rc = backend_startup_one( gi->gi_n[i].gn_be );
- if ( rc ) break;
- }
- if ( !rc && !bsame && on->on_info->oi_orig->bi_open )
- rc = on->on_info->oi_orig->bi_open( on->on_info->oi_orig );
-
- } /* other case is impossible */
- return rc;
-}
-
-/* This function will only be called in tool mode */
-static int
-glue_close (
- BackendInfo *bi
-)
-{
- static int glueClosed = 0;
- int rc = 0;
-
- if (glueClosed) return 0;
-
- glueClosed = 1;
-
- if (slapMode & SLAP_TOOL_MODE) {
- rc = backend_shutdown( NULL );
- }
- return rc;
-}
-
-static int
-glue_entry_release_rw (
- Operation *op,
- Entry *e,
- int rw
-)
-{
- BackendDB *b0, b2;
- int rc = -1;
-
- b0 = op->o_bd;
- b2 = *op->o_bd;
- b2.bd_info = (BackendInfo *)glue_tool_inst( op->o_bd->bd_info );
- op->o_bd = glue_back_select (&b2, &e->e_nname);
-
- if ( op->o_bd->be_release ) {
- rc = op->o_bd->be_release( op, e, rw );
-
- } else {
- /* FIXME: mimic be_entry_release_rw
- * when no be_release() available */
- /* free entry */
- entry_free( e );
- rc = 0;
- }
- op->o_bd = b0;
- return rc;
-}
-
-static ID
-glue_tool_entry_first (
- BackendDB *b0
-)
-{
- slap_overinst *on = glue_tool_inst( b0->bd_info );
- glueinfo *gi = on->on_bi.bi_private;
- int i;
-
- /* If we're starting from scratch, start at the most general */
- if (!glueBack) {
- if ( toolDB.be_entry_open && toolDB.be_entry_first ) {
- glueBack = &toolDB;
- } else {
- for (i = gi->gi_nodes-1; i >= 0; i--) {
- if (gi->gi_n[i].gn_be->be_entry_open &&
- gi->gi_n[i].gn_be->be_entry_first) {
- glueBack = gi->gi_n[i].gn_be;
- break;
- }
- }
- }
- }
- if (!glueBack || !glueBack->be_entry_open || !glueBack->be_entry_first ||
- glueBack->be_entry_open (glueBack, glueMode) != 0)
- return NOID;
-
- return glueBack->be_entry_first (glueBack);
-}
-
-static ID
-glue_tool_entry_next (
- BackendDB *b0
-)
-{
- slap_overinst *on = glue_tool_inst( b0->bd_info );
- glueinfo *gi = on->on_bi.bi_private;
- int i;
- ID rc;
-
- if (!glueBack || !glueBack->be_entry_next)
- return NOID;
-
- rc = glueBack->be_entry_next (glueBack);
-
- /* If we ran out of entries in one database, move on to the next */
- while (rc == NOID) {
- if ( glueBack && glueBack->be_entry_close )
- glueBack->be_entry_close (glueBack);
- for (i=0; i<gi->gi_nodes; i++) {
- if (gi->gi_n[i].gn_be == glueBack)
- break;
- }
- if (i == 0) {
- glueBack = NULL;
- break;
- } else {
- glueBack = gi->gi_n[i-1].gn_be;
- rc = glue_tool_entry_first (b0);
- }
- }
- return rc;
-}
-
-static Entry *
-glue_tool_entry_get (
- BackendDB *b0,
- ID id
-)
-{
- if (!glueBack || !glueBack->be_entry_get)
- return NULL;
-
- return glueBack->be_entry_get (glueBack, id);
-}
-
-static ID
-glue_tool_entry_put (
- BackendDB *b0,
- Entry *e,
- struct berval *text
-)
-{
- BackendDB *be, b2;
- int rc = -1;
-
- b2 = *b0;
- b2.bd_info = (BackendInfo *)glue_tool_inst( b0->bd_info );
- be = glue_back_select (&b2, &e->e_nname);
- if ( be == &b2 ) be = &toolDB;
-
- if (!be->be_entry_put)
- return NOID;
-
- if (!glueBack) {
- if ( be->be_entry_open ) {
- rc = be->be_entry_open (be, glueMode);
- }
- if (rc != 0) {
- return NOID;
- }
- } else if (be != glueBack) {
- /* If this entry belongs in a different branch than the
- * previous one, close the current database and open the
- * new one.
- */
- if ( glueBack->be_entry_close ) {
- glueBack->be_entry_close (glueBack);
- }
- if ( be->be_entry_open ) {
- rc = be->be_entry_open (be, glueMode);
- }
- if (rc != 0) {
- return NOID;
- }
- }
- glueBack = be;
- return be->be_entry_put (be, e, text);
-}
-
-static int
-glue_tool_entry_reindex (
- BackendDB *b0,
- ID id
-)
-{
- if (!glueBack || !glueBack->be_entry_reindex)
- return -1;
-
- return glueBack->be_entry_reindex (glueBack, id);
-}
-
-static int
-glue_tool_sync (
- BackendDB *b0
-)
-{
- slap_overinst *on = glue_tool_inst( b0->bd_info );
- glueinfo *gi = on->on_bi.bi_private;
- BackendInfo *bi = b0->bd_info;
- int i;
-
- /* just sync everyone */
- for (i = 0; i<gi->gi_nodes; i++)
- if (gi->gi_n[i].gn_be->be_sync)
- gi->gi_n[i].gn_be->be_sync (gi->gi_n[i].gn_be);
- b0->bd_info = on->on_info->oi_orig;
- if ( b0->be_sync )
- b0->be_sync( b0 );
- b0->bd_info = bi;
- return 0;
-}
-
-static int
-glue_db_init(
- BackendDB *be
-)
-{
- slap_overinst *on = (slap_overinst *)be->bd_info;
- slap_overinfo *oi = on->on_info;
- glueinfo *gi;
-
- gi = ch_calloc( 1, sizeof(glueinfo));
- on->on_bi.bi_private = gi;
- dnParent( be->be_nsuffix, &gi->gi_pdn );
-
- /* Currently the overlay framework doesn't handle these entry points
- * but we need them....
- */
- oi->oi_bi.bi_open = glue_open;
- oi->oi_bi.bi_close = glue_close;
-
- oi->oi_bi.bi_entry_release_rw = glue_entry_release_rw;
-
- oi->oi_bi.bi_tool_entry_open = glue_tool_entry_open;
- oi->oi_bi.bi_tool_entry_close = glue_tool_entry_close;
- oi->oi_bi.bi_tool_entry_first = glue_tool_entry_first;
- oi->oi_bi.bi_tool_entry_next = glue_tool_entry_next;
- oi->oi_bi.bi_tool_entry_get = glue_tool_entry_get;
- oi->oi_bi.bi_tool_entry_put = glue_tool_entry_put;
- oi->oi_bi.bi_tool_entry_reindex = glue_tool_entry_reindex;
- oi->oi_bi.bi_tool_sync = glue_tool_sync;
-
- /*FIXME : need to add support */
- oi->oi_bi.bi_tool_dn2id_get = 0;
- oi->oi_bi.bi_tool_id2entry_get = 0;
- oi->oi_bi.bi_tool_entry_modify = 0;
-
- return 0;
-}
-
-static int
-glue_db_destroy (
- BackendDB *be
-)
-{
- slap_overinst *on = (slap_overinst *)be->bd_info;
- glueinfo *gi = (glueinfo *)on->on_bi.bi_private;
-
- free (gi);
- return SLAP_CB_CONTINUE;
-}
-
-static int
-glue_db_close(
- BackendDB *be
-)
-{
- slap_overinst *on = (slap_overinst *)be->bd_info;
-
- on->on_info->oi_bi.bi_db_close = NULL;
- return 0;
-}
-
-static int
-glue_db_config(
- BackendDB *be,
- const char *fname,
- int lineno,
- int argc,
- char **argv
-)
-{
- slap_overinst *on = (slap_overinst *)be->bd_info;
- glueinfo *gi = (glueinfo *)on->on_bi.bi_private;
-
- /* redundant; could be applied just once */
- SLAP_DBFLAGS( be ) |= SLAP_DBFLAG_GLUE_INSTANCE;
-
- if ( strcasecmp( argv[0], "glue-sub" ) == 0 ) {
- int i, async = 0, advertise = 0;
- BackendDB *b2;
- struct berval bv, dn = BER_BVNULL;
-
- if ( argc < 2 ) {
- fprintf( stderr, "%s: line %d: too few arguments in "
- "\"glue-sub <suffixDN> [async] [advertise]\"\n", fname, lineno );
- return -1;
- }
- for ( i = 2; i < argc; i++ ) {
- if ( strcasecmp( argv[i], "async" ) == 0 ) {
- async = 1;
-
- } else if ( strcasecmp( argv[i], "advertise" ) == 0 ) {
- advertise = 1;
-
- } else {
- fprintf( stderr, "%s: line %d: unrecognized option "
- "\"%s\" ignored.\n", fname, lineno, argv[i] );
- }
- }
- ber_str2bv( argv[1], 0, 0, &bv );
- if ( dnNormalize( 0, NULL, NULL, &bv, &dn, NULL )) {
- fprintf( stderr, "invalid suffixDN \"%s\"\n", argv[1] );
- return -1;
- }
- b2 = select_backend( &dn, 0, 1 );
- ber_memfree( dn.bv_val );
- if ( !b2 ) {
- fprintf( stderr, "%s: line %d: unknown suffix \"%s\"\n",
- fname, lineno, argv[1] );
- return -1;
- }
- if ( SLAP_GLUE_INSTANCE( b2 )) {
- fprintf( stderr, "%s: line %d: backend for %s is already glued; "
- "only one glue overlay is allowed per tree.\n",
- fname, lineno, argv[1] );
- return -1;
- }
- SLAP_DBFLAGS(b2) |= SLAP_DBFLAG_GLUE_SUBORDINATE;
- if ( advertise ) {
- SLAP_DBFLAGS(b2) |= SLAP_DBFLAG_GLUE_ADVERTISE;
- }
- gi = (glueinfo *)ch_realloc( gi, sizeof(glueinfo) +
- gi->gi_nodes * sizeof(gluenode));
- gi->gi_n[gi->gi_nodes].gn_be = b2;
- dnParent( &b2->be_nsuffix[0], &gi->gi_n[gi->gi_nodes].gn_pdn );
- gi->gi_n[gi->gi_nodes].gn_async = async;
- gi->gi_nodes++;
- on->on_bi.bi_private = gi;
- return 0;
- }
- return SLAP_CONF_UNKNOWN;
-}
-
-int
-glue_init()
-{
- glue.on_bi.bi_type = "glue";
-
- glue.on_bi.bi_db_init = glue_db_init;
- glue.on_bi.bi_db_config = glue_db_config;
- glue.on_bi.bi_db_close = glue_db_close;
- glue.on_bi.bi_db_destroy = glue_db_destroy;
-
- glue.on_bi.bi_op_search = glue_op_search;
- glue.on_bi.bi_op_modify = glue_op_func;
- glue.on_bi.bi_op_modrdn = glue_op_func;
- glue.on_bi.bi_op_add = glue_op_func;
- glue.on_bi.bi_op_delete = glue_op_func;
-
- glue.on_bi.bi_chk_referrals = glue_chk_referrals;
- glue.on_bi.bi_chk_controls = glue_chk_controls;
-
- return overlay_register( &glue );
-}
-
-#if SLAPD_OVER_GLUE == SLAPD_MOD_DYNAMIC
-int
-init_module( int argc, char *argv[] )
-{
- return glue_init();
-}
-#endif /* SLAPD_OVER_GLUE == SLAPD_MOD_DYNAMIC */
-
-#endif /* defined(SLAPD_OVER_GLUE */
LDAP_SLAPD_V(BackendInfo) slap_binfo[];
+/*
+ * backglue.c
+ */
+
+LDAP_SLAPD_F (int) glue_sub_init( void );
+LDAP_SLAPD_F (int) glue_sub_add( BackendDB *be, int advert, int online );
+LDAP_SLAPD_F (int) glue_sub_del( BackendDB *be );
+
/*
* backover.c
*/
break;
}
+ rc = glue_sub_init();
+
+ if ( rc != 0 ) {
+ fprintf( stderr, "%s: subordinate configuration error\n", progname );
+ exit( EXIT_FAILURE );
+ }
+
rc = slap_schema_check();
if ( rc != 0 ) {
#metamod#moduleload back_meta.la
#monitormod#modulepath ../servers/slapd/back-monitor/
#monitormod#moduleload back_monitor.la
-#gluemod#modulepath ../servers/slapd/overlays/
-#gluemod#moduleload glue.la
#rwmmod#modulepath ../servers/slapd/overlays/
#rwmmod#moduleload rwm.la
# remote
database ldap
suffix "ou=Meta,dc=example,dc=com"
+subordinate
uri "@URI2@"
rootdn "cn=Manager,dc=example,dc=com"
chase-referrals no
flags=non-prescriptive
idassert-authzfrom "dn.exact:cn=Manager,dc=example,dc=com"
-
-overlay glue
-glue-sub "ou=Meta,dc=example,dc=com"
-
#monitor#database monitor
#mod#moduleload back_@BACKEND@.la
#monitormod#modulepath ../servers/slapd/back-monitor/
#monitormod#moduleload back_monitor.la
-#gluemod#moduleload ../servers/slapd/overlays/glue.la
#syncprovmod#moduleload ../servers/slapd/overlays/syncprov.la
#######################################################################
database @BACKEND@
suffix "ou=Information Technology Division,ou=People,dc=example,dc=com"
+subordinate
directory ./testrun/db.1.a
rootdn "cn=Manager 1,dc=example,dc=com"
#bdb#index objectclass eq
database @BACKEND@
suffix "ou=Groups,dc=example,dc=com"
+subordinate
directory ./testrun/db.1.b
rootdn "cn=Manager 1,dc=example,dc=com"
#bdb#index objectclass eq
#ldbm#dbnosync
#ldbm#dbnolocking
#overlay syncprov
-overlay glue
-glue-sub "ou=Information Technology Division,ou=People,dc=example,dc=com"
-glue-sub "ou=Groups,dc=example,dc=com"
#monitor#database monitor
#mod#moduleload back_@BACKEND@.la
#monitormod#modulepath ../servers/slapd/back-monitor/
#monitormod#moduleload back_monitor.la
-#gluemod#moduleload ../servers/slapd/overlays/glue.la
#syncprovmod#moduleload ../servers/slapd/overlays/syncprov.la
#######################################################################
database @BACKEND@
suffix "ou=Information Technology Division,ou=People,dc=example,dc=com"
+subordinate
directory ./testrun/db.2.a
rootdn "cn=Manager 2,dc=example,dc=com"
#bdb#index objectclass eq
database @BACKEND@
suffix "ou=Groups,dc=example,dc=com"
+subordinate
directory ./testrun/db.2.b
rootdn "cn=Manager 2,dc=example,dc=com"
#bdb#index objectclass eq
#ldbm#dbnosync
#ldbm#dbnolocking
#overlay syncprov
-overlay glue
-glue-sub "ou=Information Technology Division,ou=People,dc=example,dc=com"
-glue-sub "ou=Groups,dc=example,dc=com"
#monitor#database monitor
#mod#moduleload back_@BACKEND@.la
#monitormod#modulepath ../servers/slapd/back-monitor/
#monitormod#moduleload back_monitor.la
-#gluemod#moduleload ../servers/slapd/overlays/glue.la
#######################################################################
# database definitions
database @BACKEND@
suffix "ou=Information Technology Division,ou=People,dc=example,dc=com"
+subordinate
directory ./testrun/db.1.a
rootdn "cn=Manager, dc=example,dc=com"
#bdb#index objectclass eq
database @BACKEND@
suffix "ou=Groups,dc=example,dc=com"
+subordinate
directory ./testrun/db.1.b
rootdn "cn=Manager, dc=example,dc=com"
#bdb#index objectclass eq
#ldbm#index cn,sn pres,eq,sub,subany
#ldbm#dbnosync
#ldbm#dbnolocking
-overlay glue
-glue-sub "ou=Information Technology Division,ou=People,dc=example,dc=com"
-glue-sub "ou=Groups,dc=example,dc=com"
#monitor#database monitor
#ldapmod#moduleload back_ldap.la
#monitormod#modulepath ../servers/slapd/back-monitor/
#monitormod#moduleload back_monitor.la
-#gluemod#moduleload ../servers/slapd/overlays/glue.la
#######################################################################
# database definitions
access to *
by * read
-# people branch
-database ldap
-suffix "ou=People,dc=example,dc=com"
-uri "@URI2@"
-# FIXME: doesn't work with authz=native
-#sasl#idassert-bind bindmethod=sasl authcid=proxy credentials=proxy @SASL_MECH@ mode=self
-#nosasl#idassert-bind bindmethod=simple binddn="uid=proxy,ou=People,dc=example,dc=com" credentials=proxy mode=self
-
# groups branch
database ldap
suffix "ou=Groups,dc=example,dc=com"
+subordinate
uri "@URI3@"
# FIXME: doesn't work with authz=native
#sasl#idassert-bind bindmethod=sasl authcid=proxy credentials=proxy @SASL_MECH@ mode=self
#nosasl#idassert-bind bindmethod=simple binddn="uid=proxy,ou=Groups,dc=example,dc=com" credentials=proxy mode=self
+# people branch
+database ldap
+suffix "ou=People,dc=example,dc=com"
+subordinate
+uri "@URI2@"
+# FIXME: doesn't work with authz=native
+#sasl#idassert-bind bindmethod=sasl authcid=proxy credentials=proxy @SASL_MECH@ mode=self
+#nosasl#idassert-bind bindmethod=simple binddn="uid=proxy,ou=People,dc=example,dc=com" credentials=proxy mode=self
+
# root
database @BACKEND@
suffix "dc=example,dc=com"
#hdb#index cn,sn,uid pres,eq,sub
#ldbm#index objectClass eq
#ldbm#index cn,sn,uid pres,eq,sub
-overlay glue
-glue-sub "ou=groups,dc=example,dc=com"
-glue-sub "ou=people,dc=example,dc=com"
#monitor#database monitor
BACKSQL=${AC_sql-sqlno}
RDBMS=${SLAPD_USE_SQL-rdbmsno}
RDBMSWRITE=${SLAPD_USE_SQLWRITE-no}
-GLUE=${AC_glue-glueno}
PROXYCACHE=${AC_pcache-pcacheno}
PPOLICY=${AC_ppolicy-ppolicyno}
REFINT=${AC_refint-refintno}
echo "running defines.sh"
. $SRCDIR/scripts/defines.sh
-if test $GLUE = glueno; then
- echo "Backend glue overlay not available, test skipped"
- exit 0
-fi
-
mkdir -p $TESTDIR $DBDIR1A $DBDIR1B $DBDIR1C
echo "Running slapadd to build glued slapd databases..."
echo "running defines.sh"
. $SRCDIR/scripts/defines.sh
-if test $GLUE = glueno; then
- echo "Backend glue overlay not available, test skipped"
- exit 0
-fi
-
mkdir -p $TESTDIR $DBDIR1A $DBDIR1B $DBDIR1C
echo "Starting slapd on TCP/IP port $PORT..."
exit 0
fi
-if test $GLUE = "glueno" ; then
- echo "glue overlay not available, test skipped"
- exit 0
-fi
-
if test $WITH_SASL = "yes" ; then
if test $USE_SASL != "no" ; then
if test $USE_SASL = "yes" ; then
echo "running defines.sh"
. $SRCDIR/scripts/defines.sh
-if test $GLUE = glueno; then
- echo "Backend glue overlay not available, test skipped"
- exit 0
-fi
-
mkdir -p $TESTDIR $DBDIR1A $DBDIR1B $DBDIR1C
echo "Running slapadd to build glued slapd databases..."
exit 0
fi
-if test $GLUE = "glueno" ; then
- echo "glue overlay not available, test skipped"
- exit 0
-fi
-
if test $RWM = rwmno ; then
echo "rwm (rewrite/remap) overlay not available, test skipped"
exit 0