]> git.sur5r.net Git - openldap/commitdiff
Changed backglue configuration. Added noSubordinates arg to select_backend
authorHoward Chu <hyc@openldap.org>
Mon, 10 Dec 2001 12:09:40 +0000 (12:09 +0000)
committerHoward Chu <hyc@openldap.org>
Mon, 10 Dec 2001 12:09:40 +0000 (12:09 +0000)
to deal with glued subordinates.

23 files changed:
servers/slapd/add.c
servers/slapd/back-bdb/back-bdb.h
servers/slapd/back-ldap/config.c
servers/slapd/back-meta/config.c
servers/slapd/back-monitor/init.c
servers/slapd/backend.c
servers/slapd/backglue.c
servers/slapd/bind.c
servers/slapd/compare.c
servers/slapd/config.c
servers/slapd/delete.c
servers/slapd/main.c
servers/slapd/modify.c
servers/slapd/modrdn.c
servers/slapd/proto-slap.h
servers/slapd/repl.c
servers/slapd/root_dse.c
servers/slapd/saslauthz.c
servers/slapd/search.c
servers/slapd/slap.h
servers/slapd/tools/slapadd.c
servers/slapd/tools/slapcommon.c
servers/slapd/tools/slapcommon.h

index 1af8aaeb47e82423cf9d8088b4774ac9b537c6b3..046ae393782cfbcad92f43974443f771a6f6d9a9 100644 (file)
@@ -203,7 +203,7 @@ do_add( Connection *conn, Operation *op )
         * appropriate one, or send a referral to our "referral server"
         * if we don't hold it.
         */
