[krb5] Update collection cache patch set for ksu

Nalin Dahyabhai nalin at fedoraproject.org
Fri Aug 15 19:20:23 UTC 2014


commit c042f71c80c2a49c6d62bfceff303faeb7e742e1
Author: Nalin Dahyabhai <nalin at redhat.com>
Date:   Fri Aug 15 13:55:48 2014 -0400

    Update collection cache patch set for ksu
    
    - replace older proposed changes for ksu with backports of the changes
      after review and merging upstream (#1015559, #1026099, #1118347)

 ...-try-to-stat-not-on-disk-ccache-residuals.patch |  316 ---------------
 ...su-merge-krb5_ccache_copy-and-_restricted.patch |  230 +++++++++++
 ...u-don-t-stat-not-on-disk-ccache-residuals.patch |  369 +++++++++++++++++
 ...n-memory-cache-until-we-need-the-target-s.patch |  321 ---------------
 ...-to-destroy-the-ccache-we-re-copying-from.patch |   95 -----
 0003-Use-an-intermediate-memory-cache-in-ksu.patch |  417 ++++++++++++++++++++
 ...u-respect-the-default_ccache_name-setting.patch |  378 ++++++++++++++++++
 ...e-the-default_ccache_name-d-as-the-target.patch |  149 -------
 ...more-careful-of-target-ccache-collections.patch |  179 ---------
 ...y-config-entries-to-the-ksu-target-ccache.patch |   12 +-
 ...-randomness-for-ksu-secondary-cache-names.patch |  115 ++++++
 ...krb5_cc_new_unique-create-DIR-directories.patch |   37 ++
 krb5-1.12.1-pam.patch                              |   18 +-
 krb5.spec                                          |   32 +-
 14 files changed, 1578 insertions(+), 1090 deletions(-)
---
diff --git a/0001-In-ksu-merge-krb5_ccache_copy-and-_restricted.patch b/0001-In-ksu-merge-krb5_ccache_copy-and-_restricted.patch
new file mode 100644
index 0000000..ac7baa1
--- /dev/null
+++ b/0001-In-ksu-merge-krb5_ccache_copy-and-_restricted.patch
@@ -0,0 +1,230 @@
+From 74e775ac6d937c9d22be4fc1d429e5e62705fb7d Mon Sep 17 00:00:00 2001
+From: Nalin Dahyabhai <nalin at redhat.com>
+Date: Thu, 24 Jul 2014 15:39:53 -0400
+Subject: [PATCH 1/7] In ksu, merge krb5_ccache_copy() and _restricted()
+
+Other than whether or not they limit the creds it stores to the new
+ccache based on the principal name of the client for whom the creds were
+issued, there's no meaningful difference between what these two
+functions do.  Merge them.
+---
+ src/clients/ksu/ccache.c | 106 ++++++-----------------------------------------
+ src/clients/ksu/ksu.h    |   6 +--
+ src/clients/ksu/main.c   |  27 ++++--------
+ 3 files changed, 22 insertions(+), 117 deletions(-)
+
+diff --git a/src/clients/ksu/ccache.c b/src/clients/ksu/ccache.c
+index 9916c75..118fc53 100644
+--- a/src/clients/ksu/ccache.c
++++ b/src/clients/ksu/ccache.c
+@@ -47,12 +47,14 @@ void show_credential();
+ */
+ 
+ krb5_error_code krb5_ccache_copy (context, cc_def, cc_other_tag,
+-                                  primary_principal, cc_out, stored, target_uid)
++                                  primary_principal, restrict_creds, cc_out,
++                                  stored, target_uid)
+ /* IN */
+     krb5_context context;
+     krb5_ccache cc_def;
+     char *cc_other_tag;
+     krb5_principal primary_principal;
++    krb5_boolean restrict_creds;
+     uid_t target_uid;
+     /* OUT */
+     krb5_ccache *cc_out;
+@@ -83,9 +85,6 @@ 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))
+         return EINVAL;
+ 
+@@ -98,8 +97,16 @@ krb5_error_code krb5_ccache_copy (context, cc_def, cc_other_tag,
+         return retval;
+     }
+ 
+-    retval = krb5_store_all_creds(context, * cc_other, cc_def_creds_arr,
+-                                  cc_other_creds_arr);
++    if (restrict_creds) {
++        retval = krb5_store_some_creds(context, *cc_other, cc_def_creds_arr,
++                                       cc_other_creds_arr, primary_principal,
++                                       stored);
++    } else {
++        *stored = krb5_find_princ_in_cred_list(context, cc_def_creds_arr,
++                                               primary_principal);
++        retval = krb5_store_all_creds(context, *cc_other, cc_def_creds_arr,
++                                      cc_other_creds_arr);
++    }
+ 
+     if (cc_def_creds_arr){
+         while (cc_def_creds_arr[i]){
+@@ -623,93 +630,6 @@ krb5_error_code krb5_store_some_creds(context, cc, creds_def, creds_other, prst,
+     *stored = temp_stored;
+     return 0;
+ }
+-/******************************************************************
+-krb5_cache_copy_restricted
+-
+-gets rid of any expired tickets in the secondary cache,
+-copies the default cache into the secondary cache,
+-only credentials that are for prst are copied.
+-
+-the algorithm may look a bit funny,
+-but I had to do it this way, since cc_remove function did not come
+-with k5 beta 3 release.
+-************************************************************************/
+-
+-krb5_error_code krb5_ccache_copy_restricted (context, cc_def, cc_other_tag,
+-                                             prst, cc_out, stored, target_uid)
+-    krb5_context context;
+-    krb5_ccache cc_def;
+-    char *cc_other_tag;
+-    krb5_principal prst;
+-    uid_t target_uid;
+-    /* OUT */
+-    krb5_ccache *cc_out;
+-    krb5_boolean *stored;
+-{
+-
+-    int i=0;
+-    krb5_ccache  * cc_other;
+-    const char * cc_def_name;
+-    const char * cc_other_name;
+-    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));
+-
+-    if ((retval = krb5_cc_resolve(context, cc_other_tag, cc_other))){
+-        com_err(prog_name, retval, _("resolving ccache %s"), 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);
+-
+-    if ( ! stat(cc_def_name, &st_temp)){
+-        if((retval = krb5_get_nonexp_tkts(context,cc_def,&cc_def_creds_arr))){
+-            return retval;
+-        }
+-
+-    }
+-
+-    if (!lstat( cc_other_name, &st_temp)) {
+-        return EINVAL;
+-    }
+-
+-    if (krb5_seteuid(0)||krb5_seteuid(target_uid)) {
+-        return errno;
+-    }
+-
+-
+-    if ((retval = krb5_cc_initialize(context, *cc_other, prst))){
+-        return retval;
+-    }
+-
+-    retval = krb5_store_some_creds(context, * cc_other,
+-                                   cc_def_creds_arr, cc_other_creds_arr, prst, stored);
+-
+-
+-
+-    if (cc_def_creds_arr){
+-        while (cc_def_creds_arr[i]){
+-            krb5_free_creds(context, cc_def_creds_arr[i]);
+-            i++;
+-        }
+-    }
+-
+-    i=0;
+-
+-    if(cc_other_creds_arr){
+-        while (cc_other_creds_arr[i]){
+-            krb5_free_creds(context, cc_other_creds_arr[i]);
+-            i++;
+-        }
+-    }
+-
+-    *cc_out = *cc_other;
+-    return retval;
+-}
+ 
+ krb5_error_code krb5_ccache_filter (context, cc, prst)
+     krb5_context context;
+diff --git a/src/clients/ksu/ksu.h b/src/clients/ksu/ksu.h
+index f2c0811..9e0c613 100644
+--- a/src/clients/ksu/ksu.h
++++ b/src/clients/ksu/ksu.h
+@@ -107,7 +107,7 @@ extern krb5_error_code get_best_principal
+ /* ccache.c */
+ extern krb5_error_code krb5_ccache_copy
+ (krb5_context, krb5_ccache, char *, krb5_principal,
+- krb5_ccache *, krb5_boolean *, uid_t);
++ krb5_boolean, krb5_ccache *, krb5_boolean *, uid_t);
+ 
+ extern krb5_error_code krb5_store_all_creds
+ (krb5_context, krb5_ccache, krb5_creds **, krb5_creds **);
+@@ -141,10 +141,6 @@ extern krb5_error_code krb5_store_some_creds
+ (krb5_context, krb5_ccache, krb5_creds **, krb5_creds **,
+  krb5_principal, krb5_boolean *);
+ 
+-extern krb5_error_code krb5_ccache_copy_restricted
+-(krb5_context, krb5_ccache, char *, krb5_principal,
+- krb5_ccache *, krb5_boolean *, uid_t);
+-
+ extern krb5_error_code krb5_ccache_refresh
+ (krb5_context, krb5_ccache);
+ 
+diff --git a/src/clients/ksu/main.c b/src/clients/ksu/main.c
+index 233eb52..62f3bc0 100644
+--- a/src/clients/ksu/main.c
++++ b/src/clients/ksu/main.c
+@@ -117,6 +117,7 @@ main (argc, argv)
+     krb5_principal  kdc_server;
+     krb5_boolean zero_password;
+     char * dir_of_cc_target;
++    krb5_boolean restrict_creds;
+ 
+     options.opt = KRB5_DEFAULT_OPTIONS;
+     options.lifetime = KRB5_DEFAULT_TKT_LIFE;
+@@ -464,25 +465,13 @@ main (argc, argv)
+        then only the credentials for that particular user
+        should be copied */
+ 
+-    if ((source_uid == 0) && (target_uid != 0)) {
+-
+-        if ((retval = krb5_ccache_copy_restricted(ksu_context,  cc_source,
+-                                                  cc_target_tag, client,
+-                                                  &cc_target, &stored,
+-                                                  target_uid))){
+-            com_err(prog_name, retval, _("while copying cache %s to %s"),
+-                    krb5_cc_get_name(ksu_context, cc_source), cc_target_tag);
+-            exit(1);
+-        }
+-
+-    } else {
+-        if ((retval = krb5_ccache_copy(ksu_context, cc_source, cc_target_tag,
+-                                       client,&cc_target, &stored, target_uid))) {
+-            com_err(prog_name, retval, _("while copying cache %s to %s"),
+-                    krb5_cc_get_name(ksu_context, cc_source), cc_target_tag);
+-            exit(1);
+-        }
+-
++    restrict_creds = (source_uid == 0) && (target_uid != 0);
++    retval = krb5_ccache_copy(ksu_context, cc_source, cc_target_tag, client,
++                              restrict_creds, &cc_target, &stored, target_uid);
++    if (retval) {
++        com_err(prog_name, retval, _("while copying cache %s to %s"),
++                krb5_cc_get_name(ksu_context, cc_source), cc_target_tag);
++        exit(1);
+     }
+ 
+     /* Become root for authentication*/
+-- 
+2.0.4
+
diff --git a/0002-In-ksu-don-t-stat-not-on-disk-ccache-residuals.patch b/0002-In-ksu-don-t-stat-not-on-disk-ccache-residuals.patch
new file mode 100644
index 0000000..262e7c7
--- /dev/null
+++ b/0002-In-ksu-don-t-stat-not-on-disk-ccache-residuals.patch
@@ -0,0 +1,369 @@
+From 9ebae7cb434b9b177c0af85c67a6d6267f46bc68 Mon Sep 17 00:00:00 2001
+From: Nalin Dahyabhai <nalin at redhat.com>
+Date: Fri, 1 Nov 2013 09:48:13 -0400
+Subject: [PATCH 2/7] In ksu, don't 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, and
+use whether or not that succeeds as an indication of whether or not
+there's a ccache in a given location.
+
+ticket: 7728
+---
+ src/clients/ksu/ccache.c    | 60 ++++++++++++++++++++--------------
+ src/clients/ksu/heuristic.c | 13 ++------
+ src/clients/ksu/ksu.h       |  8 +++--
+ src/clients/ksu/main.c      | 79 +++++++++------------------------------------
+ 4 files changed, 60 insertions(+), 100 deletions(-)
+
+diff --git a/src/clients/ksu/ccache.c b/src/clients/ksu/ccache.c
+index 118fc53..5f57279 100644
+--- a/src/clients/ksu/ccache.c
++++ b/src/clients/ksu/ccache.c
+@@ -62,12 +62,9 @@ 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;
+     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));
+ 
+@@ -76,16 +73,13 @@ 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);
+-
+-    if ( ! stat(cc_def_name, &st_temp)){
++    if (ks_ccache_is_initialized(context, cc_def)) {
+         if((retval = krb5_get_nonexp_tkts(context,cc_def,&cc_def_creds_arr))){
+             return retval;
+         }
+     }
+ 
+-    if (!lstat( cc_other_name, &st_temp))
++    if (ks_ccache_name_is_initialized(context, cc_other_tag))
+         return EINVAL;
+ 
+     if (krb5_seteuid(0)||krb5_seteuid(target_uid)) {
+@@ -540,24 +534,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 (ks_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 (ks_ccache_is_initialized(context, cct)) {
+         if ((retval = krb5_cc_get_principal(context, cct, &temp_principal))){
+             return retval;
+         }
+@@ -643,12 +631,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 (ks_ccache_is_initialized(context, cc)) {
+         if (auth_debug) {
+             fprintf(stderr,"putting cache %s through a filter for -z option\n",                     cc_name);
+         }
+@@ -713,12 +699,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 (ks_ccache_is_initialized(context, cc)) {
+         if ((retval = krb5_get_nonexp_tkts(context, cc, &creds_list))){
+             return retval;
+         }
+@@ -727,3 +709,33 @@ 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;
+ }
++
++krb5_boolean
++ks_ccache_name_is_initialized(krb5_context context, const char *cctag)
++{
++    krb5_boolean result;
++    krb5_ccache cc;
++
++    if (krb5_cc_resolve(context, cctag, &cc) != 0)
++        return FALSE;
++    result = ks_ccache_is_initialized(context, cc);
++    krb5_cc_close(context, cc);
++
++    return result;
++}
++
++krb5_boolean
++ks_ccache_is_initialized(krb5_context context, krb5_ccache cc)
++{
++    krb5_principal princ;
++    krb5_error_code retval;
++
++    if (cc == NULL)
++        return FALSE;
++
++    retval = krb5_cc_get_principal(context, cc, &princ);
++    if (retval == 0)
++        krb5_free_principal(context, princ);
++
++    return retval == 0;
++}
+diff --git a/src/clients/ksu/heuristic.c b/src/clients/ksu/heuristic.c
+index 99b54e5..f73b8eb 100644
+--- a/src/clients/ksu/heuristic.c
++++ b/src/clients/ksu/heuristic.c
+@@ -397,12 +397,8 @@ krb5_error_code find_either_ticket (context, cc, client, end_server, found)
+     krb5_principal kdc_server;
+     krb5_error_code retval;
+     krb5_boolean temp_found = FALSE;
+-    const char * cc_source_name;
+-    struct stat st_temp;
+ 
+-    cc_source_name = krb5_cc_get_name(context, cc);
+-
+-    if ( ! stat(cc_source_name, &st_temp)){
++    if (ks_ccache_is_initialized(context, cc)) {
+ 
+         retval = find_ticket(context, cc, client, end_server, &temp_found);
+         if (retval)
+@@ -539,7 +535,6 @@ krb5_error_code get_best_princ_for_target(context, source_uid, target_uid,
+ {
+ 
+     princ_info princ_trials[10];
+-    const char * cc_source_name;
+     krb5_principal cc_def_princ = NULL;
+     krb5_principal temp_client;
+     krb5_principal target_client;
+@@ -551,7 +546,6 @@ krb5_error_code get_best_princ_for_target(context, source_uid, target_uid,
+     struct stat tb;
+     int count =0;
+     int i;
+-    struct stat st_temp;
+ 
+     *path_out = 0;
+ 
+@@ -559,10 +553,7 @@ krb5_error_code get_best_princ_for_target(context, source_uid, target_uid,
+     if (options->princ)
+         return 0;
+ 
+-    cc_source_name = krb5_cc_get_name(context, cc_source);
+-
+-
+-    if (! stat(cc_source_name, &st_temp)) {
++    if (ks_ccache_is_initialized(context, cc_source)) {
+         retval = krb5_cc_get_principal(context, cc_source, &cc_def_princ);
+         if (retval)
+             return retval;
+diff --git a/src/clients/ksu/ksu.h b/src/clients/ksu/ksu.h
+index 9e0c613..e1e34f1 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 ks_ccache_name_is_initialized
++(krb5_context, const char *);
++
++extern krb5_boolean ks_ccache_is_initialized
++(krb5_context, krb5_ccache);
++
+ extern krb5_error_code krb5_ccache_refresh
+ (krb5_context, krb5_ccache);
+ 
+@@ -198,8 +204,6 @@ extern int standard_shell (char *);
+ 
+ extern krb5_error_code get_params (int *, int, char **, char ***);
+ 
+-extern char *get_dir_of_file (const char *);
+-
+ /* heuristic.c */
+ extern krb5_error_code get_all_princ_from_file (FILE *, char ***);
+ 
+diff --git a/src/clients/ksu/main.c b/src/clients/ksu/main.c
+index 62f3bc0..8c49f94 100644
+--- a/src/clients/ksu/main.c
++++ b/src/clients/ksu/main.c
+@@ -51,7 +51,6 @@ static void print_status( const char *fmt, ...)
+     __attribute__ ((__format__ (__printf__, 1, 2)))
+ #endif
+     ;
+-char * get_dir_of_file();
+ 
+ /* Note -e and -a options are mutually exclusive */
+ /* insure the proper specification of target user as well as catching
+@@ -96,7 +95,6 @@ main (argc, argv)
+     const char * cc_source_tag = NULL;
+     uid_t source_gid;
+     const char * cc_source_tag_tmp = NULL;
+-    char * cc_target_tag_tmp=NULL;
+     char * cmd = NULL, * exec_cmd = NULL;
+     int errflg = 0;
+     krb5_boolean auth_val;
+@@ -112,11 +110,9 @@ 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;
+-    char * dir_of_cc_target;
+     krb5_boolean restrict_creds;
+ 
+     options.opt = KRB5_DEFAULT_OPTIONS;
+@@ -266,9 +262,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 (!ks_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);
+                     }
+@@ -419,32 +416,18 @@ main (argc, argv)
+         exit(1);
+     }
+ 
+-    if (cc_target_tag == NULL) {
+-
+-        cc_target_tag = (char *)xcalloc(KRB5_SEC_BUFFSIZE ,sizeof(char));
+-        /* make sure that the new ticket file does not already exist
+-           This is run as source_uid because it is reasonable to
+-           require the source user to have write to where the target
+-           cache will be created.*/
+-
+-        do {
+-            snprintf(cc_target_tag, KRB5_SEC_BUFFSIZE, "%s%ld.%d",
+-                     KRB5_SECONDARY_CACHE,
+-                     (long) target_uid, gen_sym());
+-            cc_target_tag_tmp = strchr(cc_target_tag, ':') + 1;
+-
+-        }while ( !stat ( cc_target_tag_tmp, &st_temp));
+-    }
+-
+-
+-    dir_of_cc_target = get_dir_of_file(cc_target_tag_tmp);
+-
+-    if (access(dir_of_cc_target, R_OK | W_OK )){
+-        fprintf(stderr,
+-                _("%s does not have correct permissions for %s\n"),
+-                source_user, cc_target_tag);
+-        exit(1);
+-    }
++    /*
++     * Make sure that the new ticket file does not already exist.
++     * This is run as source_uid because it is reasonable to
++     * require the source user to have write to where the target
++     * cache will be created.
++     */
++    cc_target_tag = (char *)xcalloc(KRB5_SEC_BUFFSIZE, sizeof(char));
++    do {
++        snprintf(cc_target_tag, KRB5_SEC_BUFFSIZE, "%s%ld.%d",
++                 KRB5_SECONDARY_CACHE,
++                 (long)target_uid, gen_sym());
++    } while (ks_ccache_name_is_initialized(ksu_context, cc_target_tag));
+ 
+     if (auth_debug){
+         fprintf(stderr, " source cache =  %s\n", cc_source_tag);
+@@ -747,13 +730,6 @@ main (argc, argv)
+         exit(1);
+     }
+ 
+-    if (access( cc_target_tag_tmp, R_OK | W_OK )){
+-        com_err(prog_name, errno,
+-                _("%s does not have correct permissions for %s, %s aborted"),
+-                target_user, cc_target_tag_tmp, prog_name);
+-        exit(1);
+-    }
+-
+     if ( cc_source)
+         krb5_cc_close(ksu_context, cc_source);
+ 
+@@ -873,8 +849,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) {
+@@ -883,8 +857,7 @@ static void sweep_up(context, cc)
+         exit(1);
+     }
+ 
+-    cc_name = krb5_cc_get_name(context, cc);
+-    if ( ! stat(cc_name, &st_temp)){
++    if (ks_ccache_is_initialized(context, cc)) {
+         if ((retval = krb5_cc_destroy(context, cc)))
+             com_err(prog_name, retval, _("while destroying cache"));
+     }
+@@ -937,26 +910,6 @@ void print_status(const char *fmt, ...)
+     }
+ }
+ 
+-
+-char *get_dir_of_file(path)
+-    const char *path;
+-{
+-    char * temp_path;
+-    char * ptr;
+-
+-    temp_path =  xstrdup(path);
+-
+-    if ((ptr = strrchr( temp_path, '/'))) {
+-        *ptr = '\0';
+-    } else {
+-        free (temp_path);
+-        temp_path = xmalloc(MAXPATHLEN);
+-        if (temp_path)
+-            getcwd(temp_path, MAXPATHLEN);
+-    }
+-    return temp_path;
+-}
+-
+ krb5_error_code
+ ksu_tgtname(context, server, client, tgtprinc)
+     krb5_context context;
+-- 
+2.0.4
+
diff --git a/0003-Use-an-intermediate-memory-cache-in-ksu.patch b/0003-Use-an-intermediate-memory-cache-in-ksu.patch
new file mode 100644
index 0000000..4bef600
--- /dev/null
+++ b/0003-Use-an-intermediate-memory-cache-in-ksu.patch
@@ -0,0 +1,417 @@
+From dccc80a469b1925fcfe7697406a69912efe4baa1 Mon Sep 17 00:00:00 2001
+From: Nalin Dahyabhai <nalin at dahyabhai.net>
+Date: Wed, 30 Oct 2013 21:45:35 -0400
+Subject: [PATCH 3/7] Use an intermediate memory cache in ksu
+
+Instead of copying source or obtained creds into the target cache and
+changing ownership if everything succeeds, copy them into a MEMORY:
+cache and then, if everything succeeds, create the target cache as the
+target user.
+
+We no longer need to clean up the temporary ccache when exiting in
+most error cases.
+
+Use a fake principal name ("_ksu/_ksu at _ksu") as the primary holder of
+the temporary cache so that we won't accidentally select it when we
+make a subsequent call to krb5_cc_cache_match() (to be added in a
+later patch) to find the target location where the creds should be
+stored for use while running as the target user.
+---
+ src/clients/ksu/ccache.c |  10 +--
+ src/clients/ksu/ksu.h    |   4 +-
+ src/clients/ksu/main.c   | 156 ++++++++++++++++++++++++-----------------------
+ 3 files changed, 87 insertions(+), 83 deletions(-)
+
+diff --git a/src/clients/ksu/ccache.c b/src/clients/ksu/ccache.c
+index 5f57279..d0fc389 100644
+--- a/src/clients/ksu/ccache.c
++++ b/src/clients/ksu/ccache.c
+@@ -47,14 +47,15 @@ void show_credential();
+ */
+ 
+ krb5_error_code krb5_ccache_copy (context, cc_def, cc_other_tag,
+-                                  primary_principal, restrict_creds, cc_out,
+-                                  stored, target_uid)
++                                  primary_principal, restrict_creds,
++                                  target_principal, cc_out, stored, target_uid)
+ /* IN */
+     krb5_context context;
+     krb5_ccache cc_def;
+     char *cc_other_tag;
+     krb5_principal primary_principal;
+     krb5_boolean restrict_creds;
++    krb5_principal target_principal;
+     uid_t target_uid;
+     /* OUT */
+     krb5_ccache *cc_out;
+@@ -86,10 +87,9 @@ krb5_error_code krb5_ccache_copy (context, cc_def, cc_other_tag,
+         return errno;
+     }
+ 
+-
+-    if ((retval = krb5_cc_initialize(context, *cc_other, primary_principal))){
++    retval = krb5_cc_initialize(context, *cc_other, target_principal);
++    if (retval)
+         return retval;
+-    }
+ 
+     if (restrict_creds) {
+         retval = krb5_store_some_creds(context, *cc_other, cc_def_creds_arr,
+diff --git a/src/clients/ksu/ksu.h b/src/clients/ksu/ksu.h
+index e1e34f1..08bf01b 100644
+--- a/src/clients/ksu/ksu.h
++++ b/src/clients/ksu/ksu.h
+@@ -106,8 +106,8 @@ extern krb5_error_code get_best_principal
+ 
+ /* ccache.c */
+ extern krb5_error_code krb5_ccache_copy
+-(krb5_context, krb5_ccache, char *, krb5_principal,
+- krb5_boolean, krb5_ccache *, krb5_boolean *, uid_t);
++(krb5_context, krb5_ccache, char *, krb5_principal, krb5_boolean,
++ krb5_principal, krb5_ccache *, krb5_boolean *, uid_t);
+ 
+ extern krb5_error_code krb5_store_all_creds
+ (krb5_context, krb5_ccache, krb5_creds **, krb5_creds **);
+diff --git a/src/clients/ksu/main.c b/src/clients/ksu/main.c
+index 8c49f94..d1bb8ca 100644
+--- a/src/clients/ksu/main.c
++++ b/src/clients/ksu/main.c
+@@ -42,10 +42,13 @@ char * gb_err = NULL;
+ int quiet = 0;
+ /***********/
+ 
++#define KS_TEMPORARY_CACHE "MEMORY:_ksu"
++#define KS_TEMPORARY_PRINC "_ksu/_ksu at _ksu"
+ #define _DEF_CSH "/bin/csh"
+ static int set_env_var (char *, char *);
+ static void sweep_up (krb5_context, krb5_ccache);
+ static char * ontty (void);
++static krb5_error_code set_ccname_env(krb5_context, krb5_ccache);
+ static void print_status( const char *fmt, ...)
+ #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)
+     __attribute__ ((__format__ (__printf__, 1, 2)))
+@@ -84,8 +87,8 @@ main (argc, argv)
+     int option=0;
+     int statusp=0;
+     krb5_error_code retval = 0;
+-    krb5_principal client = NULL;
+-    krb5_ccache cc_target = NULL;
++    krb5_principal client = NULL, tmp_princ = NULL;
++    krb5_ccache cc_tmp = NULL, cc_target = NULL;
+     krb5_context ksu_context;
+     char * cc_target_tag = NULL;
+     char * target_user = NULL;
+@@ -93,7 +96,6 @@ main (argc, argv)
+ 
+     krb5_ccache cc_source = NULL;
+     const char * cc_source_tag = NULL;
+-    uid_t source_gid;
+     const char * cc_source_tag_tmp = NULL;
+     char * cmd = NULL, * exec_cmd = NULL;
+     int errflg = 0;
+@@ -342,8 +344,6 @@ main (argc, argv)
+     /* allocate space and copy the usernamane there */
+     source_user = xstrdup(pwd->pw_name);
+     source_uid = pwd->pw_uid;
+-    source_gid = pwd->pw_gid;
+-
+ 
+     if (!strcmp(SOURCE_USER_LOGIN, target_user)){
+         target_user = xstrdup (source_user);
+@@ -435,25 +435,32 @@ main (argc, argv)
+     }
+ 
+     /*
+-      Only when proper authentication and authorization
+-      takes place, the target user becomes the owner of the cache.
+-    */
+-
+-    /* we continue to run as source uid until
+-       the middle of the copy, when becomewe become the target user
+-       The cache is owned by the target user.*/
++     * After proper authentication and authorization, populate a cache for the
++     * target user.
++     */
+ 
++    /*
++     * We read the set of creds we want to copy from the source ccache as the
++     * source uid, become root for authentication, and then become the target
++     * user to handle authorization and creating the target user's cache.
++     */
+ 
+     /* if root ksu's to a regular user, then
+        then only the credentials for that particular user
+        should be copied */
+ 
+     restrict_creds = (source_uid == 0) && (target_uid != 0);
+-    retval = krb5_ccache_copy(ksu_context, cc_source, cc_target_tag, client,
+-                              restrict_creds, &cc_target, &stored, target_uid);
++    retval = krb5_parse_name(ksu_context, KS_TEMPORARY_PRINC, &tmp_princ);
++    if (retval) {
++        com_err(prog_name, retval, _("while parsing temporary name"));
++        exit(1);
++    }
++    retval = krb5_ccache_copy(ksu_context, cc_source, KS_TEMPORARY_CACHE,
++                              client, restrict_creds, tmp_princ, &cc_tmp,
++                              &stored, 0);
+     if (retval) {
+         com_err(prog_name, retval, _("while copying cache %s to %s"),
+-                krb5_cc_get_name(ksu_context, cc_source), cc_target_tag);
++                krb5_cc_get_name(ksu_context, cc_source), KS_TEMPORARY_CACHE);
+         exit(1);
+     }
+ 
+@@ -473,7 +480,6 @@ main (argc, argv)
+                                       &kdc_server))){
+                 com_err(prog_name, retval,
+                         _("while creating tgt for local realm"));
+-                sweep_up(ksu_context, cc_target);
+                 exit(1);
+             }
+ 
+@@ -481,13 +487,12 @@ main (argc, argv)
+                               "enter it here and are logged\n"));
+             fprintf(stderr, _("         in remotely using an unsecure "
+                               "(non-encrypted) channel.\n"));
+-            if (krb5_get_tkt_via_passwd (ksu_context, &cc_target, client,
+-                                         kdc_server, &options,
+-                                         &zero_password) == FALSE){
++            if (krb5_get_tkt_via_passwd(ksu_context, &cc_tmp, client,
++                                        kdc_server, &options,
++                                        &zero_password) == FALSE){
+ 
+                 if (zero_password == FALSE){
+                     fprintf(stderr, _("Goodbye\n"));
+-                    sweep_up(ksu_context, cc_target);
+                     exit(1);
+                 }
+ 
+@@ -506,48 +511,20 @@ main (argc, argv)
+     if (source_uid && (source_uid != target_uid)) {
+         char * client_name;
+ 
+-        auth_val = krb5_auth_check(ksu_context, client, localhostname, &options,
+-                                   target_user,cc_target, &path_passwd, target_uid);
++        auth_val = krb5_auth_check(ksu_context, client, localhostname,
++                                   &options, target_user, cc_tmp,
++                                   &path_passwd, target_uid);
+ 
+         /* if Kerberos authentication failed then exit */
+         if (auth_val ==FALSE){
+             fprintf(stderr, _("Authentication failed.\n"));
+             syslog(LOG_WARNING, "'%s %s' authentication failed for %s%s",
+                    prog_name,target_user,source_user,ontty());
+-            sweep_up(ksu_context, cc_target);
+             exit(1);
+         }
+ 
+-#if 0
+-        /* At best, this avoids a single kdc request
+-           It is hard to implement dealing with file permissions and
+-           is unnecessary.  It is important
+-           to properly handle races in chown if this code is ever re-enabled.
+-        */
+-        /* cache the tickets if possible in the source cache */
+-        if (!path_passwd){
+-
+-            if ((retval = krb5_ccache_overwrite(ksu_context, cc_target, cc_source,
+-                                                client))){
+-                com_err (prog_name, retval,
+-                         "while copying cache %s to %s",
+-                         krb5_cc_get_name(ksu_context, cc_target),
+-                         krb5_cc_get_name(ksu_context, cc_source));
+-                sweep_up(ksu_context, cc_target);
+-                exit(1);
+-            }
+-            if (chown(cc_source_tag_tmp, source_uid, source_gid)){
+-                com_err(prog_name, errno,
+-                        "while changing owner for %s",
+-                        cc_source_tag_tmp);
+-                exit(1);
+-            }
+-        }
+-#endif /*0*/
+-
+         if ((retval = krb5_unparse_name(ksu_context, client, &client_name))) {
+             com_err(prog_name, retval, _("When unparsing name"));
+-            sweep_up(ksu_context, cc_target);
+             exit(1);
+         }
+ 
+@@ -560,7 +537,6 @@ main (argc, argv)
+         if (krb5_seteuid(target_uid)) {
+             com_err(prog_name, errno, _("while switching to target for "
+                                         "authorization check"));
+-            sweep_up(ksu_context, cc_target);
+             exit(1);
+         }
+ 
+@@ -568,14 +544,12 @@ main (argc, argv)
+                                          cmd, &authorization_val, &exec_cmd))){
+             com_err(prog_name,retval, _("while checking authorization"));
+             krb5_seteuid(0); /*So we have some chance of sweeping up*/
+-            sweep_up(ksu_context, cc_target);
+             exit(1);
+         }
+ 
+         if (krb5_seteuid(0)) {
+             com_err(prog_name, errno, _("while switching back from target "
+                                         "after authorization check"));
+-            sweep_up(ksu_context, cc_target);
+             exit(1);
+         }
+         if (authorization_val == TRUE){
+@@ -617,25 +591,25 @@ main (argc, argv)
+ 
+             }
+ 
+-            sweep_up(ksu_context, cc_target);
+             exit(1);
+         }
+     }
+ 
+     if( some_rest_copy){
+-        if ((retval = krb5_ccache_filter(ksu_context, cc_target, client))){
++        retval = krb5_ccache_filter(ksu_context, cc_tmp, client);
++        if (retval) {
+             com_err(prog_name,retval, _("while calling cc_filter"));
+-            sweep_up(ksu_context, cc_target);
+             exit(1);
+         }
+     }
+ 
+     if (all_rest_copy){
+-        if ((retval = krb5_cc_initialize(ksu_context, cc_target, client))){
++        retval = krb5_cc_initialize(ksu_context, cc_tmp, tmp_princ);
++        if (retval) {
+             com_err(prog_name, retval, _("while erasing target cache"));
+             exit(1);
+         }
+-
++        stored = FALSE;
+     }
+ 
+     /* get the shell of the user, this will be the shell used by su */
+@@ -653,7 +627,6 @@ main (argc, argv)
+ 
+     if (!standard_shell(target_pwd->pw_shell) && source_uid) {
+         fprintf(stderr, _("ksu: permission denied (shell).\n"));
+-        sweep_up(ksu_context, cc_target);
+         exit(1);
+     }
+ #endif /* HAVE_GETUSERSHELL */
+@@ -663,43 +636,28 @@ main (argc, argv)
+         if(set_env_var("USER", target_pwd->pw_name)){
+             fprintf(stderr,
+                     _("ksu: couldn't set environment variable USER\n"));
+-            sweep_up(ksu_context, cc_target);
+             exit(1);
+         }
+     }
+ 
+     if(set_env_var( "HOME", target_pwd->pw_dir)){
+         fprintf(stderr, _("ksu: couldn't set environment variable HOME\n"));
+-        sweep_up(ksu_context, cc_target);
+         exit(1);
+     }
+ 
+     if(set_env_var( "SHELL", shell)){
+         fprintf(stderr, _("ksu: couldn't set environment variable SHELL\n"));
+-        sweep_up(ksu_context, cc_target);
+-        exit(1);
+-    }
+-
+-    /* set the cc env name to target */
+-
+-    if(set_env_var( KRB5_ENV_CCNAME, cc_target_tag)){
+-        fprintf(stderr, _("ksu: couldn't set environment variable %s\n"),
+-                KRB5_ENV_CCNAME);
+-        sweep_up(ksu_context, cc_target);
+         exit(1);
+     }
+ 
+     /* set permissions */
+     if (setgid(target_pwd->pw_gid) < 0) {
+         perror("ksu: setgid");
+-        sweep_up(ksu_context, cc_target);
+         exit(1);
+     }
+ 
+-
+     if (initgroups(target_user, target_pwd->pw_gid)) {
+         fprintf(stderr, _("ksu: initgroups failed.\n"));
+-        sweep_up(ksu_context, cc_target);
+         exit(1);
+     }
+ 
+@@ -719,13 +677,36 @@ main (argc, argv)
+      */
+     if (setluid((uid_t) pwd->pw_uid) < 0) {
+         perror("setluid");
+-        sweep_up(ksu_context, cc_target);
+         exit(1);
+     }
+ #endif  /* HAVE_SETLUID */
+ 
+     if (setuid(target_pwd->pw_uid) < 0) {
+         perror("ksu: setuid");
++        exit(1);
++    }
++
++    retval = krb5_ccache_copy(ksu_context, cc_tmp, cc_target_tag,
++                              client, FALSE, client, &cc_target, &stored,
++                              target_pwd->pw_uid);
++    if (retval) {
++        com_err(prog_name, retval, _("while copying cache %s to %s"),
++                KS_TEMPORARY_CACHE, cc_target_tag);
++        exit(1);
++    }
++
++    if (stored && !ks_ccache_is_initialized(ksu_context, cc_target)) {
++        com_err(prog_name, errno,
++                _("%s does not have correct permissions for %s, %s aborted"),
++                target_user, cc_target_tag, prog_name);
++        exit(1);
++    }
++
++    free(cc_target_tag);
++
++    /* Set the cc env name to target. */
++    retval = set_ccname_env(ksu_context, cc_target);
++    if (retval != 0) {
+         sweep_up(ksu_context, cc_target);
+         exit(1);
+     }
+@@ -799,6 +780,29 @@ main (argc, argv)
+     }
+ }
+ 
++/* Set KRB5CCNAME in the environment to point to ccache.  Print an error
++ * message on failure. */
++static krb5_error_code
++set_ccname_env(krb5_context ksu_context, krb5_ccache ccache)
++{
++    krb5_error_code retval;
++    char *ccname;
++
++    retval = krb5_cc_get_full_name(ksu_context, ccache, &ccname);
++    if (retval) {
++        com_err(prog_name, retval, _("while reading cache name from ccache"));
++        return retval;
++    }
++    if (set_env_var(KRB5_ENV_CCNAME, ccname)) {
++        retval = errno;
++        fprintf(stderr,
++                _("ksu: couldn't set environment variable %s\n"),
++                KRB5_ENV_CCNAME);
++    }
++    krb5_free_string(ksu_context, ccname);
++    return retval;
++}
++
+ #ifdef HAVE_GETUSERSHELL
+ 
+ int standard_shell(sh)
+-- 
+2.0.4
+
diff --git a/0004-Make-ksu-respect-the-default_ccache_name-setting.patch b/0004-Make-ksu-respect-the-default_ccache_name-setting.patch
new file mode 100644
index 0000000..cb45f1b
--- /dev/null
+++ b/0004-Make-ksu-respect-the-default_ccache_name-setting.patch
@@ -0,0 +1,378 @@
+From 3a456898af626dcab4e1ab0749ca2ccb9ad6162b Mon Sep 17 00:00:00 2001
+From: Nalin Dahyabhai <nalin at dahyabhai.net>
+Date: Wed, 30 Oct 2013 21:47:14 -0400
+Subject: [PATCH 4/7] Make ksu respect the default_ccache_name setting
+
+Move the logic for resolving and initializing a cache that we're
+copying creds into out of krb5_ccache_copy(), and let the caller deal
+with it.  Add a helper functions to select/resolve an output ccache in
+the default location for the target user after we've switched to the
+target user's privileges.  If the destination is a collection, take
+care not to change which subsidiary is its primary, and reuse a
+subsidiary cache if we can.  If the destination is not a collection,
+append a unique value to its name to make a new ccache.
+
+[ghudson at mit.edu: some changes to variable names and comments; move
+responsibility for getting target ccache name from
+resolve_target_ccache to main]
+
+ticket: 7984 (new)
+---
+ src/clients/ksu/ccache.c |  35 +++------
+ src/clients/ksu/ksu.h    |   6 +-
+ src/clients/ksu/main.c   | 181 ++++++++++++++++++++++++++++++++++++++---------
+ 3 files changed, 157 insertions(+), 65 deletions(-)
+
+diff --git a/src/clients/ksu/ccache.c b/src/clients/ksu/ccache.c
+index d0fc389..4693bd4 100644
+--- a/src/clients/ksu/ccache.c
++++ b/src/clients/ksu/ccache.c
+@@ -46,59 +46,41 @@ void show_credential();
+    with k5 beta 3 release.
+ */
+ 
+-krb5_error_code krb5_ccache_copy (context, cc_def, cc_other_tag,
+-                                  primary_principal, restrict_creds,
+-                                  target_principal, cc_out, stored, target_uid)
++krb5_error_code krb5_ccache_copy(context, cc_def, target_principal, cc_target,
++                                 restrict_creds, primary_principal, stored)
+ /* IN */
+     krb5_context context;
+     krb5_ccache cc_def;
+-    char *cc_other_tag;
+-    krb5_principal primary_principal;
+-    krb5_boolean restrict_creds;
+     krb5_principal target_principal;
+-    uid_t target_uid;
++    krb5_ccache cc_target;
++    krb5_boolean restrict_creds;
++    krb5_principal primary_principal;
+     /* OUT */
+-    krb5_ccache *cc_out;
+     krb5_boolean *stored;
+ {
+     int i=0;
+-    krb5_ccache  * cc_other;
+     krb5_error_code retval=0;
+     krb5_creds ** cc_def_creds_arr = NULL;
+     krb5_creds ** cc_other_creds_arr = NULL;
+ 
+-    cc_other = (krb5_ccache *)  xcalloc(1, sizeof (krb5_ccache));
+-
+-    if ((retval = krb5_cc_resolve(context, cc_other_tag, cc_other))){
+-        com_err(prog_name, retval, _("resolving ccache %s"), cc_other_tag);
+-        return retval;
+-    }
+-
+     if (ks_ccache_is_initialized(context, cc_def)) {
+         if((retval = krb5_get_nonexp_tkts(context,cc_def,&cc_def_creds_arr))){
+             return retval;
+         }
+     }
+ 
+-    if (ks_ccache_name_is_initialized(context, cc_other_tag))
+-        return EINVAL;
+-
+-    if (krb5_seteuid(0)||krb5_seteuid(target_uid)) {
+-        return errno;
+-    }
+-
+-    retval = krb5_cc_initialize(context, *cc_other, target_principal);
++    retval = krb5_cc_initialize(context, cc_target, target_principal);
+     if (retval)
+         return retval;
+ 
+     if (restrict_creds) {
+-        retval = krb5_store_some_creds(context, *cc_other, cc_def_creds_arr,
++        retval = krb5_store_some_creds(context, cc_target, cc_def_creds_arr,
+                                        cc_other_creds_arr, primary_principal,
+                                        stored);
+     } else {
+         *stored = krb5_find_princ_in_cred_list(context, cc_def_creds_arr,
+                                                primary_principal);
+-        retval = krb5_store_all_creds(context, *cc_other, cc_def_creds_arr,
++        retval = krb5_store_all_creds(context, cc_target, cc_def_creds_arr,
+                                       cc_other_creds_arr);
+     }
+ 
+@@ -118,7 +100,6 @@ krb5_error_code krb5_ccache_copy (context, cc_def, cc_other_tag,
+         }
+     }
+ 
+-    *cc_out = *cc_other;
+     return retval;
+ }
+ 
+diff --git a/src/clients/ksu/ksu.h b/src/clients/ksu/ksu.h
+index 08bf01b..fbbf217 100644
+--- a/src/clients/ksu/ksu.h
++++ b/src/clients/ksu/ksu.h
+@@ -44,8 +44,6 @@
+ #define KRB5_DEFAULT_OPTIONS 0
+ #define KRB5_DEFAULT_TKT_LIFE 60*60*12 /* 12 hours */
+ 
+-#define KRB5_SECONDARY_CACHE "FILE:/tmp/krb5cc_"
+-
+ #define KRB5_LOGIN_NAME ".k5login"
+ #define KRB5_USERS_NAME ".k5users"
+ #define USE_DEFAULT_REALM_NAME "."
+@@ -106,8 +104,8 @@ extern krb5_error_code get_best_principal
+ 
+ /* ccache.c */
+ extern krb5_error_code krb5_ccache_copy
+-(krb5_context, krb5_ccache, char *, krb5_principal, krb5_boolean,
+- krb5_principal, krb5_ccache *, krb5_boolean *, uid_t);
++(krb5_context, krb5_ccache, krb5_principal, krb5_ccache,
++ krb5_boolean, krb5_principal, krb5_boolean *);
+ 
+ extern krb5_error_code krb5_store_all_creds
+ (krb5_context, krb5_ccache, krb5_creds **, krb5_creds **);
+diff --git a/src/clients/ksu/main.c b/src/clients/ksu/main.c
+index d1bb8ca..41a3bf8 100644
+--- a/src/clients/ksu/main.c
++++ b/src/clients/ksu/main.c
+@@ -54,6 +54,10 @@ static void print_status( const char *fmt, ...)
+     __attribute__ ((__format__ (__printf__, 1, 2)))
+ #endif
+     ;
++static krb5_error_code resolve_target_cache(krb5_context ksu_context,
++                                            krb5_principal princ,
++                                            krb5_ccache *ccache_out,
++                                            krb5_boolean *ccache_reused);
+ 
+ /* Note -e and -a options are mutually exclusive */
+ /* insure the proper specification of target user as well as catching
+@@ -112,7 +116,7 @@ main (argc, argv)
+     extern char * getpass(), *crypt();
+     int pargc;
+     char ** pargv;
+-    krb5_boolean stored = FALSE;
++    krb5_boolean stored = FALSE, cc_reused = FALSE;
+     krb5_principal  kdc_server;
+     krb5_boolean zero_password;
+     krb5_boolean restrict_creds;
+@@ -416,23 +420,8 @@ main (argc, argv)
+         exit(1);
+     }
+ 
+-    /*
+-     * Make sure that the new ticket file does not already exist.
+-     * This is run as source_uid because it is reasonable to
+-     * require the source user to have write to where the target
+-     * cache will be created.
+-     */
+-    cc_target_tag = (char *)xcalloc(KRB5_SEC_BUFFSIZE, sizeof(char));
+-    do {
+-        snprintf(cc_target_tag, KRB5_SEC_BUFFSIZE, "%s%ld.%d",
+-                 KRB5_SECONDARY_CACHE,
+-                 (long)target_uid, gen_sym());
+-    } while (ks_ccache_name_is_initialized(ksu_context, cc_target_tag));
+-
+-    if (auth_debug){
++    if (auth_debug)
+         fprintf(stderr, " source cache =  %s\n", cc_source_tag);
+-        fprintf(stderr, " target cache =  %s\n", cc_target_tag);
+-    }
+ 
+     /*
+      * After proper authentication and authorization, populate a cache for the
+@@ -455,14 +444,19 @@ main (argc, argv)
+         com_err(prog_name, retval, _("while parsing temporary name"));
+         exit(1);
+     }
+-    retval = krb5_ccache_copy(ksu_context, cc_source, KS_TEMPORARY_CACHE,
+-                              client, restrict_creds, tmp_princ, &cc_tmp,
+-                              &stored, 0);
++    retval = krb5_cc_resolve(ksu_context, KS_TEMPORARY_CACHE, &cc_tmp);
++    if (retval) {
++        com_err(prog_name, retval, _("while creating temporary cache"));
++        exit(1);
++    }
++    retval = krb5_ccache_copy(ksu_context, cc_source, tmp_princ, cc_tmp,
++                              restrict_creds, client, &stored);
+     if (retval) {
+         com_err(prog_name, retval, _("while copying cache %s to %s"),
+                 krb5_cc_get_name(ksu_context, cc_source), KS_TEMPORARY_CACHE);
+         exit(1);
+     }
++    krb5_cc_close(ksu_context, cc_source);
+ 
+     /* Become root for authentication*/
+ 
+@@ -686,23 +680,38 @@ main (argc, argv)
+         exit(1);
+     }
+ 
+-    retval = krb5_ccache_copy(ksu_context, cc_tmp, cc_target_tag,
+-                              client, FALSE, client, &cc_target, &stored,
+-                              target_pwd->pw_uid);
++    retval = resolve_target_cache(ksu_context, client, &cc_target, &cc_reused);
++    if (retval)
++        exit(1);
++    retval = krb5_cc_get_full_name(ksu_context, cc_target, &cc_target_tag);
+     if (retval) {
+-        com_err(prog_name, retval, _("while copying cache %s to %s"),
+-                KS_TEMPORARY_CACHE, cc_target_tag);
++        com_err(prog_name, retval, _("while getting name of target ccache"));
++        sweep_up(ksu_context, cc_target);
+         exit(1);
+     }
++    if (auth_debug)
++        fprintf(stderr, " target cache =  %s\n", cc_target_tag);
++    if (cc_reused)
++        keep_target_cache = TRUE;
+ 
+-    if (stored && !ks_ccache_is_initialized(ksu_context, cc_target)) {
+-        com_err(prog_name, errno,
+-                _("%s does not have correct permissions for %s, %s aborted"),
+-                target_user, cc_target_tag, prog_name);
+-        exit(1);
++    if (stored) {
++        retval = krb5_ccache_copy(ksu_context, cc_tmp, client, cc_target,
++                                  FALSE, client, &stored);
++        if (retval) {
++            com_err(prog_name, retval, _("while copying cache %s to %s"),
++                    KS_TEMPORARY_CACHE, cc_target_tag);
++            exit(1);
++        }
++
++        if (!ks_ccache_is_initialized(ksu_context, cc_target)) {
++            com_err(prog_name, errno,
++                    _("%s does not have correct permissions for %s, "
++                      "%s aborted"), target_user, cc_target_tag, prog_name);
++            exit(1);
++        }
+     }
+ 
+-    free(cc_target_tag);
++    krb5_free_string(ksu_context, cc_target_tag);
+ 
+     /* Set the cc env name to target. */
+     retval = set_ccname_env(ksu_context, cc_target);
+@@ -711,9 +720,6 @@ main (argc, argv)
+         exit(1);
+     }
+ 
+-    if ( cc_source)
+-        krb5_cc_close(ksu_context, cc_source);
+-
+     if (cmd){
+         if ((source_uid == 0) || (source_uid == target_uid )){
+             exec_cmd = cmd;
+@@ -803,6 +809,113 @@ set_ccname_env(krb5_context ksu_context, krb5_ccache ccache)
+     return retval;
+ }
+ 
++/*
++ * Get the configured default ccache name.  Unset KRB5CCNAME and force a
++ * recomputation so we don't use values for the source user.  Print an error
++ * message on failure.
++ */
++static krb5_error_code
++get_configured_defccname(krb5_context context, char **target_out)
++{
++    krb5_error_code retval;
++    const char *defname;
++    char *target;
++
++    *target_out = NULL;
++
++    if (unsetenv(KRB5_ENV_CCNAME) != 0) {
++        retval = errno;
++        com_err(prog_name, retval, _("while clearing the value of %s"),
++                KRB5_ENV_CCNAME);
++        return retval;
++    }
++
++    /* Make sure we don't have a cached value for a different uid. */
++    retval = krb5_cc_set_default_name(context, NULL);
++    if (retval != 0) {
++        com_err(prog_name, retval, _("while resetting target ccache name"));
++        return retval;
++    }
++
++    defname = krb5_cc_default_name(context);
++    target = (defname == NULL) ? NULL : strdup(defname);
++    if (target == NULL) {
++        com_err(prog_name, ENOMEM, _("while determining target ccache name"));
++        return ENOMEM;
++    }
++    *target_out = target;
++    return 0;
++}
++
++/* Determine where the target user's creds should be stored.  Print an error
++ * message on failure. */
++static krb5_error_code
++resolve_target_cache(krb5_context context, krb5_principal princ,
++                     krb5_ccache *ccache_out, krb5_boolean *ccache_reused)
++{
++    krb5_error_code retval;
++    krb5_boolean switchable, reused = FALSE;
++    krb5_ccache ccache = NULL;
++    char *sep, *ccname = NULL, *target;
++
++    *ccache_out = NULL;
++    *ccache_reused = FALSE;
++
++    retval = get_configured_defccname(context, &target);
++    if (retval != 0)
++        return retval;
++
++    /* Check if the configured default name uses a switchable type. */
++    sep = strchr(target, ':');
++    *sep = '\0';
++    switchable = krb5_cc_support_switch(context, target);
++    *sep = ':';
++
++    if (!switchable) {
++        /* Try to avoid destroying an in-use target ccache by coming up with
++         * the name of a cache that doesn't exist yet. */
++        do {
++            free(ccname);
++            if (asprintf(&ccname, "%s.%d", target, gen_sym()) < 0) {
++                retval = ENOMEM;
++                com_err(prog_name, ENOMEM,
++                        _("while allocating memory for target ccache name"));
++                goto cleanup;
++            }
++        } while (ks_ccache_name_is_initialized(context, ccname));
++        retval = krb5_cc_resolve(context, ccname, &ccache);
++    } else {
++        /* Look for a cache in the collection that we can reuse. */
++        retval = krb5_cc_cache_match(context, princ, &ccache);
++        if (retval == 0) {
++            reused = TRUE;
++        } else {
++            /* There isn't one, so create a new one. */
++            *sep = '\0';
++            retval = krb5_cc_new_unique(context, target, NULL, &ccache);
++            *sep = ':';
++            if (retval) {
++                com_err(prog_name, retval,
++                        _("while creating new target ccache"));
++                goto cleanup;
++            }
++            retval = krb5_cc_initialize(context, ccache, princ);
++            if (retval) {
++                com_err(prog_name, retval,
++                        _("while initializing target cache"));
++                goto cleanup;
++            }
++        }
++    }
++
++    *ccache_out = ccache;
++    *ccache_reused = reused;
++
++cleanup:
++    free(target);
++    return retval;
++}
++
+ #ifdef HAVE_GETUSERSHELL
+ 
+ int standard_shell(sh)
+-- 
+2.0.4
+
diff --git a/0006-Copy-config-entries-to-the-target-ccache.patch b/0005-Copy-config-entries-to-the-ksu-target-ccache.patch
similarity index 77%
rename from 0006-Copy-config-entries-to-the-target-ccache.patch
rename to 0005-Copy-config-entries-to-the-ksu-target-ccache.patch
index e7d033c..e004136 100644
--- a/0006-Copy-config-entries-to-the-target-ccache.patch
+++ b/0005-Copy-config-entries-to-the-ksu-target-ccache.patch
@@ -1,19 +1,21 @@
-From 0d2a65745287238c5e5e2cc2fc68c40b358e68e4 Mon Sep 17 00:00:00 2001
+From 297496f0938955ba4aaf0ebecf4e393e527b8cbf Mon Sep 17 00:00:00 2001
 From: Nalin Dahyabhai <nalin at dahyabhai.net>
 Date: Tue, 29 Oct 2013 16:27:20 -0400
-Subject: [PATCH 6/6] Copy config entries to the target ccache
+Subject: [PATCH 5/7] Copy config entries to the ksu target ccache
 
 When we try to screen out expired creds while reading them from one
 ccache to eventually store in another, also keep configuration entries.
+
+ticket: 7986 (new)
 ---
  src/clients/ksu/ccache.c | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)
 
 diff --git a/src/clients/ksu/ccache.c b/src/clients/ksu/ccache.c
-index 2a97893..83b5e46 100644
+index 4693bd4..0f9e042 100644
 --- a/src/clients/ksu/ccache.c
 +++ b/src/clients/ksu/ccache.c
-@@ -269,7 +269,8 @@ krb5_error_code krb5_get_nonexp_tkts(context, cc, creds_array)
+@@ -219,7 +219,8 @@ krb5_error_code krb5_get_nonexp_tkts(context, cc, creds_array)
  
      while (!(retval = krb5_cc_next_cred(context, cc, &cur, &creds))){
  
@@ -24,5 +26,5 @@ index 2a97893..83b5e46 100644
                  return retval;
              }
 -- 
-1.8.5.3
+2.0.4
 
diff --git a/0006-Use-more-randomness-for-ksu-secondary-cache-names.patch b/0006-Use-more-randomness-for-ksu-secondary-cache-names.patch
new file mode 100644
index 0000000..da8a32a
--- /dev/null
+++ b/0006-Use-more-randomness-for-ksu-secondary-cache-names.patch
@@ -0,0 +1,115 @@
+From 69c8e20b18577781e17c5959e23514134dfb5755 Mon Sep 17 00:00:00 2001
+From: Nalin Dahyabhai <nalin at redhat.com>
+Date: Thu, 24 Jul 2014 16:43:21 -0400
+Subject: [PATCH 6/7] Use more randomness for ksu secondary cache names
+
+When generating a suffix to append to a ccache name that will hold the
+credentials for a ksu-invoked process, instead of using integers
+counting up from 1, use the result of base64-encoding six randomly-
+generated octets.  Tweak the output alphabet just a bit to avoid using
+'+' or '/' in the generated names, the latter of which could really
+confuse things.
+---
+ src/clients/ksu/ccache.c | 27 +++++++++++++++++++++++----
+ src/clients/ksu/ksu.h    |  2 +-
+ src/clients/ksu/main.c   | 16 ++++++++++++----
+ 3 files changed, 36 insertions(+), 9 deletions(-)
+
+diff --git a/src/clients/ksu/ccache.c b/src/clients/ksu/ccache.c
+index 0f9e042..a0736f2 100644
+--- a/src/clients/ksu/ccache.c
++++ b/src/clients/ksu/ccache.c
+@@ -27,6 +27,7 @@
+  */
+ 
+ #include "ksu.h"
++#include "k5-base64.h"
+ #include "adm_proto.h"
+ #include <sys/types.h>
+ #include <sys/stat.h>
+@@ -504,10 +505,28 @@ show_credential(context, cred, cc)
+     free(sname);
+ }
+ 
+-int gen_sym(){
+-    static int i = 0;
+-    i ++;
+-    return i;
++/* Create a random string suitable for a filename extension. */
++krb5_error_code
++gen_sym(krb5_context context, char **sym_out)
++{
++    krb5_error_code retval;
++    char bytes[6], *p, *sym;
++    krb5_data data = make_data(bytes, sizeof(bytes));
++
++    *sym_out = NULL;
++    retval = krb5_c_random_make_octets(context, &data);
++    if (retval)
++        return retval;
++    sym = k5_base64_encode(data.data, data.length);
++    if (sym == NULL)
++        return ENOMEM;
++    /* Tweak the output alphabet just a bit. */
++    while ((p = strchr(sym, '/')) != NULL)
++        *p = '_';
++    while ((p = strchr(sym, '+')) != NULL)
++        *p = '-';
++    *sym_out = sym;
++    return 0;
+ }
+ 
+ krb5_error_code krb5_ccache_overwrite(context, ccs, cct, primary_principal)
+diff --git a/src/clients/ksu/ksu.h b/src/clients/ksu/ksu.h
+index fbbf217..5ba5ceb 100644
+--- a/src/clients/ksu/ksu.h
++++ b/src/clients/ksu/ksu.h
+@@ -130,7 +130,7 @@ extern krb5_error_code krb5_get_login_princ
+ extern void show_credential
+ (krb5_context, krb5_creds *, krb5_ccache);
+ 
+-extern int gen_sym (void);
++krb5_error_code gen_sym(krb5_context context, char **sym);
+ 
+ extern krb5_error_code krb5_ccache_overwrite
+ (krb5_context, krb5_ccache, krb5_ccache, krb5_principal);
+diff --git a/src/clients/ksu/main.c b/src/clients/ksu/main.c
+index 41a3bf8..47fa820 100644
+--- a/src/clients/ksu/main.c
++++ b/src/clients/ksu/main.c
+@@ -856,7 +856,7 @@ resolve_target_cache(krb5_context context, krb5_principal princ,
+     krb5_error_code retval;
+     krb5_boolean switchable, reused = FALSE;
+     krb5_ccache ccache = NULL;
+-    char *sep, *ccname = NULL, *target;
++    char *sep, *ccname = NULL, *sym = NULL, *target;
+ 
+     *ccache_out = NULL;
+     *ccache_reused = FALSE;
+@@ -876,12 +876,20 @@ resolve_target_cache(krb5_context context, krb5_principal princ,
+          * the name of a cache that doesn't exist yet. */
+         do {
+             free(ccname);
+-            if (asprintf(&ccname, "%s.%d", target, gen_sym()) < 0) {
++            retval = gen_sym(context, &sym);
++            if (retval) {
++                com_err(prog_name, retval,
++                        _("while generating part of the target ccache name"));
++                return retval;
++            }
++            if (asprintf(&ccname, "%s.%s", target, sym) < 0) {
+                 retval = ENOMEM;
+-                com_err(prog_name, ENOMEM,
+-                        _("while allocating memory for target ccache name"));
++                free(sym);
++                com_err(prog_name, retval, _("while allocating memory for the "
++                                             "target ccache name"));
+                 goto cleanup;
+             }
++            free(sym);
+         } while (ks_ccache_name_is_initialized(context, ccname));
+         retval = krb5_cc_resolve(context, ccname, &ccache);
+     } else {
+-- 
+2.0.4
+
diff --git a/0007-Make-krb5_cc_new_unique-create-DIR-directories.patch b/0007-Make-krb5_cc_new_unique-create-DIR-directories.patch
new file mode 100644
index 0000000..c0b8778
--- /dev/null
+++ b/0007-Make-krb5_cc_new_unique-create-DIR-directories.patch
@@ -0,0 +1,37 @@
+Context tweaked to apply to 1.12.1.
+
+From bca1191210eb582fe09e94486e2631d72b8a5ca5 Mon Sep 17 00:00:00 2001
+From: Nalin Dahyabhai <nalin at redhat.com>
+Date: Fri, 8 Aug 2014 16:58:03 -0400
+Subject: [PATCH 7/7] Make krb5_cc_new_unique create DIR: directories
+
+When we use krb5_cc_new_unique to create a new cache in a directory
+cache collection, we will fail if the directory doesn't exist yet.
+
+Go ahead and preemptively create it, as we do during krb5_cc_resolve,
+before attempting to create a new file under it.
+
+ticket: 7988 (new)
+target_version: 1.13
+tags: pullup
+---
+ src/lib/krb5/ccache/cc_dir.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/src/lib/krb5/ccache/cc_dir.c b/src/lib/krb5/ccache/cc_dir.c
+index d82f335..b00a6bb 100644
+--- a/src/lib/krb5/ccache/cc_dir.c
++++ b/src/lib/krb5/ccache/cc_dir.c
+@@ -401,6 +401,9 @@ dcc_gen_new(krb5_context context, krb5_ccache *cache_out)
+                                  "collection"));
+         return KRB5_DCC_CANNOT_CREATE;
+     }
++    ret = verify_dir(context, dirname);
++    if (ret)
++        goto cleanup;
+     ret = k5_path_join(dirname, "tktXXXXXX", &template);
+     if (ret)
+         goto cleanup;
+-- 
+2.0.4
+
diff --git a/krb5-1.12.1-pam.patch b/krb5-1.12.1-pam.patch
index 3bcdb34..5a8e65e 100644
--- a/krb5-1.12.1-pam.patch
+++ b/krb5-1.12.1-pam.patch
@@ -96,7 +96,7 @@ diff -up krb5/src/clients/ksu/main.c.pam krb5/src/clients/ksu/main.c
 +#include "autoconf.h"
  #include "ksu.h"
  #include "adm_proto.h"
- #include "../../lib/krb5/os/os-proto.h"
+ #include <sys/types.h>
 @@ -33,6 +34,10 @@
  #include <signal.h>
  #include <grp.h>
@@ -115,8 +115,8 @@ diff -up krb5/src/clients/ksu/main.c.pam krb5/src/clients/ksu/main.c
 +int force_fork = 0;
  /***********/
  
- #define _DEF_CSH "/bin/csh"
-@@ -586,6 +592,25 @@ main (argc, argv)
+ #define KS_TEMPORARY_CACHE "MEMORY:_ksu"
+@@ -586,6 +592,23 @@ main (argc, argv)
                 prog_name,target_user,client_name,
                 source_user,ontty());
  
@@ -126,13 +126,11 @@ diff -up krb5/src/clients/ksu/main.c.pam krb5/src/clients/ksu/main.c
 +                                   NULL, source_user,
 +                                   ttyname(STDERR_FILENO)) != 0) {
 +                fprintf(stderr, "Access denied for %s.\n", target_user);
-+                sweep_up(ksu_context, cc_tmp);
 +                exit(1);
 +            }
 +            if (appl_pam_requires_chauthtok()) {
 +                fprintf(stderr, "Password change required for %s.\n",
 +                        target_user);
-+                sweep_up(ksu_context, cc_tmp);
 +                exit(1);
 +            }
 +            force_fork++;
