diff options
author | Nathaniel McCallum <npmccallum@redhat.com> | 2014-03-04 11:22:42 -0500 |
---|---|---|
committer | Nathaniel McCallum <npmccallum@redhat.com> | 2014-03-04 11:22:42 -0500 |
commit | 44d0e80df02d95d527de7eed367d4eb2fa320434 (patch) | |
tree | bc383119d49b86eec22fb820a0065cae9ceb98cb | |
parent | 2550f0f56b0721d1433f1b178c12f058b2a42506 (diff) | |
download | krb5-44d0e80df02d95d527de7eed367d4eb2fa320434.tar.gz krb5-44d0e80df02d95d527de7eed367d4eb2fa320434.tar.xz krb5-44d0e80df02d95d527de7eed367d4eb2fa320434.zip |
Backport fix for change password requests when using FAST (RT#7868)
-rw-r--r-- | krb5-1.12-pwdch-fast.patch | 176 | ||||
-rw-r--r-- | krb5.spec | 8 |
2 files changed, 183 insertions, 1 deletions
diff --git a/krb5-1.12-pwdch-fast.patch b/krb5-1.12-pwdch-fast.patch new file mode 100644 index 0000000..3b7d4bb --- /dev/null +++ b/krb5-1.12-pwdch-fast.patch @@ -0,0 +1,176 @@ +From 230858394d2dded001ef3d2029daa6c468aca097 Mon Sep 17 00:00:00 2001 +From: Greg Hudson <ghudson@mit.edu> +Date: Fri, 28 Feb 2014 14:49:35 -0500 +Subject: [PATCH] Use preauth options when changing password + +If we try to change the password in rb5_get_init_creds_password, we +must use all application-specified gic options which affect +preauthentication when getting the kadmin/changepw ticket. Create a +helper function make_chpw_options which copies the application's +options, unsets the options we don't want, and sets options +appropriate for a temporary ticket. + +ticket: 7868 + +npmccallum: + * include tests from 06817686bfdef99523f300464bcbb0c8b037a27d +--- + src/lib/krb5/krb/gic_pwd.c | 63 +++++++++++++++++++++++++++++++++++++--------- + src/tests/Makefile.in | 1 + + src/tests/t_changepw.py | 37 +++++++++++++++++++++++++++ + 3 files changed, 89 insertions(+), 12 deletions(-) + create mode 100644 src/tests/t_changepw.py + +diff --git a/src/lib/krb5/krb/gic_pwd.c b/src/lib/krb5/krb/gic_pwd.c +index a97823f6b51b7393755e82f36612c30b64096754..6aec7c3a71f99d2194b09374b296327174e6d4b8 100644 +--- a/src/lib/krb5/krb/gic_pwd.c ++++ b/src/lib/krb5/krb/gic_pwd.c +@@ -242,6 +242,54 @@ warn_pw_expiry(krb5_context context, krb5_get_init_creds_opt *options, + (*prompter)(context, data, 0, banner, 0, 0); + } + ++/* ++ * Create a temporary options structure for getting a kadmin/changepw ticket, ++ * based on the appplication-specified options. Propagate all application ++ * options which affect preauthentication, but not options which affect the ++ * resulting ticket or how it is stored. Set lifetime and flags appropriate ++ * for a ticket which we will use immediately and then discard. ++ * ++ * storage1 and storage2 will be used to hold the temporary options. The ++ * caller must not free the result, as it will contain aliases into the ++ * application options. ++ */ ++static krb5_get_init_creds_opt * ++make_chpw_options(krb5_get_init_creds_opt *in, krb5_gic_opt_ext *storage1, ++ gic_opt_private *storage2) ++{ ++ krb5_gic_opt_ext *in_ext; ++ krb5_get_init_creds_opt *opt; ++ ++ /* Copy the application's options to storage. */ ++ if (in == NULL) { ++ storage1->flags = 0; ++ } else if (gic_opt_is_extended(in)) { ++ in_ext = (krb5_gic_opt_ext *)in; ++ *storage1 = *in_ext; ++ *storage2 = *in_ext->opt_private; ++ storage1->opt_private = storage2; ++ } else { ++ *(krb5_get_init_creds_opt *)storage1 = *in; ++ } ++ ++ /* Get a non-forwardable, non-proxiable, short-lifetime ticket. */ ++ opt = (krb5_get_init_creds_opt *)storage1; ++ krb5_get_init_creds_opt_set_tkt_life(opt, 5 * 60); ++ krb5_get_init_creds_opt_set_renew_life(opt, 0); ++ krb5_get_init_creds_opt_set_forwardable(opt, 0); ++ krb5_get_init_creds_opt_set_proxiable(opt, 0); ++ ++ /* Unset options which should only apply to the actual ticket. */ ++ opt->flags &= ~KRB5_GET_INIT_CREDS_OPT_ADDRESS_LIST; ++ opt->flags &= ~KRB5_GET_INIT_CREDS_OPT_ANONYMOUS; ++ ++ /* The output ccache should only be used for the actual ticket. */ ++ if (gic_opt_is_extended(opt)) ++ storage2->out_ccache = NULL; ++ ++ return opt; ++} ++ + krb5_error_code KRB5_CALLCONV + krb5_get_init_creds_password(krb5_context context, + krb5_creds *creds, +@@ -259,6 +307,8 @@ krb5_get_init_creds_password(krb5_context context, + int tries; + krb5_creds chpw_creds; + krb5_get_init_creds_opt *chpw_opts = NULL; ++ krb5_gic_opt_ext storage1; ++ gic_opt_private storage2; + struct gak_password gakpw; + krb5_data pw0, pw1; + char banner[1024], pw0array[1024], pw1array[1024]; +@@ -345,16 +395,7 @@ krb5_get_init_creds_password(krb5_context context, + /* ok, we have an expired password. Give the user a few chances + to change it */ + +- /* use a minimal set of options */ +- +- ret = krb5_get_init_creds_opt_alloc(context, &chpw_opts); +- if (ret) +- goto cleanup; +- krb5_get_init_creds_opt_set_tkt_life(chpw_opts, 5*60); +- krb5_get_init_creds_opt_set_renew_life(chpw_opts, 0); +- krb5_get_init_creds_opt_set_forwardable(chpw_opts, 0); +- krb5_get_init_creds_opt_set_proxiable(chpw_opts, 0); +- ++ chpw_opts = make_chpw_options(options, &storage1, &storage2); + ret = k5_get_init_creds(context, &chpw_creds, client, prompter, data, + start_time, "kadmin/changepw", chpw_opts, + krb5_get_as_key_password, &gakpw, &use_master, +@@ -471,8 +512,6 @@ cleanup: + warn_pw_expiry(context, options, prompter, data, in_tkt_service, + as_reply); + +- if (chpw_opts) +- krb5_get_init_creds_opt_free(context, chpw_opts); + zapfree(gakpw.storage.data, gakpw.storage.length); + memset(pw0array, 0, sizeof(pw0array)); + memset(pw1array, 0, sizeof(pw1array)); +diff --git a/src/tests/Makefile.in b/src/tests/Makefile.in +index 62523895d53da24844141a6ada6cab23e77dd9e6..55f1d6419f8d924a6f9a2971d36f1eac6d293d32 100644 +--- a/src/tests/Makefile.in ++++ b/src/tests/Makefile.in +@@ -94,6 +94,7 @@ check-pytests:: t_init_creds t_localauth + $(RUNPYTEST) $(srcdir)/t_iprop.py $(PYTESTFLAGS) + $(RUNPYTEST) $(srcdir)/t_kprop.py $(PYTESTFLAGS) + $(RUNPYTEST) $(srcdir)/t_policy.py $(PYTESTFLAGS) ++ $(RUNPYTEST) $(srcdir)/t_changepw.py $(PYTESTFLAGS) + $(RUNPYTEST) $(srcdir)/t_pkinit.py $(PYTESTFLAGS) + $(RUNPYTEST) $(srcdir)/t_otp.py $(PYTESTFLAGS) + $(RUNPYTEST) $(srcdir)/t_localauth.py $(PYTESTFLAGS) +diff --git a/src/tests/t_changepw.py b/src/tests/t_changepw.py +new file mode 100644 +index 0000000000000000000000000000000000000000..0b9832668e618b3db8d88cf388ec918898bb4df3 +--- /dev/null ++++ b/src/tests/t_changepw.py +@@ -0,0 +1,37 @@ ++#!/usr/bin/python ++from k5test import * ++ ++# This file is intended to cover any password-changing mechanism. For ++# now it only contains a regression test for #7868. ++ ++realm = K5Realm(create_host=False, get_creds=False, start_kadmind=True) ++ ++# Mark a principal as expired and change its password through kinit. ++realm.run_kadminl('modprinc -pwexpire "1 day ago" user') ++pwinput = password('user') + '\nabcd\nabcd\n' ++realm.run([kinit, realm.user_princ], input=pwinput) ++ ++# Do the same thing with FAST, with tracing turned on. ++realm.run_kadminl('modprinc -pwexpire "1 day ago" user') ++pwinput = 'abcd\nefgh\nefgh\n' ++tracefile = os.path.join(realm.testdir, 'trace') ++realm.run(['env', 'KRB5_TRACE=' + tracefile, kinit, '-T', realm.ccache, ++ realm.user_princ], input=pwinput) ++ ++# Read the trace and check that FAST was used when getting the ++# kadmin/changepw ticket. ++f = open(tracefile, 'r') ++trace = f.read() ++f.close() ++getting_changepw = fast_used_for_changepw = False ++for line in trace.splitlines(): ++ if 'Getting initial credentials for user@' in line: ++ getting_changepw_ticket = False ++ if 'Setting initial creds service to kadmin/changepw' in line: ++ getting_changepw_ticket = True ++ if getting_changepw_ticket and 'Using FAST' in line: ++ fast_used_for_changepw = True ++if not fast_used_for_changepw: ++ fail('FAST was not used to get kadmin/changepw ticket') ++ ++success('Password change tests') +-- +1.8.5.3 + @@ -41,7 +41,7 @@ Summary: The Kerberos network authentication system Name: krb5 Version: 1.12.1 -Release: 5%{?dist} +Release: 6%{?dist} # Maybe we should explode from the now-available-to-everybody tarball instead? # http://web.mit.edu/kerberos/dist/krb5/1.12/krb5-1.12.1-signed.tar Source0: krb5-%{version}.tar.gz @@ -76,6 +76,7 @@ Source100: nss_wrapper-0.0-20140204195100.git3d58327.tar.xz Source101: noport.c Source102: socket_wrapper-0.0-20140204194748.gitf3b2ece.tar.xz +Patch1: krb5-1.12-pwdch-fast.patch Patch6: krb5-1.12-ksu-path.patch Patch12: krb5-1.12-ktany.patch Patch16: krb5-1.12-buildconf.patch @@ -309,6 +310,8 @@ certificate. %setup -q -a 3 -a 100 -a 102 ln -s NOTICE LICENSE +%patch1 -p1 -b .pwdch-fast + %patch201 -p1 -b .Don-t-try-to-stat-not-on-disk-ccache-residuals %patch202 -p1 -b .Use-an-in-memory-cache-until-we-need-the-target-s %patch203 -p1 -b .Learn-to-destroy-the-ccache-we-re-copying-from @@ -1018,6 +1021,9 @@ exit 0 %{_sbindir}/uuserver %changelog +* Tue Mar 04 2014 Nathaniel McCallum <npmccallum@redhat.com> - 1.12.1-6 +- Backport fix for change password requests when using FAST (RT#7868) + * Mon Feb 17 2014 Nalin Dahyabhai <nalin@redhat.com> - 1.12.1-5 - spnego: pull in patch from master to restore preserving the OID of the mechanism the initiator requested when we have multiple OIDs for the same |