diff --git a/krb5-master-empty-credstore.patch b/krb5-master-empty-credstore.patch new file mode 100644 index 0000000..b6cd7ef --- /dev/null +++ b/krb5-master-empty-credstore.patch @@ -0,0 +1,43 @@ +commit 970304b558a360e08d8421ef92245d2df0ac5e49 +Author: Greg Hudson +Date: Thu Jan 16 11:49:04 2014 -0500 + + Allow empty store in gss_acquire_cred_from + + There is no reason to deny a zero-length cred store, so don't check + for it in val_acq_cred_args or val_add_cred_args. + + ticket: 7836 (new) + target_version: 1.12.2 + tags: pullup + +diff --git a/src/lib/gssapi/mechglue/g_acquire_cred.c b/src/lib/gssapi/mechglue/g_acquire_cred.c +index 03b67e3..b9a3142 100644 +--- a/src/lib/gssapi/mechglue/g_acquire_cred.c ++++ b/src/lib/gssapi/mechglue/g_acquire_cred.c +@@ -80,12 +80,6 @@ val_acq_cred_args( + return GSS_S_FAILURE; + } + +- if (cred_store != NULL && cred_store->count == 0) { +- *minor_status = EINVAL; +- map_errcode(minor_status); +- return GSS_S_FAILURE; +- } +- + return (GSS_S_COMPLETE); + } + +@@ -302,12 +296,6 @@ val_add_cred_args( + return GSS_S_FAILURE; + } + +- if (cred_store != NULL && cred_store->count == 0) { +- *minor_status = EINVAL; +- map_errcode(minor_status); +- return GSS_S_FAILURE; +- } +- + return (GSS_S_COMPLETE); + } + diff --git a/krb5-master-rcache-acquirecred-cleanup.patch b/krb5-master-rcache-acquirecred-cleanup.patch new file mode 100644 index 0000000..72b97d3 --- /dev/null +++ b/krb5-master-rcache-acquirecred-cleanup.patch @@ -0,0 +1,105 @@ +commit ef8e19af863158e4c1abc15fc710aa8cfad38406 +Author: Greg Hudson +Date: Wed Jan 15 12:51:42 2014 -0500 + + Clean up GSS krb5 acquire_accept_cred + + Use a cleanup handler instead of releasing kt in multiple error + clauses. Wrap a long line and fix a comment with a missing word. + Rewrap the function arguments to use fewer lines. + +diff --git a/src/lib/gssapi/krb5/acquire_cred.c b/src/lib/gssapi/krb5/acquire_cred.c +index 9547207..37cc6b5 100644 +--- a/src/lib/gssapi/krb5/acquire_cred.c ++++ b/src/lib/gssapi/krb5/acquire_cred.c +@@ -179,13 +179,13 @@ cleanup: + */ + + static OM_uint32 +-acquire_accept_cred(krb5_context context, +- OM_uint32 *minor_status, +- krb5_keytab req_keytab, +- krb5_gss_cred_id_rec *cred) ++acquire_accept_cred(krb5_context context, OM_uint32 *minor_status, ++ krb5_keytab req_keytab, krb5_gss_cred_id_rec *cred) + { ++ OM_uint32 major; + krb5_error_code code; +- krb5_keytab kt; ++ krb5_keytab kt = NULL; ++ krb5_rcache rc = NULL; + + assert(cred->keytab == NULL); + +@@ -202,46 +202,54 @@ acquire_accept_cred(krb5_context context, + } + } + if (code) { +- *minor_status = code; +- return GSS_S_CRED_UNAVAIL; ++ major = GSS_S_CRED_UNAVAIL; ++ goto cleanup; + } + + if (cred->name != NULL) { +- /* Make sure we keys matching the desired name in the keytab. */ ++ /* Make sure we have keys matching the desired name in the keytab. */ + code = check_keytab(context, kt, cred->name); + if (code) { +- krb5_kt_close(context, kt); + if (code == KRB5_KT_NOTFOUND) { + char *errstr = (char *)krb5_get_error_message(context, code); +- krb5_set_error_message(context, KG_KEYTAB_NOMATCH, "%s", errstr); ++ krb5_set_error_message(context, KG_KEYTAB_NOMATCH, "%s", ++ errstr); + krb5_free_error_message(context, errstr); +- *minor_status = KG_KEYTAB_NOMATCH; +- } else +- *minor_status = code; +- return GSS_S_CRED_UNAVAIL; ++ code = KG_KEYTAB_NOMATCH; ++ } ++ major = GSS_S_CRED_UNAVAIL; ++ goto cleanup; + } + + /* Open the replay cache for this principal. */ + code = krb5_get_server_rcache(context, &cred->name->princ->data[0], +- &cred->rcache); ++ &rc); + if (code) { +- krb5_kt_close(context, kt); +- *minor_status = code; +- return GSS_S_FAILURE; ++ major = GSS_S_FAILURE; ++ goto cleanup; + } + } else { + /* Make sure we have a keytab with keys in it. */ + code = krb5_kt_have_content(context, kt); + if (code) { +- krb5_kt_close(context, kt); +- *minor_status = code; +- return GSS_S_CRED_UNAVAIL; ++ major = GSS_S_CRED_UNAVAIL; ++ goto cleanup; + } + } + + cred->keytab = kt; ++ kt = NULL; ++ cred->rcache = rc; ++ rc = NULL; ++ major = GSS_S_COMPLETE; + +- return GSS_S_COMPLETE; ++cleanup: ++ if (kt != NULL) ++ krb5_kt_close(context, kt); ++ if (rc != NULL) ++ krb5_rc_close(context, rc); ++ *minor_status = code; ++ return major; + } + #endif /* LEAN_CLIENT */ + diff --git a/krb5-master-rcache-acquirecred-leak.patch b/krb5-master-rcache-acquirecred-leak.patch new file mode 100644 index 0000000..0ae7b34 --- /dev/null +++ b/krb5-master-rcache-acquirecred-leak.patch @@ -0,0 +1,26 @@ +commit 9df0c4bdce6b88a01af51e4bbb9a365db00256d5 +Author: Greg Hudson +Date: Wed Jan 15 14:41:54 2014 -0500 + + Clean up rcache if GSS krb5 acquire_cred fails + + The error handler in acquire_cred_context didn't release the rcache, + which would cause it to leak if we failed after acquire_accept_cred. + + ticket: 7818 (new) + target_version: 1.12.2 + tags: pullup + +diff --git a/src/lib/gssapi/krb5/acquire_cred.c b/src/lib/gssapi/krb5/acquire_cred.c +index 37cc6b5..f625c0c 100644 +--- a/src/lib/gssapi/krb5/acquire_cred.c ++++ b/src/lib/gssapi/krb5/acquire_cred.c +@@ -829,6 +829,8 @@ error_out: + if (cred->keytab) + krb5_kt_close(context, cred->keytab); + #endif /* LEAN_CLIENT */ ++ if (cred->rcache) ++ krb5_rc_close(context, cred->rcache); + if (cred->name) + kg_release_name(context, &cred->name); + k5_mutex_destroy(&cred->lock); diff --git a/krb5-master-rcache-acquirecred-source.patch b/krb5-master-rcache-acquirecred-source.patch new file mode 100644 index 0000000..71c3876 --- /dev/null +++ b/krb5-master-rcache-acquirecred-source.patch @@ -0,0 +1,136 @@ +commit 7dad0bee30fbbde8cfc0eacd2d1487c198a004a1 +Author: Simo Sorce +Date: Thu Dec 26 19:05:34 2013 -0500 + + Add rcache feature to gss_acquire_cred_from + + The "rcache" cred store entry can specify a replay cache type and name + to be used with the credentials being acquired. + + [ghudson@mit.edu: split up, simplified, and altered to fit preparatory + commits] + + ticket: 7819 (new) + +diff --git a/src/lib/gssapi/krb5/acquire_cred.c b/src/lib/gssapi/krb5/acquire_cred.c +index f625c0c..5d680f9 100644 +--- a/src/lib/gssapi/krb5/acquire_cred.c ++++ b/src/lib/gssapi/krb5/acquire_cred.c +@@ -180,7 +180,8 @@ cleanup: + + static OM_uint32 + acquire_accept_cred(krb5_context context, OM_uint32 *minor_status, +- krb5_keytab req_keytab, krb5_gss_cred_id_rec *cred) ++ krb5_keytab req_keytab, const char *rcname, ++ krb5_gss_cred_id_rec *cred) + { + OM_uint32 major; + krb5_error_code code; +@@ -189,6 +190,20 @@ acquire_accept_cred(krb5_context context, OM_uint32 *minor_status, + + assert(cred->keytab == NULL); + ++ /* If we have an explicit rcache name, open it. */ ++ if (rcname != NULL) { ++ code = krb5_rc_resolve_full(context, &rc, rcname); ++ if (code) { ++ major = GSS_S_FAILURE; ++ goto cleanup; ++ } ++ code = krb5_rc_recover_or_initialize(context, rc, context->clockskew); ++ if (code) { ++ major = GSS_S_FAILURE; ++ goto cleanup; ++ } ++ } ++ + if (req_keytab != NULL) { + code = krb5_kt_dup(context, req_keytab, &kt); + } else { +@@ -221,12 +236,14 @@ acquire_accept_cred(krb5_context context, OM_uint32 *minor_status, + goto cleanup; + } + +- /* Open the replay cache for this principal. */ +- code = krb5_get_server_rcache(context, &cred->name->princ->data[0], +- &rc); +- if (code) { +- major = GSS_S_FAILURE; +- goto cleanup; ++ if (rc == NULL) { ++ /* Open the replay cache for this principal. */ ++ code = krb5_get_server_rcache(context, &cred->name->princ->data[0], ++ &rc); ++ if (code) { ++ major = GSS_S_FAILURE; ++ goto cleanup; ++ } + } + } else { + /* Make sure we have a keytab with keys in it. */ +@@ -718,8 +735,8 @@ acquire_cred_context(krb5_context context, OM_uint32 *minor_status, + gss_name_t desired_name, gss_buffer_t password, + OM_uint32 time_req, gss_cred_usage_t cred_usage, + krb5_ccache ccache, krb5_keytab client_keytab, +- krb5_keytab keytab, krb5_boolean iakerb, +- gss_cred_id_t *output_cred_handle, ++ krb5_keytab keytab, const char *rcname, ++ krb5_boolean iakerb, gss_cred_id_t *output_cred_handle, + OM_uint32 *time_rec) + { + krb5_gss_cred_id_t cred = NULL; +@@ -775,7 +792,7 @@ acquire_cred_context(krb5_context context, OM_uint32 *minor_status, + * in cred->name if desired_princ is specified. + */ + if (cred_usage == GSS_C_ACCEPT || cred_usage == GSS_C_BOTH) { +- ret = acquire_accept_cred(context, minor_status, keytab, cred); ++ ret = acquire_accept_cred(context, minor_status, keytab, rcname, cred); + if (ret != GSS_S_COMPLETE) + goto error_out; + } +@@ -867,7 +884,7 @@ acquire_cred(OM_uint32 *minor_status, gss_name_t desired_name, + + ret = acquire_cred_context(context, minor_status, desired_name, password, + time_req, cred_usage, ccache, NULL, keytab, +- iakerb, output_cred_handle, time_rec); ++ NULL, iakerb, output_cred_handle, time_rec); + + out: + krb5_free_context(context); +@@ -1135,7 +1152,7 @@ krb5_gss_acquire_cred_from(OM_uint32 *minor_status, + krb5_keytab client_keytab = NULL; + krb5_keytab keytab = NULL; + krb5_ccache ccache = NULL; +- const char *value; ++ const char *rcname, *value; + OM_uint32 ret; + + code = gss_krb5int_initialize_library(); +@@ -1191,9 +1208,14 @@ krb5_gss_acquire_cred_from(OM_uint32 *minor_status, + } + } + ++ ret = kg_value_from_cred_store(cred_store, KRB5_CS_RCACHE_URN, &rcname); ++ if (GSS_ERROR(ret)) ++ goto out; ++ + ret = acquire_cred_context(context, minor_status, desired_name, NULL, + time_req, cred_usage, ccache, client_keytab, +- keytab, 0, output_cred_handle, time_rec); ++ keytab, rcname, 0, output_cred_handle, ++ time_rec); + + out: + if (ccache != NULL) +diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h +index 0167816..8e4f6d9 100644 +--- a/src/lib/gssapi/krb5/gssapiP_krb5.h ++++ b/src/lib/gssapi/krb5/gssapiP_krb5.h +@@ -1260,6 +1260,7 @@ data_to_gss(krb5_data *input_k5data, gss_buffer_t output_buffer) + #define KRB5_CS_CLI_KEYTAB_URN "client_keytab" + #define KRB5_CS_KEYTAB_URN "keytab" + #define KRB5_CS_CCACHE_URN "ccache" ++#define KRB5_CS_RCACHE_URN "rcache" + + OM_uint32 + kg_value_from_cred_store(gss_const_key_value_set_t cred_store, diff --git a/krb5-master-rcache-acquirecred-test.patch b/krb5-master-rcache-acquirecred-test.patch new file mode 100644 index 0000000..e8eef5e --- /dev/null +++ b/krb5-master-rcache-acquirecred-test.patch @@ -0,0 +1,82 @@ +commit 6f8d5135334c9ddb674f9824e750872b3b0642ea +Author: Greg Hudson +Date: Thu Jan 16 11:49:55 2014 -0500 + + Add test for gss_acquire_cred_from rcache feature + +diff --git a/src/tests/gssapi/t_credstore.c b/src/tests/gssapi/t_credstore.c +index 575f96d..e28f5d0 100644 +--- a/src/tests/gssapi/t_credstore.c ++++ b/src/tests/gssapi/t_credstore.c +@@ -46,7 +46,9 @@ main(int argc, char *argv[]) + gss_cred_usage_t cred_usage = GSS_C_BOTH; + gss_OID_set mechs = GSS_C_NO_OID_SET; + gss_cred_id_t cred = GSS_C_NO_CREDENTIAL; +- krb5_boolean store_creds = FALSE; ++ gss_ctx_id_t ictx = GSS_C_NO_CONTEXT, actx = GSS_C_NO_CONTEXT; ++ gss_buffer_desc itok, atok; ++ krb5_boolean store_creds = FALSE, replay = FALSE; + char opt; + + /* Parse options. */ +@@ -54,6 +56,8 @@ main(int argc, char *argv[]) + opt = (*argv)[1]; + if (opt == 's') + store_creds = TRUE; ++ else if (opt == 'r') ++ replay = TRUE; + else if (opt == 'a') + cred_usage = GSS_C_ACCEPT; + else if (opt == 'b') +@@ -101,6 +105,31 @@ main(int argc, char *argv[]) + &store, &cred, NULL, NULL); + check_gsserr("gss_acquire_cred_from", major, minor); + ++ if (replay) { ++ /* Induce a replay using cred as the acceptor cred, to test the replay ++ * cache indicated by the store. */ ++ major = gss_init_sec_context(&minor, GSS_C_NO_CREDENTIAL, &ictx, name, ++ &mech_krb5, 0, GSS_C_INDEFINITE, ++ GSS_C_NO_CHANNEL_BINDINGS, ++ GSS_C_NO_BUFFER, NULL, &itok, NULL, NULL); ++ check_gsserr("gss_init_sec_context", major, minor); ++ (void)gss_delete_sec_context(&minor, &ictx, NULL); ++ ++ major = gss_accept_sec_context(&minor, &actx, cred, &itok, ++ GSS_C_NO_CHANNEL_BINDINGS, NULL, NULL, ++ &atok, NULL, NULL, NULL); ++ check_gsserr("gss_accept_sec_context(1)", major, minor); ++ (void)gss_release_buffer(&minor, &atok); ++ (void)gss_delete_sec_context(&minor, &actx, NULL); ++ ++ major = gss_accept_sec_context(&minor, &actx, cred, &itok, ++ GSS_C_NO_CHANNEL_BINDINGS, NULL, NULL, ++ &atok, NULL, NULL, NULL); ++ check_gsserr("gss_accept_sec_context(2)", major, minor); ++ (void)gss_release_buffer(&minor, &atok); ++ (void)gss_delete_sec_context(&minor, &actx, NULL); ++ } ++ + gss_release_name(&minor, &name); + gss_release_cred(&minor, &cred); + free(store.elements); +diff --git a/src/tests/gssapi/t_gssapi.py b/src/tests/gssapi/t_gssapi.py +index 74139e4..106910d 100755 +--- a/src/tests/gssapi/t_gssapi.py ++++ b/src/tests/gssapi/t_gssapi.py +@@ -91,6 +91,15 @@ realm.kinit(service_cs, None, ['-k', '-t', servicekeytab]) + realm.run(['./t_credstore', '-s', 'p:' + service_cs, 'ccache', storagecache, + 'keytab', servicekeytab]) + ++# Test rcache feature of cred stores. t_credstore -r should produce a ++# replay error normally, but not with rcache set to "none:". ++output = realm.run(['./t_credstore', '-r', '-a', 'p:' + realm.host_princ], ++ expected_code=1) ++if 'gss_accept_sec_context(2): Request is a replay' not in output: ++ fail('Expected replay error not seen in t_credstore output') ++realm.run(['./t_credstore', '-r', '-a', 'p:' + realm.host_princ, ++ 'rcache', 'none:']) ++ + # Verify that we can't acquire acceptor creds without a keytab. + os.remove(realm.keytab) + output = realm.run(['./t_accname', 'p:abc'], expected_code=1) diff --git a/krb5-master-rcache-internal-const.patch b/krb5-master-rcache-internal-const.patch new file mode 100644 index 0000000..5cb1108 --- /dev/null +++ b/krb5-master-rcache-internal-const.patch @@ -0,0 +1,46 @@ +commit 74ff6c4accb68bd1d6c652c55e66519720db9fc4 +Author: Greg Hudson +Date: Wed Jan 15 12:31:41 2014 -0500 + + Make rcache resolve functions take const char * + +diff --git a/src/include/k5-int.h b/src/include/k5-int.h +index bbc7fab..b4757a9 100644 +--- a/src/include/k5-int.h ++++ b/src/include/k5-int.h +@@ -1887,8 +1887,10 @@ krb5_error_code KRB5_CALLCONV + krb5int_cc_user_set_default_name(krb5_context context, const char *name); + + krb5_error_code krb5_rc_default(krb5_context, krb5_rcache *); +-krb5_error_code krb5_rc_resolve_type(krb5_context, krb5_rcache *,char *); +-krb5_error_code krb5_rc_resolve_full(krb5_context, krb5_rcache *,char *); ++krb5_error_code krb5_rc_resolve_type(krb5_context, krb5_rcache *, ++ const char *); ++krb5_error_code krb5_rc_resolve_full(krb5_context, krb5_rcache *, ++ const char *); + char *krb5_rc_get_type(krb5_context, krb5_rcache); + char *krb5_rc_default_type(krb5_context); + char *krb5_rc_default_name(krb5_context); +diff --git a/src/lib/krb5/rcache/rc_base.c b/src/lib/krb5/rcache/rc_base.c +index 2fc96c5..373ac30 100644 +--- a/src/lib/krb5/rcache/rc_base.c ++++ b/src/lib/krb5/rcache/rc_base.c +@@ -65,7 +65,8 @@ krb5_rc_register_type(krb5_context context, const krb5_rc_ops *ops) + } + + krb5_error_code +-krb5_rc_resolve_type(krb5_context context, krb5_rcache *idptr, char *type) ++krb5_rc_resolve_type(krb5_context context, krb5_rcache *idptr, ++ const char *type) + { + struct krb5_rc_typelist *t; + krb5_error_code err; +@@ -146,7 +147,7 @@ krb5_rc_default(krb5_context context, krb5_rcache *idptr) + + krb5_error_code + krb5_rc_resolve_full(krb5_context context, krb5_rcache *idptr, +- char *string_name) ++ const char *string_name) + { + char *type; + char *residual; diff --git a/krb5.spec b/krb5.spec index db829f6..1cd32da 100644 --- a/krb5.spec +++ b/krb5.spec @@ -41,7 +41,7 @@ Summary: The Kerberos network authentication system Name: krb5 Version: 1.12.1 -Release: 1%{?dist} +Release: 2%{?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 @@ -91,6 +91,12 @@ Patch105: krb5-kvno-230379.patch Patch129: krb5-1.11-run_user_0.patch Patch134: krb5-1.11-kpasswdtest.patch Patch135: krb5-master-keyring-kdcsync.patch +Patch136: krb5-master-rcache-internal-const.patch +Patch137: krb5-master-rcache-acquirecred-cleanup.patch +Patch138: krb5-master-rcache-acquirecred-leak.patch +Patch139: krb5-master-rcache-acquirecred-source.patch +Patch140: krb5-master-empty-credstore.patch +Patch141: krb5-master-rcache-acquirecred-test.patch License: MIT URL: http://web.mit.edu/kerberos/www/ @@ -318,6 +324,13 @@ ln -s NOTICE LICENSE %patch135 -p1 -b .keyring-kdcsync +%patch136 -p1 -b .rcache-internal-const +%patch137 -p1 -b .rcache-acquirecred-cleanup +%patch138 -p1 -b .rcache-acquirecred-leak +%patch139 -p1 -b .rcache-acquirecred-source +%patch140 -p1 -b .empty-credstore +%patch141 -p1 -b .rcache-acquirecred-test + # Take the execute bit off of documentation. chmod -x doc/krb5-protocol/*.txt @@ -965,6 +978,11 @@ exit 0 %{_sbindir}/uuserver %changelog +* Tue Jan 21 2014 Nalin Dahyabhai - 1.12.1-2 +- pull in multiple changes to allow replay caches to be added to a GSS + credential store as "rcache"-type credentials (RT#7818/#7819/#7836, + #1056078/#1056080) + * Fri Jan 17 2014 Nalin Dahyabhai - 1.12.1-1 - update to 1.12.1 - drop patch for RT#7794, included now