@@ -142,8 +140,8 @@ diff -up krb5/src/clients/ksu/main.c.pam krb5/src/clients/ksu/main.c
          /* Run authorization as target.*/
          if (krb5_seteuid(target_uid)) {
              com_err(prog_name, errno, _("while switching to target for "
-@@ -651,6 +676,26 @@
-             sweep_up(ksu_context, cc_tmp);
+@@ -651,6 +676,24 @@
+ 
              exit(1);
          }
 +#ifdef USE_PAM
@@ -154,13 +152,11 @@ diff -up krb5/src/clients/ksu/main.c.pam krb5/src/clients/ksu/main.c
 +                                   NULL, source_user,
 +                                   ttyname(STDERR_FILENO)) != 0) {
 +                fprintf(stderr, "Access denied for %s.\n", target_user);
-+                sweep_up(ksu_context, cc_tmp);
 +                exit(1);
 +            }
 +            if (appl_pam_requires_chauthtok()) {
 +                fprintf(stderr, "Password change required for %s.\n",
 +                        target_user);
-+                sweep_up(ksu_context, cc_tmp);
 +                exit(1);
 +            }
 +            force_fork++;
@@ -169,7 +165,7 @@ diff -up krb5/src/clients/ksu/main.c.pam krb5/src/clients/ksu/main.c
      }
  
      if( some_rest_copy){
-@@ -720,6 +745,32 @@
+@@ -720,6 +745,30 @@
          exit(1);
      }
  
