From 414f99e0e8b86c8e3679a1cabcd8e17888bccea0 Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Fri, 31 Jan 2014 16:25:49 -0500 Subject: Drop call-access()-more patch for ksu - drop patch to add additional access() checks to ksu - they add to breakage when non-FILE: caches are in use (#1026099), shouldn't be resulting in any benefit, and clash with proposed changes to fix its cache handling --- 0000-ksu-intermediates.patch | 13 + ...-try-to-stat-not-on-disk-ccache-residuals.patch | 316 ++++++++++++++++++++ ...n-memory-cache-until-we-need-the-target-s.patch | 321 +++++++++++++++++++++ ...-to-destroy-the-ccache-we-re-copying-from.patch | 95 ++++++ ...e-the-default_ccache_name-d-as-the-target.patch | 149 ++++++++++ ...more-careful-of-target-ccache-collections.patch | 179 ++++++++++++ ...-Copy-config-entries-to-the-target-ccache.patch | 28 ++ krb5-1.10-ksu-access.patch | 47 --- krb5-1.11-pam.patch | 19 +- krb5.spec | 30 +- 10 files changed, 1138 insertions(+), 59 deletions(-) create mode 100644 0000-ksu-intermediates.patch create mode 100644 0001-Don-t-try-to-stat-not-on-disk-ccache-residuals.patch create mode 100644 0002-Use-an-in-memory-cache-until-we-need-the-target-s.patch create mode 100644 0003-Learn-to-destroy-the-ccache-we-re-copying-from.patch create mode 100644 0004-Try-to-use-the-default_ccache_name-d-as-the-target.patch create mode 100644 0005-Be-more-careful-of-target-ccache-collections.patch create mode 100644 0006-Copy-config-entries-to-the-target-ccache.patch delete mode 100644 krb5-1.10-ksu-access.patch diff --git a/0000-ksu-intermediates.patch b/0000-ksu-intermediates.patch new file mode 100644 index 0000000..d567116 --- /dev/null +++ b/0000-ksu-intermediates.patch @@ -0,0 +1,13 @@ +Collect changes that prevent the ksu collections changes from being directly +pullable from master (or, as of this writing, the proposed changes for master). +--- krb5/src/clients/ksu/main.c ++++ krb5/src/clients/ksu/main.c +@@ -706,7 +706,7 @@ main (argc, argv) + } + + if(set_env_var( "HOME", target_pwd->pw_dir)){ +- fprintf(stderr, _("ksu: couldn't set environment variable USER\n")); ++ fprintf(stderr, _("ksu: couldn't set environment variable HOME\n")); + sweep_up(ksu_context, cc_target); + exit(1); + } 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 new file mode 100644 index 0000000..ac6ce53 --- /dev/null +++ b/0001-Don-t-try-to-stat-not-on-disk-ccache-residuals.patch @@ -0,0 +1,316 @@ +From 9f902f70a79ab864083078d104196a83943844ac Mon Sep 17 00:00:00 2001 +From: Nalin Dahyabhai +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/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 new file mode 100644 index 0000000..ef62793 --- /dev/null +++ b/0002-Use-an-in-memory-cache-until-we-need-the-target-s.patch @@ -0,0 +1,321 @@ +From 5195c2b20593330192feff67dd5f271e88f562e7 Mon Sep 17 00:00:00 2001 +From: Nalin Dahyabhai +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 new file mode 100644 index 0000000..ae96369 --- /dev/null +++ b/0003-Learn-to-destroy-the-ccache-we-re-copying-from.patch @@ -0,0 +1,95 @@ +From 85ac175a62fcd629592c049f2318fff79949884b Mon Sep 17 00:00:00 2001 +From: Nalin Dahyabhai +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 + #include + #include +@@ -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/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 new file mode 100644 index 0000000..bd78d12 --- /dev/null +++ b/0004-Try-to-use-the-default_ccache_name-d-as-the-target.patch @@ -0,0 +1,149 @@ +From acbb59cd4b1759afe492b8503cddb0a2f719e6c8 Mon Sep 17 00:00:00 2001 +From: Nalin Dahyabhai +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 new file mode 100644 index 0000000..5f9de36 --- /dev/null +++ b/0005-Be-more-careful-of-target-ccache-collections.patch @@ -0,0 +1,179 @@ +From 5286fddf967af8952bd9d42d6d1ec1ddfcc159ad Mon Sep 17 00:00:00 2001 +From: Nalin Dahyabhai +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/0006-Copy-config-entries-to-the-target-ccache.patch new file mode 100644 index 0000000..e7d033c --- /dev/null +++ b/0006-Copy-config-entries-to-the-target-ccache.patch @@ -0,0 +1,28 @@ +From 0d2a65745287238c5e5e2cc2fc68c40b358e68e4 Mon Sep 17 00:00:00 2001 +From: Nalin Dahyabhai +Date: Tue, 29 Oct 2013 16:27:20 -0400 +Subject: [PATCH 6/6] Copy config entries to the 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. +--- + 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 +--- 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) + + while (!(retval = krb5_cc_next_cred(context, cc, &cur, &creds))){ + +- if ((retval = krb5_check_exp(context, creds.times))){ ++ if (!krb5_is_config_principal(context, creds.server) && ++ (retval = krb5_check_exp(context, creds.times))){ + if (retval != KRB5KRB_AP_ERR_TKT_EXPIRED){ + return retval; + } +-- +1.8.5.3 + diff --git a/krb5-1.10-ksu-access.patch b/krb5-1.10-ksu-access.patch deleted file mode 100644 index ca155f7..0000000 --- a/krb5-1.10-ksu-access.patch +++ /dev/null @@ -1,47 +0,0 @@ -The idea is to not complain about problems in the default ticket file if we -couldn't read it, because the client would be able to tell if it's there or -not, and we're implicitly letting the client tell us where it is. Still needs -work, I think. - ---- krb5/src/clients/ksu/ccache.c -+++ krb5/src/clients/ksu/ccache.c -@@ -78,7 +78,7 @@ krb5_error_code krb5_ccache_copy (contex - 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 ( ! access(cc_def_name, R_OK) && ! stat(cc_def_name, &st_temp)){ - if((retval = krb5_get_nonexp_tkts(context,cc_def,&cc_def_creds_arr))){ - return retval; - } ---- krb5/src/clients/ksu/heuristic.c -+++ krb5/src/clients/ksu/heuristic.c -@@ -409,7 +409,7 @@ krb5_error_code find_either_ticket (cont - - cc_source_name = krb5_cc_get_name(context, cc); - -- if ( ! stat(cc_source_name, &st_temp)){ -+ if ( ! access(cc_source_name, F_OK | R_OK) && ! stat(cc_source_name, &st_temp)){ - - retval = find_ticket(context, cc, client, end_server, &temp_found); - if (retval) -@@ -569,7 +569,7 @@ krb5_error_code get_best_princ_for_targe - cc_source_name = krb5_cc_get_name(context, cc_source); - - -- if (! stat(cc_source_name, &st_temp)) { -+ if (! access(cc_source_name, F_OK | R_OK) && ! stat(cc_source_name, &st_temp)) { - retval = krb5_cc_get_principal(context, cc_source, &cc_def_princ); - if (retval) - return retval; ---- krb5/src/clients/ksu/main.c -+++ krb5/src/clients/ksu/main.c -@@ -270,7 +270,7 @@ 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( access( cc_source_tag_tmp, F_OK | R_OK) || stat( cc_source_tag_tmp, &st_temp)){ - com_err(prog_name, errno, - _("while looking for credentials file %s"), - cc_source_tag_tmp); diff --git a/krb5-1.11-pam.patch b/krb5-1.11-pam.patch index 55c3ddf..9e1d516 100644 --- a/krb5-1.11-pam.patch +++ b/krb5-1.11-pam.patch @@ -9,7 +9,8 @@ section of /etc/krb5.conf. When enabled, ksu gains a dependency on libpam. Originally RT#5939, though it's changed since then to perform the account -and session management before dropping privileges. +and session management before dropping privileges, and to apply on top of +changes we're proposing for how it handles cache collections. diff -up krb5-1.8/src/aclocal.m4.pam krb5-1.8/src/aclocal.m4 --- krb5-1.8/src/aclocal.m4.pam 2009-11-22 12:00:45.000000000 -0500 @@ -95,7 +96,7 @@ diff -up krb5-1.8/src/clients/ksu/main.c.pam krb5-1.8/src/clients/ksu/main.c +#include "autoconf.h" #include "ksu.h" #include "adm_proto.h" - #include + #include "../../lib/krb5/os/os-proto.h" @@ -33,6 +34,10 @@ #include #include @@ -125,13 +126,13 @@ diff -up krb5-1.8/src/clients/ksu/main.c.pam krb5-1.8/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_target); ++ 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_target); ++ sweep_up(ksu_context, cc_tmp); + exit(1); + } + force_fork++; @@ -142,7 +143,7 @@ diff -up krb5-1.8/src/clients/ksu/main.c.pam krb5-1.8/src/clients/ksu/main.c if (krb5_seteuid(target_uid)) { com_err(prog_name, errno, _("while switching to target for " @@ -651,6 +676,26 @@ - sweep_up(ksu_context, cc_target); + sweep_up(ksu_context, cc_tmp); exit(1); } +#ifdef USE_PAM @@ -153,13 +154,13 @@ diff -up krb5-1.8/src/clients/ksu/main.c.pam krb5-1.8/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_target); ++ 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_target); ++ sweep_up(ksu_context, cc_tmp); + exit(1); + } + force_fork++; @@ -176,7 +177,7 @@ diff -up krb5-1.8/src/clients/ksu/main.c.pam krb5-1.8/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_target); ++ sweep_up(ksu_context, cc_tmp); + exit(1); + } +#ifdef DEBUG @@ -187,7 +188,7 @@ diff -up krb5-1.8/src/clients/ksu/main.c.pam krb5-1.8/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_target); ++ sweep_up(ksu_context, cc_tmp); + exit(1); + } +#ifdef DEBUG diff --git a/krb5.spec b/krb5.spec index 96a9688..daa9b0e 100644 --- a/krb5.spec +++ b/krb5.spec @@ -32,7 +32,7 @@ Summary: The Kerberos network authentication system Name: krb5 Version: 1.11.3 -Release: 19%{?dist} +Release: 20%{?dist} # Maybe we should explode from the now-available-to-everybody tarball instead? # http://web.mit.edu/kerberos/dist/krb5/1.11/krb5-1.11.3-signed.tar Source0: krb5-%{version}.tar.gz @@ -65,7 +65,6 @@ BuildRequires: cmake Source100: nss_wrapper-0.0-20130719153839Z.git6cb59864.bz2 Source101: noport.c -Patch5: krb5-1.10-ksu-access.patch Patch6: krb5-1.10-ksu-path.patch Patch12: krb5-1.7-ktany.patch Patch16: krb5-1.10-buildconf.patch @@ -124,6 +123,15 @@ Patch201: krb5-1.11.2-keycheck.patch Patch202: krb5-1.11.2-otp.patch Patch203: krb5-1.11.3-otp2.patch +# Patches to teach ksu about cache collections +Patch300: 0000-ksu-intermediates.patch +Patch301: 0001-Don-t-try-to-stat-not-on-disk-ccache-residuals.patch +Patch302: 0002-Use-an-in-memory-cache-until-we-need-the-target-s.patch +Patch303: 0003-Learn-to-destroy-the-ccache-we-re-copying-from.patch +Patch304: 0004-Try-to-use-the-default_ccache_name-d-as-the-target.patch +Patch305: 0005-Be-more-careful-of-target-ccache-collections.patch +Patch306: 0006-Copy-config-entries-to-the-target-ccache.patch + License: MIT URL: http://web.mit.edu/kerberos/www/ Group: System Environment/Libraries @@ -318,11 +326,18 @@ certificate. %setup -q -n %{name}-%{version} -a 3 -a 100 ln -s NOTICE LICENSE +%patch300 -p1 -b .ksu-intermediates +%patch301 -p1 -b .Don-t-try-to-stat-not-on-disk-ccache-residuals +%patch302 -p1 -b .Use-an-in-memory-cache-until-we-need-the-target-s +%patch303 -p1 -b .Learn-to-destroy-the-ccache-we-re-copying-from +%patch304 -p1 -b .Try-to-use-the-default_ccache_name-d-as-the-target +%patch305 -p1 -b .Be-more-careful-of-target-ccache-collections +%patch306 -p1 -b .Copy-config-entries-to-the-target-ccache + %patch60 -p1 -b .pam %patch63 -p1 -b .selinux-label -%patch5 -p1 -b .ksu-access %patch6 -p1 -b .ksu-path %patch12 -p1 -b .ktany %patch16 -p1 -b .buildconf %{?_rawbuild} @@ -967,6 +982,15 @@ exit 0 %{_sbindir}/uuserver %changelog +* Fri Jan 31 2014 Nalin Dahyabhai - 1.11.3-20 +- add currently-proposed changes to teach ksu about credential cache + collections and the default_ccache_name setting (#1015559,#1026099) + +* Fri Jan 31 2014 Nalin Dahyabhai +- drop patch to add additional access() checks to ksu - they add to breakage + when non-FILE: caches are in use (#1026099), shouldn't be resulting in any + benefit, and clash with proposed changes to fix its cache handling + * Tue Jan 21 2014 Nalin Dahyabhai - 1.11.3-19 - pull in and backport multiple changes to allow replay caches to be added to a GSS credential store as "rcache"-type credentials (RT#7818/#7819/#7836, -- cgit