]> git.ipfire.org Git - pakfire.git/commitdiff
daemon: Completely destroy the Kerberos credentials cache on update
authorMichael Tremer <michael.tremer@ipfire.org>
Tue, 15 Apr 2025 16:53:11 +0000 (16:53 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Tue, 15 Apr 2025 16:53:11 +0000 (16:53 +0000)
This is required because on Debian, cURL is linked against Heimdal which
does not seem to be able to skip any deleted tickets in the file.
Instead it always uses the first ticket which would eventually have
expired. Therefore we destroy the entire cache and write it again so
Heimdal cannot get confused.

Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/pakfire/daemon.c

index ad0d31d5389e594b2318cce8c742b325a14185ae..b17be0564fc000dd571303ab821483ebd343adc6 100644 (file)
@@ -929,24 +929,6 @@ static int pakfire_daemon_setup_krb5(struct pakfire_daemon* daemon) {
 
        DEBUG(daemon->ctx, "Authenticating as: %s\n", name);
 
-       // Create a new credentials cache
-       r = krb5_cc_resolve(daemon->krb5.ctx, KRB5_CREDENTIALS_CACHE, &daemon->krb5.ccache);
-       if (r) {
-               error = krb5_get_error_message(daemon->krb5.ctx, r);
-
-               ERROR(daemon->ctx, "Could not resolve the credentials cache: %s\n", error);
-               goto ERROR;
-       }
-
-       // Initialize the cache for the principal
-       r = krb5_cc_initialize(daemon->krb5.ctx, daemon->krb5.ccache, daemon->krb5.principal);
-       if (r) {
-               error = krb5_get_error_message(daemon->krb5.ctx, r);
-
-               ERROR(daemon->ctx, "Could not initialize the credentials cache: %s\n", error);
-               goto ERROR;
-       }
-
        // Set the credentials cache environment variable
        r = setenv("KRB5CCNAME", KRB5_CREDENTIALS_CACHE, 1);
        if (r < 0) {
@@ -1028,12 +1010,35 @@ static int pakfire_daemon_auth(sd_event_source* s, uint64_t usec, void* data) {
        DEBUG(daemon->ctx, "Successfully fetched credentials\n");
        DEBUG(daemon->ctx, "  Expires: %s\n", time);
 
-       // Remove any previous credentials
-       r = krb5_cc_remove_cred(daemon->krb5.ctx, daemon->krb5.ccache, 0, &creds);
+       // Destroy the content of the cache
+       if (daemon->krb5.ccache) {
+               r = krb5_cc_destroy(daemon->krb5.ctx, daemon->krb5.ccache);
+               if (r) {
+                       error = krb5_get_error_message(daemon->krb5.ctx, r);
+
+                       ERROR(daemon->ctx, "Failed to destroy the credentials cache: %s\n", error);
+                       r = -ENOTSUP;
+                       goto ERROR;
+               }
+       }
+
+       // Create a new credentials cache
+       r = krb5_cc_resolve(daemon->krb5.ctx, KRB5_CREDENTIALS_CACHE, &daemon->krb5.ccache);
        if (r) {
                error = krb5_get_error_message(daemon->krb5.ctx, r);
 
-               ERROR(daemon->ctx, "Failed to remove credentials: %s\n", error);
+               ERROR(daemon->ctx, "Could not resolve the credentials cache: %s\n", error);
+               r = -EINVAL;
+               goto ERROR;
+       }
+
+       // Initialize the cache for the principal
+       r = krb5_cc_initialize(daemon->krb5.ctx, daemon->krb5.ccache, daemon->krb5.principal);
+       if (r) {
+               error = krb5_get_error_message(daemon->krb5.ctx, r);
+
+               ERROR(daemon->ctx, "Could not initialize the credentials cache: %s\n", error);
+               r = -EINVAL;
                goto ERROR;
        }
 
@@ -1043,6 +1048,7 @@ static int pakfire_daemon_auth(sd_event_source* s, uint64_t usec, void* data) {
                error = krb5_get_error_message(daemon->krb5.ctx, r);
 
                ERROR(daemon->ctx, "Could not store credentials: %s\n", error);
+               r = -EINVAL;
                goto ERROR;
        }
 
@@ -1273,7 +1279,7 @@ static void pakfire_daemon_free(struct pakfire_daemon* daemon) {
        if (daemon->krb5.principal)
                krb5_free_principal(daemon->krb5.ctx, daemon->krb5.principal);
        if (daemon->krb5.ccache)
-               krb5_cc_close(daemon->krb5.ctx, daemon->krb5.ccache);
+               krb5_cc_destroy(daemon->krb5.ctx, daemon->krb5.ccache);
        if (daemon->krb5.ctx)
                krb5_free_context(daemon->krb5.ctx);