mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-03-13 14:27:59 +08:00
Changed backglue configuration. Added noSubordinates arg to select_backend
to deal with glued subordinates.
This commit is contained in:
parent
95f1740aa6
commit
ef0b308bea
@ -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 );
|
||||
|
@ -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 '%'
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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,11 +63,53 @@ 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_open (
|
||||
BackendInfo *bi
|
||||
)
|
||||
{
|
||||
int rc = 0;
|
||||
static int glueOpened = 0;
|
||||
|
||||
if (glueOpened) return 0;
|
||||
|
||||
glueOpened = 1;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* This function will only be called in tool mode */
|
||||
static int
|
||||
glue_back_close (
|
||||
BackendInfo *bi
|
||||
)
|
||||
{
|
||||
static int glueClosed = 0;
|
||||
int rc;
|
||||
|
||||
if (glueClosed) return 0;
|
||||
|
||||
glueClosed = 1;
|
||||
|
||||
if (slapMode & SLAP_TOOL_MODE) {
|
||||
rc = backend_shutdown (NULL);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -72,68 +117,20 @@ glue_back_db_open (
|
||||
BackendDB *be
|
||||
)
|
||||
{
|
||||
glueinfo *gi;
|
||||
int i, j, k;
|
||||
int ok;
|
||||
glueinfo *gi = (glueinfo *)be->be_private;
|
||||
static int glueOpened = 0;
|
||||
int rc = 0;
|
||||
|
||||
/*
|
||||
* Done already?
|
||||
*/
|
||||
if (be->be_private)
|
||||
return 0;
|
||||
if (glueOpened) return 0;
|
||||
|
||||
for (i = 0; be->be_nsuffix[i]; i++);
|
||||
glueOpened = 1;
|
||||
|
||||
gi = (struct glueinfo *) ch_calloc (1, sizeof (glueinfo) +
|
||||
(i-1) * sizeof (gluenode) );
|
||||
gi->be->be_acl = be->be_acl;
|
||||
|
||||
be->be_private = gi;
|
||||
if (gi->be->bd_info->bi_db_open)
|
||||
rc = gi->be->bd_info->bi_db_open(gi->be);
|
||||
|
||||
if (!gi)
|
||||
return 1;
|
||||
|
||||
gi->nodes = i;
|
||||
be->be_glueflags = SLAP_GLUE_INSTANCE;
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -141,53 +138,34 @@ glue_back_db_close (
|
||||
BackendDB *be
|
||||
)
|
||||
{
|
||||
glueinfo *gi = (glueinfo *) 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 );
|
||||
|
||||
if (slapMode & SLAP_TOOL_MODE) {
|
||||
int i;
|
||||
for (i = 0; be->be_nsuffix[i]; i++) {
|
||||
backend_shutdown (gi->n[i].be);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
glue_back_db_destroy (
|
||||
BackendDB *be
|
||||
)
|
||||
{
|
||||
free (be->be_private);
|
||||
glueinfo *gi = (glueinfo *)be->be_private;
|
||||
|
||||
if (gi->be->bd_info->bi_db_destroy)
|
||||
gi->be->bd_info->bi_db_destroy( gi->be );
|
||||
free (gi->be);
|
||||
free (gi);
|
||||
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
|
||||
)
|
||||
{
|
||||
BackendDB *be;
|
||||
int rc;
|
||||
|
||||
be = glue_back_select (b0, ndn);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
typedef struct glue_state {
|
||||
int err;
|
||||
int nentries;
|
||||
@ -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;
|
||||
int i, j, k;
|
||||
int cont = num_subs;
|
||||
BackendDB *b1, *be;
|
||||
BackendInfo *bi;
|
||||
glueinfo *gi;
|
||||
|
||||
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
|
||||
/* While there are subordinate backends, search backwards through the
|
||||
* backends and connect them to their superior.
|
||||
*/
|
||||
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;
|
||||
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_connection_init = 0;
|
||||
bi->bi_connection_destroy = 0;
|
||||
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;
|
||||
|
||||
return 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;
|
||||
} 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;
|
||||
}
|
||||
|
@ -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 );
|
||||
|
@ -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 );
|
||||
|
||||
|
@ -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 "
|
||||
|
@ -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 );
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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 );
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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 ));
|
||||
|
@ -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;
|
||||
|
@ -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];
|
||||
|
@ -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;
|
||||
|
@ -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 );
|
||||
|
||||
|
@ -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; /* */
|
||||
|
||||
|
@ -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",
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user