2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina/*
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina Authors:
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina Pavel Březina <pbrezina@redhat.com>
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina Copyright (C) 2016 Red Hat
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina This program is free software; you can redistribute it and/or modify
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina it under the terms of the GNU General Public License as published by
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina the Free Software Foundation; either version 3 of the License, or
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina (at your option) any later version.
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina This program is distributed in the hope that it will be useful,
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina but WITHOUT ANY WARRANTY; without even the implied warranty of
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina GNU General Public License for more details.
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina You should have received a copy of the GNU General Public License
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina along with this program. If not, see <http://www.gnu.org/licenses/>.
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina*/
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina#include <ldb.h>
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina#include <talloc.h>
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina#include <tevent.h>
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina#include "util/util.h"
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina#include "responder/common/cache_req/cache_req_private.h"
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina#include "responder/common/cache_req/cache_req_plugin.h"
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březinastatic errno_t cache_req_search_ncache(struct cache_req *cr)
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina{
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina errno_t ret;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina if (cr->plugin->ncache_check_fn == NULL) {
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina CACHE_REQ_DEBUG(SSSDBG_TRACE_INTERNAL, cr,
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina "This request type does not support negative cache\n");
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina return EOK;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina }
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, cr,
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina "Checking negative cache for [%s]\n",
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina cr->debugobj);
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina ret = cr->plugin->ncache_check_fn(cr->ncache, cr->domain, cr->data);
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina if (ret == EEXIST) {
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, cr,
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina "[%s] does not exist (negative cache)\n",
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina cr->debugobj);
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina return ENOENT;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina } else if (ret != EOK && ret != ENOENT) {
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina CACHE_REQ_DEBUG(SSSDBG_CRIT_FAILURE, cr,
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina "Unable to check negative cache [%d]: %s\n",
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina ret, sss_strerror(ret));
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina return ret;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina }
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, cr,
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina "[%s] is not present in negative cache\n",
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina cr->debugobj);
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina return EOK;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina}
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
800b1a27543fa83bc6cd73d8e2789f3cdbaf584aJakub Hrozekvoid cache_req_search_ncache_add_to_domain(struct cache_req *cr,
800b1a27543fa83bc6cd73d8e2789f3cdbaf584aJakub Hrozek struct sss_domain_info *domain)
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina{
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina errno_t ret;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina if (cr->plugin->ncache_add_fn == NULL) {
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina CACHE_REQ_DEBUG(SSSDBG_TRACE_INTERNAL, cr,
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina "This request type does not support negative cache\n");
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina return;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina }
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, cr, "Adding [%s] to negative cache\n",
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina cr->debugobj);
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
800b1a27543fa83bc6cd73d8e2789f3cdbaf584aJakub Hrozek ret = cr->plugin->ncache_add_fn(cr->ncache, domain, cr->data);
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina if (ret != EOK) {
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina CACHE_REQ_DEBUG(SSSDBG_MINOR_FAILURE, cr,
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina "Cannot set negative cache for [%s] [%d]: %s\n",
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina cr->debugobj, ret, sss_strerror(ret));
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina /* not fatal */
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina }
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina return;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina}
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
800b1a27543fa83bc6cd73d8e2789f3cdbaf584aJakub Hrozekstatic void cache_req_search_ncache_add(struct cache_req *cr)
800b1a27543fa83bc6cd73d8e2789f3cdbaf584aJakub Hrozek{
800b1a27543fa83bc6cd73d8e2789f3cdbaf584aJakub Hrozek return cache_req_search_ncache_add_to_domain(cr, cr->domain);
800b1a27543fa83bc6cd73d8e2789f3cdbaf584aJakub Hrozek}
800b1a27543fa83bc6cd73d8e2789f3cdbaf584aJakub Hrozek
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidênciostatic errno_t cache_req_search_ncache_filter(TALLOC_CTX *mem_ctx,
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio struct cache_req *cr,
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio struct ldb_result **_result)
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio{
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio TALLOC_CTX *tmp_ctx;
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio struct ldb_result *filtered_result;
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio struct ldb_message **msgs;
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio size_t msg_count;
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio const char *name;
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio errno_t ret;
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio tmp_ctx = talloc_new(NULL);
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio if (tmp_ctx == NULL) {
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio return ENOMEM;
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio }
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio if (cr->plugin->ncache_filter_fn == NULL) {
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, cr,
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio "This request type does not support filtering "
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio "result by negative cache\n");
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio ret = EOK;
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio goto done;
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio }
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, cr,
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio "Filtering out results by negative cache\n");
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio
c8193b1602cf44740b59f5dfcdc5330508c0c365Fabiano Fidêncio msgs = talloc_zero_array(tmp_ctx, struct ldb_message *, (*_result)->count);
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio msg_count = 0;
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio
c8193b1602cf44740b59f5dfcdc5330508c0c365Fabiano Fidêncio for (size_t i = 0; i < (*_result)->count; i++) {
c8193b1602cf44740b59f5dfcdc5330508c0c365Fabiano Fidêncio name = sss_get_name_from_msg(cr->domain, (*_result)->msgs[i]);
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio if (name == NULL) {
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio CACHE_REQ_DEBUG(SSSDBG_CRIT_FAILURE, cr,
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio "sss_get_name_from_msg() returned NULL, which should never "
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio "happen in this scenario!\n");
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio ret = ERR_INTERNAL;
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio goto done;
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio }
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio ret = cr->plugin->ncache_filter_fn(cr->ncache, cr->domain, name);
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio if (ret == EEXIST) {
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, cr,
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio "[%s] filtered out! (negative cache)\n",
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio name);
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio continue;
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio } else if (ret != EOK && ret != ENOENT) {
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio CACHE_REQ_DEBUG(SSSDBG_CRIT_FAILURE, cr,
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio "Unable to check negative cache [%d]: %s\n",
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio ret, sss_strerror(ret));
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio goto done;
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio }
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio
c8193b1602cf44740b59f5dfcdc5330508c0c365Fabiano Fidêncio msgs[msg_count] = talloc_steal(msgs, (*_result)->msgs[i]);
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio msg_count++;
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio }
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio if (msg_count == 0) {
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio ret = ENOENT;
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio goto done;
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio }
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio filtered_result = cache_req_create_ldb_result_from_msg_list(tmp_ctx, msgs,
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio msg_count);
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio if (filtered_result == NULL) {
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio ret = ENOMEM;
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio goto done;
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio }
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio
c8193b1602cf44740b59f5dfcdc5330508c0c365Fabiano Fidêncio talloc_zfree(*_result);
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio *_result = talloc_steal(mem_ctx, filtered_result);
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio ret = EOK;
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidênciodone:
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio talloc_free(tmp_ctx);
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio return ret;
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio}
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březinastatic errno_t cache_req_search_cache(TALLOC_CTX *mem_ctx,
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina struct cache_req *cr,
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina struct ldb_result **_result)
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina{
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina struct ldb_result *result = NULL;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina errno_t ret;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina if (cr->plugin->lookup_fn == NULL) {
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina CACHE_REQ_DEBUG(SSSDBG_CRIT_FAILURE, cr,
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina "Bug: No cache lookup function specified\n");
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina return ERR_INTERNAL;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina }
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, cr,
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina "Looking up [%s] in cache\n",
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina cr->debugobj);
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina ret = cr->plugin->lookup_fn(mem_ctx, cr, cr->data, cr->domain, &result);
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina if (ret == EOK && (result == NULL || result->count == 0)) {
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina ret = ENOENT;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina }
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina switch (ret) {
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina case EOK:
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina if (cr->plugin->only_one_result && result->count > 1) {
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina CACHE_REQ_DEBUG(SSSDBG_CRIT_FAILURE, cr,
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina "Multiple objects were found when "
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina "only one was expected!\n");
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina ret = ERR_INTERNAL;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina goto done;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina }
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina *_result = result;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina break;
2af80640f18966d65cf82106059ce3c060df93bfamitkuma case ERR_ID_OUTSIDE_RANGE:
2af80640f18966d65cf82106059ce3c060df93bfamitkuma CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, cr,
2af80640f18966d65cf82106059ce3c060df93bfamitkuma "ID [%s] was filtered out\n",
2af80640f18966d65cf82106059ce3c060df93bfamitkuma cr->debugobj);
2af80640f18966d65cf82106059ce3c060df93bfamitkuma break;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina case ENOENT:
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, cr,
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina "Object [%s] was not found in cache\n",
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina cr->debugobj);
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina break;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina default:
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina CACHE_REQ_DEBUG(SSSDBG_CRIT_FAILURE, cr,
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina "Unable to lookup [%s] in cache [%d]: %s\n",
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina cr->debugobj, ret, sss_strerror(ret));
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina break;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina }
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březinadone:
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina if (ret != EOK) {
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina talloc_free(result);
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina }
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina return ret;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina}
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březinastatic enum cache_object_status
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březinacache_req_expiration_status(struct cache_req *cr,
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina struct ldb_result *result)
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina{
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina time_t expire;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina errno_t ret;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina if (result == NULL || result->count == 0 || cr->plugin->bypass_cache) {
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina return CACHE_OBJECT_MISSING;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina }
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina expire = ldb_msg_find_attr_as_uint64(result->msgs[0],
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina cr->plugin->attr_expiration, 0);
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina ret = sss_cmd_check_cache(result->msgs[0], cr->midpoint, expire);
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina if (ret == EOK) {
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina return CACHE_OBJECT_VALID;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina } else if (ret == EAGAIN) {
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina return CACHE_OBJECT_MIDPOINT;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina }
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina return CACHE_OBJECT_EXPIRED;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina}
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březinastruct cache_req_search_state {
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina /* input data */
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina struct tevent_context *ev;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina struct resp_ctx *rctx;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina struct cache_req *cr;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina /* output data */
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina struct ldb_result *result;
2d12aae08aff6c17c1edb107a204c54d9acfe08dPavel Březina bool dp_success;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina};
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březinastatic errno_t cache_req_search_dp(struct tevent_req *req,
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina enum cache_object_status status);
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březinastatic void cache_req_search_oob_done(struct tevent_req *subreq);
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březinastatic void cache_req_search_done(struct tevent_req *subreq);
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březinastruct tevent_req *
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březinacache_req_search_send(TALLOC_CTX *mem_ctx,
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina struct tevent_context *ev,
8bb6680637ead03e24a38d15ec5265d11a920a1dFabiano Fidêncio struct cache_req *cr,
8bb6680637ead03e24a38d15ec5265d11a920a1dFabiano Fidêncio bool bypass_cache,
8bb6680637ead03e24a38d15ec5265d11a920a1dFabiano Fidêncio bool bypass_dp)
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina{
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina struct cache_req_search_state *state;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina enum cache_object_status status;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina struct tevent_req *req;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina errno_t ret;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina req = tevent_req_create(mem_ctx, &state, struct cache_req_search_state);
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina if (req == NULL) {
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina return NULL;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina }
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
817e3ec31bbdb5447f4ffcd3302c558283b90943Pavel Březina CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, cr, "Looking up %s\n", cr->debugobj);
817e3ec31bbdb5447f4ffcd3302c558283b90943Pavel Březina
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina state->ev = ev;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina state->cr = cr;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina ret = cache_req_search_ncache(cr);
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina if (ret != EOK) {
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina goto done;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina }
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
f63607bfcc01ad426efa20ed8ec65f429c9b2bd6Pavel Březina /* If bypass_cache is enabled we always contact data provider before
f63607bfcc01ad426efa20ed8ec65f429c9b2bd6Pavel Březina * searching the cache. Thus we set expiration status to missing,
f63607bfcc01ad426efa20ed8ec65f429c9b2bd6Pavel Březina * which will trigger data provider request later.
f63607bfcc01ad426efa20ed8ec65f429c9b2bd6Pavel Březina *
f63607bfcc01ad426efa20ed8ec65f429c9b2bd6Pavel Březina * If disabled, we want to search the cache here to see if the
f63607bfcc01ad426efa20ed8ec65f429c9b2bd6Pavel Březina * object is already cached and valid or if data provider needs
f63607bfcc01ad426efa20ed8ec65f429c9b2bd6Pavel Březina * to be contacted.
f63607bfcc01ad426efa20ed8ec65f429c9b2bd6Pavel Březina */
f63607bfcc01ad426efa20ed8ec65f429c9b2bd6Pavel Březina state->result = NULL;
f63607bfcc01ad426efa20ed8ec65f429c9b2bd6Pavel Březina status = CACHE_OBJECT_MISSING;
8bb6680637ead03e24a38d15ec5265d11a920a1dFabiano Fidêncio if (!bypass_cache) {
f63607bfcc01ad426efa20ed8ec65f429c9b2bd6Pavel Březina ret = cache_req_search_cache(state, cr, &state->result);
f63607bfcc01ad426efa20ed8ec65f429c9b2bd6Pavel Březina if (ret != EOK && ret != ENOENT) {
f63607bfcc01ad426efa20ed8ec65f429c9b2bd6Pavel Březina goto done;
f63607bfcc01ad426efa20ed8ec65f429c9b2bd6Pavel Březina }
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
f63607bfcc01ad426efa20ed8ec65f429c9b2bd6Pavel Březina status = cache_req_expiration_status(cr, state->result);
f63607bfcc01ad426efa20ed8ec65f429c9b2bd6Pavel Březina if (status == CACHE_OBJECT_VALID) {
f63607bfcc01ad426efa20ed8ec65f429c9b2bd6Pavel Březina CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, cr,
f63607bfcc01ad426efa20ed8ec65f429c9b2bd6Pavel Březina "Returning [%s] from cache\n", cr->debugobj);
f63607bfcc01ad426efa20ed8ec65f429c9b2bd6Pavel Březina ret = EOK;
f63607bfcc01ad426efa20ed8ec65f429c9b2bd6Pavel Březina goto done;
f63607bfcc01ad426efa20ed8ec65f429c9b2bd6Pavel Březina }
606015a4f71d8ee809347188667d268f73110483Pavel Březina
606015a4f71d8ee809347188667d268f73110483Pavel Březina /* If bypass_dp is true but we found the object in this domain,
606015a4f71d8ee809347188667d268f73110483Pavel Březina * we will contact the data provider anyway to refresh it so
606015a4f71d8ee809347188667d268f73110483Pavel Březina * we can return it without searching the rest of the domains.
606015a4f71d8ee809347188667d268f73110483Pavel Březina */
606015a4f71d8ee809347188667d268f73110483Pavel Březina if (status != CACHE_OBJECT_MISSING) {
606015a4f71d8ee809347188667d268f73110483Pavel Březina CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, cr,
606015a4f71d8ee809347188667d268f73110483Pavel Březina "Object found, but needs to be refreshed.\n");
606015a4f71d8ee809347188667d268f73110483Pavel Březina bypass_dp = false;
606015a4f71d8ee809347188667d268f73110483Pavel Březina } else {
606015a4f71d8ee809347188667d268f73110483Pavel Březina ret = ENOENT;
606015a4f71d8ee809347188667d268f73110483Pavel Březina }
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina }
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
8bb6680637ead03e24a38d15ec5265d11a920a1dFabiano Fidêncio if (!bypass_dp) {
8bb6680637ead03e24a38d15ec5265d11a920a1dFabiano Fidêncio ret = cache_req_search_dp(req, status);
8bb6680637ead03e24a38d15ec5265d11a920a1dFabiano Fidêncio }
8bb6680637ead03e24a38d15ec5265d11a920a1dFabiano Fidêncio
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina if (ret != EAGAIN) {
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina goto done;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina }
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina return req;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březinadone:
4c09cd008967c5c0ec358dc658ffc6fc1cef2697Fabiano Fidêncio if (ret == EOK) {
4c09cd008967c5c0ec358dc658ffc6fc1cef2697Fabiano Fidêncio ret = cache_req_search_ncache_filter(state, cr, &state->result);
4c09cd008967c5c0ec358dc658ffc6fc1cef2697Fabiano Fidêncio }
4c09cd008967c5c0ec358dc658ffc6fc1cef2697Fabiano Fidêncio
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina if (ret == EOK) {
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina tevent_req_done(req);
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina } else {
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina tevent_req_error(req, ret);
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina }
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina tevent_req_post(req, ev);
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina return req;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina}
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březinastatic errno_t cache_req_search_dp(struct tevent_req *req,
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina enum cache_object_status status)
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina{
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina struct cache_req_search_state *state;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina struct tevent_req *subreq;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina errno_t ret;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina state = tevent_req_data(req, struct cache_req_search_state);
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina switch (status) {
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina case CACHE_OBJECT_MIDPOINT:
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina /* Out of band update. The calling function will return the cached
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina * entry immediately. We need to use rctx so the request is not
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina * removed when state is freed. */
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, state->cr,
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina "Performing midpoint cache update of [%s]\n",
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina state->cr->debugobj);
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
0dacb781f094b97e40694aeff288853a8a4e9d63Pavel Březina subreq = state->cr->plugin->dp_send_fn(state->rctx, state->cr,
4df7aec645f87342f3a5146062abcb15f71f4fd9Pavel Březina state->cr->data,
4df7aec645f87342f3a5146062abcb15f71f4fd9Pavel Březina state->cr->domain,
4df7aec645f87342f3a5146062abcb15f71f4fd9Pavel Březina state->result);
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina if (subreq == NULL) {
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory sending out-of-band "
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina "data provider request\n");
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina /* This is non-fatal, so we'll continue here */
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina } else {
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina tevent_req_set_callback(subreq, cache_req_search_oob_done, req);
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina }
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
4df7aec645f87342f3a5146062abcb15f71f4fd9Pavel Březina ret = EOK;
4df7aec645f87342f3a5146062abcb15f71f4fd9Pavel Březina break;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina case CACHE_OBJECT_EXPIRED:
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina case CACHE_OBJECT_MISSING:
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, state->cr,
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina "Looking up [%s] in data provider\n",
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina state->cr->debugobj);
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
4df7aec645f87342f3a5146062abcb15f71f4fd9Pavel Březina subreq = state->cr->plugin->dp_send_fn(state->cr, state->cr,
4df7aec645f87342f3a5146062abcb15f71f4fd9Pavel Březina state->cr->data,
4df7aec645f87342f3a5146062abcb15f71f4fd9Pavel Březina state->cr->domain,
4df7aec645f87342f3a5146062abcb15f71f4fd9Pavel Březina state->result);
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina if (subreq == NULL) {
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE,
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina "Out of memory sending data provider request\n");
4df7aec645f87342f3a5146062abcb15f71f4fd9Pavel Březina ret = ENOMEM;
4df7aec645f87342f3a5146062abcb15f71f4fd9Pavel Březina break;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina }
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina tevent_req_set_callback(subreq, cache_req_search_done, req);
4df7aec645f87342f3a5146062abcb15f71f4fd9Pavel Březina ret = EAGAIN;
4df7aec645f87342f3a5146062abcb15f71f4fd9Pavel Březina break;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina default:
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina /* error */
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina CACHE_REQ_DEBUG(SSSDBG_CRIT_FAILURE, state->cr,
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina "Unexpected status [%d]\n", status);
4df7aec645f87342f3a5146062abcb15f71f4fd9Pavel Březina ret = ERR_INTERNAL;
4df7aec645f87342f3a5146062abcb15f71f4fd9Pavel Březina break;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina }
4df7aec645f87342f3a5146062abcb15f71f4fd9Pavel Březina
4df7aec645f87342f3a5146062abcb15f71f4fd9Pavel Březina return ret;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina}
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březinastatic void cache_req_search_oob_done(struct tevent_req *subreq)
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina{
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina DEBUG(SSSDBG_TRACE_INTERNAL, "Out of band request finished\n");
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina talloc_zfree(subreq);
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina return;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina}
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březinastatic void cache_req_search_done(struct tevent_req *subreq)
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina{
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina struct cache_req_search_state *state;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina struct tevent_req *req;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina errno_t ret;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina req = tevent_req_callback_data(subreq, struct tevent_req);
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina state = tevent_req_data(req, struct cache_req_search_state);
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
4df7aec645f87342f3a5146062abcb15f71f4fd9Pavel Březina state->dp_success = state->cr->plugin->dp_recv_fn(subreq, state->cr);
4df7aec645f87342f3a5146062abcb15f71f4fd9Pavel Březina talloc_zfree(subreq);
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina /* Get result from cache again. */
c8193b1602cf44740b59f5dfcdc5330508c0c365Fabiano Fidêncio ret = cache_req_search_cache(state, state->cr, &state->result);
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio if (ret != EOK) {
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio if (ret == ENOENT) {
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio /* Only store entry in negative cache if DP request succeeded
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio * because only then we know that the entry does not exist. */
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio if (state->dp_success) {
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio cache_req_search_ncache_add(state->cr);
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio }
2d12aae08aff6c17c1edb107a204c54d9acfe08dPavel Březina }
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio goto done;
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio }
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio /* ret == EOK */
c8193b1602cf44740b59f5dfcdc5330508c0c365Fabiano Fidêncio ret = cache_req_search_ncache_filter(state, state->cr, &state->result);
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio if (ret != EOK) {
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio goto done;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina }
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, state->cr,
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina "Returning updated object [%s]\n", state->cr->debugobj);
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidênciodone:
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio if (ret != EOK) {
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio tevent_req_error(req, ret);
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio return;
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio }
4ef0b19a5e8a327443d027e57487c8a1e4f654ceFabiano Fidêncio
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina tevent_req_done(req);
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina return;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina}
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březinaerrno_t cache_req_search_recv(TALLOC_CTX *mem_ctx,
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina struct tevent_req *req,
2d12aae08aff6c17c1edb107a204c54d9acfe08dPavel Březina struct ldb_result **_result,
2d12aae08aff6c17c1edb107a204c54d9acfe08dPavel Březina bool *_dp_success)
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina{
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina struct cache_req_search_state *state = NULL;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina state = tevent_req_data(req, struct cache_req_search_state);
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
2d12aae08aff6c17c1edb107a204c54d9acfe08dPavel Březina *_dp_success = state->dp_success;
2d12aae08aff6c17c1edb107a204c54d9acfe08dPavel Březina
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina TEVENT_REQ_RETURN_ON_ERROR(req);
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina *_result = talloc_steal(mem_ctx, state->result);
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina return EOK;
2749964664a69bbb99d09409c1110095cbfcc664Pavel Březina}
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozekstruct cache_req_locate_domain_state {
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek struct cache_req *cr;
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek char *found_domain;
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek};
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozekstatic void cache_req_locate_domain_done(struct tevent_req *subreq);
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozekstruct tevent_req *cache_req_locate_domain_send(TALLOC_CTX *mem_ctx,
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek struct tevent_context *ev,
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek struct cache_req *cr)
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek{
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek struct cache_req_locate_domain_state *state;
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek struct tevent_req *req;
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek struct tevent_req *subreq;
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek errno_t ret;
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek bool should_run;
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek req = tevent_req_create(mem_ctx, &state, struct cache_req_locate_domain_state);
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek if (req == NULL) {
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek return NULL;
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek }
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek state->cr = cr;
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek should_run = cr->plugin->dp_get_domain_check_fn(cr->rctx,
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek get_domains_head(cr->domain),
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek cr->data);
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek if (should_run == false) {
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek /* The request was tried too recently, don't issue a new one
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek * as its results are still valid
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek */
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek ret = ERR_GET_ACCT_DOM_CACHED;
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek goto immediate;
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek }
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek subreq = cr->plugin->dp_get_domain_send_fn(state,
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek cr->rctx,
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek get_domains_head(cr->domain),
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek cr->data);
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek if (subreq == NULL) {
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek ret = ENOMEM;
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek goto immediate;
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek }
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek tevent_req_set_callback(subreq, cache_req_locate_domain_done, req);
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek return req;
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozekimmediate:
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek if (ret == EOK) {
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek tevent_req_done(req);
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek } else {
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek tevent_req_error(req, ret);
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek }
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek tevent_req_post(req, ev);
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek return req;
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek}
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozekstatic void cache_req_locate_domain_done(struct tevent_req *subreq)
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek{
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek struct tevent_req *req;
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek struct cache_req_locate_domain_state *state;
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek errno_t ret;
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek req = tevent_req_callback_data(subreq, struct tevent_req);
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek state = tevent_req_data(req, struct cache_req_locate_domain_state);
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek ret = state->cr->plugin->dp_get_domain_recv_fn(state,
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek subreq,
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek state->cr,
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek &state->found_domain);
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek talloc_zfree(subreq);
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek if (ret != EOK) {
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek tevent_req_error(req, ret);
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek return;
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek }
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek tevent_req_done(req);
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek}
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozekerrno_t cache_req_locate_domain_recv(TALLOC_CTX *mem_ctx,
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek struct tevent_req *req,
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek char **_found_domain)
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek{
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek struct cache_req_locate_domain_state *state = NULL;
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek state = tevent_req_data(req, struct cache_req_locate_domain_state);
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek TEVENT_REQ_RETURN_ON_ERROR(req);
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek *_found_domain = talloc_steal(mem_ctx, state->found_domain);
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek return EOK;
0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054Jakub Hrozek}