diff options
author | Luke Howard <lukeh@padl.com> | 2009-11-17 09:54:28 +0000 |
---|---|---|
committer | Luke Howard <lukeh@padl.com> | 2009-11-17 09:54:28 +0000 |
commit | d6d9f41285ef3a6c079ead042a1766be14d32c5a (patch) | |
tree | 5fef7c0b490379ec3430638b9eb5e549c272524b | |
parent | 958f311ee140255a231ac8e9fe0d67ee2aaaa822 (diff) | |
download | krb5-d6d9f41285ef3a6c079ead042a1766be14d32c5a.zip krb5-d6d9f41285ef3a6c079ead042a1766be14d32c5a.tar.gz krb5-d6d9f41285ef3a6c079ead042a1766be14d32c5a.tar.bz2 |
rewrite supplied server
git-svn-id: svn://anonsvn.mit.edu/krb5/users/lhoward/iakerb@23256 dc483132-0cff-0310-8789-dd5450dbe970
-rw-r--r-- | src/lib/krb5/krb/gc_frm_kdc.c | 61 |
1 files changed, 46 insertions, 15 deletions
diff --git a/src/lib/krb5/krb/gc_frm_kdc.c b/src/lib/krb5/krb/gc_frm_kdc.c index ce37dde..faf6720 100644 --- a/src/lib/krb5/krb/gc_frm_kdc.c +++ b/src/lib/krb5/krb/gc_frm_kdc.c @@ -111,6 +111,7 @@ struct _krb5_tkt_creds_context { krb5_data *realm; krb5_principal client; krb5_principal server; + krb5_principal supplied_server; krb5_creds *out_cred; krb5_creds **tgts; int kdcopt; @@ -123,6 +124,7 @@ struct _krb5_tkt_creds_context { krb5_timestamp timestamp; krb5_keyblock *subkey; krb5_data encoded_previous_request; + int is_referral_realm; }; /* NOTE: This only checks if NXT_TGT is CUR_CC_TGT. */ @@ -295,6 +297,9 @@ tkt_make_tgs_request(krb5_context context, if ((kdcopt & KDC_OPT_ENC_TKT_IN_SKEY) == 0) in_cred->is_skey = FALSE; + if (!krb5_c_valid_enctype(tgt->keyblock.enctype)) + return KRB5_PROG_ETYPE_NOSUPP; + code = krb5_make_tgs_request(context, tgt, kdcopt, tgt->addresses, NULL, in_cred, NULL, NULL, @@ -512,7 +517,11 @@ init_rtree(krb5_context context, krb5_tkt_creds_context ctx) krb5_error_code retval; struct tr_state *ts = TR_STATE(ctx); - ts->kdc_list = NULL; + if (ts->kdc_list != NULL) { + krb5_free_realm_tree(context, ts->kdc_list); + ts->kdc_list = NULL; + } + retval = krb5_walk_realm_tree(context, krb5_princ_realm(context, ctx->client), krb5_princ_realm(context, ctx->server), @@ -527,9 +536,16 @@ init_rtree(krb5_context context, krb5_tkt_creds_context ctx) assert(ts->nkdcs > 1); ts->lst_kdc = ts->kdc_list + ts->nkdcs - 1; - ts->kdc_tgts = calloc(ts->nkdcs + 1, sizeof(krb5_creds)); + ts->kdc_tgts = realloc(ts->kdc_tgts, (ts->nkdcs + 1) * sizeof(krb5_creds)); if (ts->kdc_tgts == NULL) return ENOMEM; + memset(ts->kdc_tgts, 0, (ts->nkdcs + 1) * sizeof(krb5_creds)); + + if (ts->offpath_tgt != NULL) { + assert(ctx->tgtptr != ts->offpath_tgt); + krb5_free_creds(context, ts->offpath_tgt); + ts->offpath_tgt = NULL; + } return 0; } @@ -685,9 +701,6 @@ try_kdc_request(krb5_context context, struct tr_state *ts = TR_STATE(ctx); TR_DBG(context, ctx, "try_kdc_request"); - /* This check should probably be in gc_via_tkt. */ - if (!krb5_c_valid_enctype(ts->cur_tgt->keyblock.enctype)) - return KRB5_PROG_ETYPE_NOSUPP; retval = tkt_make_tgs_request(context, ctx, ts->cur_tgt, 0, &ctx->tgtq, req); @@ -779,6 +792,7 @@ tkt_creds_set_state(krb5_context context, if (freeReferrals) { for (i = 0; i < ctx->referral_count; i++) { + assert(ctx->tgtptr != ctx->referral_tgts[i]); krb5_free_creds(context, ctx->referral_tgts[i]); ctx->referral_tgts[i] = NULL; } @@ -950,8 +964,9 @@ do_traversal_request(krb5_context context, krb5_error_code retval = 0; struct tr_state *ts = TR_STATE(ctx); - if (ts->kdc_list == NULL) { + if (ctx->tgtptr == NULL) { /* Initial state */ + clean_cc_tgts(context, ctx); init_cc_tgts(context, ctx); retval = init_rtree(context, ctx); @@ -1208,14 +1223,19 @@ krb5_tkt_creds_init(krb5_context context, ctx->client = ctx->in_cred.client; ctx->server = ctx->in_cred.server; - if (krb5_is_referral_realm(&ctx->server->realm)) { + code = krb5_copy_principal(context, ctx->server, &ctx->supplied_server); + if (code != 0) + goto cleanup; + + ctx->is_referral_realm = krb5_is_referral_realm(&ctx->server->realm); + if (ctx->is_referral_realm) { /* Use the client realm. */ DPRINTF(("krb5_tkt_creds_init: no server realm supplied, " "using client realm\n")); - krb5_free_data_contents(context, &ctx->in_cred.server->realm); + krb5_free_data_contents(context, &ctx->server->realm); code = krb5int_copy_data_contents_add0(context, - &ctx->in_cred.client->realm, - &ctx->in_cred.server->realm); + &ctx->client->realm, + &ctx->server->realm); if (code != 0) goto cleanup; } @@ -1251,6 +1271,7 @@ krb5_tkt_creds_free(krb5_context context, if (ctx == NULL) return; + krb5_free_principal(context, ctx->supplied_server); krb5_free_cred_contents(context, &ctx->in_cred); krb5_free_cred_contents(context, &ctx->tgtq); krb5_free_creds(context, ctx->out_cred); @@ -1356,7 +1377,7 @@ tkt_creds_request_initial_tgt(krb5_context context, /* Fast path: is it in the ccache? */ krb5_free_cred_contents(context, &ctx->cc_tgt); code = krb5_cc_retrieve_cred(context, ctx->ccache, RETR_FLAGS, - &ctx->tgtq, &ctx->cc_tgt); + &ctx->tgtq, &ctx->cc_tgt); if (code == 0) { tkt_creds_set_state(context, ctx, ctx->state + 1, 0, "tkt_creds_request_initial_tgt"); @@ -1455,7 +1476,8 @@ tkt_creds_reply_referral_tgt(krb5_context context, if (ctx->referral_count == 0) { /* Fall through to non-referral case */ tkt_creds_set_state(context, ctx, TKT_CREDS_FALLBACK_INITIAL_TGT, - 0, "tkt_creds_reply_referral_tgt"); + 1, "tkt_creds_reply_referral_tgt"); + ctx->tgtptr = NULL; code = 0; } goto cleanup; @@ -1552,7 +1574,7 @@ tkt_creds_reply_referral_tgt(krb5_context context, ctx->out_cred = NULL; tkt_creds_set_state(context, ctx, TKT_CREDS_FALLBACK_INITIAL_TGT, 1, "tkt_creds_reply_referral_tgt"); - ctx->referral_count = 0; + ctx->tgtptr = NULL; } cleanup: @@ -1575,8 +1597,7 @@ tkt_creds_request_fallback_initial_tgt(krb5_context context, * back to the server principal as originally issued and try the * conventional path. */ - - if (krb5_is_referral_realm(&ctx->server->realm)) { + if (ctx->is_referral_realm) { if (ctx->server->length >= 2) { code = krb5_get_fallback_host_realm(context, &ctx->server->data[1], @@ -1684,6 +1705,16 @@ tkt_creds_request_complete(krb5_context context, goto cleanup; } + krb5_free_principal(context, ctx->out_cred->server); + ctx->out_cred->server = ctx->supplied_server; + ctx->supplied_server = NULL; + + assert(ctx->out_cred->authdata == NULL); + code = krb5_copy_authdata(context, ctx->in_cred.authdata, + &ctx->out_cred->authdata); + if (code != 0) + goto cleanup; + cleanup: return code; } |