From: Howard Chu Date: Mon, 10 Dec 2001 12:09:40 +0000 (+0000) Subject: Changed backglue configuration. Added noSubordinates arg to select_backend X-Git-Tag: LDBM_PRE_GIANT_RWLOCK~676 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=ef0b308bea3741a5db2846aea0ab0608c2ffe5b9;p=openldap Changed backglue configuration. Added noSubordinates arg to select_backend to deal with glued subordinates. --- diff --git a/servers/slapd/add.c b/servers/slapd/add.c index 1af8aaeb47..046ae39378 100644 --- a/servers/slapd/add.c +++ b/servers/slapd/add.c @@ -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 ); diff --git a/servers/slapd/back-bdb/back-bdb.h b/servers/slapd/back-bdb/back-bdb.h index 1e55821395..0d3ad463c6 100644 --- a/servers/slapd/back-bdb/back-bdb.h +++ b/servers/slapd/back-bdb/back-bdb.h @@ -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 '%' diff --git a/servers/slapd/back-ldap/config.c b/servers/slapd/back-ldap/config.c index f493b0d8e5..605a16ab2f 100644 --- a/servers/slapd/back-ldap/config.c +++ b/servers/slapd/back-ldap/config.c @@ -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" diff --git a/servers/slapd/back-meta/config.c b/servers/slapd/back-meta/config.c index 35041ffe34..0cc797f7bf 100644 --- a/servers/slapd/back-meta/config.c +++ b/servers/slapd/back-meta/config.c @@ -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: of URI does not refer to current backend" " in \"uri ://[:port]/\" 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: of URI does not resolve to a backend" " in \"uri ://[:port]/\" 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" diff --git a/servers/slapd/back-monitor/init.c b/servers/slapd/back-monitor/init.c index 5b46dca302..dfa020f54f 100644 --- a/servers/slapd/back-monitor/init.c +++ b/servers/slapd/back-monitor/init.c @@ -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 diff --git a/servers/slapd/backend.c b/servers/slapd/backend.c index d199d8486d..1162fa5a9a 100644 --- a/servers/slapd/backend.c +++ b/servers/slapd/backend.c @@ -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; diff --git a/servers/slapd/backglue.c b/servers/slapd/backglue.c index d228e9cf93..48ec03100b 100644 --- a/servers/slapd/backglue.c +++ b/servers/slapd/backglue.c @@ -10,14 +10,12 @@ * 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; inodes; 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; } diff --git a/servers/slapd/bind.c b/servers/slapd/bind.c index f91f65bbfb..1de3d7a72b 100644 --- a/servers/slapd/bind.c +++ b/servers/slapd/bind.c @@ -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 ); diff --git a/servers/slapd/compare.c b/servers/slapd/compare.c index f7d81050ac..b3ccf30a71 100644 --- a/servers/slapd/compare.c +++ b/servers/slapd/compare.c @@ -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 ); diff --git a/servers/slapd/config.c b/servers/slapd/config.c index 20386a9afe..92c3b44dba 100644 --- a/servers/slapd/config.c +++ b/servers/slapd/config.c @@ -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 " diff --git a/servers/slapd/delete.c b/servers/slapd/delete.c index 492d44c2bd..bbda5a3f90 100644 --- a/servers/slapd/delete.c +++ b/servers/slapd/delete.c @@ -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 ); diff --git a/servers/slapd/main.c b/servers/slapd/main.c index ccb6c0e12c..b71bb99d21 100644 --- a/servers/slapd/main.c +++ b/servers/slapd/main.c @@ -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, diff --git a/servers/slapd/modify.c b/servers/slapd/modify.c index 081e484b68..6c882c7ab5 100644 --- a/servers/slapd/modify.c +++ b/servers/slapd/modify.c @@ -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 ); diff --git a/servers/slapd/modrdn.c b/servers/slapd/modrdn.c index 1d57bd875b..861b2142b7 100644 --- a/servers/slapd/modrdn.c +++ b/servers/slapd/modrdn.c @@ -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 */ diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index 0b4b737c2e..5571ec2fb6 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -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 )); diff --git a/servers/slapd/repl.c b/servers/slapd/repl.c index 42f4a090b1..92b1f44275 100644 --- a/servers/slapd/repl.c +++ b/servers/slapd/repl.c @@ -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; diff --git a/servers/slapd/root_dse.c b/servers/slapd/root_dse.c index f5e2e95fd8..61de132c3a 100644 --- a/servers/slapd/root_dse.c +++ b/servers/slapd/root_dse.c @@ -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]; diff --git a/servers/slapd/saslauthz.c b/servers/slapd/saslauthz.c index 280e50ad15..a487139a47 100644 --- a/servers/slapd/saslauthz.c +++ b/servers/slapd/saslauthz.c @@ -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; diff --git a/servers/slapd/search.c b/servers/slapd/search.c index 086e924137..0f9af2b4b2 100644 --- a/servers/slapd/search.c +++ b/servers/slapd/search.c @@ -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 ); diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index d509d068e0..0cdb930dea 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -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; /* */ diff --git a/servers/slapd/tools/slapadd.c b/servers/slapd/tools/slapadd.c index c32d593ae4..65923fcae5 100644 --- a/servers/slapd/tools/slapadd.c +++ b/servers/slapd/tools/slapadd.c @@ -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", diff --git a/servers/slapd/tools/slapcommon.c b/servers/slapd/tools/slapcommon.c index 9c583c964d..3143550611 100644 --- a/servers/slapd/tools/slapcommon.c +++ b/servers/slapd/tools/slapcommon.c @@ -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, diff --git a/servers/slapd/tools/slapcommon.h b/servers/slapd/tools/slapcommon.h index ca8dcf5207..600418b0c4 100644 --- a/servers/slapd/tools/slapcommon.h +++ b/servers/slapd/tools/slapcommon.h @@ -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;