From f0b5e19cee8b05924df6c20a1e96ffde66234e1b Mon Sep 17 00:00:00 2001 From: Andrew Boardman Date: Fri, 8 Sep 2006 00:51:52 +0000 Subject: [PATCH] - Remove KRB5_REFERRAL_REALM check to separate function. - Conditionalize gc_frm_kdc out_cred freeing so it doesn't SEGV on an early failure before out_cred is allocated. git-svn-id: svn://anonsvn.mit.edu/krb5/branches/referrals@18572 dc483132-0cff-0310-8789-dd5450dbe970 --- TODO | 4 +-- src/include/krb5/krb5.hin | 5 +++ src/lib/krb5/krb/gc_frm_kdc.c | 64 +++++++++++++++++++++++------------ src/lib/krb5/os/hst_realm.c | 8 ++--- 4 files changed, 54 insertions(+), 27 deletions(-) diff --git a/TODO b/TODO index 9d18cba612..593e5efff6 100644 --- a/TODO +++ b/TODO @@ -3,10 +3,10 @@ blocking issues for beta release - correctly return first-hop TGTs for ccache storage - old code was convoluted and buggy. replacement underway. - referral loop checking -- testing, cleanup, documentation -- ccache match failure; referred tickets are always refetched - fallback uses local realm instead of remote fallback realm - switch string comparisons to use krb5_is_referral_realm +- wrong TGT in use for referrals with non-local specified domain? +- testing, cleanup, documentation further work: ============ diff --git a/src/include/krb5/krb5.hin b/src/include/krb5/krb5.hin index f01f387568..b434a802d1 100644 --- a/src/include/krb5/krb5.hin +++ b/src/include/krb5/krb5.hin @@ -265,6 +265,11 @@ typedef const krb5_principal_data *krb5_const_principal; #define KRB5_REFERRAL_REALM "" #define KRB5_REFERRAL_MAXHOPS 5 +/* + * Referral-specific functions. + */ +krb5_boolean krb5_is_referral_realm(krb5_data *); + /* * Referral debugging hooks. */ diff --git a/src/lib/krb5/krb/gc_frm_kdc.c b/src/lib/krb5/krb/gc_frm_kdc.c index a619ebd0d0..736de0714a 100644 --- a/src/lib/krb5/krb/gc_frm_kdc.c +++ b/src/lib/krb5/krb/gc_frm_kdc.c @@ -775,7 +775,7 @@ krb5_get_cred_from_kdc_opt(krb5_context context, krb5_ccache ccache, client = in_cred->client; if ((retval=krb5_copy_principal(context, in_cred->server, &server))) return retval; -/* We need a second copy for the output creds*/ + /* We need a second copy for the output creds. */ if ((retval = krb5_copy_principal(context, server, &out_supplied_server)) != 0 ) { krb5_free_principal(context, server); return retval; @@ -796,12 +796,12 @@ krb5_get_cred_from_kdc_opt(krb5_context context, krb5_ccache ccache, tgtptr = NULL; *tgts = NULL; + *out_cred=NULL; old_use_conf_ktypes = context->use_conf_ktypes; /* Copy client realm to server if no hint. */ - if (!strcmp(server->realm.data, KRB5_REFERRAL_REALM)) { // XXX a realm is not a string! + if (krb5_is_referral_realm(&server->realm)) { /* Use the client realm. */ - #ifdef DEBUG_REFERRALS printf("gc_from_kdc: no server realm supplied, using client realm.\n"); #endif @@ -885,8 +885,8 @@ krb5_get_cred_from_kdc_opt(krb5_context context, krb5_ccache ccache, kdcopt | (in_cred->second_ticket.length ? KDC_OPT_ENC_TKT_IN_SKEY : 0), - tgtptr->addresses - , in_cred, out_cred); + tgtptr->addresses, + in_cred, out_cred); /* Whether or not that succeeded, we're done. */ goto cleanup; } @@ -942,24 +942,24 @@ krb5_get_cred_from_kdc_opt(krb5_context context, krb5_ccache ccache, */ /* Referrals have failed. Look up fallback realm if not currently set. */ - if (!strcmp(server->realm.data, KRB5_REFERRAL_REALM)) { // XXX a realm is not a string! - if (server->length >= 2) { - retval=krb5_get_fallback_host_realm(context, server->data[1].data, - &hrealms); - if (retval) goto cleanup; + if (krb5_is_referral_realm(&server->realm)) { + if (server->length >= 2) { + retval=krb5_get_fallback_host_realm(context, server->data[1].data, + &hrealms); + if (retval) goto cleanup; #ifdef DEBUG_REFERRALS - printf("gc_from_kdc: using fallback realm of %s\n",hrealms[0]); + printf("gc_from_kdc: using fallback realm of %s\n",hrealms[0]); #endif - in_cred->server->realm.data=hrealms[0]; - } - else { - /* XXX realm tagged for referral but apparently not in a - / format. Fall back in some intelligent way or - just punt? */ + in_cred->server->realm.data=hrealms[0]; + } + else { + /* XXX realm tagged for referral but apparently not in a + / format. Fall back in some intelligent way or + just punt? */ #ifdef DEBUG_REFERRALS - printf("gc_from_kdc: referral specified but no fallback realm. wtf? exiting.\n"); + printf("gc_from_kdc: referral specified but no fallback realm. wtf? exiting.\n"); // XXX #endif - exit(1); + exit(1); } } @@ -1012,9 +1012,14 @@ cleanup: dbgref_dump_principal("gc_from_kdc: final hacked server principal at cleanup",server); #endif krb5_free_principal(context, server); - krb5_free_principal (context, (*out_cred)->server); in_cred->server = supplied_server; - (*out_cred)->server= out_supplied_server; + if (*out_cred) { + krb5_free_principal (context, (*out_cred)->server); + (*out_cred)->server= out_supplied_server; + } + else { + krb5_free_principal (context, out_supplied_server); + } #ifdef DEBUG_REFERRALS dbgref_dump_principal("gc_from_kdc: final server after reversion",in_cred->server); #endif @@ -1053,3 +1058,20 @@ krb5_get_cred_from_kdc_renew(krb5_context context, krb5_ccache ccache, KDC_OPT_RENEW); } +krb5_boolean krb5_is_referral_realm(krb5_data *r) +{ + /* + * Check for a match with KRB5_REFERRAL_REALM. Currently this relies + * on that string constant being zero-length. (Unlike principal realm + * names, KRB5_REFERRAL_REALM is known to be a string.) + */ +#ifdef DEBUG_REFERRALS + printf("krb5_is_ref_realm: checking <%s> for referralness: %s\n", + r->data,(r->length==0)?"true":"false"); +#endif + assert(strlen(KRB5_REFERRAL_REALM)==0); + if (r->length==0) + return TRUE; + else + return FALSE; +} diff --git a/src/lib/krb5/os/hst_realm.c b/src/lib/krb5/os/hst_realm.c index 42e6df00cf..094f5b7a49 100644 --- a/src/lib/krb5/os/hst_realm.c +++ b/src/lib/krb5/os/hst_realm.c @@ -249,10 +249,10 @@ krb5_get_host_realm(krb5_context context, const char *host, char ***realmsp) } if (realm == (char *)NULL) { - if (!(cp = (char *)malloc(strlen(KRB5_REFERRAL_REALM)+1))) - return ENOMEM; - strcpy(cp, KRB5_REFERRAL_REALM); - realm = cp; + if (!(cp = (char *)malloc(strlen(KRB5_REFERRAL_REALM)+1))) + return ENOMEM; + strcpy(cp, KRB5_REFERRAL_REALM); + realm = cp; } if (!(retrealms = (char **)calloc(2, sizeof(*retrealms)))) { -- 2.47.2