From 4b0918f8082c32a57a940178888efdd2fdfc60f4 Mon Sep 17 00:00:00 2001 From: John Kohl Date: Tue, 27 Mar 1990 13:55:44 +0000 Subject: [PATCH] compiles; not tested git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@425 dc483132-0cff-0310-8789-dd5450dbe970 --- src/lib/krb5/krb/gc_frm_kdc.c | 93 +++++++++++++++++++++++++++++++---- src/lib/krb5/krb/gc_via_tgt.c | 66 +++++++++++++------------ 2 files changed, 119 insertions(+), 40 deletions(-) diff --git a/src/lib/krb5/krb/gc_frm_kdc.c b/src/lib/krb5/krb/gc_frm_kdc.c index 158e3f037..6c0d23b58 100644 --- a/src/lib/krb5/krb/gc_frm_kdc.c +++ b/src/lib/krb5/krb/gc_frm_kdc.c @@ -19,6 +19,11 @@ static char rcsid_gcfkdc_c[] = #include #include +#include +#include + +#include +#include "int-proto.h" /* * Retrieve credentials for principal creds->client, @@ -29,7 +34,8 @@ static char rcsid_gcfkdc_c[] = * TGT credentials obtained in the process of contacting the KDC are * returned in an array of credentials; tgts is filled in to point to an * array of pointers to credential structures (if no TGT's were used, the - * pointer is zeroed). + * pointer is zeroed). TGT's may be returned even if no useful end ticket + * was obtained. * * The returned credentials are NOT cached. * @@ -43,6 +49,9 @@ static char rcsid_gcfkdc_c[] = * returns errors, system errors. */ +/* helper function: convert flags to necessary KDC options */ +#define flags2options(flags) (flags & KDC_TKT_COMMON_MASK) + krb5_error_code krb5_get_cred_from_kdc (ccache, cred, tgts) krb5_ccache ccache; @@ -50,15 +59,20 @@ krb5_get_cred_from_kdc (ccache, cred, tgts) krb5_creds ***tgts; { krb5_creds tgt, tgtq; + krb5_creds **ret_tgts = 0; + krb5_principal *tgs_list, next_server; krb5_error_code retval; + int nservers; + /* in case we never get a TGT, zero the return */ + tgts = 0; + /* * we know that the desired credentials aren't in the cache yet. * * To get them, we first need a tgt for the realm of the server. + * first, we see if we have such a TGT in cache. */ - - /* first, we see if we have a shortcut path to the server's realm. */ /* * look for ticket with: @@ -74,9 +88,10 @@ krb5_get_cred_from_kdc (ccache, cred, tgts) if (retval = krb5_tgtname(cred->server, cred->client, &tgtq.server)) return retval; - /* go find it.. */ + + /* try to fetch it directly */ retval = krb5_cc_retrieve_cred (ccache, - KRB5_CF_CLIENT|KRB5_CF_SERVER, + 0, /* default is client & server */ &tgtq, &tgt); krb5_free_principal(tgtq.server); @@ -84,11 +99,71 @@ krb5_get_cred_from_kdc (ccache, cred, tgts) if (retval != 0) { if (retval != KRB5_CC_NOTFOUND) goto out; - /* nope; attempt to get tgt */ + /* don't have the right TGT in the cred cache. Time to iterate + across realms to get the right TGT. */ + + /* get a list of realms to consult */ + retval = krb5_walk_realm_tree(cred->client, cred->server, &tgs_list); + if (retval) + goto out; + /* walk the list BACKWARDS until we find a cached + TGT, then move forward obtaining TGTs until we get the last + TGT needed */ + for (next_server = tgs_list[0]; next_server; next_server++); + nservers = next_server - tgs_list[0]; + next_server--; + + /* next_server now points to the last TGT */ + for (; next_server >= tgs_list[0]; next_server--) { + tgtq.server = next_server; + retval = krb5_cc_retrieve_cred (ccache, + 0, /* default is client & server */ + &tgtq, + &tgt); + if (retval) { + if (retval != KRB5_CC_NOTFOUND) { + krb5_free_realm_tree(tgs_list); + goto out; + } + continue; + } + next_server++; + break; /* found one! */ + } + /* allocate storage for TGT pointers. */ + ret_tgts = (krb5_creds **)calloc(nservers+1, sizeof(krb5_creds)); + if (!ret_tgts) { + retval = ENOMEM; + goto out; + } + for (nservers = 0; next_server; next_server++, nservers++) { + /* now get the TGTs */ + tgtq.times = tgt.times; + tgtq.client = tgt.client; + tgtq.server = next_server; + tgtq.is_skey = FALSE; + tgtq.ticket_flags = tgt.ticket_flags; + if (retval = krb5_get_cred_via_tgt(&tgt, + flags2options(tgtq.ticket_flags), + 0, /* XXX etype */ + 0, /* XXX sumtype */ + 0, /* XXX addrs */ + &tgtq)) + goto out; + /* save tgt in return array */ + if (retval = krb5_copy_cred(&tgtq, &ret_tgts[nservers])) + goto out; + /* XXX need to clean up stuff pointed to by tgtq? */ + tgt = tgtq; + } } - /* got tgt! */ - retval = krb5_get_cred_via_tgt(&tgt, cred); + /* got/finally have tgt! */ + retval = krb5_get_cred_via_tgt(&tgt, + flags2options(tgtq.ticket_flags), + 0, /* XXX etype */ + 0, /* XXX sumtype */ + 0, /* XXX addrs */ + cred); out: - /* XXX what about tgts? */ return retval; } diff --git a/src/lib/krb5/krb/gc_via_tgt.c b/src/lib/krb5/krb/gc_via_tgt.c index e00c88c43..c2dc04af2 100644 --- a/src/lib/krb5/krb/gc_via_tgt.c +++ b/src/lib/krb5/krb/gc_via_tgt.c @@ -24,28 +24,26 @@ static char rcsid_gcvtgt_c[] = #include #include #include - -static krb5_flags -creds_to_kdcoptions(creds) -krb5_creds *creds; -{ - krb5_flags result; - - /* XXX this is a hack; we don't necessarily want all these! */ - result = creds->ticket_flags & KDC_TKT_COMMON_MASK; - result |= KDC_OPT_RENEWABLE_OK; - return result; -} +#include "int-proto.h" krb5_error_code -krb5_get_cred_via_tgt (tgt, cred) - krb5_creds *tgt; /* IN */ - krb5_creds *cred; /* IN OUT */ +krb5_get_cred_via_tgt (DECLARG(krb5_creds *, tgt), + DECLARG(krb5_flags, kdcoptions), + DECLARG(krb5_enctype, etype), + DECLARG(krb5_cksumtype, sumtype), + DECLARG(krb5_address **, addrs), + DECLARG(krb5_creds *, cred)) +OLDDECLARG(krb5_creds *, tgt) +OLDDECLARG(krb5_flags, kdcoptions) +OLDDECLARG(krb5_enctype, etype) +OLDDECLARG(krb5_cksumtype, sumtype) +OLDDECLARG(krb5_address **, addrs) +OLDDECLARG(krb5_creds *, cred) { krb5_tgs_req tgsreq; krb5_real_tgs_req realreq; krb5_error_code retval; - krb5f_principal tempprinc; + krb5_principal tempprinc; krb5_data *scratch, reply; krb5_checksum ap_checksum; krb5_kdc_rep *dec_rep; @@ -71,35 +69,37 @@ krb5_get_cred_via_tgt (tgt, cred) bzero((char *)&realreq, sizeof(realreq)); - realreq.kdc_options = creds_to_kdcoptions(cred); + realreq.kdc_options = kdcoptions; realreq.from = cred->times.starttime; realreq.till = cred->times.endtime; realreq.rtime = cred->times.renew_till; if (retval = krb5_timeofday(&realreq.ctime)) return(retval); - realreq.etype = xxx; + realreq.etype = etype; realreq.server = cred->server; - realreq.addresses = xxx; + realreq.addresses = addrs; /* enc_part & enc_part2 are left blank for the moment. */ if (retval = encode_krb5_real_tgs_req(&realreq, &scratch)) return(retval); /* xxx choose a checksum type */ - if (retval = (*(krb5_cksumarray[xxx]->sum_func))(scratch->data, - 0, /* XXX? */ - (krb5_pointer) cred->keyblock.contents, - scratch->length, - cred->keyblock.length, - &ap_checksum)) { + if (retval = (*(krb5_cksumarray[sumtype]-> + sum_func))(scratch->data, + 0, /* XXX? */ + (krb5_pointer) cred->keyblock.contents, + scratch->length, + cred->keyblock.length, + &ap_checksum)) { krb5_free_data(scratch); return retval; } tgsreq.tgs_request = *scratch; xfree(scratch); -#define cleanup() {(void) free(tgsreq.tgs_request.data);} +#define cleanup() {(void) free((char *)tgsreq.tgs_request.data); \ + (void) free((char *)ap_checksum.contents);} /* * Now get an ap_req. @@ -138,7 +138,7 @@ krb5_get_cred_via_tgt (tgt, cred) /* we expect *reply to be either an error or a proper reply */ if (retval = krb5_decode_kdc_rep(&reply, &tgt->keyblock, - xxx, /* enctype */ + realreq.etype, /* enctype */ &dec_rep)) { if (decode_krb5_error(&reply, &err_reply)) { cleanup(); @@ -160,11 +160,11 @@ krb5_get_cred_via_tgt (tgt, cred) if (!krb5_principal_compare(dec_rep->client, tgt->client)) { cleanup(); - return XXX_MODIFIED; + return KRB5_KDCREP_MODIFIED; } /* put pieces into cred-> */ - if (retval = xxx_copy_keyblock(dec_rep->enc_part2->session, - &cred->keyblock)) { + if (retval = krb5_copy_keyblock(dec_rep->enc_part2->session, + &cred->keyblock)) { cleanup(); return retval; } @@ -172,8 +172,12 @@ krb5_get_cred_via_tgt (tgt, cred) /* check compatibility here first ? XXX */ cred->ticket_flags = dec_rep->enc_part2->flags; cred->is_skey = FALSE; - retval = xxx_copy_ticket(dec_rep->ticket, &cred->ticket); + retval = krb5_encode_ticket(dec_rep->ticket, &scratch); + if (!retval) { + cred->ticket = *scratch; + free((char *)scratch); + } cleanup(); return retval; } -- 2.26.2