/*1* Copyright (c) 2005, PADL Software Pty Ltd.2* All rights reserved.3*4* Redistribution and use in source and binary forms, with or without5* modification, are permitted provided that the following conditions6* are met:7*8* 1. Redistributions of source code must retain the above copyright9* notice, this list of conditions and the following disclaimer.10*11* 2. Redistributions in binary form must reproduce the above copyright12* notice, this list of conditions and the following disclaimer in the13* documentation and/or other materials provided with the distribution.14*15* 3. Neither the name of PADL Software nor the names of its contributors16* may be used to endorse or promote products derived from this software17* without specific prior written permission.18*19* THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND20* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE21* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE22* ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE23* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL24* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS25* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)26* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT27* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY28* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF29* SUCH DAMAGE.30*/3132#include "kcm_locl.h"3334RCSID("$Id$");3536krb5_error_code37kcm_ccache_refresh(krb5_context context,38kcm_ccache ccache,39krb5_creds **credp)40{41krb5_error_code ret;42krb5_creds in, *out;43krb5_kdc_flags flags;44krb5_const_realm realm;45krb5_ccache_data ccdata;4647memset(&in, 0, sizeof(in));4849KCM_ASSERT_VALID(ccache);5051if (ccache->client == NULL) {52/* no primary principal */53kcm_log(0, "Refresh credentials requested but no client principal");54return KRB5_CC_NOTFOUND;55}5657HEIMDAL_MUTEX_lock(&ccache->mutex);5859/* Fake up an internal ccache */60kcm_internal_ccache(context, ccache, &ccdata);6162/* Find principal */63in.client = ccache->client;6465if (ccache->server != NULL) {66ret = krb5_copy_principal(context, ccache->server, &in.server);67if (ret) {68kcm_log(0, "Failed to copy service principal: %s",69krb5_get_err_text(context, ret));70goto out;71}72} else {73realm = krb5_principal_get_realm(context, in.client);74ret = krb5_make_principal(context, &in.server, realm,75KRB5_TGS_NAME, realm, NULL);76if (ret) {77kcm_log(0, "Failed to make TGS principal for realm %s: %s",78realm, krb5_get_err_text(context, ret));79goto out;80}81}8283if (ccache->tkt_life)84in.times.endtime = time(NULL) + ccache->tkt_life;85if (ccache->renew_life)86in.times.renew_till = time(NULL) + ccache->renew_life;8788flags.i = 0;89flags.b.renewable = TRUE;90flags.b.renew = TRUE;9192ret = krb5_get_kdc_cred(context,93&ccdata,94flags,95NULL,96NULL,97&in,98&out);99if (ret) {100kcm_log(0, "Failed to renew credentials for cache %s: %s",101ccache->name, krb5_get_err_text(context, ret));102goto out;103}104105/* Swap them in */106kcm_ccache_remove_creds_internal(context, ccache);107108ret = kcm_ccache_store_cred_internal(context, ccache, out, 0, credp);109if (ret) {110kcm_log(0, "Failed to store credentials for cache %s: %s",111ccache->name, krb5_get_err_text(context, ret));112krb5_free_creds(context, out);113goto out;114}115116free(out); /* but not contents */117118out:119HEIMDAL_MUTEX_unlock(&ccache->mutex);120121return ret;122}123124125126