>From ff586d3813c4fbea75c1c8dfba9620327630c531 Mon Sep 17 00:00:00 2001
From: Jan Zeleny <jzeleny@redhat.com>
Date: Tue, 5 Jun 2012 15:07:10 -0400
Subject: [PATCH 09/10] Primary server support: new options in krb5 provider

This patch adds support for new config options krb5_secondary_server and
krb5_secondary_kpasswd. The description of this option's functionality
is included in man page in one of previous patches.
---
 src/config/SSSDConfig/__init__.py.in     |    2 ++
 src/config/SSSDConfigTest.py             |    6 ++++++
 src/config/etc/sssd.api.d/sssd-krb5.conf |    2 ++
 src/man/sssd-krb5.5.xml                  |    4 ++--
 src/providers/ipa/ipa_opts.h             |    3 +++
 src/providers/krb5/krb5_common.h         |    2 ++
 src/providers/krb5/krb5_init.c           |   17 +++++++++++++----
 src/providers/krb5/krb5_opts.h           |    2 ++
 src/providers/ldap/ldap_opts.h           |    1 +
 src/providers/ldap/sdap.h                |    1 +
 10 files changed, 34 insertions(+), 6 deletions(-)

diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in
index 51ea228e87c6243a3e530102dccd7b89a65889ed..473cf526f93e3f17da29bd4d46d1ba8dff048ffa 100644
--- a/src/config/SSSDConfig/__init__.py.in
+++ b/src/config/SSSDConfig/__init__.py.in
@@ -135,6 +135,7 @@ option_strings = {
     # [provider/krb5]
     'krb5_kdcip' : _('Kerberos server address'),
     'krb5_server' : _('Kerberos server address'),
+    'krb5_secondaryserver' : _('Kerberos secondary server address'),
     'krb5_realm' : _('Kerberos realm'),
     'krb5_auth_timeout' : _('Authentication timeout'),
 
@@ -153,6 +154,7 @@ option_strings = {
 
     # [provider/krb5/chpass]
     'krb5_kpasswd' : _('Server where the change password service is running if not on the KDC'),
+    'krb5_secondary_kpasswd' : _('Server where the change password service is running if not on the KDC'),
 
     # [provider/ldap]
     'ldap_uri' : _('ldap_uri, The URI of the LDAP server'),
diff --git a/src/config/SSSDConfigTest.py b/src/config/SSSDConfigTest.py
index ef696e98c0b1ccce3dccda8ead7a3bda10049cf8..e8908cf72f8ef0aaacc90fdbee4c31edfdc7ae0f 100755
--- a/src/config/SSSDConfigTest.py
+++ b/src/config/SSSDConfigTest.py
@@ -570,8 +570,10 @@ class SSSDConfigTestSSSDDomain(unittest.TestCase):
         backup_list = control_list[:]
         control_list.extend(
             ['krb5_server',
+             'krb5_secondary_server',
              'krb5_realm',
              'krb5_kpasswd',
+             'krb5_secondary_kpasswd',
              'krb5_ccachedir',
              'krb5_ccname_template',
              'krb5_keytab',
@@ -723,9 +725,11 @@ class SSSDConfigTestSSSDDomain(unittest.TestCase):
         options = domain.list_provider_options('krb5', 'auth')
         control_list = [
             'krb5_server',
+            'krb5_secondary_server',
             'krb5_kdcip',
             'krb5_realm',
             'krb5_kpasswd',
+            'krb5_secondary_kpasswd',
             'krb5_ccachedir',
             'krb5_ccname_template',
             'krb5_keytab',
@@ -900,9 +904,11 @@ class SSSDConfigTestSSSDDomain(unittest.TestCase):
         backup_list = control_list[:]
         control_list.extend(
             ['krb5_server',
+             'krb5_secondary_server',
              'krb5_kdcip',
              'krb5_realm',
              'krb5_kpasswd',
+             'krb5_secondary_kpasswd',
              'krb5_ccachedir',
              'krb5_ccname_template',
              'krb5_keytab',
diff --git a/src/config/etc/sssd.api.d/sssd-krb5.conf b/src/config/etc/sssd.api.d/sssd-krb5.conf
index c52df1a6d9cd20eecfb13c5cea446fa7b61d4280..29835b63fc131bc356cdd7994bea8ed5e352ce48 100644
--- a/src/config/etc/sssd.api.d/sssd-krb5.conf
+++ b/src/config/etc/sssd.api.d/sssd-krb5.conf
@@ -1,9 +1,11 @@
 [provider/krb5]
 krb5_kdcip = str, None, false
 krb5_server = str, None, false
+krb5_secondary_server = str, None, false
 krb5_realm = str, None, true
 krb5_auth_timeout = int, None, false
 krb5_kpasswd = str, None, false
+krb5_secondary_kpasswd = str, None, false
 
 [provider/krb5/auth]
 krb5_ccachedir = str, None, false
diff --git a/src/man/sssd-krb5.5.xml b/src/man/sssd-krb5.5.xml
index 1baee36e9b0ade76de2990fd4f06bc655b5ce06c..e0c5ae6937940a83c83dbb145b86fc7a8b2b910a 100644
--- a/src/man/sssd-krb5.5.xml
+++ b/src/man/sssd-krb5.5.xml
@@ -71,7 +71,7 @@
             for details on the configuration of a SSSD domain.
             <variablelist>
                 <varlistentry>
-                    <term>krb5_server (string)</term>
+                    <term>krb5_server, krb5_secondary_server (string)</term>
                     <listitem>
                         <para>
                             Specifies the comma-separated list of IP addresses or hostnames
@@ -110,7 +110,7 @@
                 </varlistentry>
 
                 <varlistentry>
-                    <term>krb5_kpasswd (string)</term>
+                    <term>krb5_kpasswd, krb5_secondary_kpasswd (string)</term>
                     <listitem>
                         <para>
                             If the change password service is not running on the
diff --git a/src/providers/ipa/ipa_opts.h b/src/providers/ipa/ipa_opts.h
index fcf4b3f612fd45539523dc9743ce6113a3985709..52fd6d42f2c1dc467f7f1a1348362f00551d229b 100644
--- a/src/providers/ipa/ipa_opts.h
+++ b/src/providers/ipa/ipa_opts.h
@@ -90,6 +90,7 @@ struct dp_option ipa_def_ldap_opts[] = {
     { "ldap_krb5_init_creds", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE },
     /* use the same parm name as the krb5 module so we set it only once */
     { "krb5_server", DP_OPT_STRING, NULL_STRING, NULL_STRING },
+    { "krb5_secondary_server", DP_OPT_STRING, NULL_STRING, NULL_STRING },
     { "krb5_realm", DP_OPT_STRING, NULL_STRING, NULL_STRING },
     { "krb5_canonicalize", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE },
     { "ldap_pwd_policy", DP_OPT_STRING, { "none" } , NULL_STRING },
@@ -235,6 +236,7 @@ struct sdap_attr_map ipa_selinux_user_map[] = {
 
 struct dp_option ipa_def_krb5_opts[] = {
     { "krb5_server", DP_OPT_STRING, NULL_STRING, NULL_STRING },
+    { "krb5_secondary_server", DP_OPT_STRING, NULL_STRING, NULL_STRING },
     { "krb5_realm", DP_OPT_STRING, NULL_STRING, NULL_STRING },
     { "krb5_ccachedir", DP_OPT_STRING, { DEFAULT_CCACHE_DIR }, NULL_STRING },
     { "krb5_ccname_template", DP_OPT_STRING, { DEFAULT_CCNAME_TEMPLATE }, NULL_STRING},
@@ -242,6 +244,7 @@ struct dp_option ipa_def_krb5_opts[] = {
     { "krb5_keytab", DP_OPT_STRING, { "/etc/krb5.keytab" }, NULL_STRING },
     { "krb5_validate", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE },
     { "krb5_kpasswd", DP_OPT_STRING, NULL_STRING, NULL_STRING },
+    { "krb5_secondary_kpasswd", DP_OPT_STRING, NULL_STRING, NULL_STRING },
     { "krb5_store_password_if_offline", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
     { "krb5_renewable_lifetime", DP_OPT_STRING, NULL_STRING, NULL_STRING },
     { "krb5_lifetime", DP_OPT_STRING, NULL_STRING, NULL_STRING },
diff --git a/src/providers/krb5/krb5_common.h b/src/providers/krb5/krb5_common.h
index 8abd1e9223c62be397bc856b89d74eb99a52ca65..426ad6b6e49c6fb771be6004c7a9d8ed0d2f0c3e 100644
--- a/src/providers/krb5/krb5_common.h
+++ b/src/providers/krb5/krb5_common.h
@@ -49,6 +49,7 @@
 
 enum krb5_opts {
     KRB5_KDC = 0,
+    KRB5_SECONDARY_KDC,
     KRB5_REALM,
     KRB5_CCACHEDIR,
     KRB5_CCNAME_TMPL,
@@ -56,6 +57,7 @@ enum krb5_opts {
     KRB5_KEYTAB,
     KRB5_VALIDATE,
     KRB5_KPASSWD,
+    KRB5_SECONDARY_KPASSWD,
     KRB5_STORE_PASSWORD_IF_OFFLINE,
     KRB5_RENEWABLE_LIFETIME,
     KRB5_LIFETIME,
diff --git a/src/providers/krb5/krb5_init.c b/src/providers/krb5/krb5_init.c
index 74a1407548c6ac21d927083d59d60f87bd34a07e..6dad29fed411fc890220732bdb320170d1ef5cfe 100644
--- a/src/providers/krb5/krb5_init.c
+++ b/src/providers/krb5/krb5_init.c
@@ -62,7 +62,9 @@ int sssm_krb5_auth_init(struct be_ctx *bectx,
     unsigned v;
     FILE *debug_filep;
     const char *krb5_servers;
+    const char *krb5_secondary_servers;
     const char *krb5_kpasswd_servers;
+    const char *krb5_secondary_kpasswd_servers;
     const char *krb5_realm;
     const char *errstr;
     int errval;
@@ -100,9 +102,7 @@ int sssm_krb5_auth_init(struct be_ctx *bectx,
     ctx->opts = krb5_options->opts;
 
     krb5_servers = dp_opt_get_string(ctx->opts, KRB5_KDC);
-    if (krb5_servers == NULL) {
-        DEBUG(1, ("Missing krb5_server option, using service discovery!\n"));
-    }
+    krb5_secondary_servers = dp_opt_get_string(ctx->opts, KRB5_KDC);
 
     krb5_realm = dp_opt_get_string(ctx->opts, KRB5_REALM);
     if (krb5_realm == NULL) {
@@ -111,13 +111,22 @@ int sssm_krb5_auth_init(struct be_ctx *bectx,
     }
 
     ret = krb5_service_init(ctx, bectx, SSS_KRB5KDC_FO_SRV, krb5_servers,
-                            NULL, krb5_realm, &ctx->service);
+                            krb5_secondary_servers, krb5_realm, &ctx->service);
     if (ret != EOK) {
         DEBUG(0, ("Failed to init KRB5 failover service!\n"));
         return ret;
     }
 
     krb5_kpasswd_servers = dp_opt_get_string(ctx->opts, KRB5_KPASSWD);
+    krb5_secondary_kpasswd_servers = dp_opt_get_string(ctx->opts,
+                                                       KRB5_SECONDARY_KPASSWD);
+    if (krb5_kpasswd_servers == NULL && krb5_secondary_kpasswd_servers != NULL) {
+        DEBUG(SSSDBG_CONF_SETTINGS, ("kpasswd server wasn't specified but "
+                                     "secondary kpasswd given. Using it as primary\n"));
+        krb5_kpasswd_servers = krb5_secondary_kpasswd_servers;
+        krb5_secondary_kpasswd_servers = NULL;
+    }
+
     if (krb5_kpasswd_servers == NULL && krb5_servers != NULL) {
         DEBUG(0, ("Missing krb5_kpasswd option and KDC set explicitly, "
                   "will use KDC for pasword change operations!\n"));
diff --git a/src/providers/krb5/krb5_opts.h b/src/providers/krb5/krb5_opts.h
index 9de93b0cd725b15210263b282514af94f9dd9473..ab4b8d998eec8447f6789725d2b6350011cee715 100644
--- a/src/providers/krb5/krb5_opts.h
+++ b/src/providers/krb5/krb5_opts.h
@@ -27,6 +27,7 @@
 
 struct dp_option default_krb5_opts[] = {
     { "krb5_server", DP_OPT_STRING, NULL_STRING, NULL_STRING },
+    { "krb5_secondary_server", DP_OPT_STRING, NULL_STRING, NULL_STRING },
     { "krb5_realm", DP_OPT_STRING, NULL_STRING, NULL_STRING },
     { "krb5_ccachedir", DP_OPT_STRING, { DEFAULT_CCACHE_DIR }, NULL_STRING },
     { "krb5_ccname_template", DP_OPT_STRING, { DEFAULT_CCNAME_TEMPLATE }, NULL_STRING},
@@ -34,6 +35,7 @@ struct dp_option default_krb5_opts[] = {
     { "krb5_keytab", DP_OPT_STRING, { "/etc/krb5.keytab" }, NULL_STRING },
     { "krb5_validate", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
     { "krb5_kpasswd", DP_OPT_STRING, NULL_STRING, NULL_STRING },
+    { "krb5_secondary_kpasswd", DP_OPT_STRING, NULL_STRING, NULL_STRING },
     { "krb5_store_password_if_offline", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
     { "krb5_renewable_lifetime", DP_OPT_STRING, NULL_STRING, NULL_STRING },
     { "krb5_lifetime", DP_OPT_STRING, NULL_STRING, NULL_STRING },
diff --git a/src/providers/ldap/ldap_opts.h b/src/providers/ldap/ldap_opts.h
index f0a5baa5bd9bb0ec26e879d4181c9613c293c850..d186443d5ea0a0981006038637844991d483b406 100644
--- a/src/providers/ldap/ldap_opts.h
+++ b/src/providers/ldap/ldap_opts.h
@@ -71,6 +71,7 @@ struct dp_option default_basic_opts[] = {
     { "ldap_krb5_init_creds", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE },
     /* use the same parm name as the krb5 module so we set it only once */
     { "krb5_server", DP_OPT_STRING, NULL_STRING, NULL_STRING },
+    { "krb5_secondary_server", DP_OPT_STRING, NULL_STRING, NULL_STRING },
     { "krb5_realm", DP_OPT_STRING, NULL_STRING, NULL_STRING },
     { "krb5_canonicalize", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE },
     { "ldap_pwd_policy", DP_OPT_STRING, { "none" }, NULL_STRING },
diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h
index a67fbf609a790717f07ffce49c5b69281cddf2cc..a28430df3b20ff3e9defa94241c181712b319f8c 100644
--- a/src/providers/ldap/sdap.h
+++ b/src/providers/ldap/sdap.h
@@ -189,6 +189,7 @@ enum sdap_basic_opt {
     SDAP_KRB5_KEYTAB,
     SDAP_KRB5_KINIT,
     SDAP_KRB5_KDC,
+    SDAP_KRB5_SECONDARY_KDC,
     SDAP_KRB5_REALM,
     SDAP_KRB5_CANONICALIZE,
     SDAP_PWD_POLICY,
-- 
1.7.7.6

