]> git.sur5r.net Git - openldap/commitdiff
Ready for release OPENLDAP_REL_ENG_2_3_7
authorKurt Zeilenga <kurt@openldap.org>
Thu, 1 Sep 2005 22:27:55 +0000 (22:27 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Thu, 1 Sep 2005 22:27:55 +0000 (22:27 +0000)
29 files changed:
CHANGES
configure
configure.in
doc/man/man5/slapd.conf.5
doc/man/man5/slapo-glue.5 [deleted file]
doc/man/man8/slapadd.8
doc/man/man8/slapcat.8
doc/man/man8/slapindex.8
include/portable.hin
servers/slapd/Makefile.in
servers/slapd/back-bdb/init.c
servers/slapd/backglue.c [new file with mode: 0644]
servers/slapd/bconfig.c
servers/slapd/main.c
servers/slapd/overlays/Makefile.in
servers/slapd/overlays/glue.c [deleted file]
servers/slapd/proto-slap.h
servers/slapd/slapcommon.c
tests/data/slapd-glue-ldap.conf
tests/data/slapd-glue-syncrepl1.conf
tests/data/slapd-glue-syncrepl2.conf
tests/data/slapd-glue.conf
tests/data/slapd-ldapglue.conf
tests/scripts/defines.sh
tests/scripts/test011-glue-slapadd
tests/scripts/test012-glue-populate
tests/scripts/test029-ldapglue
tests/scripts/test033-glue-syncrepl
tests/scripts/test039-glue-ldap-concurrency

diff --git a/CHANGES b/CHANGES
index 4fda00acce70405fe8b7ad5b00f5bae1d190e3d9..3da76514fac99f83c05f1e0628a902e6731d4f4f 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -9,6 +9,7 @@ OpenLDAP 2.3.7 Release
        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)
@@ -16,6 +17,7 @@ OpenLDAP 2.3.7 Release
        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)
index 5d20068110f82db5d90df9833a61c61ee0dde4e9..70442223409be6ca4bf11221c0456d4ae44fdbdc 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,5 +1,5 @@
 #! /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.
 #
@@ -465,7 +465,7 @@ ac_includes_default="\
 # 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.
@@ -1051,7 +1051,6 @@ SLAPD Overlay 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]
@@ -3145,7 +3144,6 @@ Overlays="accesslog \
        denyop \
        dyngroup \
        dynlist \
-       glue \
        lastmod \
        ppolicy \
        proxycache \
@@ -3280,30 +3278,6 @@ else
 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.
@@ -3877,7 +3851,6 @@ BUILD_ACCESSLOG=no
 BUILD_DENYOP=no
 BUILD_DYNGROUP=no
 BUILD_DYNLIST=no
-BUILD_GLUE=no
 BUILD_LASTMOD=no
 BUILD_PPOLICY=no
 BUILD_PROXYCACHE=no
@@ -5712,7 +5685,7 @@ ia64-*-hpux*)
   ;;
 *-*-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=$?
@@ -7692,11 +7665,11 @@ else
    -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.
@@ -7954,11 +7927,11 @@ else
    -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.
@@ -8016,11 +7989,11 @@ else
    -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
@@ -10256,7 +10229,7 @@ else
   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
@@ -10354,7 +10327,7 @@ else
   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
@@ -42535,22 +42508,6 @@ _ACEOF
 
 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
@@ -42822,7 +42779,6 @@ fi
 
 
 
-
 
 
 # Check whether --with-xxinstall or --without-xxinstall was given.
@@ -43573,7 +43529,6 @@ s,@BUILD_ACCESSLOG@,$BUILD_ACCESSLOG,;t t
 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
index bf859e6c0b22aa591cbfe2086aa59cf64377a1d0..d1ef9c248cb96775133b726f15d54fd9960979b4 100644 (file)
@@ -340,7 +340,6 @@ Overlays="accesslog \
        denyop \
        dyngroup \
        dynlist \
-       glue \
        lastmod \
        ppolicy \
        proxycache \
@@ -365,8 +364,6 @@ OL_ARG_ENABLE(dyngroup,[    --enable-dyngroup         Dynamic Group overlay],
        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],
@@ -617,7 +614,6 @@ BUILD_ACCESSLOG=no
 BUILD_DENYOP=no
 BUILD_DYNGROUP=no
 BUILD_DYNLIST=no
