Add those proposed patches

... as referenced by 9b18d26ce3
This commit is contained in:
Nalin Dahyabhai 2014-02-05 14:53:25 -05:00
parent 419c14d6ac
commit 99444865b1
6 changed files with 1088 additions and 0 deletions

View File

@ -0,0 +1,316 @@
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

View File

@ -0,0 +1,321 @@
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

View File

@ -0,0 +1,95 @@
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

View File

@ -0,0 +1,149 @@
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

View File

@ -0,0 +1,179 @@
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

View File

@ -0,0 +1,28 @@
From 0d2a65745287238c5e5e2cc2fc68c40b358e68e4 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
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