From 9ee7dd24d99162f28a0573e2d97861e063623885 Mon Sep 17 00:00:00 2001 From: Love Hornquist Astrand Date: Mon, 22 Nov 2010 13:19:27 -0800 Subject: [PATCH] support kswitch -i, interactive mode --- doc/setup.texi | 47 ++++++++++++++++++++++++++++++++ kuser/Makefile.am | 2 ++ kuser/kswitch.c | 67 +++++++++++++++++++++++++++++++++++++++++++++- kuser/kuser_locl.h | 2 ++ 4 files changed, 117 insertions(+), 1 deletion(-) diff --git a/doc/setup.texi b/doc/setup.texi index be9670176..6be7dac82 100644 --- a/doc/setup.texi +++ b/doc/setup.texi @@ -713,6 +713,53 @@ Configure the system startup script to start the kcm process, default_cc_type = KCM @end example +Now when you run @command{kinit} it doesn't overwrite your existing +credentials but rather just add them to the set of +credentials. @command{klist -l} lists the credentials and the star +marks the default credential. + +@example +$ kinit lha@@KTH.SE +lha@@KTH.SE's Password: +$ klist -l + Name Cache name Expires +lha@@KTH.SE 0 Nov 22 23:09:40 * +lha@@SU.SE Initial default ccache Nov 22 14:14:24 +@end example + +When switching between credentials you can use @command{kswitch}. + +@example +$ kswitch -i + Principal +1 lha@@KTH.SE +2 lha@@SU.SE +Select number: 2 +@end example + +After switching, a new set of credentials are used as default. + +@example +$ klist -l + Name Cache name Expires +lha@@SU.SE Initial default ccache Nov 22 14:14:24 * +lha@@KTH.SE 0 Nov 22 23:09:40 +@end example + +Som applications, like openssh with Simon Wilkinsons patch applied, +support specifiying that credential to use. The example below will +login to the host computer.kth.se using lha@@KTH.SE (not the current +default credential). + +@example +$ ssh \ + -o GSSAPIAuthentication=yes \ + -o GSSAPIKeyExchange=yes \ + -o GSSAPIClientIdentity=lha@@KTH.SE \ + computer.kth.se +@end example + + @node Cross realm, Transit policy, Credential cache server - KCM, Setting up a realm @section Cross realm diff --git a/kuser/Makefile.am b/kuser/Makefile.am index 11a3149b6..70cd5c24a 100644 --- a/kuser/Makefile.am +++ b/kuser/Makefile.am @@ -35,6 +35,8 @@ klist_LDADD = $(kinit_LDADD) kimpersonate_LDADD = $(kinit_LDADD) +kswitch_LDADD = $(kinit_LDADD) $(LIB_readline) + dist_kdigest_SOURCES = kdigest.c nodist_kdigest_SOURCES = kdigest-commands.c diff --git a/kuser/kswitch.c b/kuser/kswitch.c index d28223725..c53676d41 100644 --- a/kuser/kswitch.c +++ b/kuser/kswitch.c @@ -33,6 +33,10 @@ #include "kuser_locl.h" +#ifdef HAVE_READLINE +char *readline(char *prompt); +#endif + /* * */ @@ -42,6 +46,7 @@ static int help_flag = 0; static char *cache; static char *principal; static char *type; +static int interactive_flag; static struct getargs args[] = { { "type", 't', arg_string, &type, @@ -50,6 +55,8 @@ static struct getargs args[] = { NP_("name of credential cache", ""), "cache" }, { "principal", 'p', arg_string, &principal, NP_("name of principal", ""), "principal" }, + { "interactive", 'i', arg_flag, &interactive_flag, + NP_("interactive selection", ""), NULL }, { "version", 0, arg_flag, &version_flag, NP_("print version", ""), NULL }, { "help", 0, arg_flag, &help_flag, NULL, NULL} @@ -106,7 +113,65 @@ main (int argc, char **argv) krb5_errx(context, 1, N_("Both --cache and --principal given, choose one", "")); - if (principal) { + if (interactive_flag) { + krb5_cc_cache_cursor cursor; + krb5_ccache *ids; + size_t i, len = 0; + char *name; + rtbl_t ct; + + ct = rtbl_create(); + + rtbl_add_column (ct, "", 0); + rtbl_add_column (ct, "Principal", 0); + rtbl_set_column_prefix(ct, "Principal", " "); + + ret = krb5_cc_cache_get_first (context, NULL, &cursor); + if (ret) + krb5_err (context, 1, ret, "krb5_cc_cache_get_first"); + + while (krb5_cc_cache_next (context, cursor, &id) == 0) { + krb5_principal p; + char num[10]; + + ret = krb5_cc_get_principal(context, id, &p); + if (ret) + continue; + + ret = krb5_unparse_name(context, p, &name); + krb5_free_principal(context, p); + + snprintf(num, sizeof(num), "%d", (int)(len + 1)); + rtbl_add_column_entry(ct, "", num); + rtbl_add_column_entry(ct, "Principal", name); + free(name); + + ids = erealloc(ids, (len + 1) * sizeof(ids[0])); + ids[len] = id; + len++; + } + krb5_cc_cache_end_seq_get(context, cursor); + + rtbl_format(ct, stdout); + rtbl_destroy(ct); + + name = readline("Select number: "); + if (name) { + i = atoi(name); + if (i == 0) + krb5_errx(context, 1, "Cache number '%s' is invalid", name); + if (i > len) + krb5_errx(context, 1, "Cache number '%s' is too large", name); + + id = ids[i - 1]; + ids[i - 1] = NULL; + } else + krb5_errx(context, 1, "No cache selected"); + for (i = 0; i < len; i++) + if (ids[i]) + krb5_cc_close(context, ids[i]); + + } else if (principal) { krb5_principal p; ret = krb5_parse_name(context, principal, &p); diff --git a/kuser/kuser_locl.h b/kuser/kuser_locl.h index 1bf682b1d..ead88e606 100644 --- a/kuser/kuser_locl.h +++ b/kuser/kuser_locl.h @@ -84,6 +84,8 @@ #endif #include "crypto-headers.h" /* for UI_UTIL_read_pw_string */ +#include + #ifdef HAVE_LOCALE_H #include #endif