@@ -177,7 +173,6 @@ diff -up krb5/src/clients/ksu/main.c.pam krb5/src/clients/ksu/main.c
 +    if (appl_pam_enabled(ksu_context, "ksu")) {
 +        if (appl_pam_session_open() != 0) {
 +            fprintf(stderr, "Error opening session for %s.\n", target_user);
-+            sweep_up(ksu_context, cc_tmp);
 +            exit(1);
 +        }
 +#ifdef DEBUG
@@ -188,7 +183,6 @@ diff -up krb5/src/clients/ksu/main.c.pam krb5/src/clients/ksu/main.c
 +        if (appl_pam_cred_init()) {
 +            fprintf(stderr, "Error initializing credentials for %s.\n",
 +                    target_user);
-+            sweep_up(ksu_context, cc_tmp);
 +            exit(1);
 +        }
 +#ifdef DEBUG
diff --git a/krb5.spec b/krb5.spec
index 47da922..8279931 100644
--- a/krb5.spec
+++ b/krb5.spec
@@ -110,12 +110,13 @@ Patch148: krb5-gssapi-mech-doublefree.patch
 Patch149: krb5-gssapi-spnego-deref.patch
 Patch150: http://web.mit.edu/kerberos/advisories/2014-001-patch.txt
 Patch151: http://web.mit.edu/kerberos/advisories/2014-001-patch.txt.asc
-Patch201: 0001-Don-t-try-to-stat-not-on-disk-ccache-residuals.patch
-Patch202: 0002-Use-an-in-memory-cache-until-we-need-the-target-s.patch
-Patch203: 0003-Learn-to-destroy-the-ccache-we-re-copying-from.patch
-Patch204: 0004-Try-to-use-the-default_ccache_name-d-as-the-target.patch
-Patch205: 0005-Be-more-careful-of-target-ccache-collections.patch
-Patch206: 0006-Copy-config-entries-to-the-target-ccache.patch
+Patch201: 0001-In-ksu-merge-krb5_ccache_copy-and-_restricted.patch
+Patch202: 0002-In-ksu-don-t-stat-not-on-disk-ccache-residuals.patch
+Patch203: 0003-Use-an-intermediate-memory-cache-in-ksu.patch
+Patch204: 0004-Make-ksu-respect-the-default_ccache_name-setting.patch
+Patch205: 0005-Copy-config-entries-to-the-ksu-target-ccache.patch
+Patch206: 0006-Use-more-randomness-for-ksu-secondary-cache-names.patch
+Patch207: 0007-Make-krb5_cc_new_unique-create-DIR-directories.patch
 
 License: MIT
 URL: http://web.mit.edu/kerberos/www/
@@ -318,14 +319,15 @@ certificate.
 %setup -q -a 3 -a 100 -a 102
 ln -s NOTICE LICENSE
 
-%patch1 -p1 -b .pwdch-fast
+%patch201 -p1 -b .In-ksu-merge-krb5_ccache_copy-and-_restricted
+%patch202 -p1 -b .In-ksu-don-t-stat-not-on-disk-ccache-residuals
+%patch203 -p1 -b .Use-an-intermediate-memory-cache-in-ksu
+%patch204 -p1 -b .Make-ksu-respect-the-default_ccache_name-setting
+%patch205 -p1 -b .Copy-config-entries-to-the-ksu-target-ccache
+%patch206 -p1 -b .Use-more-randomness-for-ksu-secondary-cache-names
+%patch207 -p1 -b .Make-krb5_cc_new_unique-create-DIR-directories
 
-%patch201 -p1 -b .Don-t-try-to-stat-not-on-disk-ccache-residuals
-%patch202 -p1 -b .Use-an-in-memory-cache-until-we-need-the-target-s
-%patch203 -p1 -b .Learn-to-destroy-the-ccache-we-re-copying-from
-%patch204 -p1 -b .Try-to-use-the-default_ccache_name-d-as-the-target
-%patch205 -p1 -b .Be-more-careful-of-target-ccache-collections
-%patch206 -p1 -b .Copy-config-entries-to-the-target-ccache
+%patch1 -p1 -b .pwdch-fast
 
 %patch60 -p1 -b .pam
 
@@ -1043,6 +1045,10 @@ exit 0
 %{_sbindir}/uuserver
 
 %changelog
+* Fri Aug 15 2014 Nalin Dahyabhai <nalin at redhat.com>
+- replace older proposed changes for ksu with backports of the changes
+  after review and merging upstream (#1015559, #1026099, #1118347)
+
 * Thu Aug  7 2014 Nalin Dahyabhai <nalin at redhat.com> - 1.12.1-14
 - incorporate fix for MITKRB5-SA-2014-001 (CVE-2014-4345)
 


More information about the scm-commits mailing list