From 516e2d4071113c1486209b66f9708962e80306ce Mon Sep 17 00:00:00 2001
From: Jan Zeleny <jzeleny@redhat.com>
Date: Wed, 19 Oct 2011 03:27:47 -0400
Subject: [PATCH] Add support to request canonicalization on krb AS requests

https://fedorahosted.org/sssd/ticket/957
---
 src/config/etc/sssd.api.d/sssd-krb5.conf |    1 +
 src/providers/ipa/ipa_common.c           |    3 ++-
 src/providers/ipa/ipa_common.h           |    2 +-
 src/providers/krb5/krb5_child.c          |   16 ++++++++++++++++
 src/providers/krb5/krb5_common.c         |    9 ++++++++-
 src/providers/krb5/krb5_common.h         |    2 ++
 6 files changed, 30 insertions(+), 3 deletions(-)

diff --git a/src/config/etc/sssd.api.d/sssd-krb5.conf b/src/config/etc/sssd.api.d/sssd-krb5.conf
index 79c67aeacc3d50485df43e788771e940d9f0976c..9392ae417cb36eee953087199f0bbfcc84f6bc4a 100644
--- a/src/config/etc/sssd.api.d/sssd-krb5.conf
+++ b/src/config/etc/sssd.api.d/sssd-krb5.conf
@@ -15,6 +15,7 @@ krb5_renewable_lifetime = str, None, false
 krb5_lifetime = str, None, false
 krb5_renew_interval = int, None, false
 krb5_use_fast = str, None, false
+krb5_canonicalize = bool, None, false
 
 [provider/krb5/access]
 
