111497Sphk/* 211497Sphk * Copyright (c) 2005, PADL Software Pty Ltd. 311497Sphk * All rights reserved. 411497Sphk * 593151Sphk * Redistribution and use in source and binary forms, with or without 611497Sphk * modification, are permitted provided that the following conditions 711497Sphk * are met: 811497Sphk * 911497Sphk * 1. Redistributions of source code must retain the above copyright 10108605Sphk * notice, this list of conditions and the following disclaimer. 11108605Sphk * 1250477Speter * 2. Redistributions in binary form must reproduce the above copyright 1311497Sphk * notice, this list of conditions and the following disclaimer in the 14108605Sphk * documentation and/or other materials provided with the distribution. 15108605Sphk * 1611497Sphk * 3. Neither the name of PADL Software nor the names of its contributors 17103392Sphk * may be used to endorse or promote products derived from this software 1841594Sarchie * without specific prior written permission. 19108605Sphk * 2041594Sarchie * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND 21108605Sphk * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22108605Sphk * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23108605Sphk * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE 24108605Sphk * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25103392Sphk * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26108605Sphk * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27108605Sphk * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28108605Sphk * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29108605Sphk * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30108605Sphk * SUCH DAMAGE. 31108605Sphk */ 32108605Sphk 33108605Sphk#include "kcm_locl.h" 34108605Sphk 35108605SphkRCSID("$Id$"); 36108605Sphk 37108605Sphkkrb5_error_code 38108605Sphkkcm_ccache_refresh(krb5_context context, 39108605Sphk kcm_ccache ccache, 40108605Sphk krb5_creds **credp) 41108605Sphk{ 42108605Sphk krb5_error_code ret; 43108605Sphk krb5_creds in, *out; 44108605Sphk krb5_kdc_flags flags; 45108605Sphk krb5_const_realm realm; 46108605Sphk krb5_ccache_data ccdata; 47108605Sphk 48108605Sphk memset(&in, 0, sizeof(in)); 49108605Sphk 50108605Sphk KCM_ASSERT_VALID(ccache); 51108605Sphk 52108605Sphk if (ccache->client == NULL) { 53108605Sphk /* no primary principal */ 54108605Sphk kcm_log(0, "Refresh credentials requested but no client principal"); 55108605Sphk return KRB5_CC_NOTFOUND; 56108605Sphk } 57108605Sphk 58108605Sphk HEIMDAL_MUTEX_lock(&ccache->mutex); 59108605Sphk 60108605Sphk /* Fake up an internal ccache */ 61108605Sphk kcm_internal_ccache(context, ccache, &ccdata); 62108605Sphk 63108605Sphk /* Find principal */ 64108605Sphk in.client = ccache->client; 65108605Sphk 66108605Sphk if (ccache->server != NULL) { 67103392Sphk ret = krb5_copy_principal(context, ccache->server, &in.server); 6841594Sarchie if (ret) { 6941594Sarchie kcm_log(0, "Failed to copy service principal: %s", 70141640Sphk krb5_get_err_text(context, ret)); 71103392Sphk goto out; 72141640Sphk } 73141640Sphk } else { 74141640Sphk realm = krb5_principal_get_realm(context, in.client); 75141640Sphk ret = krb5_make_principal(context, &in.server, realm, 76141640Sphk KRB5_TGS_NAME, realm, NULL); 77141640Sphk if (ret) { 78141640Sphk kcm_log(0, "Failed to make TGS principal for realm %s: %s", 79141640Sphk realm, krb5_get_err_text(context, ret)); 80141640Sphk goto out; 8111497Sphk } 8211497Sphk } 8311497Sphk 8411497Sphk if (ccache->tkt_life) 8511497Sphk in.times.endtime = time(NULL) + ccache->tkt_life; 8611497Sphk if (ccache->renew_life) 8711497Sphk in.times.renew_till = time(NULL) + ccache->renew_life; 88141640Sphk 89141640Sphk flags.i = 0; 90141640Sphk flags.b.renewable = TRUE; 91141640Sphk flags.b.renew = TRUE; 9211497Sphk 93141640Sphk ret = krb5_get_kdc_cred(context, 94141640Sphk &ccdata, 9511497Sphk flags, 9611497Sphk NULL, 9711497Sphk NULL, 9811497Sphk &in, 9911497Sphk &out); 10011497Sphk if (ret) { 10111497Sphk kcm_log(0, "Failed to renew credentials for cache %s: %s", 10211497Sphk ccache->name, krb5_get_err_text(context, ret)); 103141640Sphk goto out; 10411497Sphk } 10511497Sphk 10611497Sphk /* Swap them in */ 10712814Sphk kcm_ccache_remove_creds_internal(context, ccache); 10812814Sphk 10911497Sphk ret = kcm_ccache_store_cred_internal(context, ccache, out, 0, credp); 11012814Sphk if (ret) { 111141640Sphk kcm_log(0, "Failed to store credentials for cache %s: %s", 11211497Sphk ccache->name, krb5_get_err_text(context, ret)); 11311497Sphk krb5_free_creds(context, out); 11411497Sphk goto out; 11511497Sphk } 11611497Sphk 11711497Sphk free(out); /* but not contents */ 11811497Sphk 11911497Sphkout: 12011497Sphk HEIMDAL_MUTEX_unlock(&ccache->mutex); 121108605Sphk 12211497Sphk return ret; 12311497Sphk} 12411497Sphk 12511497Sphk