[krb5/f20] Backport changes to allow "rcache" credstores

Nalin Dahyabhai nalin at fedoraproject.org
Tue Jan 21 23:57:53 UTC 2014


commit e4496aca6bc180c7dbb19b1dd495cb9c1bdba261
Author: Nalin Dahyabhai <nalin at dahyabhai.net>
Date:   Tue Jan 21 18:31:27 2014 -0500

    Backport changes to allow "rcache" credstores
    
    - pull in and backport multiple changes to allow replay caches to be
      added to a GSS credential store as "rcache"-type credentials
      (RT#7818/#7819/#7836, #1056078/#1056080)

 krb5-1.11-rcache-acquirecred-source.patch    |  138 ++++++++++++++++++++++++++
 krb5-1.11-rcache-acquirecred-test.patch      |   90 +++++++++++++++++
 krb5-1.11.3-1.12.1-credstoretest.patch       |  125 +++++++++++++++++++++++
 krb5-master-empty-credstore.patch            |   43 ++++++++
 krb5-master-rcache-acquirecred-cleanup.patch |  105 +++++++++++++++++++
 krb5-master-rcache-acquirecred-leak.patch    |   26 +++++
 krb5-master-rcache-internal-const.patch      |   46 +++++++++
 krb5.spec                                    |   23 ++++-
 8 files changed, 595 insertions(+), 1 deletions(-)
---
diff --git a/krb5-1.11-rcache-acquirecred-source.patch b/krb5-1.11-rcache-acquirecred-source.patch
new file mode 100644
index 0000000..d67d5c7
--- /dev/null
+++ b/krb5-1.11-rcache-acquirecred-source.patch
@@ -0,0 +1,138 @@
+Adapted.
+
+commit 7dad0bee30fbbde8cfc0eacd2d1487c198a004a1
+Author: Simo Sorce <simo at redhat.com>
+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 at 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) {
+         char ktname[BUFSIZ];
+ 
+@@ -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-1.11-rcache-acquirecred-test.patch b/krb5-1.11-rcache-acquirecred-test.patch
new file mode 100644
index 0000000..ec1709b
--- /dev/null
+++ b/krb5-1.11-rcache-acquirecred-test.patch
@@ -0,0 +1,90 @@
+Adapted, with some more intermediate context applied in between.
+
+commit 6f8d5135334c9ddb674f9824e750872b3b0642ea
+Author: Greg Hudson <ghudson at mit.edu>
+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
+@@ -89,11 +89,18 @@
+ realm.addprinc(service_cs)
+ realm.extract_keytab(service_cs, servicekeytab)
+ realm.kinit(service_cs, None, ['-k', '-t', servicekeytab])
+-output = realm.run_as_client(['./t_credstore', service_cs, '--cred_store',
++output = realm.run_as_client(['./t_credstore', '-s', 'p:' + service_cs,
+                               'ccache', storagecache, 'keytab', servicekeytab])
+-if 'Cred Store Success' not in output:
+-    fail('Expected test to succeed')
+ 
++# 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_as_client(['./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_as_client(['./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_as_client(['./t_accname', 'p:abc'], expected_code=1)
diff --git a/krb5-1.11.3-1.12.1-credstoretest.patch b/krb5-1.11.3-1.12.1-credstoretest.patch
new file mode 100644
index 0000000..dbfd7fe
--- /dev/null
+++ b/krb5-1.11.3-1.12.1-credstoretest.patch
@@ -0,0 +1,125 @@
+diff --git a/src/tests/gssapi/t_credstore.c b/src/tests/gssapi/t_credstore.c
+index 085bc79..575f96d 100644
+--- a/src/tests/gssapi/t_credstore.c
++++ b/src/tests/gssapi/t_credstore.c
+@@ -33,7 +33,7 @@ static void
+ usage(void)
+ {
+     fprintf(stderr,
+-            "Usage: t_credstore principal [--cred_store {key value} ...]\n");
++            "Usage: t_credstore [-sabi] principal [{key value} ...]\n");
+     exit(1);
+ }
+ 
+@@ -42,63 +42,66 @@ main(int argc, char *argv[])
+ {
+     OM_uint32 minor, major;
+     gss_key_value_set_desc store;
+-    gss_buffer_desc buf;
+-    gss_name_t service = GSS_C_NO_NAME;
++    gss_name_t name;
++    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;
+-    int i, e;
+-
+-    if (argc < 2 || ((argc - 3) % 2))
+-        usage();
+-
+-    store.count = (argc - 3) / 2;
+-    store.elements = calloc(store.count,
+-                            sizeof(struct gss_key_value_element_struct));
+-    if (!store.elements) {
+-        fprintf(stderr, "OOM\n");
+-        exit(1);
++    krb5_boolean store_creds = FALSE;
++    char opt;
++
++    /* Parse options. */
++    for (argv++; *argv != NULL && **argv == '-'; argv++) {
++        opt = (*argv)[1];
++        if (opt == 's')
++            store_creds = TRUE;
++        else if (opt == 'a')
++            cred_usage = GSS_C_ACCEPT;
++        else if (opt == 'b')
++            cred_usage = GSS_C_BOTH;
++        else if (opt == 'i')
++            cred_usage = GSS_C_INITIATE;
++        else
++            usage();
+     }
+ 
+-    if (argc > 2) {
+-        if (strcmp(argv[2], "--cred_store") != 0)
++    /* Get the principal name. */
++    if (*argv == NULL)
++        usage();
++    name = import_name(*argv++);
++
++    /* Put any remaining arguments into the store. */
++    store.elements = calloc(argc, sizeof(struct gss_key_value_element_struct));
++    if (!store.elements)
++        errout("OOM");
++    store.count = 0;
++    while (*argv != NULL) {
++        if (*(argv + 1) == NULL)
+             usage();
+-
+-        for (i = 3, e = 0; i < argc; i += 2, e++) {
+-            store.elements[e].key = argv[i];
+-            store.elements[e].value = argv[i + 1];
+-            continue;
+-        }
++        store.elements[store.count].key = *argv;
++        store.elements[store.count].value = *(argv + 1);
++        store.count++;
++        argv += 2;
+     }
+ 
+-    /* First acquire default creds and try to store them in the cred store. */
+-
+-    major = gss_acquire_cred(&minor, GSS_C_NO_NAME, 0, GSS_C_NO_OID_SET,
+-                             GSS_C_INITIATE, &cred, NULL, NULL);
+-    check_gsserr("gss_acquire_cred", major, minor);
++    if (store_creds) {
++        /* Acquire default creds and try to store them in the cred store. */
++        major = gss_acquire_cred(&minor, GSS_C_NO_NAME, 0, GSS_C_NO_OID_SET,
++                                 GSS_C_INITIATE, &cred, NULL, NULL);
++        check_gsserr("gss_acquire_cred", major, minor);
+ 
+-    major = gss_store_cred_into(&minor, cred, GSS_C_INITIATE,
+-                                GSS_C_NO_OID, 1, 0, &store, NULL, NULL);
+-    check_gsserr("gss_store_cred_into", major, minor);
++        major = gss_store_cred_into(&minor, cred, GSS_C_INITIATE,
++                                    GSS_C_NO_OID, 1, 0, &store, NULL, NULL);
++        check_gsserr("gss_store_cred_into", major, minor);
+ 
+-    gss_release_cred(&minor, &cred);
+-
+-    /* Then try to acquire creds from store. */
+-
+-    buf.value = argv[1];
+-    buf.length = strlen(argv[1]);
+-
+-    major = gss_import_name(&minor, &buf,
+-                            (gss_OID)GSS_KRB5_NT_PRINCIPAL_NAME,
+-                            &service);
+-    check_gsserr("gss_import_name", major, minor);
++        gss_release_cred(&minor, &cred);
++    }
+ 
+-    major = gss_acquire_cred_from(&minor, service,
+-                                  0, GSS_C_NO_OID_SET, GSS_C_BOTH,
++    /* Try to acquire creds from store. */
++    major = gss_acquire_cred_from(&minor, name, 0, mechs, cred_usage,
+                                   &store, &cred, NULL, NULL);
+     check_gsserr("gss_acquire_cred_from", major, minor);
+ 
+-    fprintf(stdout, "Cred Store Success\n");
+-
+-    gss_release_name(&minor, &service);
++    gss_release_name(&minor, &name);
+     gss_release_cred(&minor, &cred);
+     free(store.elements);
+     return 0;
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 <ghudson at mit.edu>
+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 <ghudson at mit.edu>
+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 <ghudson at mit.edu>
+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-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 <ghudson at mit.edu>
+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 9b95f38..40e6b94 100644
--- a/krb5.spec
+++ b/krb5.spec
@@ -41,7 +41,7 @@
 Summary: The Kerberos network authentication system
 Name: krb5
 Version: 1.11.3
-Release: 38%{?dist}
+Release: 39%{?dist}
 # Maybe we should explode from the now-available-to-everybody tarball instead?
 # http://web.mit.edu/kerberos/dist/krb5/1.11/krb5-1.11.3-signed.tar
 Source0: krb5-%{version}.tar.gz
@@ -121,6 +121,14 @@ Patch148: krb5-1.11-preauthcore.patch
 Patch149: krb5-1.11.3-copy_context.patch
 Patch150: krb5-1.11.3-spnego_error_messages.patch
 
+Patch151: krb5-master-rcache-internal-const.patch
+Patch152: krb5-master-rcache-acquirecred-cleanup.patch
+Patch153: krb5-master-rcache-acquirecred-leak.patch
+Patch154: krb5-1.11-rcache-acquirecred-source.patch
+Patch155: krb5-master-empty-credstore.patch
+Patch156: krb5-1.11.3-1.12.1-credstoretest.patch
+Patch157: krb5-1.11-rcache-acquirecred-test.patch
+
 # Patches for otp plugin backport
 Patch201: krb5-1.11.2-keycheck.patch
 Patch202: krb5-1.11.2-otp.patch
@@ -384,6 +392,14 @@ ln -s NOTICE LICENSE
 %patch149 -p1 -b .copy_context
 %patch150 -p1 -b .spnego_error_messages
 
+%patch151 -p1 -b .rcache-internal-const
+%patch152 -p1 -b .rcache-acquirecred-cleanup
+%patch153 -p1 -b .rcache-acquirecred-leak
+%patch154 -p1 -b .rcache-acquirecred-source
+%patch155 -p1 -b .empty-credstore
+%patch156 -p1 -b .credstoretest
+%patch157 -p1 -b .rcache-acquirecred-test
+
 %patch201 -p1 -b .keycheck
 %patch202 -p1 -b .otp
 %patch203 -p1 -b .otp2
@@ -1035,6 +1051,11 @@ exit 0
 %{_sbindir}/uuserver
 
 %changelog
+* Tue Jan 21 2014 Nalin Dahyabhai <nalin at redhat.com>
+- pull in and backport multiple changes to allow replay caches to be added to
+  a GSS credential store as "rcache"-type credentials (RT#7818/#7819/#7836,
+  #1056078/#1056080)
+
 * Thu Dec 19 2013 Nalin Dahyabhai <nalin at redhat.com> - 1.11.3-38
 - pull in fix from master to make reporting of errors encountered by the SPNEGO
   mechanism work better (RT#7045, part of #1043962)


More information about the scm-commits mailing list