Blob Blame History Raw
From a4dd1eb5087c2f8a3a9133f42efa025221edc1c9 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Wed, 30 Oct 2019 14:23:12 +0100
Subject: [PATCH] ipa: add failover to access checks
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

While reading the different components of the HBAC rules failover
handling was missing. Since the access control is typically the second
step after authentication SSSD would have already switched to a working
server or into offline mode during authentication. But if e.g. ssh keys
are used for authentication and user data are read from cache the HABC
rule searches might have to handle failover as well.

Related to https://pagure.io/SSSD/sssd/issue/4114

Reviewed-by: Michal Židek <mzidek@redhat.com>
(cherry picked from commit 707fdf0406644de08cfb7f59fa4eec393be5c62a)
---
 src/providers/ipa/ipa_access.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/src/providers/ipa/ipa_access.c b/src/providers/ipa/ipa_access.c
index de9f68170..375b6f885 100644
--- a/src/providers/ipa/ipa_access.c
+++ b/src/providers/ipa/ipa_access.c
@@ -296,6 +296,7 @@ static void ipa_fetch_hbac_hostinfo_done(struct tevent_req *subreq)
     struct ipa_fetch_hbac_state *state = NULL;
     struct tevent_req *req = NULL;
     errno_t ret;
+    int dp_error;
 
     req = tevent_req_callback_data(subreq, struct tevent_req);
     state = tevent_req_data(req, struct ipa_fetch_hbac_state);
@@ -308,7 +309,22 @@ static void ipa_fetch_hbac_hostinfo_done(struct tevent_req *subreq)
     state->hosts->entry_subdir = HBAC_HOSTS_SUBDIR;
     state->hosts->group_subdir = HBAC_HOSTGROUPS_SUBDIR;
     talloc_zfree(subreq);
+
     if (ret != EOK) {
+        /* Only call sdap_id_op_done in case of an error to trigger a
+         * failover. In general changing the tevent_req layout would be better
+         * so that all searches are in another sub-request so that we can
+         * error out at any step and the parent request can call
+         * sdap_id_op_done just once. */
+        ret = sdap_id_op_done(state->sdap_op, ret, &dp_error);
+        if (dp_error == DP_ERR_OK && ret != EOK) {
+            /* retry */
+            ret = ipa_fetch_hbac_retry(req);
+            if (ret != EAGAIN) {
+                goto done;
+            }
+            return;
+        }
         goto done;
     }
 
-- 
2.21.1