-BUILD_GLUE=no
 BUILD_LASTMOD=no
 BUILD_PPOLICY=no
 BUILD_PROXYCACHE=no
@@ -2907,18 +2903,6 @@ if test "$ol_enable_dynlist" != no ; then
        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
@@ -3101,7 +3085,6 @@ dnl overlays
   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)
index 573d4f1af8051bc187389a6a3d402620936caeaa..27e0be29be002db9216158d699efaa122cbe33d2 100644 (file)
@@ -2,7 +2,6 @@
 .\" 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
@@ -1392,6 +1391,36 @@ backend database.  Multiple suffix lines can be given and at least one is
 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>
@@ -1665,10 +1694,6 @@ It has no effect on any other operations.
 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,
@@ -1764,15 +1789,6 @@ lastmod   off
 "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
@@ -1812,7 +1828,6 @@ Known overlays are documented in
 .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),
diff --git a/doc/man/man5/slapo-glue.5 b/doc/man/man5/slapo-glue.5
deleted file mode 100644 (file)
index 23d8f56..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-.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).
index 03412881d7de34c062646e6c10e7f9f63a3f8a02..818f77cbe98d429574ae06f3866adc1171c0e76e 100644 (file)
@@ -26,9 +26,9 @@ database.
 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
index 70954fe6636c218af1765f3580e7193c3ce13dcf..03a0aa5d4a5e92e87e6f30fcdab0ebadd6ec0a2c 100644 (file)
@@ -27,9 +27,9 @@ database.
 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).
index 63f7d1a17da1fd91300dff961fdaa2047fd40afb..f99d09d3fbe9826427786c227d638dd78bae50c7 100644 (file)
@@ -24,9 +24,9 @@ indices based upon the current contents of a database.
 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
