Blob Blame History Raw
From fc748ba83eb29f10fd44b6572b04709fa27dc587 Mon Sep 17 00:00:00 2001
From: Simo Sorce <simo@redhat.com>
Date: Mon, 13 Mar 2017 08:06:12 -0400
Subject: [PATCH] Properly renew expired credentials

When a caller imports expired credentials, we aim to actually renew them
if we can. However due to incorrect checks and not clearing of the
ret_maj variable after checks we end up returning an error instead.

Also fix mechglue to also save and properly report the first call errors
when both remote and local fail.

Resolves: #170

Signed-off-by: Simo Sorce <simo@redhat.com>
Reviewed-by: Robbie Harwood <rharwood@redhat.com>
(cherry picked from commit dc462321226f59ceaab0d3db47446a694a8ecba2)
---
 proxy/src/gp_creds.c                  | 14 +++++++++-----
 proxy/src/mechglue/gpp_acquire_cred.c |  5 +++++
 2 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/proxy/src/gp_creds.c b/proxy/src/gp_creds.c
index 5d84904..171a724 100644
--- a/proxy/src/gp_creds.c
+++ b/proxy/src/gp_creds.c
@@ -629,8 +629,12 @@ uint32_t gp_add_krb5_creds(uint32_t *min,
         ret_maj = gp_check_cred(&ret_min, in_cred, desired_name, cred_usage);
         if (ret_maj == GSS_S_COMPLETE) {
             return GSS_S_COMPLETE;
-        } else if (ret_maj != GSS_S_CREDENTIALS_EXPIRED &&
-                   ret_maj != GSS_S_NO_CRED) {
+        } else if (ret_maj == GSS_S_CREDENTIALS_EXPIRED ||
+                   ret_maj == GSS_S_NO_CRED) {
+            /* continue and try to obtain new creds */
+            ret_maj = 0;
+            ret_min = 0;
+        } else {
             *min = ret_min;
             return GSS_S_CRED_UNAVAIL;
         }
@@ -639,14 +643,14 @@ uint32_t gp_add_krb5_creds(uint32_t *min,
     if (acquire_type == ACQ_NORMAL) {
         ret_min = gp_get_cred_environment(gpcall, desired_name, &req_name,
                                           &cred_usage, &cred_store);
+        if (ret_min) {
+            ret_maj = GSS_S_CRED_UNAVAIL;
+        }
     } else if (desired_name) {
         ret_maj = gp_conv_gssx_to_name(&ret_min, desired_name, &req_name);
     }
     if (ret_maj) {
         goto done;
-    } else if (ret_min) {
-        ret_maj = GSS_S_CRED_UNAVAIL;
-        goto done;
     }
 
     if (!try_impersonate(gpcall->service, cred_usage, acquire_type)) {
diff --git a/proxy/src/mechglue/gpp_acquire_cred.c b/proxy/src/mechglue/gpp_acquire_cred.c
index d876699..514fdd1 100644
--- a/proxy/src/mechglue/gpp_acquire_cred.c
+++ b/proxy/src/mechglue/gpp_acquire_cred.c
@@ -186,6 +186,11 @@ OM_uint32 gssi_acquire_cred_from(OM_uint32 *minor_status,
     }
 
     if (behavior == GPP_REMOTE_FIRST) {
+        if (maj != GSS_S_COMPLETE) {
+            /* save errors */
+            tmaj = maj;
+            tmin = min;
+        }
         /* So remote failed, but we can fallback to local, try that */
         maj = acquire_local(&min, NULL, name,
                             time_req, desired_mechs, cred_usage, cred_store,