Add start_realm cc config
This commit is contained in:
@@ -639,7 +639,12 @@ krb5_cc_initialize(krb5_context context,
|
||||
krb5_ccache id,
|
||||
krb5_principal primary_principal)
|
||||
{
|
||||
return (*id->ops->init)(context, id, primary_principal);
|
||||
krb5_error_code ret;
|
||||
|
||||
ret = (*id->ops->init)(context, id, primary_principal);
|
||||
if (ret == 0)
|
||||
id->initialized = 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -696,7 +701,36 @@ krb5_cc_store_cred(krb5_context context,
|
||||
krb5_ccache id,
|
||||
krb5_creds *creds)
|
||||
{
|
||||
return (*id->ops->store)(context, id, creds);
|
||||
krb5_error_code ret;
|
||||
krb5_data realm;
|
||||
|
||||
ret = (*id->ops->store)(context, id, creds);
|
||||
|
||||
/* Look for and mark the first root TGT's realm as the start realm */
|
||||
if (ret == 0 && id->initialized &&
|
||||
!krb5_is_config_principal(context, creds->server) &&
|
||||
krb5_principal_is_root_krbtgt(context, creds->server)) {
|
||||
|
||||
id->initialized = 1;
|
||||
realm.length = strlen(creds->server->realm) + 1;
|
||||
realm.data = creds->server->realm;
|
||||
(void) krb5_cc_set_config(context, id, NULL, "start_realm", &realm);
|
||||
} else if (ret == 0 && id->initialized &&
|
||||
krb5_is_config_principal(context, creds->server) &&
|
||||
strcmp(creds->server->name.name_string.val[1], "start_realm") == 0) {
|
||||
|
||||
/*
|
||||
* But if the caller is storing a start_realm ccconfig, then
|
||||
* stop looking for root TGTs to mark as the start_realm.
|
||||
*
|
||||
* By honoring any start_realm cc config stored, we interop
|
||||
* both, with ccache implementations that don't preserve
|
||||
* insertion order, and Kerberos implementations that store this
|
||||
* cc config before the TGT.
|
||||
*/
|
||||
id->initialized = 1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1679,6 +1713,11 @@ krb5_cc_get_lifetime(krb5_context context, krb5_ccache id, time_t *t)
|
||||
/**
|
||||
* If we find a krbtgt in the cache, use that as the lifespan.
|
||||
*/
|
||||
/*
|
||||
* FIXME We should try to find the start_realm cc config and
|
||||
* look for root TGTs for that realm instead of any random
|
||||
* (first) root TGT.
|
||||
*/
|
||||
if (krb5_principal_is_root_krbtgt(context, cred.server)) {
|
||||
if (now < cred.times.endtime)
|
||||
endtime = cred.times.endtime;
|
||||
|
@@ -951,7 +951,8 @@ get_cred_kdc_referral(krb5_context context,
|
||||
Ticket *second_ticket,
|
||||
krb5_creds **out_creds)
|
||||
{
|
||||
krb5_const_realm client_realm;
|
||||
krb5_realm start_realm = NULL;
|
||||
krb5_data config_start_realm;
|
||||
krb5_error_code ret;
|
||||
krb5_creds tgt, referral, ticket;
|
||||
krb5_creds **referral_tgts = NULL; /* used for loop detection */
|
||||
@@ -972,33 +973,49 @@ get_cred_kdc_referral(krb5_context context,
|
||||
|
||||
*out_creds = NULL;
|
||||
|
||||
client_realm = krb5_principal_get_realm(context, in_creds->client);
|
||||
|
||||
ret = krb5_cc_get_config(context, ccache, NULL, "start_realm", &config_start_realm);
|
||||
if (ret == 0) {
|
||||
start_realm = strndup(config_start_realm.data, config_start_realm.length);
|
||||
krb5_data_free(&config_start_realm);
|
||||
} else {
|
||||
start_realm = strdup(krb5_principal_get_realm(context, in_creds->client));
|
||||
}
|
||||
if (start_realm == NULL)
|
||||
return krb5_enomem(context);
|
||||
|
||||
/* find tgt for the clients base realm */
|
||||
{
|
||||
krb5_principal tgtname;
|
||||
|
||||
ret = krb5_make_principal(context, &tgtname,
|
||||
client_realm,
|
||||
start_realm,
|
||||
KRB5_TGS_NAME,
|
||||
client_realm,
|
||||
start_realm,
|
||||
NULL);
|
||||
if(ret)
|
||||
if (ret) {
|
||||
free(start_realm);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = find_cred(context, ccache, tgtname, NULL, &tgt);
|
||||
krb5_free_principal(context, tgtname);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
free(start_realm);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
referral = *in_creds;
|
||||
ret = krb5_copy_principal(context, in_creds->server, &referral.server);
|
||||
if (ret) {
|
||||
krb5_free_cred_contents(context, &tgt);
|
||||
free(start_realm);
|
||||
return ret;
|
||||
}
|
||||
ret = krb5_principal_set_realm(context, referral.server, client_realm);
|
||||
ret = krb5_principal_set_realm(context, referral.server, start_realm);
|
||||
free(start_realm);
|
||||
start_realm = NULL;
|
||||
if (ret) {
|
||||
krb5_free_cred_contents(context, &tgt);
|
||||
krb5_free_principal(context, referral.server);
|
||||
|
@@ -381,6 +381,7 @@ typedef struct krb5_cccol_cursor_data *krb5_cccol_cursor;
|
||||
typedef struct krb5_ccache_data {
|
||||
const struct krb5_cc_ops *ops;
|
||||
krb5_data data;
|
||||
int initialized; /* if non-zero: krb5_cc_initialize() called, now empty */
|
||||
}krb5_ccache_data;
|
||||
|
||||
typedef struct krb5_ccache_data *krb5_ccache;
|
||||
|
Reference in New Issue
Block a user