Blame SOURCES/0079-AD-Do-not-mark-the-whole-back-end-as-offline-if-subd.patch

6cf099
From 1055c11f7cafae490221e9203f33ddfa94f47c48 Mon Sep 17 00:00:00 2001
6cf099
From: Jakub Hrozek <jhrozek@redhat.com>
6cf099
Date: Wed, 2 Sep 2015 15:52:51 +0200
6cf099
Subject: [PATCH 79/87] AD: Do not mark the whole back end as offline if
6cf099
 subdomain lookup fails
6cf099
MIME-Version: 1.0
6cf099
Content-Type: text/plain; charset=UTF-8
6cf099
Content-Transfer-Encoding: 8bit
6cf099
6cf099
Required for:
6cf099
https://fedorahosted.org/sssd/ticket/2637
6cf099
6cf099
Rather mark the domain as inactive. It will be marked as active later,
6cf099
in the meantime the main domain can continue to work online and
6cf099
subdomain requests will be answered from cache.
6cf099
6cf099
The lookup request itself just returns a special error code and lets the
6cf099
caller handle the error code as appropriate (normally by disabling the
6cf099
subdomain temporarily).
6cf099
6cf099
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
6cf099
(cherry picked from commit 64d4b1e5fd4a3c99ef8d8fef6ad0db52c5152c1c)
6cf099
---
6cf099
 src/providers/ad/ad_id.c | 81 +++++++++++++++++++++++++++++++++++++++---------
6cf099
 1 file changed, 67 insertions(+), 14 deletions(-)
6cf099
6cf099
diff --git a/src/providers/ad/ad_id.c b/src/providers/ad/ad_id.c
6cf099
index 4f327f823173eb113153a556322dae4cc4b42f3e..ecaf6c993bf7ddb7ba565d40ef0ad250114f5536 100644
6cf099
--- a/src/providers/ad/ad_id.c
6cf099
+++ b/src/providers/ad/ad_id.c
6cf099
@@ -91,17 +91,27 @@ ad_handle_acct_info_send(TALLOC_CTX *mem_ctx,
6cf099
     state->ad_options = ad_options;
6cf099
     state->cindex = 0;
6cf099
 
6cf099
+    if (sss_domain_get_state(sdom->dom) == DOM_INACTIVE) {
6cf099
+        ret = ERR_SUBDOM_INACTIVE;
6cf099
+        goto immediate;
6cf099
+    }
6cf099
+
6cf099
     ret = ad_handle_acct_info_step(req);
6cf099
-    if (ret == EOK) {
6cf099
-        tevent_req_done(req);
6cf099
-        tevent_req_post(req, be_ctx->ev);
6cf099
-    } else if (ret != EAGAIN) {
6cf099
-        tevent_req_error(req, ret);
6cf099
-        tevent_req_post(req, be_ctx->ev);
6cf099
+    if (ret != EAGAIN) {
6cf099
+        goto immediate;
6cf099
     }
6cf099
 
6cf099
     /* Lookup in progress */
6cf099
     return req;
6cf099
+
6cf099
+immediate:
6cf099
+    if (ret != EOK) {
6cf099
+        tevent_req_error(req, ret);
6cf099
+    } else {
6cf099
+        tevent_req_done(req);
6cf099
+    }
6cf099
+    tevent_req_post(req, be_ctx->ev);
6cf099
+    return req;
6cf099
 }
6cf099
 
6cf099
 static errno_t
6cf099
@@ -160,8 +170,7 @@ ad_handle_acct_info_done(struct tevent_req *subreq)
6cf099
         state->dp_error = dp_error;
6cf099
         state->err = err;
6cf099
 
6cf099
-        tevent_req_error(req, ret);
6cf099
-        return;
6cf099
+        goto fail;
6cf099
     }
6cf099
 
6cf099
     if (sdap_err == EOK) {
6cf099
@@ -170,8 +179,8 @@ ad_handle_acct_info_done(struct tevent_req *subreq)
6cf099
     } else if (sdap_err == ERR_NO_POSIX) {
6cf099
         disable_gc(state->ad_options);
6cf099
     } else if (sdap_err != ENOENT) {
6cf099
-        tevent_req_error(req, EIO);
6cf099
-        return;
6cf099
+        ret = EIO;
6cf099
+        goto fail;
6cf099
     }
6cf099
 
6cf099
     /* Ret is only ENOENT or ERR_NO_POSIX now. Try the next connection */
6cf099
@@ -188,12 +197,27 @@ ad_handle_acct_info_done(struct tevent_req *subreq)
6cf099
             /* No more connections */
6cf099
             tevent_req_done(req);
6cf099
         } else {
6cf099
-            tevent_req_error(req, ret);
6cf099
+            goto fail;
6cf099
         }
6cf099
         return;
6cf099
     }
6cf099
 
6cf099
     /* Another lookup in progress */
