xref: /minix3/crypto/external/bsd/heimdal/dist/lib/krb5/replay.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc /*	$NetBSD: replay.c,v 1.1.1.2 2014/04/24 12:45:51 pettai Exp $	*/
2ebfedea0SLionel Sambuc 
3ebfedea0SLionel Sambuc /*
4ebfedea0SLionel Sambuc  * Copyright (c) 1997-2001 Kungliga Tekniska Högskolan
5ebfedea0SLionel Sambuc  * (Royal Institute of Technology, Stockholm, Sweden).
6ebfedea0SLionel Sambuc  * All rights reserved.
7ebfedea0SLionel Sambuc  *
8ebfedea0SLionel Sambuc  * Redistribution and use in source and binary forms, with or without
9ebfedea0SLionel Sambuc  * modification, are permitted provided that the following conditions
10ebfedea0SLionel Sambuc  * are met:
11ebfedea0SLionel Sambuc  *
12ebfedea0SLionel Sambuc  * 1. Redistributions of source code must retain the above copyright
13ebfedea0SLionel Sambuc  *    notice, this list of conditions and the following disclaimer.
14ebfedea0SLionel Sambuc  *
15ebfedea0SLionel Sambuc  * 2. Redistributions in binary form must reproduce the above copyright
16ebfedea0SLionel Sambuc  *    notice, this list of conditions and the following disclaimer in the
17ebfedea0SLionel Sambuc  *    documentation and/or other materials provided with the distribution.
18ebfedea0SLionel Sambuc  *
19ebfedea0SLionel Sambuc  * 3. Neither the name of the Institute nor the names of its contributors
20ebfedea0SLionel Sambuc  *    may be used to endorse or promote products derived from this software
21ebfedea0SLionel Sambuc  *    without specific prior written permission.
22ebfedea0SLionel Sambuc  *
23ebfedea0SLionel Sambuc  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24ebfedea0SLionel Sambuc  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25ebfedea0SLionel Sambuc  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26ebfedea0SLionel Sambuc  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27ebfedea0SLionel Sambuc  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28ebfedea0SLionel Sambuc  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29ebfedea0SLionel Sambuc  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30ebfedea0SLionel Sambuc  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31ebfedea0SLionel Sambuc  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32ebfedea0SLionel Sambuc  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33ebfedea0SLionel Sambuc  * SUCH DAMAGE.
34ebfedea0SLionel Sambuc  */
35ebfedea0SLionel Sambuc 
36ebfedea0SLionel Sambuc #include "krb5_locl.h"
37ebfedea0SLionel Sambuc #include <vis.h>
38ebfedea0SLionel Sambuc 
39ebfedea0SLionel Sambuc struct krb5_rcache_data {
40ebfedea0SLionel Sambuc     char *name;
41ebfedea0SLionel Sambuc };
42ebfedea0SLionel Sambuc 
43ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_rc_resolve(krb5_context context,krb5_rcache id,const char * name)44ebfedea0SLionel Sambuc krb5_rc_resolve(krb5_context context,
45ebfedea0SLionel Sambuc 		krb5_rcache id,
46ebfedea0SLionel Sambuc 		const char *name)
47ebfedea0SLionel Sambuc {
48ebfedea0SLionel Sambuc     id->name = strdup(name);
49ebfedea0SLionel Sambuc     if(id->name == NULL) {
50ebfedea0SLionel Sambuc 	krb5_set_error_message(context, KRB5_RC_MALLOC,
51ebfedea0SLionel Sambuc 			       N_("malloc: out of memory", ""));
52ebfedea0SLionel Sambuc 	return KRB5_RC_MALLOC;
53ebfedea0SLionel Sambuc     }
54ebfedea0SLionel Sambuc     return 0;
55ebfedea0SLionel Sambuc }
56ebfedea0SLionel Sambuc 
57ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_rc_resolve_type(krb5_context context,krb5_rcache * id,const char * type)58ebfedea0SLionel Sambuc krb5_rc_resolve_type(krb5_context context,
59ebfedea0SLionel Sambuc 		     krb5_rcache *id,
60ebfedea0SLionel Sambuc 		     const char *type)
61ebfedea0SLionel Sambuc {
62ebfedea0SLionel Sambuc     *id = NULL;
63ebfedea0SLionel Sambuc     if(strcmp(type, "FILE")) {
64ebfedea0SLionel Sambuc 	krb5_set_error_message (context, KRB5_RC_TYPE_NOTFOUND,
65ebfedea0SLionel Sambuc 				N_("replay cache type %s not supported", ""),
66ebfedea0SLionel Sambuc 				type);
67ebfedea0SLionel Sambuc 	return KRB5_RC_TYPE_NOTFOUND;
68ebfedea0SLionel Sambuc     }
69ebfedea0SLionel Sambuc     *id = calloc(1, sizeof(**id));
70ebfedea0SLionel Sambuc     if(*id == NULL) {
71ebfedea0SLionel Sambuc 	krb5_set_error_message(context, KRB5_RC_MALLOC,
72ebfedea0SLionel Sambuc 			       N_("malloc: out of memory", ""));
73ebfedea0SLionel Sambuc 	return KRB5_RC_MALLOC;
74ebfedea0SLionel Sambuc     }
75ebfedea0SLionel Sambuc     return 0;
76ebfedea0SLionel Sambuc }
77ebfedea0SLionel Sambuc 
78ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_rc_resolve_full(krb5_context context,krb5_rcache * id,const char * string_name)79ebfedea0SLionel Sambuc krb5_rc_resolve_full(krb5_context context,
80ebfedea0SLionel Sambuc 		     krb5_rcache *id,
81ebfedea0SLionel Sambuc 		     const char *string_name)
82ebfedea0SLionel Sambuc {
83ebfedea0SLionel Sambuc     krb5_error_code ret;
84ebfedea0SLionel Sambuc 
85ebfedea0SLionel Sambuc     *id = NULL;
86ebfedea0SLionel Sambuc 
87ebfedea0SLionel Sambuc     if(strncmp(string_name, "FILE:", 5)) {
88ebfedea0SLionel Sambuc 	krb5_set_error_message(context, KRB5_RC_TYPE_NOTFOUND,
89ebfedea0SLionel Sambuc 			       N_("replay cache type %s not supported", ""),
90ebfedea0SLionel Sambuc 			       string_name);
91ebfedea0SLionel Sambuc 	return KRB5_RC_TYPE_NOTFOUND;
92ebfedea0SLionel Sambuc     }
93ebfedea0SLionel Sambuc     ret = krb5_rc_resolve_type(context, id, "FILE");
94ebfedea0SLionel Sambuc     if(ret)
95ebfedea0SLionel Sambuc 	return ret;
96ebfedea0SLionel Sambuc     ret = krb5_rc_resolve(context, *id, string_name + 5);
97ebfedea0SLionel Sambuc     if (ret) {
98ebfedea0SLionel Sambuc 	krb5_rc_close(context, *id);
99ebfedea0SLionel Sambuc 	*id = NULL;
100ebfedea0SLionel Sambuc     }
101ebfedea0SLionel Sambuc     return ret;
102ebfedea0SLionel Sambuc }
103ebfedea0SLionel Sambuc 
104ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION const char* KRB5_LIB_CALL
krb5_rc_default_name(krb5_context context)105ebfedea0SLionel Sambuc krb5_rc_default_name(krb5_context context)
106ebfedea0SLionel Sambuc {
107ebfedea0SLionel Sambuc     return "FILE:/var/run/default_rcache";
108ebfedea0SLionel Sambuc }
109ebfedea0SLionel Sambuc 
110ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION const char* KRB5_LIB_CALL
krb5_rc_default_type(krb5_context context)111ebfedea0SLionel Sambuc krb5_rc_default_type(krb5_context context)
112ebfedea0SLionel Sambuc {
113ebfedea0SLionel Sambuc     return "FILE";
114ebfedea0SLionel Sambuc }
115ebfedea0SLionel Sambuc 
116ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_rc_default(krb5_context context,krb5_rcache * id)117ebfedea0SLionel Sambuc krb5_rc_default(krb5_context context,
118ebfedea0SLionel Sambuc 		krb5_rcache *id)
119ebfedea0SLionel Sambuc {
120ebfedea0SLionel Sambuc     return krb5_rc_resolve_full(context, id, krb5_rc_default_name(context));
121ebfedea0SLionel Sambuc }
122ebfedea0SLionel Sambuc 
123ebfedea0SLionel Sambuc struct rc_entry{
124ebfedea0SLionel Sambuc     time_t stamp;
125ebfedea0SLionel Sambuc     unsigned char data[16];
126ebfedea0SLionel Sambuc };
127ebfedea0SLionel Sambuc 
128ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_rc_initialize(krb5_context context,krb5_rcache id,krb5_deltat auth_lifespan)129ebfedea0SLionel Sambuc krb5_rc_initialize(krb5_context context,
130ebfedea0SLionel Sambuc 		   krb5_rcache id,
131ebfedea0SLionel Sambuc 		   krb5_deltat auth_lifespan)
132ebfedea0SLionel Sambuc {
133ebfedea0SLionel Sambuc     FILE *f = fopen(id->name, "w");
134ebfedea0SLionel Sambuc     struct rc_entry tmp;
135ebfedea0SLionel Sambuc     int ret;
136ebfedea0SLionel Sambuc 
137ebfedea0SLionel Sambuc     if(f == NULL) {
138ebfedea0SLionel Sambuc 	char buf[128];
139ebfedea0SLionel Sambuc 	ret = errno;
140ebfedea0SLionel Sambuc 	rk_strerror_r(ret, buf, sizeof(buf));
141ebfedea0SLionel Sambuc 	krb5_set_error_message(context, ret, "open(%s): %s", id->name, buf);
142ebfedea0SLionel Sambuc 	return ret;
143ebfedea0SLionel Sambuc     }
144ebfedea0SLionel Sambuc     tmp.stamp = auth_lifespan;
145ebfedea0SLionel Sambuc     fwrite(&tmp, 1, sizeof(tmp), f);
146ebfedea0SLionel Sambuc     fclose(f);
147ebfedea0SLionel Sambuc     return 0;
148ebfedea0SLionel Sambuc }
149ebfedea0SLionel Sambuc 
150ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_rc_recover(krb5_context context,krb5_rcache id)151ebfedea0SLionel Sambuc krb5_rc_recover(krb5_context context,
152ebfedea0SLionel Sambuc 		krb5_rcache id)
153ebfedea0SLionel Sambuc {
154ebfedea0SLionel Sambuc     return 0;
155ebfedea0SLionel Sambuc }
156ebfedea0SLionel Sambuc 
157ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_rc_destroy(krb5_context context,krb5_rcache id)158ebfedea0SLionel Sambuc krb5_rc_destroy(krb5_context context,
159ebfedea0SLionel Sambuc 		krb5_rcache id)
160ebfedea0SLionel Sambuc {
161ebfedea0SLionel Sambuc     int ret;
162ebfedea0SLionel Sambuc 
163ebfedea0SLionel Sambuc     if(remove(id->name) < 0) {
164ebfedea0SLionel Sambuc 	char buf[128];
165ebfedea0SLionel Sambuc 	ret = errno;
166ebfedea0SLionel Sambuc 	rk_strerror_r(ret, buf, sizeof(buf));
167ebfedea0SLionel Sambuc 	krb5_set_error_message(context, ret, "remove(%s): %s", id->name, buf);
168ebfedea0SLionel Sambuc 	return ret;
169ebfedea0SLionel Sambuc     }
170ebfedea0SLionel Sambuc     return krb5_rc_close(context, id);
171ebfedea0SLionel Sambuc }
172ebfedea0SLionel Sambuc 
173ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_rc_close(krb5_context context,krb5_rcache id)174ebfedea0SLionel Sambuc krb5_rc_close(krb5_context context,
175ebfedea0SLionel Sambuc 	      krb5_rcache id)
176ebfedea0SLionel Sambuc {
177ebfedea0SLionel Sambuc     free(id->name);
178ebfedea0SLionel Sambuc     free(id);
179ebfedea0SLionel Sambuc     return 0;
180ebfedea0SLionel Sambuc }
181ebfedea0SLionel Sambuc 
182ebfedea0SLionel Sambuc static void
checksum_authenticator(Authenticator * auth,void * data)183ebfedea0SLionel Sambuc checksum_authenticator(Authenticator *auth, void *data)
184ebfedea0SLionel Sambuc {
185ebfedea0SLionel Sambuc     EVP_MD_CTX *m = EVP_MD_CTX_create();
186ebfedea0SLionel Sambuc     unsigned i;
187ebfedea0SLionel Sambuc 
188ebfedea0SLionel Sambuc     EVP_DigestInit_ex(m, EVP_md5(), NULL);
189ebfedea0SLionel Sambuc 
190ebfedea0SLionel Sambuc     EVP_DigestUpdate(m, auth->crealm, strlen(auth->crealm));
191ebfedea0SLionel Sambuc     for(i = 0; i < auth->cname.name_string.len; i++)
192ebfedea0SLionel Sambuc 	EVP_DigestUpdate(m, auth->cname.name_string.val[i],
193ebfedea0SLionel Sambuc 		   strlen(auth->cname.name_string.val[i]));
194ebfedea0SLionel Sambuc     EVP_DigestUpdate(m, &auth->ctime, sizeof(auth->ctime));
195ebfedea0SLionel Sambuc     EVP_DigestUpdate(m, &auth->cusec, sizeof(auth->cusec));
196ebfedea0SLionel Sambuc 
197ebfedea0SLionel Sambuc     EVP_DigestFinal_ex(m, data, NULL);
198ebfedea0SLionel Sambuc     EVP_MD_CTX_destroy(m);
199ebfedea0SLionel Sambuc }
200ebfedea0SLionel Sambuc 
201ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_rc_store(krb5_context context,krb5_rcache id,krb5_donot_replay * rep)202ebfedea0SLionel Sambuc krb5_rc_store(krb5_context context,
203ebfedea0SLionel Sambuc 	      krb5_rcache id,
204ebfedea0SLionel Sambuc 	      krb5_donot_replay *rep)
205ebfedea0SLionel Sambuc {
206ebfedea0SLionel Sambuc     struct rc_entry ent, tmp;
207ebfedea0SLionel Sambuc     time_t t;
208ebfedea0SLionel Sambuc     FILE *f;
209ebfedea0SLionel Sambuc     int ret;
210ebfedea0SLionel Sambuc 
211ebfedea0SLionel Sambuc     ent.stamp = time(NULL);
212ebfedea0SLionel Sambuc     checksum_authenticator(rep, ent.data);
213ebfedea0SLionel Sambuc     f = fopen(id->name, "r");
214ebfedea0SLionel Sambuc     if(f == NULL) {
215ebfedea0SLionel Sambuc 	char buf[128];
216ebfedea0SLionel Sambuc 	ret = errno;
217ebfedea0SLionel Sambuc 	rk_strerror_r(ret, buf, sizeof(buf));
218ebfedea0SLionel Sambuc 	krb5_set_error_message(context, ret, "open(%s): %s", id->name, buf);
219ebfedea0SLionel Sambuc 	return ret;
220ebfedea0SLionel Sambuc     }
221ebfedea0SLionel Sambuc     rk_cloexec_file(f);
222ebfedea0SLionel Sambuc     fread(&tmp, sizeof(ent), 1, f);
223ebfedea0SLionel Sambuc     t = ent.stamp - tmp.stamp;
224ebfedea0SLionel Sambuc     while(fread(&tmp, sizeof(ent), 1, f)){
225ebfedea0SLionel Sambuc 	if(tmp.stamp < t)
226ebfedea0SLionel Sambuc 	    continue;
227ebfedea0SLionel Sambuc 	if(memcmp(tmp.data, ent.data, sizeof(ent.data)) == 0){
228ebfedea0SLionel Sambuc 	    fclose(f);
229ebfedea0SLionel Sambuc 	    krb5_clear_error_message (context);
230ebfedea0SLionel Sambuc 	    return KRB5_RC_REPLAY;
231ebfedea0SLionel Sambuc 	}
232ebfedea0SLionel Sambuc     }
233ebfedea0SLionel Sambuc     if(ferror(f)){
234ebfedea0SLionel Sambuc 	char buf[128];
235ebfedea0SLionel Sambuc 	ret = errno;
236ebfedea0SLionel Sambuc 	fclose(f);
237ebfedea0SLionel Sambuc 	rk_strerror_r(ret, buf, sizeof(buf));
238ebfedea0SLionel Sambuc 	krb5_set_error_message(context, ret, "%s: %s",
239ebfedea0SLionel Sambuc 			       id->name, buf);
240ebfedea0SLionel Sambuc 	return ret;
241ebfedea0SLionel Sambuc     }
242ebfedea0SLionel Sambuc     fclose(f);
243ebfedea0SLionel Sambuc     f = fopen(id->name, "a");
244ebfedea0SLionel Sambuc     if(f == NULL) {
245ebfedea0SLionel Sambuc 	char buf[128];
246ebfedea0SLionel Sambuc 	rk_strerror_r(errno, buf, sizeof(buf));
247ebfedea0SLionel Sambuc 	krb5_set_error_message(context, KRB5_RC_IO_UNKNOWN,
248ebfedea0SLionel Sambuc 			       "open(%s): %s", id->name, buf);
249ebfedea0SLionel Sambuc 	return KRB5_RC_IO_UNKNOWN;
250ebfedea0SLionel Sambuc     }
251ebfedea0SLionel Sambuc     fwrite(&ent, 1, sizeof(ent), f);
252ebfedea0SLionel Sambuc     fclose(f);
253ebfedea0SLionel Sambuc     return 0;
254ebfedea0SLionel Sambuc }
255ebfedea0SLionel Sambuc 
256ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_rc_expunge(krb5_context context,krb5_rcache id)257ebfedea0SLionel Sambuc krb5_rc_expunge(krb5_context context,
258ebfedea0SLionel Sambuc 		krb5_rcache id)
259ebfedea0SLionel Sambuc {
260ebfedea0SLionel Sambuc     return 0;
261ebfedea0SLionel Sambuc }
262ebfedea0SLionel Sambuc 
263ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_rc_get_lifespan(krb5_context context,krb5_rcache id,krb5_deltat * auth_lifespan)264ebfedea0SLionel Sambuc krb5_rc_get_lifespan(krb5_context context,
265ebfedea0SLionel Sambuc 		     krb5_rcache id,
266ebfedea0SLionel Sambuc 		     krb5_deltat *auth_lifespan)
267ebfedea0SLionel Sambuc {
268ebfedea0SLionel Sambuc     FILE *f = fopen(id->name, "r");
269ebfedea0SLionel Sambuc     int r;
270ebfedea0SLionel Sambuc     struct rc_entry ent;
271ebfedea0SLionel Sambuc     r = fread(&ent, sizeof(ent), 1, f);
272ebfedea0SLionel Sambuc     fclose(f);
273ebfedea0SLionel Sambuc     if(r){
274ebfedea0SLionel Sambuc 	*auth_lifespan = ent.stamp;
275ebfedea0SLionel Sambuc 	return 0;
276ebfedea0SLionel Sambuc     }
277ebfedea0SLionel Sambuc     krb5_clear_error_message (context);
278ebfedea0SLionel Sambuc     return KRB5_RC_IO_UNKNOWN;
279ebfedea0SLionel Sambuc }
280ebfedea0SLionel Sambuc 
281ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION const char* KRB5_LIB_CALL
krb5_rc_get_name(krb5_context context,krb5_rcache id)282ebfedea0SLionel Sambuc krb5_rc_get_name(krb5_context context,
283ebfedea0SLionel Sambuc 		 krb5_rcache id)
284ebfedea0SLionel Sambuc {
285ebfedea0SLionel Sambuc     return id->name;
286ebfedea0SLionel Sambuc }
287ebfedea0SLionel Sambuc 
288ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION const char* KRB5_LIB_CALL
krb5_rc_get_type(krb5_context context,krb5_rcache id)289ebfedea0SLionel Sambuc krb5_rc_get_type(krb5_context context,
290ebfedea0SLionel Sambuc 		 krb5_rcache id)
291ebfedea0SLionel Sambuc {
292ebfedea0SLionel Sambuc     return "FILE";
293ebfedea0SLionel Sambuc }
294ebfedea0SLionel Sambuc 
295ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_get_server_rcache(krb5_context context,const krb5_data * piece,krb5_rcache * id)296ebfedea0SLionel Sambuc krb5_get_server_rcache(krb5_context context,
297ebfedea0SLionel Sambuc 		       const krb5_data *piece,
298ebfedea0SLionel Sambuc 		       krb5_rcache *id)
299ebfedea0SLionel Sambuc {
300ebfedea0SLionel Sambuc     krb5_rcache rcache;
301ebfedea0SLionel Sambuc     krb5_error_code ret;
302ebfedea0SLionel Sambuc 
303ebfedea0SLionel Sambuc     char *tmp = malloc(4 * piece->length + 1);
304ebfedea0SLionel Sambuc     char *name;
305ebfedea0SLionel Sambuc 
306ebfedea0SLionel Sambuc     if(tmp == NULL) {
307ebfedea0SLionel Sambuc 	krb5_set_error_message(context, ENOMEM,
308ebfedea0SLionel Sambuc 			       N_("malloc: out of memory", ""));
309ebfedea0SLionel Sambuc 	return ENOMEM;
310ebfedea0SLionel Sambuc     }
311ebfedea0SLionel Sambuc     strvisx(tmp, piece->data, piece->length, VIS_WHITE | VIS_OCTAL);
312ebfedea0SLionel Sambuc #ifdef HAVE_GETEUID
313ebfedea0SLionel Sambuc     ret = asprintf(&name, "FILE:rc_%s_%u", tmp, (unsigned)geteuid());
314ebfedea0SLionel Sambuc #else
315ebfedea0SLionel Sambuc     ret = asprintf(&name, "FILE:rc_%s", tmp);
316ebfedea0SLionel Sambuc #endif
317ebfedea0SLionel Sambuc     free(tmp);
318ebfedea0SLionel Sambuc     if(ret < 0 || name == NULL) {
319ebfedea0SLionel Sambuc 	krb5_set_error_message(context, ENOMEM,
320ebfedea0SLionel Sambuc 			       N_("malloc: out of memory", ""));
321ebfedea0SLionel Sambuc 	return ENOMEM;
322ebfedea0SLionel Sambuc     }
323ebfedea0SLionel Sambuc 
324ebfedea0SLionel Sambuc     ret = krb5_rc_resolve_full(context, &rcache, name);
325ebfedea0SLionel Sambuc     free(name);
326ebfedea0SLionel Sambuc     if(ret)
327ebfedea0SLionel Sambuc 	return ret;
328ebfedea0SLionel Sambuc     *id = rcache;
329ebfedea0SLionel Sambuc     return ret;
330ebfedea0SLionel Sambuc }
331