diff --git a/Use-fallback-realm-for-GSSAPI-ccache-selection.patch b/Use-fallback-realm-for-GSSAPI-ccache-selection.patch new file mode 100644 index 0000000..fef1817 --- /dev/null +++ b/Use-fallback-realm-for-GSSAPI-ccache-selection.patch @@ -0,0 +1,188 @@ +From d903c706a378c521ae38d57d95e43fb10469b03f Mon Sep 17 00:00:00 2001 +From: Matt Rogers +Date: Fri, 10 Feb 2017 12:53:42 -0500 +Subject: [PATCH] Use fallback realm for GSSAPI ccache selection + +In krb5_cc_select(), if the server principal has an empty realm, use +krb5_get_fallback_host_realm() and set the server realm to the first +fallback found. This helps with the selection of a non-default ccache +when there is no [domain_realms] configuration for the server domain. +Modify t_ccselect.py tests to account for fallback behavior. + +ticket: 8549 (new) +(cherry picked from commit 234b64bd6139d5b75dadd5abbd5bef5a162e298a) +[rharwood@redhat.com conflicts t_ccselect.py] +--- + src/lib/krb5/ccache/ccselect.c | 37 +++++++++++++++++++++++++----- + src/tests/gssapi/t_ccselect.py | 51 +++++++++++++++++++++++++++++++++--------- + 2 files changed, 73 insertions(+), 15 deletions(-) + +diff --git a/src/lib/krb5/ccache/ccselect.c b/src/lib/krb5/ccache/ccselect.c +index 2f3071a27..ee4b83a9b 100644 +--- a/src/lib/krb5/ccache/ccselect.c ++++ b/src/lib/krb5/ccache/ccselect.c +@@ -132,6 +132,8 @@ krb5_cc_select(krb5_context context, krb5_principal server, + struct ccselect_module_handle **hp, *h; + krb5_ccache cache; + krb5_principal princ; ++ krb5_principal srvcp = NULL; ++ char **fbrealms = NULL; + + *cache_out = NULL; + *princ_out = NULL; +@@ -139,7 +141,27 @@ krb5_cc_select(krb5_context context, krb5_principal server, + if (context->ccselect_handles == NULL) { + ret = load_modules(context); + if (ret) +- return ret; ++ goto cleanup; ++ } ++ ++ /* Try to use the fallback host realm for the server if there is no ++ * authoritative realm. */ ++ if (krb5_is_referral_realm(&server->realm) && ++ server->type == KRB5_NT_SRV_HST && server->length == 2) { ++ ret = krb5_get_fallback_host_realm(context, &server->data[1], ++ &fbrealms); ++ if (ret) ++ goto cleanup; ++ ++ /* Make a copy with the first fallback realm. */ ++ ret = krb5_copy_principal(context, server, &srvcp); ++ if (ret) ++ goto cleanup; ++ ret = krb5_set_principal_realm(context, srvcp, fbrealms[0]); ++ if (ret) ++ goto cleanup; ++ ++ server = srvcp; + } + + /* Consult authoritative modules first, then heuristic ones. */ +@@ -155,20 +177,25 @@ krb5_cc_select(krb5_context context, krb5_principal server, + princ); + *cache_out = cache; + *princ_out = princ; +- return 0; ++ goto cleanup; + } else if (ret == KRB5_CC_NOTFOUND) { + TRACE_CCSELECT_MODNOTFOUND(context, h->vt.name, server, princ); + *princ_out = princ; +- return ret; ++ goto cleanup; + } else if (ret != KRB5_PLUGIN_NO_HANDLE) { + TRACE_CCSELECT_MODFAIL(context, h->vt.name, ret, server); +- return ret; ++ goto cleanup; + } + } + } + + TRACE_CCSELECT_NOTFOUND(context, server); +- return KRB5_CC_NOTFOUND; ++ ret = KRB5_CC_NOTFOUND; ++ ++cleanup: ++ krb5_free_principal(context, srvcp); ++ krb5_free_host_realm(context, fbrealms); ++ return ret; + } + + void +diff --git a/src/tests/gssapi/t_ccselect.py b/src/tests/gssapi/t_ccselect.py +index 6be6b4ec0..c6201ca41 100755 +--- a/src/tests/gssapi/t_ccselect.py ++++ b/src/tests/gssapi/t_ccselect.py +@@ -31,12 +31,18 @@ r2 = K5Realm(create_user=False, realm='KRBTEST2.COM', portbase=62000, + + host1 = 'p:' + r1.host_princ + host2 = 'p:' + r2.host_princ ++foo = 'foo.krbtest.com' ++foo2 = 'foo.krbtest2.com' + +-# gsserver specifies the target as a GSS name. The resulting +-# principal will have the host-based type, but the realm won't be +-# known before the client cache is selected (since k5test realms have +-# no domain-realm mapping by default). +-gssserver = 'h:host@' + hostname ++# These strings specify the target as a GSS name. The resulting ++# principal will have the host-based type, with the referral realm ++# (since k5test realms have no domain-realm mapping by default). ++# krb5_cc_select() will use the fallback realm, which is either the ++# uppercased parent domain, or the default realm if the hostname is a ++# single component. ++gssserver = 'h:host@' + foo ++gssserver2 = 'h:host@' + foo2 ++gsslocal = 'h:host@localhost' + + # refserver specifies the target as a principal in the referral realm. + # The principal won't be treated as a host principal by the +@@ -67,6 +73,16 @@ r1.addprinc(alice, password('alice')) + r1.addprinc(bob, password('bob')) + r2.addprinc(zaphod, password('zaphod')) + ++# Create host principals and keytabs for fallback realm tests. ++r1.addprinc('host/localhost') ++r2.addprinc('host/localhost') ++r1.addprinc('host/' + foo) ++r2.addprinc('host/' + foo2) ++r1.extract_keytab('host/localhost', r1.keytab) ++r2.extract_keytab('host/localhost', r2.keytab) ++r1.extract_keytab('host/' + foo, r1.keytab) ++r2.extract_keytab('host/' + foo2, r2.keytab) ++ + # Get tickets for one user in each realm (zaphod will be primary). + r1.kinit(alice, password('alice')) + r2.kinit(zaphod, password('zaphod')) +@@ -94,10 +110,24 @@ if output != (zaphod + '\n'): + fail('zaphod not chosen as default initiator name for server in r1') + + # Check that primary cache is used if server realm is unknown. +-output = r2.run(['./t_ccselect', gssserver]) ++output = r2.run(['./t_ccselect', refserver]) + if output != (zaphod + '\n'): + fail('zaphod not chosen via primary cache for unknown server realm') +-r1.run(['./t_ccselect', gssserver], expected_code=1) ++r1.run(['./t_ccselect', gssserver2], expected_code=1) ++# Check ccache selection using a fallback realm. ++output = r1.run(['./t_ccselect', gssserver]) ++if output != (alice + '\n'): ++ fail('alice not chosen via parent domain fallback') ++output = r2.run(['./t_ccselect', gssserver2]) ++if output != (zaphod + '\n'): ++ fail('zaphod not chosen via parent domain fallback') ++# Check ccache selection using a fallback realm (default realm). ++output = r1.run(['./t_ccselect', gsslocal]) ++if output != (alice + '\n'): ++ fail('alice not chosen via default realm fallback') ++output = r2.run(['./t_ccselect', gsslocal]) ++if output != (zaphod + '\n'): ++ fail('zaphod not chosen via default realm fallback') + + # Get a second cred in r1 (bob will be primary). + r1.kinit(bob, password('bob')) +@@ -105,20 +135,21 @@ r1.kinit(bob, password('bob')) + # Try some cache selections using .k5identity. + k5id = open(os.path.join(r1.testdir, '.k5identity'), 'w') + k5id.write('%s realm=%s\n' % (alice, r1.realm)) +-k5id.write('%s service=ho*t host=%s\n' % (zaphod, hostname)) ++k5id.write('%s service=ho*t host=localhost\n' % zaphod) + k5id.write('noprinc service=bogus') + k5id.close() + output = r1.run(['./t_ccselect', host1]) + if output != (alice + '\n'): + fail('alice not chosen via .k5identity realm line.') +-output = r2.run(['./t_ccselect', gssserver]) ++output = r2.run(['./t_ccselect', gsslocal]) + if output != (zaphod + '\n'): + fail('zaphod not chosen via .k5identity service/host line.') + output = r1.run(['./t_ccselect', refserver]) + if output != (bob + '\n'): + fail('bob not chosen via primary cache when no .k5identity line matches.') +-output = r1.run(['./t_ccselect', 'h:bogus@' + hostname], expected_code=1) + if 'Can\'t find client principal noprinc' not in output: + fail('Expected error not seen when k5identity selects bad principal.') ++r1.run(['./t_ccselect', 'h:bogus@' + foo2], expected_code=1, ++ expected_msg="Can't find client principal noprinc") + + success('GSSAPI credential selection tests') diff --git a/krb5.spec b/krb5.spec index d5294ff..65a9caf 100644 --- a/krb5.spec +++ b/krb5.spec @@ -13,7 +13,7 @@ Summary: The Kerberos network authentication system Name: krb5 Version: 1.14.4 -Release: 4%{?dist} +Release: 5%{?dist} # - Maybe we should explode from the now-available-to-everybody tarball instead? # http://web.mit.edu/kerberos/dist/krb5/1.13/krb5-1.13.2-signed.tar # - The sources below are stored in a lookaside cache. Upload with @@ -56,18 +56,7 @@ Patch8: krb5-1.13-dirsrv-accountlock.patch Patch9: krb5-1.9-debuginfo.patch Patch10: krb5-1.11-run_user_0.patch Patch11: krb5-1.11-kpasswdtest.patch -Patch12: Fix-impersonate_name-to-work-with-interposers.patch -Patch13: Create-KDC-and-kadmind-log-files-with-mode-0640.patch -Patch14: Add-KDC-pre-send-and-post-receive-KDC-hooks.patch -Patch15: Add-tests-for-send-and-receive-sendto_kdc-hooks.patch -Patch16: Set-prompt-type-for-OTP-preauth-prompt.patch -Patch17: Improve-bad-password-inference-in-kinit.patch -Patch18: Change-KDC-error-for-encrypted-timestamp-preauth.patch -Patch19: Add-krb5_db_register_keytab.patch -Patch20: Don-t-feed-OS-RNG-output-into-the-OS-RNG.patch -Patch21: Rename-prng_os.c-to-prng_device.c.patch -Patch22: Add-getrandom-to-k5_get_os_entropy-using-syscall.patch -Patch23: Add-OS-prng-intended-for-use-with-getrandom.patch +Patch15: Use-fallback-realm-for-GSSAPI-ccache-selection.patch License: MIT URL: http://web.mit.edu/kerberos/www/ @@ -722,6 +711,9 @@ exit 0 %{_libdir}/libkadm5srv_mit.so.* %changelog +* Fri Feb 17 2017 Robbie Harwood - 1.14.4-5 +- Backport fix for GSSAPI fallback realm + * Fri Sep 30 2016 Robbie Harwood - 1.14.4-4 - Fix backward check in kprop.service