diff options
author | Ray Strode <rstrode@redhat.com> | 2022-12-15 15:35:49 -0500 |
---|---|---|
committer | Ray Strode <rstrode@redhat.com> | 2022-12-16 23:51:12 -0500 |
commit | 3562279567d458075815bcadfc7ad070ccdbc71d (patch) | |
tree | 428f3cc4fb06bafdf56e6ac5dac44d6e7327331f | |
parent | 0907502aaf472d74438bf5a45d77af547be469b3 (diff) | |
download | gnome-online-accounts-3562279567d458075815bcadfc7ad070ccdbc71d.tar.gz |
goakerberosidentity: Explicitly switch to credentials cache when needed
If we're updating a credentials cache and decide
it should be the new default for an identity, and
the old credentials cache was the default cache
for the cache collection then we should make the
new credential cache the default cache for the
collection, too.
This commit adds that. It also makes the new
credentials cache the default if there wasn't a
valid default set already. This brings consistency
to differences in behavior from different kerberos
ccache types.
-rw-r--r-- | src/goaidentity/goakerberosidentity.c | 63 |
1 files changed, 60 insertions, 3 deletions
diff --git a/src/goaidentity/goakerberosidentity.c b/src/goaidentity/goakerberosidentity.c index 46a6fb2..4fe4b70 100644 --- a/src/goaidentity/goakerberosidentity.c +++ b/src/goaidentity/goakerberosidentity.c @@ -1554,6 +1554,41 @@ goa_kerberos_identity_compare (GoaKerberosIdentity *self, return 0; } +static char * +get_default_cache_name (GoaKerberosIdentity *self) +{ + int error_code; + krb5_ccache default_cache; + krb5_principal principal; + char *default_cache_name; + char *principal_name; + + error_code = krb5_cc_default (self->kerberos_context, &default_cache); + + if (error_code != 0) + return NULL; + + /* Return NULL if the default cache doesn't pass basic sanity checks + */ + error_code = krb5_cc_get_principal (self->kerberos_context, default_cache, &principal); + + if (error_code != 0) + return NULL; + + error_code = krb5_unparse_name_flags (self->kerberos_context, principal, 0, &principal_name); + krb5_free_principal (self->kerberos_context, principal); + + if (error_code != 0) + return NULL; + + krb5_free_unparsed_name (self->kerberos_context, principal_name); + + default_cache_name = g_strdup (krb5_cc_get_name (self->kerberos_context, default_cache)); + krb5_cc_close (self->kerberos_context, default_cache); + + return default_cache_name; +} + void goa_kerberos_identity_update (GoaKerberosIdentity *self, GoaKerberosIdentity *new_identity) @@ -1564,21 +1599,45 @@ goa_kerberos_identity_update (GoaKerberosIdentity *self, int comparison; G_LOCK (identity_lock); + + old_verification_level = self->cached_verification_level; + new_verification_level = new_identity->cached_verification_level; + comparison = goa_kerberos_identity_compare (self, new_identity); if (new_identity->active_credentials_cache_name != NULL) { + g_autofree char *default_cache_name = NULL; krb5_ccache credentials_cache; krb5_ccache copied_cache; + gboolean should_switch_to_new_credentials_cache = FALSE; + + default_cache_name = get_default_cache_name (self); + + if (default_cache_name == NULL) + should_switch_to_new_credentials_cache = TRUE; credentials_cache = (krb5_ccache) g_hash_table_lookup (new_identity->credentials_caches, new_identity->active_credentials_cache_name); krb5_cc_dup (new_identity->kerberos_context, credentials_cache, &copied_cache); + if (g_strcmp0 (default_cache_name, self->active_credentials_cache_name) == 0) + { + if ((comparison < 0) || + (comparison == 0 && old_verification_level != VERIFICATION_LEVEL_SIGNED_IN)) + should_switch_to_new_credentials_cache = TRUE; + } + if (comparison < 0) - g_clear_pointer (&self->active_credentials_cache_name, g_free); + { + g_clear_pointer (&self->active_credentials_cache_name, g_free); + self->active_credentials_cache_name = g_strdup (new_identity->active_credentials_cache_name); + } goa_kerberos_identity_add_credentials_cache (self, copied_cache); + + if (should_switch_to_new_credentials_cache) + krb5_cc_switch (self->kerberos_context, copied_cache); } G_UNLOCK (identity_lock); @@ -1592,8 +1651,6 @@ goa_kerberos_identity_update (GoaKerberosIdentity *self, time_changed |= set_start_time (self, new_identity->start_time); time_changed |= set_renewal_time (self, new_identity->renewal_time); time_changed |= set_expiration_time (self, new_identity->expiration_time); - old_verification_level = self->cached_verification_level; - new_verification_level = new_identity->cached_verification_level; G_UNLOCK (identity_lock); if (time_changed) |