Blob Blame History Raw
From d30dd0f52d452562e47f9a30b1630eff2f817792 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek@redhat.com>
Date: Mon, 30 Oct 2017 20:21:05 +0100
Subject: [PATCH 80/83] CACHE_REQ: Add a private request
 cache_req_locate_domain()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Adds a new request cache_req_locate_domain_send/recv. This request, if the
plugin that is being processed supports the locator, will call the plugin's
dp_get_domain_send_fn(). On any error, the request returns just the error
code. On success, the request returns the domain the object was found at.

If the getAccountDomain() method returns that the back end does not support
the locator method, all further getAccountDomain() calls are disabled for
that domain.

Related:
https://pagure.io/SSSD/sssd/issue/3468

Reviewed-by: Pavel Březina <pbrezina@redhat.com>
Reviewed-by: Sumit Bose <sbose@redhat.com>
(cherry picked from commit 0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054)
---
 src/responder/common/cache_req/cache_req_private.h |  7 ++
 src/responder/common/cache_req/cache_req_search.c  | 93 ++++++++++++++++++++++
 src/util/util_errors.c                             |  1 +
 src/util/util_errors.h                             |  1 +
 4 files changed, 102 insertions(+)

diff --git a/src/responder/common/cache_req/cache_req_private.h b/src/responder/common/cache_req/cache_req_private.h
index a156fc65fed80693cdd0473613aeaaa3f5bb2269..9586e3788045ff44eb2a4b626dc7fcaf11ec8028 100644
--- a/src/responder/common/cache_req/cache_req_private.h
+++ b/src/responder/common/cache_req/cache_req_private.h
@@ -106,6 +106,13 @@ errno_t cache_req_search_recv(TALLOC_CTX *mem_ctx,
                               struct ldb_result **_result,
                               bool *_dp_success);
 
+struct tevent_req *cache_req_locate_domain_send(TALLOC_CTX *mem_ctx,
+                                                struct tevent_context *ev,
+                                                struct cache_req *cr);
+errno_t cache_req_locate_domain_recv(TALLOC_CTX *mem_ctx,
+                                     struct tevent_req *req,
+                                     char **_found_domain);
+
 struct tevent_req *
 cache_req_steal_data_and_send(TALLOC_CTX *mem_ctx,
                               struct tevent_context *ev,
diff --git a/src/responder/common/cache_req/cache_req_search.c b/src/responder/common/cache_req/cache_req_search.c
index 9d5ad8056cda0284b1cc32cd51d7cb0ec12ad667..3365962d473b0982945de2541e44ba86b43a0db5 100644
--- a/src/responder/common/cache_req/cache_req_search.c
+++ b/src/responder/common/cache_req/cache_req_search.c
@@ -485,3 +485,96 @@ errno_t cache_req_search_recv(TALLOC_CTX *mem_ctx,
 
     return EOK;
 }
+
+struct cache_req_locate_domain_state {
+    struct cache_req *cr;
+
+    char *found_domain;
+};
+
+static void cache_req_locate_domain_done(struct tevent_req *subreq);
+
+struct tevent_req *cache_req_locate_domain_send(TALLOC_CTX *mem_ctx,
+                                                struct tevent_context *ev,
+                                                struct cache_req *cr)
+{
+    struct cache_req_locate_domain_state *state;
+    struct tevent_req *req;
+    struct tevent_req *subreq;
+    errno_t ret;
+    bool should_run;
+
+    req = tevent_req_create(mem_ctx, &state, struct cache_req_locate_domain_state);
+    if (req == NULL) {
+        DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
+        return NULL;
+    }
+    state->cr = cr;
+
+    should_run = cr->plugin->dp_get_domain_check_fn(cr->rctx,
+                                                    get_domains_head(cr->domain),
+                                                    cr->data);
+    if (should_run == false) {
+        /* The request was tried too recently, don't issue a new one
+         * as its results are still valid
+         */
+        ret = ERR_GET_ACCT_DOM_CACHED;
+        goto immediate;
+    }
+
+    subreq = cr->plugin->dp_get_domain_send_fn(state,
+                                               cr->rctx,
+                                               get_domains_head(cr->domain),
+                                               cr->data);
+    if (subreq == NULL) {
+        ret = ENOMEM;
+        goto immediate;
+    }
+    tevent_req_set_callback(subreq, cache_req_locate_domain_done, req);
+    return req;
+
+immediate:
+    if (ret == EOK) {
+        tevent_req_done(req);
+    } else {
+        tevent_req_error(req, ret);
+    }
+    tevent_req_post(req, ev);
+    return req;
+}
+
+static void cache_req_locate_domain_done(struct tevent_req *subreq)
+{
+    struct tevent_req *req;
+    struct cache_req_locate_domain_state *state;
+    errno_t ret;
+
+    req = tevent_req_callback_data(subreq, struct tevent_req);
+    state = tevent_req_data(req, struct cache_req_locate_domain_state);
+
+    ret = state->cr->plugin->dp_get_domain_recv_fn(state,
+                                                   subreq,
+                                                   state->cr,
+                                                   &state->found_domain);
+    talloc_zfree(subreq);
+    if (ret != EOK) {
+        tevent_req_error(req, ret);
+        return;
+    }
+
+    tevent_req_done(req);
+}
+
+errno_t cache_req_locate_domain_recv(TALLOC_CTX *mem_ctx,
+                                     struct tevent_req *req,
+                                     char **_found_domain)
+{
+    struct cache_req_locate_domain_state *state = NULL;
+
+    state = tevent_req_data(req, struct cache_req_locate_domain_state);
+
+    TEVENT_REQ_RETURN_ON_ERROR(req);
+
+    *_found_domain = talloc_steal(mem_ctx, state->found_domain);
+    return EOK;
+}
diff --git a/src/util/util_errors.c b/src/util/util_errors.c
index 9a9ba3f3063cab4afb538c3a58527a2d2ed3fffd..06c620b40aaa00d6ce58ace3a28449ffbdf8da88 100644
--- a/src/util/util_errors.c
+++ b/src/util/util_errors.c
@@ -116,6 +116,7 @@ struct err_string error_to_str[] = {
     { "Unable to verify peer" }, /* ERR_UNABLE_TO_VERIFY_PEER */
     { "Unable to resolve host" }, /* ERR_UNABLE_TO_RESOLVE_HOST */
     { "GetAccountDomain() not supported" }, /* ERR_GET_ACCT_DOM_NOT_SUPPORTED */
+    { "The last GetAccountDomain() result is still valid" }, /* ERR_GET_ACCT_DOM_CACHED */
     { "ERR_LAST" } /* ERR_LAST */
 };
 
diff --git a/src/util/util_errors.h b/src/util/util_errors.h
index 5ee9862c3f2f60c078693b1b85a40f15436e818c..bebd6e198fc0077891a602f80182a993ce3f789b 100644
--- a/src/util/util_errors.h
+++ b/src/util/util_errors.h
@@ -138,6 +138,7 @@ enum sssd_errors {
     ERR_UNABLE_TO_VERIFY_PEER,
     ERR_UNABLE_TO_RESOLVE_HOST,
     ERR_GET_ACCT_DOM_NOT_SUPPORTED,
+    ERR_GET_ACCT_DOM_CACHED,
     ERR_LAST            /* ALWAYS LAST */
 };
 
-- 
2.14.3