From c68a5e0ea82af904ffcdc7a8c7f8dc1f9edb686a Mon Sep 17 00:00:00 2001 From: Noriko Hosoi Date: Tue, 8 Jul 2014 17:40:00 -0700 Subject: [PATCH 236/243] Ticket #47824 - paged results control is not working in some cases when we have a subsuffix. Bug Description: When a simple paged result search is run against multiple backends, subsuffix backends were not correctly set to the next loop when crossing the backend boundary. Fix Description: This patch changes the logic to detect the page search finished and set the next backend correctly to the paged- results handle. Also, when reusing the paged result handle in pagedresults_parse_control_value, increment the refcnt. https://fedorahosted.org/389/ticket/47824 Reviewed by mreynolds@redhat.com (Thank you, Mark!!) (cherry picked from commit b116d7e2a7a8e7443be93ecb84efee1364b6ba86) (cherry picked from commit 0bc9016541b7033916bc9ca6636f447a95d33c36) (cherry picked from commit 96741952eff493cca968914346bab898a064a986) --- ldap/servers/slapd/opshared.c | 17 ++++++++++------- ldap/servers/slapd/pagedresults.c | 5 +++++ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/ldap/servers/slapd/opshared.c b/ldap/servers/slapd/opshared.c index 1689283..65fcea6 100644 --- a/ldap/servers/slapd/opshared.c +++ b/ldap/servers/slapd/opshared.c @@ -510,7 +510,6 @@ op_shared_search (Slapi_PBlock *pb, int send_result) err_code = slapi_mapping_tree_select_all(pb, be_list, referral_list, errorbuf); if (((err_code != LDAP_SUCCESS) && (err_code != LDAP_OPERATIONS_ERROR) && (err_code != LDAP_REFERRAL)) || ((err_code == LDAP_OPERATIONS_ERROR) && (be_list[0] == NULL))) - { send_ldap_result(pb, err_code, NULL, errorbuf, 0, NULL); rc = -1; @@ -713,10 +712,6 @@ op_shared_search (Slapi_PBlock *pb, int send_result) curr_search_count = -1; } else { curr_search_count = pnentries; - /* no more entries, but at least another backend */ - if (pagedresults_set_current_be(pb->pb_conn, next_be, pr_idx) < 0) { - goto free_and_return; - } } estimate = 0; } else { @@ -731,12 +726,20 @@ op_shared_search (Slapi_PBlock *pb, int send_result) pagedresults_set_search_result_set_size_estimate(pb->pb_conn, operation, estimate, pr_idx); - next_be = NULL; /* to break the loop */ - if (curr_search_count == -1) { + if (PAGEDRESULTS_SEARCH_END == pr_stat) { pagedresults_lock(pb->pb_conn, pr_idx); slapi_pblock_set(pb, SLAPI_SEARCH_RESULT_SET, NULL); pagedresults_free_one(pb->pb_conn, operation, pr_idx); pagedresults_unlock(pb->pb_conn, pr_idx); + if (next_be) { + /* no more entries, but at least another backend */ + if (pagedresults_set_current_be(pb->pb_conn, next_be, pr_idx) < 0) { + goto free_and_return; + } + } + next_be = NULL; /* to break the loop */ + } else if (PAGEDRESULTS_PAGE_END == pr_stat) { + next_be = NULL; /* to break the loop */ } } else { /* be_suffix null means that we are searching the default backend diff --git a/ldap/servers/slapd/pagedresults.c b/ldap/servers/slapd/pagedresults.c index edd76c6..d589708 100644 --- a/ldap/servers/slapd/pagedresults.c +++ b/ldap/servers/slapd/pagedresults.c @@ -136,6 +136,7 @@ pagedresults_parse_control_value( Slapi_PBlock *pb, } conn->c_pagedresults.prl_count++; } else { + PagedResults *prp = NULL; /* Repeated paged results request. * PagedResults is already allocated. */ char *ptr = slapi_ch_malloc(cookie.bv_len + 1); @@ -143,6 +144,10 @@ pagedresults_parse_control_value( Slapi_PBlock *pb, *(ptr+cookie.bv_len) = '\0'; *index = strtol(ptr, NULL, 10); slapi_ch_free_string(&ptr); + prp = conn->c_pagedresults.prl_list + *index; + if (!(prp->pr_search_result_set)) { /* freed and reused for the next backend. */ + conn->c_pagedresults.prl_count++; + } } /* reset sizelimit */ op->o_pagedresults_sizelimit = -1; -- 1.8.1.4