Blob Blame History Raw
From bbe47ea8ebe6373d0b05181eb27bb65432a9cc97 Mon Sep 17 00:00:00 2001
From: Nathaniel McCallum <npmccallum@redhat.com>
Date: Fri, 7 Mar 2014 12:21:11 -0500
Subject: [PATCH 106/107] Fix krb5 changepw when FAST-only preauth methods are
 used (like OTP)

Before this patch, a different set of options was used when calling
krb5_get_init_creds_password() for the changepw principal. Because
this set of options did not contain the same FAST settings as the
options for normal requests, all authentication would fail when the
password of a FAST-only account would expire.

The two sets approach was cargo-cult from kinit where multiple
requests could be issued using the same options set. However, in the
case of krb5_child, only one request (or occasionally a well-defined
second request) will be issued. Two option sets are therefore not
required.

To fix this problem we removed the second option set used for changepw
requests. All requests now use a single option set which is modified,
if needed, for well-defined subsequent requests.

Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
Reviewed-by: Sumit Bose <sbose@redhat.com>
---
 src/providers/krb5/krb5_child.c | 40 ++++++----------------------------------
 1 file changed, 6 insertions(+), 34 deletions(-)

diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c
index aa29de0cb4e14ea4804ba660b4b8e9b64e9e340e..461a27464f4fea09d4ca430b53aff072b29de141 100644
--- a/src/providers/krb5/krb5_child.c
+++ b/src/providers/krb5/krb5_child.c
@@ -65,27 +65,14 @@ 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 get_changepw_options(krb5_context ctx,
-                                            krb5_get_init_creds_opt **_options)
+static void set_changepw_options(krb5_context ctx,
+                                 krb5_get_init_creds_opt *options)
 {
-    krb5_get_init_creds_opt *options;
-    krb5_error_code kerr;
-
-    kerr = sss_krb5_get_init_creds_opt_alloc(ctx, &options);
-    if (kerr != 0) {
-        KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
-        return kerr;
-    }
-
     sss_krb5_get_init_creds_opt_set_canonicalize(options, 0);
     krb5_get_init_creds_opt_set_forwardable(options, 0);
     krb5_get_init_creds_opt_set_proxiable(options, 0);
     krb5_get_init_creds_opt_set_renew_life(options, 0);
     krb5_get_init_creds_opt_set_tkt_life(options, 5*60);
-
-    *_options = options;
-
-    return 0;
 }
 
 static errno_t sss_send_pac(krb5_authdata **pac_authdata)
@@ -1023,7 +1010,6 @@ static errno_t changepw_child(struct krb5_req *kr, bool prelim)
     krb5_prompter_fct prompter = NULL;
     const char *realm_name;
     int realm_length;
-    krb5_get_init_creds_opt *chagepw_options;
     size_t msg_len;
     uint8_t *msg;
 
@@ -1041,12 +1027,7 @@ static errno_t changepw_child(struct krb5_req *kr, bool prelim)
         prompter = sss_krb5_prompter;
     }
 
-    kerr = get_changepw_options(kr->ctx, &chagepw_options);
-    if (kerr != 0) {
-        DEBUG(SSSDBG_OP_FAILURE, ("get_changepw_options failed.\n"));
-        return kerr;
-    }
-
+    set_changepw_options(kr->ctx, kr->options);
     sss_krb5_princ_realm(kr->ctx, kr->princ, &realm_name, &realm_length);
 
     DEBUG(SSSDBG_TRACE_FUNC,
@@ -1055,8 +1036,7 @@ static errno_t changepw_child(struct krb5_req *kr, bool prelim)
                                         discard_const(password),
                                         prompter, kr, 0,
                                         SSSD_KRB5_CHANGEPW_PRINCIPAL,
-                                        chagepw_options);
-    sss_krb5_get_init_creds_opt_free(kr->ctx, chagepw_options);
+                                        kr->options);
     if (kerr != 0) {
         ret = pack_user_info_chpass_error(kr->pd, "Old password not accepted.",
                                           &msg_len, &msg);
@@ -1164,7 +1144,6 @@ static errno_t changepw_child(struct krb5_req *kr, bool prelim)
 
 static errno_t tgt_req_child(struct krb5_req *kr)
 {
-    krb5_get_init_creds_opt *chagepw_options;
     const char *password = NULL;
     krb5_error_code kerr;
     int ret;
@@ -1210,19 +1189,12 @@ static errno_t tgt_req_child(struct krb5_req *kr)
         DEBUG(1, ("Failed to unset expire callback, continue ...\n"));
     }
 
-    kerr = get_changepw_options(kr->ctx, &chagepw_options);
-    if (kerr != 0) {
-        DEBUG(SSSDBG_OP_FAILURE, ("get_changepw_options failed.\n"));
-        return kerr;
-    }
-
+    set_changepw_options(kr->ctx, kr->options);
     kerr = krb5_get_init_creds_password(kr->ctx, kr->creds, kr->princ,
                                         discard_const(password),
                                         sss_krb5_prompter, kr, 0,
                                         SSSD_KRB5_CHANGEPW_PRINCIPAL,
-                                        chagepw_options);
-
-    sss_krb5_get_init_creds_opt_free(kr->ctx, chagepw_options);
+                                        kr->options);
 
     krb5_free_cred_contents(kr->ctx, kr->creds);
     if (kerr == 0) {
-- 
1.8.5.3