Backport fix for change password requests when using FAST (RT#7868)
This commit is contained in:
parent
2550f0f56b
commit
44d0e80df0
176
krb5-1.12-pwdch-fast.patch
Normal file
176
krb5-1.12-pwdch-fast.patch
Normal file
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user