Blame SOURCES/0080-CACHE_REQ-Add-a-private-request-cache_req_locate_dom.patch

ced1f5
From d30dd0f52d452562e47f9a30b1630eff2f817792 Mon Sep 17 00:00:00 2001
ced1f5
From: Jakub Hrozek <jhrozek@redhat.com>
ced1f5
Date: Mon, 30 Oct 2017 20:21:05 +0100
ced1f5
Subject: [PATCH 80/83] CACHE_REQ: Add a private request
ced1f5
 cache_req_locate_domain()
ced1f5
MIME-Version: 1.0
ced1f5
Content-Type: text/plain; charset=UTF-8
ced1f5
Content-Transfer-Encoding: 8bit
ced1f5
ced1f5
Adds a new request cache_req_locate_domain_send/recv. This request, if the
ced1f5
plugin that is being processed supports the locator, will call the plugin's
ced1f5
dp_get_domain_send_fn(). On any error, the request returns just the error
ced1f5
code. On success, the request returns the domain the object was found at.
ced1f5
ced1f5
If the getAccountDomain() method returns that the back end does not support
ced1f5
the locator method, all further getAccountDomain() calls are disabled for
ced1f5
that domain.
ced1f5
ced1f5
Related:
ced1f5
https://pagure.io/SSSD/sssd/issue/3468
ced1f5
ced1f5
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
ced1f5
Reviewed-by: Sumit Bose <sbose@redhat.com>
ced1f5
(cherry picked from commit 0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054)
ced1f5
---
ced1f5
 src/responder/common/cache_req/cache_req_private.h |  7 ++
ced1f5
 src/responder/common/cache_req/cache_req_search.c  | 93 ++++++++++++++++++++++
ced1f5
 src/util/util_errors.c                             |  1 +
ced1f5
 src/util/util_errors.h                             |  1 +
ced1f5
 4 files changed, 102 insertions(+)
ced1f5
ced1f5
diff --git a/src/responder/common/cache_req/cache_req_private.h b/src/responder/common/cache_req/cache_req_private.h
ced1f5
index a156fc65fed80693cdd0473613aeaaa3f5bb2269..9586e3788045ff44eb2a4b626dc7fcaf11ec8028 100644
ced1f5
--- a/src/responder/common/cache_req/cache_req_private.h
ced1f5
+++ b/src/responder/common/cache_req/cache_req_private.h
ced1f5
@@ -106,6 +106,13 @@ errno_t cache_req_search_recv(TALLOC_CTX *mem_ctx,
ced1f5
                               struct ldb_result **_result,
ced1f5
                               bool *_dp_success);
ced1f5
 
ced1f5
+struct tevent_req *cache_req_locate_domain_send(TALLOC_CTX *mem_ctx,
ced1f5
+                                                struct tevent_context *ev,
ced1f5
+                                                struct cache_req *cr);
ced1f5
+errno_t cache_req_locate_domain_recv(TALLOC_CTX *mem_ctx,
ced1f5
+                                     struct tevent_req *req,
ced1f5
+                                     char **_found_domain);
ced1f5
+
ced1f5
 struct tevent_req *
