>From f8f6683dff83d27fb246be33466216142dedf71f Mon Sep 17 00:00:00 2001
From: Pavel Reichl <preichl@redhat.com>
Date: Wed, 7 Jan 2015 11:02:44 +0000
Subject: [PATCH 2/2] AD: support for AD site override

Override AD site found during DNS discovery.

Resolves:
https://fedorahosted.org/sssd/ticket/2486
---
 src/providers/ad/ad_init.c         |  6 +++++-
 src/providers/ad/ad_srv.c          | 24 +++++++++++++++++++++---
 src/providers/ad/ad_srv.h          |  3 ++-
 src/providers/ad/ad_subdomains.c   |  5 ++++-
 src/providers/ipa/ipa_subdomains.c |  6 +++++-
 5 files changed, 37 insertions(+), 7 deletions(-)

diff --git a/src/providers/ad/ad_init.c b/src/providers/ad/ad_init.c
index cba792726374fb7a949ee4077d799a737b2f6681..2de7e0a44015750c7a4c7980d4ebeb26736c4f02 100644
--- a/src/providers/ad/ad_init.c
+++ b/src/providers/ad/ad_init.c
@@ -159,6 +159,7 @@ sssm_ad_id_init(struct be_ctx *bectx,
     struct ad_id_ctx *ad_ctx;
     const char *hostname;
     const char *ad_domain;
+    const char *ad_site_override;
     struct ad_srv_plugin_ctx *srv_ctx;
 
     if (!ad_options) {
@@ -234,9 +235,12 @@ sssm_ad_id_init(struct be_ctx *bectx,
     if (dp_opt_get_bool(ad_options->basic, AD_ENABLE_DNS_SITES)) {
         /* use AD plugin */
         ad_domain = dp_opt_get_string(ad_options->basic, AD_DOMAIN);
+        ad_site_override = dp_opt_get_string(ad_options->basic, AD_SITE);
+
         srv_ctx = ad_srv_plugin_ctx_init(bectx, bectx->be_res,
                                          default_host_dbs, ad_options->id,
-                                         hostname, ad_domain);
+                                         hostname, ad_domain,
+                                         ad_site_override);
         if (srv_ctx == NULL) {
             DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory?\n");
             ret = ENOMEM;
diff --git a/src/providers/ad/ad_srv.c b/src/providers/ad/ad_srv.c
index 53d8a87701705654318845eaa4e4eac9ff6a5951..ac9dfa187213e6cdb9cdc3440f013e5b73e11fc4 100644
--- a/src/providers/ad/ad_srv.c
+++ b/src/providers/ad/ad_srv.c
@@ -540,7 +540,7 @@ done:
 
 int ad_get_client_site_recv(TALLOC_CTX *mem_ctx,
                             struct tevent_req *req,
-                            char **_site,
+                            const char **_site,
                             char **_forest)
 {
     struct ad_get_client_site_state *state = NULL;
@@ -560,6 +560,7 @@ struct ad_srv_plugin_ctx {
     struct sdap_options *opts;
     const char *hostname;
     const char *ad_domain;
+    const char *ad_site_override;
 };
 
 struct ad_srv_plugin_ctx *
@@ -568,7 +569,8 @@ ad_srv_plugin_ctx_init(TALLOC_CTX *mem_ctx,
                        enum host_database *host_dbs,
                        struct sdap_options *opts,
                        const char *hostname,
-                       const char *ad_domain)
+                       const char *ad_domain,
+                       const char *ad_site_override)
 {
     struct ad_srv_plugin_ctx *ctx = NULL;
 
@@ -591,6 +593,13 @@ ad_srv_plugin_ctx_init(TALLOC_CTX *mem_ctx,
         goto fail;
     }
 
+    if (ad_site_override != NULL) {
+        ctx->ad_site_override = talloc_strdup(ctx, ad_site_override);
+        if (ctx->ad_site_override == NULL) {
+            goto fail;
+        }
+    }
+
     return ctx;
 
 fail:
@@ -605,7 +614,7 @@ struct ad_srv_plugin_state {
     const char *protocol;
     const char *discovery_domain;
 
-    char *site;
+    const char *site;
     char *dns_domain;
     char *forest;
     struct fo_server_info *primary_servers;
@@ -756,6 +765,15 @@ static void ad_srv_plugin_site_done(struct tevent_req *subreq)
 
     ret = ad_get_client_site_recv(state, subreq, &state->site, &state->forest);
     talloc_zfree(subreq);
+    /* Ignore AD site found by dns discovery if specific site is set in
+     * configuration file. */
+    if (state->ctx->ad_site_override != NULL) {
+        DEBUG(SSSDBG_TRACE_INTERNAL,
+              "Ignoring AD site found by DNS discovery: '%s', "
+              "using configured value: '%s' instead.\n",
+              state->site, state->ctx->ad_site_override);
+        state->site = state->ctx->ad_site_override;
+    }
     if (ret == EOK) {
         if (strcmp(state->service, "gc") == 0) {
             primary_domain = talloc_asprintf(state, AD_SITE_DOMAIN_FMT,
diff --git a/src/providers/ad/ad_srv.h b/src/providers/ad/ad_srv.h
index 7522ecae4d15397efc0bd3c6cd711a3024eb1771..be3ac2826186008a4db6333e5d27e408aaed2e51 100644
--- a/src/providers/ad/ad_srv.h
+++ b/src/providers/ad/ad_srv.h
@@ -29,7 +29,8 @@ ad_srv_plugin_ctx_init(TALLOC_CTX *mem_ctx,
                        enum host_database *host_dbs,
                        struct sdap_options *opts,
                        const char *hostname,
-                       const char *ad_domain);
+                       const char *ad_domain,
+                       const char *ad_site_override);
 
 struct tevent_req *ad_srv_plugin_send(TALLOC_CTX *mem_ctx,
                                        struct tevent_context *ev,
diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c
index 3c61d13522c7c773171ea8645dddb417e610745c..b3821f8d07855e431e69cdc00c225bcd7e4db1eb 100644
--- a/src/providers/ad/ad_subdomains.c
+++ b/src/providers/ad/ad_subdomains.c
@@ -102,6 +102,7 @@ ad_subdom_ad_ctx_new(struct be_ctx *be_ctx,
     const char *gc_service_name;
     struct ad_srv_plugin_ctx *srv_ctx;
     char *ad_domain;
+    char *ad_site_override;
     struct sdap_domain *sdom;
     errno_t ret;
     const char *realm;
@@ -122,6 +123,7 @@ ad_subdom_ad_ctx_new(struct be_ctx *be_ctx,
     }
 
     ad_domain = subdom->name;
+    ad_site_override = dp_opt_get_string(ad_options->basic, AD_SITE);
 
     ret = dp_opt_set_string(ad_options->basic, AD_DOMAIN, ad_domain);
     if (ret != EOK) {
@@ -158,7 +160,8 @@ ad_subdom_ad_ctx_new(struct be_ctx *be_ctx,
                                      default_host_dbs,
                                      ad_id_ctx->ad_options->id,
                                      hostname,
-                                     ad_domain);
+                                     ad_domain,
+                                     ad_site_override);
     if (srv_ctx == NULL) {
         DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory?\n");
         return ENOMEM;
diff --git a/src/providers/ipa/ipa_subdomains.c b/src/providers/ipa/ipa_subdomains.c
index 3148389f71135b6c64e62d1cf7f4064dd183f595..d0f02badee52afc93eb9bf316e654aa0e789937a 100644
--- a/src/providers/ipa/ipa_subdomains.c
+++ b/src/providers/ipa/ipa_subdomains.c
@@ -116,6 +116,7 @@ ipa_ad_ctx_new(struct be_ctx *be_ctx,
     const char *gc_service_name;
     struct ad_srv_plugin_ctx *srv_ctx;
     char *ad_domain;
+    const char *ad_site_override;
     struct sdap_domain *sdom;
     errno_t ret;
     const char *extra_attrs;
@@ -201,12 +202,15 @@ ipa_ad_ctx_new(struct be_ctx *be_ctx,
     ad_id_ctx->sdap_id_ctx->opts = ad_options->id;
     ad_options->id_ctx = ad_id_ctx;
 
+    ad_site_override = dp_opt_get_string(ad_options->basic, AD_SITE);
+
     /* use AD plugin */
     srv_ctx = ad_srv_plugin_ctx_init(be_ctx, be_ctx->be_res,
                                      default_host_dbs,
                                      ad_id_ctx->ad_options->id,
                                      id_ctx->server_mode->hostname,
-                                     ad_domain);
+                                     ad_domain,
+                                     ad_site_override);
     if (srv_ctx == NULL) {
         DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory?\n");
         return ENOMEM;
-- 
2.1.0