diff --git a/src/providers/ipa/ipa_common.c b/src/providers/ipa/ipa_common.c
index c622945684112a353b8667fbaa53432b4865151f..be67dec9acfd8a59e6024ad98e4a3a8e691abc54 100644
--- a/src/providers/ipa/ipa_common.c
+++ b/src/providers/ipa/ipa_common.c
@@ -175,7 +175,8 @@ struct dp_option ipa_def_krb5_opts[] = {
     { "krb5_lifetime", DP_OPT_STRING, NULL_STRING, NULL_STRING },
     { "krb5_renew_interval", DP_OPT_NUMBER, NULL_NUMBER, NULL_NUMBER },
     { "krb5_use_fast", DP_OPT_STRING, NULL_STRING, NULL_STRING },
-    { "krb5_fast_principal", DP_OPT_STRING, NULL_STRING, NULL_STRING }
+    { "krb5_fast_principal", DP_OPT_STRING, NULL_STRING, NULL_STRING },
+    { "krb5_canonicalize", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE }
 };
 
 int ipa_get_options(TALLOC_CTX *memctx,
diff --git a/src/providers/ipa/ipa_common.h b/src/providers/ipa/ipa_common.h
index 575911504920824ffdd6bcb365c513ee156c2c0b..20074b45b521febb854fbbaa359fafea2f24c64c 100644
--- a/src/providers/ipa/ipa_common.h
+++ b/src/providers/ipa/ipa_common.h
@@ -40,7 +40,7 @@ struct ipa_service {
 /* the following define is used to keep track of the options in the krb5
  * module, so that if they change and ipa is not updated correspondingly
  * this will trigger a runtime abort error */
-#define IPA_KRB5_OPTS_TEST 14
+#define IPA_KRB5_OPTS_TEST 15
 
 enum ipa_basic_opt {
     IPA_DOMAIN = 0,
diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c
index ec2251e43807f8df3aaab4058eb69f6030d7ff2e..d0ba81b8b79f1060a50a6ae5210a8d2f6a76d782 100644
--- a/src/providers/krb5/krb5_child.c
+++ b/src/providers/krb5/krb5_child.c
@@ -591,6 +591,9 @@ static krb5_error_code get_and_save_tgt_with_keytab(krb5_context ctx,
                                                     krb5_keytab keytab,
                                                     char *ccname)
 {
+    int canonicalize = 0;
+    char *tmp_str;
+
     krb5_error_code kerr = 0;
     krb5_creds creds;
     krb5_get_init_creds_opt options;
@@ -602,6 +605,12 @@ static krb5_error_code get_and_save_tgt_with_keytab(krb5_context ctx,
     krb5_get_init_creds_opt_set_forwardable(&options, 0);
     krb5_get_init_creds_opt_set_proxiable(&options, 0);
 
+    tmp_str = getenv(SSSD_KRB5_CANONICALIZE);
+    if (tmp_str != NULL && strcasecmp(tmp_str, "true") == 0) {
+        canonicalize = 1;
+    }
+    krb5_get_init_creds_opt_set_canonicalize(&options, canonicalize);
+
     kerr = krb5_get_init_creds_keytab(ctx, &creds, princ, keytab, 0, NULL,
                                       &options);
     if (kerr != 0) {
@@ -1329,6 +1338,7 @@ static int krb5_child_setup(struct krb5_req *kr, uint32_t offline)
     char *fast_principal = NULL;
     const char *fast_principal_realm = NULL;
     krb5_deltat lifetime;
+    int canonicalize = 0;
 
     kr->krb5_ctx = talloc_zero(kr, struct krb5_child_ctx);
     if (kr->krb5_ctx == NULL) {
@@ -1482,6 +1492,12 @@ static int krb5_child_setup(struct krb5_req *kr, uint32_t offline)
                 }
             }
 
+            tmp_str = getenv(SSSD_KRB5_CANONICALIZE);
+            if (tmp_str != NULL && strcasecmp(tmp_str, "true") == 0) {
+                canonicalize = 1;
+            }
+            krb5_get_init_creds_opt_set_canonicalize(kr->options, canonicalize);
+
             kerr = check_fast_ccache(kr->ctx, fast_principal, fast_principal_realm, kr->keytab,
                                      kr, &kr->fast_ccname);
             if (kerr != 0) {
diff --git a/src/providers/krb5/krb5_common.c b/src/providers/krb5/krb5_common.c
index 4e792861bdf9891628750ecee849d522cdf2b08e..4675e0a1f18a9608affaec5dfb5ce8a3f16e3011 100644
--- a/src/providers/krb5/krb5_common.c
+++ b/src/providers/krb5/krb5_common.c
@@ -45,7 +45,8 @@ struct dp_option default_krb5_opts[] = {
     { "krb5_lifetime", DP_OPT_STRING, NULL_STRING, NULL_STRING },
     { "krb5_renew_interval", DP_OPT_NUMBER, NULL_NUMBER, NULL_NUMBER },
     { "krb5_use_fast", DP_OPT_STRING, NULL_STRING, NULL_STRING },
-    { "krb5_fast_principal", DP_OPT_STRING, NULL_STRING, NULL_STRING }
+    { "krb5_fast_principal", DP_OPT_STRING, NULL_STRING, NULL_STRING },
+    { "krb5_canonicalize", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }
 };
 
 errno_t check_and_export_lifetime(struct dp_option *opts, const int opt_id,
@@ -169,6 +170,12 @@ errno_t check_and_export_options(struct dp_option *opts,
         }
     }
 
+    if (dp_opt_get_bool(opts, KRB5_CANONICALIZE)) {
+        setenv(SSSD_KRB5_CANONICALIZE, "true", 1);
+    } else {
+        setenv(SSSD_KRB5_CANONICALIZE, "false", 1);
+    }
+
     dummy = dp_opt_get_cstring(opts, KRB5_KDC);
     if (dummy == NULL) {
         DEBUG(1, ("No KDC explicitly configured, using defaults.\n"));
diff --git a/src/providers/krb5/krb5_common.h b/src/providers/krb5/krb5_common.h
index 670fd1a51d95f594ad9a57a20619898cb0ef38d0..950505f1208f164f9267aacbf49da136b3cc0073 100644
--- a/src/providers/krb5/krb5_common.h
+++ b/src/providers/krb5/krb5_common.h
@@ -39,6 +39,7 @@
 #define SSSD_KRB5_LIFETIME "SSSD_KRB5_LIFETIME"
 #define SSSD_KRB5_USE_FAST "SSSD_KRB5_USE_FAST"
 #define SSSD_KRB5_FAST_PRINCIPAL "SSSD_KRB5_FAST_PRINCIPAL"
+#define SSSD_KRB5_CANONICALIZE "SSSD_KRB5_CANONICALIZE"
 
 #define KDCINFO_TMPL PUBCONF_PATH"/kdcinfo.%s"
 #define KPASSWDINFO_TMPL PUBCONF_PATH"/kpasswdinfo.%s"
@@ -61,6 +62,7 @@ enum krb5_opts {
     KRB5_RENEW_INTERVAL,
     KRB5_USE_FAST,
     KRB5_FAST_PRINCIPAL,
+    KRB5_CANONICALIZE,
 
     KRB5_OPTS
 };
-- 
1.7.6.4

