diff options
Diffstat (limited to 'src/providers/ad/ad_srv.c')
-rw-r--r-- | src/providers/ad/ad_srv.c | 44 |
1 files changed, 43 insertions, 1 deletions
diff --git a/src/providers/ad/ad_srv.c b/src/providers/ad/ad_srv.c index ff01ee95c..be1ba0f23 100644 --- a/src/providers/ad/ad_srv.c +++ b/src/providers/ad/ad_srv.c @@ -481,6 +481,7 @@ struct ad_srv_plugin_ctx { const char *hostname; const char *ad_domain; const char *ad_site_override; + const char *current_site; }; struct ad_srv_plugin_ctx * @@ -518,6 +519,11 @@ ad_srv_plugin_ctx_init(TALLOC_CTX *mem_ctx, if (ctx->ad_site_override == NULL) { goto fail; } + + ctx->current_site = talloc_strdup(ctx, ad_site_override); + if (ctx->current_site == NULL) { + goto fail; + } } return ctx; @@ -527,6 +533,32 @@ fail: return NULL; } +static errno_t +ad_srv_plugin_ctx_switch_site(struct ad_srv_plugin_ctx *ctx, + const char *new_site) +{ + const char *site; + errno_t ret; + + if (new_site == NULL) { + return EOK; + } + + if (ctx->current_site != NULL && strcmp(ctx->current_site, new_site) == 0) { + return EOK; + } + + site = talloc_strdup(ctx, new_site); + if (site == NULL) { + return ENOMEM; + } + + talloc_zfree(ctx->current_site); + ctx->current_site = site; + + return EOK; +} + struct ad_srv_plugin_state { struct tevent_context *ev; struct ad_srv_plugin_ctx *ctx; @@ -613,7 +645,7 @@ struct tevent_req *ad_srv_plugin_send(TALLOC_CTX *mem_ctx, subreq = ad_get_dc_servers_send(state, ev, ctx->be_res->resolv, state->discovery_domain, - state->ctx->ad_site_override); + state->ctx->current_site); if (subreq == NULL) { ret = ENOMEM; goto immediately; @@ -709,6 +741,16 @@ static void ad_srv_plugin_site_done(struct tevent_req *subreq) backup_domain = NULL; if (ret == EOK) { + /* Remember current site so it can be used during next lookup so + * we can contact directory controllers within a known reachable + * site first. */ + ret = ad_srv_plugin_ctx_switch_site(state->ctx, state->site); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to set site [%d]: %s\n", + ret, sss_strerror(ret)); + goto done; + } + if (strcmp(state->service, "gc") == 0) { if (state->forest != NULL) { if (state->site != NULL) { |