diff options
Diffstat (limited to 'src/back-sch.c')
-rw-r--r-- | src/back-sch.c | 173 |
1 files changed, 132 insertions, 41 deletions
diff --git a/src/back-sch.c b/src/back-sch.c index acc71af..4eb1873 100644 --- a/src/back-sch.c +++ b/src/back-sch.c @@ -659,7 +659,6 @@ struct backend_search_cbdata { const char *matched, *text; int n_entries; }; - static bool_t backend_search_entry_cb(const char *domain, const char *map, bool_t secure, const char *key, unsigned int key_len, @@ -675,15 +674,26 @@ backend_search_entry_cb(const char *domain, const char *map, bool_t secure, cbdata = cb_data; entry_data = backend_data; sdn = slapi_entry_get_sdn(entry_data->e); - /* We've already done the scope check, so just check the filter. */ + /* We've already done the scope check, so just check the entry against + * the filter. */ result = slapi_filter_test(cbdata->pb, entry_data->e, cbdata->filter, cbdata->check_access); - if (result == -1) { - /* No match. Return. */ - return TRUE; - } - /* Return an LDAP error, if one was generated. */ - if (result != 0) { + switch (result) { + case -1: + /* Not a match. */ + break; + case 0: + /* Match. Return the entry. */ + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata->state->plugin_desc->spd_id, + "search matched %s\n", + slapi_sdn_get_ndn(sdn)); + slapi_send_ldap_search_entry(cbdata->pb, entry_data->e, NULL, + cbdata->attrs, cbdata->attrsonly); + cbdata->n_entries++; + break; + default: + /* Return an LDAP error. */ slapi_log_error(SLAPI_LOG_PLUGIN, cbdata->state->plugin_desc->spd_id, "search got error %d checking %s\n", @@ -692,17 +702,8 @@ backend_search_entry_cb(const char *domain, const char *map, bool_t secure, if (cbdata->result == 0) { cbdata->result = result; } - return TRUE; + break; } - /* Return the result entry. */ - slapi_log_error(SLAPI_LOG_PLUGIN, - cbdata->state->plugin_desc->spd_id, - "search matched %s\n", - slapi_sdn_get_ndn(sdn)); - cbdata->answer = TRUE; - slapi_send_ldap_search_entry(cbdata->pb, entry_data->e, - NULL, cbdata->attrs, cbdata->attrsonly); - cbdata->n_entries++; return TRUE; } static bool_t @@ -711,50 +712,141 @@ backend_search_set_cb(const char *group, const char *set, bool_t flag, { struct backend_search_cbdata *cbdata; struct backend_set_data *set_data; + Slapi_Entry *set_entry; + int result; + const char *ndn; + cbdata = cb_data; set_data = backend_data; cbdata->check_access = set_data->check_access; - /* First, do a scope test on this set. */ + /* Check the set itself. */ + if (slapi_sdn_scope_test(set_data->container_sdn, cbdata->target_dn, + cbdata->scope)) { + set_entry = slapi_entry_alloc(); + slapi_entry_add_string(set_entry, + "objectClass", "extensibleObject"); + slapi_entry_set_sdn(set_entry, set_data->container_sdn); + ndn = slapi_sdn_get_ndn(set_data->container_sdn); + result = slapi_filter_test(cbdata->pb, set_entry, + cbdata->filter, + cbdata->check_access); + switch (result) { + case -1: + /* Not a match. */ + break; + case 0: + /* Match. Return the entry. */ + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata->state->plugin_desc->spd_id, + "search matched %s\n", ndn); + slapi_send_ldap_search_entry(cbdata->pb, set_entry, + NULL, cbdata->attrs, + cbdata->attrsonly); + cbdata->n_entries++; + break; + default: + /* Return an LDAP error. */ + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata->state->plugin_desc->spd_id, + "search got error %d checking %s\n", + result, ndn); + cbdata->answer = TRUE; + if (cbdata->result == 0) { + cbdata->result = result; + } + break; + } + slapi_entry_free(set_entry); + } + /* Now scope-check the set's contents so that we only do it once. */ switch (cbdata->scope) { case LDAP_SCOPE_BASE: - /* If the container is not the parent of the target, and it is - * not itself the target, then we're done with this set. */ - if ((slapi_sdn_compare(set_data->container_sdn, - cbdata->target_dn) != 0) && - (slapi_sdn_isparent(set_data->container_sdn, - cbdata->target_dn) != 1)) { + /* If the container is not the parent of the target, then we're + * done with this set. */ + if (slapi_sdn_isparent(set_data->container_sdn, + cbdata->target_dn) != 1) { return TRUE; } break; case LDAP_SCOPE_ONE: - /* If it's not a scope=one search of this set or the group to - * which the set belongs, then we're done with this set. */ - if ((slapi_sdn_compare(set_data->container_sdn, - cbdata->target_dn) != 0) && - (slapi_sdn_isparent(cbdata->target_dn, - set_data->container_sdn) != 1)) { + /* If it's not a scope=one search of this set, then we're done + * with this set. */ + if (slapi_sdn_compare(set_data->container_sdn, + cbdata->target_dn) != 0) { return TRUE; } break; case LDAP_SCOPE_SUB: - /* If the target is not a child of this container, it is not - * the container itself, and it is not the group, then we're - * done with this set. */ - if ((slapi_sdn_isparent(set_data->container_sdn, - cbdata->target_dn) != 1) && - (slapi_sdn_compare(set_data->container_sdn, + /* If the search suffix is not a suffix of the set and it's not + * the set itself, then we're done with this set. */ + if ((slapi_sdn_compare(set_data->container_sdn, cbdata->target_dn) != 0) && - (slapi_sdn_isparent(cbdata->target_dn, - set_data->container_sdn) != 1)) { + (slapi_sdn_issuffix(set_data->container_sdn, + cbdata->target_dn) != 1)) { return TRUE; } break; } + /* Walk the set of entries in this set. */ map_data_foreach_entry_id(cbdata->state, group, set, NULL, backend_search_entry_cb, cbdata); return TRUE; } +static bool_t +backend_search_group_cb(const char *group, void *cb_data) +{ + struct backend_search_cbdata *cbdata; + Slapi_DN *group_dn; + Slapi_Entry *group_entry; + int result; + + cbdata = cb_data; + /* Check the group itself. */ + group_dn = slapi_sdn_new_dn_byref(group); + if (slapi_sdn_scope_test(group_dn, cbdata->target_dn, cbdata->scope)) { + group_entry = slapi_entry_alloc(); + slapi_entry_add_string(group_entry, + "objectClass", "extensibleObject"); + slapi_entry_set_sdn(group_entry, group_dn); + result = slapi_filter_test(cbdata->pb, group_entry, + cbdata->filter, + cbdata->check_access); + switch (result) { + case -1: + /* Not a match. */ + break; + case 0: + /* Match. Return the entry. */ + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata->state->plugin_desc->spd_id, + "search matched %s\n", group); + slapi_send_ldap_search_entry(cbdata->pb, group_entry, + NULL, cbdata->attrs, + cbdata->attrsonly); + cbdata->n_entries++; + break; + default: + /* Return an LDAP error. */ + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata->state->plugin_desc->spd_id, + "search got error %d checking %s\n", + result, group); + cbdata->answer = TRUE; + if (cbdata->result == 0) { + cbdata->result = result; + } + break; + } + slapi_entry_free(group_entry); + } + slapi_sdn_free(&group_dn); + /* Now check the group's sets and their contents. */ + map_data_foreach_map(cbdata->state, group, + backend_search_set_cb, cbdata); + return TRUE; +} + static int backend_search_cb(Slapi_PBlock *pb) { @@ -778,8 +870,7 @@ backend_search_cb(Slapi_PBlock *pb) cbdata.matched = ""; cbdata.text = ""; cbdata.n_entries = 0; - map_data_foreach_map(cbdata.state, NULL, - backend_search_set_cb, &cbdata); + map_data_foreach_domain(cbdata.state, backend_search_group_cb, &cbdata); slapi_sdn_free(&cbdata.target_dn); if (cbdata.answer) { slapi_send_ldap_result(cbdata.pb, cbdata.result, |