6cf099
+    return;
6cf099
+
6cf099
+fail:
6cf099
+    if (IS_SUBDOMAIN(state->sdom->dom)) {
6cf099
+        /* Deactivate subdomain on lookup errors instead of going
6cf099
+         * offline completely.
6cf099
+         * This is a stopgap, until our failover is per-domain,
6cf099
+         * not per-backend. Unfortunately, we can't rewrite the error
6cf099
+         * code on some reported codes only, because sdap_id_op code
6cf099
+         * encapsulated the failover as well..
6cf099
+         */
6cf099
+        ret = ERR_SUBDOM_INACTIVE;
6cf099
+    }
6cf099
+    tevent_req_error(req, ret);
6cf099
+    return;
6cf099
 }
6cf099
 
6cf099
 errno_t
6cf099
@@ -258,6 +282,16 @@ get_conn_list(struct be_req *breq, struct ad_id_ctx *ad_ctx,
6cf099
         break;
6cf099
     }
6cf099
 
6cf099
+    /* Regardless of connection types, a subdomain error must not be allowed
6cf099
+     * to set the whole back end offline, rather report an error and let the
6cf099
+     * caller deal with it (normally disable the subdomain
6cf099
+     */
6cf099
+    if (IS_SUBDOMAIN(dom)) {
6cf099
+        for (cindex = 0; clist[cindex] != NULL; cindex++) {
6cf099
+            clist[cindex]->ignore_mark_offline = true;
6cf099
+        }
6cf099
+    }
6cf099
+
6cf099
     return clist;
6cf099
 }
6cf099
 
6cf099
@@ -328,6 +362,11 @@ done:
6cf099
 
6cf099
 static void ad_account_info_complete(struct tevent_req *req);
6cf099
 
6cf099
+struct ad_account_info_state {
6cf099
+    struct be_req *be_req;
6cf099
+    struct sss_domain_info *dom;
6cf099
+};
6cf099
+
6cf099
 void
6cf099
 ad_account_info_handler(struct be_req *be_req)
6cf099
 {
6cf099
@@ -341,6 +380,7 @@ ad_account_info_handler(struct be_req *be_req)
6cf099
     struct sdap_id_conn_ctx **clist;
6cf099
     bool shortcut;
6cf099
     errno_t ret;
6cf099
+    struct ad_account_info_state *state;
6cf099
 
6cf099
     ad_ctx = talloc_get_type(be_ctx->bet_info[BET_ID].pvt_bet_data,
6cf099
                              struct ad_id_ctx);
6cf099
@@ -391,13 +431,21 @@ ad_account_info_handler(struct be_req *be_req)
6cf099
         goto fail;
6cf099
     }
6cf099
 
6cf099
+    state = talloc(be_req, struct ad_account_info_state);
6cf099
+    if (state == NULL) {
6cf099
+        ret = ENOMEM;
6cf099
+        goto fail;
6cf099
+    }
6cf099
+    state->dom = sdom->dom;
6cf099
+    state->be_req = be_req;
6cf099
+
6cf099
     req = ad_handle_acct_info_send(be_req, be_req, ar, sdap_id_ctx,
6cf099
                                    ad_ctx->ad_options, sdom, clist);
6cf099
     if (req == NULL) {
6cf099
         ret = ENOMEM;
6cf099
         goto fail;
6cf099
     }
6cf099
-    tevent_req_set_callback(req, ad_account_info_complete, be_req);
6cf099
+    tevent_req_set_callback(req, ad_account_info_complete, state);
6cf099
     return;
6cf099
 
6cf099
 fail:
6cf099
@@ -412,12 +460,17 @@ ad_account_info_complete(struct tevent_req *req)
6cf099
     int dp_error;
6cf099
     const char *error_text = "Internal error";
6cf099
     const char *req_error_text;
6cf099
+    struct ad_account_info_state *state;
6cf099
 
6cf099
-    be_req = tevent_req_callback_data(req, struct be_req);
6cf099
+    state = tevent_req_callback_data(req, struct ad_account_info_state);
6cf099
+    be_req = state->be_req;
6cf099
 
6cf099
     ret = ad_handle_acct_info_recv(req, &dp_error, &req_error_text);
6cf099
     talloc_zfree(req);
6cf099
-    if (dp_error == DP_ERR_OK) {
6cf099
+    if (ret == ERR_SUBDOM_INACTIVE) {
6cf099
+        be_mark_dom_offline(state->dom, be_req_get_be_ctx(be_req));
6cf099
+        return be_req_terminate(be_req, DP_ERR_OFFLINE, EAGAIN, "Offline");
6cf099
+    } else if (dp_error == DP_ERR_OK) {
6cf099
         if (ret == EOK) {
6cf099
             error_text = NULL;
6cf099
         } else {
6cf099
-- 
6cf099
2.4.3
6cf099