renew.c revision 1.2
1/* $NetBSD: renew.c,v 1.2 2017/01/28 21:31:44 christos Exp $ */ 2 3/* 4 * Copyright (c) 2005, PADL Software Pty Ltd. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * 3. Neither the name of PADL Software nor the names of its contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 35#include "kcm_locl.h" 36 37__RCSID("$NetBSD: renew.c,v 1.2 2017/01/28 21:31:44 christos Exp $"); 38 39krb5_error_code 40kcm_ccache_refresh(krb5_context context, 41 kcm_ccache ccache, 42 krb5_creds **credp) 43{ 44 krb5_error_code ret; 45 krb5_creds in, *out; 46 krb5_kdc_flags flags; 47 krb5_const_realm realm; 48 krb5_ccache_data ccdata; 49 const char *estr; 50 51 memset(&in, 0, sizeof(in)); 52 53 KCM_ASSERT_VALID(ccache); 54 55 if (ccache->client == NULL) { 56 /* no primary principal */ 57 kcm_log(0, "Refresh credentials requested but no client principal"); 58 return KRB5_CC_NOTFOUND; 59 } 60 61 HEIMDAL_MUTEX_lock(&ccache->mutex); 62 63 /* Fake up an internal ccache */ 64 kcm_internal_ccache(context, ccache, &ccdata); 65 66 /* Find principal */ 67 in.client = ccache->client; 68 69 if (ccache->server != NULL) { 70 ret = krb5_copy_principal(context, ccache->server, &in.server); 71 if (ret) { 72 estr = krb5_get_error_message(context, ret); 73 kcm_log(0, "Failed to copy service principal: %s", 74 estr); 75 krb5_free_error_message(context, estr); 76 goto out; 77 } 78 } else { 79 realm = krb5_principal_get_realm(context, in.client); 80 ret = krb5_make_principal(context, &in.server, realm, 81 KRB5_TGS_NAME, realm, NULL); 82 if (ret) { 83 estr = krb5_get_error_message(context, ret); 84 kcm_log(0, "Failed to make TGS principal for realm %s: %s", 85 realm, estr); 86 krb5_free_error_message(context, estr); 87 goto out; 88 } 89 } 90 91 if (ccache->tkt_life) 92 in.times.endtime = time(NULL) + ccache->tkt_life; 93 if (ccache->renew_life) 94 in.times.renew_till = time(NULL) + ccache->renew_life; 95 96 flags.i = 0; 97 flags.b.renewable = TRUE; 98 flags.b.renew = TRUE; 99 100 ret = krb5_get_kdc_cred(context, 101 &ccdata, 102 flags, 103 NULL, 104 NULL, 105 &in, 106 &out); 107 if (ret) { 108 estr = krb5_get_error_message(context, ret); 109 kcm_log(0, "Failed to renew credentials for cache %s: %s", 110 ccache->name, estr); 111 krb5_free_error_message(context, estr); 112 goto out; 113 } 114 115 /* Swap them in */ 116 kcm_ccache_remove_creds_internal(context, ccache); 117 118 ret = kcm_ccache_store_cred_internal(context, ccache, out, 0, credp); 119 if (ret) { 120 estr = krb5_get_error_message(context, ret); 121 kcm_log(0, "Failed to store credentials for cache %s: %s", 122 ccache->name, estr); 123 krb5_free_error_message(context, estr); 124 krb5_free_creds(context, out); 125 goto out; 126 } 127 128 free(out); /* but not contents */ 129 130out: 131 HEIMDAL_MUTEX_unlock(&ccache->mutex); 132 133 return ret; 134} 135 136