[SSSD] [PATCH] krb5-child: add revert_changepw_options()

Sumit Bose sbose at redhat.com
Fri Mar 21 15:40:22 UTC 2014


On Fri, Mar 21, 2014 at 02:22:47PM +0100, Sumit Bose wrote:
> Hi,
> 
> a recent patch unified the usage of the krb5_get_init_creds_opt options
> to make sure the same set of FAST related options are uses for
> authentication and password changes. Before changing the password some
> options were set to special values but were not reverted before
> requesting a new TGT with the new password. As a result the new TGT will
> have some unexpected options set or the request might even fail.
> 
> This patch set resets the password change related option to their
> original values before requesting the new TGT.
> 
> The first two patches are just refactorings which are required to keep
> the third patch simple.
> 
> bye,
> Sumit

On IRC Jakub pointed out that the lifetimes are not correctly reset if
not given explicitly. Additionally he asked to rename
krb5_set_canonicalize().

New versions attached. The rename of krb5_set_canonicalize() is now in a
separate patch.

bye,
Sumit
-------------- next part --------------
From 61ba904d9b3c276ea7c0f728f8538997e292960e Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Thu, 20 Mar 2014 18:39:48 +0100
Subject: [PATCH 1/4] krb5_child: remove unused option lifetime_str from
 k5c_setup_fast()

---
 src/providers/krb5/krb5_child.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c
index 1bff0e9..b10ec88 100644
--- a/src/providers/krb5/krb5_child.c
+++ b/src/providers/krb5/krb5_child.c
@@ -1678,7 +1678,7 @@ static errno_t k5c_recv_data(struct krb5_req *kr, int fd, uint32_t *offline)
     return ret;
 }
 
