kuser: allow kinit to renew anonymous PKINIT tickets
Anonymous PKINIT tickets discard the realm information used to locate the issuing AS. Store the issuing realm in the credentials cache in order to locate a KDC which can renew them.
This commit is contained in:
@@ -206,6 +206,9 @@ static struct getargs args[] = {
|
||||
{ "help", 0, arg_flag, &help_flag, NULL, NULL }
|
||||
};
|
||||
|
||||
static char *
|
||||
get_default_realm(krb5_context context);
|
||||
|
||||
static void
|
||||
usage(int ret)
|
||||
{
|
||||
@@ -236,7 +239,7 @@ copy_configs(krb5_context context,
|
||||
krb5_principal start_ticket_server)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
const char *cfg_names[] = {"realm-config", "FriendlyName", NULL};
|
||||
const char *cfg_names[] = {"realm-config", "FriendlyName", "anon-pkinit-realm", NULL};
|
||||
const char *cfg_names_w_pname[] = {"fast_avail", NULL};
|
||||
krb5_data cfg_data;
|
||||
size_t i;
|
||||
@@ -276,6 +279,30 @@ copy_configs(krb5_context context,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static krb5_error_code
|
||||
get_anon_pkinit_tgs_name(krb5_context context,
|
||||
krb5_ccache ccache,
|
||||
krb5_principal *tgs_name)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
krb5_data data;
|
||||
char *realm;
|
||||
|
||||
ret = krb5_cc_get_config(context, ccache, NULL, "anon-pkinit-realm", &data);
|
||||
if (ret == 0) {
|
||||
realm = malloc(data.length + 1);
|
||||
memcpy(realm, data.data, data.length);
|
||||
realm[data.length] = '\0';
|
||||
} else
|
||||
realm = get_default_realm(context);
|
||||
|
||||
ret = krb5_make_principal(context, tgs_name, realm,
|
||||
KRB5_TGS_NAME, realm, NULL);
|
||||
free(realm);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static krb5_error_code
|
||||
renew_validate(krb5_context context,
|
||||
int renew,
|
||||
@@ -296,7 +323,13 @@ renew_validate(krb5_context context,
|
||||
krb5_warn(context, ret, "krb5_cc_get_principal");
|
||||
return ret;
|
||||
}
|
||||
ret = get_server(context, in.client, server, &in.server);
|
||||
|
||||
if (server == NULL &&
|
||||
krb5_principal_is_anonymous(context, in.client,
|
||||
KRB5_ANON_MATCH_UNAUTHENTICATED))
|
||||
ret = get_anon_pkinit_tgs_name(context, cache, &in.server);
|
||||
else
|
||||
ret = get_server(context, in.client, server, &in.server);
|
||||
if (ret) {
|
||||
krb5_warn(context, ret, "get_server");
|
||||
goto out;
|
||||
@@ -777,6 +810,15 @@ get_new_tickets(krb5_context context,
|
||||
krb5_cc_set_config(context, ccache, NULL, "realm-config", &data);
|
||||
}
|
||||
|
||||
if (anonymous_pkinit) {
|
||||
krb5_data data;
|
||||
|
||||
data.length = strlen(principal->realm);
|
||||
data.data = principal->realm;
|
||||
|
||||
krb5_cc_set_config(context, ccache, NULL, "anon-pkinit-realm", &data);
|
||||
}
|
||||
|
||||
out:
|
||||
krb5_get_init_creds_opt_free(context, opt);
|
||||
if (ctx)
|
||||
|
@@ -737,9 +737,10 @@ fi
|
||||
if test "$pkinit" = yes -a "$rsa" = yes ; then
|
||||
|
||||
echo "try anonymous pkinit"; > messages.log
|
||||
${kinit} -n @${R} || \
|
||||
${kinit} --renewable -n @${R} || \
|
||||
{ ec=1 ; eval "${testfailed}"; }
|
||||
${kgetcred} ${server}@${R} || { ec=1 ; eval "${testfailed}"; }
|
||||
${kinit} --renew || { ec=1 ; eval "${testfailed}"; }
|
||||
${kdestroy}
|
||||
|
||||
for type in "" "--pk-use-enckey"; do
|
||||
|
Reference in New Issue
Block a user