summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNalin Dahyabhai <nalin@redhat.com>2014-08-22 09:50:15 -0400
committerNalin Dahyabhai <nalin@redhat.com>2014-08-22 09:50:15 -0400
commitb883d575b9cac81039e9f4c224c3faeccdce18eb (patch)
tree56526b77e1bd2629dc167770e2cf1278229c9d03
parente096b95812c734140045d425498070d6f294153d (diff)
parentc48fd0f0bcdc3e18914a4f8eed6d59a38bd47e1e (diff)
downloadkrb5-b883d575b9cac81039e9f4c224c3faeccdce18eb.tar.gz
krb5-b883d575b9cac81039e9f4c224c3faeccdce18eb.tar.xz
krb5-b883d575b9cac81039e9f4c224c3faeccdce18eb.zip
Merge changes from master into f21
Update to 1.12.2.
-rw-r--r--.gitignore3
-rw-r--r--0001-Don-t-try-to-stat-not-on-disk-ccache-residuals.patch316
-rw-r--r--0001-In-ksu-merge-krb5_ccache_copy-and-_restricted.patch230
-rw-r--r--0002-In-ksu-don-t-stat-not-on-disk-ccache-residuals.patch369
-rw-r--r--0002-Use-an-in-memory-cache-until-we-need-the-target-s.patch321
-rw-r--r--0003-Learn-to-destroy-the-ccache-we-re-copying-from.patch95
-rw-r--r--0003-Use-an-intermediate-memory-cache-in-ksu.patch417
-rw-r--r--0004-Make-ksu-respect-the-default_ccache_name-setting.patch378
-rw-r--r--0004-Try-to-use-the-default_ccache_name-d-as-the-target.patch149
-rw-r--r--0005-Be-more-careful-of-target-ccache-collections.patch179
-rw-r--r--0005-Copy-config-entries-to-the-ksu-target-ccache.patch (renamed from 0006-Copy-config-entries-to-the-target-ccache.patch)12
-rw-r--r--0006-Use-more-randomness-for-ksu-secondary-cache-names.patch115
-rw-r--r--0007-Make-krb5_cc_new_unique-create-DIR-directories.patch37
-rw-r--r--krb5-1.10-doublelog.patch14
-rw-r--r--krb5-1.12-CVE-2014-4341_4342-tests.patch547
-rw-r--r--krb5-1.12-CVE-2014-4341_4342.patch163
-rw-r--r--krb5-1.12-tcl86.patch149
-rw-r--r--krb5-1.12.1-pam.patch18
-rw-r--r--krb5-master-empty-credstore.patch43
-rw-r--r--krb5-master-keyring-kdcsync.patch108
-rw-r--r--krb5-master-mechd.patch38
-rw-r--r--krb5-master-move-otp-sockets.patch11
-rw-r--r--krb5-master-rcache-acquirecred-leak.patch26
-rw-r--r--krb5-master-spnego-preserve-oid.patch166
-rw-r--r--krb5-master-strdupcheck.patch23
-rw-r--r--krb5.spec83
-rw-r--r--sources6
27 files changed, 1637 insertions, 2379 deletions
diff --git a/.gitignore b/.gitignore
index fd3a350..294595c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -107,3 +107,6 @@ krb5-1.8.3-pdf.tar.gz
/krb5-1.12.1.tar.gz
/krb5-1.12.1.tar.gz.asc
/krb5-1.12.1-pdf.tar.xz
+/krb5-1.12.2.tar.gz
+/krb5-1.12.2.tar.gz.asc
+/krb5-1.12.2-pdf.tar.xz
diff --git a/0001-Don-t-try-to-stat-not-on-disk-ccache-residuals.patch b/0001-Don-t-try-to-stat-not-on-disk-ccache-residuals.patch
deleted file mode 100644
index ac6ce53..0000000
--- a/0001-Don-t-try-to-stat-not-on-disk-ccache-residuals.patch
+++ /dev/null
@@ -1,316 +0,0 @@
-From 9f902f70a79ab864083078d104196a83943844ac Mon Sep 17 00:00:00 2001
-From: Nalin Dahyabhai <nalin@redhat.com>
-Date: Fri, 1 Nov 2013 09:48:13 -0400
-Subject: [PATCH 1/6] Don't try to stat() not-on-disk ccache residuals
-
-Don't assume that ccache residual names are filenames which we can
-stat() usefully. Instead, use helper functions to call the library
-routines to try to read the default principal name from caches.
----
- src/clients/ksu/ccache.c | 88 +++++++++++++++++++++++++++------------------
- src/clients/ksu/heuristic.c | 13 ++-----
- src/clients/ksu/ksu.h | 6 ++++
- src/clients/ksu/main.c | 17 +++++----
- 4 files changed, 70 insertions(+), 54 deletions(-)
-
-diff --git a/src/clients/ksu/ccache.c b/src/clients/ksu/ccache.c
-index 9916c75..7917af2 100644
---- a/src/clients/ksu/ccache.c
-+++ b/src/clients/ksu/ccache.c
-@@ -60,12 +60,10 @@ krb5_error_code krb5_ccache_copy (context, cc_def, cc_other_tag,
- {
- int i=0;
- krb5_ccache * cc_other;
-- const char * cc_def_name;
-- const char * cc_other_name;
-+ const char * cc_other_type;
- krb5_error_code retval=0;
- krb5_creds ** cc_def_creds_arr = NULL;
- krb5_creds ** cc_other_creds_arr = NULL;
-- struct stat st_temp;
-
- cc_other = (krb5_ccache *) xcalloc(1, sizeof (krb5_ccache));
-
-@@ -74,10 +72,9 @@ krb5_error_code krb5_ccache_copy (context, cc_def, cc_other_tag,
- return retval;
- }
-
-- cc_def_name = krb5_cc_get_name(context, cc_def);
-- cc_other_name = krb5_cc_get_name(context, *cc_other);
-+ cc_other_type = krb5_cc_get_type(context, *cc_other);
-
-- if ( ! stat(cc_def_name, &st_temp)){
-+ if (krb5_ccache_is_initialized(context, cc_def)) {
- if((retval = krb5_get_nonexp_tkts(context,cc_def,&cc_def_creds_arr))){
- return retval;
- }
-@@ -86,7 +83,8 @@ krb5_error_code krb5_ccache_copy (context, cc_def, cc_other_tag,
- *stored = krb5_find_princ_in_cred_list(context, cc_def_creds_arr,
- primary_principal);
-
-- if (!lstat( cc_other_name, &st_temp))
-+ if (!krb5_cc_support_switch(context, cc_other_type) &&
-+ krb5_ccache_name_is_initialized(context, cc_other_tag))
- return EINVAL;
-
- if (krb5_seteuid(0)||krb5_seteuid(target_uid)) {
-@@ -533,24 +531,18 @@ krb5_error_code krb5_ccache_overwrite(context, ccs, cct, primary_principal)
- krb5_ccache cct;
- krb5_principal primary_principal;
- {
-- const char * cct_name;
-- const char * ccs_name;
- krb5_error_code retval=0;
- krb5_principal temp_principal;
- krb5_creds ** ccs_creds_arr = NULL;
- int i=0;
-- struct stat st_temp;
-
-- ccs_name = krb5_cc_get_name(context, ccs);
-- cct_name = krb5_cc_get_name(context, cct);
--
-- if ( ! stat(ccs_name, &st_temp)){
-+ if (krb5_ccache_is_initialized(context, ccs)) {
- if ((retval = krb5_get_nonexp_tkts(context, ccs, &ccs_creds_arr))){
- return retval;
- }
- }
-
-- if ( ! stat(cct_name, &st_temp)){
-+ if (krb5_ccache_is_initialized(context, cct)) {
- if ((retval = krb5_cc_get_principal(context, cct, &temp_principal))){
- return retval;
- }
-@@ -649,12 +641,10 @@ krb5_error_code krb5_ccache_copy_restricted (context, cc_def, cc_other_tag,
-
- int i=0;
- krb5_ccache * cc_other;
-- const char * cc_def_name;
-- const char * cc_other_name;
-+ const char * cc_other_type;
- krb5_error_code retval=0;
- krb5_creds ** cc_def_creds_arr = NULL;
- krb5_creds ** cc_other_creds_arr = NULL;
-- struct stat st_temp;
-
- cc_other = (krb5_ccache *) xcalloc(1, sizeof (krb5_ccache));
-
-@@ -663,19 +653,17 @@ krb5_error_code krb5_ccache_copy_restricted (context, cc_def, cc_other_tag,
- return retval;
- }
-
-- cc_def_name = krb5_cc_get_name(context, cc_def);
-- cc_other_name = krb5_cc_get_name(context, *cc_other);
-+ cc_other_type = krb5_cc_get_type(context, *cc_other);
-
-- if ( ! stat(cc_def_name, &st_temp)){
-- if((retval = krb5_get_nonexp_tkts(context,cc_def,&cc_def_creds_arr))){
-+ if (krb5_ccache_is_initialized(context, cc_def)) {
-+ retval = krb5_get_nonexp_tkts(context, cc_def, &cc_def_creds_arr);
-+ if (retval)
- return retval;
-- }
--
- }
-
-- if (!lstat( cc_other_name, &st_temp)) {
-+ if (!krb5_cc_support_switch(context, cc_other_type) &&
-+ krb5_ccache_name_is_initialized(context, cc_other_tag))
- return EINVAL;
-- }
-
- if (krb5_seteuid(0)||krb5_seteuid(target_uid)) {
- return errno;
-@@ -723,12 +711,10 @@ krb5_error_code krb5_ccache_filter (context, cc, prst)
- krb5_creds ** cc_creds_arr = NULL;
- const char * cc_name;
- krb5_boolean stored;
-- struct stat st_temp;
-
- cc_name = krb5_cc_get_name(context, cc);
-
-- if ( ! stat(cc_name, &st_temp)){
--
-+ if (krb5_ccache_is_initialized(context, cc)) {
- if (auth_debug) {
- fprintf(stderr,"putting cache %s through a filter for -z option\n", cc_name);
- }
-@@ -793,12 +779,8 @@ krb5_error_code krb5_find_princ_in_cache (context, cc, princ, found)
- {
- krb5_error_code retval;
- krb5_creds ** creds_list = NULL;
-- const char * cc_name;
-- struct stat st_temp;
-
-- cc_name = krb5_cc_get_name(context, cc);
--
-- if ( ! stat(cc_name, &st_temp)){
-+ if (krb5_ccache_is_initialized(context, cc)) {
- if ((retval = krb5_get_nonexp_tkts(context, cc, &creds_list))){
- return retval;
- }
-@@ -807,3 +789,41 @@ krb5_error_code krb5_find_princ_in_cache (context, cc, princ, found)
- *found = krb5_find_princ_in_cred_list(context, creds_list, princ);
- return 0;
- }
-+
-+extern krb5_boolean
-+krb5_ccache_name_is_initialized(krb5_context context, const char *cctag)
-+{
-+ krb5_error_code retval = 0;
-+ krb5_ccache cc;
-+ krb5_principal princ;
-+
-+ retval = krb5_cc_resolve(context, cctag, &cc);
-+ if (retval)
-+ return FALSE;
-+
-+ retval = krb5_cc_get_principal(context, cc, &princ);
-+ if (retval == 0)
-+ krb5_free_principal(context, princ);
-+ krb5_cc_close(context, cc);
-+
-+ return retval == 0;
-+}
-+
-+extern krb5_boolean
-+krb5_ccache_is_initialized(krb5_context context, krb5_ccache def_cc)
-+{
-+ krb5_error_code retval = 0;
-+ krb5_boolean result;
-+ char *def_cc_name;
-+
-+ if (def_cc == NULL)
-+ return FALSE;
-+
-+ retval = krb5_cc_get_full_name(context, def_cc, &def_cc_name);
-+ if (retval)
-+ return FALSE;
-+
-+ result = krb5_ccache_name_is_initialized(context, def_cc_name);
-+ krb5_free_string(context, def_cc_name);
-+ return result;
-+}
-diff --git a/src/clients/ksu/heuristic.c b/src/clients/ksu/heuristic.c
-index c7e691c..bfde451 100644
---- a/src/clients/ksu/heuristic.c
-+++ b/src/clients/ksu/heuristic.c
-@@ -404,12 +404,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 (krb5_ccache_is_initialized(context, cc)) {
-
- retval = find_ticket(context, cc, client, end_server, &temp_found);
- if (retval)
-@@ -546,7 +542,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;
-@@ -558,7 +553,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;
-
-@@ -566,10 +560,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 (krb5_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 f2c0811..2a63c21 100644
---- a/src/clients/ksu/ksu.h
-+++ b/src/clients/ksu/ksu.h
-@@ -141,6 +141,12 @@ extern krb5_error_code krb5_store_some_creds
- (krb5_context, krb5_ccache, krb5_creds **, krb5_creds **,
- krb5_principal, krb5_boolean *);
-
-+extern krb5_boolean krb5_ccache_name_is_initialized
-+(krb5_context, const char *);
-+
-+extern krb5_boolean krb5_ccache_is_initialized
-+(krb5_context, krb5_ccache);
-+
- extern krb5_error_code krb5_ccache_copy_restricted
- (krb5_context, krb5_ccache, char *, krb5_principal,
- krb5_ccache *, krb5_boolean *, uid_t);
-diff --git a/src/clients/ksu/main.c b/src/clients/ksu/main.c
-index 233eb52..e2ca06a 100644
---- a/src/clients/ksu/main.c
-+++ b/src/clients/ksu/main.c
-@@ -112,7 +112,6 @@ main (argc, argv)
- extern char * getpass(), *crypt();
- int pargc;
- char ** pargv;
-- struct stat st_temp;
- krb5_boolean stored = FALSE;
- krb5_principal kdc_server;
- krb5_boolean zero_password;
-@@ -265,9 +264,10 @@ main (argc, argv)
- if ( strchr(cc_source_tag, ':')){
- cc_source_tag_tmp = strchr(cc_source_tag, ':') + 1;
-
-- if( stat( cc_source_tag_tmp, &st_temp)){
-+ if (!krb5_ccache_name_is_initialized(ksu_context,
-+ cc_source_tag)) {
- com_err(prog_name, errno,
-- _("while looking for credentials file %s"),
-+ _("while looking for credentials cache %s"),
- cc_source_tag_tmp);
- exit (1);
- }
-@@ -432,7 +432,8 @@ main (argc, argv)
- (long) target_uid, gen_sym());
- cc_target_tag_tmp = strchr(cc_target_tag, ':') + 1;
-
-- }while ( !stat ( cc_target_tag_tmp, &st_temp));
-+ } while (krb5_ccache_name_is_initialized(ksu_context,
-+ cc_target_tag));
- }
-
-
-@@ -884,8 +885,6 @@ static void sweep_up(context, cc)
- krb5_ccache cc;
- {
- krb5_error_code retval;
-- const char * cc_name;
-- struct stat st_temp;
-
- krb5_seteuid(0);
- if (krb5_seteuid(target_uid) < 0) {
-@@ -894,9 +893,9 @@ static void sweep_up(context, cc)
- exit(1);
- }
-
-- cc_name = krb5_cc_get_name(context, cc);
-- if ( ! stat(cc_name, &st_temp)){
-- if ((retval = krb5_cc_destroy(context, cc)))
-+ if (krb5_ccache_is_initialized(context, cc)) {
-+ retval = krb5_cc_destroy(context, cc);
-+ if (retval)
- com_err(prog_name, retval, _("while destroying cache"));
- }
- }
---
-1.8.5.3
-
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@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@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/0002-Use-an-in-memory-cache-until-we-need-the-target-s.patch b/0002-Use-an-in-memory-cache-until-we-need-the-target-s.patch
deleted file mode 100644
index ef62793..0000000
--- a/0002-Use-an-in-memory-cache-until-we-need-the-target-s.patch
+++ /dev/null
@@ -1,321 +0,0 @@
-From 5195c2b20593330192feff67dd5f271e88f562e7 Mon Sep 17 00:00:00 2001
-From: Nalin Dahyabhai <nalin@dahyabhai.net>
-Date: Wed, 30 Oct 2013 21:45:35 -0400
-Subject: [PATCH 2/6] Use an in-memory cache until we need the target's
-
-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.
----
- src/clients/ksu/ksu.h | 1 +
- src/clients/ksu/main.c | 133 +++++++++++++++++++++++++++++--------------------
- 2 files changed, 80 insertions(+), 54 deletions(-)
-
-diff --git a/src/clients/ksu/ksu.h b/src/clients/ksu/ksu.h
-index 2a63c21..1d102a1 100644
---- a/src/clients/ksu/ksu.h
-+++ b/src/clients/ksu/ksu.h
-@@ -45,6 +45,7 @@
- #define KRB5_DEFAULT_TKT_LIFE 60*60*12 /* 12 hours */
-
- #define KRB5_SECONDARY_CACHE "FILE:/tmp/krb5cc_"
-+#define KRB5_TEMPORARY_CACHE "MEMORY:_ksu"
-
- #define KRB5_LOGIN_NAME ".k5login"
- #define KRB5_USERS_NAME ".k5users"
-diff --git a/src/clients/ksu/main.c b/src/clients/ksu/main.c
-index e2ca06a..fa86c78 100644
---- a/src/clients/ksu/main.c
-+++ b/src/clients/ksu/main.c
-@@ -86,7 +86,7 @@ main (argc, argv)
- int statusp=0;
- krb5_error_code retval = 0;
- krb5_principal client = NULL;
-- krb5_ccache cc_target = NULL;
-+ krb5_ccache cc_tmp = NULL, cc_target = NULL;
- krb5_context ksu_context;
- char * cc_target_tag = NULL;
- char * target_user = NULL;
-@@ -452,14 +452,15 @@ 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.*/
-+ * Only after proper authentication and authorization has
-+ * taken place, do we 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
-@@ -468,19 +469,23 @@ main (argc, argv)
- 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))){
-+ KRB5_TEMPORARY_CACHE, client,
-+ &cc_tmp, &stored,
-+ 0))){
- 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),
-+ KRB5_TEMPORARY_CACHE);
- exit(1);
- }
-
- } else {
-- if ((retval = krb5_ccache_copy(ksu_context, cc_source, cc_target_tag,
-- client,&cc_target, &stored, target_uid))) {
-+
-+ retval = krb5_ccache_copy(ksu_context, cc_source, KRB5_TEMPORARY_CACHE,
-+ client, &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),
-+ KRB5_TEMPORARY_CACHE);
- exit(1);
- }
-
-@@ -502,7 +507,7 @@ main (argc, argv)
- &kdc_server))){
- com_err(prog_name, retval,
- _("while creating tgt for local realm"));
-- sweep_up(ksu_context, cc_target);
-+ sweep_up(ksu_context, cc_tmp);
- exit(1);
- }
-
-@@ -510,13 +515,13 @@ 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);
-+ sweep_up(ksu_context, cc_tmp);
- exit(1);
- }
-
-@@ -535,15 +540,16 @@ 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);
-+ sweep_up(ksu_context, cc_tmp);
- exit(1);
- }
-
-@@ -576,7 +582,7 @@ main (argc, argv)
-
- if ((retval = krb5_unparse_name(ksu_context, client, &client_name))) {
- com_err(prog_name, retval, _("When unparsing name"));
-- sweep_up(ksu_context, cc_target);
-+ sweep_up(ksu_context, cc_tmp);
- exit(1);
- }
-
-@@ -589,7 +595,7 @@ 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);
-+ sweep_up(ksu_context, cc_tmp);
- exit(1);
- }
-
-@@ -597,14 +603,14 @@ 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);
-+ sweep_up(ksu_context, cc_tmp);
- 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);
-+ sweep_up(ksu_context, cc_tmp);
- exit(1);
- }
- if (authorization_val == TRUE){
-@@ -646,21 +652,23 @@ main (argc, argv)
-
- }
-
-- sweep_up(ksu_context, cc_target);
-+ sweep_up(ksu_context, cc_tmp);
- 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);
-+ sweep_up(ksu_context, cc_tmp);
- exit(1);
- }
- }
-
- if (all_rest_copy){
-- if ((retval = krb5_cc_initialize(ksu_context, cc_target, client))){
-+ retval = krb5_cc_initialize(ksu_context, cc_tmp, client);
-+ if (retval) {
- com_err(prog_name, retval, _("while erasing target cache"));
- exit(1);
- }
-@@ -682,7 +690,7 @@ 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);
-+ sweep_up(ksu_context, cc_tmp);
- exit(1);
- }
- #endif /* HAVE_GETUSERSHELL */
-@@ -692,43 +700,33 @@ 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);
-+ sweep_up(ksu_context, cc_tmp);
- 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);
-+ sweep_up(ksu_context, cc_tmp);
- 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);
-+ sweep_up(ksu_context, cc_tmp);
- exit(1);
- }
-
- /* set permissions */
- if (setgid(target_pwd->pw_gid) < 0) {
- perror("ksu: setgid");
-- sweep_up(ksu_context, cc_target);
-+ sweep_up(ksu_context, cc_tmp);
- exit(1);
- }
-
--
- if (initgroups(target_user, target_pwd->pw_gid)) {
- fprintf(stderr, _("ksu: initgroups failed.\n"));
-- sweep_up(ksu_context, cc_target);
-+ sweep_up(ksu_context, cc_tmp);
- exit(1);
- }
-
-@@ -748,22 +746,49 @@ main (argc, argv)
- */
- if (setluid((uid_t) pwd->pw_uid) < 0) {
- perror("setluid");
-- sweep_up(ksu_context, cc_target);
-+ sweep_up(ksu_context, cc_tmp);
- exit(1);
- }
- #endif /* HAVE_SETLUID */
-
-- if (setuid(target_pwd->pw_uid) < 0) {
-+ if (seteuid(0) < 0 || seteuid(target_pwd->pw_uid) < 0) {
-+ perror("ksu: seteuid");
-+ sweep_up(ksu_context, cc_tmp);
-+ exit(1);
-+ }
-+
-+ retval = krb5_ccache_copy(ksu_context, cc_tmp, cc_target_tag,
-+ client, &cc_target, &stored,
-+ target_pwd->pw_uid);
-+ if (retval) {
-+ com_err(prog_name, retval, _("while copying cache %s to %s"),
-+ krb5_cc_get_name(ksu_context, cc_tmp), cc_target_tag);
-+ exit(1);
-+ }
-+
-+ if (setuid(0) < 0 || setuid(target_pwd->pw_uid) < 0) {
- perror("ksu: setuid");
- sweep_up(ksu_context, cc_target);
- 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);
-+ /* set the cc env name to target */
-+ if (stored) {
-+ if (krb5_cc_get_full_name(ksu_context, cc_target,
-+ &cc_target_tag) == 0) {
-+ 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);
-+ }
-+ krb5_free_string(ksu_context, cc_target_tag);
-+ } else {
-+ com_err(prog_name, retval, _("while reading cache name from %s"),
-+ cc_target_tag);
-+ exit(1);
-+ }
- }
-
- if ( cc_source)
---
-1.8.5.3
-
diff --git a/0003-Learn-to-destroy-the-ccache-we-re-copying-from.patch b/0003-Learn-to-destroy-the-ccache-we-re-copying-from.patch
deleted file mode 100644
index ae96369..0000000
--- a/0003-Learn-to-destroy-the-ccache-we-re-copying-from.patch
+++ /dev/null
@@ -1,95 +0,0 @@
-From 85ac175a62fcd629592c049f2318fff79949884b Mon Sep 17 00:00:00 2001
-From: Nalin Dahyabhai <nalin@redhat.com>
-Date: Thu, 31 Oct 2013 15:43:49 -0400
-Subject: [PATCH 3/6] Learn to destroy the ccache we're copying from
-
-Add a flag to krb5_ccache_copy() which will instruct it to destroy a
-source ccache after reading its contents. Using this when we copy the
-creds from a MEMORY cache to somewhere else is necessary to avoid having
-a subsequent call to krb5_cc_cache_match() select the MEMORY cache when
-we're trying to have it search a different location by default.
----
- src/clients/ksu/ccache.c | 10 +++++++++-
- src/clients/ksu/ksu.h | 2 +-
- src/clients/ksu/main.c | 5 +++--
- 3 files changed, 13 insertions(+), 4 deletions(-)
-
-diff --git a/src/clients/ksu/ccache.c b/src/clients/ksu/ccache.c
-index 7917af2..90ba2f2 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, destroy_def,
-+ cc_out, stored, target_uid)
- /* IN */
- krb5_context context;
- krb5_ccache cc_def;
- char *cc_other_tag;
- krb5_principal primary_principal;
-+ krb5_boolean destroy_def;
- uid_t target_uid;
- /* OUT */
- krb5_ccache *cc_out;
-@@ -80,6 +82,12 @@ krb5_error_code krb5_ccache_copy (context, cc_def, cc_other_tag,
- }
- }
-
-+ if (destroy_def) {
-+ retval = krb5_cc_destroy(context, cc_def);
-+ if (retval)
-+ return retval;
-+ }
-+
- *stored = krb5_find_princ_in_cred_list(context, cc_def_creds_arr,
- primary_principal);
-
-diff --git a/src/clients/ksu/ksu.h b/src/clients/ksu/ksu.h
-index 1d102a1..a889fb9 100644
---- a/src/clients/ksu/ksu.h
-+++ b/src/clients/ksu/ksu.h
-@@ -108,7 +108,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 **);
-diff --git a/src/clients/ksu/main.c b/src/clients/ksu/main.c
-index fa86c78..7497a2b 100644
---- a/src/clients/ksu/main.c
-+++ b/src/clients/ksu/main.c
-@@ -28,6 +28,7 @@
-
- #include "ksu.h"
- #include "adm_proto.h"
-+#include "../../lib/krb5/os/os-proto.h"
- #include <sys/types.h>
- #include <sys/wait.h>
- #include <signal.h>
-@@ -481,7 +482,7 @@ main (argc, argv)
- } else {
-
- retval = krb5_ccache_copy(ksu_context, cc_source, KRB5_TEMPORARY_CACHE,
-- client, &cc_tmp, &stored, 0);
-+ client, FALSE, &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),
-@@ -758,7 +759,7 @@ main (argc, argv)
- }
-
- retval = krb5_ccache_copy(ksu_context, cc_tmp, cc_target_tag,
-- client, &cc_target, &stored,
-+ client, TRUE, &cc_target, &stored,
- target_pwd->pw_uid);
- if (retval) {
- com_err(prog_name, retval, _("while copying cache %s to %s"),
---
-1.8.5.3
-
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@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@_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@_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@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@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/0004-Try-to-use-the-default_ccache_name-d-as-the-target.patch b/0004-Try-to-use-the-default_ccache_name-d-as-the-target.patch
deleted file mode 100644
index bd78d12..0000000
--- a/0004-Try-to-use-the-default_ccache_name-d-as-the-target.patch
+++ /dev/null
@@ -1,149 +0,0 @@
-From acbb59cd4b1759afe492b8503cddb0a2f719e6c8 Mon Sep 17 00:00:00 2001
-From: Nalin Dahyabhai <nalin@dahyabhai.net>
-Date: Wed, 30 Oct 2013 21:47:14 -0400
-Subject: [PATCH 4/6] Try to use the default_ccache_name'd as the target
-
-Try to use the location named by the default_ccache_name setting as the
-target cache. If it's a collection, just create or update a subsidiary
-cache. If it's not, then fall back to creating a new cache to try to
-avoid destroying the contents of one that might already be there. We
-can't really detect this in advance for KEYRING: caches, though.
----
- src/clients/ksu/ksu.h | 2 +-
- src/clients/ksu/main.c | 91 ++++++++++++++++++++++++++++++++++++--------------
- 2 files changed, 67 insertions(+), 26 deletions(-)
-
-diff --git a/src/clients/ksu/ksu.h b/src/clients/ksu/ksu.h
-index a889fb9..a195f52 100644
---- a/src/clients/ksu/ksu.h
-+++ b/src/clients/ksu/ksu.h
-@@ -44,7 +44,7 @@
- #define KRB5_DEFAULT_OPTIONS 0
- #define KRB5_DEFAULT_TKT_LIFE 60*60*12 /* 12 hours */
-
--#define KRB5_SECONDARY_CACHE "FILE:/tmp/krb5cc_"
-+#define KRB5_DEFAULT_SECONDARY_CACHE "FILE:/tmp/krb5cc_%{uid}"
- #define KRB5_TEMPORARY_CACHE "MEMORY:_ksu"
-
- #define KRB5_LOGIN_NAME ".k5login"
-diff --git a/src/clients/ksu/main.c b/src/clients/ksu/main.c
-index 7497a2b..58df6a1 100644
---- a/src/clients/ksu/main.c
-+++ b/src/clients/ksu/main.c
-@@ -90,7 +90,10 @@ main (argc, argv)
- krb5_ccache cc_tmp = NULL, cc_target = NULL;
- krb5_context ksu_context;
- char * cc_target_tag = NULL;
-+ char * cc_target_tag_conf;
-+ krb5_boolean cc_target_switchable;
- char * target_user = NULL;
-+ char * target_user_uid_str;
- char * source_user;
-
- krb5_ccache cc_source = NULL;
-@@ -116,7 +119,6 @@ main (argc, argv)
- krb5_boolean stored = FALSE;
- krb5_principal kdc_server;
- krb5_boolean zero_password;
-- char * dir_of_cc_target;
-
- options.opt = KRB5_DEFAULT_OPTIONS;
- options.lifetime = KRB5_DEFAULT_TKT_LIFE;
-@@ -420,31 +422,70 @@ main (argc, argv)
- }
-
- 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 (krb5_ccache_name_is_initialized(ksu_context,
-- cc_target_tag));
-- }
--
--
-- 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);
-+ if (cc_target_tag == NULL) {
-+ com_err(prog_name, retval , _("while allocating memory for the "
-+ "target ccache name"));
-+ exit(1);
-+ }
-+ /* Read the configured value. */
-+ if (profile_get_string(ksu_context->profile, KRB5_CONF_LIBDEFAULTS,
-+ KRB5_CONF_DEFAULT_CCACHE_NAME, NULL,
-+ KRB5_DEFAULT_SECONDARY_CACHE,
-+ &cc_target_tag_conf)) {
-+ com_err(prog_name, retval , _("while allocating memory for the "
-+ "target ccache name"));
-+ exit(1);
-+ }
-+ /* Prepend "FILE:" if a cctype wasn't specified in the config. */
-+ if (strchr(cc_target_tag_conf, ':')) {
-+ cc_target_tag_tmp = strdup(cc_target_tag_conf);
-+ } else {
-+ if (asprintf(&cc_target_tag_tmp, "FILE:%s",
-+ cc_target_tag_conf) < 0)
-+ cc_target_tag_tmp = NULL;
-+ }
-+ profile_release_string(cc_target_tag_conf);
-+ if (cc_target_tag_tmp == NULL) {
-+ com_err(prog_name, retval , _("while allocating memory for the "
-+ "target ccache name"));
-+ exit(1);
-+ }
-+ /* Resolve parameters in the configured value for the target user. */
-+ if (asprintf(&target_user_uid_str, "%lu",
-+ (unsigned long)target_uid) < 0) {
-+ com_err(prog_name, retval , _("while allocating memory for the "
-+ "target ccache name"));
-+ exit(1);
-+ }
-+ if (k5_expand_path_tokens_extra(ksu_context,
-+ cc_target_tag_tmp, &cc_target_tag_conf,
-+ "euid", target_user_uid_str,
-+ "uid", target_user_uid_str,
-+ "USERID", target_user_uid_str,
-+ "username", target_user,
-+ NULL) != 0) {
-+ com_err(prog_name, retval , _("while allocating memory for the "
-+ "target ccache name"));
-+ exit(1);
-+ }
-+ cc_target_tag_tmp[strcspn(cc_target_tag_tmp, ":")] = '\0';
-+ cc_target_switchable = krb5_cc_support_switch(ksu_context,
-+ cc_target_tag_tmp);
-+ free(cc_target_tag_tmp);
-+ /* Try to avoid destroying a target ccache. */
-+ if (cc_target_switchable) {
-+ snprintf(cc_target_tag, KRB5_SEC_BUFFSIZE, "%s",
-+ cc_target_tag_conf);
-+ } else {
-+ do {
-+ snprintf(cc_target_tag, KRB5_SEC_BUFFSIZE, "%s.%d",
-+ cc_target_tag_conf, gen_sym());
-+ } while (krb5_ccache_name_is_initialized(ksu_context,
-+ cc_target_tag));
-+ }
-+ cc_target_tag_tmp = strchr(cc_target_tag, ':') + 1;
-+ krb5_free_string(ksu_context, cc_target_tag_conf);
- }
-
- if (auth_debug){
---
-1.8.5.3
-
diff --git a/0005-Be-more-careful-of-target-ccache-collections.patch b/0005-Be-more-careful-of-target-ccache-collections.patch
deleted file mode 100644
index 5f9de36..0000000
--- a/0005-Be-more-careful-of-target-ccache-collections.patch
+++ /dev/null
@@ -1,179 +0,0 @@
-From 5286fddf967af8952bd9d42d6d1ec1ddfcc159ad Mon Sep 17 00:00:00 2001
-From: Nalin Dahyabhai <nalin@dahyabhai.net>
-Date: Wed, 30 Oct 2013 21:34:27 -0400
-Subject: [PATCH 5/6] Be more careful of target ccache collections
-
-When copying credentials to a cache collection, take care to avoid
-generating multiple caches for a single client principal, but don't
-change the primary out from anyone who might already be using the
-target collection.
----
- src/clients/ksu/ccache.c | 62 ++++++++++++++++++++++++++++++++++++++++++------
- src/clients/ksu/ksu.h | 2 +-
- src/clients/ksu/main.c | 11 +++++++--
- 3 files changed, 65 insertions(+), 10 deletions(-)
-
-diff --git a/src/clients/ksu/ccache.c b/src/clients/ksu/ccache.c
-index 90ba2f2..2a97893 100644
---- a/src/clients/ksu/ccache.c
-+++ b/src/clients/ksu/ccache.c
-@@ -48,7 +48,7 @@ void show_credential();
-
- krb5_error_code krb5_ccache_copy (context, cc_def, cc_other_tag,
- primary_principal, destroy_def,
-- cc_out, stored, target_uid)
-+ cc_out, stored, reused, target_uid)
- /* IN */
- krb5_context context;
- krb5_ccache cc_def;
-@@ -59,10 +59,12 @@ krb5_error_code krb5_ccache_copy (context, cc_def, cc_other_tag,
- /* OUT */
- krb5_ccache *cc_out;
- krb5_boolean *stored;
-+ krb5_boolean *reused;
- {
- int i=0;
- krb5_ccache * cc_other;
- const char * cc_other_type;
-+ char * saved_cc_default_name;
- krb5_error_code retval=0;
- krb5_creds ** cc_def_creds_arr = NULL;
- krb5_creds ** cc_other_creds_arr = NULL;
-@@ -99,9 +101,33 @@ krb5_error_code krb5_ccache_copy (context, cc_def, cc_other_tag,
- return errno;
- }
-
--
-- if ((retval = krb5_cc_initialize(context, *cc_other, primary_principal))){
-- return retval;
-+ if (krb5_cc_support_switch(context, cc_other_type)) {
-+ *reused = TRUE;
-+ krb5_cc_close(context, *cc_other);
-+ saved_cc_default_name = strdup(krb5_cc_default_name(context));
-+ krb5_cc_set_default_name(context, cc_other_tag);
-+ if (krb5_cc_cache_match(context, primary_principal, cc_other) != 0) {
-+ *reused = FALSE;
-+ retval = krb5_cc_new_unique(context, cc_other_type, NULL,
-+ cc_other);
-+ if (retval) {
-+ krb5_cc_set_default_name(context, saved_cc_default_name);
-+ free(saved_cc_default_name);
-+ return retval;
-+ }
-+ }
-+ retval = krb5_cc_initialize(context, *cc_other, primary_principal);
-+ krb5_cc_set_default_name(context, saved_cc_default_name);
-+ free(saved_cc_default_name);
-+ if (retval) {
-+ return retval;
-+ }
-+ } else {
-+ *reused = FALSE;
-+ retval = krb5_cc_initialize(context, *cc_other, primary_principal);
-+ if (retval) {
-+ return retval;
-+ }
- }
-
- retval = krb5_store_all_creds(context, * cc_other, cc_def_creds_arr,
-@@ -650,6 +676,7 @@ krb5_error_code krb5_ccache_copy_restricted (context, cc_def, cc_other_tag,
- int i=0;
- krb5_ccache * cc_other;
- const char * cc_other_type;
-+ char * saved_cc_default_name;
- krb5_error_code retval=0;
- krb5_creds ** cc_def_creds_arr = NULL;
- krb5_creds ** cc_other_creds_arr = NULL;
-@@ -677,9 +704,30 @@ krb5_error_code krb5_ccache_copy_restricted (context, cc_def, cc_other_tag,
- return errno;
- }
-
--
-- if ((retval = krb5_cc_initialize(context, *cc_other, prst))){
-- return retval;
-+ if (krb5_cc_support_switch(context, cc_other_type)) {
-+ krb5_cc_close(context, *cc_other);
-+ saved_cc_default_name = strdup(krb5_cc_default_name(context));
-+ krb5_cc_set_default_name(context, cc_other_tag);
-+ if (krb5_cc_cache_match(context, prst, cc_other) != 0) {
-+ retval = krb5_cc_new_unique(context, cc_other_type, NULL,
-+ cc_other);
-+ if (retval) {
-+ krb5_cc_set_default_name(context, saved_cc_default_name);
-+ free(saved_cc_default_name);
-+ return retval;
-+ }
-+ }
-+ retval = krb5_cc_initialize(context, *cc_other, prst);
-+ if (retval) {
-+ return retval;
-+ }
-+ krb5_cc_set_default_name(context, saved_cc_default_name);
-+ free(saved_cc_default_name);
-+ } else {
-+ retval = krb5_cc_initialize(context, *cc_other, prst);
-+ if (retval) {
-+ return retval;
-+ }
- }
-
- retval = krb5_store_some_creds(context, * cc_other,
-diff --git a/src/clients/ksu/ksu.h b/src/clients/ksu/ksu.h
-index a195f52..b3ef7b9 100644
---- a/src/clients/ksu/ksu.h
-+++ b/src/clients/ksu/ksu.h
-@@ -108,7 +108,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_boolean, krb5_ccache *, krb5_boolean *, uid_t);
-+ krb5_boolean, krb5_ccache *, krb5_boolean *, 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 58df6a1..1c0c822 100644
---- a/src/clients/ksu/main.c
-+++ b/src/clients/ksu/main.c
-@@ -117,6 +117,7 @@ main (argc, argv)
- int pargc;
- char ** pargv;
- krb5_boolean stored = FALSE;
-+ krb5_boolean reused = FALSE;
- krb5_principal kdc_server;
- krb5_boolean zero_password;
-
-@@ -523,7 +524,8 @@ main (argc, argv)
- } else {
-
- retval = krb5_ccache_copy(ksu_context, cc_source, KRB5_TEMPORARY_CACHE,
-- client, FALSE, &cc_tmp, &stored, 0);
-+ client, FALSE, &cc_tmp, &stored, &reused,
-+ 0);
- if (retval) {
- com_err(prog_name, retval, _("while copying cache %s to %s"),
- krb5_cc_get_name(ksu_context, cc_source),
-@@ -801,7 +803,7 @@ main (argc, argv)
-
- retval = krb5_ccache_copy(ksu_context, cc_tmp, cc_target_tag,
- client, TRUE, &cc_target, &stored,
-- target_pwd->pw_uid);
-+ &reused, target_pwd->pw_uid);
- if (retval) {
- com_err(prog_name, retval, _("while copying cache %s to %s"),
- krb5_cc_get_name(ksu_context, cc_tmp), cc_target_tag);
-@@ -825,6 +827,11 @@ main (argc, argv)
- sweep_up(ksu_context, cc_target);
- exit(1);
- }
-+ if (reused && !keep_target_cache) {
-+ print_status(_("Reusing cache %s, it will not be removed.\n"),
-+ cc_target_tag);
-+ keep_target_cache = TRUE;
-+ }
- krb5_free_string(ksu_context, cc_target_tag);
- } else {
- com_err(prog_name, retval, _("while reading cache name from %s"),
---
-1.8.5.3
-
diff --git a/0006-Copy-config-entries-to-the-target-ccache.patch b/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@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@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@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.10-doublelog.patch b/krb5-1.10-doublelog.patch
deleted file mode 100644
index c20075c..0000000
--- a/krb5-1.10-doublelog.patch
+++ /dev/null
@@ -1,14 +0,0 @@
-Don't double-log (actually, don't process /etc/krb5.conf twice) just
-because we built with --sysconfdir=/etc. RT#3277
-
---- krb5/src/include/Makefile.in
-+++ krb5/src/include/Makefile.in
-@@ -67,6 +67,8 @@ PROCESS_REPLACE = -e "s+@KRB5RCTMPDIR+$(
- -e "s+@GSSMODULEDIR+$(GSS_MODULE_DIR)+" \
- -e 's+@LOCALSTATEDIR+$(LOCALSTATEDIR)+' \
- -e 's+@SYSCONFDIR+$(SYSCONFDIR)+' \
-+ -e 's+:/etc/krb5.conf:/etc/krb5.conf"+:/etc/krb5.conf"+' \
-+ -e 's+"/etc/krb5.conf:/etc/krb5.conf"+"/etc/krb5.conf"+' \
- -e 's+@DYNOBJEXT+$(DYNOBJEXT)+'
-
- OSCONFSRC = $(srcdir)/osconf.hin
diff --git a/krb5-1.12-CVE-2014-4341_4342-tests.patch b/krb5-1.12-CVE-2014-4341_4342-tests.patch
deleted file mode 100644
index 9db28e7..0000000
--- a/krb5-1.12-CVE-2014-4341_4342-tests.patch
+++ /dev/null
@@ -1,547 +0,0 @@
-Changes to .gitignore removed, chunks for tests/gssapi/Makefile.in adjusted to
-account for t_prf not being around yet, calls to gssint_g__seqstate_init()
-changed to calls to gssint_g_order_init(), changed attempt to export
-gssint_g_seqstate_init() to export gssint_g_order_init().
-
-commit 7a9990d73537dcdd95bf9b280ebfd560adf8342d
-Author: Greg Hudson <ghudson@mit.edu>
-Date: Thu Jun 19 13:13:33 2014 -0400
-
- Add tests for invalid GSSAPI per-message tokens
-
- ticket: 7949
-
---- a/src/lib/gssapi/libgssapi_krb5.exports
-+++ b/src/lib/gssapi/libgssapi_krb5.exports
-@@ -157,3 +157,4 @@ gss_inquire_name
- gss_acquire_cred_from
- gss_add_cred_from
- gss_store_cred_into
-+gssint_g_order_init
-diff --git a/src/tests/gssapi/Makefile.in b/src/tests/gssapi/Makefile.in
-index ac6a435..5effd90 100644
---- a/src/tests/gssapi/Makefile.in
-+++ b/src/tests/gssapi/Makefile.in
-@@ -1,6 +1,7 @@
- mydir=tests$(S)gssapi
- BUILDTOP=$(REL)..$(S)..
- DEFINES = -DUSE_AUTOCONF_H
-+LOCALINCLUDES = -I../../lib/gssapi/mechglue -I../../lib/gssapi/generic -I../../lib/gssapi/krb5
-
- SRCS= $(srcdir)/ccinit.c $(srcdir)/ccrefresh.c $(srcdir)/common.c \
- $(srcdir)/t_accname.c $(srcdir)/t_ccselect.c $(srcdir)/t_credstore.c \
-@@ -12,27 +13,28 @@ SRCS= $(srcdir)/ccinit.c $(srcdir)/ccrefresh.c $(srcdir)/common.c \
- $(srcdir)/t_accname.c $(srcdir)/t_ccselect.c $(srcdir)/t_credstore.c \
- $(srcdir)/t_enctypes.c $(srcdir)/t_err.c $(srcdir)/t_export_cred.c \
- $(srcdir)/t_export_name.c $(srcdir)/t_gssexts.c \
-- $(srcdir)/t_imp_cred.c $(srcdir)/t_imp_name.c $(srcdir)/t_inq_cred.c \
-- $(srcdir)/t_inq_mechs_name.c $(srcdir)/t_iov.c \
-+ $(srcdir)/t_imp_cred.c $(srcdir)/t_imp_name.c $(srcdir)/t_invalid.c \
-+ $(srcdir)/t_inq_cred.c $(srcdir)/t_inq_mechs_name.c $(srcdir)/t_iov.c \
- $(srcdir)/t_namingexts.c $(srcdir)/t_oid.c $(srcdir)/t_s4u.c \
- $(srcdir)/t_s4u2proxy_krb5.c $(srcdir)/t_saslname.c \
- $(srcdir)/t_spnego.c
-
- OBJS= ccinit.o ccrefresh.o common.o t_accname.o t_ccselect.o t_credstore.o \
- t_enctypes.o t_err.o t_export_cred.o t_export_name.o t_gssexts.o \
-- t_imp_cred.o t_imp_name.o t_inq_cred.o t_inq_mechs_name.o t_iov.o \
-- t_namingexts.o t_oid.o t_s4u.o t_s4u2proxy_krb5.o t_saslname.o \
-+ t_imp_cred.o t_imp_name.o t_invalid.o t_inq_cred.o t_inq_mechs_name.o \
-+ t_iov.o t_namingexts.o t_oid.o t_s4u.o t_s4u2proxy_krb5.o t_saslname.o \
- t_spnego.o
-
- COMMON_DEPS= common.o $(GSS_DEPLIBS) $(KRB5_BASE_DEPLIBS)
- COMMON_LIBS= common.o $(GSS_LIBS) $(KRB5_BASE_LIBS)
-
- all:: ccinit ccrefresh t_accname t_ccselect t_credstore t_enctypes t_err \
-- t_export_cred t_export_name t_gssexts t_imp_cred t_imp_name \
-+ t_export_cred t_export_name t_gssexts t_imp_cred t_imp_name t_invalid \
- t_inq_cred t_inq_mechs_name t_iov t_namingexts t_oid t_s4u \
- t_s4u2proxy_krb5 t_saslname t_spnego
-
- check-unix:: t_oid
-+ $(RUN_SETUP) $(VALGRIND) ./t_invalid
- $(RUN_SETUP) $(VALGRIND) ./t_oid
-
- check-pytests:: ccinit ccrefresh t_accname t_ccselect t_credstore t_enctypes \
-@@ -70,6 +72,8 @@ t_imp_cred: t_imp_cred.o $(COMMON_DEPS)
- $(CC_LINK) -o $@ t_imp_cred.o $(COMMON_LIBS)
- t_imp_name: t_imp_name.o $(COMMON_DEPS)
- $(CC_LINK) -o $@ t_imp_name.o $(COMMON_LIBS)
-+t_invalid: t_invalid.o $(COMMON_DEPS)
-+ $(CC_LINK) -o $@ t_invalid.o $(COMMON_LIBS)
- t_inq_cred: t_inq_cred.o $(COMMON_DEPS)
- $(CC_LINK) -o $@ t_inq_cred.o $(COMMON_LIBS)
- t_inq_mechs_name: t_inq_mechs_name.o $(COMMON_DEPS)
-@@ -94,5 +98,5 @@ t_spnego: t_spnego.o $(COMMON_DEPS)
- clean::
- $(RM) ccinit ccrefresh t_accname t_ccselect t_credstore t_enctypes
- $(RM) t_err t_export_cred t_export_name t_gssexts t_imp_cred t_imp_name
-- $(RM) t_inq_cred t_inq_mechs_name t_iov t_namingexts t_oid t_s4u
-- $(RM) t_s4u2proxy_krb5 t_saslname t_spnego
-+ $(RM) t_invalid t_inq_cred t_inq_mechs_name t_iov t_namingexts t_oid
-+ $(RM) t_s4u t_s4u2proxy_krb5 t_saslname t_spnego
-diff --git a/src/tests/gssapi/deps b/src/tests/gssapi/deps
-index c76d4ca..0a82d5d 100644
---- a/src/tests/gssapi/deps
-+++ b/src/tests/gssapi/deps
-@@ -75,6 +75,24 @@ $(OUTPRE)t_imp_name.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \
- $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \
- $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \
- common.h t_imp_name.c
-+$(OUTPRE)t_invalid.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
-+ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_alloc.h \
-+ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \
-+ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
-+ $(BUILDTOP)/include/profile.h $(BUILDTOP)/lib/gssapi/generic/gssapi_err_generic.h \
-+ $(BUILDTOP)/lib/gssapi/krb5/gssapi_err_krb5.h $(COM_ERR_DEPS) \
-+ $(srcdir)/../../lib/gssapi/generic/gssapiP_generic.h \
-+ $(srcdir)/../../lib/gssapi/generic/gssapi_ext.h $(srcdir)/../../lib/gssapi/generic/gssapi_generic.h \
-+ $(srcdir)/../../lib/gssapi/krb5/gssapiP_krb5.h $(srcdir)/../../lib/gssapi/krb5/gssapi_krb5.h \
-+ $(srcdir)/../../lib/gssapi/mechglue/mechglue.h $(srcdir)/../../lib/gssapi/mechglue/mglueP.h \
-+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \
-+ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \
-+ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \
-+ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \
-+ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \
-+ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \
-+ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
-+ common.h t_invalid.c
- $(OUTPRE)t_inq_cred.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \
- $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \
- $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \
-diff --git a/src/tests/gssapi/t_invalid.c b/src/tests/gssapi/t_invalid.c
-new file mode 100644
-index 0000000..5c8ddac
---- /dev/null
-+++ b/src/tests/gssapi/t_invalid.c
-@@ -0,0 +1,429 @@
-+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-+/* tests/gssapi/t_invalid.c - Invalid message token regression tests */
-+/*
-+ * Copyright (C) 2014 by the Massachusetts Institute of Technology.
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ *
-+ * * Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ *
-+ * * Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in
-+ * the documentation and/or other materials provided with the
-+ * distribution.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-+ * OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+/*
-+ * This file contains regression tests for some GSSAPI krb5 invalid per-message
-+ * token vulnerabilities.
-+ *
-+ * 1. A pre-CFX wrap or MIC token processed with a CFX-only context causes a
-+ * null pointer dereference. (The token must use SEAL_ALG_NONE or it will
-+ * be rejected.)
-+ *
-+ * 2. A pre-CFX wrap or MIC token with fewer than 24 bytes after the ASN.1
-+ * header causes an input buffer overrun, usually leading to either a segv
-+ * or a GSS_S_DEFECTIVE_TOKEN error due to garbage algorithm, filler, or
-+ * sequence number values.
-+ *
-+ * 3. A pre-CFX wrap token with fewer than 16 + cksumlen bytes after the ASN.1
-+ * header causes an integer underflow when computing the ciphertext length,
-+ * leading to an allocation error on 32-bit platforms or a segv on 64-bit
-+ * platforms. A pre-CFX MIC token of this size causes an input buffer
-+ * overrun when comparing the checksum, perhaps leading to a segv.
-+ *
-+ * 4. A pre-CFX wrap token with fewer than conflen + padlen bytes in the
-+ * ciphertext (where padlen is the last byte of the decrypted ciphertext)
-+ * causes an integer underflow when computing the original message length,
-+ * leading to an allocation error.
-+ *
-+ * Vulnerabilities #1 and #2 also apply to IOV unwrap, although tokens with
-+ * fewer than 16 bytes after the ASN.1 header will be rejected. Vulnerability
-+ * #2 can only be robustly detected using a memory-checking environment such as
-+ * valgrind.
-+ */
-+
-+#include "k5-int.h"
-+#include "common.h"
-+#include "mglueP.h"
-+#include "gssapiP_krb5.h"
-+
-+/*
-+ * The following samples contain context parameters and otherwise valid seal
-+ * tokens where the plain text is padded with byte value 100 instead of the
-+ * proper value 1.
-+ */
-+struct test {
-+ krb5_enctype enctype;
-+ krb5_enctype encseq_enctype;
-+ int sealalg;
-+ int signalg;
-+ size_t cksum_size;
-+ size_t keylen;
-+ const char *keydata;
-+ size_t toklen;
-+ const char *token;
-+} tests[] = {
-+ {
-+ ENCTYPE_DES_CBC_CRC, ENCTYPE_DES_CBC_RAW,
-+ SEAL_ALG_DES, SGN_ALG_DES_MAC_MD5, 8,
-+ 8,
-+ "\x26\xEC\xBA\xB6\xFE\xBA\x91\xCE",
-+ 53,
-+ "\x60\x33\x06\x09\x2A\x86\x48\x86\xF7\x12\x01\x02\x02\x02\x01\x00"
-+ "\x00\x00\x00\xFF\xFF\xF0\x0B\x90\x7B\xC4\xFC\xEB\xF4\x84\x9C\x5A"
-+ "\xA8\x56\x41\x3E\xE1\x62\xEE\x38\xD1\x34\x9A\xE3\xFB\xC9\xFD\x0A"
-+ "\xDC\x83\xE1\x4A\xE4"
-+ },
-+ {
-+ ENCTYPE_DES3_CBC_SHA1, ENCTYPE_DES3_CBC_RAW,
-+ SEAL_ALG_DES3KD, SGN_ALG_HMAC_SHA1_DES3_KD, 20,
-+ 24,
-+ "\x4F\xEA\x19\x19\x5E\x0E\x10\xDF\x3D\x29\xB5\x13\x8F\x01\xC7\xA7"
-+ "\x92\x3D\x38\xF7\x26\x73\x0D\x6D",
-+ 65,
-+ "\x60\x3F\x06\x09\x2A\x86\x48\x86\xF7\x12\x01\x02\x02\x02\x01\x04"
-+ "\x00\x02\x00\xFF\xFF\xEB\xF3\x9A\x89\x24\x57\xB8\x63\x95\x25\xE8"
-+ "\x6E\x8E\x79\xE6\x2E\xCA\xD3\xFF\x57\x9F\x8C\xAB\xEF\xDD\x28\x10"
-+ "\x2F\x93\x21\x2E\xF2\x52\xB6\x6F\xA8\xBB\x8A\x6D\xAA\x6F\xB7\xF4\xD4"
-+ },
-+ {
-+ ENCTYPE_ARCFOUR_HMAC, ENCTYPE_ARCFOUR_HMAC,
-+ SEAL_ALG_MICROSOFT_RC4, SGN_ALG_HMAC_MD5, 8,
-+ 16,
-+ "\x66\x64\x41\x64\x55\x78\x21\xD0\xD0\xFD\x05\x6A\xFF\x6F\xE8\x09",
-+ 53,
-+ "\x60\x33\x06\x09\x2A\x86\x48\x86\xF7\x12\x01\x02\x02\x02\x01\x11"
-+ "\x00\x10\x00\xFF\xFF\x35\xD4\x79\xF3\x8C\x47\x8F\x6E\x23\x6F\x3E"
-+ "\xCC\x5E\x57\x5C\x6A\x89\xF0\xA2\x03\x4F\x0B\x51\x11\xEE\x89\x7E"
-+ "\xD6\xF6\xB5\xD6\x51"
-+ }
-+};
-+
-+/* Fake up enough of a CFX GSS context for gss_unwrap, using an AES key. */
-+static gss_ctx_id_t
-+make_fake_cfx_context()
-+{
-+ gss_union_ctx_id_t uctx;
-+ krb5_gss_ctx_id_t kgctx;
-+ krb5_keyblock kb;
-+
-+ kgctx = calloc(1, sizeof(*kgctx));
-+ if (kgctx == NULL)
-+ abort();
-+ kgctx->established = 1;
-+ kgctx->proto = 1;
-+ if (g_order_init(&kgctx->seqstate, 0, 0, 0, 0) != 0)
-+ abort();
-+ kgctx->mech_used = &mech_krb5;
-+ kgctx->sealalg = -1;
-+ kgctx->signalg = -1;
-+
-+ kb.enctype = ENCTYPE_AES128_CTS_HMAC_SHA1_96;
-+ kb.length = 16;
-+ kb.contents = (unsigned char *)"1234567887654321";
-+ if (krb5_k_create_key(NULL, &kb, &kgctx->subkey) != 0)
-+ abort();
-+
-+ uctx = calloc(1, sizeof(*uctx));
-+ if (uctx == NULL)
-+ abort();
-+ uctx->mech_type = &mech_krb5;
-+ uctx->internal_ctx_id = (gss_ctx_id_t)kgctx;
-+ return (gss_ctx_id_t)uctx;
-+}
-+
-+/* Fake up enough of a GSS context for gss_unwrap, using keys from test. */
-+static gss_ctx_id_t
-+make_fake_context(const struct test *test)
-+{
-+ gss_union_ctx_id_t uctx;
-+ krb5_gss_ctx_id_t kgctx;
-+ krb5_keyblock kb;
-+ unsigned char encbuf[8];
-+ size_t i;
-+
-+ kgctx = calloc(1, sizeof(*kgctx));
-+ if (kgctx == NULL)
-+ abort();
-+ kgctx->established = 1;
-+ if (g_order_init(&kgctx->seqstate, 0, 0, 0, 0) != 0)
-+ abort();
-+ kgctx->mech_used = &mech_krb5;
-+ kgctx->sealalg = test->sealalg;
-+ kgctx->signalg = test->signalg;
-+ kgctx->cksum_size = test->cksum_size;
-+
-+ kb.enctype = test->enctype;
-+ kb.length = test->keylen;
-+ kb.contents = (unsigned char *)test->keydata;
-+ if (krb5_k_create_key(NULL, &kb, &kgctx->subkey) != 0)
-+ abort();
-+
-+ kb.enctype = test->encseq_enctype;
-+ if (krb5_k_create_key(NULL, &kb, &kgctx->seq) != 0)
-+ abort();
-+
-+ if (kb.enctype == ENCTYPE_DES_CBC_RAW) {
-+ for (i = 0; i < 8; i++)
-+ encbuf[i] = kb.contents[i] ^ 0xF0;
-+ kb.contents = encbuf;
-+ }
-+ if (krb5_k_create_key(NULL, &kb, &kgctx->enc) != 0)
-+ abort();
-+
-+ uctx = calloc(1, sizeof(*uctx));
-+ if (uctx == NULL)
-+ abort();
-+ uctx->mech_type = &mech_krb5;
-+ uctx->internal_ctx_id = (gss_ctx_id_t)kgctx;
-+ return (gss_ctx_id_t)uctx;
-+}
-+
-+/* Free a context created by make_fake_context. */
-+static void
-+free_fake_context(gss_ctx_id_t ctx)
-+{
-+ gss_union_ctx_id_t uctx = (gss_union_ctx_id_t)ctx;
-+ krb5_gss_ctx_id_t kgctx = (krb5_gss_ctx_id_t)uctx->internal_ctx_id;
-+
-+ free(kgctx->seqstate);
-+ krb5_k_free_key(NULL, kgctx->subkey);
-+ krb5_k_free_key(NULL, kgctx->seq);
-+ krb5_k_free_key(NULL, kgctx->enc);
-+ free(kgctx);
-+ free(uctx);
-+}
-+
-+/* Prefix a token (starting at the two-byte ID) with an ASN.1 header and return
-+ * it in an allocated block to facilitate checking by valgrind or similar. */
-+static void
-+make_token(unsigned char *token, size_t len, gss_buffer_t out)
-+{
-+ char *wrapped;
-+
-+ assert(mech_krb5.length == 9);
-+ assert(len + 11 < 128);
-+ wrapped = malloc(len + 13);
-+ if (wrapped == NULL)
-+ abort();
-+ wrapped[0] = 0x60;
-+ wrapped[1] = len + 11;
-+ wrapped[2] = 0x06;
-+ wrapped[3] = 9;
-+ memcpy(wrapped + 4, mech_krb5.elements, 9);
-+ memcpy(wrapped + 13, token, len);
-+ out->length = len + 13;
-+ out->value = wrapped;
-+}
-+
-+/* Unwrap a superficially valid RFC 1964 token with a CFX-only context, with
-+ * regular and IOV unwrap. */
-+static void
-+test_bogus_1964_token(gss_ctx_id_t ctx)
-+{
-+ OM_uint32 minor, major;
-+ unsigned char tokbuf[128];
-+ gss_buffer_desc in, out;
-+ gss_iov_buffer_desc iov;
-+
-+ store_16_be(KG_TOK_SIGN_MSG, tokbuf);
-+ store_16_le(SGN_ALG_DES_MAC_MD5, tokbuf + 2);
-+ store_16_le(SEAL_ALG_NONE, tokbuf + 4);
-+ store_16_le(0xFFFF, tokbuf + 6);
-+ memset(tokbuf + 8, 0, 16);
-+ make_token(tokbuf, 24, &in);
-+
-+ major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL);
-+ if (major != GSS_S_DEFECTIVE_TOKEN)
-+ abort();
-+ (void)gss_release_buffer(&minor, &out);
-+
-+ iov.type = GSS_IOV_BUFFER_TYPE_HEADER;
-+ iov.buffer = in;
-+ major = gss_unwrap_iov(&minor, ctx, NULL, NULL, &iov, 1);
-+ if (major != GSS_S_DEFECTIVE_TOKEN)
-+ abort();
-+
-+ free(in.value);
-+}
-+
-+/* Process wrap and MIC tokens with incomplete headers. */
-+static void
-+test_short_header(gss_ctx_id_t ctx)
-+{
-+ OM_uint32 minor, major;
-+ unsigned char tokbuf[128];
-+ gss_buffer_desc in, out, empty = GSS_C_EMPTY_BUFFER;
-+
-+ /* Seal token, 2-24 bytes */
-+ store_16_be(KG_TOK_SEAL_MSG, tokbuf);
-+ make_token(tokbuf, 2, &in);
-+ major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL);
-+ if (major != GSS_S_DEFECTIVE_TOKEN)
-+ abort();
-+ free(in.value);
-+ (void)gss_release_buffer(&minor, &out);
-+
-+ /* Sign token, 2-24 bytes */
-+ store_16_be(KG_TOK_SIGN_MSG, tokbuf);
-+ make_token(tokbuf, 2, &in);
-+ major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL);
-+ if (major != GSS_S_DEFECTIVE_TOKEN)
-+ abort();
-+ free(in.value);
-+ (void)gss_release_buffer(&minor, &out);
-+
-+ /* MIC token, 2-24 bytes */
-+ store_16_be(KG_TOK_MIC_MSG, tokbuf);
-+ make_token(tokbuf, 2, &in);
-+ major = gss_verify_mic(&minor, ctx, &empty, &in, NULL);
-+ if (major != GSS_S_DEFECTIVE_TOKEN)
-+ abort();
-+ free(in.value);
-+}
-+
-+/* Process wrap and MIC tokens with incomplete headers. */
-+static void
-+test_short_header_iov(gss_ctx_id_t ctx, const struct test *test)
-+{
-+ OM_uint32 minor, major;
-+ unsigned char tokbuf[128];
-+ gss_iov_buffer_desc iov;
-+
-+ /* IOV seal token, 16-23 bytes */
-+ store_16_be(KG_TOK_SEAL_MSG, tokbuf);
-+ store_16_le(test->signalg, tokbuf + 2);
-+ store_16_le(test->sealalg, tokbuf + 4);
-+ store_16_be(0xFFFF, tokbuf + 6);
-+ memset(tokbuf + 8, 0, 8);
-+ iov.type = GSS_IOV_BUFFER_TYPE_HEADER;
-+ make_token(tokbuf, 16, &iov.buffer);
-+ major = gss_unwrap_iov(&minor, ctx, NULL, NULL, &iov, 1);
-+ if (major != GSS_S_DEFECTIVE_TOKEN)
-+ abort();
-+ free(iov.buffer.value);
-+
-+ /* IOV sign token, 16-23 bytes */
-+ store_16_be(KG_TOK_SIGN_MSG, tokbuf);
-+ store_16_le(test->signalg, tokbuf + 2);
-+ store_16_le(SEAL_ALG_NONE, tokbuf + 4);
-+ store_16_le(0xFFFF, tokbuf + 6);
-+ memset(tokbuf + 8, 0, 8);
-+ iov.type = GSS_IOV_BUFFER_TYPE_HEADER;
-+ make_token(tokbuf, 16, &iov.buffer);
-+ major = gss_unwrap_iov(&minor, ctx, NULL, NULL, &iov, 1);
-+ if (major != GSS_S_DEFECTIVE_TOKEN)
-+ abort();
-+ free(iov.buffer.value);
-+
-+ /* IOV MIC token, 16-23 bytes */
-+ store_16_be(KG_TOK_MIC_MSG, tokbuf);
-+ store_16_be(test->signalg, tokbuf + 2);
-+ store_16_le(SEAL_ALG_NONE, tokbuf + 4);
-+ store_16_le(0xFFFF, tokbuf + 6);
-+ memset(tokbuf + 8, 0, 8);
-+ iov.type = GSS_IOV_BUFFER_TYPE_MIC_TOKEN;
-+ make_token(tokbuf, 16, &iov.buffer);
-+ major = gss_verify_mic_iov(&minor, ctx, NULL, &iov, 1);
-+ if (major != GSS_S_DEFECTIVE_TOKEN)
-+ abort();
-+ free(iov.buffer.value);
-+}
-+
-+/* Process wrap and MIC tokens with incomplete checksums. */
-+static void
-+test_short_checksum(gss_ctx_id_t ctx, const struct test *test)
-+{
-+ OM_uint32 minor, major;
-+ unsigned char tokbuf[128];
-+ gss_buffer_desc in, out, empty = GSS_C_EMPTY_BUFFER;
-+
-+ /* Can only do this with the DES3 checksum, as we can't easily get past
-+ * retrieving the sequence number when the checksum is only eight bytes. */
-+ if (test->cksum_size <= 8)
-+ return;
-+ /* Seal token, fewer than 16 + cksum_size bytes. Use the token from the
-+ * test data to get a valid sequence number. */
-+ make_token((unsigned char *)test->token + 13, 24, &in);
-+ major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL);
-+ if (major != GSS_S_DEFECTIVE_TOKEN)
-+ abort();
-+ free(in.value);
-+ (void)gss_release_buffer(&minor, &out);
-+
-+ /* Sign token, fewer than 16 + cksum_size bytes. */
-+ memcpy(tokbuf, test->token + 13, 24);
-+ store_16_be(KG_TOK_SIGN_MSG, tokbuf);
-+ store_16_le(SEAL_ALG_NONE, tokbuf + 4);
-+ make_token(tokbuf, 24, &in);
-+ major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL);
-+ if (major != GSS_S_DEFECTIVE_TOKEN)
-+ abort();
-+ free(in.value);
-+ (void)gss_release_buffer(&minor, &out);
-+
-+ /* MIC token, fewer than 16 + cksum_size bytes. */
-+ memcpy(tokbuf, test->token + 13, 24);
-+ store_16_be(KG_TOK_MIC_MSG, tokbuf);
-+ store_16_le(SEAL_ALG_NONE, tokbuf + 4);
-+ make_token(tokbuf, 24, &in);
-+ major = gss_verify_mic(&minor, ctx, &empty, &in, NULL);
-+ if (major != GSS_S_DEFECTIVE_TOKEN)
-+ abort();
-+ free(in.value);
-+}
-+
-+/* Unwrap a token with a bogus padding byte in the decrypted ciphertext. */
-+static void
-+test_bad_pad(gss_ctx_id_t ctx, const struct test *test)
-+{
-+ OM_uint32 minor, major;
-+ gss_buffer_desc in, out;
-+
-+ in.length = test->toklen;
-+ in.value = (char *)test->token;
-+ major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL);
-+ if (major != GSS_S_BAD_SIG)
-+ abort();
-+ (void)gss_release_buffer(&minor, &out);
-+}
-+
-+int
-+main(int argc, char **argv)
-+{
-+ gss_ctx_id_t ctx;
-+ size_t i;
-+
-+ ctx = make_fake_cfx_context();
-+ test_bogus_1964_token(ctx);
-+ free_fake_context(ctx);
-+
-+ for (i = 0; i < sizeof(tests) / sizeof(*tests); i++) {
-+ ctx = make_fake_context(&tests[i]);
-+ test_short_header(ctx);
-+ test_short_header_iov(ctx, &tests[i]);
-+ test_short_checksum(ctx, &tests[i]);
-+ test_bad_pad(ctx, &tests[i]);
-+ free_fake_context(ctx);
-+ }
-+
-+ return 0;
-+}
diff --git a/krb5-1.12-CVE-2014-4341_4342.patch b/krb5-1.12-CVE-2014-4341_4342.patch
deleted file mode 100644
index c7719d2..0000000
--- a/krb5-1.12-CVE-2014-4341_4342.patch
+++ /dev/null
@@ -1,163 +0,0 @@
-commit e6ae703ae597d798e310368d52b8f38ee11c6a73
-Author: Greg Hudson <ghudson@mit.edu>
-Date: Thu Jun 19 13:49:16 2014 -0400
-
- Handle invalid RFC 1964 tokens [CVE-2014-4341...]
-
- Detect the following cases which would otherwise cause invalid memory
- accesses and/or integer underflow:
-
- * An RFC 1964 token being processed by an RFC 4121-only context
- [CVE-2014-4342]
-
- * A header with fewer than 22 bytes after the token ID or an
- incomplete checksum [CVE-2014-4341 CVE-2014-4342]
-
- * A ciphertext shorter than the confounder [CVE-2014-4341]
-
- * A declared padding length longer than the plaintext [CVE-2014-4341]
-
- If we detect a bad pad byte, continue on to compute the checksum to
- avoid creating a padding oracle, but treat the checksum as invalid
- even if it compares equal.
-
- CVE-2014-4341:
-
- In MIT krb5, an unauthenticated remote attacker with the ability to
- inject packets into a legitimately established GSSAPI application
- session can cause a program crash due to invalid memory references
- when attempting to read beyond the end of a buffer.
-
- CVSSv2 Vector: AV:N/AC:M/Au:N/C:N/I:N/A:P/E:POC/RL:OF/RC:C
-
- CVE-2014-4342:
-
- In MIT krb5 releases krb5-1.7 and later, an unauthenticated remote
- attacker with the ability to inject packets into a legitimately
- established GSSAPI application session can cause a program crash due
- to invalid memory references when reading beyond the end of a buffer
- or by causing a null pointer dereference.
-
- CVSSv2 Vector: AV:N/AC:M/Au:N/C:N/I:N/A:P/E:POC/RL:OF/RC:C
-
- [tlyu@mit.edu: CVE summaries, CVSS]
-
- (cherry picked from commit fb99962cbd063ac04c9a9d2cc7c75eab73f3533d)
-
- ticket: 7949
- version_fixed: 1.12.2
- status: resolved
-
-diff --git a/src/lib/gssapi/krb5/k5unseal.c b/src/lib/gssapi/krb5/k5unseal.c
-index ca21d43..b65c83c 100644
---- a/src/lib/gssapi/krb5/k5unseal.c
-+++ b/src/lib/gssapi/krb5/k5unseal.c
-@@ -74,6 +74,7 @@ kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer,
- int conflen = 0;
- int signalg;
- int sealalg;
-+ int bad_pad = 0;
- gss_buffer_desc token;
- krb5_checksum cksum;
- krb5_checksum md5cksum;
-@@ -86,6 +87,7 @@ kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer,
- krb5_ui_4 seqnum;
- OM_uint32 retval;
- size_t sumlen;
-+ size_t padlen;
- krb5_keyusage sign_usage = KG_USAGE_SIGN;
-
- if (toktype == KG_TOK_SEAL_MSG) {
-@@ -93,18 +95,23 @@ kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer,
- message_buffer->value = NULL;
- }
-
-- /* get the sign and seal algorithms */
--
-- signalg = ptr[0] + (ptr[1]<<8);
-- sealalg = ptr[2] + (ptr[3]<<8);
--
- /* Sanity checks */
-
-- if ((ptr[4] != 0xff) || (ptr[5] != 0xff)) {
-+ if (ctx->seq == NULL) {
-+ /* ctx was established using a newer enctype, and cannot process RFC
-+ * 1964 tokens. */
-+ *minor_status = 0;
-+ return GSS_S_DEFECTIVE_TOKEN;
-+ }
-+
-+ if ((bodysize < 22) || (ptr[4] != 0xff) || (ptr[5] != 0xff)) {
- *minor_status = 0;
- return GSS_S_DEFECTIVE_TOKEN;
- }
-
-+ signalg = ptr[0] + (ptr[1]<<8);
-+ sealalg = ptr[2] + (ptr[3]<<8);
-+
- if ((toktype != KG_TOK_SEAL_MSG) &&
- (sealalg != 0xffff)) {
- *minor_status = 0;
-@@ -153,6 +160,11 @@ kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer,
- return GSS_S_DEFECTIVE_TOKEN;
- }
-
-+ if ((size_t)bodysize < 14 + cksum_len) {
-+ *minor_status = 0;
-+ return GSS_S_DEFECTIVE_TOKEN;
-+ }
-+
- /* get the token parameters */
-
- if ((code = kg_get_seq_num(context, ctx->seq, ptr+14, ptr+6, &direction,
-@@ -207,7 +219,20 @@ kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer,
- plainlen = tmsglen;
-
- conflen = kg_confounder_size(context, ctx->enc->keyblock.enctype);
-- token.length = tmsglen - conflen - plain[tmsglen-1];
-+ if (tmsglen < conflen) {
-+ if (sealalg != 0xffff)
-+ xfree(plain);
-+ *minor_status = 0;
-+ return(GSS_S_DEFECTIVE_TOKEN);
-+ }
-+ padlen = plain[tmsglen - 1];
-+ if (tmsglen - conflen < padlen) {
-+ /* Don't error out yet, to avoid padding oracle attacks. We will
-+ * treat this as a checksum failure later on. */
-+ padlen = 0;
-+ bad_pad = 1;
-+ }
-+ token.length = tmsglen - conflen - padlen;
-
- if (token.length) {
- if ((token.value = (void *) gssalloc_malloc(token.length)) == NULL) {
-@@ -403,7 +428,7 @@ kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer,
-
- /* compare the computed checksum against the transmitted checksum */
-
-- if (code) {
-+ if (code || bad_pad) {
- if (toktype == KG_TOK_SEAL_MSG)
- gssalloc_free(token.value);
- *minor_status = 0;
-diff --git a/src/lib/gssapi/krb5/k5unsealiov.c b/src/lib/gssapi/krb5/k5unsealiov.c
-index e34bda4..8d6a2da 100644
---- a/src/lib/gssapi/krb5/k5unsealiov.c
-+++ b/src/lib/gssapi/krb5/k5unsealiov.c
-@@ -69,7 +69,14 @@ kg_unseal_v1_iov(krb5_context context,
- return GSS_S_DEFECTIVE_TOKEN;
- }
-
-- if (header->buffer.length < token_wrapper_len + 14) {
-+ if (ctx->seq == NULL) {
-+ /* ctx was established using a newer enctype, and cannot process RFC
-+ * 1964 tokens. */
-+ *minor_status = 0;
-+ return GSS_S_DEFECTIVE_TOKEN;
-+ }
-+
-+ if (header->buffer.length < token_wrapper_len + 22) {
- *minor_status = 0;
- return GSS_S_DEFECTIVE_TOKEN;
- }
diff --git a/krb5-1.12-tcl86.patch b/krb5-1.12-tcl86.patch
deleted file mode 100644
index 565a78d..0000000
--- a/krb5-1.12-tcl86.patch
+++ /dev/null
@@ -1,149 +0,0 @@
-commit b63496d7b44f090ea5d300dc09b4fc043138ae38
-Author: Greg Hudson <ghudson@mit.edu>
-Date: Wed May 28 18:06:59 2014 -0400
-
- Make tcl_kadm5.c work with Tcl 8.6
-
- Directly accessing the result field of Tcl_Interp has been deprecated
- for a long time, requires a special define in Tcl 8.6, and will be
- impossible in Tcl 9. Use Tcl_SetResult instead. The new error
- messages are less helpful than the old ones, but this is just support
- infrastructure for old tests, so it isn't important.
-
- ticket: 7924
-
-diff --git a/src/kadmin/testing/util/tcl_kadm5.c b/src/kadmin/testing/util/tcl_kadm5.c
-index 8338cc9..b2f51d3 100644
---- a/src/kadmin/testing/util/tcl_kadm5.c
-+++ b/src/kadmin/testing/util/tcl_kadm5.c
-@@ -801,8 +801,7 @@ static int parse_keysalts(Tcl_Interp *interp, const char *list,
- return retcode;
- }
- if (argc != num_keysalts) {
-- sprintf(interp->result, "%d keysalts specified, "
-- "but num_keysalts is %d", argc, num_keysalts);
-+ Tcl_SetResult(interp, "wrong number of keysalts", TCL_STATIC);
- retcode = TCL_ERROR;
- goto finished;
- }
-@@ -814,8 +813,7 @@ static int parse_keysalts(Tcl_Interp *interp, const char *list,
- goto finished;
- }
- if (argc1 != 2) {
-- sprintf(interp->result, "wrong # fields in keysalt "
-- "(%d should be 2)", argc1);
-+ Tcl_SetResult(interp, "wrong # of fields in keysalt", TCL_STATIC);
- retcode = TCL_ERROR;
- goto finished;
- }
-@@ -856,8 +854,7 @@ static int parse_key_data(Tcl_Interp *interp, const char *list,
- *key_data = NULL;
- if (list == NULL) {
- if (n_key_data != 0) {
-- sprintf(interp->result, "0 key_datas specified, "
-- "but n_key_data is %d", n_key_data);
-+ Tcl_SetResult(interp, "wrong number of key_datas", TCL_STATIC);
- retcode = TCL_ERROR;
- goto finished;
- } else
-@@ -868,14 +865,13 @@ static int parse_key_data(Tcl_Interp *interp, const char *list,
- return retcode;
- }
- if (argc != n_key_data) {
-- sprintf(interp->result, "%d key_datas specified, "
-- "but n_key_data is %d", argc, n_key_data);
-+ Tcl_SetResult(interp, "wrong number of key_datas", TCL_STATIC);
- retcode = TCL_ERROR;
- goto finished;
- }
-
- if (argc != 0) {
-- sprintf(interp->result, "cannot parse key_data yet");
-+ Tcl_SetResult(interp, "cannot parse key_data yet", TCL_STATIC);
- retcode = TCL_ERROR;
- goto finished;
- }
-@@ -896,8 +892,7 @@ static int parse_tl_data(Tcl_Interp *interp, const char *list,
- *tlp = NULL;
- if (list == NULL) {
- if (n_tl_data != 0) {
-- sprintf(interp->result, "0 tl_datas specified, "
-- "but n_tl_data is %d", n_tl_data);
-+ Tcl_SetResult(interp, "wrong number of tl_datas", TCL_STATIC);
- retcode = TCL_ERROR;
- goto finished;
- } else
-@@ -908,8 +903,7 @@ static int parse_tl_data(Tcl_Interp *interp, const char *list,
- return retcode;
- }
- if (argc != n_tl_data) {
-- sprintf(interp->result, "%d tl_datas specified, "
-- "but n_tl_data is %d", argc, n_tl_data);
-+ Tcl_SetResult(interp, "wrong number of tl_datas", TCL_STATIC);
- retcode = TCL_ERROR;
- goto finished;
- }
-@@ -929,8 +923,7 @@ static int parse_tl_data(Tcl_Interp *interp, const char *list,
- goto finished;
- }
- if (argc1 != 3) {
-- sprintf(interp->result, "wrong # fields in tl_data "
-- "(%d should be 3)", argc1);
-+ Tcl_SetResult(interp, "wrong # of fields in tl_data", TCL_STATIC);
- retcode = TCL_ERROR;
- goto finished;
- }
-@@ -949,9 +942,7 @@ static int parse_tl_data(Tcl_Interp *interp, const char *list,
- }
- tl->tl_data_length = tmp;
- if (tl->tl_data_length != strlen(argv1[2])) {
-- sprintf(interp->result, "specified length %d does not "
-- "match length %lu of string \"%s\"", tmp,
-- (unsigned long) strlen(argv1[2]), argv1[2]);
-+ Tcl_SetResult(interp, "length != string length", TCL_STATIC);
- retcode = TCL_ERROR;
- goto finished;
- }
-@@ -962,7 +953,7 @@ static int parse_tl_data(Tcl_Interp *interp, const char *list,
- tl = tl->tl_data_next;
- }
- if (tl != NULL) {
-- sprintf(interp->result, "tl is not NULL!");
-+ Tcl_SetResult(interp, "tl is not NULL!", TCL_STATIC);
- retcode = TCL_ERROR;
- goto finished;
- }
-@@ -992,9 +983,8 @@ static int parse_config_params(Tcl_Interp *interp, char *list,
- }
-
- if (argc != 20) {
-- sprintf(interp->result,
-- "wrong # args in config params structure (%d should be 20)",
-- argc);
-+ Tcl_SetResult(interp, "wrong # args in config params structure",
-+ TCL_STATIC);
- retcode = TCL_ERROR;
- goto finished;
- }
-@@ -1129,9 +1119,8 @@ static int parse_principal_ent(Tcl_Interp *interp, char *list,
- }
-
- if (argc != 12 && argc != 20) {
-- sprintf(interp->result,
-- "wrong # args in principal structure (%d should be 12 or 20)",
-- argc);
-+ Tcl_SetResult(interp, "wrong # args in principal structure",
-+ TCL_STATIC);
- retcode = TCL_ERROR;
- goto finished;
- }
-@@ -1391,8 +1380,7 @@ static int parse_policy_ent(Tcl_Interp *interp, char *list,
- }
-
- if (argc != 7 && argc != 10) {
-- sprintf(interp->result, "wrong # args in policy structure (%d should be 7 or 10)",
-- argc);
-+ Tcl_SetResult(interp, "wrong # args in policy structure", TCL_STATIC);
- retcode = TCL_ERROR;
- goto finished;
- }
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-master-empty-credstore.patch b/krb5-master-empty-credstore.patch
deleted file mode 100644
index b6cd7ef..0000000
--- a/krb5-master-empty-credstore.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-commit 970304b558a360e08d8421ef92245d2df0ac5e49
-Author: Greg Hudson <ghudson@mit.edu>
-Date: Thu Jan 16 11:49:04 2014 -0500
-
- Allow empty store in gss_acquire_cred_from
-
- There is no reason to deny a zero-length cred store, so don't check
- for it in val_acq_cred_args or val_add_cred_args.
-
- ticket: 7836 (new)
- target_version: 1.12.2
- tags: pullup
-
-diff --git a/src/lib/gssapi/mechglue/g_acquire_cred.c b/src/lib/gssapi/mechglue/g_acquire_cred.c
-index 03b67e3..b9a3142 100644
---- a/src/lib/gssapi/mechglue/g_acquire_cred.c
-+++ b/src/lib/gssapi/mechglue/g_acquire_cred.c
-@@ -80,12 +80,6 @@ val_acq_cred_args(
- return GSS_S_FAILURE;
- }
-
-- if (cred_store != NULL && cred_store->count == 0) {
-- *minor_status = EINVAL;
-- map_errcode(minor_status);
-- return GSS_S_FAILURE;
-- }
--
- return (GSS_S_COMPLETE);
- }
-
-@@ -302,12 +296,6 @@ val_add_cred_args(
- return GSS_S_FAILURE;
- }
-
-- if (cred_store != NULL && cred_store->count == 0) {
-- *minor_status = EINVAL;
-- map_errcode(minor_status);
-- return GSS_S_FAILURE;
-- }
--
- return (GSS_S_COMPLETE);
- }
-
diff --git a/krb5-master-keyring-kdcsync.patch b/krb5-master-keyring-kdcsync.patch
deleted file mode 100644
index 3079bf2..0000000
--- a/krb5-master-keyring-kdcsync.patch
+++ /dev/null
@@ -1,108 +0,0 @@
-commit e99c688913a7761c6adea9488ea9355f43539883
-Author: Greg Hudson <ghudson@mit.edu>
-Date: Thu Jan 16 17:48:54 2014 -0500
-
- Get time offsets for all keyring ccaches
-
- Move the time offset lookup from krb5_krcc_resolve to make_cache, so
- that we fetch time offsets for caches created by
- krb5_krcc_ptcursor_next.
-
- ticket: 7820
- target_version: 1.12.2
- tags: pullup
-
-diff --git a/src/lib/krb5/ccache/cc_keyring.c b/src/lib/krb5/ccache/cc_keyring.c
-index a0c8035..27bad9d 100644
---- a/src/lib/krb5/ccache/cc_keyring.c
-+++ b/src/lib/krb5/ccache/cc_keyring.c
-@@ -1077,11 +1077,13 @@ krb5_krcc_destroy(krb5_context context, krb5_ccache id)
-
- /* Create a cache handle for a cache ID. */
- static krb5_error_code
--make_cache(key_serial_t collection_id, key_serial_t cache_id,
-- const char *anchor_name, const char *collection_name,
-- const char *subsidiary_name, krb5_ccache *cache_out)
-+make_cache(krb5_context context, key_serial_t collection_id,
-+ key_serial_t cache_id, const char *anchor_name,
-+ const char *collection_name, const char *subsidiary_name,
-+ krb5_ccache *cache_out)
- {
- krb5_error_code ret;
-+ krb5_os_context os_ctx = &context->os_context;
- krb5_ccache ccache = NULL;
- krb5_krcc_data *d;
- key_serial_t pkey = 0;
-@@ -1108,6 +1110,18 @@ make_cache(key_serial_t collection_id, key_serial_t cache_id,
- ccache->data = d;
- ccache->magic = KV5M_CCACHE;
- *cache_out = ccache;
-+
-+ /* Lookup time offsets if necessary. */
-+ if ((context->library_options & KRB5_LIBOPT_SYNC_KDCTIME) &&
-+ !(os_ctx->os_flags & KRB5_OS_TOFFSET_VALID)) {
-+ if (krb5_krcc_get_time_offsets(context, ccache,
-+ &os_ctx->time_offset,
-+ &os_ctx->usec_offset) == 0) {
-+ os_ctx->os_flags &= ~KRB5_OS_TOFFSET_TIME;
-+ os_ctx->os_flags |= KRB5_OS_TOFFSET_VALID;
-+ }
-+ }
-+
- return 0;
- }
-
-@@ -1134,7 +1148,6 @@ make_cache(key_serial_t collection_id, key_serial_t cache_id,
- static krb5_error_code KRB5_CALLCONV
- krb5_krcc_resolve(krb5_context context, krb5_ccache *id, const char *residual)
- {
-- krb5_os_context os_ctx = &context->os_context;
- krb5_error_code ret;
- key_serial_t collection_id, cache_id;
- char *anchor_name = NULL, *collection_name = NULL, *subsidiary_name = NULL;
-@@ -1161,22 +1174,11 @@ krb5_krcc_resolve(krb5_context context, krb5_ccache *id, const char *residual)
- if (cache_id < 0)
- cache_id = 0;
-
-- ret = make_cache(collection_id, cache_id, anchor_name, collection_name,
-- subsidiary_name, id);
-+ ret = make_cache(context, collection_id, cache_id, anchor_name,
-+ collection_name, subsidiary_name, id);
- if (ret)
- goto cleanup;
-
-- /* Lookup time offsets if necessary. */
-- if ((context->library_options & KRB5_LIBOPT_SYNC_KDCTIME) &&
-- !(os_ctx->os_flags & KRB5_OS_TOFFSET_VALID)) {
-- if (krb5_krcc_get_time_offsets(context, *id,
-- &os_ctx->time_offset,
-- &os_ctx->usec_offset) == 0) {
-- os_ctx->os_flags &= ~KRB5_OS_TOFFSET_TIME;
-- os_ctx->os_flags |= KRB5_OS_TOFFSET_VALID;
-- }
-- }
--
- cleanup:
- free(anchor_name);
- free(collection_name);
-@@ -1928,8 +1930,9 @@ krb5_krcc_ptcursor_next(krb5_context context, krb5_cc_ptcursor cursor,
- cache_id = keyctl_search(data->collection_id, KRCC_KEY_TYPE_KEYRING,
- first_name, 0);
- if (cache_id != -1) {
-- return make_cache(data->collection_id, cache_id, data->anchor_name,
-- data->collection_name, first_name, cache_out);
-+ return make_cache(context, data->collection_id, cache_id,
-+ data->anchor_name, data->collection_name,
-+ first_name, cache_out);
- }
- }
-
-@@ -1967,7 +1970,7 @@ krb5_krcc_ptcursor_next(krb5_context context, krb5_cc_ptcursor cursor,
-
- /* We found a valid key */
- data->next_key++;
-- ret = make_cache(data->collection_id, key, data->anchor_name,
-+ ret = make_cache(context, data->collection_id, key, data->anchor_name,
- data->collection_name, subsidiary_name, cache_out);
- free(description);
- return ret;
diff --git a/krb5-master-mechd.patch b/krb5-master-mechd.patch
index 8982fdd..965a436 100644
--- a/krb5-master-mechd.patch
+++ b/krb5-master-mechd.patch
@@ -273,41 +273,3 @@ index f0acf1a..8bce14c 100644
}
/*
-
-commit 41d38531043b99e8daa334f2b6ddf376adf1e878
-Author: Sam Hartman <hartmans@debian.org>
-Date: Wed Jun 4 12:06:27 2014 -0400
-
- Do not loop on add_cred_from and other new methods
-
- Several new GSS-API methods were added but GSSAPI_ADD_METHOD was
- called to add them rather than GSSAPI_ADD_METHOD_NOLOOP. This means
- that the implementation from the GSS-API mechglue would be used if the
- mechanism had no implementation. As a result, the mechglue will call
- into itself exhausting the call stack in an endless loop when one of
- these methods is called.
-
- ticket: 7926
- target_version: 1.12.2
- tags: pullup
-
-diff --git a/src/lib/gssapi/mechglue/g_initialize.c b/src/lib/gssapi/mechglue/g_initialize.c
-index 8bce14c..b0eb40a 100644
---- a/src/lib/gssapi/mechglue/g_initialize.c
-+++ b/src/lib/gssapi/mechglue/g_initialize.c
-@@ -703,11 +703,11 @@ build_dynamicMech(void *dl, const gss_OID mech_type)
- GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_inquire_mech_for_saslname);
- /* RFC 5587 */
- GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_inquire_attrs_for_mech);
-- GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_acquire_cred_from);
-- GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_store_cred_into);
-+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_acquire_cred_from);
-+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_store_cred_into);
- GSS_ADD_DYNAMIC_METHOD(dl, mech, gssspi_acquire_cred_with_password);
-- GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_export_cred);
-- GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_import_cred);
-+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_export_cred);
-+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_import_cred);
- GSS_ADD_DYNAMIC_METHOD(dl, mech, gssspi_import_sec_context_by_mech);
- GSS_ADD_DYNAMIC_METHOD(dl, mech, gssspi_import_name_by_mech);
- GSS_ADD_DYNAMIC_METHOD(dl, mech, gssspi_import_cred_by_mech);
diff --git a/krb5-master-move-otp-sockets.patch b/krb5-master-move-otp-sockets.patch
index 4f7bdac..350a818 100644
--- a/krb5-master-move-otp-sockets.patch
+++ b/krb5-master-move-otp-sockets.patch
@@ -1,4 +1,4 @@
-Adjusted to apply after the local doublelog patch.
+Adjusted to apply to 1.12.2.
commit 1e4bdcfed2c7bda94d5c135cc32a5993ca032501
Author: Nathaniel McCallum <npmccallum@redhat.com>
@@ -103,8 +103,9 @@ diff --git a/src/configure.in b/src/configure.in
index 2145d54..c2eaf78 100644
--- a/src/configure.in
+++ b/src/configure.in
-@@ -1,5 +1,11 @@
- K5_AC_INIT([aclocal.m4])
+@@ -9,6 +9,12 @@
+ fi
+ AC_SUBST(SYSCONFCONF)
+# If $runstatedir isn't set by autoconf (<2.70), set it manually.
+if test x"$runstatedir" == x; then
@@ -153,8 +154,8 @@ index e13042a..f83ff4e 100644
-e 's+@LOCALSTATEDIR+$(LOCALSTATEDIR)+' \
+ -e 's+@RUNSTATEDIR+$(RUNSTATEDIR)+' \
-e 's+@SYSCONFDIR+$(SYSCONFDIR)+' \
- -e 's+:/etc/krb5.conf:/etc/krb5.conf"+:/etc/krb5.conf"+' \
- -e 's+"/etc/krb5.conf:/etc/krb5.conf"+"/etc/krb5.conf"+' \
+ -e 's+@DYNOBJEXT+$(DYNOBJEXT)+' \
+ -e 's+@SYSCONFCONF+$(SYSCONFCONF)+'
diff --git a/src/include/osconf.hin b/src/include/osconf.hin
index 90ab86d..871503a 100644
--- a/src/include/osconf.hin
diff --git a/krb5-master-rcache-acquirecred-leak.patch b/krb5-master-rcache-acquirecred-leak.patch
deleted file mode 100644
index 0ae7b34..0000000
--- a/krb5-master-rcache-acquirecred-leak.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-commit 9df0c4bdce6b88a01af51e4bbb9a365db00256d5
-Author: Greg Hudson <ghudson@mit.edu>
-Date: Wed Jan 15 14:41:54 2014 -0500
-
- Clean up rcache if GSS krb5 acquire_cred fails
-
- The error handler in acquire_cred_context didn't release the rcache,
- which would cause it to leak if we failed after acquire_accept_cred.
-
- ticket: 7818 (new)
- target_version: 1.12.2
- tags: pullup
-
-diff --git a/src/lib/gssapi/krb5/acquire_cred.c b/src/lib/gssapi/krb5/acquire_cred.c
-index 37cc6b5..f625c0c 100644
---- a/src/lib/gssapi/krb5/acquire_cred.c
-+++ b/src/lib/gssapi/krb5/acquire_cred.c
-@@ -829,6 +829,8 @@ error_out:
- if (cred->keytab)
- krb5_kt_close(context, cred->keytab);
- #endif /* LEAN_CLIENT */
-+ if (cred->rcache)
-+ krb5_rc_close(context, cred->rcache);
- if (cred->name)
- kg_release_name(context, &cred->name);
- k5_mutex_destroy(&cred->lock);
diff --git a/krb5-master-spnego-preserve-oid.patch b/krb5-master-spnego-preserve-oid.patch
deleted file mode 100644
index 749de5e..0000000
--- a/krb5-master-spnego-preserve-oid.patch
+++ /dev/null
@@ -1,166 +0,0 @@
-commit 8255613476d4c1583a5e810b50444f188fde871f
-Author: Greg Hudson <ghudson@mit.edu>
-Date: Mon Feb 3 21:11:34 2014 -0500
-
- Properly reflect MS krb5 mech in SPNEGO acceptor
-
- r25590 changed negotiate_mech() to return an alias into the acceptor's
- mech set, with the unfortunate side effect of transforming the
- erroneous Microsoft krb5 mech OID into the correct krb5 mech OID,
- meaning that we answer with a different OID than the requested one.
- Return an alias into the initiator's mech set instead, and store that
- in mech_set field the SPNEGO context. The acceptor code only uses
- mech_set to hold the allocated storage pointed into by internal_mech,
- so this change is safe.
-
- ticket: 7858
- target_version: 1.12.2
- tags: pullup
-
-diff --git a/src/lib/gssapi/spnego/spnego_mech.c b/src/lib/gssapi/spnego/spnego_mech.c
-index 7e4bf90..7529c74 100644
---- a/src/lib/gssapi/spnego/spnego_mech.c
-+++ b/src/lib/gssapi/spnego/spnego_mech.c
-@@ -1388,8 +1388,8 @@ acc_ctx_new(OM_uint32 *minor_status,
- *return_token = NO_TOKEN_SEND;
- goto cleanup;
- }
-- sc->mech_set = supported_mechSet;
-- supported_mechSet = GSS_C_NO_OID_SET;
-+ sc->mech_set = mechTypes;
-+ mechTypes = GSS_C_NO_OID_SET;
- sc->internal_mech = mech_wanted;
- sc->DER_mechTypes = der_mechTypes;
- der_mechTypes.length = 0;
-@@ -3538,7 +3538,7 @@ put_negResult(unsigned char **buf_out, OM_uint32 negResult,
- * is set to ACCEPT_INCOMPLETE if it's the first mech, REQUEST_MIC if
- * it's not the first mech, otherwise we return NULL and negResult
- * is set to REJECT. The returned pointer is an alias into
-- * supported->elements and should not be freed.
-+ * received->elements and should not be freed.
- *
- * NOTE: There is currently no way to specify a preference order of
- * mechanisms supported by the acceptor.
-@@ -3560,7 +3560,7 @@ negotiate_mech(gss_OID_set supported, gss_OID_set received,
- if (g_OID_equal(mech_oid, &supported->elements[j])) {
- *negResult = (i == 0) ? ACCEPT_INCOMPLETE :
- REQUEST_MIC;
-- return &supported->elements[j];
-+ return &received->elements[i];
- }
- }
- }
-
-commit 53cfb8327c452bd72a8e915338fb5ec838079cd3
-Author: Greg Hudson <ghudson@mit.edu>
-Date: Mon Feb 3 20:59:54 2014 -0500
-
- Test SPNEGO acceptor response to MS krb5 mech OID
-
- In t_spnego.c, add code to make a SPNEGO request with the erroneous
- Microsoft OID value and examine the response to make sure that it uses
- the same OID value as the request did. The token and tmp variables
- were unused, so rename them to itok and atok for the purpose of the
- new test code.
-
- ticket: 7858
- target_version: 1.12.2
- tags: pullup
-
-diff --git a/src/tests/gssapi/t_spnego.c b/src/tests/gssapi/t_spnego.c
-index cbf720b..ca05848 100644
---- a/src/tests/gssapi/t_spnego.c
-+++ b/src/tests/gssapi/t_spnego.c
-@@ -27,9 +27,15 @@
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-+#include <assert.h>
-
- #include "common.h"
-
-+static gss_OID_desc mech_krb5_wrong = {
-+ 9, "\052\206\110\202\367\022\001\002\002"
-+};
-+gss_OID_set_desc mechset_krb5_wrong = { 1, &mech_krb5_wrong };
-+
- /*
- * Test program for SPNEGO and gss_set_neg_mechs
- *
-@@ -44,11 +50,13 @@ main(int argc, char *argv[])
- {
- OM_uint32 minor, major, flags;
- gss_cred_id_t verifier_cred_handle = GSS_C_NO_CREDENTIAL;
-+ gss_cred_id_t initiator_cred_handle = GSS_C_NO_CREDENTIAL;
- gss_OID_set actual_mechs = GSS_C_NO_OID_SET;
-- gss_buffer_desc token = GSS_C_EMPTY_BUFFER, tmp = GSS_C_EMPTY_BUFFER;
-+ gss_buffer_desc itok = GSS_C_EMPTY_BUFFER, atok = GSS_C_EMPTY_BUFFER;
- gss_ctx_id_t initiator_context, acceptor_context;
- gss_name_t target_name, source_name = GSS_C_NO_NAME;
- gss_OID mech = GSS_C_NO_OID;
-+ const unsigned char *atok_oid;
-
- if (argc < 2 || argc > 3) {
- fprintf(stderr, "Usage: %s target_name [keytab]\n", argv[0]);
-@@ -83,10 +91,58 @@ main(int argc, char *argv[])
- (void)gss_delete_sec_context(&minor, &initiator_context, NULL);
- (void)gss_delete_sec_context(&minor, &acceptor_context, NULL);
- (void)gss_release_name(&minor, &source_name);
-- (void)gss_release_name(&minor, &target_name);
-- (void)gss_release_buffer(&minor, &token);
-- (void)gss_release_buffer(&minor, &tmp);
- (void)gss_release_cred(&minor, &verifier_cred_handle);
- (void)gss_release_oid_set(&minor, &actual_mechs);
-+
-+ /*
-+ * Test that the SPNEGO acceptor code properly reflects back the erroneous
-+ * Microsoft mech OID in the supportedMech field of the NegTokenResp
-+ * message. Our initiator code doesn't care (it treats all variants of the
-+ * krb5 mech as equivalent when comparing the supportedMech response to its
-+ * first-choice mech), so we have to look directly at the DER encoding of
-+ * the response token. If we don't request mutual authentication, the
-+ * SPNEGO reply will contain no underlying mech token, so the encoding of
-+ * the correct NegotiationToken response is completely predictable:
-+ *
-+ * A1 14 (choice 1, length 20, meaning negTokenResp)
-+ * 30 12 (sequence, length 18)
-+ * A0 03 (context tag 0, length 3)
-+ * 0A 01 00 (enumerated value 0, meaning accept-completed)
-+ * A1 0B (context tag 1, length 11)
-+ * 06 09 (object identifier, length 9)
-+ * 2A 86 48 82 F7 12 01 02 02 (the erroneous krb5 OID)
-+ *
-+ * So we can just compare the length to 22 and the nine bytes at offset 13
-+ * to the expected OID.
-+ */
-+ major = gss_acquire_cred(&minor, GSS_C_NO_NAME, GSS_C_INDEFINITE,
-+ &mechset_spnego, GSS_C_INITIATE,
-+ &initiator_cred_handle, NULL, NULL);
-+ check_gsserr("gss_acquire_cred(2)", major, minor);
-+ major = gss_set_neg_mechs(&minor, initiator_cred_handle,
-+ &mechset_krb5_wrong);
-+ check_gsserr("gss_set_neg_mechs(2)", major, minor);
-+ major = gss_init_sec_context(&minor, initiator_cred_handle,
-+ &initiator_context, target_name, &mech_spnego,
-+ flags, GSS_C_INDEFINITE,
-+ GSS_C_NO_CHANNEL_BINDINGS, &atok, NULL, &itok,
-+ NULL, NULL);
-+ check_gsserr("gss_init_sec_context", major, minor);
-+ assert(major == GSS_S_CONTINUE_NEEDED);
-+ major = gss_accept_sec_context(&minor, &acceptor_context,
-+ GSS_C_NO_CREDENTIAL, &itok,
-+ GSS_C_NO_CHANNEL_BINDINGS, NULL,
-+ NULL, &atok, NULL, NULL, NULL);
-+ assert(atok.length == 22);
-+ atok_oid = (unsigned char *)atok.value + 13;
-+ assert(memcmp(atok_oid, mech_krb5_wrong.elements, 9) == 0);
-+ check_gsserr("gss_accept_sec_context", major, minor);
-+
-+ (void)gss_delete_sec_context(&minor, &initiator_context, NULL);
-+ (void)gss_delete_sec_context(&minor, &acceptor_context, NULL);
-+ (void)gss_release_cred(&minor, &initiator_cred_handle);
-+ (void)gss_release_name(&minor, &target_name);
-+ (void)gss_release_buffer(&minor, &itok);
-+ (void)gss_release_buffer(&minor, &atok);
- return 0;
- }
diff --git a/krb5-master-strdupcheck.patch b/krb5-master-strdupcheck.patch
new file mode 100644
index 0000000..4c9d0c1
--- /dev/null
+++ b/krb5-master-strdupcheck.patch
@@ -0,0 +1,23 @@
+commit b6810da129512b6d0200580d78d22d38cc214e21
+Author: Lukas Slebodnik <lslebodn@redhat.com>
+Date: Sat Jun 21 17:09:31 2014 +0200
+
+ Fix error check in krb5_ldap_parse_principal_name
+
+ Test the correct variable for NULL to detect a strdup failure.
+
+ [ghudson@mit.edu: clarified commit message]
+
+diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c
+index 21695a9..44bf339 100644
+--- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c
++++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c
+@@ -412,7 +412,7 @@ krb5_ldap_parse_principal_name(char *i_princ_name, char **o_princ_name)
+ at_rlm_name = strrchr(i_princ_name, '@');
+ if (!at_rlm_name) {
+ *o_princ_name = strdup(i_princ_name);
+- if (!o_princ_name)
++ if (!*o_princ_name)
+ return ENOMEM;
+ } else {
+ k5_buf_init_dynamic(&buf);
diff --git a/krb5.spec b/krb5.spec
index 88048f2..f09ef2c 100644
--- a/krb5.spec
+++ b/krb5.spec
@@ -40,10 +40,10 @@
Summary: The Kerberos network authentication system
Name: krb5
-Version: 1.12.1
-Release: 15%{?dist}
+Version: 1.12.2
+Release: 3%{?dist}
# Maybe we should explode from the now-available-to-everybody tarball instead?
-# http://web.mit.edu/kerberos/dist/krb5/1.12/krb5-1.12.1-signed.tar
+# http://web.mit.edu/kerberos/dist/krb5/1.12/krb5-1.12.2-signed.tar
Source0: krb5-%{version}.tar.gz
Source1: krb5-%{version}.tar.gz.asc
# Use a dummy krb5-%{version}-pdf.tar.xz the first time through, then
@@ -84,7 +84,6 @@ Patch23: krb5-1.3.1-dns.patch
Patch29: krb5-1.10-kprop-mktemp.patch
Patch30: krb5-1.3.4-send-pr-tempfile.patch
Patch39: krb5-1.12-api.patch
-Patch56: krb5-1.10-doublelog.patch
Patch59: krb5-1.10-kpasswd_tcp.patch
Patch60: krb5-1.12.1-pam.patch
Patch63: krb5-1.12-selinux-label.patch
@@ -93,29 +92,20 @@ Patch86: krb5-1.9-debuginfo.patch
Patch105: krb5-kvno-230379.patch
Patch129: krb5-1.11-run_user_0.patch
Patch134: krb5-1.11-kpasswdtest.patch
-Patch135: krb5-master-keyring-kdcsync.patch
Patch136: krb5-master-rcache-internal-const.patch
Patch137: krb5-master-rcache-acquirecred-cleanup.patch
-Patch138: krb5-master-rcache-acquirecred-leak.patch
Patch139: krb5-master-rcache-acquirecred-source.patch
-Patch140: krb5-master-empty-credstore.patch
Patch141: krb5-master-rcache-acquirecred-test.patch
Patch142: krb5-master-move-otp-sockets.patch
-Patch143: krb5-master-spnego-preserve-oid.patch
-Patch144: krb5-1.12-tcl86.patch
Patch145: krb5-master-mechd.patch
-Patch146: krb5-1.12-CVE-2014-4341_4342.patch
-Patch147: krb5-1.12-CVE-2014-4341_4342-tests.patch
-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
+Patch146: krb5-master-strdupcheck.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 +308,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
@@ -338,7 +329,6 @@ ln -s NOTICE LICENSE
%patch29 -p1 -b .kprop-mktemp
%patch30 -p1 -b .send-pr-tempfile
%patch39 -p1 -b .api
-%patch56 -p1 -b .doublelog
%patch59 -p1 -b .kpasswd_tcp
%patch71 -p1 -b .dirsrv-accountlock %{?_rawbuild}
%patch86 -p0 -b .debuginfo
@@ -350,23 +340,13 @@ ln -s NOTICE LICENSE
%patch134 -p1 -b .kpasswdtest
-%patch135 -p1 -b .keyring-kdcsync
-
%patch136 -p1 -b .rcache-internal-const
%patch137 -p1 -b .rcache-acquirecred-cleanup
-%patch138 -p1 -b .rcache-acquirecred-leak
%patch139 -p1 -b .rcache-acquirecred-source
-%patch140 -p1 -b .empty-credstore
%patch141 -p1 -b .rcache-acquirecred-test
%patch142 -p1 -b .move-otp-sockets
-%patch143 -p1 -b .spnego-preserve-oid
-%patch144 -p1 -b .tcl86
%patch145 -p1 -b .master-mechd
-%patch146 -p1 -b .CVE-2014-4341_4342
-%patch147 -p1 -b .CVE-2014-4341_4342
-%patch148 -p1 -b .gssapi-mech-doublefree
-%patch149 -p1 -b .gssapi-spnego-deref
-%patch150 -p1 -b .2014-001
+%patch146 -p1 -b .master-strdupcheck
# Take the execute bit off of documentation.
chmod -x doc/krb5-protocol/*.txt doc/ccapi/*.html
@@ -1043,9 +1023,32 @@ exit 0
%{_sbindir}/uuserver
%changelog
+* Wed Aug 20 2014 Nalin Dahyabhai <nalin@redhat.com> - 1.12.2-3
+- pull in upstream fix for an incorrect check on the value returned by a
+ strdup() call (#1132062)
+
* Sun Aug 17 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.12.1-15
- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild
+* Sun Aug 17 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.12.2-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild
+
+* Fri Aug 15 2014 Nalin Dahyabhai <nalin@redhat.com> - 1.12.2-1
+- update to 1.12.2
+ - drop patch for RT#7820, fixed in 1.12.2
+ - drop patch for #231147, fixed as RT#3277 in 1.12.2
+ - drop patch for RT#7818, fixed in 1.12.2
+ - drop patch for RT#7836, fixed in 1.12.2
+ - drop patch for RT#7858, fixed in 1.12.2
+ - drop patch for RT#7924, fixed in 1.12.2
+ - drop patch for RT#7926, fixed in 1.12.2
+ - drop patches for CVE-2014-4341/CVE-2014-4342, included in 1.12.2
+ - drop patch for CVE-2014-4343, included in 1.12.2
+ - drop patch for CVE-2014-4344, included in 1.12.2
+ - drop patch for CVE-2014-4345, included in 1.12.2
+- 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@redhat.com> - 1.12.1-14
- incorporate fix for MITKRB5-SA-2014-001 (CVE-2014-4345)
diff --git a/sources b/sources
index 63500fa..e06d894 100644
--- a/sources
+++ b/sources
@@ -1,5 +1,5 @@
-4a631b3474d3e44773f1ecda96f04400 krb5-1.12.1.tar.gz
-6a1389393f5f5473933104207216e160 krb5-1.12.1.tar.gz.asc
-5852bb09254bcb743ccff4d5b7560f13 krb5-1.12.1-pdf.tar.xz
+8777a835ae84f7d2f5872bf388bc6d76 krb5-1.12.2.tar.gz
+5a45834367bda0a037d1b8f5a8912002 krb5-1.12.2.tar.gz.asc
+c4dca109bc4d480ae4b05d1430671c77 krb5-1.12.2-pdf.tar.xz
142c7f3f8d2b08936d2cee3de743133e nss_wrapper-0.0-20140204195100.git3d58327.tar.xz
d8e42cf537192765463c3f1bad870250 socket_wrapper-0.0-20140204194748.gitf3b2ece.tar.xz