From: Tom Yu Date: Wed, 29 Aug 2007 22:59:52 +0000 (+0000) Subject: Make ccache handle referrals better by storing both server principal X-Git-Tag: krb5-1.7-alpha1~900 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=8bb51eb0645b0ff5077312a99845ae447ba14e01;p=krb5.git Make ccache handle referrals better by storing both server principal names if they differ between the creds structure and the encoded ticket and by looking up the server principal using the client's realm if not found and server's realm was initially the referral (empty) realm. ticket: 5697 tags: pullup git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@19898 dc483132-0cff-0310-8789-dd5450dbe970 --- diff --git a/src/lib/krb5/ccache/ccfns.c b/src/lib/krb5/ccache/ccfns.c index 5e80059ae..f44c0fe6c 100644 --- a/src/lib/krb5/ccache/ccfns.c +++ b/src/lib/krb5/ccache/ccfns.c @@ -1,7 +1,7 @@ /* * lib/krb5/ccache/ccfns.c * - * Copyright 2000 by the Massachusetts Institute of Technology. + * Copyright 2000, 2007 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may @@ -65,7 +65,28 @@ krb5_error_code KRB5_CALLCONV krb5_cc_store_cred (krb5_context context, krb5_ccache cache, krb5_creds *creds) { - return cache->ops->store(context, cache, creds); + krb5_error_code ret; + krb5_ticket *tkt; + krb5_principal s1, s2; + + ret = cache->ops->store(context, cache, creds); + if (ret) return ret; + + /* + * If creds->server and the server in the decoded ticket differ, + * store both principals. + */ + s1 = creds->server; + ret = decode_krb5_ticket(&creds->ticket, &tkt); + if (ret) return ret; + s2 = tkt->server; + if (!krb5_principal_compare(context, s1, s2)) { + creds->server = s2; + ret = cache->ops->store(context, cache, creds); + creds->server = s1; + } + krb5_free_ticket(context, tkt); + return ret; } krb5_error_code KRB5_CALLCONV @@ -73,7 +94,23 @@ krb5_cc_retrieve_cred (krb5_context context, krb5_ccache cache, krb5_flags flags, krb5_creds *mcreds, krb5_creds *creds) { - return cache->ops->retrieve(context, cache, flags, mcreds, creds); + krb5_error_code ret; + krb5_data tmprealm; + + ret = cache->ops->retrieve(context, cache, flags, mcreds, creds); + if (ret != KRB5_CC_NOTFOUND) + return ret; + if (!krb5_is_referral_realm(&mcreds->server->realm)) + return ret; + + /* + * Retry using client's realm if service has referral realm. + */ + tmprealm = mcreds->server->realm; + mcreds->server->realm = mcreds->client->realm; + ret = cache->ops->retrieve(context, cache, flags, mcreds, creds); + mcreds->server->realm = tmprealm; + return ret; } krb5_error_code KRB5_CALLCONV