From 8bb51eb0645b0ff5077312a99845ae447ba14e01 Mon Sep 17 00:00:00 2001 From: Tom Yu Date: Wed, 29 Aug 2007 22:59:52 +0000 Subject: [PATCH] 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 --- src/lib/krb5/ccache/ccfns.c | 43 ++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) 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 -- 2.26.2