X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fbackglue.c;h=f65ee40f477a2e8eece49722a5d3c4b9bc896ae1;hb=20965abe9c5bb80d79e5ad791cd2b59ec60259b5;hp=6185ed77f92ee2325ccb8a0ec23e4c110619a5ec;hpb=8b3a69ae39043cd08e1aef1647b46a968c699a0b;p=openldap diff --git a/servers/slapd/backglue.c b/servers/slapd/backglue.c index 6185ed77f9..f65ee40f47 100644 --- a/servers/slapd/backglue.c +++ b/servers/slapd/backglue.c @@ -45,15 +45,15 @@ #include "slap.h" typedef struct gluenode { - BackendDB *be; - struct berval pdn; + BackendDB *gn_be; + struct berval gn_pdn; } gluenode; typedef struct glueinfo { - BackendInfo bi; - BackendDB bd; - int nodes; - gluenode n[1]; + BackendInfo gi_bi; + BackendDB gi_bd; + int gi_nodes; + gluenode gi_n[1]; } glueinfo; static int glueMode; @@ -75,11 +75,11 @@ glue_back_select ( bv.bv_len = strlen(dn); bv.bv_val = (char *) dn; - for (i = 0; inodes; i++) { - assert( gi->n[i].be->be_nsuffix ); + for (i = 0; igi_nodes; i++) { + assert( gi->gi_n[i].gn_be->be_nsuffix ); - if (dnIsSuffix(&bv, &gi->n[i].be->be_nsuffix[0])) { - return gi->n[i].be; + if (dnIsSuffix(&bv, &gi->gi_n[i].gn_be->be_nsuffix[0])) { + return gi->gi_n[i].gn_be; } } return NULL; @@ -137,10 +137,12 @@ glue_back_db_open ( glueOpened = 1; - gi->bd.be_acl = be->be_acl; + gi->gi_bd.be_acl = be->be_acl; + gi->gi_bd.be_pending_csn_list = be->be_pending_csn_list; + gi->gi_bd.be_context_csn = be->be_context_csn; - if (gi->bd.bd_info->bi_db_open) - rc = gi->bd.bd_info->bi_db_open(&gi->bd); + if (gi->gi_bd.bd_info->bi_db_open) + rc = gi->gi_bd.bd_info->bi_db_open(&gi->gi_bd); return rc; } @@ -158,8 +160,8 @@ glue_back_db_close ( glueClosed = 1; /* Close the master */ - if (gi->bd.bd_info->bi_db_close) - gi->bd.bd_info->bi_db_close( &gi->bd ); + if (gi->gi_bd.bd_info->bi_db_close) + gi->gi_bd.bd_info->bi_db_close( &gi->gi_bd ); return 0; } @@ -171,15 +173,14 @@ glue_back_db_destroy ( { glueinfo *gi = (glueinfo *) be->bd_info; - if (gi->bd.bd_info->bi_db_destroy) - gi->bd.bd_info->bi_db_destroy( &gi->bd ); + if (gi->gi_bd.bd_info->bi_db_destroy) + gi->gi_bd.bd_info->bi_db_destroy( &gi->gi_bd ); free (gi); return 0; } typedef struct glue_state { int err; - int is_slimit; int slimit; int matchlen; char *matched; @@ -194,8 +195,10 @@ glue_back_response ( Operation *op, SlapReply *rs ) switch(rs->sr_type) { case REP_SEARCH: - if ( gs->is_slimit && rs->sr_nentries >= gs->slimit ) { - gs->err = LDAP_SIZELIMIT_EXCEEDED; + if ( gs->slimit != SLAP_NO_LIMIT + && rs->sr_nentries >= gs->slimit ) + { + rs->sr_err = gs->err = LDAP_SIZELIMIT_EXCEEDED; return -1; } /* fallthru */ @@ -203,14 +206,13 @@ glue_back_response ( Operation *op, SlapReply *rs ) return SLAP_CB_CONTINUE; default: - if ( gs->is_slimit && rs->sr_err == LDAP_SIZELIMIT_EXCEEDED - && rs->sr_nentries >= gs->slimit ) { - gs->err = LDAP_SIZELIMIT_EXCEEDED; - return -1; - } - if (rs->sr_err == LDAP_SUCCESS || gs->err != LDAP_SUCCESS) { + if (rs->sr_err == LDAP_SUCCESS || + rs->sr_err == LDAP_SIZELIMIT_EXCEEDED || + rs->sr_err == LDAP_TIMELIMIT_EXCEEDED || + rs->sr_err == LDAP_ADMINLIMIT_EXCEEDED || + rs->sr_err == LDAP_NO_SUCH_OBJECT || + gs->err != LDAP_SUCCESS) gs->err = rs->sr_err; - } if (gs->err == LDAP_SUCCESS && gs->matched) { ch_free (gs->matched); gs->matched = NULL; @@ -254,28 +256,25 @@ static int glue_back_search ( Operation *op, SlapReply *rs ) { BackendDB *b0 = op->o_bd; + BackendDB *b1 = NULL; glueinfo *gi = (glueinfo *) b0->bd_info; int i; long stoptime = 0; - glue_state gs = {0, 0, 0, 0, NULL, 0, NULL}; + glue_state gs = {0, 0, 0, NULL, 0, NULL}; slap_callback cb = { NULL, glue_back_response, NULL, NULL }; int scope0, slimit0, tlimit0; struct berval dn, ndn; - gs.is_slimit = ( op->ors_slimit > 0 ); - cb.sc_private = &gs; cb.sc_next = op->o_callback; - if (op->ors_tlimit) { - stoptime = slap_get_time () + op->ors_tlimit; - } + stoptime = slap_get_time () + op->ors_tlimit; + + op->o_bd = glue_back_select (b0, op->o_req_ndn.bv_val); switch (op->ors_scope) { case LDAP_SCOPE_BASE: - op->o_bd = glue_back_select (b0, op->o_req_ndn.bv_val); - if (op->o_bd && op->o_bd->be_search) { rs->sr_err = op->o_bd->be_search( op, rs ); } else { @@ -286,31 +285,45 @@ glue_back_search ( Operation *op, SlapReply *rs ) case LDAP_SCOPE_ONELEVEL: case LDAP_SCOPE_SUBTREE: +#ifdef LDAP_SCOPE_SUBORDINATE case LDAP_SCOPE_SUBORDINATE: /* FIXME */ +#endif + + if ( op->o_sync_mode & SLAP_SYNC_REFRESH ) { + if (op->o_bd && op->o_bd->be_search) { + rs->sr_err = op->o_bd->be_search( op, rs ); + } else { + send_ldap_error(op, rs, LDAP_UNWILLING_TO_PERFORM, + "No search target found"); + } + return rs->sr_err; + } + op->o_callback = &cb; rs->sr_err = gs.err = LDAP_UNWILLING_TO_PERFORM; scope0 = op->ors_scope; - if ( gs.is_slimit ) { - slimit0 = gs.slimit = op->ors_slimit; - } + slimit0 = gs.slimit = op->ors_slimit; tlimit0 = op->ors_tlimit; dn = op->o_req_dn; ndn = op->o_req_ndn; + b1 = op->o_bd; /* * Execute in reverse order, most general first */ - for (i = gi->nodes-1; i >= 0; i--) { - if (!gi->n[i].be || !gi->n[i].be->be_search) + for (i = gi->gi_nodes-1; i >= 0; i--) { + if (!gi->gi_n[i].gn_be || !gi->gi_n[i].gn_be->be_search) continue; - if (tlimit0) { + if (!dnIsSuffix(&gi->gi_n[i].gn_be->be_nsuffix[0], &b1->be_nsuffix[0])) + continue; + if (tlimit0 != SLAP_NO_LIMIT) { op->ors_tlimit = stoptime - slap_get_time (); if (op->ors_tlimit <= 0) { rs->sr_err = gs.err = LDAP_TIMELIMIT_EXCEEDED; break; } } - if ( gs.is_slimit ) { + if (slimit0 != SLAP_NO_LIMIT) { op->ors_slimit = slimit0 - rs->sr_nentries; if (op->ors_slimit < 0) { rs->sr_err = gs.err = LDAP_SIZELIMIT_EXCEEDED; @@ -322,27 +335,35 @@ glue_back_search ( Operation *op, SlapReply *rs ) * check for abandon */ if (op->o_abandon) { - goto done; + goto end_of_loop; } - op->o_bd = gi->n[i].be; + op->o_bd = gi->gi_n[i].gn_be; assert( op->o_bd->be_suffix ); assert( op->o_bd->be_nsuffix ); if (scope0 == LDAP_SCOPE_ONELEVEL && - dn_match(&gi->n[i].pdn, &ndn)) + dn_match(&gi->gi_n[i].gn_pdn, &ndn)) { op->ors_scope = LDAP_SCOPE_BASE; op->o_req_dn = op->o_bd->be_suffix[0]; op->o_req_ndn = op->o_bd->be_nsuffix[0]; rs->sr_err = op->o_bd->be_search(op, rs); + } else if (scope0 == LDAP_SCOPE_SUBTREE && + dn_match(&op->o_bd->be_nsuffix[0], &ndn)) + { + rs->sr_err = op->o_bd->be_search( op, rs ); + } else if (scope0 == LDAP_SCOPE_SUBTREE && dnIsSuffix(&op->o_bd->be_nsuffix[0], &ndn)) { op->o_req_dn = op->o_bd->be_suffix[0]; op->o_req_ndn = op->o_bd->be_nsuffix[0]; rs->sr_err = op->o_bd->be_search( op, rs ); + if ( rs->sr_err == LDAP_NO_SUCH_OBJECT ) { + gs.err = LDAP_SUCCESS; + } } else if (dnIsSuffix(&ndn, &op->o_bd->be_nsuffix[0])) { rs->sr_err = op->o_bd->be_search( op, rs ); @@ -357,6 +378,7 @@ glue_back_search ( Operation *op, SlapReply *rs ) case LDAP_SIZELIMIT_EXCEEDED: case LDAP_TIMELIMIT_EXCEEDED: case LDAP_ADMINLIMIT_EXCEEDED: + case LDAP_NO_SUCH_OBJECT: goto end_of_loop; default: @@ -365,23 +387,22 @@ glue_back_search ( Operation *op, SlapReply *rs ) } end_of_loop:; op->ors_scope = scope0; - if ( gs.is_slimit ) { - op->ors_slimit = slimit0; - } + op->ors_slimit = slimit0; op->ors_tlimit = tlimit0; op->o_req_dn = dn; op->o_req_ndn = ndn; break; } - op->o_callback = cb.sc_next; - rs->sr_err = gs.err; - rs->sr_matched = gs.matched; - rs->sr_ref = gs.refs; + if ( !op->o_abandon ) { + op->o_callback = cb.sc_next; + rs->sr_err = gs.err; + rs->sr_matched = gs.matched; + rs->sr_ref = gs.refs; - send_ldap_result( op, rs ); + send_ldap_result( op, rs ); + } -done: op->o_bd = b0; if (gs.matched) free (gs.matched); @@ -432,10 +453,10 @@ glue_tool_entry_first ( /* If we're starting from scratch, start at the most general */ if (!glueBack) { - for (i = gi->nodes-1; i >= 0; i--) { - if (gi->n[i].be->be_entry_open && - gi->n[i].be->be_entry_first) { - glueBack = gi->n[i].be; + for (i = gi->gi_nodes-1; i >= 0; i--) { + if (gi->gi_n[i].gn_be->be_entry_open && + gi->gi_n[i].gn_be->be_entry_first) { + glueBack = gi->gi_n[i].gn_be; break; } } @@ -466,15 +487,15 @@ glue_tool_entry_next ( while (rc == NOID) { if ( glueBack && glueBack->be_entry_close ) glueBack->be_entry_close (glueBack); - for (i=0; inodes; i++) { - if (gi->n[i].be == glueBack) + for (i=0; igi_nodes; i++) { + if (gi->gi_n[i].gn_be == glueBack) break; } if (i == 0) { glueBack = NULL; break; } else { - glueBack = gi->n[i-1].be; + glueBack = gi->gi_n[i-1].gn_be; rc = glue_tool_entry_first (b0); } } @@ -546,9 +567,9 @@ glue_tool_sync ( int i; /* just sync everyone */ - for (i = 0; inodes; i++) - if (gi->n[i].be->be_sync) - gi->n[i].be->be_sync (gi->n[i].be); + for (i = 0; igi_nodes; i++) + if (gi->gi_n[i].gn_be->be_sync) + gi->gi_n[i].gn_be->be_sync (gi->gi_n[i].gn_be); return 0; } @@ -568,7 +589,7 @@ glue_sub_init( ) if (SLAP_GLUE_SUBORDINATE ( b1 ) ) { /* The last database cannot be a subordinate of noone */ if (i == nBackendDB - 1) { - b1->be_flags ^= SLAP_BFLAG_GLUE_SUBORDINATE; + SLAP_DBFLAGS(b1) ^= SLAP_DBFLAG_GLUE_SUBORDINATE; } continue; } @@ -587,7 +608,7 @@ glue_sub_init( ) continue; } cont--; - be->be_flags |= SLAP_BFLAG_GLUE_LINKED; + SLAP_DBFLAGS(be) |= SLAP_DBFLAG_GLUE_LINKED; if (gi == NULL) { /* We create a copy of the superior's be * structure, pointing to all of its original @@ -596,11 +617,11 @@ glue_sub_init( ) * is used whenever we have operations to pass * down to the real database. */ - b1->be_flags |= SLAP_BFLAG_GLUE_INSTANCE; + SLAP_DBFLAGS(b1) |= SLAP_DBFLAG_GLUE_INSTANCE; gi = (glueinfo *)ch_malloc(sizeof(glueinfo)); - gi->nodes = 0; - gi->bd = *b1; - gi->bi = *b1->bd_info; + gi->gi_nodes = 0; + gi->gi_bd = *b1; + gi->gi_bi = *b1->bd_info; bi = (BackendInfo *)gi; bi->bi_open = glue_back_open; bi->bi_close = glue_back_close; @@ -628,19 +649,19 @@ glue_sub_init( ) } else { gi = (glueinfo *)ch_realloc(gi, sizeof(glueinfo) + - gi->nodes * sizeof(gluenode)); + gi->gi_nodes * sizeof(gluenode)); } - gi->n[gi->nodes].be = be; - dnParent( &be->be_nsuffix[0], &gi->n[gi->nodes].pdn ); - gi->nodes++; + gi->gi_n[gi->gi_nodes].gn_be = be; + dnParent( &be->be_nsuffix[0], &gi->gi_n[gi->gi_nodes].gn_pdn ); + gi->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->bd; - dnParent( &b1->be_nsuffix[0], &gi->n[gi->nodes].pdn ); - gi->nodes++; + sizeof(glueinfo) + gi->gi_nodes * sizeof(gluenode)); + gi->gi_n[gi->gi_nodes].gn_be = &gi->gi_bd; + dnParent( &b1->be_nsuffix[0], &gi->gi_n[gi->gi_nodes].gn_pdn ); + gi->gi_nodes++; b1->bd_info = (BackendInfo *)gi; } }