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