xref: /freebsd/crypto/heimdal/lib/krb5/acache.c (revision 6a068746777241722b2b32c5d0bc443a2a64d80b)
1c19800e8SDoug Rabson /*
2*ae771770SStanislav Sedov  * Copyright (c) 2004 - 2007 Kungliga Tekniska Högskolan
3c19800e8SDoug Rabson  * (Royal Institute of Technology, Stockholm, Sweden).
4c19800e8SDoug Rabson  * All rights reserved.
5c19800e8SDoug Rabson  *
6*ae771770SStanislav Sedov  * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
7*ae771770SStanislav Sedov  *
8c19800e8SDoug Rabson  * Redistribution and use in source and binary forms, with or without
9c19800e8SDoug Rabson  * modification, are permitted provided that the following conditions
10c19800e8SDoug Rabson  * are met:
11c19800e8SDoug Rabson  *
12c19800e8SDoug Rabson  * 1. Redistributions of source code must retain the above copyright
13c19800e8SDoug Rabson  *    notice, this list of conditions and the following disclaimer.
14c19800e8SDoug Rabson  *
15c19800e8SDoug Rabson  * 2. Redistributions in binary form must reproduce the above copyright
16c19800e8SDoug Rabson  *    notice, this list of conditions and the following disclaimer in the
17c19800e8SDoug Rabson  *    documentation and/or other materials provided with the distribution.
18c19800e8SDoug Rabson  *
19c19800e8SDoug Rabson  * 3. Neither the name of the Institute nor the names of its contributors
20c19800e8SDoug Rabson  *    may be used to endorse or promote products derived from this software
21c19800e8SDoug Rabson  *    without specific prior written permission.
22c19800e8SDoug Rabson  *
23c19800e8SDoug Rabson  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24c19800e8SDoug Rabson  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25c19800e8SDoug Rabson  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26c19800e8SDoug Rabson  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27c19800e8SDoug Rabson  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28c19800e8SDoug Rabson  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29c19800e8SDoug Rabson  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30c19800e8SDoug Rabson  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31c19800e8SDoug Rabson  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32c19800e8SDoug Rabson  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33c19800e8SDoug Rabson  * SUCH DAMAGE.
34c19800e8SDoug Rabson  */
35c19800e8SDoug Rabson 
36c19800e8SDoug Rabson #include "krb5_locl.h"
37c19800e8SDoug Rabson #include <krb5_ccapi.h>
38c19800e8SDoug Rabson #ifdef HAVE_DLFCN_H
39c19800e8SDoug Rabson #include <dlfcn.h>
40c19800e8SDoug Rabson #endif
41c19800e8SDoug Rabson 
42*ae771770SStanislav Sedov #ifndef KCM_IS_API_CACHE
43c19800e8SDoug Rabson 
44c19800e8SDoug Rabson static HEIMDAL_MUTEX acc_mutex = HEIMDAL_MUTEX_INITIALIZER;
45c19800e8SDoug Rabson static cc_initialize_func init_func;
46*ae771770SStanislav Sedov static void (KRB5_CALLCONV *set_target_uid)(uid_t);
47*ae771770SStanislav Sedov static void (KRB5_CALLCONV *clear_target)(void);
48c19800e8SDoug Rabson 
49c19800e8SDoug Rabson #ifdef HAVE_DLOPEN
50c19800e8SDoug Rabson static void *cc_handle;
51c19800e8SDoug Rabson #endif
52c19800e8SDoug Rabson 
53c19800e8SDoug Rabson typedef struct krb5_acc {
54c19800e8SDoug Rabson     char *cache_name;
55c19800e8SDoug Rabson     cc_context_t context;
56c19800e8SDoug Rabson     cc_ccache_t ccache;
57c19800e8SDoug Rabson } krb5_acc;
58c19800e8SDoug Rabson 
59*ae771770SStanislav Sedov static krb5_error_code KRB5_CALLCONV acc_close(krb5_context, krb5_ccache);
60c19800e8SDoug Rabson 
61c19800e8SDoug Rabson #define ACACHE(X) ((krb5_acc *)(X)->data.data)
62c19800e8SDoug Rabson 
63c19800e8SDoug Rabson static const struct {
64c19800e8SDoug Rabson     cc_int32 error;
65c19800e8SDoug Rabson     krb5_error_code ret;
66c19800e8SDoug Rabson } cc_errors[] = {
67c19800e8SDoug Rabson     { ccErrBadName,		KRB5_CC_BADNAME },
68c19800e8SDoug Rabson     { ccErrCredentialsNotFound,	KRB5_CC_NOTFOUND },
69c19800e8SDoug Rabson     { ccErrCCacheNotFound,	KRB5_FCC_NOFILE },
70c19800e8SDoug Rabson     { ccErrContextNotFound,	KRB5_CC_NOTFOUND },
71c19800e8SDoug Rabson     { ccIteratorEnd,		KRB5_CC_END },
72c19800e8SDoug Rabson     { ccErrNoMem,		KRB5_CC_NOMEM },
73c19800e8SDoug Rabson     { ccErrServerUnavailable,	KRB5_CC_NOSUPP },
74*ae771770SStanislav Sedov     { ccErrInvalidCCache,	KRB5_CC_BADNAME },
75c19800e8SDoug Rabson     { ccNoError,		0 }
76c19800e8SDoug Rabson };
77c19800e8SDoug Rabson 
78c19800e8SDoug Rabson static krb5_error_code
translate_cc_error(krb5_context context,cc_int32 error)79c19800e8SDoug Rabson translate_cc_error(krb5_context context, cc_int32 error)
80c19800e8SDoug Rabson {
81*ae771770SStanislav Sedov     size_t i;
82*ae771770SStanislav Sedov     krb5_clear_error_message(context);
83c19800e8SDoug Rabson     for(i = 0; i < sizeof(cc_errors)/sizeof(cc_errors[0]); i++)
84c19800e8SDoug Rabson 	if (cc_errors[i].error == error)
85c19800e8SDoug Rabson 	    return cc_errors[i].ret;
86c19800e8SDoug Rabson     return KRB5_FCC_INTERNAL;
87c19800e8SDoug Rabson }
88c19800e8SDoug Rabson 
89c19800e8SDoug Rabson static krb5_error_code
init_ccapi(krb5_context context)90c19800e8SDoug Rabson init_ccapi(krb5_context context)
91c19800e8SDoug Rabson {
92*ae771770SStanislav Sedov     const char *lib = NULL;
93c19800e8SDoug Rabson 
94c19800e8SDoug Rabson     HEIMDAL_MUTEX_lock(&acc_mutex);
95c19800e8SDoug Rabson     if (init_func) {
96c19800e8SDoug Rabson 	HEIMDAL_MUTEX_unlock(&acc_mutex);
97*ae771770SStanislav Sedov 	if (context)
98*ae771770SStanislav Sedov 	    krb5_clear_error_message(context);
99c19800e8SDoug Rabson 	return 0;
100c19800e8SDoug Rabson     }
101c19800e8SDoug Rabson 
102*ae771770SStanislav Sedov     if (context)
103c19800e8SDoug Rabson 	lib = krb5_config_get_string(context, NULL,
104c19800e8SDoug Rabson 				     "libdefaults", "ccapi_library",
105c19800e8SDoug Rabson 				     NULL);
106c19800e8SDoug Rabson     if (lib == NULL) {
107c19800e8SDoug Rabson #ifdef __APPLE__
108c19800e8SDoug Rabson 	lib = "/System/Library/Frameworks/Kerberos.framework/Kerberos";
109*ae771770SStanislav Sedov #elif defined(KRB5_USE_PATH_TOKENS) && defined(_WIN32)
110*ae771770SStanislav Sedov 	lib = "%{LIBDIR}/libkrb5_cc.dll";
111c19800e8SDoug Rabson #else
112c19800e8SDoug Rabson 	lib = "/usr/lib/libkrb5_cc.so";
113c19800e8SDoug Rabson #endif
114c19800e8SDoug Rabson     }
115c19800e8SDoug Rabson 
116c19800e8SDoug Rabson #ifdef HAVE_DLOPEN
117c19800e8SDoug Rabson 
118c19800e8SDoug Rabson #ifndef RTLD_LAZY
119c19800e8SDoug Rabson #define RTLD_LAZY 0
120c19800e8SDoug Rabson #endif
121*ae771770SStanislav Sedov #ifndef RTLD_LOCAL
122*ae771770SStanislav Sedov #define RTLD_LOCAL 0
123*ae771770SStanislav Sedov #endif
124c19800e8SDoug Rabson 
125*ae771770SStanislav Sedov #ifdef KRB5_USE_PATH_TOKENS
126*ae771770SStanislav Sedov     {
127*ae771770SStanislav Sedov       char * explib = NULL;
128*ae771770SStanislav Sedov       if (_krb5_expand_path_tokens(context, lib, &explib) == 0) {
129*ae771770SStanislav Sedov 	cc_handle = dlopen(explib, RTLD_LAZY|RTLD_LOCAL);
130*ae771770SStanislav Sedov 	free(explib);
131*ae771770SStanislav Sedov       }
132*ae771770SStanislav Sedov     }
133*ae771770SStanislav Sedov #else
134*ae771770SStanislav Sedov     cc_handle = dlopen(lib, RTLD_LAZY|RTLD_LOCAL);
135*ae771770SStanislav Sedov #endif
136*ae771770SStanislav Sedov 
137c19800e8SDoug Rabson     if (cc_handle == NULL) {
138c19800e8SDoug Rabson 	HEIMDAL_MUTEX_unlock(&acc_mutex);
139*ae771770SStanislav Sedov 	if (context)
140*ae771770SStanislav Sedov 	    krb5_set_error_message(context, KRB5_CC_NOSUPP,
141*ae771770SStanislav Sedov 				   N_("Failed to load API cache module %s", "file"),
142*ae771770SStanislav Sedov 				   lib);
143c19800e8SDoug Rabson 	return KRB5_CC_NOSUPP;
144c19800e8SDoug Rabson     }
145c19800e8SDoug Rabson 
146c19800e8SDoug Rabson     init_func = (cc_initialize_func)dlsym(cc_handle, "cc_initialize");
147*ae771770SStanislav Sedov     set_target_uid = (void (KRB5_CALLCONV *)(uid_t))
148*ae771770SStanislav Sedov 	dlsym(cc_handle, "krb5_ipc_client_set_target_uid");
149*ae771770SStanislav Sedov     clear_target = (void (KRB5_CALLCONV *)(void))
150*ae771770SStanislav Sedov 	dlsym(cc_handle, "krb5_ipc_client_clear_target");
151c19800e8SDoug Rabson     HEIMDAL_MUTEX_unlock(&acc_mutex);
152c19800e8SDoug Rabson     if (init_func == NULL) {
153*ae771770SStanislav Sedov 	if (context)
154*ae771770SStanislav Sedov 	    krb5_set_error_message(context, KRB5_CC_NOSUPP,
155*ae771770SStanislav Sedov 				   N_("Failed to find cc_initialize"
156*ae771770SStanislav Sedov 				      "in %s: %s", "file, error"), lib, dlerror());
157c19800e8SDoug Rabson 	dlclose(cc_handle);
158c19800e8SDoug Rabson 	return KRB5_CC_NOSUPP;
159c19800e8SDoug Rabson     }
160c19800e8SDoug Rabson 
161c19800e8SDoug Rabson     return 0;
162c19800e8SDoug Rabson #else
163c19800e8SDoug Rabson     HEIMDAL_MUTEX_unlock(&acc_mutex);
164*ae771770SStanislav Sedov     if (context)
165*ae771770SStanislav Sedov 	krb5_set_error_message(context, KRB5_CC_NOSUPP,
166*ae771770SStanislav Sedov 			       N_("no support for shared object", ""));
167c19800e8SDoug Rabson     return KRB5_CC_NOSUPP;
168c19800e8SDoug Rabson #endif
169c19800e8SDoug Rabson }
170c19800e8SDoug Rabson 
171*ae771770SStanislav Sedov void
_heim_krb5_ipc_client_set_target_uid(uid_t uid)172*ae771770SStanislav Sedov _heim_krb5_ipc_client_set_target_uid(uid_t uid)
173*ae771770SStanislav Sedov {
174*ae771770SStanislav Sedov     init_ccapi(NULL);
175*ae771770SStanislav Sedov     if (set_target_uid != NULL)
176*ae771770SStanislav Sedov         (*set_target_uid)(uid);
177*ae771770SStanislav Sedov }
178*ae771770SStanislav Sedov 
179*ae771770SStanislav Sedov void
_heim_krb5_ipc_client_clear_target(void)180*ae771770SStanislav Sedov _heim_krb5_ipc_client_clear_target(void)
181*ae771770SStanislav Sedov {
182*ae771770SStanislav Sedov     init_ccapi(NULL);
183*ae771770SStanislav Sedov     if (clear_target != NULL)
184*ae771770SStanislav Sedov         (*clear_target)();
185*ae771770SStanislav Sedov }
186*ae771770SStanislav Sedov 
187c19800e8SDoug Rabson static krb5_error_code
make_cred_from_ccred(krb5_context context,const cc_credentials_v5_t * incred,krb5_creds * cred)188c19800e8SDoug Rabson make_cred_from_ccred(krb5_context context,
189c19800e8SDoug Rabson 		     const cc_credentials_v5_t *incred,
190c19800e8SDoug Rabson 		     krb5_creds *cred)
191c19800e8SDoug Rabson {
192c19800e8SDoug Rabson     krb5_error_code ret;
193*ae771770SStanislav Sedov     unsigned int i;
194c19800e8SDoug Rabson 
195c19800e8SDoug Rabson     memset(cred, 0, sizeof(*cred));
196c19800e8SDoug Rabson 
197c19800e8SDoug Rabson     ret = krb5_parse_name(context, incred->client, &cred->client);
198c19800e8SDoug Rabson     if (ret)
199c19800e8SDoug Rabson 	goto fail;
200c19800e8SDoug Rabson 
201c19800e8SDoug Rabson     ret = krb5_parse_name(context, incred->server, &cred->server);
202c19800e8SDoug Rabson     if (ret)
203c19800e8SDoug Rabson 	goto fail;
204c19800e8SDoug Rabson 
205c19800e8SDoug Rabson     cred->session.keytype = incred->keyblock.type;
206c19800e8SDoug Rabson     cred->session.keyvalue.length = incred->keyblock.length;
207c19800e8SDoug Rabson     cred->session.keyvalue.data = malloc(incred->keyblock.length);
208c19800e8SDoug Rabson     if (cred->session.keyvalue.data == NULL)
209c19800e8SDoug Rabson 	goto nomem;
210c19800e8SDoug Rabson     memcpy(cred->session.keyvalue.data, incred->keyblock.data,
211c19800e8SDoug Rabson 	   incred->keyblock.length);
212c19800e8SDoug Rabson 
213c19800e8SDoug Rabson     cred->times.authtime = incred->authtime;
214c19800e8SDoug Rabson     cred->times.starttime = incred->starttime;
215c19800e8SDoug Rabson     cred->times.endtime = incred->endtime;
216c19800e8SDoug Rabson     cred->times.renew_till = incred->renew_till;
217c19800e8SDoug Rabson 
218c19800e8SDoug Rabson     ret = krb5_data_copy(&cred->ticket,
219c19800e8SDoug Rabson 			 incred->ticket.data,
220c19800e8SDoug Rabson 			 incred->ticket.length);
221c19800e8SDoug Rabson     if (ret)
222c19800e8SDoug Rabson 	goto nomem;
223c19800e8SDoug Rabson 
224c19800e8SDoug Rabson     ret = krb5_data_copy(&cred->second_ticket,
225c19800e8SDoug Rabson 			 incred->second_ticket.data,
226c19800e8SDoug Rabson 			 incred->second_ticket.length);
227c19800e8SDoug Rabson     if (ret)
228c19800e8SDoug Rabson 	goto nomem;
229c19800e8SDoug Rabson 
230c19800e8SDoug Rabson     cred->authdata.val = NULL;
231c19800e8SDoug Rabson     cred->authdata.len = 0;
232c19800e8SDoug Rabson 
233c19800e8SDoug Rabson     cred->addresses.val = NULL;
234c19800e8SDoug Rabson     cred->addresses.len = 0;
235c19800e8SDoug Rabson 
236c19800e8SDoug Rabson     for (i = 0; incred->authdata && incred->authdata[i]; i++)
237c19800e8SDoug Rabson 	;
238c19800e8SDoug Rabson 
239c19800e8SDoug Rabson     if (i) {
240c19800e8SDoug Rabson 	cred->authdata.val = calloc(i, sizeof(cred->authdata.val[0]));
241c19800e8SDoug Rabson 	if (cred->authdata.val == NULL)
242c19800e8SDoug Rabson 	    goto nomem;
243c19800e8SDoug Rabson 	cred->authdata.len = i;
244c19800e8SDoug Rabson 	for (i = 0; i < cred->authdata.len; i++) {
245c19800e8SDoug Rabson 	    cred->authdata.val[i].ad_type = incred->authdata[i]->type;
246c19800e8SDoug Rabson 	    ret = krb5_data_copy(&cred->authdata.val[i].ad_data,
247c19800e8SDoug Rabson 				 incred->authdata[i]->data,
248c19800e8SDoug Rabson 				 incred->authdata[i]->length);
249c19800e8SDoug Rabson 	    if (ret)
250c19800e8SDoug Rabson 		goto nomem;
251c19800e8SDoug Rabson 	}
252c19800e8SDoug Rabson     }
253c19800e8SDoug Rabson 
254c19800e8SDoug Rabson     for (i = 0; incred->addresses && incred->addresses[i]; i++)
255c19800e8SDoug Rabson 	;
256c19800e8SDoug Rabson 
257c19800e8SDoug Rabson     if (i) {
258c19800e8SDoug Rabson 	cred->addresses.val = calloc(i, sizeof(cred->addresses.val[0]));
259c19800e8SDoug Rabson 	if (cred->addresses.val == NULL)
260c19800e8SDoug Rabson 	    goto nomem;
261c19800e8SDoug Rabson 	cred->addresses.len = i;
262c19800e8SDoug Rabson 
263c19800e8SDoug Rabson 	for (i = 0; i < cred->addresses.len; i++) {
264c19800e8SDoug Rabson 	    cred->addresses.val[i].addr_type = incred->addresses[i]->type;
265c19800e8SDoug Rabson 	    ret = krb5_data_copy(&cred->addresses.val[i].address,
266c19800e8SDoug Rabson 				 incred->addresses[i]->data,
267c19800e8SDoug Rabson 				 incred->addresses[i]->length);
268c19800e8SDoug Rabson 	    if (ret)
269c19800e8SDoug Rabson 		goto nomem;
270c19800e8SDoug Rabson 	}
271c19800e8SDoug Rabson     }
272c19800e8SDoug Rabson 
273c19800e8SDoug Rabson     cred->flags.i = 0;
274c19800e8SDoug Rabson     if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_FORWARDABLE)
275c19800e8SDoug Rabson 	cred->flags.b.forwardable = 1;
276c19800e8SDoug Rabson     if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_FORWARDED)
277c19800e8SDoug Rabson 	cred->flags.b.forwarded = 1;
278c19800e8SDoug Rabson     if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_PROXIABLE)
279c19800e8SDoug Rabson 	cred->flags.b.proxiable = 1;
280c19800e8SDoug Rabson     if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_PROXY)
281c19800e8SDoug Rabson 	cred->flags.b.proxy = 1;
282c19800e8SDoug Rabson     if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_MAY_POSTDATE)
283c19800e8SDoug Rabson 	cred->flags.b.may_postdate = 1;
284c19800e8SDoug Rabson     if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_POSTDATED)
285c19800e8SDoug Rabson 	cred->flags.b.postdated = 1;
286c19800e8SDoug Rabson     if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_INVALID)
287c19800e8SDoug Rabson 	cred->flags.b.invalid = 1;
288c19800e8SDoug Rabson     if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_RENEWABLE)
289c19800e8SDoug Rabson 	cred->flags.b.renewable = 1;
290c19800e8SDoug Rabson     if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_INITIAL)
291c19800e8SDoug Rabson 	cred->flags.b.initial = 1;
292c19800e8SDoug Rabson     if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_PRE_AUTH)
293c19800e8SDoug Rabson 	cred->flags.b.pre_authent = 1;
294c19800e8SDoug Rabson     if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_HW_AUTH)
295c19800e8SDoug Rabson 	cred->flags.b.hw_authent = 1;
296c19800e8SDoug Rabson     if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_TRANSIT_POLICY_CHECKED)
297c19800e8SDoug Rabson 	cred->flags.b.transited_policy_checked = 1;
298c19800e8SDoug Rabson     if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_OK_AS_DELEGATE)
299c19800e8SDoug Rabson 	cred->flags.b.ok_as_delegate = 1;
300c19800e8SDoug Rabson     if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_ANONYMOUS)
301c19800e8SDoug Rabson 	cred->flags.b.anonymous = 1;
302c19800e8SDoug Rabson 
303c19800e8SDoug Rabson     return 0;
304c19800e8SDoug Rabson 
305c19800e8SDoug Rabson nomem:
306c19800e8SDoug Rabson     ret = ENOMEM;
307*ae771770SStanislav Sedov     krb5_set_error_message(context, ret, N_("malloc: out of memory", "malloc"));
308c19800e8SDoug Rabson 
309c19800e8SDoug Rabson fail:
310c19800e8SDoug Rabson     krb5_free_cred_contents(context, cred);
311c19800e8SDoug Rabson     return ret;
312c19800e8SDoug Rabson }
313c19800e8SDoug Rabson 
314c19800e8SDoug Rabson static void
free_ccred(cc_credentials_v5_t * cred)315c19800e8SDoug Rabson free_ccred(cc_credentials_v5_t *cred)
316c19800e8SDoug Rabson {
317c19800e8SDoug Rabson     int i;
318c19800e8SDoug Rabson 
319c19800e8SDoug Rabson     if (cred->addresses) {
320c19800e8SDoug Rabson 	for (i = 0; cred->addresses[i] != 0; i++) {
321c19800e8SDoug Rabson 	    if (cred->addresses[i]->data)
322c19800e8SDoug Rabson 		free(cred->addresses[i]->data);
323c19800e8SDoug Rabson 	    free(cred->addresses[i]);
324c19800e8SDoug Rabson 	}
325c19800e8SDoug Rabson 	free(cred->addresses);
326c19800e8SDoug Rabson     }
327c19800e8SDoug Rabson     if (cred->server)
328c19800e8SDoug Rabson 	free(cred->server);
329c19800e8SDoug Rabson     if (cred->client)
330c19800e8SDoug Rabson 	free(cred->client);
331c19800e8SDoug Rabson     memset(cred, 0, sizeof(*cred));
332c19800e8SDoug Rabson }
333c19800e8SDoug Rabson 
334c19800e8SDoug Rabson static krb5_error_code
make_ccred_from_cred(krb5_context context,const krb5_creds * incred,cc_credentials_v5_t * cred)335c19800e8SDoug Rabson make_ccred_from_cred(krb5_context context,
336c19800e8SDoug Rabson 		     const krb5_creds *incred,
337c19800e8SDoug Rabson 		     cc_credentials_v5_t *cred)
338c19800e8SDoug Rabson {
339c19800e8SDoug Rabson     krb5_error_code ret;
340*ae771770SStanislav Sedov     size_t i;
341c19800e8SDoug Rabson 
342c19800e8SDoug Rabson     memset(cred, 0, sizeof(*cred));
343c19800e8SDoug Rabson 
344c19800e8SDoug Rabson     ret = krb5_unparse_name(context, incred->client, &cred->client);
345c19800e8SDoug Rabson     if (ret)
346c19800e8SDoug Rabson 	goto fail;
347c19800e8SDoug Rabson 
348c19800e8SDoug Rabson     ret = krb5_unparse_name(context, incred->server, &cred->server);
349c19800e8SDoug Rabson     if (ret)
350c19800e8SDoug Rabson 	goto fail;
351c19800e8SDoug Rabson 
352c19800e8SDoug Rabson     cred->keyblock.type = incred->session.keytype;
353c19800e8SDoug Rabson     cred->keyblock.length = incred->session.keyvalue.length;
354c19800e8SDoug Rabson     cred->keyblock.data = incred->session.keyvalue.data;
355c19800e8SDoug Rabson 
356c19800e8SDoug Rabson     cred->authtime = incred->times.authtime;
357c19800e8SDoug Rabson     cred->starttime = incred->times.starttime;
358c19800e8SDoug Rabson     cred->endtime = incred->times.endtime;
359c19800e8SDoug Rabson     cred->renew_till = incred->times.renew_till;
360c19800e8SDoug Rabson 
361c19800e8SDoug Rabson     cred->ticket.length = incred->ticket.length;
362c19800e8SDoug Rabson     cred->ticket.data = incred->ticket.data;
363c19800e8SDoug Rabson 
364c19800e8SDoug Rabson     cred->second_ticket.length = incred->second_ticket.length;
365c19800e8SDoug Rabson     cred->second_ticket.data = incred->second_ticket.data;
366c19800e8SDoug Rabson 
367c19800e8SDoug Rabson     /* XXX this one should also be filled in */
368c19800e8SDoug Rabson     cred->authdata = NULL;
369c19800e8SDoug Rabson 
370c19800e8SDoug Rabson     cred->addresses = calloc(incred->addresses.len + 1,
371c19800e8SDoug Rabson 			     sizeof(cred->addresses[0]));
372c19800e8SDoug Rabson     if (cred->addresses == NULL) {
373c19800e8SDoug Rabson 
374c19800e8SDoug Rabson 	ret = ENOMEM;
375c19800e8SDoug Rabson 	goto fail;
376c19800e8SDoug Rabson     }
377c19800e8SDoug Rabson 
378c19800e8SDoug Rabson     for (i = 0; i < incred->addresses.len; i++) {
379c19800e8SDoug Rabson 	cc_data *addr;
380c19800e8SDoug Rabson 	addr = malloc(sizeof(*addr));
381c19800e8SDoug Rabson 	if (addr == NULL) {
382c19800e8SDoug Rabson 	    ret = ENOMEM;
383c19800e8SDoug Rabson 	    goto fail;
384c19800e8SDoug Rabson 	}
385c19800e8SDoug Rabson 	addr->type = incred->addresses.val[i].addr_type;
386c19800e8SDoug Rabson 	addr->length = incred->addresses.val[i].address.length;
387c19800e8SDoug Rabson 	addr->data = malloc(addr->length);
388c19800e8SDoug Rabson 	if (addr->data == NULL) {
389*ae771770SStanislav Sedov 	    free(addr);
390c19800e8SDoug Rabson 	    ret = ENOMEM;
391c19800e8SDoug Rabson 	    goto fail;
392c19800e8SDoug Rabson 	}
393c19800e8SDoug Rabson 	memcpy(addr->data, incred->addresses.val[i].address.data,
394c19800e8SDoug Rabson 	       addr->length);
395c19800e8SDoug Rabson 	cred->addresses[i] = addr;
396c19800e8SDoug Rabson     }
397c19800e8SDoug Rabson     cred->addresses[i] = NULL;
398c19800e8SDoug Rabson 
399c19800e8SDoug Rabson     cred->ticket_flags = 0;
400c19800e8SDoug Rabson     if (incred->flags.b.forwardable)
401c19800e8SDoug Rabson 	cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_FORWARDABLE;
402c19800e8SDoug Rabson     if (incred->flags.b.forwarded)
403c19800e8SDoug Rabson 	cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_FORWARDED;
404c19800e8SDoug Rabson     if (incred->flags.b.proxiable)
405c19800e8SDoug Rabson 	cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_PROXIABLE;
406c19800e8SDoug Rabson     if (incred->flags.b.proxy)
407c19800e8SDoug Rabson 	cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_PROXY;
408c19800e8SDoug Rabson     if (incred->flags.b.may_postdate)
409c19800e8SDoug Rabson 	cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_MAY_POSTDATE;
410c19800e8SDoug Rabson     if (incred->flags.b.postdated)
411c19800e8SDoug Rabson 	cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_POSTDATED;
412c19800e8SDoug Rabson     if (incred->flags.b.invalid)
413c19800e8SDoug Rabson 	cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_INVALID;
414c19800e8SDoug Rabson     if (incred->flags.b.renewable)
415c19800e8SDoug Rabson 	cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_RENEWABLE;
416c19800e8SDoug Rabson     if (incred->flags.b.initial)
417c19800e8SDoug Rabson 	cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_INITIAL;
418c19800e8SDoug Rabson     if (incred->flags.b.pre_authent)
419c19800e8SDoug Rabson 	cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_PRE_AUTH;
420c19800e8SDoug Rabson     if (incred->flags.b.hw_authent)
421c19800e8SDoug Rabson 	cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_HW_AUTH;
422c19800e8SDoug Rabson     if (incred->flags.b.transited_policy_checked)
423c19800e8SDoug Rabson 	cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_TRANSIT_POLICY_CHECKED;
424c19800e8SDoug Rabson     if (incred->flags.b.ok_as_delegate)
425c19800e8SDoug Rabson 	cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_OK_AS_DELEGATE;
426c19800e8SDoug Rabson     if (incred->flags.b.anonymous)
427c19800e8SDoug Rabson 	cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_ANONYMOUS;
428c19800e8SDoug Rabson 
429c19800e8SDoug Rabson     return 0;
430c19800e8SDoug Rabson 
431c19800e8SDoug Rabson fail:
432c19800e8SDoug Rabson     free_ccred(cred);
433c19800e8SDoug Rabson 
434*ae771770SStanislav Sedov     krb5_clear_error_message(context);
435c19800e8SDoug Rabson     return ret;
436c19800e8SDoug Rabson }
437c19800e8SDoug Rabson 
438*ae771770SStanislav Sedov static cc_int32
get_cc_name(krb5_acc * a)439*ae771770SStanislav Sedov get_cc_name(krb5_acc *a)
440c19800e8SDoug Rabson {
441c19800e8SDoug Rabson     cc_string_t name;
442c19800e8SDoug Rabson     cc_int32 error;
443c19800e8SDoug Rabson 
444*ae771770SStanislav Sedov     error = (*a->ccache->func->get_name)(a->ccache, &name);
445c19800e8SDoug Rabson     if (error)
446*ae771770SStanislav Sedov 	return error;
447c19800e8SDoug Rabson 
448*ae771770SStanislav Sedov     a->cache_name = strdup(name->data);
449c19800e8SDoug Rabson     (*name->func->release)(name);
450*ae771770SStanislav Sedov     if (a->cache_name == NULL)
451*ae771770SStanislav Sedov 	return ccErrNoMem;
452*ae771770SStanislav Sedov     return ccNoError;
453c19800e8SDoug Rabson }
454c19800e8SDoug Rabson 
455c19800e8SDoug Rabson 
456*ae771770SStanislav Sedov static const char* KRB5_CALLCONV
acc_get_name(krb5_context context,krb5_ccache id)457c19800e8SDoug Rabson acc_get_name(krb5_context context,
458c19800e8SDoug Rabson 	     krb5_ccache id)
459c19800e8SDoug Rabson {
460c19800e8SDoug Rabson     krb5_acc *a = ACACHE(id);
461*ae771770SStanislav Sedov     int32_t error;
462*ae771770SStanislav Sedov 
463*ae771770SStanislav Sedov     if (a->cache_name == NULL) {
464*ae771770SStanislav Sedov 	krb5_error_code ret;
465*ae771770SStanislav Sedov 	krb5_principal principal;
466c19800e8SDoug Rabson 	char *name;
467c19800e8SDoug Rabson 
468*ae771770SStanislav Sedov 	ret = _krb5_get_default_principal_local(context, &principal);
469*ae771770SStanislav Sedov 	if (ret)
470*ae771770SStanislav Sedov 	    return NULL;
471*ae771770SStanislav Sedov 
472*ae771770SStanislav Sedov 	ret = krb5_unparse_name(context, principal, &name);
473*ae771770SStanislav Sedov 	krb5_free_principal(context, principal);
474*ae771770SStanislav Sedov 	if (ret)
475*ae771770SStanislav Sedov 	    return NULL;
476*ae771770SStanislav Sedov 
477*ae771770SStanislav Sedov 	error = (*a->context->func->create_new_ccache)(a->context,
478*ae771770SStanislav Sedov 						       cc_credentials_v5,
479*ae771770SStanislav Sedov 						       name,
480*ae771770SStanislav Sedov 						       &a->ccache);
481*ae771770SStanislav Sedov 	krb5_xfree(name);
482*ae771770SStanislav Sedov 	if (error)
483*ae771770SStanislav Sedov 	    return NULL;
484*ae771770SStanislav Sedov 
485*ae771770SStanislav Sedov 	error = get_cc_name(a);
486*ae771770SStanislav Sedov 	if (error)
487c19800e8SDoug Rabson 	    return NULL;
488c19800e8SDoug Rabson     }
489*ae771770SStanislav Sedov 
490*ae771770SStanislav Sedov     return a->cache_name;
491c19800e8SDoug Rabson }
492c19800e8SDoug Rabson 
493*ae771770SStanislav Sedov static krb5_error_code KRB5_CALLCONV
acc_alloc(krb5_context context,krb5_ccache * id)494c19800e8SDoug Rabson acc_alloc(krb5_context context, krb5_ccache *id)
495c19800e8SDoug Rabson {
496c19800e8SDoug Rabson     krb5_error_code ret;
497c19800e8SDoug Rabson     cc_int32 error;
498c19800e8SDoug Rabson     krb5_acc *a;
499c19800e8SDoug Rabson 
500c19800e8SDoug Rabson     ret = init_ccapi(context);
501c19800e8SDoug Rabson     if (ret)
502c19800e8SDoug Rabson 	return ret;
503c19800e8SDoug Rabson 
504c19800e8SDoug Rabson     ret = krb5_data_alloc(&(*id)->data, sizeof(*a));
505c19800e8SDoug Rabson     if (ret) {
506*ae771770SStanislav Sedov 	krb5_clear_error_message(context);
507c19800e8SDoug Rabson 	return ret;
508c19800e8SDoug Rabson     }
509c19800e8SDoug Rabson 
510c19800e8SDoug Rabson     a = ACACHE(*id);
511c19800e8SDoug Rabson 
512c19800e8SDoug Rabson     error = (*init_func)(&a->context, ccapi_version_3, NULL, NULL);
513c19800e8SDoug Rabson     if (error) {
514c19800e8SDoug Rabson 	krb5_data_free(&(*id)->data);
515c19800e8SDoug Rabson 	return translate_cc_error(context, error);
516c19800e8SDoug Rabson     }
517c19800e8SDoug Rabson 
518c19800e8SDoug Rabson     a->cache_name = NULL;
519c19800e8SDoug Rabson 
520c19800e8SDoug Rabson     return 0;
521c19800e8SDoug Rabson }
522c19800e8SDoug Rabson 
523*ae771770SStanislav Sedov static krb5_error_code KRB5_CALLCONV
acc_resolve(krb5_context context,krb5_ccache * id,const char * res)524c19800e8SDoug Rabson acc_resolve(krb5_context context, krb5_ccache *id, const char *res)
525c19800e8SDoug Rabson {
526c19800e8SDoug Rabson     krb5_error_code ret;
527c19800e8SDoug Rabson     cc_int32 error;
528c19800e8SDoug Rabson     krb5_acc *a;
529c19800e8SDoug Rabson 
530c19800e8SDoug Rabson     ret = acc_alloc(context, id);
531c19800e8SDoug Rabson     if (ret)
532c19800e8SDoug Rabson 	return ret;
533c19800e8SDoug Rabson 
534c19800e8SDoug Rabson     a = ACACHE(*id);
535c19800e8SDoug Rabson 
536*ae771770SStanislav Sedov     error = (*a->context->func->open_ccache)(a->context, res, &a->ccache);
537*ae771770SStanislav Sedov     if (error == ccNoError) {
538*ae771770SStanislav Sedov 	cc_time_t offset;
539*ae771770SStanislav Sedov 	error = get_cc_name(a);
540*ae771770SStanislav Sedov 	if (error != ccNoError) {
541c19800e8SDoug Rabson 	    acc_close(context, *id);
542c19800e8SDoug Rabson 	    *id = NULL;
543*ae771770SStanislav Sedov 	    return translate_cc_error(context, error);
544c19800e8SDoug Rabson 	}
545*ae771770SStanislav Sedov 
546*ae771770SStanislav Sedov 	error = (*a->ccache->func->get_kdc_time_offset)(a->ccache,
547*ae771770SStanislav Sedov 							cc_credentials_v5,
548*ae771770SStanislav Sedov 							&offset);
549*ae771770SStanislav Sedov 	if (error == 0)
550*ae771770SStanislav Sedov 	    context->kdc_sec_offset = offset;
551*ae771770SStanislav Sedov 
552c19800e8SDoug Rabson     } else if (error == ccErrCCacheNotFound) {
553c19800e8SDoug Rabson 	a->ccache = NULL;
554c19800e8SDoug Rabson 	a->cache_name = NULL;
555c19800e8SDoug Rabson     } else {
556c19800e8SDoug Rabson 	*id = NULL;
557c19800e8SDoug Rabson 	return translate_cc_error(context, error);
558c19800e8SDoug Rabson     }
559c19800e8SDoug Rabson 
560c19800e8SDoug Rabson     return 0;
561c19800e8SDoug Rabson }
562c19800e8SDoug Rabson 
563*ae771770SStanislav Sedov static krb5_error_code KRB5_CALLCONV
acc_gen_new(krb5_context context,krb5_ccache * id)564c19800e8SDoug Rabson acc_gen_new(krb5_context context, krb5_ccache *id)
565c19800e8SDoug Rabson {
566c19800e8SDoug Rabson     krb5_error_code ret;
567c19800e8SDoug Rabson     krb5_acc *a;
568c19800e8SDoug Rabson 
569c19800e8SDoug Rabson     ret = acc_alloc(context, id);
570c19800e8SDoug Rabson     if (ret)
571c19800e8SDoug Rabson 	return ret;
572c19800e8SDoug Rabson 
573c19800e8SDoug Rabson     a = ACACHE(*id);
574c19800e8SDoug Rabson 
575c19800e8SDoug Rabson     a->ccache = NULL;
576c19800e8SDoug Rabson     a->cache_name = NULL;
577c19800e8SDoug Rabson 
578c19800e8SDoug Rabson     return 0;
579c19800e8SDoug Rabson }
580c19800e8SDoug Rabson 
581*ae771770SStanislav Sedov static krb5_error_code KRB5_CALLCONV
acc_initialize(krb5_context context,krb5_ccache id,krb5_principal primary_principal)582c19800e8SDoug Rabson acc_initialize(krb5_context context,
583c19800e8SDoug Rabson 	       krb5_ccache id,
584c19800e8SDoug Rabson 	       krb5_principal primary_principal)
585c19800e8SDoug Rabson {
586c19800e8SDoug Rabson     krb5_acc *a = ACACHE(id);
587c19800e8SDoug Rabson     krb5_error_code ret;
588c19800e8SDoug Rabson     int32_t error;
589c19800e8SDoug Rabson     char *name;
590c19800e8SDoug Rabson 
591c19800e8SDoug Rabson     ret = krb5_unparse_name(context, primary_principal, &name);
592c19800e8SDoug Rabson     if (ret)
593c19800e8SDoug Rabson 	return ret;
594c19800e8SDoug Rabson 
595*ae771770SStanislav Sedov     if (a->cache_name == NULL) {
596c19800e8SDoug Rabson 	error = (*a->context->func->create_new_ccache)(a->context,
597c19800e8SDoug Rabson 						       cc_credentials_v5,
598c19800e8SDoug Rabson 						       name,
599c19800e8SDoug Rabson 						       &a->ccache);
600c19800e8SDoug Rabson 	free(name);
601*ae771770SStanislav Sedov 	if (error == ccNoError)
602*ae771770SStanislav Sedov 	    error = get_cc_name(a);
603*ae771770SStanislav Sedov     } else {
604*ae771770SStanislav Sedov 	cc_credentials_iterator_t iter;
605*ae771770SStanislav Sedov 	cc_credentials_t ccred;
606*ae771770SStanislav Sedov 
607*ae771770SStanislav Sedov 	error = (*a->ccache->func->new_credentials_iterator)(a->ccache, &iter);
608*ae771770SStanislav Sedov 	if (error) {
609*ae771770SStanislav Sedov 	    free(name);
610*ae771770SStanislav Sedov 	    return translate_cc_error(context, error);
611*ae771770SStanislav Sedov 	}
612*ae771770SStanislav Sedov 
613*ae771770SStanislav Sedov 	while (1) {
614*ae771770SStanislav Sedov 	    error = (*iter->func->next)(iter, &ccred);
615*ae771770SStanislav Sedov 	    if (error)
616*ae771770SStanislav Sedov 		break;
617*ae771770SStanislav Sedov 	    (*a->ccache->func->remove_credentials)(a->ccache, ccred);
618*ae771770SStanislav Sedov 	    (*ccred->func->release)(ccred);
619*ae771770SStanislav Sedov 	}
620*ae771770SStanislav Sedov 	(*iter->func->release)(iter);
621*ae771770SStanislav Sedov 
622*ae771770SStanislav Sedov 	error = (*a->ccache->func->set_principal)(a->ccache,
623*ae771770SStanislav Sedov 						  cc_credentials_v5,
624*ae771770SStanislav Sedov 						  name);
625*ae771770SStanislav Sedov     }
626*ae771770SStanislav Sedov 
627*ae771770SStanislav Sedov     if (error == 0 && context->kdc_sec_offset)
628*ae771770SStanislav Sedov 	error = (*a->ccache->func->set_kdc_time_offset)(a->ccache,
629*ae771770SStanislav Sedov 							cc_credentials_v5,
630*ae771770SStanislav Sedov 							context->kdc_sec_offset);
631c19800e8SDoug Rabson 
632c19800e8SDoug Rabson     return translate_cc_error(context, error);
633c19800e8SDoug Rabson }
634c19800e8SDoug Rabson 
635*ae771770SStanislav Sedov static krb5_error_code KRB5_CALLCONV
acc_close(krb5_context context,krb5_ccache id)636c19800e8SDoug Rabson acc_close(krb5_context context,
637c19800e8SDoug Rabson 	  krb5_ccache id)
638c19800e8SDoug Rabson {
639c19800e8SDoug Rabson     krb5_acc *a = ACACHE(id);
640c19800e8SDoug Rabson 
641c19800e8SDoug Rabson     if (a->ccache) {
642c19800e8SDoug Rabson 	(*a->ccache->func->release)(a->ccache);
643c19800e8SDoug Rabson 	a->ccache = NULL;
644c19800e8SDoug Rabson     }
645c19800e8SDoug Rabson     if (a->cache_name) {
646c19800e8SDoug Rabson 	free(a->cache_name);
647c19800e8SDoug Rabson 	a->cache_name = NULL;
648c19800e8SDoug Rabson     }
649*ae771770SStanislav Sedov     if (a->context) {
650c19800e8SDoug Rabson 	(*a->context->func->release)(a->context);
651c19800e8SDoug Rabson 	a->context = NULL;
652*ae771770SStanislav Sedov     }
653c19800e8SDoug Rabson     krb5_data_free(&id->data);
654c19800e8SDoug Rabson     return 0;
655c19800e8SDoug Rabson }
656c19800e8SDoug Rabson 
657*ae771770SStanislav Sedov static krb5_error_code KRB5_CALLCONV
acc_destroy(krb5_context context,krb5_ccache id)658c19800e8SDoug Rabson acc_destroy(krb5_context context,
659c19800e8SDoug Rabson 	    krb5_ccache id)
660c19800e8SDoug Rabson {
661c19800e8SDoug Rabson     krb5_acc *a = ACACHE(id);
662c19800e8SDoug Rabson     cc_int32 error = 0;
663c19800e8SDoug Rabson 
664c19800e8SDoug Rabson     if (a->ccache) {
665c19800e8SDoug Rabson 	error = (*a->ccache->func->destroy)(a->ccache);
666c19800e8SDoug Rabson 	a->ccache = NULL;
667c19800e8SDoug Rabson     }
668c19800e8SDoug Rabson     if (a->context) {
669c19800e8SDoug Rabson 	error = (a->context->func->release)(a->context);
670c19800e8SDoug Rabson 	a->context = NULL;
671c19800e8SDoug Rabson     }
672c19800e8SDoug Rabson     return translate_cc_error(context, error);
673c19800e8SDoug Rabson }
674c19800e8SDoug Rabson 
675*ae771770SStanislav Sedov static krb5_error_code KRB5_CALLCONV
acc_store_cred(krb5_context context,krb5_ccache id,krb5_creds * creds)676c19800e8SDoug Rabson acc_store_cred(krb5_context context,
677c19800e8SDoug Rabson 	       krb5_ccache id,
678c19800e8SDoug Rabson 	       krb5_creds *creds)
679c19800e8SDoug Rabson {
680c19800e8SDoug Rabson     krb5_acc *a = ACACHE(id);
681c19800e8SDoug Rabson     cc_credentials_union cred;
682c19800e8SDoug Rabson     cc_credentials_v5_t v5cred;
683c19800e8SDoug Rabson     krb5_error_code ret;
684c19800e8SDoug Rabson     cc_int32 error;
685c19800e8SDoug Rabson 
686c19800e8SDoug Rabson     if (a->ccache == NULL) {
687*ae771770SStanislav Sedov 	krb5_set_error_message(context, KRB5_CC_NOTFOUND,
688*ae771770SStanislav Sedov 			       N_("No API credential found", ""));
689c19800e8SDoug Rabson 	return KRB5_CC_NOTFOUND;
690c19800e8SDoug Rabson     }
691c19800e8SDoug Rabson 
692c19800e8SDoug Rabson     cred.version = cc_credentials_v5;
693c19800e8SDoug Rabson     cred.credentials.credentials_v5 = &v5cred;
694c19800e8SDoug Rabson 
695c19800e8SDoug Rabson     ret = make_ccred_from_cred(context,
696c19800e8SDoug Rabson 			       creds,
697c19800e8SDoug Rabson 			       &v5cred);
698c19800e8SDoug Rabson     if (ret)
699c19800e8SDoug Rabson 	return ret;
700c19800e8SDoug Rabson 
701c19800e8SDoug Rabson     error = (*a->ccache->func->store_credentials)(a->ccache, &cred);
702c19800e8SDoug Rabson     if (error)
703c19800e8SDoug Rabson 	ret = translate_cc_error(context, error);
704c19800e8SDoug Rabson 
705c19800e8SDoug Rabson     free_ccred(&v5cred);
706c19800e8SDoug Rabson 
707c19800e8SDoug Rabson     return ret;
708c19800e8SDoug Rabson }
709c19800e8SDoug Rabson 
710*ae771770SStanislav Sedov static krb5_error_code KRB5_CALLCONV
acc_get_principal(krb5_context context,krb5_ccache id,krb5_principal * principal)711c19800e8SDoug Rabson acc_get_principal(krb5_context context,
712c19800e8SDoug Rabson 		  krb5_ccache id,
713c19800e8SDoug Rabson 		  krb5_principal *principal)
714c19800e8SDoug Rabson {
715c19800e8SDoug Rabson     krb5_acc *a = ACACHE(id);
716c19800e8SDoug Rabson     krb5_error_code ret;
717c19800e8SDoug Rabson     int32_t error;
718c19800e8SDoug Rabson     cc_string_t name;
719c19800e8SDoug Rabson 
720c19800e8SDoug Rabson     if (a->ccache == NULL) {
721*ae771770SStanislav Sedov 	krb5_set_error_message(context, KRB5_CC_NOTFOUND,
722*ae771770SStanislav Sedov 			       N_("No API credential found", ""));
723c19800e8SDoug Rabson 	return KRB5_CC_NOTFOUND;
724c19800e8SDoug Rabson     }
725c19800e8SDoug Rabson 
726c19800e8SDoug Rabson     error = (*a->ccache->func->get_principal)(a->ccache,
727c19800e8SDoug Rabson 					      cc_credentials_v5,
728c19800e8SDoug Rabson 					      &name);
729c19800e8SDoug Rabson     if (error)
730c19800e8SDoug Rabson 	return translate_cc_error(context, error);
731c19800e8SDoug Rabson 
732c19800e8SDoug Rabson     ret = krb5_parse_name(context, name->data, principal);
733c19800e8SDoug Rabson 
734c19800e8SDoug Rabson     (*name->func->release)(name);
735c19800e8SDoug Rabson     return ret;
736c19800e8SDoug Rabson }
737c19800e8SDoug Rabson 
738*ae771770SStanislav Sedov static krb5_error_code KRB5_CALLCONV
acc_get_first(krb5_context context,krb5_ccache id,krb5_cc_cursor * cursor)739c19800e8SDoug Rabson acc_get_first (krb5_context context,
740c19800e8SDoug Rabson 	       krb5_ccache id,
741c19800e8SDoug Rabson 	       krb5_cc_cursor *cursor)
742c19800e8SDoug Rabson {
743c19800e8SDoug Rabson     cc_credentials_iterator_t iter;
744c19800e8SDoug Rabson     krb5_acc *a = ACACHE(id);
745c19800e8SDoug Rabson     int32_t error;
746c19800e8SDoug Rabson 
747c19800e8SDoug Rabson     if (a->ccache == NULL) {
748*ae771770SStanislav Sedov 	krb5_set_error_message(context, KRB5_CC_NOTFOUND,
749*ae771770SStanislav Sedov 			       N_("No API credential found", ""));
750c19800e8SDoug Rabson 	return KRB5_CC_NOTFOUND;
751c19800e8SDoug Rabson     }
752c19800e8SDoug Rabson 
753c19800e8SDoug Rabson     error = (*a->ccache->func->new_credentials_iterator)(a->ccache, &iter);
754c19800e8SDoug Rabson     if (error) {
755*ae771770SStanislav Sedov 	krb5_clear_error_message(context);
756c19800e8SDoug Rabson 	return ENOENT;
757c19800e8SDoug Rabson     }
758c19800e8SDoug Rabson     *cursor = iter;
759c19800e8SDoug Rabson     return 0;
760c19800e8SDoug Rabson }
761c19800e8SDoug Rabson 
762c19800e8SDoug Rabson 
763*ae771770SStanislav Sedov static krb5_error_code KRB5_CALLCONV
acc_get_next(krb5_context context,krb5_ccache id,krb5_cc_cursor * cursor,krb5_creds * creds)764c19800e8SDoug Rabson acc_get_next (krb5_context context,
765c19800e8SDoug Rabson 	      krb5_ccache id,
766c19800e8SDoug Rabson 	      krb5_cc_cursor *cursor,
767c19800e8SDoug Rabson 	      krb5_creds *creds)
768c19800e8SDoug Rabson {
769c19800e8SDoug Rabson     cc_credentials_iterator_t iter = *cursor;
770c19800e8SDoug Rabson     cc_credentials_t cred;
771c19800e8SDoug Rabson     krb5_error_code ret;
772c19800e8SDoug Rabson     int32_t error;
773c19800e8SDoug Rabson 
774c19800e8SDoug Rabson     while (1) {
775c19800e8SDoug Rabson 	error = (*iter->func->next)(iter, &cred);
776c19800e8SDoug Rabson 	if (error)
777c19800e8SDoug Rabson 	    return translate_cc_error(context, error);
778c19800e8SDoug Rabson 	if (cred->data->version == cc_credentials_v5)
779c19800e8SDoug Rabson 	    break;
780c19800e8SDoug Rabson 	(*cred->func->release)(cred);
781c19800e8SDoug Rabson     }
782c19800e8SDoug Rabson 
783c19800e8SDoug Rabson     ret = make_cred_from_ccred(context,
784c19800e8SDoug Rabson 			       cred->data->credentials.credentials_v5,
785c19800e8SDoug Rabson 			       creds);
786c19800e8SDoug Rabson     (*cred->func->release)(cred);
787c19800e8SDoug Rabson     return ret;
788c19800e8SDoug Rabson }
789c19800e8SDoug Rabson 
790*ae771770SStanislav Sedov static krb5_error_code KRB5_CALLCONV
acc_end_get(krb5_context context,krb5_ccache id,krb5_cc_cursor * cursor)791c19800e8SDoug Rabson acc_end_get (krb5_context context,
792c19800e8SDoug Rabson 	     krb5_ccache id,
793c19800e8SDoug Rabson 	     krb5_cc_cursor *cursor)
794c19800e8SDoug Rabson {
795c19800e8SDoug Rabson     cc_credentials_iterator_t iter = *cursor;
796c19800e8SDoug Rabson     (*iter->func->release)(iter);
797c19800e8SDoug Rabson     return 0;
798c19800e8SDoug Rabson }
799c19800e8SDoug Rabson 
800*ae771770SStanislav Sedov static krb5_error_code KRB5_CALLCONV
acc_remove_cred(krb5_context context,krb5_ccache id,krb5_flags which,krb5_creds * cred)801c19800e8SDoug Rabson acc_remove_cred(krb5_context context,
802c19800e8SDoug Rabson 		krb5_ccache id,
803c19800e8SDoug Rabson 		krb5_flags which,
804c19800e8SDoug Rabson 		krb5_creds *cred)
805c19800e8SDoug Rabson {
806c19800e8SDoug Rabson     cc_credentials_iterator_t iter;
807c19800e8SDoug Rabson     krb5_acc *a = ACACHE(id);
808c19800e8SDoug Rabson     cc_credentials_t ccred;
809c19800e8SDoug Rabson     krb5_error_code ret;
810c19800e8SDoug Rabson     cc_int32 error;
811c19800e8SDoug Rabson     char *client, *server;
812c19800e8SDoug Rabson 
813c19800e8SDoug Rabson     if (a->ccache == NULL) {
814*ae771770SStanislav Sedov 	krb5_set_error_message(context, KRB5_CC_NOTFOUND,
815*ae771770SStanislav Sedov 			       N_("No API credential found", ""));
816c19800e8SDoug Rabson 	return KRB5_CC_NOTFOUND;
817c19800e8SDoug Rabson     }
818c19800e8SDoug Rabson 
819c19800e8SDoug Rabson     if (cred->client) {
820c19800e8SDoug Rabson 	ret = krb5_unparse_name(context, cred->client, &client);
821c19800e8SDoug Rabson 	if (ret)
822c19800e8SDoug Rabson 	    return ret;
823c19800e8SDoug Rabson     } else
824c19800e8SDoug Rabson 	client = NULL;
825c19800e8SDoug Rabson 
826c19800e8SDoug Rabson     ret = krb5_unparse_name(context, cred->server, &server);
827c19800e8SDoug Rabson     if (ret) {
828c19800e8SDoug Rabson 	free(client);
829c19800e8SDoug Rabson 	return ret;
830c19800e8SDoug Rabson     }
831c19800e8SDoug Rabson 
832c19800e8SDoug Rabson     error = (*a->ccache->func->new_credentials_iterator)(a->ccache, &iter);
833c19800e8SDoug Rabson     if (error) {
834c19800e8SDoug Rabson 	free(server);
835c19800e8SDoug Rabson 	free(client);
836c19800e8SDoug Rabson 	return translate_cc_error(context, error);
837c19800e8SDoug Rabson     }
838c19800e8SDoug Rabson 
839c19800e8SDoug Rabson     ret = KRB5_CC_NOTFOUND;
840c19800e8SDoug Rabson     while (1) {
841c19800e8SDoug Rabson 	cc_credentials_v5_t *v5cred;
842c19800e8SDoug Rabson 
843c19800e8SDoug Rabson 	error = (*iter->func->next)(iter, &ccred);
844c19800e8SDoug Rabson 	if (error)
845c19800e8SDoug Rabson 	    break;
846c19800e8SDoug Rabson 
847c19800e8SDoug Rabson 	if (ccred->data->version != cc_credentials_v5)
848c19800e8SDoug Rabson 	    goto next;
849c19800e8SDoug Rabson 
850c19800e8SDoug Rabson 	v5cred = ccred->data->credentials.credentials_v5;
851c19800e8SDoug Rabson 
852c19800e8SDoug Rabson 	if (client && strcmp(v5cred->client, client) != 0)
853c19800e8SDoug Rabson 	    goto next;
854c19800e8SDoug Rabson 
855c19800e8SDoug Rabson 	if (strcmp(v5cred->server, server) != 0)
856c19800e8SDoug Rabson 	    goto next;
857c19800e8SDoug Rabson 
858c19800e8SDoug Rabson 	(*a->ccache->func->remove_credentials)(a->ccache, ccred);
859c19800e8SDoug Rabson 	ret = 0;
860c19800e8SDoug Rabson     next:
861c19800e8SDoug Rabson 	(*ccred->func->release)(ccred);
862c19800e8SDoug Rabson     }
863c19800e8SDoug Rabson 
864c19800e8SDoug Rabson     (*iter->func->release)(iter);
865c19800e8SDoug Rabson 
866c19800e8SDoug Rabson     if (ret)
867*ae771770SStanislav Sedov 	krb5_set_error_message(context, ret,
868*ae771770SStanislav Sedov 			       N_("Can't find credential %s in cache",
869*ae771770SStanislav Sedov 				 "principal"), server);
870c19800e8SDoug Rabson     free(server);
871c19800e8SDoug Rabson     free(client);
872c19800e8SDoug Rabson 
873c19800e8SDoug Rabson     return ret;
874c19800e8SDoug Rabson }
875c19800e8SDoug Rabson 
876*ae771770SStanislav Sedov static krb5_error_code KRB5_CALLCONV
acc_set_flags(krb5_context context,krb5_ccache id,krb5_flags flags)877c19800e8SDoug Rabson acc_set_flags(krb5_context context,
878c19800e8SDoug Rabson 	      krb5_ccache id,
879c19800e8SDoug Rabson 	      krb5_flags flags)
880c19800e8SDoug Rabson {
881c19800e8SDoug Rabson     return 0;
882c19800e8SDoug Rabson }
883c19800e8SDoug Rabson 
884*ae771770SStanislav Sedov static int KRB5_CALLCONV
acc_get_version(krb5_context context,krb5_ccache id)885c19800e8SDoug Rabson acc_get_version(krb5_context context,
886c19800e8SDoug Rabson 		krb5_ccache id)
887c19800e8SDoug Rabson {
888c19800e8SDoug Rabson     return 0;
889c19800e8SDoug Rabson }
890c19800e8SDoug Rabson 
891c19800e8SDoug Rabson struct cache_iter {
892c19800e8SDoug Rabson     cc_context_t context;
893c19800e8SDoug Rabson     cc_ccache_iterator_t iter;
894c19800e8SDoug Rabson };
895c19800e8SDoug Rabson 
896*ae771770SStanislav Sedov static krb5_error_code KRB5_CALLCONV
acc_get_cache_first(krb5_context context,krb5_cc_cursor * cursor)897c19800e8SDoug Rabson acc_get_cache_first(krb5_context context, krb5_cc_cursor *cursor)
898c19800e8SDoug Rabson {
899c19800e8SDoug Rabson     struct cache_iter *iter;
900c19800e8SDoug Rabson     krb5_error_code ret;
901c19800e8SDoug Rabson     cc_int32 error;
902c19800e8SDoug Rabson 
903c19800e8SDoug Rabson     ret = init_ccapi(context);
904c19800e8SDoug Rabson     if (ret)
905c19800e8SDoug Rabson 	return ret;
906c19800e8SDoug Rabson 
907c19800e8SDoug Rabson     iter = calloc(1, sizeof(*iter));
908c19800e8SDoug Rabson     if (iter == NULL) {
909*ae771770SStanislav Sedov 	krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
910c19800e8SDoug Rabson 	return ENOMEM;
911c19800e8SDoug Rabson     }
912c19800e8SDoug Rabson 
913c19800e8SDoug Rabson     error = (*init_func)(&iter->context, ccapi_version_3, NULL, NULL);
914c19800e8SDoug Rabson     if (error) {
915c19800e8SDoug Rabson 	free(iter);
916c19800e8SDoug Rabson 	return translate_cc_error(context, error);
917c19800e8SDoug Rabson     }
918c19800e8SDoug Rabson 
919c19800e8SDoug Rabson     error = (*iter->context->func->new_ccache_iterator)(iter->context,
920c19800e8SDoug Rabson 							&iter->iter);
921c19800e8SDoug Rabson     if (error) {
922c19800e8SDoug Rabson 	free(iter);
923*ae771770SStanislav Sedov 	krb5_clear_error_message(context);
924c19800e8SDoug Rabson 	return ENOENT;
925c19800e8SDoug Rabson     }
926c19800e8SDoug Rabson     *cursor = iter;
927c19800e8SDoug Rabson     return 0;
928c19800e8SDoug Rabson }
929c19800e8SDoug Rabson 
930*ae771770SStanislav Sedov static krb5_error_code KRB5_CALLCONV
acc_get_cache_next(krb5_context context,krb5_cc_cursor cursor,krb5_ccache * id)931c19800e8SDoug Rabson acc_get_cache_next(krb5_context context, krb5_cc_cursor cursor, krb5_ccache *id)
932c19800e8SDoug Rabson {
933c19800e8SDoug Rabson     struct cache_iter *iter = cursor;
934c19800e8SDoug Rabson     cc_ccache_t cache;
935c19800e8SDoug Rabson     krb5_acc *a;
936c19800e8SDoug Rabson     krb5_error_code ret;
937c19800e8SDoug Rabson     int32_t error;
938c19800e8SDoug Rabson 
939c19800e8SDoug Rabson     error = (*iter->iter->func->next)(iter->iter, &cache);
940c19800e8SDoug Rabson     if (error)
941c19800e8SDoug Rabson 	return translate_cc_error(context, error);
942c19800e8SDoug Rabson 
943c19800e8SDoug Rabson     ret = _krb5_cc_allocate(context, &krb5_acc_ops, id);
944c19800e8SDoug Rabson     if (ret) {
945c19800e8SDoug Rabson 	(*cache->func->release)(cache);
946c19800e8SDoug Rabson 	return ret;
947c19800e8SDoug Rabson     }
948c19800e8SDoug Rabson 
949c19800e8SDoug Rabson     ret = acc_alloc(context, id);
950c19800e8SDoug Rabson     if (ret) {
951c19800e8SDoug Rabson 	(*cache->func->release)(cache);
952c19800e8SDoug Rabson 	free(*id);
953c19800e8SDoug Rabson 	return ret;
954c19800e8SDoug Rabson     }
955c19800e8SDoug Rabson 
956c19800e8SDoug Rabson     a = ACACHE(*id);
957c19800e8SDoug Rabson     a->ccache = cache;
958c19800e8SDoug Rabson 
959*ae771770SStanislav Sedov     error = get_cc_name(a);
960*ae771770SStanislav Sedov     if (error) {
961c19800e8SDoug Rabson 	acc_close(context, *id);
962c19800e8SDoug Rabson 	*id = NULL;
963*ae771770SStanislav Sedov 	return translate_cc_error(context, error);
964c19800e8SDoug Rabson     }
965c19800e8SDoug Rabson     return 0;
966c19800e8SDoug Rabson }
967c19800e8SDoug Rabson 
968*ae771770SStanislav Sedov static krb5_error_code KRB5_CALLCONV
acc_end_cache_get(krb5_context context,krb5_cc_cursor cursor)969c19800e8SDoug Rabson acc_end_cache_get(krb5_context context, krb5_cc_cursor cursor)
970c19800e8SDoug Rabson {
971c19800e8SDoug Rabson     struct cache_iter *iter = cursor;
972c19800e8SDoug Rabson 
973c19800e8SDoug Rabson     (*iter->iter->func->release)(iter->iter);
974c19800e8SDoug Rabson     iter->iter = NULL;
975c19800e8SDoug Rabson     (*iter->context->func->release)(iter->context);
976c19800e8SDoug Rabson     iter->context = NULL;
977c19800e8SDoug Rabson     free(iter);
978c19800e8SDoug Rabson     return 0;
979c19800e8SDoug Rabson }
980c19800e8SDoug Rabson 
981*ae771770SStanislav Sedov static krb5_error_code KRB5_CALLCONV
acc_move(krb5_context context,krb5_ccache from,krb5_ccache to)982c19800e8SDoug Rabson acc_move(krb5_context context, krb5_ccache from, krb5_ccache to)
983c19800e8SDoug Rabson {
984c19800e8SDoug Rabson     krb5_acc *afrom = ACACHE(from);
985c19800e8SDoug Rabson     krb5_acc *ato = ACACHE(to);
986c19800e8SDoug Rabson     int32_t error;
987c19800e8SDoug Rabson 
988c19800e8SDoug Rabson     if (ato->ccache == NULL) {
989c19800e8SDoug Rabson 	cc_string_t name;
990c19800e8SDoug Rabson 
991c19800e8SDoug Rabson 	error = (*afrom->ccache->func->get_principal)(afrom->ccache,
992c19800e8SDoug Rabson 						      cc_credentials_v5,
993c19800e8SDoug Rabson 						      &name);
994c19800e8SDoug Rabson 	if (error)
995c19800e8SDoug Rabson 	    return translate_cc_error(context, error);
996c19800e8SDoug Rabson 
997c19800e8SDoug Rabson 	error = (*ato->context->func->create_new_ccache)(ato->context,
998c19800e8SDoug Rabson 							 cc_credentials_v5,
999c19800e8SDoug Rabson 							 name->data,
1000c19800e8SDoug Rabson 							 &ato->ccache);
1001c19800e8SDoug Rabson 	(*name->func->release)(name);
1002c19800e8SDoug Rabson 	if (error)
1003c19800e8SDoug Rabson 	    return translate_cc_error(context, error);
1004c19800e8SDoug Rabson     }
1005c19800e8SDoug Rabson 
1006c19800e8SDoug Rabson     error = (*ato->ccache->func->move)(afrom->ccache, ato->ccache);
1007*ae771770SStanislav Sedov 
1008*ae771770SStanislav Sedov     acc_destroy(context, from);
1009*ae771770SStanislav Sedov 
1010c19800e8SDoug Rabson     return translate_cc_error(context, error);
1011c19800e8SDoug Rabson }
1012c19800e8SDoug Rabson 
1013*ae771770SStanislav Sedov static krb5_error_code KRB5_CALLCONV
acc_get_default_name(krb5_context context,char ** str)1014*ae771770SStanislav Sedov acc_get_default_name(krb5_context context, char **str)
1015c19800e8SDoug Rabson {
1016c19800e8SDoug Rabson     krb5_error_code ret;
1017c19800e8SDoug Rabson     cc_context_t cc;
1018c19800e8SDoug Rabson     cc_string_t name;
1019c19800e8SDoug Rabson     int32_t error;
1020c19800e8SDoug Rabson 
1021c19800e8SDoug Rabson     ret = init_ccapi(context);
1022c19800e8SDoug Rabson     if (ret)
1023c19800e8SDoug Rabson 	return ret;
1024c19800e8SDoug Rabson 
1025c19800e8SDoug Rabson     error = (*init_func)(&cc, ccapi_version_3, NULL, NULL);
1026c19800e8SDoug Rabson     if (error)
1027c19800e8SDoug Rabson 	return translate_cc_error(context, error);
1028c19800e8SDoug Rabson 
1029c19800e8SDoug Rabson     error = (*cc->func->get_default_ccache_name)(cc, &name);
1030c19800e8SDoug Rabson     if (error) {
1031c19800e8SDoug Rabson 	(*cc->func->release)(cc);
1032c19800e8SDoug Rabson 	return translate_cc_error(context, error);
1033c19800e8SDoug Rabson     }
1034c19800e8SDoug Rabson 
1035*ae771770SStanislav Sedov     error = asprintf(str, "API:%s", name->data);
1036c19800e8SDoug Rabson     (*name->func->release)(name);
1037c19800e8SDoug Rabson     (*cc->func->release)(cc);
1038c19800e8SDoug Rabson 
1039*ae771770SStanislav Sedov     if (error < 0 || *str == NULL) {
1040*ae771770SStanislav Sedov 	krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
1041c19800e8SDoug Rabson 	return ENOMEM;
1042c19800e8SDoug Rabson     }
1043c19800e8SDoug Rabson     return 0;
1044c19800e8SDoug Rabson }
1045c19800e8SDoug Rabson 
1046*ae771770SStanislav Sedov static krb5_error_code KRB5_CALLCONV
acc_set_default(krb5_context context,krb5_ccache id)1047*ae771770SStanislav Sedov acc_set_default(krb5_context context, krb5_ccache id)
1048*ae771770SStanislav Sedov {
1049*ae771770SStanislav Sedov     krb5_acc *a = ACACHE(id);
1050*ae771770SStanislav Sedov     cc_int32 error;
1051*ae771770SStanislav Sedov 
1052*ae771770SStanislav Sedov     if (a->ccache == NULL) {
1053*ae771770SStanislav Sedov 	krb5_set_error_message(context, KRB5_CC_NOTFOUND,
1054*ae771770SStanislav Sedov 			       N_("No API credential found", ""));
1055*ae771770SStanislav Sedov 	return KRB5_CC_NOTFOUND;
1056*ae771770SStanislav Sedov     }
1057*ae771770SStanislav Sedov 
1058*ae771770SStanislav Sedov     error = (*a->ccache->func->set_default)(a->ccache);
1059*ae771770SStanislav Sedov     if (error)
1060*ae771770SStanislav Sedov 	return translate_cc_error(context, error);
1061*ae771770SStanislav Sedov 
1062*ae771770SStanislav Sedov     return 0;
1063*ae771770SStanislav Sedov }
1064*ae771770SStanislav Sedov 
1065*ae771770SStanislav Sedov static krb5_error_code KRB5_CALLCONV
acc_lastchange(krb5_context context,krb5_ccache id,krb5_timestamp * mtime)1066*ae771770SStanislav Sedov acc_lastchange(krb5_context context, krb5_ccache id, krb5_timestamp *mtime)
1067*ae771770SStanislav Sedov {
1068*ae771770SStanislav Sedov     krb5_acc *a = ACACHE(id);
1069*ae771770SStanislav Sedov     cc_int32 error;
1070*ae771770SStanislav Sedov     cc_time_t t;
1071*ae771770SStanislav Sedov 
1072*ae771770SStanislav Sedov     if (a->ccache == NULL) {
1073*ae771770SStanislav Sedov 	krb5_set_error_message(context, KRB5_CC_NOTFOUND,
1074*ae771770SStanislav Sedov 			       N_("No API credential found", ""));
1075*ae771770SStanislav Sedov 	return KRB5_CC_NOTFOUND;
1076*ae771770SStanislav Sedov     }
1077*ae771770SStanislav Sedov 
1078*ae771770SStanislav Sedov     error = (*a->ccache->func->get_change_time)(a->ccache, &t);
1079*ae771770SStanislav Sedov     if (error)
1080*ae771770SStanislav Sedov 	return translate_cc_error(context, error);
1081*ae771770SStanislav Sedov 
1082*ae771770SStanislav Sedov     *mtime = t;
1083*ae771770SStanislav Sedov 
1084*ae771770SStanislav Sedov     return 0;
1085*ae771770SStanislav Sedov }
1086c19800e8SDoug Rabson 
1087c19800e8SDoug Rabson /**
1088c19800e8SDoug Rabson  * Variable containing the API based credential cache implemention.
1089c19800e8SDoug Rabson  *
1090c19800e8SDoug Rabson  * @ingroup krb5_ccache
1091c19800e8SDoug Rabson  */
1092c19800e8SDoug Rabson 
1093*ae771770SStanislav Sedov KRB5_LIB_VARIABLE const krb5_cc_ops krb5_acc_ops = {
1094*ae771770SStanislav Sedov     KRB5_CC_OPS_VERSION,
1095c19800e8SDoug Rabson     "API",
1096c19800e8SDoug Rabson     acc_get_name,
1097c19800e8SDoug Rabson     acc_resolve,
1098c19800e8SDoug Rabson     acc_gen_new,
1099c19800e8SDoug Rabson     acc_initialize,
1100c19800e8SDoug Rabson     acc_destroy,
1101c19800e8SDoug Rabson     acc_close,
1102c19800e8SDoug Rabson     acc_store_cred,
1103c19800e8SDoug Rabson     NULL, /* acc_retrieve */
1104c19800e8SDoug Rabson     acc_get_principal,
1105c19800e8SDoug Rabson     acc_get_first,
1106c19800e8SDoug Rabson     acc_get_next,
1107c19800e8SDoug Rabson     acc_end_get,
1108c19800e8SDoug Rabson     acc_remove_cred,
1109c19800e8SDoug Rabson     acc_set_flags,
1110c19800e8SDoug Rabson     acc_get_version,
1111c19800e8SDoug Rabson     acc_get_cache_first,
1112c19800e8SDoug Rabson     acc_get_cache_next,
1113c19800e8SDoug Rabson     acc_end_cache_get,
1114c19800e8SDoug Rabson     acc_move,
1115*ae771770SStanislav Sedov     acc_get_default_name,
1116*ae771770SStanislav Sedov     acc_set_default,
1117*ae771770SStanislav Sedov     acc_lastchange,
1118*ae771770SStanislav Sedov     NULL,
1119*ae771770SStanislav Sedov     NULL,
1120c19800e8SDoug Rabson };
1121*ae771770SStanislav Sedov 
1122*ae771770SStanislav Sedov #endif
1123