Whamcloud - gitweb
LU-16646 krb: get rid of MEMORY private cache for krb creds
[fs/lustre-release.git] / lustre / utils / gss / lgss_krb5_utils.c
index db5aab3..da85df3 100644 (file)
@@ -148,14 +148,8 @@ static void lgss_krb5_mutex_unlock(void)
         }
 }
 
-/*
- * NOTE
- *  - currently we only support "normal" cache types: "FILE" and "MEMORY".
- */
-
 #define krb5_err_msg(code)      error_message(code)
 
-const char *krb5_cc_type_mem    = "MEMORY:";
 const char *krb5_cc_type_file   = "FILE:";
 const char *krb5_cred_root_suffix  = "lustre_root";
 const char *krb5_cred_mds_suffix   = "lustre_mds";
@@ -394,58 +388,54 @@ void get_root_tgt_ccname(char *ccname, int size, unsigned int flag)
                  suffix, krb5_this_realm);
 }
 
-static
-int lkrb5_check_root_tgt_cc_base(krb5_context ctx,
-                                krb5_ccache ccache,
-                                char *ccname,
-                                unsigned int flag,
-                                uint64_t self_nid)
+static int lkrb5_check_root_tgt_cc_base(krb5_context ctx, char *ccname,
+                                       unsigned int flag, uint64_t self_nid)
 {
-        krb5_ccache             tgt_ccache;
-        krb5_creds              cred;
-        krb5_principal          princ;
-        krb5_cc_cursor          cursor;
-        krb5_error_code         code;
-        time_t                  now;
-        int                     rc = -1, found = 0;
-
-        /* prepare parsing the cache file */
-        code = krb5_cc_resolve(ctx, ccname, &tgt_ccache);
-        if (code) {
-                logmsg(LL_ERR, "resolve krb5 cc %s: %s\n",
-                       ccname, krb5_err_msg(code));
-                return -1;
-        }
+       krb5_ccache tgt_ccache;
+       krb5_creds cred;
+       krb5_principal princ;
+       krb5_cc_cursor cursor;
+       krb5_error_code code;
+       time_t now;
+       int rc = -1, found = 0;
+
+       /* prepare parsing the cache file */
+       code = krb5_cc_resolve(ctx, ccname, &tgt_ccache);
+       if (code) {
+               logmsg(LL_ERR, "resolve krb5 cc %s: %s\n",
+                      ccname, krb5_err_msg(code));
+               return -1;
+       }
 
-        /* checks the principal */
-        code = krb5_cc_get_principal(ctx, tgt_ccache, &princ);
-        if (code) {
-                logmsg(LL_ERR, "get cc principal: %s\n", krb5_err_msg(code));
-                goto out_cc;
-        }
+       /* checks the principal */
+       code = krb5_cc_get_principal(ctx, tgt_ccache, &princ);
+       if (code) {
+               logmsg(LL_ERR, "get cc principal: %s\n", krb5_err_msg(code));
+               goto out_cc;
+       }
 
        if (lkrb5_cc_check_tgt_princ(ctx, tgt_ccache, princ, flag, self_nid))
                goto out_princ;
 
-        /*
-         * find a valid entry
-         */
-        code = krb5_cc_start_seq_get(ctx, tgt_ccache, &cursor);
-        if (code) {
-                logmsg(LL_ERR, "start cc iteration: %s\n", krb5_err_msg(code));
-                goto out_princ;
-        }
+       /*
+        * find a valid entry
+        */
+       code = krb5_cc_start_seq_get(ctx, tgt_ccache, &cursor);
+       if (code) {
+               logmsg(LL_ERR, "start cc iteration: %s\n", krb5_err_msg(code));
+               goto out_princ;
+       }
 
-        now = time(0);
-        do {
-                krb5_timestamp  duration, delta;
+       now = time(0);
+       do {
+               krb5_timestamp  duration, delta;
 
-                code = krb5_cc_next_cred(ctx, tgt_ccache, &cursor, &cred);
-                if (code != 0)
-                        break;
+               code = krb5_cc_next_cred(ctx, tgt_ccache, &cursor, &cred);
+               if (code != 0)
+                       break;
 
-               logmsg(LL_DEBUG, "cred: server realm %.*s, type %d, name %.*s; "
-                      "time (%lld-%lld, renew till %lld), valid %lld\n",
+               logmsg(LL_DEBUG,
+                      "cred: server realm %.*s, type %d, name %.*s; time (%lld-%lld, renew till %lld), valid %lld\n",
                       krb5_princ_realm(ctx, cred.server)->length,
                       krb5_princ_realm(ctx, cred.server)->data,
                       krb5_princ_type(ctx, cred.server),
@@ -456,269 +446,228 @@ int lkrb5_check_root_tgt_cc_base(krb5_context ctx,
                       (long long)cred.times.renew_till,
                       (long long)(cred.times.endtime - now));
 
-                /* FIXME
-                 * we found the princ type is always 0 (KRB5_NT_UNKNOWN), why???
-                 */
-
-                /* FIXME how about inter-realm TGT??? FIXME */
-                if (lgss_krb5_strcasecmp(krb5_princ_name(ctx, cred.server),
-                                         "krbtgt"))
-                        continue;
-
-                if (lgss_krb5_strcasecmp(krb5_princ_realm(ctx, cred.server),
-                                         krb5_this_realm))
-                        continue;
-
-                /* check validity of time */
-                delta = 60 * 30; /* half an hour */
-                duration = cred.times.endtime - cred.times.starttime;
-                if (duration / 4 < delta)
-                        delta = duration / 4;
-
-                if (cred.times.starttime <= now &&
-                    cred.times.endtime >= now + delta) {
-                        found = 1;
-                        break;
-                }
-        } while (1);
-
-        if (!found) {
-                logmsg(LL_DEBUG, "doesn't find good TGT cache\n");
-                goto out_seq;
-        }
-
-        /* found a good cred, store it into @ccache */
-        logmsg(LL_DEBUG, "found good TGT cache\n");
-
-        code = krb5_cc_initialize(ctx, ccache, princ);
-        if (code) {
-                logmsg(LL_ERR, "init private cc: %s\n", krb5_err_msg(code));
-                goto out_seq;
-        }
-
-        code = krb5_cc_store_cred(ctx, ccache, &cred);
-        if (code) {
-                logmsg(LL_ERR, "store private cred: %s\n", krb5_err_msg(code));
-                goto out_seq;
-        }
+               /* FIXME
+                * we found the princ type is always 0 (KRB5_NT_UNKNOWN), why???
+                */
+
+               /* FIXME how about inter-realm TGT??? FIXME */
+               if (lgss_krb5_strcasecmp(krb5_princ_name(ctx, cred.server),
+                                        "krbtgt"))
+                       continue;
+
+               if (lgss_krb5_strcasecmp(krb5_princ_realm(ctx, cred.server),
+                                        krb5_this_realm))
+                       continue;
+
+               /* check validity of time */
+               delta = 60 * 30; /* half an hour */
+               duration = cred.times.endtime - cred.times.starttime;
+               if (duration / 4 < delta)
+                       delta = duration / 4;
+
+               if (cred.times.starttime <= now &&
+                   cred.times.endtime >= now + delta) {
+                       found = 1;
+                       break;
+               }
+       } while (1);
 
-        logmsg(LL_DEBUG, "store private ccache OK\n");
-        rc = 0;
+       if (!found) {
+               logmsg(LL_DEBUG, "doesn't find good TGT cache\n");
+               goto out_seq;
+       }
+       logmsg(LL_DEBUG, "found good TGT cache\n");
+       rc = 0;
 
 out_seq:
-        krb5_cc_end_seq_get(ctx, tgt_ccache, &cursor);
+       krb5_cc_end_seq_get(ctx, tgt_ccache, &cursor);
 out_princ:
-        krb5_free_principal(ctx, princ);
+       krb5_free_principal(ctx, princ);
 out_cc:
-        krb5_cc_close(ctx, tgt_ccache);
+       krb5_cc_close(ctx, tgt_ccache);
 
-        return rc;
+       return rc;
 }
 
 /**
  * find out whether current TGT cache is valid or not
  */
-static
-int lkrb5_check_root_tgt_cc(krb5_context ctx,
-                           krb5_ccache ccache,
-                           unsigned int root_flags,
-                           uint64_t self_nid)
+static int lkrb5_check_root_tgt_cc(krb5_context ctx, unsigned int root_flags,
+                                  uint64_t self_nid)
 {
-        struct stat             statbuf;
-        unsigned int            flag;
-        char                    ccname[1024];
-        char                   *ccfile;
-        int                     i, rc;
-
-        for (i = 0; i < LGSS_ROOT_CRED_NR; i++) {
-                flag = 1 << i;
-
-                if ((root_flags & flag) == 0)
-                        continue;
-
-                get_root_tgt_ccname(ccname, sizeof(ccname), flag);
-                logmsg(LL_DEBUG, "root krb5 TGT ccname: %s\n", ccname);
-
-                /* currently we only support type "FILE", firstly make sure
-                 * the cache file is there */
-                ccfile = ccname + strlen(krb5_cc_type);
-                if (stat(ccfile, &statbuf)) {
-                        logmsg(LL_DEBUG, "krb5 cc %s: %s\n",
-                               ccname, strerror(errno));
-                        continue;
-                }
+       char ccname[PATH_MAX];
+       struct stat statbuf;
+       unsigned int flag;
+       char *ccfile;
+       int i, rc;
+
+       for (i = 0; i < LGSS_ROOT_CRED_NR; i++) {
+               flag = 1 << i;
+
+               if ((root_flags & flag) == 0)
+                       continue;
+
+               get_root_tgt_ccname(ccname, sizeof(ccname), flag);
+               logmsg(LL_DEBUG, "root krb5 TGT ccname: %s\n", ccname);
+
+               /* currently we only support type "FILE", firstly make sure
+                * the cache file is there
+                */
+               ccfile = ccname + strlen(krb5_cc_type);
+               if (stat(ccfile, &statbuf)) {
+                       logmsg(LL_DEBUG, "krb5 cc %s: %s\n",
+                              ccname, strerror(errno));
+                       continue;
+               }
 
-               rc = lkrb5_check_root_tgt_cc_base(ctx, ccache, ccname, flag,
-                                                 self_nid);
-                if (rc == 0)
-                        return 0;
-        }
+               rc = lkrb5_check_root_tgt_cc_base(ctx, ccname, flag, self_nid);
+               if (rc == 0)
+                       return lgss_krb5_set_ccache_name(ccname);
+       }
 
-        logmsg(LL_TRACE, "doesn't find a valid tgt cc\n");
-        return -1;
+       logmsg(LL_TRACE, "doesn't find a valid tgt cc\n");
+       return -1;
 }
 
-static
-int lkrb5_get_root_tgt_keytab(krb5_context ctx,
-                              krb5_ccache ccache,
-                              krb5_keytab kt,
-                              krb5_principal princ,
-                              const char *ccname)
+static int lkrb5_get_root_tgt_keytab(krb5_context ctx, krb5_keytab kt,
+                                    krb5_principal princ, const char *ccname)
 {
-        krb5_get_init_creds_opt opts;
-        krb5_creds              cred;
-        krb5_ccache             tgt_ccache;
-        krb5_error_code         code;
-        int                     rc = -1;
-
-        krb5_get_init_creds_opt_init(&opts);
-        krb5_get_init_creds_opt_set_address_list(&opts, NULL);
-        /*
-         * by default krb5 library obtain ticket with lifetime shorter
-         * than the max value. we can change it here if we want. but
-         * seems not necessary now.
-         *
-        krb5_get_init_creds_opt_set_tkt_life(&opts, very-long-time);
-         *
-         */
-
-        /*
-         * obtain TGT and store into global ccache
-         */
-        code = krb5_get_init_creds_keytab(ctx, &cred, princ, kt,
-                                          0, NULL, &opts);
-        if (code) {
-                logmsg(LL_ERR, "failed to get root TGT for "
-                       "principal %.*s: %s\n",
-                       krb5_princ_name(ctx, princ)->length,
-                       krb5_princ_name(ctx, princ)->data,
-                       krb5_err_msg(code));
-                return -1;
-        }
-
-        code = krb5_cc_resolve(ctx, ccname, &tgt_ccache);
-        if (code) {
-                logmsg(LL_ERR, "resolve cc %s: %s\n",
-                       ccname, krb5_err_msg(code));
-                goto out_cred;
-        }
+       krb5_get_init_creds_opt opts;
+       krb5_creds cred;
+       krb5_ccache tgt_ccache;
+       krb5_error_code code;
+       int rc = -1;
+
+       krb5_get_init_creds_opt_init(&opts);
+       krb5_get_init_creds_opt_set_address_list(&opts, NULL);
+       /*
+        * by default krb5 library obtain ticket with lifetime shorter
+        * than the max value. we can change it here if we want. but
+        * seems not necessary now.
+        *
+        * krb5_get_init_creds_opt_set_tkt_life(&opts, very-long-time);
+        *
+        */
+
+       /*
+        * obtain TGT and store into cache
+        */
+       code = krb5_get_init_creds_keytab(ctx, &cred, princ, kt,
+                                         0, NULL, &opts);
+       if (code) {
+               logmsg(LL_ERR,
+                      "failed to get root TGT for principal %.*s: %s\n",
+                      krb5_princ_name(ctx, princ)->length,
+                      krb5_princ_name(ctx, princ)->data,
+                      krb5_err_msg(code));
+               return -1;
+       }
 
-        code = krb5_cc_initialize(ctx, tgt_ccache, princ);
-        if (code) {
-                logmsg(LL_ERR, "initialize cc %s: %s\n",
-                       ccname, krb5_err_msg(code));
-                goto out_cc;
-        }
+       code = krb5_cc_resolve(ctx, ccname, &tgt_ccache);
+       if (code) {
+               logmsg(LL_ERR, "resolve cc %s: %s\n",
+                      ccname, krb5_err_msg(code));
+               goto out_cred;
+       }
 
-        code = krb5_cc_store_cred(ctx, tgt_ccache, &cred);
-        if (code) {
-                logmsg(LL_ERR, "store cred to cc %s: %s\n",
-                       ccname, krb5_err_msg(code));
-                goto out_cc;
-        }
+       code = krb5_cc_initialize(ctx, tgt_ccache, princ);
+       if (code) {
+               logmsg(LL_ERR, "initialize cc %s: %s\n",
+                      ccname, krb5_err_msg(code));
+               goto out_cc;
+       }
 
-        logmsg(LL_INFO, "installed TGT of %.*s in cc %s\n",
-               krb5_princ_name(ctx, princ)->length,
-               krb5_princ_name(ctx, princ)->data,
-               ccname);
+       code = krb5_cc_store_cred(ctx, tgt_ccache, &cred);
+       if (code) {
+               logmsg(LL_ERR, "store cred to cc %s: %s\n",
+                      ccname, krb5_err_msg(code));
+               goto out_cc;
+       }
 
-        /*
-         * now store the cred into my own cc too
-         */
-        code = krb5_cc_initialize(ctx, ccache, princ);
-        if (code) {
-                logmsg(LL_ERR, "init mem cc: %s\n", krb5_err_msg(code));
-                goto out_cc;
-        }
+       logmsg(LL_INFO, "installed TGT of %.*s in cc %s\n",
+              krb5_princ_name(ctx, princ)->length,
+              krb5_princ_name(ctx, princ)->data,
+              ccname);
 
-        code = krb5_cc_store_cred(ctx, ccache, &cred);
-        if (code) {
-                logmsg(LL_ERR, "store mm cred: %s\n", krb5_err_msg(code));
-                goto out_cc;
-        }
+       rc = lgss_krb5_set_ccache_name(ccname);
 
-        logmsg(LL_DEBUG, "stored TGT into mem cc OK\n");
-        rc = 0;
 out_cc:
-        krb5_cc_close(ctx, tgt_ccache);
+       krb5_cc_close(ctx, tgt_ccache);
 out_cred:
-        krb5_free_cred_contents(ctx, &cred);
-        return rc;
+       krb5_free_cred_contents(ctx, &cred);
+       return rc;
 }
 
 /*
  * obtain a new root TGT
  */
-static
-int lkrb5_refresh_root_tgt_cc(krb5_context ctx,
-                             krb5_ccache ccache,
-                             unsigned int root_flags,
-                             uint64_t self_nid)
+static int lkrb5_refresh_root_tgt_cc(krb5_context ctx, unsigned int root_flags,
+                                    uint64_t self_nid)
 {
-        krb5_keytab             kt;
-        krb5_keytab_entry       kte;
-        krb5_kt_cursor          cursor;
-        krb5_principal          princ = NULL;
-        krb5_error_code         code;
-        char                    ccname[1024];
-        unsigned int            flag = 0;
-        int                     rc = -1;
-
-        /* prepare parsing the keytab file */
-        code = krb5_kt_resolve(ctx, krb5_keytab_file, &kt);
-        if (code) {
-                logmsg(LL_ERR, "resolve keytab %s: %s\n",
-                       krb5_keytab_file, krb5_err_msg(code));
-                return -1;
-        }
+       krb5_keytab kt;
+       krb5_keytab_entry kte;
+       krb5_kt_cursor cursor;
+       krb5_principal princ = NULL;
+       krb5_error_code code;
+       char ccname[1024];
+       unsigned int flag = 0;
+       int rc = -1;
+
+       /* prepare parsing the keytab file */
+       code = krb5_kt_resolve(ctx, krb5_keytab_file, &kt);
+       if (code) {
+               logmsg(LL_ERR, "resolve keytab %s: %s\n",
+                      krb5_keytab_file, krb5_err_msg(code));
+               return -1;
+       }
 
-        code = krb5_kt_start_seq_get(ctx, kt, &cursor);
-        if (code) {
-                logmsg(LL_ERR, "start kt iteration: %s\n", krb5_err_msg(code));
-                goto out_kt;
-        }
+       code = krb5_kt_start_seq_get(ctx, kt, &cursor);
+       if (code) {
+               logmsg(LL_ERR, "start kt iteration: %s\n", krb5_err_msg(code));
+               goto out_kt;
+       }
 
        /* iterate keytab to find proper an entry */
-        do {
-                krb5_data      *princname;
-
-                code = krb5_kt_next_entry(ctx, kt, &kte, &cursor);
-                if (code != 0)
-                        break;
-
-                logmsg(LL_TRACE, "kt entry: realm %.*s, type %d, "
-                       "size %d, name %.*s\n",
-                       krb5_princ_realm(ctx, kte.principal)->length,
-                       krb5_princ_realm(ctx, kte.principal)->data,
-                       krb5_princ_type(ctx, kte.principal),
-                       krb5_princ_size(ctx, kte.principal),
-                       krb5_princ_name(ctx, kte.principal)->length,
-                       krb5_princ_name(ctx, kte.principal)->data);
-
-                if (!princ_is_local_realm(ctx, kte.principal))
-                        continue;
-
-                princname = krb5_princ_name(ctx, kte.principal);
-
-                if ((root_flags & LGSS_ROOT_CRED_ROOT) != 0 &&
-                    lgss_krb5_strcmp(princname, LGSS_USR_ROOT_STR) == 0) {
-                        flag = LGSS_ROOT_CRED_ROOT;
-                } else if ((root_flags & LGSS_ROOT_CRED_MDT) != 0 &&
-                           lgss_krb5_strcmp(princname, LGSS_SVC_MDS_STR) == 0) {
-                        flag = LGSS_ROOT_CRED_MDT;
-                } else if ((root_flags & LGSS_ROOT_CRED_OST) != 0 &&
-                           lgss_krb5_strcmp(princname, LGSS_SVC_OSS_STR) == 0) {
-                        flag = LGSS_ROOT_CRED_OST;
-                } else {
-                        logmsg(LL_TRACE, "not what we want, skip\n");
-                        continue;
-                }
+       do {
+               krb5_data      *princname;
+
+               code = krb5_kt_next_entry(ctx, kt, &kte, &cursor);
+               if (code != 0)
+                       break;
+
+               logmsg(LL_TRACE,
+                      "kt entry: realm %.*s, type %d, size %d, name %.*s\n",
+                      krb5_princ_realm(ctx, kte.principal)->length,
+                      krb5_princ_realm(ctx, kte.principal)->data,
+                      krb5_princ_type(ctx, kte.principal),
+                      krb5_princ_size(ctx, kte.principal),
+                      krb5_princ_name(ctx, kte.principal)->length,
+                      krb5_princ_name(ctx, kte.principal)->data);
+
+               if (!princ_is_local_realm(ctx, kte.principal))
+                       continue;
+
+               princname = krb5_princ_name(ctx, kte.principal);
+
+               if ((root_flags & LGSS_ROOT_CRED_ROOT) != 0 &&
+                   lgss_krb5_strcmp(princname, LGSS_USR_ROOT_STR) == 0) {
+                       flag = LGSS_ROOT_CRED_ROOT;
+               } else if ((root_flags & LGSS_ROOT_CRED_MDT) != 0 &&
+                          lgss_krb5_strcmp(princname, LGSS_SVC_MDS_STR) == 0) {
+                       flag = LGSS_ROOT_CRED_MDT;
+               } else if ((root_flags & LGSS_ROOT_CRED_OST) != 0 &&
+                          lgss_krb5_strcmp(princname, LGSS_SVC_OSS_STR) == 0) {
+                       flag = LGSS_ROOT_CRED_OST;
+               } else {
+                       logmsg(LL_TRACE, "not what we want, skip\n");
+                       continue;
+               }
 
-                if (krb5_princ_component(ctx, kte.principal, 1) == NULL) {
-                        if (flag != LGSS_ROOT_CRED_ROOT) {
-                                logmsg(LL_TRACE, "no hostname, skip\n");
-                                continue;
-                        }
+               if (krb5_princ_component(ctx, kte.principal, 1) == NULL) {
+                       if (flag != LGSS_ROOT_CRED_ROOT) {
+                               logmsg(LL_TRACE, "no hostname, skip\n");
+                               continue;
+                       }
                } else {
                        if (svc_princ_verify_host(ctx, kte.principal, self_nid,
                                                  LL_TRACE)) {
@@ -728,90 +677,64 @@ int lkrb5_refresh_root_tgt_cc(krb5_context ctx,
                        }
                }
 
-                code = krb5_copy_principal(ctx, kte.principal, &princ);
-                if (code) {
-                        logmsg(LL_ERR, "copy princ: %s\n", krb5_err_msg(code));
-                        continue;
-                }
+               code = krb5_copy_principal(ctx, kte.principal, &princ);
+               if (code) {
+                       logmsg(LL_ERR, "copy princ: %s\n", krb5_err_msg(code));
+                       continue;
+               }
 
-                lassert(princ != NULL);
-                break;
-        } while (1);
+               lassert(princ != NULL);
+               break;
+       } while (1);
 
-        krb5_kt_end_seq_get(ctx, kt, &cursor);
+       krb5_kt_end_seq_get(ctx, kt, &cursor);
 
-        if (princ == NULL) {
-                logmsg(LL_ERR, "can't find proper keytab entry\n");
-                goto out_kt;
-        }
+       if (princ == NULL) {
+               logmsg(LL_ERR, "can't find proper keytab entry\n");
+               goto out_kt;
+       }
 
-        /* obtain root TGT */
-        get_root_tgt_ccname(ccname, sizeof(ccname), flag);
-        rc = lkrb5_get_root_tgt_keytab(ctx, ccache, kt, princ, ccname);
+       /* obtain root TGT */
+       get_root_tgt_ccname(ccname, sizeof(ccname), flag);
+       rc = lkrb5_get_root_tgt_keytab(ctx, kt, princ, ccname);
 
-        krb5_free_principal(ctx, princ);
+       krb5_free_principal(ctx, princ);
 out_kt:
-        krb5_kt_close(ctx, kt);
-        return rc;
+       krb5_kt_close(ctx, kt);
+       return rc;
 }
 
-static
-int lkrb5_prepare_root_cred(struct lgss_cred *cred)
+static int lkrb5_prepare_root_cred(struct lgss_cred *cred)
 {
-        krb5_context            ctx;
-        krb5_ccache             ccache;
-        krb5_error_code         code;
-        struct lgss_krb5_cred  *kcred;
-        int                     rc = -1;
-
-        lassert(krb5_this_realm != NULL);
-
-        kcred = (struct lgss_krb5_cred *) cred->lc_mech_cred;
-
-        /* compose the memory cc name, since the only user is myself,
-         * the name could be fixed */
-        snprintf(kcred->kc_ccname, sizeof(kcred->kc_ccname),
-                 "%s/self", krb5_cc_type_mem);
-        logmsg(LL_TRACE, "private cc: %s\n", kcred->kc_ccname);
+       krb5_context ctx;
+       krb5_error_code code;
+       int rc = -1;
 
-        code = krb5_init_context(&ctx);
-        if (code) {
-                logmsg(LL_ERR, "initialize krb5 context: %s\n",
-                       krb5_err_msg(code));
-                return -1;
-        }
+       lassert(krb5_this_realm != NULL);
 
-        code = krb5_cc_resolve(ctx, kcred->kc_ccname, &ccache);
-        if (code) {
-                logmsg(LL_ERR, "resolve krb5 cc %s: %s\n",
-                       kcred->kc_ccname, krb5_err_msg(code));
-                goto out_ctx;
-        }
-
-        /*
-         * search and/or obtain root TGT credential.
-         * it touched global (on-disk) tgt cache, do it inside mutex locking
-         */
-        lgss_krb5_mutex_lock();
+       code = krb5_init_context(&ctx);
+       if (code) {
+               logmsg(LL_ERR, "initialize krb5 context: %s\n",
+                      krb5_err_msg(code));
+               return -1;
+       }
 
-       rc = lkrb5_check_root_tgt_cc(ctx, ccache, cred->lc_root_flags,
+       /*
+        * search and/or obtain root TGT credential.
+        * it touched global (on-disk) tgt cache, do it inside mutex locking
+        */
+       lgss_krb5_mutex_lock();
+       rc = lkrb5_check_root_tgt_cc(ctx, cred->lc_root_flags,
                                     cred->lc_self_nid);
        if (rc != 0)
-               rc = lkrb5_refresh_root_tgt_cc(ctx, ccache,
-                                              cred->lc_root_flags,
+               rc = lkrb5_refresh_root_tgt_cc(ctx, cred->lc_root_flags,
                                               cred->lc_self_nid);
 
-        if (rc == 0)
-                rc = lgss_krb5_set_ccache_name(kcred->kc_ccname);
+       lgss_krb5_mutex_unlock();
+       krb5_free_context(ctx);
 
-        lgss_krb5_mutex_unlock();
-
-        krb5_cc_close(ctx, ccache);
-out_ctx:
-        krb5_free_context(ctx);
-
-        logmsg(LL_DEBUG, "prepare root credentail %s\n", rc ? "failed" : "OK");
-        return rc;
+       logmsg(LL_DEBUG, "prepare root credentail %s\n", rc ? "failed" : "OK");
+       return rc;
 }
 
 static