From 3fa3976ea4d5e051f84e25c14fe5a4f19424d1b9 Mon Sep 17 00:00:00 2001 From: Ludwig Krispenz Date: Mon, 18 Dec 2017 17:29:33 +0100 Subject: [PATCH] Ticket 49278 - no template processing for real entries, cleanup --- ldap/servers/slapd/opshared.c | 231 +++++++++++++++++++----------------------- 1 file changed, 105 insertions(+), 126 deletions(-) diff --git a/ldap/servers/slapd/opshared.c b/ldap/servers/slapd/opshared.c index c552e73..72e9919 100644 --- a/ldap/servers/slapd/opshared.c +++ b/ldap/servers/slapd/opshared.c @@ -33,6 +33,7 @@ static char *pwpolicy_lock_attrs_all[] = {"passwordRetryCount", static void compute_limits(Slapi_PBlock *pb); static int send_results_ext(Slapi_PBlock *pb, int send_result, int *nentries, int pagesize, unsigned int *pr_stat); static int process_entry(Slapi_PBlock *pb, Slapi_Entry *e, int send_result); +static void send_entry(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Operation *operation, char **attrs, int attrsonly, int *pnentries); int op_shared_is_allowed_attr(const char *attr_name, int replicated_op) @@ -1040,6 +1041,31 @@ process_entry(Slapi_PBlock *pb, Slapi_Entry *e, int send_result) return 0; } +static void +send_entry(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Operation *operation, char **attrs, int attrsonly, int *pnentries) +{ + /* + * It's a regular entry, or it's a referral and + * managedsait control is on. In either case, send + * the entry. + */ + switch (send_ldap_search_entry(pb, e, NULL, attrs, attrsonly)) { + case 0: /* entry sent ok */ + (*pnentries)++; + slapi_pblock_set(pb, SLAPI_NENTRIES, pnentries); + break; + case 1: /* entry not sent */ + break; + case -1: /* connection closed */ + /* + * mark the operation as abandoned so the backend + * next entry function gets called again and has + * a chance to clean things up. + */ + operation->o_status = SLAPI_OP_STATUS_ABANDONED; + break; + } +} #if 0 /* Loops through search entries and sends them to the client. @@ -1237,64 +1263,54 @@ iterate(Slapi_PBlock *pb, Slapi_Backend *be, int send_result, int *pnentries, in /* Check for possible get_effective_rights control */ if (operation->o_flags & OP_FLAG_GET_EFFECTIVE_RIGHTS) { - char *errbuf = NULL; + char *errbuf = NULL; + + if (PAGEDRESULTS_PAGE_END == pr_stat) { + /* + * read ahead -- there is at least more entry. + * undo it and return the PAGE_END + */ + be->be_prev_search_results(pb); + done = 1; + continue; + } + if ( e == NULL ) { char **gerattrs = NULL; char **gerattrsdup = NULL; char **gap = NULL; char *gapnext = NULL; - - if (PAGEDRESULTS_PAGE_END == pr_stat) { - /* - * read ahead -- there is at least more entry. - * undo it and return the PAGE_END + /* we have no more entries + * but we might create a template entry for GER + * so we need to continue, but make sure to stop + * after handling the template entry */ - be->be_prev_search_results(pb); - done = 1; - continue; - } - if ( e == NULL ) { - /* we have no more entries - * but we might create a template entry for GER - * so we need to continue, but make sure to stop - * after handling the template entry - */ - done = 1; - pr_stat = PAGEDRESULTS_SEARCH_END; - } + done = 1; + pr_stat = PAGEDRESULTS_SEARCH_END; slapi_pblock_get(pb, SLAPI_SEARCH_GERATTRS, &gerattrs); gerattrsdup = cool_charray_dup(gerattrs); gap = gerattrsdup; - do { + while (gap && *gap) { gapnext = NULL; - if (gap) { - if (*gap && *(gap + 1)) { - gapnext = *(gap + 1); - *(gap + 1) = NULL; - } - slapi_pblock_set(pb, SLAPI_SEARCH_GERATTRS, gap); - rc = plugin_call_acl_plugin(pb, e, attrs, NULL, - SLAPI_ACL_ALL, ACLPLUGIN_ACCESS_GET_EFFECTIVE_RIGHTS, - &errbuf); - if (NULL != gapnext) { - *(gap + 1) = gapnext; - } - } else if (NULL != e) { - rc = plugin_call_acl_plugin(pb, e, attrs, NULL, - SLAPI_ACL_ALL, ACLPLUGIN_ACCESS_GET_EFFECTIVE_RIGHTS, - &errbuf); + if (*(gap + 1)) { + gapnext = *(gap + 1); + *(gap + 1) = NULL; + } + slapi_pblock_set(pb, SLAPI_SEARCH_GERATTRS, gap); + rc = plugin_call_acl_plugin(pb, e, attrs, NULL, + SLAPI_ACL_ALL, ACLPLUGIN_ACCESS_GET_EFFECTIVE_RIGHTS, + &errbuf); + if (NULL != gapnext) { + *(gap + 1) = gapnext; } + gap++; + /* get the template entry, if any */ + slapi_pblock_get(pb, SLAPI_SEARCH_RESULT_ENTRY, &e); if (NULL == e) { - /* get the template entry, if any */ - slapi_pblock_get(pb, SLAPI_SEARCH_RESULT_ENTRY, &e); - if (NULL == e) { - /* everything is ok - don't send the result */ - pr_stat = PAGEDRESULTS_SEARCH_END; - done = 1; - continue; - } - gerentry = e; + /* everything is ok - don't send the result */ + continue; } + gerentry = e; if (rc != LDAP_SUCCESS) { /* Send error result and abort op if the control is critical */ @@ -1302,64 +1318,51 @@ iterate(Slapi_PBlock *pb, Slapi_Backend *be, int send_result, int *pnentries, in "Failed to get effective rights for entry (%s), rc=%d\n", slapi_entry_get_dn_const(e), rc); send_ldap_result(pb, rc, NULL, errbuf, 0, NULL); - slapi_ch_free((void **)&errbuf); - if (gerentry) { - slapi_pblock_set(pb, SLAPI_SEARCH_RESULT_ENTRY, NULL); - slapi_entry_free(gerentry); - gerentry = e = NULL; - } - pr_stat = PAGEDRESULTS_SEARCH_END; rval = -1; - done = 1; - continue; - } - slapi_ch_free((void **)&errbuf); - if (process_entry(pb, e, send_result)) { - /* shouldn't send this entry */ - if (gerentry) { - slapi_pblock_set(pb, SLAPI_SEARCH_RESULT_ENTRY, NULL); - slapi_entry_free(gerentry); - gerentry = e = NULL; + } else { + if (!process_entry(pb, e, send_result)) { + /* should send this entry now*/ + send_entry(pb, e, operation, attrs, attrsonly, pnentries); } - continue; } - /* - * It's a regular entry, or it's a referral and - * managedsait control is on. In either case, send - * the entry. - */ - switch (send_ldap_search_entry(pb, e, NULL, attrs, attrsonly)) { - case 0: /* entry sent ok */ - (*pnentries)++; - slapi_pblock_set(pb, SLAPI_NENTRIES, pnentries); - break; - case 1: /* entry not sent */ - break; - case -1: /* connection closed */ - /* - * mark the operation as abandoned so the backend - * next entry function gets called again and has - * a chance to clean things up. - */ - operation->o_status = SLAPI_OP_STATUS_ABANDONED; - break; - } + slapi_ch_free((void **)&errbuf); if (gerentry) { slapi_pblock_set(pb, SLAPI_SEARCH_RESULT_ENTRY, NULL); slapi_entry_free(gerentry); gerentry = e = NULL; } - } while (gap && ++gap && *gap); + } /* while ger template */ slapi_pblock_set(pb, SLAPI_SEARCH_GERATTRS, gerattrs); cool_charray_free(gerattrsdup); - if (pagesize == *pnentries) { - /* PAGED RESULTS: reached the pagesize */ - /* We don't set "done = 1" here. - * We read ahead next entry to check whether there is - * more entries to return or not. */ - pr_stat = PAGEDRESULTS_PAGE_END; + } else { + /* we are processing geteffective rights for an existing entry */ + rc = plugin_call_acl_plugin(pb, e, attrs, NULL, + SLAPI_ACL_ALL, ACLPLUGIN_ACCESS_GET_EFFECTIVE_RIGHTS, + &errbuf); + if (rc != LDAP_SUCCESS) { + /* Send error result and + abort op if the control is critical */ + slapi_log_err(SLAPI_LOG_ERR, "iterate", + "Failed to get effective rights for entry (%s), rc=%d\n", + slapi_entry_get_dn_const(e), rc); + send_ldap_result(pb, rc, NULL, errbuf, 0, NULL); + rval = -1; + } else { + if (!process_entry(pb, e, send_result)) { + /* should send this entry now*/ + send_entry(pb, e, operation, attrs, attrsonly, pnentries); + if (pagesize == *pnentries) { + /* PAGED RESULTS: reached the pagesize */ + /* We don't set "done = 1" here. + * We read ahead next entry to check whether there is + * more entries to return or not. */ + pr_stat = PAGEDRESULTS_PAGE_END; + } + } } + slapi_ch_free((void **)&errbuf); + } /* not GET_EFFECTIVE_RIGHTS */ } else if (e) { if (PAGEDRESULTS_PAGE_END == pr_stat) { @@ -1373,45 +1376,21 @@ iterate(Slapi_PBlock *pb, Slapi_Backend *be, int send_result, int *pnentries, in } /* Adding shadow password attrs. */ add_shadow_ext_password_attrs(pb, &e); - if (process_entry(pb, e, send_result)) { - /* shouldn't send this entry */ - struct slapi_entry *pb_pw_entry = slapi_pblock_get_pw_entry(pb); - slapi_entry_free(pb_pw_entry); - slapi_pblock_set_pw_entry(pb, NULL); - continue; - } - - /* - * It's a regular entry, or it's a referral and - * managedsait control is on. In either case, send - * the entry. - */ - switch (send_ldap_search_entry(pb, e, NULL, attrs, attrsonly)) { - case 0: /* entry sent ok */ - (*pnentries)++; - slapi_pblock_set(pb, SLAPI_NENTRIES, pnentries); - break; - case 1: /* entry not sent */ - break; - case -1: /* connection closed */ - /* - * mark the operation as abandoned so the backend - * next entry function gets called again and has - * a chance to clean things up. - */ - operation->o_status = SLAPI_OP_STATUS_ABANDONED; - break; + if (!process_entry(pb, e, send_result)) { + /*this entry was not sent, do it now*/ + send_entry(pb, e, operation, attrs, attrsonly, pnentries); + if (pagesize == *pnentries) { + /* PAGED RESULTS: reached the pagesize */ + /* We don't set "done = 1" here. + * We read ahead next entry to check whether there is + * more entries to return or not. */ + pr_stat = PAGEDRESULTS_PAGE_END; + } } + /* cleanup pw entry . sent or not */ struct slapi_entry *pb_pw_entry = slapi_pblock_get_pw_entry(pb); slapi_entry_free(pb_pw_entry); slapi_pblock_set_pw_entry(pb, NULL); - if (pagesize == *pnentries) { - /* PAGED RESULTS: reached the pagesize */ - /* We don't set "done = 1" here. - * We read ahead next entry to check whether there is - * more entries to return or not. */ - pr_stat = PAGEDRESULTS_PAGE_END; - } } else { /* no more entries */ done = 1; -- 2.5.5