summaryrefslogtreecommitdiffstats
path: root/krb5-master-keyring-expiration.patch
diff options
context:
space:
mode:
authorNalin Dahyabhai <nalin@dahyabhai.net>2013-11-18 17:47:36 -0500
committerNalin Dahyabhai <nalin@dahyabhai.net>2013-11-18 18:02:38 -0500
commit9488d7d5cc396c2ab42cd144fe5e4139ef59cadb (patch)
treef82f706a393d72814ed6a59043a77e2e8b6a9480 /krb5-master-keyring-expiration.patch
parentcf42e92cc6d7dfacb04b5d2378f59262c5bb3b2e (diff)
downloadkrb5-9488d7d5cc396c2ab42cd144fe5e4139ef59cadb.tar.gz
krb5-9488d7d5cc396c2ab42cd144fe5e4139ef59cadb.tar.xz
krb5-9488d7d5cc396c2ab42cd144fe5e4139ef59cadb.zip
Pull in keyring expiration from RT#7769krb5-1.11.3-33.fc20
- pull in fix to set expiration times on keyrings used for storing keyring credential caches (RT#7769, #1031724)
Diffstat (limited to 'krb5-master-keyring-expiration.patch')
-rw-r--r--krb5-master-keyring-expiration.patch127
1 files changed, 127 insertions, 0 deletions
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 <simo@redhat.com>
+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);