summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJakub Hrozek <jhrozek@redhat.com>2015-05-25 19:44:05 +0200
committerJakub Hrozek <jhrozek@redhat.com>2015-06-14 21:47:19 +0200
commit298e22fc97a99994e025c0d507737d88fe6fafef (patch)
tree199b9466152f04b637f6b132d6c932fca146c173
parent10bf907b6d463a5cd776a056cb182bc9f8765bf4 (diff)
downloadsssd-298e22fc97a99994e025c0d507737d88fe6fafef.tar.gz
sssd-298e22fc97a99994e025c0d507737d88fe6fafef.tar.xz
sssd-298e22fc97a99994e025c0d507737d88fe6fafef.zip
IPA: Make constructing an IPA server mode context async
Refactoring in preparation for requesting the keytab in future patches. Currently it's a fake async that just marks the request as done. Reviewed-by: Sumit Bose <sbose@redhat.com>
-rw-r--r--src/providers/ipa/ipa_subdomains.c36
-rw-r--r--src/providers/ipa/ipa_subdomains.h7
-rw-r--r--src/providers/ipa/ipa_subdomains_server.c236
3 files changed, 249 insertions, 30 deletions
diff --git a/src/providers/ipa/ipa_subdomains.c b/src/providers/ipa/ipa_subdomains.c
index 28693cbd0..0a5cdccf2 100644
--- a/src/providers/ipa/ipa_subdomains.c
+++ b/src/providers/ipa/ipa_subdomains.c
@@ -769,6 +769,7 @@ ipa_subdomains_handler_get_cont(struct ipa_subdomains_req_ctx *ctx,
}
static void ipa_get_view_name_done(struct tevent_req *req);
+static void ipa_server_create_trusts_done(struct tevent_req *trust_req);
static errno_t ipa_check_master(struct ipa_subdomains_req_ctx *ctx);
static errno_t ipa_get_view_name(struct ipa_subdomains_req_ctx *ctx)
@@ -1003,6 +1004,7 @@ static void ipa_subdomains_handler_done(struct tevent_req *req)
struct sss_domain_info *domain;
bool refresh_has_changes = false;
int dp_error = DP_ERR_FATAL;
+ struct tevent_req *trust_req;
ctx = tevent_req_callback_data(req, struct ipa_subdomains_req_ctx);
domain = ctx->sd_ctx->be_ctx->domain;
@@ -1047,12 +1049,17 @@ static void ipa_subdomains_handler_done(struct tevent_req *req)
goto done;
}
- ret = ipa_ad_subdom_refresh(ctx->sd_ctx->be_ctx,
- ctx->sd_ctx->id_ctx,
- domain);
- if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE, "ipa_ad_subdom_refresh failed.\n");
- goto done;
+ if (ctx->sd_ctx->id_ctx->server_mode != NULL) {
+ trust_req = ipa_server_create_trusts_send(ctx, ctx->sd_ctx->be_ctx->ev,
+ ctx->sd_ctx->be_ctx,
+ ctx->sd_ctx->id_ctx,
+ domain);
+ if (trust_req == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+ tevent_req_set_callback(trust_req, ipa_server_create_trusts_done, ctx);
+ return;
}
}
@@ -1088,6 +1095,23 @@ done:
ipa_subdomains_done(ctx->sd_ctx, ctx->be_req, dp_error, ret, NULL);
}
+static void ipa_server_create_trusts_done(struct tevent_req *trust_req)
+{
+ errno_t ret;
+ int dp_error = DP_ERR_FATAL;
+ struct ipa_subdomains_req_ctx *ctx;
+
+ ctx = tevent_req_callback_data(trust_req, struct ipa_subdomains_req_ctx);
+
+ ret = ipa_server_create_trusts_recv(trust_req);
+ talloc_zfree(trust_req);
+ if (ret == EOK) {
+ dp_error = DP_ERR_OK;
+ }
+
+ ipa_subdomains_done(ctx->sd_ctx, ctx->be_req, dp_error, ret, NULL);
+}
+
static errno_t ipa_check_master(struct ipa_subdomains_req_ctx *ctx)
{
int ret;
diff --git a/src/providers/ipa/ipa_subdomains.h b/src/providers/ipa/ipa_subdomains.h
index 3c5161d14..8dc3b78f3 100644
--- a/src/providers/ipa/ipa_subdomains.h
+++ b/src/providers/ipa/ipa_subdomains.h
@@ -48,10 +48,15 @@ struct ipa_ad_server_ctx {
};
/* To be used by ipa_subdomains.c only */
-errno_t ipa_ad_subdom_refresh(struct be_ctx *be_ctx,
+struct tevent_req *
+ipa_server_create_trusts_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct be_ctx *be_ctx,
struct ipa_id_ctx *id_ctx,
struct sss_domain_info *parent);
+errno_t ipa_server_create_trusts_recv(struct tevent_req *req);
+
void ipa_ad_subdom_remove(struct be_ctx *be_ctx,
struct ipa_id_ctx *id_ctx,
struct sss_domain_info *subdom);
diff --git a/src/providers/ipa/ipa_subdomains_server.c b/src/providers/ipa/ipa_subdomains_server.c
index 56cf0162a..6e43bbc2d 100644
--- a/src/providers/ipa/ipa_subdomains_server.c
+++ b/src/providers/ipa/ipa_subdomains_server.c
@@ -255,71 +255,185 @@ ipa_ad_ctx_new(struct be_ctx *be_ctx,
return EOK;
}
-static errno_t ipa_server_trust_add(struct be_ctx *be_ctx,
- struct ipa_id_ctx *id_ctx,
- struct sss_domain_info *subdom)
+struct ipa_server_trust_add_state {
+};
+
+static struct tevent_req *
+ipa_server_trust_add_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct be_ctx *be_ctx,
+ struct ipa_id_ctx *id_ctx,
+ struct sss_domain_info *subdom)
{
+ struct tevent_req *req = NULL;
+ struct ipa_server_trust_add_state *state = NULL;
struct ipa_ad_server_ctx *trust_ctx;
struct ad_id_ctx *ad_id_ctx;
errno_t ret;
+ req = tevent_req_create(mem_ctx, &state, struct ipa_server_trust_add_state);
+ if (req == NULL) {
+ return NULL;
+ }
+
ret = ipa_ad_ctx_new(be_ctx, id_ctx, subdom, &ad_id_ctx);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
"Cannot create ad_id_ctx for subdomain %s\n", subdom->name);
- return ret;
+ goto immediate;
}
trust_ctx = talloc(id_ctx->server_mode, struct ipa_ad_server_ctx);
if (trust_ctx == NULL) {
- return ENOMEM;
+ ret = ENOMEM;
+ goto immediate;
}
trust_ctx->dom = subdom;
trust_ctx->ad_id_ctx = ad_id_ctx;
DLIST_ADD(id_ctx->server_mode->trusts, trust_ctx);
+
+ /* In this particular patch, we just want to fake the async interface
+ * for an otherwise synchronous operation of creating two-way trusts,
+ * so currently the request is just marked as done and terminated. We
+ * will convert the request to fully async in a subsequent patch that
+ * adds support for one-way trusts.
+ */
+ ret = EOK;
+ goto immediate;
+
+ return req;
+
+immediate:
+ if (ret != EOK) {
+ tevent_req_error(req, ret);
+ } else {
+ tevent_req_done(req);
+ }
+ tevent_req_post(req, ev);
+ return req;
+}
+
+static errno_t ipa_server_trust_add_recv(struct tevent_req *req)
+{
+ TEVENT_REQ_RETURN_ON_ERROR(req);
return EOK;
}
-errno_t ipa_ad_subdom_refresh(struct be_ctx *be_ctx,
+struct ipa_server_create_trusts_state {
+ struct tevent_context *ev;
+ struct be_ctx *be_ctx;
+ struct ipa_id_ctx *id_ctx;
+ struct sss_domain_info *domiter;
+};
+
+static errno_t ipa_server_create_trusts_step(struct tevent_req *req);
+static void ipa_server_create_trusts_done(struct tevent_req *subreq);
+
+struct tevent_req *
+ipa_server_create_trusts_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct be_ctx *be_ctx,
struct ipa_id_ctx *id_ctx,
struct sss_domain_info *parent)
{
- struct sss_domain_info *dom;
- struct ipa_ad_server_ctx *trust_iter;
+ struct tevent_req *req = NULL;
+ struct ipa_server_create_trusts_state *state = NULL;
errno_t ret;
- if (dp_opt_get_bool(id_ctx->ipa_options->basic,
- IPA_SERVER_MODE) == false) {
- return EOK;
+ req = tevent_req_create(mem_ctx, &state,
+ struct ipa_server_create_trusts_state);
+ if (req == NULL) {
+ return NULL;
+ }
+
+ state->ev = ev;
+ state->be_ctx = be_ctx;
+ state->id_ctx = id_ctx;
+ state->domiter = parent;
+
+ ret = ipa_server_create_trusts_step(req);
+ if (ret != EAGAIN) {
+ goto immediate;
}
- for (dom = get_next_domain(parent, true);
- dom && IS_SUBDOMAIN(dom); /* if we get back to a parent, stop */
- dom = get_next_domain(dom, false)) {
+ return req;
+
+immediate:
+ if (ret != EOK) {
+ tevent_req_error(req, ret);
+ } else {
+ tevent_req_done(req);
+ }
+ tevent_req_post(req, ev);
+ return req;
+}
+
+static errno_t ipa_server_create_trusts_step(struct tevent_req *req)
+{
+ struct tevent_req *subreq = NULL;
+ struct ipa_ad_server_ctx *trust_iter;
+ struct ipa_server_create_trusts_state *state = NULL;
+
+ state = tevent_req_data(req, struct ipa_server_create_trusts_state);
+
+ for (state->domiter = get_next_domain(state->domiter, true);
+ state->domiter && IS_SUBDOMAIN(state->domiter);
+ state->domiter = get_next_domain(state->domiter, false)) {
/* Check if we already have an ID context for this subdomain */
- DLIST_FOR_EACH(trust_iter, id_ctx->server_mode->trusts) {
- if (trust_iter->dom == dom) {
+ DLIST_FOR_EACH(trust_iter, state->id_ctx->server_mode->trusts) {
+ if (trust_iter->dom == state->domiter) {
break;
}
}
/* Newly detected trust */
if (trust_iter == NULL) {
- ret = ipa_server_trust_add(be_ctx, id_ctx, dom);
- if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE,
- "Cannot create ad_id_ctx for subdomain %s\n",
- dom->name);
- continue;
+ subreq = ipa_server_trust_add_send(state, state->ev, state->be_ctx,
+ state->id_ctx, state->domiter);
+ if (subreq == NULL) {
+ return ENOMEM;
}
+ tevent_req_set_callback(subreq, ipa_server_create_trusts_done, req);
+ return EAGAIN;
}
}
return EOK;
}
+static void ipa_server_create_trusts_done(struct tevent_req *subreq)
+{
+ errno_t ret;
+ struct tevent_req *req = tevent_req_callback_data(subreq,
+ struct tevent_req);
+
+ ret = ipa_server_trust_add_recv(subreq);
+ talloc_zfree(subreq);
+ if (ret != EOK) {
+ tevent_req_error(req, ret);
+ return;
+ }
+
+ ret = ipa_server_create_trusts_step(req);
+ if (ret == EOK) {
+ tevent_req_done(req);
+ return;
+ } else if (ret != EAGAIN) {
+ tevent_req_error(req, ret);
+ return;
+ }
+
+ /* Will cycle back */
+}
+
+errno_t ipa_server_create_trusts_recv(struct tevent_req *req)
+{
+ TEVENT_REQ_RETURN_ON_ERROR(req);
+ return EOK;
+}
+
void ipa_ad_subdom_remove(struct be_ctx *be_ctx,
struct ipa_id_ctx *id_ctx,
struct sss_domain_info *subdom)
@@ -355,6 +469,81 @@ void ipa_ad_subdom_remove(struct be_ctx *be_ctx,
talloc_zfree(sdom);
}
+struct ipa_ad_subdom_reinit_state {
+ struct tevent_context *ev;
+ struct be_ctx *be_ctx;
+ struct ipa_id_ctx *id_ctx;
+ struct sss_domain_info *parent;
+};
+
+static void create_trusts_at_startup_done(struct tevent_req *req)
+{
+ errno_t ret;
+
+ ret = ipa_server_create_trusts_recv(req);
+ talloc_free(req);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ "ipa_server_create_trusts_send request failed [%d]: %s\n",
+ ret, sss_strerror(ret));
+ }
+}
+
+static void create_trusts_at_startup(struct tevent_context *ev,
+ struct tevent_immediate *imm,
+ void *pvt)
+{
+ struct tevent_req *req;
+ struct ipa_ad_subdom_reinit_state *state;
+
+ state = talloc_get_type(pvt, struct ipa_ad_subdom_reinit_state);
+
+ req = ipa_server_create_trusts_send(state, state->ev, state->be_ctx,
+ state->id_ctx, state->parent);
+ if (req == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "ipa_server_create_trusts_send failed.\n");
+ talloc_free(state);
+ return;
+ }
+
+ tevent_req_set_callback(req, create_trusts_at_startup_done, state);
+ return;
+}
+
+static errno_t ipa_ad_subdom_reinit(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct be_ctx *be_ctx,
+ struct ipa_id_ctx *id_ctx,
+ struct sss_domain_info *parent)
+{
+ struct tevent_immediate *imm;
+ struct ipa_ad_subdom_reinit_state *state;
+
+ state = talloc(mem_ctx, struct ipa_ad_subdom_reinit_state);
+ if (state == NULL) {
+ return ENOMEM;
+ }
+ state->ev = ev;
+ state->be_ctx = be_ctx;
+ state->id_ctx = id_ctx;
+ state->parent = parent;
+
+ if (dp_opt_get_bool(id_ctx->ipa_options->basic,
+ IPA_SERVER_MODE) == false) {
+ return EOK;
+ }
+
+ imm = tevent_create_immediate(mem_ctx);
+ if (imm == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "tevent_create_immediate failed.\n");
+ talloc_free(state);
+ return ENOMEM;
+ }
+
+ tevent_schedule_immediate(imm, ev, create_trusts_at_startup, state);
+ return EOK;
+}
+
int ipa_ad_subdom_init(struct be_ctx *be_ctx,
struct ipa_id_ctx *id_ctx)
{
@@ -405,7 +594,8 @@ int ipa_ad_subdom_init(struct be_ctx *be_ctx,
id_ctx->server_mode->trusts = NULL;
id_ctx->server_mode->ext_groups = NULL;
- ret = ipa_ad_subdom_refresh(be_ctx, id_ctx, be_ctx->domain);
+ ret = ipa_ad_subdom_reinit(be_ctx, be_ctx->ev,
+ be_ctx, id_ctx, be_ctx->domain);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, "ipa_ad_subdom_refresh failed.\n");
return ret;