+ /* While there are subordinate backends, search backwards through the
+ * backends and connect them to their superior.
+ */
+ for (i = nBackendDB - 1, b1=&backendDB[i]; cont && i>=0; b1--,i--) {
+ if (b1->be_flags & SLAP_BFLAG_GLUE_SUBORDINATE) {
+ /* The last database cannot be a subordinate of noone */
+ if (i == nBackendDB - 1) {
+ b1->be_flags ^= SLAP_BFLAG_GLUE_SUBORDINATE;
+ }
+ continue;
+ }
+ gi = NULL;
+ for (j = i-1, be=&backendDB[j]; j>=0; be--,j--) {
+ if (!(be->be_flags & SLAP_BFLAG_GLUE_SUBORDINATE)) {
+ continue;
+ }
+ /* We will only link it once */
+ if (be->be_flags & SLAP_BFLAG_GLUE_LINKED) {
+ continue;
+ }
+ if (!dnIsSuffix(&be->be_nsuffix[0], &b1->be_nsuffix[0])) {
+ continue;
+ }
+ cont--;
+ be->be_flags |= SLAP_BFLAG_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_flags |= SLAP_BFLAG_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;
+ dnParent( &be->be_nsuffix[0], &gi->n[gi->nodes].pdn );
+ 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;
+ dnParent( &b1->be_nsuffix[0], &gi->n[gi->nodes].pdn );
+ gi->nodes++;
+ b1->be_private = gi;
+ b1->bd_info = bi;
+ }
+ }
+ /* If there are any unresolved subordinates left, something is wrong */
+ return cont;