-       be = select_backend( e->e_ndn, manageDSAit );
+       be = select_backend( e->e_ndn, manageDSAit, 0 );
        if ( be == NULL ) {
                struct berval **ref = referral_rewrite( default_referral,
                        NULL, e->e_dn, LDAP_SCOPE_DEFAULT );
index 1e5582139588a3925eacdef616ded309b2504ca5..0d3ad463c62e794aef053529aea1734cd20f41f1 100644 (file)
@@ -17,7 +17,7 @@ LDAP_BEGIN_DECL
 
 #define BDB_FILTER_INDICES 1
 /* #define BDB_IDL_MULTI               1 */
-/* #define BDB_HIER            1 */
+#define BDB_HIER               1
 
 #define DN_BASE_PREFIX         SLAP_INDEX_EQUALITY_PREFIX
 #define DN_ONE_PREFIX          '%'
index f493b0d8e53fddd747b7cd851960da331992bf4c..605a16ab2f621532e3456dc1c24a9f7674ca8c5e 100644 (file)
@@ -137,7 +137,7 @@ ldap_back_db_config(
                        return( 1 );
                }
                
-               tmp_be = select_backend( argv[1], 0 );
+               tmp_be = select_backend( argv[1], 0, 0 );
                if ( tmp_be != NULL && tmp_be != be ) {
                        fprintf( stderr, "%s: line %d: suffix already in use"
                                       " by another backend in"
@@ -147,7 +147,7 @@ ldap_back_db_config(
                        return( 1 );                                            
                }
 
-               tmp_be = select_backend( argv[2], 0 );
+               tmp_be = select_backend( argv[2], 0, 0 );
                if ( tmp_be != NULL ) {
                        fprintf( stderr, "%s: line %d: massaged suffix"
                                       " already in use by another backend in" 
index 35041ffe34a8d46b606451d5ee05d794159906d0..0cc797f7bf8d4329f951218eeb3bb1a0a79b525e 100644 (file)
@@ -213,7 +213,7 @@ meta_back_db_config(
                 * uri MUST be a branch of suffix!
                 */
 #if 0 /* too strict a constraint */
-               if ( select_backend( li->targets[ i ]->suffix, 0 ) != be ) {
+               if ( select_backend( li->targets[ i ]->suffix, 0, 0 ) != be ) {
                        fprintf( stderr,
        "%s: line %d: <naming context> of URI does not refer to current backend"
        " in \"uri <protocol>://<server>[:port]/<naming context>\" line\n",
@@ -224,7 +224,7 @@ meta_back_db_config(
                /*
                 * uri MUST be a branch of a suffix!
                 */
-               if ( select_backend( li->targets[ i ]->suffix, 0 ) == NULL ) {
+               if ( select_backend( li->targets[ i ]->suffix, 0, 0 ) == NULL ) {
                        fprintf( stderr,
        "%s: line %d: <naming context> of URI does not resolve to a backend"
        " in \"uri <protocol>://<server>[:port]/<naming context>\" line\n",
@@ -419,7 +419,7 @@ meta_back_db_config(
                        return 1;
                }
                
-               tmp_be = select_backend( argv[ 1 ], 0 );
+               tmp_be = select_backend( argv[ 1 ], 0, 0 );
                if ( tmp_be != NULL && tmp_be != be ) {
                        fprintf( stderr, 
        "%s: line %d: suffix already in use by another backend in"
@@ -428,7 +428,7 @@ meta_back_db_config(
                        return 1;                                               
                }
 
-               tmp_be = select_backend( argv[ 2 ], 0 );
+               tmp_be = select_backend( argv[ 2 ], 0, 0 );
                if ( tmp_be != NULL ) {
                        fprintf( stderr,
        "%s: line %d: massaged suffix already in use by another backend in" 
index 5b46dca3026eaba9081698b3e2c7b28f2fe80890..dfa020f54fde8522e2b8620b5acab0d54b7cf999 100644 (file)
@@ -385,7 +385,7 @@ monitor_back_open(
         */
        ndn = ch_strdup( SLAPD_MONITOR_DN );
        dn_normalize( ndn );
-       be = select_backend( ndn , 0 );
+       be = select_backend( ndn , 0, 0 );
        ch_free( ndn );
        if ( be == NULL ) {
 #ifdef NEW_LOGGING
index d199d8486dffd45b001582c3b78dddcf84680c8f..1162fa5a9a160f9783eac5e97efb9a05dfc69c14 100644 (file)
@@ -101,7 +101,6 @@ static BackendInfo binfo[] = {
 #if defined(SLAPD_PRIVATE) && !defined(SLAPD_PRIVATE_DYNAMIC)
        {"private",     private_back_initialize},
 #endif
-       {"glue",        glue_back_initialize},
        {NULL}
 };
 
@@ -516,7 +515,8 @@ be_db_close( void )
 Backend *
 select_backend(
        const char * dn,
-       int manageDSAit )
+       int manageDSAit,
+       int noSubs )
 {
        int     i, j, len, dnlen;
        Backend *be = NULL;
@@ -526,6 +526,10 @@ select_backend(
                for ( j = 0; backends[i].be_nsuffix != NULL &&
                    backends[i].be_nsuffix[j] != NULL; j++ )
                {
+                       if ((backends[i].be_glueflags&SLAP_GLUE_SUBORDINATE)&&
+                               noSubs)
+                               continue;
+
                        len = backends[i].be_nsuffix[j]->bv_len;
 
                        if ( len > dnlen ) {
@@ -997,7 +1001,8 @@ backend_group(
        if( strcmp( target->e_ndn, gr_ndn ) != 0 ) {
                /* we won't attempt to send it to a different backend */
                
-               be = select_backend(gr_ndn, 0);
+               be = select_backend(gr_ndn, 0,
+                       (be->be_glueflags & SLAP_GLUE_INSTANCE));
 
                if (be == NULL) {
                        return LDAP_NO_SUCH_OBJECT;
@@ -1055,7 +1060,8 @@ backend_attribute(
        if( target == NULL || strcmp( target->e_ndn, e_ndn ) != 0 ) {
                /* we won't attempt to send it to a different backend */
                
-               be = select_backend(e_ndn, 0);
+               be = select_backend(e_ndn, 0,
+                       (be->be_glueflags & SLAP_GLUE_INSTANCE));
 
                if (be == NULL) {
                        return LDAP_NO_SUCH_OBJECT;
index d228e9cf93897095006b49856a1a09683a981a06..48ec03100bfdd21e0a1bad59210947fbaca339bd 100644 (file)
  * 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 only configuration items that are needed for this backend are
- * the suffixes, and they should be identical to suffixes of other
- * backends that are being configured. The suffixes must be listed
- * in order from longest to shortest, (most-specific to least-specific)
- * in order for the selection to work. Every backend that is being glued
- * must be fully configured as usual.
+ * This uses the backend structures and routines extensively, but is
+ * not an actual backend of its own. To use it you must add a "subordinate"
+ * keyword to the configuration of other backends. Subordinates will
+ * automatically be connected to their parent backend.
  *
- * The purpose of this backend is to allow you to split a single database
+ * 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 and rootpw.
@@ -42,15 +40,20 @@ typedef struct gluenode {
 } gluenode;
 
 typedef struct glueinfo {
+       BackendDB *be;
        int nodes;
        gluenode n[1];
 } glueinfo;
 
+static int glueMode;
+static int glueBack;
+
 /* Just like select_backend, but only for our backends */
 static BackendDB *
 glue_back_select (
        BackendDB *be,
-       const char *dn
+       const char *dn,
+       int *idx
 )
 {
        glueinfo *gi = (glueinfo *) be->be_private;
@@ -60,132 +63,107 @@ glue_back_select (
        bv.bv_len = strlen(dn);
        bv.bv_val = (char *) dn;
 
-       for (i = 0; be->be_nsuffix[i]; i++) {
-               if (dn_issuffixbv (&bv, be->be_nsuffix[i]))
+       for (i = 0; i<gi->nodes; i++) {
+               if (dn_issuffixbv (&bv, gi->n[i].be->be_nsuffix[0])) {
+                       if (idx)
+                               *idx = i;
                        return gi->n[i].be;
+               }
        }
-       return NULL;
+       return be;
 }
 
+/* This function will only be called in tool mode */
 static int
-glue_back_db_open (
-       BackendDB *be
+glue_back_open (
+       BackendInfo *bi
 )
 {
-       glueinfo *gi;
-       int i, j, k;
-       int ok;
-
-       /*
-        * Done already? 
-        */
-       if (be->be_private)
-               return 0;
+       int rc = 0;
+       static int glueOpened = 0;
 
-       for (i = 0; be->be_nsuffix[i]; i++);
+       if (glueOpened) return 0;
 
-       gi = (struct glueinfo *) ch_calloc (1, sizeof (glueinfo) +
-               (i-1) * sizeof (gluenode) );
+       glueOpened = 1;
 
-       be->be_private = gi;
+       /* If we were invoked in tool mode, open all the underlying backends */
+       if (slapMode & SLAP_TOOL_MODE) {
+               rc = backend_startup (NULL);
+       } /* other case is impossible */
+       return rc;
+}
 
-       if (!gi)
-               return 1;
+/* This function will only be called in tool mode */
+static int
+glue_back_close (
+       BackendInfo *bi
+)
+{
+       static int glueClosed = 0;
+       int rc;
 
-       gi->nodes = i;
-       be->be_glueflags = SLAP_GLUE_INSTANCE;
+       if (glueClosed) return 0;
 
-       /*
-        * For each of our suffixes, find the real backend that handles this 
-        * suffix. 
-        */
-       for (i = 0; be->be_nsuffix[i]; i++) {
-               for (j = 0; j < nbackends; j++) {
-                       if (be == &backends[j])
-                               continue;
-                       ok = 0;
-                       for (k = 0; backends[j].be_nsuffix &&
-                            backends[j].be_nsuffix[k]; k++) {
-                               if (be->be_nsuffix[i]->bv_len !=
-                                   backends[j].be_nsuffix[k]->bv_len)
-                                       continue;
-                               if (!strcmp (backends[j].be_nsuffix[k]->bv_val,
-                                            be->be_nsuffix[i]->bv_val)) {
-                                       ok = 1;
-                                       break;
-                               }
-                       }
-                       if (ok) {
-                               gi->n[i].be = &backends[j];
-                               gi->n[i].pdn = dn_parent (NULL,
-                                                be->be_nsuffix[i]->bv_val);
-                               if (i < gi->nodes - 1)
-                                       gi->n[i].be->be_glueflags =
-                                               SLAP_GLUE_SUBORDINATE;
-                               break;
-                       }
-               }
-       }
+       glueClosed = 1;
 
-       /* If we were invoked in tool mode, open all the underlying backends */
        if (slapMode & SLAP_TOOL_MODE) {
-               for (i = 0; be->be_nsuffix[i]; i++) {
-                       backend_startup (gi->n[i].be);
-               }
+               rc = backend_shutdown (NULL);
        }
-       return 0;
+       return rc;
 }
 
 static int
-glue_back_db_close (
+glue_back_db_open (
        BackendDB *be
 )
 {
-       glueinfo *gi = (glueinfo *) be->be_private;
+       glueinfo *gi = (glueinfo *)be->be_private;
+       static int glueOpened = 0;
+       int rc = 0;
 
-       if (slapMode & SLAP_TOOL_MODE) {
-               int i;
-               for (i = 0; be->be_nsuffix[i]; i++) {
-                       backend_shutdown (gi->n[i].be);
-               }
-       }
-       return 0;
+       if (glueOpened) return 0;
+
+       glueOpened = 1;
+
+       gi->be->be_acl = be->be_acl;
+
+       if (gi->be->bd_info->bi_db_open)
+               rc = gi->be->bd_info->bi_db_open(gi->be);
+
+       return rc;
 }
-int
-glue_back_db_destroy (
+
+static int
+glue_back_db_close (
        BackendDB *be
 )
 {
-       free (be->be_private);
+       glueinfo *gi = (glueinfo *)be->be_private;
+       static int glueClosed = 0;
+
+       if (glueClosed) return 0;
+
+       glueClosed = 1;
+
+       /* Close the master */
+       if (gi->be->bd_info->bi_db_close)
+               gi->be->bd_info->bi_db_close( gi->be );
+
        return 0;
 }
 
 int
-glue_back_bind (
-       BackendDB *b0,
-       Connection *conn,
-       Operation *op,
-       const char *dn,
-       const char *ndn,
-       int method,
-       struct berval *cred,
-       char **edn
+glue_back_db_destroy (
+       BackendDB *be
 )
 {
-       BackendDB *be;
-       int rc;
-
-       be = glue_back_select (b0, ndn);
+       glueinfo *gi = (glueinfo *)be->be_private;
 
-       if (be && be->be_bind) {
-               conn->c_authz_backend = be;
-               rc = be->be_bind (be, conn, op, dn, ndn, method, cred, edn);
-       } else {
-               rc = LDAP_UNWILLING_TO_PERFORM;
-               send_ldap_result (conn, op, rc, NULL, "No bind target found",
-                                 NULL, NULL);
-       }
-       return rc;
+       if (gi->be->bd_info->bi_db_destroy)
+               gi->be->bd_info->bi_db_destroy( gi->be );
+       free (gi->be);
+       free (gi);
+       return 0;
 }
 
 typedef struct glue_state {
@@ -289,7 +267,7 @@ glue_back_search (
        int attrsonly
 )
 {
-       glueinfo *gi = (glueinfo *) b0->be_private;
+       glueinfo *gi = (glueinfo *)b0->be_private;
        BackendDB *be;
        int i, rc, t2limit = 0, s2limit = 0;
        long stoptime = 0;
@@ -302,7 +280,7 @@ glue_back_search (
 
        switch (scope) {
        case LDAP_SCOPE_BASE:
-               be = glue_back_select (b0, ndn);
+               be = glue_back_select (b0, ndn, NULL);
 
                if (be && be->be_search) {
                        rc = be->be_search (be, conn, op, dn, ndn, scope,
@@ -353,20 +331,20 @@ glue_back_search (
                        if (scope == LDAP_SCOPE_ONELEVEL && 
                                !strcmp (gi->n[i].pdn, ndn)) {
                                rc = be->be_search (be, conn, op,
-                                                   b0->be_suffix[i],
-                                                   b0->be_nsuffix[i]->bv_val,
+                                                   be->be_suffix[0],
+                                                   be->be_nsuffix[0]->bv_val,
                                                    LDAP_SCOPE_BASE, deref,
                                        s2limit, t2limit, filter, filterstr,
                                                    attrs, attrsonly);
                        } else if (scope == LDAP_SCOPE_SUBTREE &&
-                               dn_issuffixbv (b0->be_nsuffix[i], &bv)) {
+                               dn_issuffixbv (be->be_nsuffix[0], &bv)) {
                                rc = be->be_search (be, conn, op,
-                                                   b0->be_suffix[i],
-                                                   b0->be_nsuffix[i]->bv_val,
+                                                   be->be_suffix[0],
+                                                   be->be_nsuffix[0]->bv_val,
                                                    scope, deref,
                                        s2limit, t2limit, filter, filterstr,
                                                    attrs, attrsonly);
-                       } else if (dn_issuffixbv (&bv, b0->be_nsuffix[i])) {
+                       } else if (dn_issuffixbv (&bv, be->be_nsuffix[0])) {
                                rc = be->be_search (be, conn, op,
                                                    dn, ndn, scope, deref,
                                        s2limit, t2limit, filter, filterstr,
@@ -389,6 +367,34 @@ done:
        return rc;
 }
 
+int
+glue_back_bind (
+       BackendDB *b0,
+       Connection *conn,
+       Operation *op,
+       const char *dn,
+       const char *ndn,
+       int method,
+       struct berval *cred,
+       char **edn
+)
+{
+       BackendDB *be;
+       int rc;
+       be = glue_back_select (b0, ndn, NULL);
+
+       if (be && be->be_bind) {
+               conn->c_authz_backend = be;
+               rc = be->be_bind (be, conn, op, dn, ndn, method, cred, edn);
+       } else {
+               rc = LDAP_UNWILLING_TO_PERFORM;
+               send_ldap_result (conn, op, rc, NULL, "No bind target found",
+                                 NULL, NULL);
+       }
+       return rc;
+}
+
 int
 glue_back_compare (
        BackendDB *b0,
@@ -402,7 +408,7 @@ glue_back_compare (
        BackendDB *be;
        int rc;
 
-       be = glue_back_select (b0, ndn);
+       be = glue_back_select (b0, ndn, NULL);
 
        if (be && be->be_compare) {
                rc = be->be_compare (be, conn, op, dn, ndn, ava);
@@ -427,7 +433,7 @@ glue_back_modify (
        BackendDB *be;
        int rc;
 
-       be = glue_back_select (b0, ndn);
+       be = glue_back_select (b0, ndn, NULL);
 
        if (be && be->be_modify) {
                rc = be->be_modify (be, conn, op, dn, ndn, mod);
@@ -454,7 +460,7 @@ glue_back_modrdn (
        BackendDB *be;
        int rc;
 
-       be = glue_back_select (b0, ndn);
+       be = glue_back_select (b0, ndn, NULL);
 
        if (be && be->be_modrdn) {
                rc = be->be_modrdn (be, conn, op, dn, ndn, newrdn, del, newsup);
@@ -477,7 +483,7 @@ glue_back_add (
        BackendDB *be;
        int rc;
 
-       be = glue_back_select (b0, e->e_ndn);
+       be = glue_back_select (b0, e->e_ndn, NULL);
 
        if (be && be->be_add) {
                rc = be->be_add (be, conn, op, e);
@@ -501,7 +507,7 @@ glue_back_delete (
        BackendDB *be;
        int rc;
 
-       be = glue_back_select (b0, ndn);
+       be = glue_back_select (b0, ndn, NULL);
 
        if (be && be->be_delete) {
                rc = be->be_delete (be, conn, op, dn, ndn);
@@ -525,7 +531,7 @@ glue_back_release_rw (
        BackendDB *be;
        int rc;
 
-       be = glue_back_select (b0, e->e_ndn);
+       be = glue_back_select (b0, e->e_ndn, NULL);
 
        if (be && be->be_release) {
                rc = be->be_release (be, conn, op, e, rw);
@@ -551,7 +557,7 @@ glue_back_group (
        BackendDB *be;
        int rc;
 
-       be = glue_back_select (b0, ndn);
+       be = glue_back_select (b0, ndn, NULL);
 
        if (be && be->be_group) {
                rc = be->be_group (be, conn, op, target, ndn, ondn, oc, ad);
@@ -575,7 +581,7 @@ glue_back_attribute (
        BackendDB *be;
        int rc;
 
-       be = glue_back_select (b0, ndn);
+       be = glue_back_select (b0, ndn, NULL);
 
        if (be && be->be_attribute) {
                rc = be->be_attribute (be, conn, op, target, ndn, ad, vals);
@@ -598,7 +604,7 @@ glue_back_referrals (
        BackendDB *be;
        int rc;
 
-       be = glue_back_select (b0, ndn);
+       be = glue_back_select (b0, ndn, NULL);
 
        if (be && be->be_chk_referrals) {
                rc = be->be_chk_referrals (be, conn, op, dn, ndn, text);
@@ -608,10 +614,6 @@ glue_back_referrals (
        return rc;
 }
 
-static int glueMode;
-static int glueBack;
-
-int
 glue_tool_entry_open (
        BackendDB *b0,
        int mode
@@ -716,31 +718,25 @@ glue_tool_entry_put (
        BackendDB *be;
        int i, rc;
 
-       be = glue_back_select (b0, e->e_ndn);
+       be = glue_back_select (b0, e->e_ndn, &i);
        if (!be->be_entry_put)
                return NOID;
 
-       i = glueBack;
-       if (i < 0) {
+       if (glueBack < 0) {
                rc = be->be_entry_open (be, glueMode);
                if (rc != 0)
                        return NOID;
-               glueBack = i;
-       } else if (be != gi->n[i].be) {
+       } else if (i != glueBack) {
                /* If this entry belongs in a different branch than the
                 * previous one, close the current database and open the
                 * new one.
                 */
-               gi->n[i].be->be_entry_close (gi->n[i].be);
-               glueBack = -1;
-               for (i = 0; b0->be_nsuffix[i]; i++)
-                       if (gi->n[i].be == be)
-                               break;
+               gi->n[glueBack].be->be_entry_close (gi->n[glueBack].be);
                rc = be->be_entry_open (be, glueMode);
                if (rc != 0)
                        return NOID;
-               glueBack = i;
        }
+       glueBack = i;
        return be->be_entry_put (be, e);
 }
 
@@ -774,53 +770,108 @@ glue_tool_sync (
        return 0;
 }
 
+extern int num_subs;   /* config.c */
+
 int
-glue_back_initialize (
-       BackendInfo *bi
-)
+glue_sub_init( )
 {
-       bi->bi_open = 0;
-       bi->bi_config = 0;
-       bi->bi_close = 0;
-       bi->bi_destroy = 0;
-
-       bi->bi_db_init = 0;
-       bi->bi_db_config = 0;
-       bi->bi_db_open = glue_back_db_open;
-       bi->bi_db_close = glue_back_db_close;
-       bi->bi_db_destroy = glue_back_db_destroy;
-
-       bi->bi_op_bind = glue_back_bind;
-       bi->bi_op_unbind = 0;
-       bi->bi_op_search = glue_back_search;
-       bi->bi_op_compare = glue_back_compare;
-       bi->bi_op_modify = glue_back_modify;
-       bi->bi_op_modrdn = glue_back_modrdn;
-       bi->bi_op_add = glue_back_add;
-       bi->bi_op_delete = glue_back_delete;
-       bi->bi_op_abandon = 0;
-
-       bi->bi_extended = 0;
-
-       bi->bi_entry_release_rw = glue_back_release_rw;
-       bi->bi_acl_group = glue_back_group;
-       bi->bi_acl_attribute = glue_back_attribute;
-       bi->bi_chk_referrals = glue_back_referrals;
-
-       /*
-        * hooks for slap tools
-        */
-       bi->bi_tool_entry_open = glue_tool_entry_open;
-       bi->bi_tool_entry_close = glue_tool_entry_close;
-       bi->bi_tool_entry_first = glue_tool_entry_first;
-       bi->bi_tool_entry_next = glue_tool_entry_next;
-       bi->bi_tool_entry_get = glue_tool_entry_get;
-       bi->bi_tool_entry_put = glue_tool_entry_put;
-       bi->bi_tool_entry_reindex = glue_tool_entry_reindex;
-       bi->bi_tool_sync = glue_tool_sync;
-
-       bi->bi_connection_init = 0;
-       bi->bi_connection_destroy = 0;
+       int i, j, k;
+       int cont = num_subs;
+       BackendDB *b1, *be;
+       BackendInfo *bi;
+       glueinfo *gi;
 
-       return 0;
+       /* While there are subordinate backends, search backwards through the
+        * backends and connect them to their superior.
+        */
+       for (i = nBackendDB - 1; cont && i>=0; i--) {
+               if (backendDB[i].be_glueflags & SLAP_GLUE_SUBORDINATE) {
+                       /* The last database cannot be a subordinate of noone */
+                       if (i == nBackendDB - 1)
+                               backendDB[i].be_glueflags ^= SLAP_GLUE_SUBORDINATE;
+                       continue;
+               }
+               b1 = &backendDB[i];
+               gi = NULL;
+               for (j = i-1; j>=0; j--) {
+                       if (!(backendDB[j].be_glueflags & SLAP_GLUE_SUBORDINATE))
+                               continue;
+                       /* We will only link it once */
+                       if (backendDB[j].be_glueflags & SLAP_GLUE_LINKED)
+                               continue;
+                       if (!dn_issuffixbv(backendDB[j].be_nsuffix[0],
+                               backendDB[i].be_nsuffix[0]))
+                               continue;
+                       be = &backendDB[j];
+                       cont--;
+                       be->be_glueflags |= SLAP_GLUE_LINKED;
+                       if (gi == NULL) {
+                               /* We create a copy of the superior's be
+                                * structure, pointing to all of its original
+                                * information. Then we replace elements of
+                                * the superior's info with our own. The copy
+                                * is used whenever we have operations to pass
+                                * down to the real database.
+                                */
+                               b1->be_glueflags |= SLAP_GLUE_INSTANCE;
+                               gi = (glueinfo *)ch_malloc(sizeof(glueinfo));
+                               gi->be = (BackendDB *)ch_malloc(sizeof(BackendDB) + sizeof(BackendInfo));
+                               bi = (BackendInfo *)(gi->be+1);
+                               *gi->be = *b1;
+                               gi->nodes = 0;
+                               *bi = *b1->bd_info;
+                               bi->bi_open = glue_back_open;
+                               bi->bi_close = glue_back_close;
+                               bi->bi_db_open = glue_back_db_open;
+                               bi->bi_db_close = glue_back_db_close;
+                               bi->bi_db_destroy = glue_back_db_destroy;
+
+                               bi->bi_op_bind = glue_back_bind;
+                               bi->bi_op_search = glue_back_search;
+                               bi->bi_op_compare = glue_back_compare;
+                               bi->bi_op_modify = glue_back_modify;
+                               bi->bi_op_modrdn = glue_back_modrdn;
+                               bi->bi_op_add = glue_back_add;
+                               bi->bi_op_delete = glue_back_delete;
+
+                               bi->bi_entry_release_rw = glue_back_release_rw;
+                               bi->bi_acl_group = glue_back_group;
+                               bi->bi_acl_attribute = glue_back_attribute;
+                               bi->bi_chk_referrals = glue_back_referrals;
+
+                               /*
+                                * hooks for slap tools
+                                */
+                               bi->bi_tool_entry_open = glue_tool_entry_open;
+                               bi->bi_tool_entry_close = glue_tool_entry_close;
+                               bi->bi_tool_entry_first = glue_tool_entry_first;
+                               bi->bi_tool_entry_next = glue_tool_entry_next;
+                               bi->bi_tool_entry_get = glue_tool_entry_get;
+                               bi->bi_tool_entry_put = glue_tool_entry_put;
+                               bi->bi_tool_entry_reindex = glue_tool_entry_reindex;
+                               bi->bi_tool_sync = glue_tool_sync;
+                       } else {
+                               gi = (glueinfo *)ch_realloc(gi,
+                                       sizeof(glueinfo) +
+                                       gi->nodes * sizeof(gluenode));
+                       }
+                       gi->n[gi->nodes].be = be;
+                       gi->n[gi->nodes].pdn = dn_parent(NULL,
+                               be->be_nsuffix[0]->bv_val);
+                       gi->nodes++;
+               }
+               if (gi) {
+                       /* One more node for the master */
+                       gi = (glueinfo *)ch_realloc(gi,
+                               sizeof(glueinfo) + gi->nodes * sizeof(gluenode));
+                       gi->n[gi->nodes].be = gi->be;
+                       gi->n[gi->nodes].pdn = dn_parent(NULL,
+                               b1->be_nsuffix[0]->bv_val);
+                       gi->nodes++;
+                       b1->be_private = gi;
+                       b1->bd_info = bi;
+               }
+       }
+       /* If there are any unresolved subordinates left, something is wrong */
+       return cont;
 }
index f91f65bbfbcdc216a8354a9c4b829c10b4cd3a94..1de3d7a72ba5a2b26686868990c135148d1cd4c1 100644 (file)
@@ -432,7 +432,7 @@ do_bind(
         * if we don't hold it.
         */
 
-       if ( (be = select_backend( ndn, 0 )) == NULL ) {
+       if ( (be = select_backend( ndn, 0, 0 )) == NULL ) {
                if ( default_referral ) {
                        struct berval **ref = referral_rewrite( default_referral,
                                NULL, dn, LDAP_SCOPE_DEFAULT );
index f7d81050ac799abcc43c8d0fbdf977a2d5e013af..b3ccf30a71681b40003b7c0fe73caf1bd753951d 100644 (file)
@@ -222,7 +222,7 @@ do_compare(
         * appropriate one, or send a referral to our "referral server"
         * if we don't hold it.
         */
-       if ( (be = select_backend( ndn, manageDSAit )) == NULL ) {
+       if ( (be = select_backend( ndn, manageDSAit, 0 )) == NULL ) {
                struct berval **ref = referral_rewrite( default_referral,
                        NULL, dn, LDAP_SCOPE_DEFAULT );
 
index 20386a9afe577a6a012b0969c5cbc2b1cee65fc2..92c3b44dba30e12bf37341dc272774de3aea0c1f 100644 (file)
@@ -48,6 +48,7 @@ char          *ldap_srvtab = "";
 char           *default_passwd_hash;
 char           *default_search_base = NULL;
 char           *default_search_nbase = NULL;
+int            num_subs = 0;
 
 ber_len_t sockbuf_max_incoming = SLAP_SB_MAX_INCOMING_DEFAULT;
 ber_len_t sockbuf_max_incoming_auth= SLAP_SB_MAX_INCOMING_AUTH;
@@ -824,6 +825,23 @@ read_config( const char *fname )
                                return( 1 );
                        }
 
+               /* mark this as a subordinate database */
+               } else if ( strcasecmp( cargv[0], "subordinate" ) == 0 ) {
+                       if ( be == NULL ) {
+#ifdef NEW_LOGGING
+                               LDAP_LOG(( "config", LDAP_LEVEL_INFO,
+                                          "%s: line %d: subordinate keyword must appear inside a database "
+                                          "definition (ignored).\n", fname, lineno ));
+#else
+                               Debug( LDAP_DEBUG_ANY,
+"%s: line %d: suffix line must appear inside a database definition (ignored)\n",
+                                   fname, lineno, 0 );
+#endif
+                       } else {
+                               be->be_glueflags |= SLAP_GLUE_SUBORDINATE;
+                               num_subs++;
+                       }
+
                /* set database suffix */
                } else if ( strcasecmp( cargv[0], "suffix" ) == 0 ) {
                        Backend *tmp_be;
@@ -877,7 +895,7 @@ read_config( const char *fname )
                                return( 1 );
 #endif /* SLAPD_MONITOR_DN */
 
-                       } else if ( ( tmp_be = select_backend( cargv[1], 0 ) ) == be ) {
+                       } else if ( ( tmp_be = select_backend( cargv[1], 0, 0 ) ) == be ) {
 #ifdef NEW_LOGGING
                                LDAP_LOG(( "config", LDAP_LEVEL_INFO,
                                           "%s: line %d: suffix already served by this backend "
@@ -1008,7 +1026,7 @@ read_config( const char *fname )
                                        fname, lineno, 0 );
 #endif
 
-                       } else if ( (tmp_be = select_backend( cargv[1], 0 )) != NULL ) {
+                       } else if ( (tmp_be = select_backend( cargv[1], 0, 0 )) != NULL ) {
 #ifdef NEW_LOGGING
                                LDAP_LOG(( "config", LDAP_LEVEL_INFO,
                                           "%s: line %d: suffixAlias served by a preceeding "
@@ -1022,7 +1040,7 @@ read_config( const char *fname )
 #endif
 
 
-                       } else if ( (tmp_be = select_backend( cargv[2], 0 )) != NULL ) {
+                       } else if ( (tmp_be = select_backend( cargv[2], 0, 0 )) != NULL ) {
 #ifdef NEW_LOGGING
                                LDAP_LOG(( "config", LDAP_LEVEL_INFO,
                                           "%s: line %d: suffixAlias derefs to a different backend "
index 492d44c2bd37738ab7283bac61801df39ab8b5d6..bbda5a3f90184d2faa9e9cee4b24b345b77fe4b7 100644 (file)
@@ -124,7 +124,7 @@ do_delete(
         * appropriate one, or send a referral to our "referral server"
         * if we don't hold it.
         */
-       if ( (be = select_backend( ndn, manageDSAit )) == NULL ) {
+       if ( (be = select_backend( ndn, manageDSAit, 0 )) == NULL ) {
                struct berval **ref = referral_rewrite( default_referral,
                        NULL, dn, LDAP_SCOPE_DEFAULT );
 
index ccb6c0e12c9fd6b928f380840f06dd1c03bad54b..b71bb99d21126a6b28afe0988251e9b5773a8212 100644 (file)
@@ -381,6 +381,18 @@ int main( int argc, char **argv )
                goto destroy;
        }
 
+       if ( glue_sub_init( ) != 0 ) {
+#ifdef NEW_LOGGING
+               LDAP_LOG(( "operation", LDAP_LEVEL_CRIT,
+                          "main: subordinate config error\n"));
+#else
+               Debug( LDAP_DEBUG_ANY,
+                   "subordinate config error\n",
+                   0, 0, 0 );
+#endif
+               goto destroy;
+       }
+
        if ( schema_prep( ) != 0 ) {
 #ifdef NEW_LOGGING
                LDAP_LOG(( "operation", LDAP_LEVEL_CRIT,
index 081e484b684ba9422a816dd2bda54135bda55b6b..6c882c7ab568f01b33803a9177c367e4f2eb59da 100644 (file)
@@ -280,7 +280,7 @@ do_modify(
         * appropriate one, or send a referral to our "referral server"
         * if we don't hold it.
         */
-       if ( (be = select_backend( ndn, manageDSAit )) == NULL ) {
+       if ( (be = select_backend( ndn, manageDSAit, 0 )) == NULL ) {
                struct berval **ref = referral_rewrite( default_referral,
                        NULL, dn, LDAP_SCOPE_DEFAULT );
 
index 1d57bd875bfae9cce0f979fda40441d3d3b5e434..861b2142b7a69bc5672f46b2e5924306dff8eb17 100644 (file)
@@ -249,7 +249,7 @@ do_modrdn(
         * appropriate one, or send a referral to our "referral server"
         * if we don't hold it.
         */
-       if ( (be = select_backend( ndn, manageDSAit )) == NULL ) {
+       if ( (be = select_backend( ndn, manageDSAit, 0 )) == NULL ) {
                struct berval **ref = referral_rewrite( default_referral,
                        NULL, dn, LDAP_SCOPE_DEFAULT );
 
@@ -278,7 +278,7 @@ do_modrdn(
         * the same backend, otherwise we return an error.
         */
        if( newSuperior != NULL ) {
-               newSuperior_be = select_backend( nnewSuperior, 0 );
+               newSuperior_be = select_backend( nnewSuperior, 0, 0 );
 
                if ( newSuperior_be != be ) {
                        /* newSuperior is in same backend */
index 0b4b737c2e1e52180067478c9a20776309ae6e21..5571ec2fb6b2fc258cb6c0d5195d8d542746fd0d 100644 (file)
@@ -152,7 +152,8 @@ LDAP_SLAPD_F (BackendDB *) backend_db_init LDAP_P(( const char *type ));
 
 LDAP_SLAPD_F (BackendDB *) select_backend LDAP_P((
        const char * dn,
-       int manageDSAit ));
+       int manageDSAit,
+       int noSubordinates ));
 
 LDAP_SLAPD_F (int) be_issuffix LDAP_P(( Backend *be, const char *suffix ));
 LDAP_SLAPD_F (int) be_isroot LDAP_P(( Backend *be, const char *ndn ));
index 42f4a090b1404f6ded4525924da66ab478acd864..92b1f442758a9ad3c96d13f4a2d12e35a0f38729 100644 (file)
@@ -57,7 +57,7 @@ add_replica_suffix(
        int     rc = 0;
 
        if ( dn_normalize( nsuffix ) != NULL ) {
-               if ( select_backend( nsuffix, 0 ) == be ) {
+               if ( select_backend( nsuffix, 0, 0 ) == be ) {
                        charray_add( &be->be_replica[nr]->ri_nsuffix, nsuffix );
                } else {
                        rc = 1;
index f5e2e95fd8560c774eec8d4f40eb093e98d4ce99..61de132c3a1728e436b24204e2b306716963f8c4 100644 (file)
@@ -70,7 +70,7 @@ root_dse_info(
        attr_merge( e, ad_objectClass, vals );
 
        for ( i = 0; i < nbackends; i++ ) {
-               if ( backends[i].be_glueflags )
+               if ( backends[i].be_glueflags & SLAP_GLUE_SUBORDINATE )
                        continue;
                for ( j = 0; backends[i].be_suffix[j] != NULL; j++ ) {
                        val.bv_val = backends[i].be_suffix[j];
index 280e50ad15bf383b84289d7d729b529b956a5b43..a487139a4773e3b1519f3a47356799b9138d33ae 100644 (file)
@@ -342,7 +342,7 @@ char *slap_sasl2dn( char *saslname )
 #endif
 
 
-       be = select_backend( searchbase, 0 );
+       be = select_backend( searchbase, 0, 1 );
        if(( be == NULL ) || ( be->be_search == NULL))
                goto FINISHED;
        searchbase = suffix_alias( be, searchbase );
@@ -463,7 +463,7 @@ int slap_sasl_match( char *rule, char *assertDN, char *authc )
 #endif
 
 
-       be = select_backend( searchbase, 0 );
+       be = select_backend( searchbase, 0, 1 );
        if(( be == NULL ) || ( be->be_search == NULL)) {
                rc = LDAP_INAPPROPRIATE_AUTH;
                goto CONCLUDED;
index 086e924137d72af0b60ef1a82b200d7ec3919a21..0f9af2b4b270c8aa0c9910d37dbf80cd0cfeee66 100644 (file)
@@ -267,7 +267,7 @@ do_search(
         * appropriate one, or send a referral to our "referral server"
         * if we don't hold it.
         */
-       if ( (be = select_backend( nbase, manageDSAit )) == NULL ) {
+       if ( (be = select_backend( nbase, manageDSAit, 1 )) == NULL ) {
                struct berval **ref = referral_rewrite( default_referral,
                        NULL, base, scope );
 
index d509d068e0b42a12fca8b221dd676398194cfdc4..0cdb930dea98f169ca212067ec6066e7dc1101bc 100644 (file)
@@ -997,8 +997,9 @@ struct slap_backend_db {
        struct berval **be_update_refs; /* where to refer modifying clients to */
        int     be_lastmod;     /* keep track of lastmodified{by,time}     */
 
-#define        SLAP_GLUE_SUBORDINATE   0x01    /* child of a glue hierarchy */
-#define        SLAP_GLUE_INSTANCE      0x02    /* a glue backend */
+#define        SLAP_GLUE_INSTANCE      0x01    /* a glue backend */
+#define        SLAP_GLUE_SUBORDINATE   0x02    /* child of a glue hierarchy */
+#define        SLAP_GLUE_LINKED        0x04    /* child is connected to parent */
 
        int     be_glueflags;   /* */
 
index c32d593ae422fff8952fb7de04bf8eaee8c7b33b..65923fcae505320f4da661f805a0d22f14e375b9 100644 (file)
@@ -81,7 +81,7 @@ main( int argc, char **argv )
                }
 
                /* check backend */
-               if( select_backend( e->e_ndn, is_entry_referral(e) ) != be )
+               if( select_backend( e->e_ndn, is_entry_referral(e), nosubs ) != be )
                {
                        fprintf( stderr, "%s: database (%s) not configured to "
                                "hold dn=\"%s\" (line=%d)\n",
index 9c583c964d28902221c6a5c520ae6fdd6eefb466..3143550611ceee2d0502344d11e19d8b5162ec5e 100644 (file)
@@ -24,6 +24,7 @@ char  *conffile       = SLAPD_DEFAULT_CONFIGFILE;
 int            truncatemode = 0;
 int            verbose         = 0;
 int            continuemode = 0;
+int    nosubs          = 0;
 
 char   *ldiffile       = NULL;
 FILE   *ldiffp         = NULL;
@@ -195,6 +196,13 @@ slap_tool_init(
                exit( EXIT_FAILURE );
        }
 
+       rc = glue_sub_init();
+
+       if (rc != 0 ) {
+               fprintf( stderr, "Subordinate configuration error\n" );
+               exit( EXIT_FAILURE );
+       }
+
        rc = schema_prep();
 
        if (rc != 0 ) {
@@ -211,7 +219,7 @@ slap_tool_init(
                        exit( EXIT_FAILURE );
                }
 
-               be = select_backend( tbase, 0 );
+               be = select_backend( tbase, 0, 0 );
                free( tbase );
 
                if( be == NULL ) {
@@ -219,9 +227,21 @@ slap_tool_init(
                                progname, base );
                        exit( EXIT_FAILURE );
                }
+               /* If the named base is a glue master, operate on the
+                * entire context
+                */
+               if (be->be_glueflags & SLAP_GLUE_INSTANCE)
+                       nosubs = 1;
 
        } else if ( dbnum == -1 ) {
                be = &backends[dbnum=0];
+               /* If just doing the first by default and it is a
+                * glue subordinate, find the master.
+                */
+               while (be->be_glueflags & SLAP_GLUE_SUBORDINATE) {
+                       nosubs = 1;
+                       be++;
+               }
 
        } else if ( dbnum < 0 || dbnum > (nbackends-1) ) {
                fprintf( stderr,
index ca8dcf52077c95564a9dec29de4b2f65ab4cfd16..600418b0c4eb5ff0ab82f81439e8a1e6b9f139c2 100644 (file)
@@ -25,6 +25,7 @@ extern        Backend *be;
 extern int             appendmode;
 extern int             verbose;
 extern int             continuemode;
+extern int     nosubs;
 
 extern char    *ldiffile;
 extern FILE    *ldiffp;