From a77ee55771e4e212b2e01c8404a0dca3fe7cfc97 Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Nov 18 2013 23:02:20 +0000 Subject: Pull in keyring expiration from RT#7769 - pull in fix to set expiration times on keyrings used for storing keyring credential caches (RT#7769, #1031724) --- diff --git a/krb5-master-keyring-expiration.patch b/krb5-master-keyring-expiration.patch new file mode 100644 index 0000000..2c58cb0 --- /dev/null +++ b/krb5-master-keyring-expiration.patch @@ -0,0 +1,127 @@ +commit 29e60c5b7ac0980606971afc6fd6028bcf0c7f0f +Author: Simo Sorce +Date: Fri Nov 15 16:36:05 2013 -0500 + + Set expiration time on keys and keyrings + + By setting the timeout based on the credetial's timeout we let the + system automatically cleanup expired credentials. + + [ghudson@mit.edu: simplified code slightly] + + ticket: 7769 (new) + target_version: 1.12 + tags: pullup + +diff --git a/src/lib/krb5/ccache/cc_keyring.c b/src/lib/krb5/ccache/cc_keyring.c +index 2192fa5..1a0f1df 100644 +--- a/src/lib/krb5/ccache/cc_keyring.c ++++ b/src/lib/krb5/ccache/cc_keyring.c +@@ -818,21 +818,68 @@ cleanup: + + static krb5_error_code + add_cred_key(const char *name, const void *payload, size_t plen, +- key_serial_t cache_id, krb5_boolean legacy_type) ++ key_serial_t cache_id, krb5_boolean legacy_type, ++ key_serial_t *key_out) + { + key_serial_t key; + ++ *key_out = -1; + if (!legacy_type) { + /* Try the preferred cred key type; fall back if no kernel support. */ + key = add_key(KRCC_CRED_KEY_TYPE, name, payload, plen, cache_id); +- if (key != -1) ++ if (key != -1) { ++ *key_out = key; + return 0; +- else if (errno != EINVAL && errno != ENODEV) ++ } else if (errno != EINVAL && errno != ENODEV) { + return errno; ++ } + } + /* Use the user key type. */ + key = add_key(KRCC_KEY_TYPE_USER, name, payload, plen, cache_id); +- return (key == -1) ? errno : 0; ++ if (key == -1) ++ return errno; ++ *key_out = key; ++ return 0; ++} ++ ++static void ++update_keyring_expiration(krb5_context context, krb5_ccache id) ++{ ++ krb5_krcc_data *d = (krb5_krcc_data *)id->data; ++ krb5_cc_cursor cursor; ++ krb5_creds creds; ++ krb5_timestamp now, endtime = 0; ++ unsigned int timeout; ++ ++ /* ++ * We have no way to know what is the actual timeout set on the keyring. ++ * We also cannot keep track of it in a local variable as another process ++ * can always modify the keyring independently, so just always enumerate ++ * all keys and find out the highest endtime time. ++ */ ++ ++ /* Find the maximum endtime of all creds in the cache. */ ++ if (krb5_krcc_start_seq_get(context, id, &cursor) != 0) ++ return; ++ for (;;) { ++ if (krb5_krcc_next_cred(context, id, &cursor, &creds) != 0) ++ break; ++ if (creds.times.endtime > endtime) ++ endtime = creds.times.endtime; ++ krb5_free_cred_contents(context, &creds); ++ } ++ (void)krb5_krcc_end_seq_get(context, id, &cursor); ++ ++ if (endtime == 0) /* No creds with end times */ ++ return; ++ ++ if (krb5_timeofday(context, &now) != 0) ++ return; ++ ++ /* Setting the timeout to zero would reset the timeout, so we set it to one ++ * second instead if creds are already expired. */ ++ timeout = (endtime > now) ? endtime - now : 1; ++ (void)keyctl_set_timeout(d->cache_id, timeout); + } + + /* +@@ -1497,6 +1544,8 @@ krb5_krcc_store(krb5_context context, krb5_ccache id, krb5_creds * creds) + char *payload = NULL; + unsigned int payloadlen; + char *keyname = NULL; ++ key_serial_t cred_key; ++ krb5_timestamp now; + + DEBUG_PRINT(("krb5_krcc_store: entered\n")); + +@@ -1523,12 +1572,24 @@ krb5_krcc_store(krb5_context context, krb5_ccache id, krb5_creds * creds) + DEBUG_PRINT(("krb5_krcc_store: adding new key '%s' to keyring %d\n", + keyname, d->cache_id)); + kret = add_cred_key(keyname, payload, payloadlen, d->cache_id, +- d->is_legacy_type); ++ d->is_legacy_type, &cred_key); + if (kret) + goto errout; + + krb5_krcc_update_change_time(d); + ++ /* Set appropriate timeouts on cache keys. */ ++ kret = krb5_timeofday(context, &now); ++ if (kret) ++ goto errout; ++ ++ if (creds->times.endtime > now) ++ (void)keyctl_set_timeout(cred_key, creds->times.endtime - now); ++ ++ update_keyring_expiration(context, id); ++ ++ kret = KRB5_OK; ++ + errout: + if (keyname) + krb5_free_unparsed_name(context, keyname); diff --git a/krb5.spec b/krb5.spec index 6dadefa..ae82224 100644 --- a/krb5.spec +++ b/krb5.spec @@ -107,6 +107,7 @@ Patch135: krb5-1.11-check_transited.patch Patch136: krb5-1.11.3-prompter1.patch Patch137: krb5-1.11.3-prompter2.patch Patch138: krb5-master-keyring-offsets.patch +Patch139: krb5-master-keyring-expiration.patch # Patches for otp plugin backport Patch201: krb5-1.11.2-keycheck.patch @@ -353,6 +354,7 @@ ln -s NOTICE LICENSE %patch136 -p1 -b .prompter1 %patch137 -p1 -b .prompter2 %patch138 -p1 -b .keyring-offsets +%patch139 -p1 -b .keyring-expiration %patch201 -p1 -b .keycheck %patch202 -p1 -b .otp @@ -1007,6 +1009,8 @@ exit 0 * Mon Nov 18 2013 Nalin Dahyabhai - 1.11.4-2 - pull in fix to store KDC time offsets in keyring credential caches (RT#7768, #1030607) +- pull in fix to set expiration times on credentials stored in keyring + credential caches (RT#7769, #1031724) * Tue Nov 12 2013 Nalin Dahyabhai - 1.11.4-1 - update to 1.11.4