summaryrefslogtreecommitdiffstats
path: root/src/providers/ipa/ipa_subdomains_server.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/providers/ipa/ipa_subdomains_server.c')
-rw-r--r--src/providers/ipa/ipa_subdomains_server.c236
1 files changed, 213 insertions, 23 deletions
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;