-static int k5c_setup_fast(struct krb5_req *kr, char *lifetime_str, bool demand)
+static int k5c_setup_fast(struct krb5_req *kr, bool demand)
 {
     krb5_principal fast_princ_struct;
     krb5_data *realm_data;
@@ -1687,9 +1687,6 @@ static int k5c_setup_fast(struct krb5_req *kr, char *lifetime_str, bool demand)
     krb5_error_code kerr;
     char *tmp_str;
 
-    DEBUG(SSSDBG_CONF_SETTINGS, "%s is set to [%s]\n",
-                                 SSSD_KRB5_LIFETIME, lifetime_str);
-
     tmp_str = getenv(SSSD_KRB5_FAST_PRINCIPAL);
     if (tmp_str) {
         DEBUG(SSSDBG_CONF_SETTINGS, "%s is set to [%s]\n",
@@ -1885,9 +1882,9 @@ static int k5c_setup(struct krb5_req *kr, uint32_t offline)
         if (use_fast_str == NULL || strcasecmp(use_fast_str, "never") == 0) {
             DEBUG(SSSDBG_CONF_SETTINGS, "Not using FAST.\n");
         } else if (strcasecmp(use_fast_str, "try") == 0) {
-            kerr = k5c_setup_fast(kr, lifetime_str, false);
+            kerr = k5c_setup_fast(kr, false);
         } else if (strcasecmp(use_fast_str, "demand") == 0) {
-            kerr = k5c_setup_fast(kr, lifetime_str, true);
+            kerr = k5c_setup_fast(kr, true);
         } else {
             DEBUG(SSSDBG_CRIT_FAILURE,
                   "Unsupported value [%s] for krb5_use_fast.\n",
-- 
1.8.3.1

-------------- next part --------------
From 39d44328ebbcffcda543dcd65d3c671502f689e9 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Fri, 21 Mar 2014 12:14:11 +0100
Subject: [PATCH 2/4] krb5-child: extract lifetime settings into
 set_lifetime_options()

Additionally the lifetime option flags are unset if there are no
explicit settings to make sure the defaults from krb5.conf are used even
if other values were set manually in between.
---
 src/providers/krb5/krb5_child.c | 91 +++++++++++++++++++++++++----------------
 1 file changed, 55 insertions(+), 36 deletions(-)

diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c
index b10ec88..7fc1122 100644
--- a/src/providers/krb5/krb5_child.c
+++ b/src/providers/krb5/krb5_child.c
@@ -65,6 +65,57 @@ struct krb5_req {
 static krb5_context krb5_error_ctx;
 #define KRB5_CHILD_DEBUG(level, error) KRB5_DEBUG(level, krb5_error_ctx, error)
 
+static krb5_error_code set_lifetime_options(krb5_get_init_creds_opt *options)
+{
+    char *lifetime_str;
+    krb5_error_code kerr;
+    krb5_deltat lifetime;
+
+    lifetime_str = getenv(SSSD_KRB5_RENEWABLE_LIFETIME);
+    if (lifetime_str == NULL) {
+        DEBUG(SSSDBG_CONF_SETTINGS, "Cannot read [%s] from environment.\n",
+              SSSD_KRB5_RENEWABLE_LIFETIME);
+
+        /* Unset option flag to make sure defaults from krb5.conf are used. */
+        options->flags &= ~(KRB5_GET_INIT_CREDS_OPT_RENEW_LIFE);
+    } else {
+        kerr = krb5_string_to_deltat(lifetime_str, &lifetime);
+        if (kerr != 0) {
+            DEBUG(SSSDBG_CRIT_FAILURE,
+                  "krb5_string_to_deltat failed for [%s].\n",
+                      lifetime_str);
+            KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
+            return kerr;
+        }
+        DEBUG(SSSDBG_CONF_SETTINGS, "%s is set to [%s]\n",
+              SSSD_KRB5_RENEWABLE_LIFETIME, lifetime_str);
+        krb5_get_init_creds_opt_set_renew_life(options, lifetime);
+    }
+
+    lifetime_str = getenv(SSSD_KRB5_LIFETIME);
+    if (lifetime_str == NULL) {
+        DEBUG(SSSDBG_CONF_SETTINGS, "Cannot read [%s] from environment.\n",
+              SSSD_KRB5_LIFETIME);
+
+        /* Unset option flag to make sure defaults from krb5.conf are used. */
+        options->flags &= ~(KRB5_GET_INIT_CREDS_OPT_TKT_LIFE);
+    } else {
+        kerr = krb5_string_to_deltat(lifetime_str, &lifetime);
+        if (kerr != 0) {
+            DEBUG(SSSDBG_CRIT_FAILURE,
+                  "krb5_string_to_deltat failed for [%s].\n",
+                      lifetime_str);
+            KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
+            return kerr;
+        }
+        DEBUG(SSSDBG_CONF_SETTINGS,
+              "%s is set to [%s]\n", SSSD_KRB5_LIFETIME, lifetime_str);
+        krb5_get_init_creds_opt_set_tkt_life(options, lifetime);
+    }
+
+    return 0;
+}
+
 static void set_changepw_options(krb5_context ctx,
                                  krb5_get_init_creds_opt *options)
 {
@@ -1758,9 +1809,7 @@ static int k5c_setup_fast(struct krb5_req *kr, bool demand)
 static int k5c_setup(struct krb5_req *kr, uint32_t offline)
 {
     krb5_error_code kerr;
-    char *lifetime_str;
     char *use_fast_str;
-    krb5_deltat lifetime;
     int parse_flags;
 
     kr->realm = getenv(SSSD_KRB5_REALM);
@@ -1839,40 +1888,10 @@ static int k5c_setup(struct krb5_req *kr, uint32_t offline)
     krb5_get_init_creds_opt_set_change_password_prompt(kr->options, 0);
 #endif
 
-    lifetime_str = getenv(SSSD_KRB5_RENEWABLE_LIFETIME);
-    if (lifetime_str == NULL) {
-        DEBUG(SSSDBG_CONF_SETTINGS, "Cannot read [%s] from environment.\n",
-              SSSD_KRB5_RENEWABLE_LIFETIME);
-    } else {
-        kerr = krb5_string_to_deltat(lifetime_str, &lifetime);
-        if (kerr != 0) {
-            DEBUG(SSSDBG_CRIT_FAILURE,
-                  "krb5_string_to_deltat failed for [%s].\n",
-                      lifetime_str);
-            KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
-            return kerr;
-        }
-        DEBUG(SSSDBG_CONF_SETTINGS, "%s is set to [%s]\n",
-              SSSD_KRB5_RENEWABLE_LIFETIME, lifetime_str);
-        krb5_get_init_creds_opt_set_renew_life(kr->options, lifetime);
-    }
-
-    lifetime_str = getenv(SSSD_KRB5_LIFETIME);
-    if (lifetime_str == NULL) {
-        DEBUG(SSSDBG_CONF_SETTINGS, "Cannot read [%s] from environment.\n",
-              SSSD_KRB5_LIFETIME);
-    } else {
-        kerr = krb5_string_to_deltat(lifetime_str, &lifetime);
-        if (kerr != 0) {
-            DEBUG(SSSDBG_CRIT_FAILURE,
-                  "krb5_string_to_deltat failed for [%s].\n",
-                      lifetime_str);
-            KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
-            return kerr;
-        }
-        DEBUG(SSSDBG_CONF_SETTINGS,
-              "%s is set to [%s]\n", SSSD_KRB5_LIFETIME, lifetime_str);
-        krb5_get_init_creds_opt_set_tkt_life(kr->options, lifetime);
+    kerr = set_lifetime_options(kr->options);
+    if (kerr != 0) {
+        DEBUG(SSSDBG_OP_FAILURE, ("set_lifetime_options failed.\n"));
+        return kerr;
     }
 
     if (!offline) {
-- 
1.8.3.1

-------------- next part --------------
From 4109efc61e2bbeae5fdf02ceaf62b80c0c9ae1d8 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Fri, 21 Mar 2014 16:15:39 +0100
Subject: [PATCH 3/4] krb5_client: rename krb5_set_canonicalize() to
 set_canonicalize_option()

---
 src/providers/krb5/krb5_child.c | 32 ++++++++++++++++----------------
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c
index 7fc1122..b37bbec 100644
--- a/src/providers/krb5/krb5_child.c
+++ b/src/providers/krb5/krb5_child.c
@@ -116,6 +116,20 @@ static krb5_error_code set_lifetime_options(krb5_get_init_creds_opt *options)
     return 0;
 }
 
+static void set_canonicalize_option(krb5_get_init_creds_opt *opts)
+{
+    int canonicalize = 0;
+    char *tmp_str;
+
+    tmp_str = getenv(SSSD_KRB5_CANONICALIZE);
+    if (tmp_str != NULL && strcasecmp(tmp_str, "true") == 0) {
+        canonicalize = 1;
+    }
+    DEBUG(SSSDBG_CONF_SETTINGS, "%s is set to [%s]\n",
+          SSSD_KRB5_CANONICALIZE, tmp_str ? tmp_str : "not set");
+    sss_krb5_get_init_creds_opt_set_canonicalize(opts, canonicalize);
+}
+
 static void set_changepw_options(krb5_context ctx,
                                  krb5_get_init_creds_opt *options)
 {
@@ -876,20 +890,6 @@ done:
 
 }
 
-static void krb5_set_canonicalize(krb5_get_init_creds_opt *opts)
-{
-    int canonicalize = 0;
-    char *tmp_str;
-
-    tmp_str = getenv(SSSD_KRB5_CANONICALIZE);
-    if (tmp_str != NULL && strcasecmp(tmp_str, "true") == 0) {
-        canonicalize = 1;
-    }
-    DEBUG(SSSDBG_CONF_SETTINGS, "%s is set to [%s]\n",
-          SSSD_KRB5_CANONICALIZE, tmp_str ? tmp_str : "not set");
-    sss_krb5_get_init_creds_opt_set_canonicalize(opts, canonicalize);
-}
-
 static krb5_error_code get_and_save_tgt_with_keytab(krb5_context ctx,
                                                     krb5_principal princ,
                                                     krb5_keytab keytab,
@@ -905,7 +905,7 @@ static krb5_error_code get_and_save_tgt_with_keytab(krb5_context ctx,
     krb5_get_init_creds_opt_set_address_list(&options, NULL);
     krb5_get_init_creds_opt_set_forwardable(&options, 0);
     krb5_get_init_creds_opt_set_proxiable(&options, 0);
-    krb5_set_canonicalize(&options);
+    set_canonicalize_option(&options);
 
     kerr = krb5_get_init_creds_keytab(ctx, &creds, princ, keytab, 0, NULL,
                                       &options);
@@ -1895,7 +1895,7 @@ static int k5c_setup(struct krb5_req *kr, uint32_t offline)
     }
 
     if (!offline) {
-        krb5_set_canonicalize(kr->options);
+        set_canonicalize_option(kr->options);
 
         use_fast_str = getenv(SSSD_KRB5_USE_FAST);
         if (use_fast_str == NULL || strcasecmp(use_fast_str, "never") == 0) {
-- 
1.8.3.1

-------------- next part --------------
From e9f6d41d6e0ad3a5124d4a3c1ea3fcd4d01ddf37 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Fri, 21 Mar 2014 16:16:23 +0100
Subject: [PATCH 4/4] krb5-child: add revert_changepw_options()

After changing the Kerberos password krb5-child will try to get a fresh
TGT with the new password. This patch tries to make sure the right gic
options are used.

Resolves: https://fedorahosted.org/sssd/ticket/2289
---
 src/providers/krb5/krb5_child.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c
index b37bbec..913d458 100644
--- a/src/providers/krb5/krb5_child.c
+++ b/src/providers/krb5/krb5_child.c
@@ -140,6 +140,24 @@ static void set_changepw_options(krb5_context ctx,
     krb5_get_init_creds_opt_set_tkt_life(options, 5*60);
 }
 
+static void revert_changepw_options(krb5_get_init_creds_opt *options)
+{
+    krb5_error_code kerr;
+
+    set_canonicalize_option(options);
+
+    /* Currently we do not set forwardable and proxiable explicitly, the flags
+     * must be removed so that libkrb5 can take the defaults from krb5.conf */
+    options->flags &= ~(KRB5_GET_INIT_CREDS_OPT_FORWARDABLE);
+    options->flags &= ~(KRB5_GET_INIT_CREDS_OPT_PROXIABLE);
+
+    kerr = set_lifetime_options(options);
+    if (kerr != 0) {
+        DEBUG(SSSDBG_OP_FAILURE, ("set_lifetime_options failed.\n"));
+    }
+}
+
+
 static errno_t sss_send_pac(krb5_authdata **pac_authdata)
 {
     struct sss_cli_req_data sss_data;
@@ -1196,6 +1214,10 @@ static errno_t changepw_child(struct krb5_req *kr, bool prelim)
 
     krb5_free_cred_contents(kr->ctx, kr->creds);
 
+    /* We changed some of the gic options for the password change, now we have
+     * to change them back to get a fresh TGT. */
+    revert_changepw_options(kr->options);
+
     kerr = get_and_save_tgt(kr, newpassword);
 
     sss_authtok_set_empty(kr->pd->newauthtok);
-- 
1.8.3.1

-------------- next part --------------
From 962d946a346b7fda5e19b924fc63c1a6753261c9 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Thu, 20 Mar 2014 18:39:48 +0100
Subject: [PATCH 1/4] krb5_child: remove unused option lifetime_str from
 k5c_setup_fast()

---
 src/providers/krb5/krb5_child.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c
index b268c86..6c38ec6 100644
--- a/src/providers/krb5/krb5_child.c
+++ b/src/providers/krb5/krb5_child.c
@@ -1667,7 +1667,7 @@ static errno_t k5c_recv_data(struct krb5_req *kr, int fd, uint32_t *offline)
     return ret;
 }
 
-static int k5c_setup_fast(struct krb5_req *kr, char *lifetime_str, bool demand)
+static int k5c_setup_fast(struct krb5_req *kr, bool demand)
 {
     krb5_principal fast_princ_struct;
     krb5_data *realm_data;
@@ -1676,9 +1676,6 @@ static int k5c_setup_fast(struct krb5_req *kr, char *lifetime_str, bool demand)
     krb5_error_code kerr;
     char *tmp_str;
 
-    DEBUG(SSSDBG_CONF_SETTINGS, ("%s is set to [%s]\n",
-                                 SSSD_KRB5_LIFETIME, lifetime_str));
-
     tmp_str = getenv(SSSD_KRB5_FAST_PRINCIPAL);
     if (tmp_str) {
         DEBUG(SSSDBG_CONF_SETTINGS, ("%s is set to [%s]\n",
@@ -1870,9 +1867,9 @@ static int k5c_setup(struct krb5_req *kr, uint32_t offline)
         if (use_fast_str == NULL || strcasecmp(use_fast_str, "never") == 0) {
             DEBUG(SSSDBG_CONF_SETTINGS, ("Not using FAST.\n"));
         } else if (strcasecmp(use_fast_str, "try") == 0) {
-            kerr = k5c_setup_fast(kr, lifetime_str, false);
+            kerr = k5c_setup_fast(kr, false);
         } else if (strcasecmp(use_fast_str, "demand") == 0) {
-            kerr = k5c_setup_fast(kr, lifetime_str, true);
+            kerr = k5c_setup_fast(kr, true);
         } else {
             DEBUG(SSSDBG_CRIT_FAILURE,
                   ("Unsupported value [%s] for krb5_use_fast.\n",
-- 
1.8.3.1

-------------- next part --------------
From 147b18f13c864154cf1547e36e655298fb301f77 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Fri, 21 Mar 2014 12:14:11 +0100
Subject: [PATCH 2/4] krb5-child: extract lifetime settings into
 set_lifetime_options()

Additionally the lifetime option flags are unset if there are no
explicit settings to make sure the defaults from krb5.conf are used even
if other values were set manually in between.
---
 src/providers/krb5/krb5_child.c | 89 +++++++++++++++++++++++++----------------
 1 file changed, 55 insertions(+), 34 deletions(-)

diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c
index 6c38ec6..a99c42f 100644
--- a/src/providers/krb5/krb5_child.c
+++ b/src/providers/krb5/krb5_child.c
@@ -65,6 +65,57 @@ struct krb5_req {
 static krb5_context krb5_error_ctx;
 #define KRB5_CHILD_DEBUG(level, error) KRB5_DEBUG(level, krb5_error_ctx, error)
 
+static krb5_error_code set_lifetime_options(krb5_get_init_creds_opt *options)
+{
+    char *lifetime_str;
+    krb5_error_code kerr;
+    krb5_deltat lifetime;
+
+    lifetime_str = getenv(SSSD_KRB5_RENEWABLE_LIFETIME);
+    if (lifetime_str == NULL) {
+        DEBUG(SSSDBG_CONF_SETTINGS, ("Cannot read [%s] from environment.\n",
+              SSSD_KRB5_RENEWABLE_LIFETIME));
+
+        /* Unset option flag to make sure defaults from krb5.conf are used. */
+        options->flags &= ~(KRB5_GET_INIT_CREDS_OPT_RENEW_LIFE);
+    } else {
+        kerr = krb5_string_to_deltat(lifetime_str, &lifetime);
+        if (kerr != 0) {
+            DEBUG(SSSDBG_CRIT_FAILURE,
+                  ("krb5_string_to_deltat failed for [%s].\n",
+                      lifetime_str));
+            KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
+            return kerr;
+        }
+        DEBUG(SSSDBG_CONF_SETTINGS, ("%s is set to [%s]\n",
+              SSSD_KRB5_RENEWABLE_LIFETIME, lifetime_str));
+        krb5_get_init_creds_opt_set_renew_life(options, lifetime);
+    }
+
+    lifetime_str = getenv(SSSD_KRB5_LIFETIME);
+    if (lifetime_str == NULL) {
+        DEBUG(SSSDBG_CONF_SETTINGS, ("Cannot read [%s] from environment.\n",
+              SSSD_KRB5_LIFETIME));
+
+        /* Unset option flag to make sure defaults from krb5.conf are used. */
+        options->flags &= ~(KRB5_GET_INIT_CREDS_OPT_TKT_LIFE);
+    } else {
+        kerr = krb5_string_to_deltat(lifetime_str, &lifetime);
+        if (kerr != 0) {
+            DEBUG(SSSDBG_CRIT_FAILURE,
+                  ("krb5_string_to_deltat failed for [%s].\n",
+                      lifetime_str));
+            KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
+            return kerr;
+        }
+        DEBUG(SSSDBG_CONF_SETTINGS,
+              ("%s is set to [%s]\n", SSSD_KRB5_LIFETIME, lifetime_str));
+        krb5_get_init_creds_opt_set_tkt_life(options, lifetime);
+    }
+
+    return 0;
+}
+
 static void set_changepw_options(krb5_context ctx,
                                  krb5_get_init_creds_opt *options)
 {
@@ -1745,9 +1796,7 @@ static int k5c_setup_fast(struct krb5_req *kr, bool demand)
 static int k5c_setup(struct krb5_req *kr, uint32_t offline)
 {
     krb5_error_code kerr;
-    char *lifetime_str;
     char *use_fast_str;
-    krb5_deltat lifetime;
     int parse_flags;
 
     kr->realm = getenv(SSSD_KRB5_REALM);
@@ -1826,38 +1875,10 @@ static int k5c_setup(struct krb5_req *kr, uint32_t offline)
     krb5_get_init_creds_opt_set_change_password_prompt(kr->options, 0);
 #endif
 
-    lifetime_str = getenv(SSSD_KRB5_RENEWABLE_LIFETIME);
-    if (lifetime_str == NULL) {
-        DEBUG(SSSDBG_CONF_SETTINGS, ("Cannot read [%s] from environment.\n",
-              SSSD_KRB5_RENEWABLE_LIFETIME));
-    } else {
-        kerr = krb5_string_to_deltat(lifetime_str, &lifetime);
-        if (kerr != 0) {
-            DEBUG(1, ("krb5_string_to_deltat failed for [%s].\n",
-                      lifetime_str));
-            KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
-            return kerr;
-        }
-        DEBUG(SSSDBG_CONF_SETTINGS, ("%s is set to [%s]\n",
-              SSSD_KRB5_RENEWABLE_LIFETIME, lifetime_str));
-        krb5_get_init_creds_opt_set_renew_life(kr->options, lifetime);
-    }
-
-    lifetime_str = getenv(SSSD_KRB5_LIFETIME);
-    if (lifetime_str == NULL) {
-        DEBUG(SSSDBG_CONF_SETTINGS, ("Cannot read [%s] from environment.\n",
-              SSSD_KRB5_LIFETIME));
-    } else {
-        kerr = krb5_string_to_deltat(lifetime_str, &lifetime);
-        if (kerr != 0) {
-            DEBUG(1, ("krb5_string_to_deltat failed for [%s].\n",
-                      lifetime_str));
-            KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
-            return kerr;
-        }
-        DEBUG(SSSDBG_CONF_SETTINGS,
-              ("%s is set to [%s]\n", SSSD_KRB5_LIFETIME, lifetime_str));
-        krb5_get_init_creds_opt_set_tkt_life(kr->options, lifetime);
+    kerr = set_lifetime_options(kr->options);
+    if (kerr != 0) {
+        DEBUG(SSSDBG_OP_FAILURE, ("set_lifetime_options failed.\n"));
+        return kerr;
     }
 
     if (!offline) {
-- 
1.8.3.1

-------------- next part --------------
From d648811e252a08996162deb9b9b3a31a5188a07a Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Fri, 21 Mar 2014 16:15:39 +0100
Subject: [PATCH 3/4] krb5_client: rename krb5_set_canonicalize() to
 set_canonicalize_option()

---
 src/providers/krb5/krb5_child.c | 32 ++++++++++++++++----------------
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c
index a99c42f..6157e4e 100644
--- a/src/providers/krb5/krb5_child.c
+++ b/src/providers/krb5/krb5_child.c
@@ -116,6 +116,20 @@ static krb5_error_code set_lifetime_options(krb5_get_init_creds_opt *options)
     return 0;
 }
 
+static void set_canonicalize_option(krb5_get_init_creds_opt *opts)
+{
+    int canonicalize = 0;
+    char *tmp_str;
+
+    tmp_str = getenv(SSSD_KRB5_CANONICALIZE);
+    if (tmp_str != NULL && strcasecmp(tmp_str, "true") == 0) {
+        canonicalize = 1;
+    }
+    DEBUG(SSSDBG_CONF_SETTINGS, ("%s is set to [%s]\n",
+          SSSD_KRB5_CANONICALIZE, tmp_str ? tmp_str : "not set"));
+    sss_krb5_get_init_creds_opt_set_canonicalize(opts, canonicalize);
+}
+
 static void set_changepw_options(krb5_context ctx,
                                  krb5_get_init_creds_opt *options)
 {
@@ -875,20 +889,6 @@ done:
 
 }
 
-static void krb5_set_canonicalize(krb5_get_init_creds_opt *opts)
-{
-    int canonicalize = 0;
-    char *tmp_str;
-
-    tmp_str = getenv(SSSD_KRB5_CANONICALIZE);
-    if (tmp_str != NULL && strcasecmp(tmp_str, "true") == 0) {
-        canonicalize = 1;
-    }
-    DEBUG(SSSDBG_CONF_SETTINGS, ("%s is set to [%s]\n",
-          SSSD_KRB5_CANONICALIZE, tmp_str ? tmp_str : "not set"));
-    sss_krb5_get_init_creds_opt_set_canonicalize(opts, canonicalize);
-}
-
 static krb5_error_code get_and_save_tgt_with_keytab(krb5_context ctx,
                                                     krb5_principal princ,
                                                     krb5_keytab keytab,
@@ -904,7 +904,7 @@ static krb5_error_code get_and_save_tgt_with_keytab(krb5_context ctx,
     krb5_get_init_creds_opt_set_address_list(&options, NULL);
     krb5_get_init_creds_opt_set_forwardable(&options, 0);
     krb5_get_init_creds_opt_set_proxiable(&options, 0);
-    krb5_set_canonicalize(&options);
+    set_canonicalize_option(&options);
 
     kerr = krb5_get_init_creds_keytab(ctx, &creds, princ, keytab, 0, NULL,
                                       &options);
@@ -1882,7 +1882,7 @@ static int k5c_setup(struct krb5_req *kr, uint32_t offline)
     }
 
     if (!offline) {
-        krb5_set_canonicalize(kr->options);
+        set_canonicalize_option(kr->options);
 
         use_fast_str = getenv(SSSD_KRB5_USE_FAST);
         if (use_fast_str == NULL || strcasecmp(use_fast_str, "never") == 0) {
-- 
1.8.3.1

-------------- next part --------------
From 146e5326118391f2f3096e2346f38b9e076d5ef6 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Fri, 21 Mar 2014 16:16:23 +0100
Subject: [PATCH 4/4] krb5-child: add revert_changepw_options()

After changing the Kerberos password krb5-child will try to get a fresh
TGT with the new password. This patch tries to make sure the right gic
options are used.

Resolves: https://fedorahosted.org/sssd/ticket/2289
---
 src/providers/krb5/krb5_child.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c
index 6157e4e..d000d70 100644
--- a/src/providers/krb5/krb5_child.c
+++ b/src/providers/krb5/krb5_child.c
@@ -140,6 +140,24 @@ static void set_changepw_options(krb5_context ctx,
     krb5_get_init_creds_opt_set_tkt_life(options, 5*60);
 }
 
+static void revert_changepw_options(krb5_get_init_creds_opt *options)
+{
+    krb5_error_code kerr;
+
+    set_canonicalize_option(options);
+
+    /* Currently we do not set forwardable and proxiable explicitly, the flags
+     * must be removed so that libkrb5 can take the defaults from krb5.conf */
+    options->flags &= ~(KRB5_GET_INIT_CREDS_OPT_FORWARDABLE);
+    options->flags &= ~(KRB5_GET_INIT_CREDS_OPT_PROXIABLE);
+
+    kerr = set_lifetime_options(options);
+    if (kerr != 0) {
+        DEBUG(SSSDBG_OP_FAILURE, ("set_lifetime_options failed.\n"));
+    }
+}
+
+
 static errno_t sss_send_pac(krb5_authdata **pac_authdata)
 {
     struct sss_cli_req_data sss_data;
@@ -1187,6 +1205,10 @@ static errno_t changepw_child(struct krb5_req *kr, bool prelim)
 
     krb5_free_cred_contents(kr->ctx, kr->creds);
 
+    /* We changed some of the gic options for the password change, now we have
+     * to change them back to get a fresh TGT. */
+    revert_changepw_options(kr->options);
+
     kerr = get_and_save_tgt(kr, newpassword);
 
     sss_authtok_set_empty(kr->pd->newauthtok);
-- 
1.8.3.1



More information about the sssd-devel mailing list