summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/providers/ad/ad_srv.c44
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) {