Skip to content

Commit

Permalink
Add start_realm cc config
Browse files Browse the repository at this point in the history
  • Loading branch information
nicowilliams committed Apr 14, 2015
1 parent f5a86ad commit 629eeb8
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 9 deletions.
43 changes: 41 additions & 2 deletions lib/krb5/cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}


Expand Down Expand Up @@ -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;
}

/**
Expand Down Expand Up @@ -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;
Expand Down
31 changes: 24 additions & 7 deletions lib/krb5/get_cred.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -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);
Expand Down
1 change: 1 addition & 0 deletions lib/krb5/krb5.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 629eeb8

Please sign in to comment.