>From c11b25307153a473fd3a5e226c9486e112305083 Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Mon, 16 Dec 2013 02:51:43 +0100 Subject: [PATCH 4/4] AD: Enumerate users from GC, other entities from LDAP https://fedorahosted.org/sssd/ticket/2142 When performing regular user or group lookups, we connect to GC primarily. However, the enumeration task could only connect to LDAP. When different attributes are present in GC and LDAP, this could have lead to very confusing results. This patch switches to using GC by default for both users and groups. Services, if present, are downloaded using the LDAP connection. --- src/providers/ad/ad_id.c | 127 ++++++++++++++++++++++++++++++++++++++- src/providers/ad/ad_id.h | 10 +++ src/providers/ad/ad_subdomains.c | 24 ++++---- 3 files changed, 147 insertions(+), 14 deletions(-) diff --git a/src/providers/ad/ad_id.c b/src/providers/ad/ad_id.c index 97599c3cb1c599995fba0157e51f9db949f53938..c72f8bc7403e52555735c0a9d8c1318a899b2b8c 100644 --- a/src/providers/ad/ad_id.c +++ b/src/providers/ad/ad_id.c @@ -549,6 +549,7 @@ ad_enumeration_master_done(struct tevent_req *subreq) char *flat_name; char *master_sid; int dp_error; + struct sdap_id_conn_ctx *user_conn; ret = ad_master_domain_recv(subreq, state, &flat_name, &master_sid); @@ -573,8 +574,17 @@ ad_enumeration_master_done(struct tevent_req *subreq) return; } - subreq = sdap_dom_enum_send(state, state->ev, state->id_ctx->sdap_id_ctx, - state->sdom, state->id_ctx->ldap_ctx); + if (dp_opt_get_bool(state->id_ctx->ad_options->basic, AD_ENABLE_GC)) { + user_conn = state->id_ctx->gc_ctx; + } else { + user_conn = state->id_ctx->ldap_ctx; + } + + subreq = sdap_dom_enum_ex_send(state, state->ev, state->id_ctx->sdap_id_ctx, + state->sdom, + user_conn, /* Users */ + user_conn, /* Groups */ + state->id_ctx->ldap_ctx); /* svcs */ if (subreq == NULL) { /* The ptask API will reschedule the enumeration on its own on * failure */ @@ -595,7 +605,7 @@ ad_enumeration_done(struct tevent_req *subreq) struct ad_enumeration_state *state = tevent_req_data(req, struct ad_enumeration_state); - ret = sdap_dom_enum_recv(subreq); + ret = sdap_dom_enum_ex_recv(subreq); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, @@ -613,3 +623,114 @@ ad_enumeration_recv(struct tevent_req *req) TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } + +/* Enumerate a subdomain */ +struct ad_enum_subdom_state { + struct ad_id_ctx *id_ctx; + struct ad_id_ctx *subdom_id_ctx; + + struct ldap_enum_ctx *ectx; + struct tevent_context *ev; + + struct sdap_domain *sdom; +}; + +static void ad_enum_subdom_done(struct tevent_req *subreq); + +struct tevent_req * +ad_enum_subdom_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct be_ctx *be_ctx, + struct be_ptask *be_ptask, + void *pvt) +{ + struct tevent_req *req; + struct tevent_req *subreq; + struct ad_enum_subdom_state *state; + struct ldap_enum_ctx *ectx; + errno_t ret; + struct sdap_id_conn_ctx *user_conn; + + req = tevent_req_create(mem_ctx, &state, struct ad_enum_subdom_state); + if (req == NULL) return NULL; + + ectx = talloc_get_type(pvt, struct ldap_enum_ctx); + if (ectx == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, ("Cannot retrieve ldap_enum_ctx!\n")); + ret = EFAULT; + goto fail; + } + + state->ectx = ectx; + state->ev = ev; + state->sdom = ectx->sdom; + state->id_ctx = talloc_get_type(ectx->pvt, struct ad_id_ctx); + if (state->id_ctx == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, ("Cannot retrieve ad_id_ctx!\n")); + ret = EFAULT; + goto fail; + } + + state->subdom_id_ctx = talloc_get_type(state->sdom->pvt, struct ad_id_ctx); + if (state->subdom_id_ctx == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, ("Cannot retrieve subdomain ad_id_ctx!\n")); + ret = EFAULT; + goto fail; + } + + if (dp_opt_get_bool(state->id_ctx->ad_options->basic, AD_ENABLE_GC)) { + user_conn = state->id_ctx->gc_ctx; + } else { + user_conn = state->subdom_id_ctx->ldap_ctx; + } + + subreq = sdap_dom_enum_ex_send(state, state->ev, state->id_ctx->sdap_id_ctx, + state->sdom, + user_conn, /* Users */ + user_conn, /* Groups */ + state->subdom_id_ctx->ldap_ctx); /* svcs */ + if (subreq == NULL) { + /* The ptask API will reschedule the enumeration on its own on + * failure */ + DEBUG(SSSDBG_OP_FAILURE, + ("Failed to schedule enumeration, retrying later!\n")); + ret = ENOMEM; + goto fail; + } + tevent_req_set_callback(subreq, ad_enum_subdom_done, req); + + return req; + +fail: + tevent_req_error(req, ret); + tevent_req_post(req, ev); + return req; +} + +static void +ad_enum_subdom_done(struct tevent_req *subreq) +{ + errno_t ret; + struct tevent_req *req = tevent_req_callback_data(subreq, + struct tevent_req); + struct ad_enum_subdom_state *state = tevent_req_data(req, + struct ad_enum_subdom_state); + + ret = sdap_dom_enum_ex_recv(subreq); + talloc_zfree(subreq); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, + ("Could not enumerate domain %s\n", state->sdom->dom->name)); + tevent_req_error(req, ret); + return; + } + + tevent_req_done(req); +} + +errno_t +ad_enum_subdom_recv(struct tevent_req *req) +{ + TEVENT_REQ_RETURN_ON_ERROR(req); + return EOK; +} diff --git a/src/providers/ad/ad_id.h b/src/providers/ad/ad_id.h index 74b85645c2d6458617a4064fe3fb3f99696c3741..20fe0b76350f1246fd0ad3f24b1138271a8a1521 100644 --- a/src/providers/ad/ad_id.h +++ b/src/providers/ad/ad_id.h @@ -47,6 +47,16 @@ ad_enumeration_send(TALLOC_CTX *mem_ctx, errno_t ad_enumeration_recv(struct tevent_req *req); +struct tevent_req * +ad_enum_subdom_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct be_ctx *be_ctx, + struct be_ptask *be_ptask, + void *pvt); + +errno_t +ad_enum_subdom_recv(struct tevent_req *req); + void ad_check_online(struct be_req *be_req); #endif /* AD_ID_H_ */ diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c index 381d17697b73e6a9cfb81ca7e03e20f88de433f5..9a4117cc6a6d232b2d12bdf60f88aa876480929e 100644 --- a/src/providers/ad/ad_subdomains.c +++ b/src/providers/ad/ad_subdomains.c @@ -26,6 +26,7 @@ #include "providers/ad/ad_subdomains.h" #include "providers/ad/ad_domain_info.h" #include "providers/ad/ad_srv.h" +#include "providers/ad/ad_id.h" #include "providers/ldap/sdap_idmap.h" #include "util/util_sss_idmap.h" #include @@ -176,17 +177,6 @@ ad_subdom_ad_ctx_new(struct be_ctx *be_ctx, return EFAULT; } - ret = sdap_id_setup_tasks(be_ctx, - ad_id_ctx->sdap_id_ctx, - sdom, - ldap_enumeration_send, - ldap_enumeration_recv, - ad_id_ctx->sdap_id_ctx); - if (ret != EOK) { - talloc_free(ad_options); - return ret; - } - /* Set up the ID mapping object */ ad_id_ctx->sdap_id_ctx->opts->idmap_ctx = id_ctx->sdap_id_ctx->opts->idmap_ctx; @@ -217,6 +207,18 @@ ads_store_sdap_subdom(struct ad_subdomains_ctx *ctx, DEBUG(SSSDBG_OP_FAILURE, ("ad_subdom_ad_ctx_new failed.\n")); } else { sditer->pvt = subdom_id_ctx; + + /* Set up enumeration/cleanup for the new subdomain */ + ret = sdap_id_setup_tasks(ctx->be_ctx, + ctx->ad_id_ctx->sdap_id_ctx, + sditer, + ad_enum_subdom_send, + ad_enum_subdom_recv, + subdom_id_ctx); + if (ret != EOK) { + return ret; + } + } } } -- 1.8.4.2