From 850c62a73133ac0b7fb0e509b00c3651dec6f496 Mon Sep 17 00:00:00 2001
From: Jan Zeleny <jzeleny@redhat.com>
Date: Tue, 5 Jun 2012 15:07:10 -0400
Subject: [PATCH 7/8] 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 1c79d6cfcaa958deab6636f03ca7f66b412527b0..781add0279f004b10d7bfdf7b5282a62f3aa0fbf 100644
--- a/src/config/SSSDConfig/__init__.py.in
+++ b/src/config/SSSDConfig/__init__.py.in
@@ -132,6 +132,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'),
 
@@ -150,6 +151,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 1e1fe98e6850f7539579db00fc0bd96d2a865c9b..867b282f4bf53bdec6c536e54477cb7946a19b21 100755
--- a/src/config/SSSDConfigTest.py
+++ b/src/config/SSSDConfigTest.py
@@ -569,8 +569,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',
@@ -722,9 +724,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',
@@ -899,9 +903,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 247337a90a80b078d0395b27a02e5ea2c72a5ce8..a2da02dd1447af2f13bf8edc494eb945cfe666ea 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 5fac673e5e2ddd19d848781843bb4782f6e26edc..0eb9f215dbcf89e702413766b3d223ac49047c90 100644
--- a/src/providers/ipa/ipa_opts.h
+++ b/src/providers/ipa/ipa_opts.h
@@ -89,6 +89,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 },
@@ -232,6 +233,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, { "/tmp" }, NULL_STRING },
     { "krb5_ccname_template", DP_OPT_STRING, { "FILE:%d/krb5cc_%U_XXXXXX" }, NULL_STRING},
@@ -239,6 +241,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 dd5e0cec3b736b101c0a836233d3ddd72910e700..f49ae582a6f49a3931c33e86cac539784e37ec07 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 7f47290c961ce6455e0d123e9ec14c7add39d28d..bff5cf46389d340eded51fadbe0c70487d92ec2a 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, { "/tmp" }, NULL_STRING },
     { "krb5_ccname_template", DP_OPT_STRING, { "FILE:%d/krb5cc_%U_XXXXXX" }, 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 37fdf3953b550052f18272911584cbdb5f2d568d..fc24a1358f526655a17c6e71896a3237dd4f216f 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 67d09b744e30bb7119469cc3cdf0d8a2ec03f8bc..62d6a84462b0d82923b794077e7ad813c134fe10 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

