|
|
6cf099 |
From 569233a9db93bfd2926bb1ecf73d9b67a634e840 Mon Sep 17 00:00:00 2001
|
|
|
6cf099 |
From: Jakub Hrozek <jhrozek@redhat.com>
|
|
|
6cf099 |
Date: Thu, 17 Sep 2015 17:11:34 +0200
|
|
|
6cf099 |
Subject: [PATCH 96/96] IPA: Retry fetching keytab if IPA user lookup fails
|
|
|
6cf099 |
|
|
|
6cf099 |
Required for:
|
|
|
6cf099 |
https://fedorahosted.org/sssd/ticket/2639
|
|
|
6cf099 |
|
|
|
6cf099 |
Instead of calling ipa_get_ad_acct_send directly, call a new request
|
|
|
6cf099 |
ipa_srv_ad_acct_send. The new request wraps ipa_get_ad_acct_send and
|
|
|
6cf099 |
either tries to request a new keytab every time the lookup fails but the
|
|
|
6cf099 |
domain is online.
|
|
|
6cf099 |
|
|
|
6cf099 |
be_mark_dom_offline() is called when the retry fails with the new code.
|
|
|
6cf099 |
|
|
|
6cf099 |
The retry tries to re-setup the trusted domain. With two-way setups, the
|
|
|
6cf099 |
request is a no-op. With one-way trust setups, the request re-fetches
|
|
|
6cf099 |
new keytab unconditionally.
|
|
|
6cf099 |
|
|
|
6cf099 |
Reviewed-by: Sumit Bose <sbose@redhat.com>
|
|
|
6cf099 |
(cherry picked from commit 0aff5b651a414a1fd58ab3eb2f029399c0278a18)
|
|
|
6cf099 |
---
|
|
|
6cf099 |
src/providers/ipa/ipa_id.h | 9 --
|
|
|
6cf099 |
src/providers/ipa/ipa_subdomains_id.c | 190 +++++++++++++++++++++++++++++++++-
|
|
|
6cf099 |
2 files changed, 185 insertions(+), 14 deletions(-)
|
|
|
6cf099 |
|
|
|
6cf099 |
diff --git a/src/providers/ipa/ipa_id.h b/src/providers/ipa/ipa_id.h
|
|
|
6cf099 |
index c03ca037a2850478a8f4933bac4fcf8bd70ada04..91a94115386955f63eca706bf6f4ac41884445eb 100644
|
|
|
6cf099 |
--- a/src/providers/ipa/ipa_id.h
|
|
|
6cf099 |
+++ b/src/providers/ipa/ipa_id.h
|
|
|
6cf099 |
@@ -70,15 +70,6 @@ struct tevent_req *ipa_get_subdom_acct_send(TALLOC_CTX *memctx,
|
|
|
6cf099 |
struct be_acct_req *ar);
|
|
|
6cf099 |
int ipa_get_subdom_acct_recv(struct tevent_req *req, int *dp_error_out);
|
|
|
6cf099 |
|
|
|
6cf099 |
-struct tevent_req *ipa_get_ad_acct_send(TALLOC_CTX *mem_ctx,
|
|
|
6cf099 |
- struct tevent_context *ev,
|
|
|
6cf099 |
- struct ipa_id_ctx *ipa_ctx,
|
|
|
6cf099 |
- struct be_req *be_req,
|
|
|
6cf099 |
- struct sysdb_attrs *override_attrs,
|
|
|
6cf099 |
- struct be_acct_req *ar);
|
|
|
6cf099 |
-
|
|
|
6cf099 |
-errno_t ipa_get_ad_acct_recv(struct tevent_req *req, int *dp_error_out);
|
|
|
6cf099 |
-
|
|
|
6cf099 |
errno_t get_be_acct_req_for_sid(TALLOC_CTX *mem_ctx, const char *sid,
|
|
|
6cf099 |
const char *domain_name,
|
|
|
6cf099 |
struct be_acct_req **_ar);
|
|
|
6cf099 |
diff --git a/src/providers/ipa/ipa_subdomains_id.c b/src/providers/ipa/ipa_subdomains_id.c
|
|
|
6cf099 |
index ff14b4a4c68cb5c6e9865a66931ee4ecd6e49211..86dd71f3cc09f11de88c4269d49552718c5ba027 100644
|
|
|
6cf099 |
--- a/src/providers/ipa/ipa_subdomains_id.c
|
|
|
6cf099 |
+++ b/src/providers/ipa/ipa_subdomains_id.c
|
|
|
6cf099 |
@@ -34,6 +34,16 @@
|
|
|
6cf099 |
#include "providers/ad/ad_id.h"
|
|
|
6cf099 |
#include "providers/ipa/ipa_subdomains.h"
|
|
|
6cf099 |
|
|
|
6cf099 |
+static struct tevent_req *
|
|
|
6cf099 |
+ipa_srv_ad_acct_send(TALLOC_CTX *mem_ctx,
|
|
|
6cf099 |
+ struct tevent_context *ev,
|
|
|
6cf099 |
+ struct ipa_id_ctx *ipa_ctx,
|
|
|
6cf099 |
+ struct be_req *be_req,
|
|
|
6cf099 |
+ struct sysdb_attrs *override_attrs,
|
|
|
6cf099 |
+ struct be_acct_req *ar);
|
|
|
6cf099 |
+static errno_t
|
|
|
6cf099 |
+ipa_srv_ad_acct_recv(struct tevent_req *req, int *dp_error_out);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
struct ipa_subdomain_account_state {
|
|
|
6cf099 |
struct tevent_context *ev;
|
|
|
6cf099 |
struct ipa_id_ctx *ipa_ctx;
|
|
|
6cf099 |
@@ -45,6 +55,7 @@ struct ipa_subdomain_account_state {
|
|
|
6cf099 |
struct be_acct_req *ar;
|
|
|
6cf099 |
|
|
|
6cf099 |
bool ipa_server_mode;
|
|
|
6cf099 |
+ bool server_retry;
|
|
|
6cf099 |
int entry_type;
|
|
|
6cf099 |
const char *filter;
|
|
|
6cf099 |
int filter_type;
|
|
|
6cf099 |
@@ -263,7 +274,7 @@ static errno_t ipa_subdomain_account_get_original_step(struct tevent_req *req,
|
|
|
6cf099 |
struct tevent_req *subreq;
|
|
|
6cf099 |
|
|
|
6cf099 |
if (state->ipa_server_mode) {
|
|
|
6cf099 |
- subreq = ipa_get_ad_acct_send(state, state->ev, state->ipa_ctx,
|
|
|
6cf099 |
+ subreq = ipa_srv_ad_acct_send(state, state->ev, state->ipa_ctx,
|
|
|
6cf099 |
state->be_req, state->override_attrs, ar);
|
|
|
6cf099 |
} else {
|
|
|
6cf099 |
subreq = ipa_get_subdom_acct_send(state, state->ev, state->ipa_ctx,
|
|
|
6cf099 |
@@ -291,7 +302,7 @@ static void ipa_subdomain_account_done(struct tevent_req *subreq)
|
|
|
6cf099 |
int ret;
|
|
|
6cf099 |
|
|
|
6cf099 |
if (state->ipa_server_mode) {
|
|
|
6cf099 |
- ret = ipa_get_ad_acct_recv(subreq, &dp_error);
|
|
|
6cf099 |
+ ret = ipa_srv_ad_acct_recv(subreq, &dp_error);
|
|
|
6cf099 |
} else {
|
|
|
6cf099 |
ret = ipa_get_subdom_acct_recv(subreq, &dp_error);
|
|
|
6cf099 |
}
|
|
|
6cf099 |
@@ -575,7 +586,7 @@ static void ipa_get_ad_acct_done(struct tevent_req *subreq);
|
|
|
6cf099 |
static struct ad_id_ctx *ipa_get_ad_id_ctx(struct ipa_id_ctx *ipa_ctx,
|
|
|
6cf099 |
struct sss_domain_info *dom);
|
|
|
6cf099 |
|
|
|
6cf099 |
-struct tevent_req *
|
|
|
6cf099 |
+static struct tevent_req *
|
|
|
6cf099 |
ipa_get_ad_acct_send(TALLOC_CTX *mem_ctx,
|
|
|
6cf099 |
struct tevent_context *ev,
|
|
|
6cf099 |
struct ipa_id_ctx *ipa_ctx,
|
|
|
6cf099 |
@@ -1039,7 +1050,6 @@ ipa_get_ad_acct_ad_part_done(struct tevent_req *subreq)
|
|
|
6cf099 |
ret = ad_handle_acct_info_recv(subreq, &state->dp_error, NULL);
|
|
|
6cf099 |
talloc_zfree(subreq);
|
|
|
6cf099 |
if (ret == ERR_SUBDOM_INACTIVE) {
|
|
|
6cf099 |
- be_mark_dom_offline(state->obj_dom, be_req_get_be_ctx(state->be_req));
|
|
|
6cf099 |
tevent_req_error(req, ret);
|
|
|
6cf099 |
return;
|
|
|
6cf099 |
} else if (ret != EOK) {
|
|
|
6cf099 |
@@ -1324,7 +1334,7 @@ ipa_get_ad_acct_done(struct tevent_req *subreq)
|
|
|
6cf099 |
tevent_req_done(req);
|
|
|
6cf099 |
}
|
|
|
6cf099 |
|
|
|
6cf099 |
-errno_t
|
|
|
6cf099 |
+static errno_t
|
|
|
6cf099 |
ipa_get_ad_acct_recv(struct tevent_req *req, int *dp_error_out)
|
|
|
6cf099 |
{
|
|
|
6cf099 |
struct ipa_get_ad_acct_state *state = tevent_req_data(req,
|
|
|
6cf099 |
@@ -1338,3 +1348,173 @@ ipa_get_ad_acct_recv(struct tevent_req *req, int *dp_error_out)
|
|
|
6cf099 |
|
|
|
6cf099 |
return EOK;
|
|
|
6cf099 |
}
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+struct ipa_srv_ad_acct_state {
|
|
|
6cf099 |
+ struct tevent_context *ev;
|
|
|
6cf099 |
+ struct ipa_id_ctx *ipa_ctx;
|
|
|
6cf099 |
+ struct be_req *be_req;
|
|
|
6cf099 |
+ struct sysdb_attrs *override_attrs;
|
|
|
6cf099 |
+ struct be_acct_req *ar;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ struct sss_domain_info *obj_dom;
|
|
|
6cf099 |
+ struct be_ctx *be_ctx;
|
|
|
6cf099 |
+ bool retry;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ int dp_error;
|
|
|
6cf099 |
+};
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+static int ipa_srv_ad_acct_lookup_step(struct tevent_req *req);
|
|
|
6cf099 |
+static void ipa_srv_ad_acct_lookup_done(struct tevent_req *subreq);
|
|
|
6cf099 |
+static void ipa_srv_ad_acct_retried(struct tevent_req *subreq);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+static struct tevent_req *
|
|
|
6cf099 |
+ipa_srv_ad_acct_send(TALLOC_CTX *mem_ctx,
|
|
|
6cf099 |
+ struct tevent_context *ev,
|
|
|
6cf099 |
+ struct ipa_id_ctx *ipa_ctx,
|
|
|
6cf099 |
+ struct be_req *be_req,
|
|
|
6cf099 |
+ struct sysdb_attrs *override_attrs,
|
|
|
6cf099 |
+ struct be_acct_req *ar)
|
|
|
6cf099 |
+{
|
|
|
6cf099 |
+ errno_t ret;
|
|
|
6cf099 |
+ struct tevent_req *req;
|
|
|
6cf099 |
+ struct ipa_srv_ad_acct_state *state;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ req = tevent_req_create(mem_ctx, &state, struct ipa_srv_ad_acct_state);
|
|
|
6cf099 |
+ if (req == NULL) {
|
|
|
6cf099 |
+ return NULL;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ state->ev = ev;
|
|
|
6cf099 |
+ state->ipa_ctx = ipa_ctx;
|
|
|
6cf099 |
+ state->be_req = be_req;
|
|
|
6cf099 |
+ state->override_attrs = override_attrs;
|
|
|
6cf099 |
+ state->ar = ar;
|
|
|
6cf099 |
+ state->retry = true;
|
|
|
6cf099 |
+ state->dp_error = DP_ERR_FATAL;
|
|
|
6cf099 |
+ state->be_ctx = be_req_get_be_ctx(state->be_req);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ state->obj_dom = find_domain_by_name(
|
|
|
6cf099 |
+ state->ipa_ctx->sdap_id_ctx->be->domain,
|
|
|
6cf099 |
+ state->ar->domain, true);
|
|
|
6cf099 |
+ if (state->obj_dom == NULL) {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_OP_FAILURE, "Domain not found\n");
|
|
|
6cf099 |
+ ret = ERR_DOMAIN_NOT_FOUND;
|
|
|
6cf099 |
+ goto fail;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ ret = ipa_srv_ad_acct_lookup_step(req);
|
|
|
6cf099 |
+ if (ret != EOK) {
|
|
|
6cf099 |
+ goto fail;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ return req;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+fail:
|
|
|
6cf099 |
+ tevent_req_error(req, ret);
|
|
|
6cf099 |
+ tevent_req_post(req, ev);
|
|
|
6cf099 |
+ return req;
|
|
|
6cf099 |
+}
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+static int ipa_srv_ad_acct_lookup_step(struct tevent_req *req)
|
|
|
6cf099 |
+{
|
|
|
6cf099 |
+ struct tevent_req *subreq;
|
|
|
6cf099 |
+ struct ipa_srv_ad_acct_state *state = tevent_req_data(req,
|
|
|
6cf099 |
+ struct ipa_srv_ad_acct_state);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ DEBUG(SSSDBG_TRACE_FUNC, "Looking up AD account\n");
|
|
|
6cf099 |
+ subreq = ipa_get_ad_acct_send(state, state->ev, state->ipa_ctx,
|
|
|
6cf099 |
+ state->be_req, state->override_attrs,
|
|
|
6cf099 |
+ state->ar);
|
|
|
6cf099 |
+ if (subreq == NULL) {
|
|
|
6cf099 |
+ return ENOMEM;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+ tevent_req_set_callback(subreq, ipa_srv_ad_acct_lookup_done, req);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ return EOK;
|
|
|
6cf099 |
+}
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+static void ipa_srv_ad_acct_lookup_done(struct tevent_req *subreq)
|
|
|
6cf099 |
+{
|
|
|
6cf099 |
+ errno_t ret;
|
|
|
6cf099 |
+ int dp_error = DP_ERR_FATAL;
|
|
|
6cf099 |
+ struct tevent_req *req = tevent_req_callback_data(subreq,
|
|
|
6cf099 |
+ struct tevent_req);
|
|
|
6cf099 |
+ struct ipa_srv_ad_acct_state *state = tevent_req_data(req,
|
|
|
6cf099 |
+ struct ipa_srv_ad_acct_state);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ ret = ipa_get_ad_acct_recv(subreq, &dp_error);
|
|
|
6cf099 |
+ talloc_free(subreq);
|
|
|
6cf099 |
+ if (ret == ERR_SUBDOM_INACTIVE && state->retry == true) {
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ state->retry = false;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ DEBUG(SSSDBG_MINOR_FAILURE,
|
|
|
6cf099 |
+ "Sudomain lookup failed, will try to reset sudomain..\n");
|
|
|
6cf099 |
+ subreq = ipa_server_trusted_dom_setup_send(state, state->ev,
|
|
|
6cf099 |
+ state->be_ctx,
|
|
|
6cf099 |
+ state->ipa_ctx,
|
|
|
6cf099 |
+ state->obj_dom);
|
|
|
6cf099 |
+ if (subreq == NULL) {
|
|
|
6cf099 |
+ goto fail;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+ tevent_req_set_callback(subreq, ipa_srv_ad_acct_retried, req);
|
|
|
6cf099 |
+ return;
|
|
|
6cf099 |
+ } else if (ret != EOK) {
|
|
|
6cf099 |
+ be_mark_dom_offline(state->obj_dom, state->be_ctx);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ DEBUG(SSSDBG_OP_FAILURE, "ipa_get_*_acct request failed: [%d]: %s.\n",
|
|
|
6cf099 |
+ ret, sss_strerror(ret));
|
|
|
6cf099 |
+ goto fail;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ state->dp_error = DP_ERR_OK;
|
|
|
6cf099 |
+ tevent_req_done(req);
|
|
|
6cf099 |
+ return;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+fail:
|
|
|
6cf099 |
+ state->dp_error = dp_error;
|
|
|
6cf099 |
+ tevent_req_error(req, ret);
|
|
|
6cf099 |
+}
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+static void ipa_srv_ad_acct_retried(struct tevent_req *subreq)
|
|
|
6cf099 |
+{
|
|
|
6cf099 |
+ errno_t ret;
|
|
|
6cf099 |
+ struct tevent_req *req = tevent_req_callback_data(subreq,
|
|
|
6cf099 |
+ struct tevent_req);
|
|
|
6cf099 |
+ struct ipa_srv_ad_acct_state *state = tevent_req_data(req,
|
|
|
6cf099 |
+ struct ipa_srv_ad_acct_state);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ ret = ipa_server_trusted_dom_setup_recv(subreq);
|
|
|
6cf099 |
+ talloc_free(subreq);
|
|
|
6cf099 |
+ if (ret != EOK) {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
|
6cf099 |
+ "Failed to re-set subdomain [%d]: %s\n", ret, sss_strerror(ret));
|
|
|
6cf099 |
+ state->dp_error = DP_ERR_FATAL;
|
|
|
6cf099 |
+ tevent_req_error(req, ret);
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ DEBUG(SSSDBG_TRACE_FUNC, "Sudomain re-set, will retry lookup\n");
|
|
|
6cf099 |
+ be_fo_reset_svc(state->be_ctx, state->obj_dom->name);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ ret = ipa_srv_ad_acct_lookup_step(req);
|
|
|
6cf099 |
+ if (ret != EOK) {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
|
6cf099 |
+ "Failed to look up AD acct [%d]: %s\n", ret, sss_strerror(ret));
|
|
|
6cf099 |
+ state->dp_error = DP_ERR_FATAL;
|
|
|
6cf099 |
+ tevent_req_error(req, ret);
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+}
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+static errno_t
|
|
|
6cf099 |
+ipa_srv_ad_acct_recv(struct tevent_req *req, int *dp_error_out)
|
|
|
6cf099 |
+{
|
|
|
6cf099 |
+ struct ipa_srv_ad_acct_state *state = tevent_req_data(req,
|
|
|
6cf099 |
+ struct ipa_srv_ad_acct_state);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ if (dp_error_out) {
|
|
|
6cf099 |
+ *dp_error_out = state->dp_error;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ TEVENT_REQ_RETURN_ON_ERROR(req);
|
|
|
6cf099 |
+ return EOK;
|
|
|
6cf099 |
+}
|
|
|
6cf099 |
--
|
|
|
6cf099 |
2.4.3
|
|
|
6cf099 |
|