>From d110ea1989b0f8a23ef88ee6e2f94e3ec36d9ea5 Mon Sep 17 00:00:00 2001
From: Jan Zeleny <jzeleny@redhat.com>
Date: Tue, 17 Jul 2012 07:56:24 -0400
Subject: [PATCH 07/12] Primary server support: AD adaptation

This patch adds support for the primary server functionality into AD
provider. No backup servers are added at the moment, just the basic
support is in place.
---
 src/providers/ad/ad_common.c |  171 ++++++++++++++++++++++++++----------------
 src/providers/ad/ad_common.h |    3 +-
 src/providers/ad/ad_init.c   |    2 +-
 3 files changed, 109 insertions(+), 67 deletions(-)

diff --git a/src/providers/ad/ad_common.c b/src/providers/ad/ad_common.c
index d8e761c8953ce3e794a49e890a6568800bd30c20..29d5b28a8ae4299a808b81bc55e995929d5c1d12 100644
--- a/src/providers/ad/ad_common.c
+++ b/src/providers/ad/ad_common.c
@@ -144,77 +144,22 @@ done:
 static void
 ad_resolve_callback(void *private_data, struct fo_server *server);
 
-errno_t
-ad_failover_init(TALLOC_CTX *mem_ctx, struct be_ctx *bectx,
-                 const char *servers,
-                 struct ad_options *options,
-                 struct ad_service **_service)
+static errno_t
+ad_servers_init(TALLOC_CTX *mem_ctx,
+                struct be_ctx *bectx,
+                const char *servers,
+                struct ad_options *options,
+                bool primary)
 {
+    size_t i;
     errno_t ret;
-    TALLOC_CTX *tmp_ctx;
-    struct ad_service *service;
-    char *ad_domain;
-    char *realm;
     char **list;
-    size_t i;
+    char *ad_domain;
+    TALLOC_CTX *tmp_ctx;
 
     tmp_ctx = talloc_new(mem_ctx);
     if (!tmp_ctx) return ENOMEM;
 
-    service = talloc_zero(tmp_ctx, struct ad_service);
-    if (!service) {
-        ret = ENOMEM;
-        goto done;
-    }
-
-    service->sdap = talloc_zero(service, struct sdap_service);
-    if (!service->sdap) {
-        ret = ENOMEM;
-        goto done;
-    }
-
-    service->krb5_service = talloc_zero(service, struct krb5_service);
-    if (!service->krb5_service) {
-        ret = ENOMEM;
-        goto done;
-    }
-
-    ret = be_fo_add_service(bectx, AD_SERVICE_NAME);
-    if (ret != EOK) {
-        DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to create failover service!\n"));
-        goto done;
-    }
-
-    service->sdap->name = talloc_strdup(service, AD_SERVICE_NAME);
-    if (!service->sdap->name) {
-        ret = ENOMEM;
-        goto done;
-    }
-
-    service->krb5_service->name = talloc_strdup(service, AD_SERVICE_NAME);
-    if (!service->krb5_service->name) {
-        ret = ENOMEM;
-        goto done;
-    }
-    service->sdap->kinit_service_name = service->krb5_service->name;
-
-    realm = dp_opt_get_string(options->basic, AD_KRB5_REALM);
-    if (!realm) {
-        DEBUG(SSSDBG_CRIT_FAILURE, ("No Kerberos realm set\n"));
-        ret = EINVAL;
-        goto done;
-    }
-    service->krb5_service->realm =
-        talloc_strdup(service->krb5_service, realm);
-    if (!service->krb5_service->realm) {
-        ret = ENOMEM;
-        goto done;
-    }
-
-    if (!servers) {
-        servers = BE_SRV_IDENTIFIER;
-    }
-
     /* Split the server list */
     ret = split_on_separator(tmp_ctx, servers, ',', true, &list, NULL);
     if (ret != EOK) {
@@ -241,7 +186,7 @@ ad_failover_init(TALLOC_CTX *mem_ctx, struct be_ctx *bectx,
             continue;
         }
 
-        ret = be_fo_add_server(bectx, AD_SERVICE_NAME, list[i], 0, NULL);
+        ret = be_fo_add_server(bectx, AD_SERVICE_NAME, list[i], 0, NULL, primary);
         if (ret && ret != EEXIST) {
             DEBUG(SSSDBG_FATAL_FAILURE, ("Failed to add server\n"));
             goto done;
@@ -249,6 +194,102 @@ ad_failover_init(TALLOC_CTX *mem_ctx, struct be_ctx *bectx,
 
         DEBUG(SSSDBG_CONF_SETTINGS, ("Added failover server %s\n", list[i]));
     }
+done:
+    talloc_free(tmp_ctx);
+    return ret;
+}
+
+errno_t
+ad_failover_init(TALLOC_CTX *mem_ctx, struct be_ctx *bectx,
+                 const char *primary_servers,
+                 const char *backup_servers,
+                 struct ad_options *options,
+                 struct ad_service **_service)
+{
+    errno_t ret;
+    TALLOC_CTX *tmp_ctx;
+    struct ad_service *service;
+    char *realm;
+
+    tmp_ctx = talloc_new(mem_ctx);
+    if (!tmp_ctx) return ENOMEM;
+
+    service = talloc_zero(tmp_ctx, struct ad_service);
+    if (!service) {
+        ret = ENOMEM;
+        goto done;
+    }
+
+    service->sdap = talloc_zero(service, struct sdap_service);
+    if (!service->sdap) {
+        ret = ENOMEM;
+        goto done;
+    }
+
+    service->krb5_service = talloc_zero(service, struct krb5_service);
+    if (!service->krb5_service) {
+        ret = ENOMEM;
+        goto done;
+    }
+
+    ret = be_fo_add_service(bectx, AD_SERVICE_NAME);
+    if (ret != EOK) {
+        DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to create failover service!\n"));
+        goto done;
+    }
+
+    service->sdap->name = talloc_strdup(service, AD_SERVICE_NAME);
+    if (!service->sdap->name) {
+        ret = ENOMEM;
+        goto done;
+    }
+
+    service->krb5_service->name = talloc_strdup(service, AD_SERVICE_NAME);
+    if (!service->krb5_service->name) {
+        ret = ENOMEM;
+        goto done;
+    }
+    service->sdap->kinit_service_name = service->krb5_service->name;
+
+    realm = dp_opt_get_string(options->basic, AD_KRB5_REALM);
+    if (!realm) {
+        DEBUG(SSSDBG_CRIT_FAILURE, ("No Kerberos realm set\n"));
+        ret = EINVAL;
+        goto done;
+    }
+    service->krb5_service->realm =
+        talloc_strdup(service->krb5_service, realm);
+    if (!service->krb5_service->realm) {
+        ret = ENOMEM;
+        goto done;
+    }
+
+    if (!primary_servers) {
+        if (backup_servers) {
+            DEBUG(SSSDBG_TRACE_FUNC,
+                  ("No primary servers defined but backup are present, "
+                   "setting backup servers as primary\n"));
+            primary_servers = backup_servers;
+            backup_servers = NULL;
+        } else {
+            DEBUG(SSSDBG_TRACE_FUNC,
+                  ("No primary or backup servers defined but backup are present, "
+                   "setting backup servers as primary\n"));
+            primary_servers = BE_SRV_IDENTIFIER;
+        }
+    }
+
+    ret = ad_servers_init(mem_ctx, bectx, primary_servers, options, true);
+    if (ret != EOK) {
+        goto done;
+    }
+
+    if (backup_servers) {
+        ret = ad_servers_init(mem_ctx, bectx, backup_servers, options, false);
+        if (ret != EOK) {
+            goto done;
+        }
+    }
 
     ret = be_fo_service_add_callback(mem_ctx, bectx, AD_SERVICE_NAME,
                                      ad_resolve_callback, service);
diff --git a/src/providers/ad/ad_common.h b/src/providers/ad/ad_common.h
index d28bfc8a9b246d7cfaa98a12576257dc5bf5f473..f2ed680d2991bdd13a2a3dfe0f8999158a1820a0 100644
--- a/src/providers/ad/ad_common.h
+++ b/src/providers/ad/ad_common.h
@@ -73,7 +73,8 @@ ad_get_common_options(TALLOC_CTX *mem_ctx,
 
 errno_t
 ad_failover_init(TALLOC_CTX *mem_ctx, struct be_ctx *ctx,
-                 const char *servers,
+                 const char *primary_servers,
+                 const char *backup_servers,
                  struct ad_options *options,
                  struct ad_service **_service);
 
diff --git a/src/providers/ad/ad_init.c b/src/providers/ad/ad_init.c
index 6baae0ce5cb835e92bf0b139c7acd90bc413bad5..0c0a8ef63cbd4ed1003452594221c3262ac5c971 100644
--- a/src/providers/ad/ad_init.c
+++ b/src/providers/ad/ad_init.c
@@ -83,7 +83,7 @@ common_ad_init(struct be_ctx *bectx)
     ad_servers = dp_opt_get_string(ad_options->basic, AD_SERVER);
 
     /* Set up the failover service */
-    ret = ad_failover_init(ad_options, bectx, ad_servers, ad_options,
+    ret = ad_failover_init(ad_options, bectx, ad_servers, NULL, ad_options,
                            &ad_options->service);
     if (ret != EOK) {
         DEBUG(SSSDBG_FATAL_FAILURE,
-- 
1.7.7.6

