Blob Blame History Raw
From 7e0bcb958eb5861cb30a190dcac1e6422d65299e Mon Sep 17 00:00:00 2001
From: Nalin Dahyabhai <nalin@redhat.com>
Date: Fri, 1 Nov 2013 09:48:13 -0400
Subject: [PATCH 1/6] Don't try to stat() not-on-disk ccache residuals

Don't assume that ccache residual names are filenames which we can
stat() usefully.  Instead, use helper functions to call the library
routines to try to read the default principal name from caches.
---
 src/clients/ksu/ccache.c | 88 +++++++++++++++++++++++++++++-------------------
 src/clients/ksu/ksu.h    |  6 ++++
 src/clients/ksu/main.c   | 17 +++++-----
 3 files changed, 68 insertions(+), 43 deletions(-)

diff --git a/src/clients/ksu/ccache.c b/src/clients/ksu/ccache.c
index 9916c75..7917af2 100644
--- a/src/clients/ksu/ccache.c
+++ b/src/clients/ksu/ccache.c
@@ -60,12 +60,10 @@ krb5_error_code krb5_ccache_copy (context, cc_def, cc_other_tag,
 {
     int i=0;
     krb5_ccache  * cc_other;
-    const char * cc_def_name;
-    const char * cc_other_name;
+    const char * cc_other_type;
     krb5_error_code retval=0;
     krb5_creds ** cc_def_creds_arr = NULL;
     krb5_creds ** cc_other_creds_arr = NULL;
-    struct stat st_temp;
 
     cc_other = (krb5_ccache *)  xcalloc(1, sizeof (krb5_ccache));
 
@@ -74,10 +72,9 @@ krb5_error_code krb5_ccache_copy (context, cc_def, cc_other_tag,
         return retval;
     }
 
-    cc_def_name = krb5_cc_get_name(context, cc_def);
-    cc_other_name = krb5_cc_get_name(context, *cc_other);
+    cc_other_type = krb5_cc_get_type(context, *cc_other);
 
-    if ( ! stat(cc_def_name, &st_temp)){
+    if (krb5_ccache_is_initialized(context, cc_def)) {
         if((retval = krb5_get_nonexp_tkts(context,cc_def,&cc_def_creds_arr))){
             return retval;
         }
@@ -86,7 +83,8 @@ krb5_error_code krb5_ccache_copy (context, cc_def, cc_other_tag,
     *stored = krb5_find_princ_in_cred_list(context, cc_def_creds_arr,
                                            primary_principal);
 
-    if (!lstat( cc_other_name, &st_temp))
+    if (!krb5_cc_support_switch(context, cc_other_type) &&
+        krb5_ccache_name_is_initialized(context, cc_other_tag))
         return EINVAL;
 
     if (krb5_seteuid(0)||krb5_seteuid(target_uid)) {
@@ -533,24 +531,18 @@ krb5_error_code krb5_ccache_overwrite(context, ccs, cct, primary_principal)
     krb5_ccache cct;
     krb5_principal primary_principal;
 {
-    const char * cct_name;
-    const char * ccs_name;
     krb5_error_code retval=0;
     krb5_principal temp_principal;
     krb5_creds ** ccs_creds_arr = NULL;
     int i=0;
-    struct stat st_temp;
 
-    ccs_name = krb5_cc_get_name(context, ccs);
-    cct_name = krb5_cc_get_name(context, cct);
-
-    if ( ! stat(ccs_name, &st_temp)){
+    if (krb5_ccache_is_initialized(context, ccs)) {
         if ((retval = krb5_get_nonexp_tkts(context,  ccs, &ccs_creds_arr))){
             return retval;
         }
     }
 
-    if ( ! stat(cct_name, &st_temp)){
+    if (krb5_ccache_is_initialized(context, cct)) {
         if ((retval = krb5_cc_get_principal(context, cct, &temp_principal))){
             return retval;
         }
@@ -649,12 +641,10 @@ krb5_error_code krb5_ccache_copy_restricted (context, cc_def, cc_other_tag,
 
     int i=0;
     krb5_ccache  * cc_other;
-    const char * cc_def_name;
-    const char * cc_other_name;
+    const char * cc_other_type;
     krb5_error_code retval=0;
     krb5_creds ** cc_def_creds_arr = NULL;
     krb5_creds ** cc_other_creds_arr = NULL;
-    struct stat st_temp;
 
     cc_other = (krb5_ccache *)  xcalloc(1, sizeof (krb5_ccache));
 
@@ -663,19 +653,17 @@ krb5_error_code krb5_ccache_copy_restricted (context, cc_def, cc_other_tag,
         return retval;
     }
 
-    cc_def_name = krb5_cc_get_name(context, cc_def);
-    cc_other_name = krb5_cc_get_name(context, *cc_other);
+    cc_other_type = krb5_cc_get_type(context, *cc_other);
 
-    if ( ! stat(cc_def_name, &st_temp)){
-        if((retval = krb5_get_nonexp_tkts(context,cc_def,&cc_def_creds_arr))){
+    if (krb5_ccache_is_initialized(context, cc_def)) {
+        retval = krb5_get_nonexp_tkts(context, cc_def, &cc_def_creds_arr);
+        if (retval)
             return retval;
-        }
-
     }
 
-    if (!lstat( cc_other_name, &st_temp)) {
+    if (!krb5_cc_support_switch(context, cc_other_type) &&
+        krb5_ccache_name_is_initialized(context, cc_other_tag))
         return EINVAL;
-    }
 
     if (krb5_seteuid(0)||krb5_seteuid(target_uid)) {
         return errno;
@@ -723,12 +711,10 @@ krb5_error_code krb5_ccache_filter (context, cc, prst)
     krb5_creds ** cc_creds_arr = NULL;
     const char * cc_name;
     krb5_boolean stored;
-    struct stat st_temp;
 
     cc_name = krb5_cc_get_name(context, cc);
 
-    if ( ! stat(cc_name, &st_temp)){
-
+    if (krb5_ccache_is_initialized(context, cc)) {
         if (auth_debug) {
             fprintf(stderr,"putting cache %s through a filter for -z option\n",                     cc_name);
         }
@@ -793,12 +779,8 @@ krb5_error_code  krb5_find_princ_in_cache (context, cc, princ, found)
 {
     krb5_error_code retval;
     krb5_creds ** creds_list = NULL;
-    const char * cc_name;
-    struct stat st_temp;
 
-    cc_name = krb5_cc_get_name(context, cc);
-
-    if ( ! stat(cc_name, &st_temp)){
+    if (krb5_ccache_is_initialized(context, cc)) {
         if ((retval = krb5_get_nonexp_tkts(context, cc, &creds_list))){
             return retval;
         }
@@ -807,3 +789,41 @@ krb5_error_code  krb5_find_princ_in_cache (context, cc, princ, found)
     *found = krb5_find_princ_in_cred_list(context, creds_list, princ);
     return 0;
 }
+
+extern krb5_boolean
+krb5_ccache_name_is_initialized(krb5_context context, const char *cctag)
+{
+    krb5_error_code retval = 0;
+    krb5_ccache cc;
+    krb5_principal princ;
+
+    retval = krb5_cc_resolve(context, cctag, &cc);
+    if (retval)
+        return FALSE;
+
+    retval = krb5_cc_get_principal(context, cc, &princ);
+    if (retval == 0)
+        krb5_free_principal(context, princ);
+    krb5_cc_close(context, cc);
+
+    return retval == 0;
+}
+
+extern krb5_boolean
+krb5_ccache_is_initialized(krb5_context context, krb5_ccache def_cc)
+{
+    krb5_error_code retval = 0;
+    krb5_boolean result;
+    char *def_cc_name;
+
+    if (def_cc == NULL)
+        return FALSE;
+
+    retval = krb5_cc_get_full_name(context, def_cc, &def_cc_name);
+    if (retval)
+        return FALSE;
+
+    result = krb5_ccache_name_is_initialized(context, def_cc_name);
+    krb5_free_string(context, def_cc_name);
+    return result;
+}
diff --git a/src/clients/ksu/ksu.h b/src/clients/ksu/ksu.h
index f2c0811..2a63c21 100644
--- a/src/clients/ksu/ksu.h
+++ b/src/clients/ksu/ksu.h
@@ -141,6 +141,12 @@ extern krb5_error_code krb5_store_some_creds
 (krb5_context, krb5_ccache, krb5_creds **, krb5_creds **,
  krb5_principal, krb5_boolean *);
 
+extern krb5_boolean krb5_ccache_name_is_initialized
+(krb5_context, const char *);
+
+extern krb5_boolean krb5_ccache_is_initialized
+(krb5_context, krb5_ccache);
+
 extern krb5_error_code krb5_ccache_copy_restricted
 (krb5_context, krb5_ccache, char *, krb5_principal,
  krb5_ccache *, krb5_boolean *, uid_t);
diff --git a/src/clients/ksu/main.c b/src/clients/ksu/main.c
index 233eb52..e2ca06a 100644
--- a/src/clients/ksu/main.c
+++ b/src/clients/ksu/main.c
@@ -112,7 +112,6 @@ main (argc, argv)
     extern char * getpass(), *crypt();
     int pargc;
     char ** pargv;
-    struct stat  st_temp;
     krb5_boolean stored = FALSE;
     krb5_principal  kdc_server;
     krb5_boolean zero_password;
@@ -265,9 +264,10 @@ main (argc, argv)
                 if ( strchr(cc_source_tag, ':')){
                     cc_source_tag_tmp = strchr(cc_source_tag, ':') + 1;
 
-                    if( stat( cc_source_tag_tmp, &st_temp)){
+                    if (!krb5_ccache_name_is_initialized(ksu_context,
+                                                         cc_source_tag)) {
                         com_err(prog_name, errno,
-                                _("while looking for credentials file %s"),
+                                _("while looking for credentials cache %s"),
                                 cc_source_tag_tmp);
                         exit (1);
                     }
@@ -432,7 +432,8 @@ main (argc, argv)
                      (long) target_uid, gen_sym());
             cc_target_tag_tmp = strchr(cc_target_tag, ':') + 1;
 
-        }while ( !stat ( cc_target_tag_tmp, &st_temp));
+        } while (krb5_ccache_name_is_initialized(ksu_context,
+                                                 cc_target_tag));
     }
 
 
@@ -884,8 +885,6 @@ static void sweep_up(context, cc)
     krb5_ccache cc;
 {
     krb5_error_code retval;
-    const char * cc_name;
-    struct stat  st_temp;
 
     krb5_seteuid(0);
     if (krb5_seteuid(target_uid) < 0) {
@@ -894,9 +893,9 @@ static void sweep_up(context, cc)
         exit(1);
     }
 
-    cc_name = krb5_cc_get_name(context, cc);
-    if ( ! stat(cc_name, &st_temp)){
-        if ((retval = krb5_cc_destroy(context, cc)))
+    if (krb5_ccache_is_initialized(context, cc)) {
+        retval = krb5_cc_destroy(context, cc);
+        if (retval)
             com_err(prog_name, retval, _("while destroying cache"));
     }
 }
-- 
1.8.4.2