ced1f5
 cache_req_steal_data_and_send(TALLOC_CTX *mem_ctx,
ced1f5
                               struct tevent_context *ev,
ced1f5
diff --git a/src/responder/common/cache_req/cache_req_search.c b/src/responder/common/cache_req/cache_req_search.c
ced1f5
index 9d5ad8056cda0284b1cc32cd51d7cb0ec12ad667..3365962d473b0982945de2541e44ba86b43a0db5 100644
ced1f5
--- a/src/responder/common/cache_req/cache_req_search.c
ced1f5
+++ b/src/responder/common/cache_req/cache_req_search.c
ced1f5
@@ -485,3 +485,96 @@ errno_t cache_req_search_recv(TALLOC_CTX *mem_ctx,
ced1f5
 
ced1f5
     return EOK;
ced1f5
 }
ced1f5
+
ced1f5
+struct cache_req_locate_domain_state {
ced1f5
+    struct cache_req *cr;
ced1f5
+
ced1f5
+    char *found_domain;
ced1f5
+};
ced1f5
+
ced1f5
+static void cache_req_locate_domain_done(struct tevent_req *subreq);
ced1f5
+
ced1f5
+struct tevent_req *cache_req_locate_domain_send(TALLOC_CTX *mem_ctx,
ced1f5
+                                                struct tevent_context *ev,
ced1f5
+                                                struct cache_req *cr)
ced1f5
+{
ced1f5
+    struct cache_req_locate_domain_state *state;
ced1f5
+    struct tevent_req *req;
ced1f5
+    struct tevent_req *subreq;
ced1f5
+    errno_t ret;
ced1f5
+    bool should_run;
ced1f5
+
ced1f5
+    req = tevent_req_create(mem_ctx, &state, struct cache_req_locate_domain_state);
ced1f5
+    if (req == NULL) {
ced1f5
+        DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
ced1f5
+        return NULL;
ced1f5
+    }
ced1f5
+    state->cr = cr;
ced1f5
+
ced1f5
+    should_run = cr->plugin->dp_get_domain_check_fn(cr->rctx,
ced1f5
+                                                    get_domains_head(cr->domain),
ced1f5
+                                                    cr->data);
ced1f5
+    if (should_run == false) {
ced1f5
+        /* The request was tried too recently, don't issue a new one
ced1f5
+         * as its results are still valid
ced1f5
+         */
ced1f5
+        ret = ERR_GET_ACCT_DOM_CACHED;
ced1f5
+        goto immediate;
ced1f5
+    }
ced1f5
+
ced1f5
+    subreq = cr->plugin->dp_get_domain_send_fn(state,
ced1f5
+                                               cr->rctx,
ced1f5
+                                               get_domains_head(cr->domain),
ced1f5
+                                               cr->data);
ced1f5
+    if (subreq == NULL) {
ced1f5
+        ret = ENOMEM;
ced1f5
+        goto immediate;
ced1f5
+    }
ced1f5
+    tevent_req_set_callback(subreq, cache_req_locate_domain_done, req);
ced1f5
+    return req;
ced1f5
+
ced1f5
+immediate:
ced1f5
+    if (ret == EOK) {
ced1f5
+        tevent_req_done(req);
ced1f5
+    } else {
ced1f5
+        tevent_req_error(req, ret);
ced1f5
+    }
ced1f5
+    tevent_req_post(req, ev);
ced1f5
+    return req;
ced1f5
+}
ced1f5
+
ced1f5
+static void cache_req_locate_domain_done(struct tevent_req *subreq)
ced1f5
+{
ced1f5
+    struct tevent_req *req;
ced1f5
+    struct cache_req_locate_domain_state *state;
ced1f5
+    errno_t ret;
ced1f5
+
ced1f5
+    req = tevent_req_callback_data(subreq, struct tevent_req);
ced1f5
+    state = tevent_req_data(req, struct cache_req_locate_domain_state);
ced1f5
+
ced1f5
+    ret = state->cr->plugin->dp_get_domain_recv_fn(state,
ced1f5
+                                                   subreq,
ced1f5
+                                                   state->cr,
ced1f5
+                                                   &state->found_domain);
ced1f5
+    talloc_zfree(subreq);
ced1f5
+    if (ret != EOK) {
ced1f5
+        tevent_req_error(req, ret);
ced1f5
+        return;
ced1f5
+    }
ced1f5
+
ced1f5
+    tevent_req_done(req);
ced1f5
+}
ced1f5
+
ced1f5
+errno_t cache_req_locate_domain_recv(TALLOC_CTX *mem_ctx,
ced1f5
+                                     struct tevent_req *req,
ced1f5
+                                     char **_found_domain)
ced1f5
+{
ced1f5
+    struct cache_req_locate_domain_state *state = NULL;
ced1f5
+
ced1f5
+    state = tevent_req_data(req, struct cache_req_locate_domain_state);
ced1f5
+
ced1f5
+    TEVENT_REQ_RETURN_ON_ERROR(req);
ced1f5
+
ced1f5
+    *_found_domain = talloc_steal(mem_ctx, state->found_domain);
ced1f5
+    return EOK;
ced1f5
+}
ced1f5
diff --git a/src/util/util_errors.c b/src/util/util_errors.c
ced1f5
index 9a9ba3f3063cab4afb538c3a58527a2d2ed3fffd..06c620b40aaa00d6ce58ace3a28449ffbdf8da88 100644
ced1f5
--- a/src/util/util_errors.c
ced1f5
+++ b/src/util/util_errors.c
ced1f5
@@ -116,6 +116,7 @@ struct err_string error_to_str[] = {
ced1f5
     { "Unable to verify peer" }, /* ERR_UNABLE_TO_VERIFY_PEER */
ced1f5
     { "Unable to resolve host" }, /* ERR_UNABLE_TO_RESOLVE_HOST */
ced1f5
     { "GetAccountDomain() not supported" }, /* ERR_GET_ACCT_DOM_NOT_SUPPORTED */
ced1f5
+    { "The last GetAccountDomain() result is still valid" }, /* ERR_GET_ACCT_DOM_CACHED */
ced1f5
     { "ERR_LAST" } /* ERR_LAST */
ced1f5
 };
ced1f5
 
ced1f5
diff --git a/src/util/util_errors.h b/src/util/util_errors.h
ced1f5
index 5ee9862c3f2f60c078693b1b85a40f15436e818c..bebd6e198fc0077891a602f80182a993ce3f789b 100644
ced1f5
--- a/src/util/util_errors.h
ced1f5
+++ b/src/util/util_errors.h
ced1f5
@@ -138,6 +138,7 @@ enum sssd_errors {
ced1f5
     ERR_UNABLE_TO_VERIFY_PEER,
ced1f5
     ERR_UNABLE_TO_RESOLVE_HOST,
ced1f5
     ERR_GET_ACCT_DOM_NOT_SUPPORTED,
ced1f5
+    ERR_GET_ACCT_DOM_CACHED,
ced1f5
     ERR_LAST            /* ALWAYS LAST */
ced1f5
 };
ced1f5
 
ced1f5
-- 
ced1f5
2.14.3
ced1f5