diff --git a/kuser/kimpersonate.8 b/kuser/kimpersonate.8 index 48709cfded..c0e982cff0 100644 --- a/kuser/kimpersonate.8 +++ b/kuser/kimpersonate.8 @@ -44,6 +44,8 @@ .Op Fl c Ar string \*(Ba Fl Fl client= Ns Ar string .Op Fl k Ar string \*(Ba Fl Fl keytab= Ns Ar string .Op Fl 5 | Fl Fl krb5 +.Op Fl A | Fl Fl add +.Op Fl R | Fl Fl referral .Op Fl e Ar integer \*(Ba Fl Fl expire-time= Ns Ar integer .Op Fl a Ar string \*(Ba Fl Fl client-address= Ns Ar string .Op Fl t Ar string \*(Ba Fl Fl enc-type= Ns Ar string @@ -55,9 +57,9 @@ .Sh DESCRIPTION The .Nm -program creates a "fake" ticket using the service-key of the service. -The service key can be read from a Kerberos 5 keytab or AFS KeyFile. -Supported options: +program creates a "fake" ticket using the service-key of the service and +stores it in the given (or default) ccache. The service key can be read +from a Kerberos 5 keytab or AFS KeyFile. Supported options: .Bl -tag -width Ds .It Fl Fl ccache= Ns Ar string ccache into which to store the ticket @@ -69,6 +71,12 @@ name of client principal name of keytab file .It Fl 5 Ns , Fl Fl krb5 create a Kerberos 5 ticket +.It Fl A Ns , Fl Fl add +don't re-initialize the ccache, instead add the ticket to an existing +ccache. +.It Fl R Ns , Fl Fl referral +simulate a referrals-based KDC client by storing two entries, one with +the empty realm for the service principal name. .It Fl e Ar integer Ns , Fl Fl expire-time= Ns Ar integer lifetime of ticket in seconds .It Fl a Ar string Ns , Fl Fl client-address= Ns Ar string diff --git a/kuser/kimpersonate.c b/kuser/kimpersonate.c index a54635499f..d2a485b3f9 100644 --- a/kuser/kimpersonate.c +++ b/kuser/kimpersonate.c @@ -51,6 +51,8 @@ static struct getarg_strings client_addresses; static int version_flag = 0; static int help_flag = 0; static int use_krb5 = 1; +static int add_to_ccache = 0; +static int use_referral_realm = 0; static const char *enc_type = "aes256-cts-hmac-sha1-96"; static const char *session_enc_type = NULL; @@ -159,7 +161,7 @@ create_krb5_tickets(krb5_context context, krb5_keytab kt) krb5_err (context, 1, ret, "krb5_string_to_enctype (session-enc-type)"); ret = krb5_kt_get_entry(context, kt, server_principal, 0, etype, &entry); if (ret) - krb5_err(context, 1, ret, "krb5_kt_get_entry"); + krb5_err(context, 1, ret, "krb5_kt_get_entry (perhaps use different --enc-type)"); /* * setup cred @@ -207,10 +209,46 @@ create_krb5_tickets(krb5_context context, krb5_keytab kt) krb5_err(context, 1, ret, "krb5_cc_default"); } - ret = krb5_cc_initialize(context, ccache, cred.client); - if (ret) - krb5_err(context, 1, ret, "krb5_cc_initialize"); + if (add_to_ccache) { + krb5_principal def_princ; + + /* + * Force fcache to read the ccache header, otherwise the store + * will fail. + */ + ret = krb5_cc_get_principal(context, ccache, &def_princ); + if (ret) { + krb5_warn(context, ret, + "Given ccache appears not to exist; initializing it"); + ret = krb5_cc_initialize(context, ccache, cred.client); + if (ret) + krb5_err(context, 1, ret, "krb5_cc_initialize"); + } + krb5_free_principal(context, def_princ); + } else { + ret = krb5_cc_initialize(context, ccache, cred.client); + if (ret) + krb5_err(context, 1, ret, "krb5_cc_initialize"); + } + if (use_referral_realm && + strcmp(krb5_principal_get_realm(context, cred.server), "") != 0) { + krb5_free_principal(context, cred.server); + ret = krb5_copy_principal(context, server_principal, &cred.server); + if (ret) + krb5_err(context, 1, ret, "krb5_copy_principal"); + ret = krb5_principal_set_realm(context, cred.server, ""); + if (ret) + krb5_err(context, 1, ret, "krb5_principal_set_realm"); + ret = krb5_cc_store_cred(context, ccache, &cred); + if (ret) + krb5_err(context, 1, ret, "krb5_cc_store_cred"); + + krb5_free_principal(context, cred.server); + ret = krb5_copy_principal(context, server_principal, &cred.server); + if (ret) + krb5_err(context, 1, ret, "krb5_copy_principal"); + } ret = krb5_cc_store_cred(context, ccache, &cred); if (ret) krb5_err(context, 1, ret, "krb5_cc_store_cred"); @@ -285,6 +323,10 @@ struct getargs args[] = { "name of keytab file", NULL }, { "krb5", '5', arg_flag, &use_krb5, "create a kerberos 5 ticket", NULL }, + { "add", 'A', arg_flag, &add_to_ccache, + "add to ccache without re-initializing it", NULL }, + { "referral", 'R', arg_flag, &use_referral_realm, + "store an additional entry for the service with the empty realm", NULL }, { "expire-time", 'e', arg_integer, &expiration_time, "lifetime of ticket in seconds", NULL }, { "client-addresses", 'a', arg_strings, &client_addresses,