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
39 krb5_error_code
kcm_ccache_refresh(krb5_context context,kcm_ccache ccache,krb5_creds ** credp)40 kcm_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
130 out:
131 HEIMDAL_MUTEX_unlock(&ccache->mutex);
132
133 return ret;
134 }
135
136