index 1a54e8c3e4fd8dc4d8b1030232676395d289ba52..e339b15d12a4b1390375ba60f6cbd1140d23028e 100644 (file)
 /* 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
 
index f774b1322c26d2a17554a21b14312773c8a32d63..46ee8dac699793b90bffe8759556c950cb498046 100644 (file)
@@ -35,7 +35,7 @@ SRCS  = main.c globals.c bconfig.c config.c daemon.c \
                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 \
@@ -53,7 +53,7 @@ OBJS  = main.o globals.o bconfig.o config.o daemon.o \
                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 \
index e7417c7faad45fb56f277480f935f07783616e4c..36af08c8e5d03e6fe3e42ff3949172c949718b4b 100644 (file)
@@ -312,8 +312,10 @@ bdb_db_open( BackendDB *be )
                        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,
diff --git a/servers/slapd/backglue.c b/servers/slapd/backglue.c
new file mode 100644 (file)
index 0000000..936d617
--- /dev/null
@@ -0,0 +1,942 @@
+/* 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();
+}
index 4b47318626d144375a8c1a16dfd0b0ce819f5765..5718714c279cf0950d9881dcb17f32b55e3243d6 100644 (file)
@@ -105,6 +105,7 @@ static ConfigDriver config_schema_dn;
 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;
@@ -481,6 +482,9 @@ static ConfigTable config_back_cf_table[] = {
 #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 },
@@ -634,7 +638,7 @@ static ConfigOCs cf_ocs[] = {
                "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 $ "
@@ -1560,6 +1564,42 @@ config_overlay(ConfigArgs *c) {
        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)
 {
index 03b264513dd5a4fa86aeb0d883987f1125a6e963..81fbed49f46f3908b573d304eee901a0d1160e66 100644 (file)
@@ -631,6 +631,14 @@ unhandled_option:;
                }
        }
 
+       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",
index 59547e22feb72671ea2fcee021e0c49b6eba22e7..86c8f043ca38fcf3f5e5b12184006e82a37682e0 100644 (file)
@@ -18,7 +18,6 @@ SRCS = overlays.c \
        denyop.c \
        dyngroup.c \
        dynlist.c \
-       glue.c \
        lastmod.c \
        pcache.c \
        ppolicy.c \
@@ -68,9 +67,6 @@ dyngroup.la : dyngroup.lo
 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)
 
diff --git a/servers/slapd/overlays/glue.c b/servers/slapd/overlays/glue.c
deleted file mode 100644 (file)
index 52f3034..0000000
+++ /dev/null
@@ -1,876 +0,0 @@
-/* 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 */
index 899d13dfccb1c72b32fef037251f616718190a91..d79433ca2090c97047d99287bbf69c1baa75f806 100644 (file)
@@ -389,6 +389,14 @@ LDAP_SLAPD_F (int) backend_operational LDAP_P((
 
 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
  */
index a035874ee1c56b47507f95ea60bbc9267cb8284f..bbdb5bb3e3556b8c5aa6f35df750c4682ef5177d 100644 (file)
@@ -424,6 +424,13 @@ slap_tool_init(
                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 ) {
index e8a3f3e483a6b6074140cb116d94896f381f59f7..32497bf9db7fb96a64953e6de3649615a077bb4e 100644 (file)
@@ -32,8 +32,6 @@ argsfile    ./test-db/slapd.m.args
 #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
 
@@ -47,6 +45,7 @@ rwm-suffixmassage     "o=Example,c=US" "dc=example,dc=com"
 # remote
 database       ldap
 suffix         "ou=Meta,dc=example,dc=com"
+subordinate
 uri            "@URI2@"
 rootdn         "cn=Manager,dc=example,dc=com"
 chase-referrals        no
@@ -71,8 +70,4 @@ idassert-bind bindmethod=simple
                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
index 4f10f84b56a5d93085676acee09b57e69c08d0d5..ef9ebf485bd9b152e1bc40840d00c523ac1f0935 100644 (file)
@@ -26,7 +26,6 @@ argsfile      ./testrun/slapd.1.args
 #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
 
 #######################################################################
@@ -35,6 +34,7 @@ argsfile      ./testrun/slapd.1.args
 
 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
@@ -54,6 +54,7 @@ overlay               syncprov
 
 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
@@ -102,8 +103,5 @@ rootpw              secret
 #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
index 19ddc8d5d9ca307ad72aa8eed3da37b61fb8303a..2147cc16316a722876df7d56049c3cb3000a810c 100644 (file)
@@ -26,7 +26,6 @@ argsfile      ./testrun/slapd.2.args
 #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
 
 #######################################################################
@@ -35,6 +34,7 @@ argsfile      ./testrun/slapd.2.args
 
 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
@@ -67,6 +67,7 @@ updateref     @URI1@
 
 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
@@ -102,8 +103,5 @@ rootpw              secret
 #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
index 69e9178c565780fb18d690cd6fb2f465e977b634..4f9d1c2a9599bb96815a78426f4ed067f15f77c3 100644 (file)
@@ -26,7 +26,6 @@ argsfile    ./testrun/slapd.1.args
 #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
@@ -34,6 +33,7 @@ argsfile    ./testrun/slapd.1.args
 
 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
@@ -50,6 +50,7 @@ rootdn                "cn=Manager, dc=example,dc=com"
 
 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
@@ -80,8 +81,5 @@ rootpw                secret
 #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
index e235aed4d8a0a3bf00005fe576c6a37aa9802d26..9f0bfd3dc031d3a32ae5644cf9868f3066483a6c 100644 (file)
@@ -29,7 +29,6 @@ argsfile    ./testrun/slapd.1.args
 #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
@@ -49,22 +48,24 @@ access to attr=userpassword
 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"
@@ -77,8 +78,5 @@ rootpw                secret
 #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
index c504790be92a8d039202fc5e0eb91df73589b076..a26622a23107cbed569efffaee7efb4e1396ea88 100755 (executable)
@@ -20,7 +20,6 @@ BACKRELAY=${AC_relay-relayno}
 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}
index df6afa1d581fa6166bfd97106400af02c9be17ed..f87fe6df770f469b50079c5e251a341976f2d4ce 100755 (executable)
 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..."
index 085a005b4f9e472f364e9eafca598a358fd34e17..c45feec9d6d5fbf575aab78e988fb6e014f487e3 100755 (executable)
 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..."
index 572e7e8199b51a696d71f888249ce9eb5c686d96..4701e1897e055e8a66a836b3a36171600c38ebb9 100755 (executable)
@@ -27,11 +27,6 @@ if test $BACKLDAP = "ldapno" ; then
        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
index 75b876cf169f45a784648ff475d9874394ff5345..1ffb611d6bf4c894d2d90e6de3f5d01f0d505024 100755 (executable)
 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..."
index d0d89afc30f1be4e82a63b6163431970d5c6d8e0..87cabe33d89e706ac73abc9d05999c376124d83e 100755 (executable)
@@ -23,11 +23,6 @@ if test $BACKLDAP = ldapno ; then
        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