2 * Copyright (c) 2004 - 2007 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the Institute nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 #include "krb5_locl.h"
37 #include <krb5_ccapi.h>
42 #ifndef KCM_IS_API_CACHE
44 static HEIMDAL_MUTEX acc_mutex
= HEIMDAL_MUTEX_INITIALIZER
;
45 static cc_initialize_func init_func
;
46 static void (KRB5_CALLCONV
*set_target_uid
)(uid_t
);
47 static void (KRB5_CALLCONV
*clear_target
)(void);
50 static void *cc_handle
;
53 typedef struct krb5_acc
{
59 static krb5_error_code KRB5_CALLCONV
acc_close(krb5_context
, krb5_ccache
);
61 #define ACACHE(X) ((krb5_acc *)(X)->data.data)
67 { ccErrBadName
, KRB5_CC_BADNAME
},
68 { ccErrCredentialsNotFound
, KRB5_CC_NOTFOUND
},
69 { ccErrCCacheNotFound
, KRB5_FCC_NOFILE
},
70 { ccErrContextNotFound
, KRB5_CC_NOTFOUND
},
71 { ccIteratorEnd
, KRB5_CC_END
},
72 { ccErrNoMem
, KRB5_CC_NOMEM
},
73 { ccErrServerUnavailable
, KRB5_CC_NOSUPP
},
74 { ccErrInvalidCCache
, KRB5_CC_BADNAME
},
78 static krb5_error_code
79 translate_cc_error(krb5_context context
, cc_int32 error
)
82 krb5_clear_error_message(context
);
83 for(i
= 0; i
< sizeof(cc_errors
)/sizeof(cc_errors
[0]); i
++)
84 if (cc_errors
[i
].error
== error
)
85 return cc_errors
[i
].ret
;
86 return KRB5_FCC_INTERNAL
;
89 static krb5_error_code
90 init_ccapi(krb5_context context
)
92 const char *lib
= NULL
;
94 HEIMDAL_MUTEX_lock(&acc_mutex
);
96 HEIMDAL_MUTEX_unlock(&acc_mutex
);
98 krb5_clear_error_message(context
);
103 lib
= krb5_config_get_string(context
, NULL
,
104 "libdefaults", "ccapi_library",
108 lib
= "/System/Library/Frameworks/Kerberos.framework/Kerberos";
109 #elif defined(KRB5_USE_PATH_TOKENS) && defined(_WIN32)
110 lib
= "%{LIBDIR}/libkrb5_cc.dll";
112 lib
= "/usr/lib/libkrb5_cc.so";
125 #ifdef KRB5_USE_PATH_TOKENS
127 char * explib
= NULL
;
128 if (_krb5_expand_path_tokens(context
, lib
, &explib
) == 0) {
129 cc_handle
= dlopen(explib
, RTLD_LAZY
|RTLD_LOCAL
);
134 cc_handle
= dlopen(lib
, RTLD_LAZY
|RTLD_LOCAL
);
137 if (cc_handle
== NULL
) {
138 HEIMDAL_MUTEX_unlock(&acc_mutex
);
140 krb5_set_error_message(context
, KRB5_CC_NOSUPP
,
141 N_("Failed to load API cache module %s", "file"),
143 return KRB5_CC_NOSUPP
;
146 init_func
= (cc_initialize_func
)dlsym(cc_handle
, "cc_initialize");
147 set_target_uid
= (void (KRB5_CALLCONV
*)(uid_t
))
148 dlsym(cc_handle
, "krb5_ipc_client_set_target_uid");
149 clear_target
= (void (KRB5_CALLCONV
*)(void))
150 dlsym(cc_handle
, "krb5_ipc_client_clear_target");
151 HEIMDAL_MUTEX_unlock(&acc_mutex
);
152 if (init_func
== NULL
) {
154 krb5_set_error_message(context
, KRB5_CC_NOSUPP
,
155 N_("Failed to find cc_initialize"
156 "in %s: %s", "file, error"), lib
, dlerror());
158 return KRB5_CC_NOSUPP
;
163 HEIMDAL_MUTEX_unlock(&acc_mutex
);
165 krb5_set_error_message(context
, KRB5_CC_NOSUPP
,
166 N_("no support for shared object", ""));
167 return KRB5_CC_NOSUPP
;
171 KRB5_LIB_FUNCTION
void KRB5_LIB_CALL
172 _heim_krb5_ipc_client_set_target_uid(uid_t uid
)
175 if (set_target_uid
!= NULL
)
176 (*set_target_uid
)(uid
);
179 KRB5_LIB_FUNCTION
void KRB5_LIB_CALL
180 _heim_krb5_ipc_client_clear_target(void)
183 if (clear_target
!= NULL
)
187 static krb5_error_code
188 make_cred_from_ccred(krb5_context context
,
189 const cc_credentials_v5_t
*incred
,
195 memset(cred
, 0, sizeof(*cred
));
197 ret
= krb5_parse_name(context
, incred
->client
, &cred
->client
);
201 ret
= krb5_parse_name(context
, incred
->server
, &cred
->server
);
205 cred
->session
.keytype
= incred
->keyblock
.type
;
206 cred
->session
.keyvalue
.length
= incred
->keyblock
.length
;
207 cred
->session
.keyvalue
.data
= malloc(incred
->keyblock
.length
);
208 if (cred
->session
.keyvalue
.data
== NULL
)
210 memcpy(cred
->session
.keyvalue
.data
, incred
->keyblock
.data
,
211 incred
->keyblock
.length
);
213 cred
->times
.authtime
= incred
->authtime
;
214 cred
->times
.starttime
= incred
->starttime
;
215 cred
->times
.endtime
= incred
->endtime
;
216 cred
->times
.renew_till
= incred
->renew_till
;
218 ret
= krb5_data_copy(&cred
->ticket
,
220 incred
->ticket
.length
);
224 ret
= krb5_data_copy(&cred
->second_ticket
,
225 incred
->second_ticket
.data
,
226 incred
->second_ticket
.length
);
230 cred
->authdata
.val
= NULL
;
231 cred
->authdata
.len
= 0;
233 cred
->addresses
.val
= NULL
;
234 cred
->addresses
.len
= 0;
236 for (i
= 0; incred
->authdata
&& incred
->authdata
[i
]; i
++)
240 cred
->authdata
.val
= calloc(i
, sizeof(cred
->authdata
.val
[0]));
241 if (cred
->authdata
.val
== NULL
)
243 cred
->authdata
.len
= i
;
244 for (i
= 0; i
< cred
->authdata
.len
; i
++) {
245 cred
->authdata
.val
[i
].ad_type
= incred
->authdata
[i
]->type
;
246 ret
= krb5_data_copy(&cred
->authdata
.val
[i
].ad_data
,
247 incred
->authdata
[i
]->data
,
248 incred
->authdata
[i
]->length
);
254 for (i
= 0; incred
->addresses
&& incred
->addresses
[i
]; i
++)
258 cred
->addresses
.val
= calloc(i
, sizeof(cred
->addresses
.val
[0]));
259 if (cred
->addresses
.val
== NULL
)
261 cred
->addresses
.len
= i
;
263 for (i
= 0; i
< cred
->addresses
.len
; i
++) {
264 cred
->addresses
.val
[i
].addr_type
= incred
->addresses
[i
]->type
;
265 ret
= krb5_data_copy(&cred
->addresses
.val
[i
].address
,
266 incred
->addresses
[i
]->data
,
267 incred
->addresses
[i
]->length
);
274 if (incred
->ticket_flags
& KRB5_CCAPI_TKT_FLG_FORWARDABLE
)
275 cred
->flags
.b
.forwardable
= 1;
276 if (incred
->ticket_flags
& KRB5_CCAPI_TKT_FLG_FORWARDED
)
277 cred
->flags
.b
.forwarded
= 1;
278 if (incred
->ticket_flags
& KRB5_CCAPI_TKT_FLG_PROXIABLE
)
279 cred
->flags
.b
.proxiable
= 1;
280 if (incred
->ticket_flags
& KRB5_CCAPI_TKT_FLG_PROXY
)
281 cred
->flags
.b
.proxy
= 1;
282 if (incred
->ticket_flags
& KRB5_CCAPI_TKT_FLG_MAY_POSTDATE
)
283 cred
->flags
.b
.may_postdate
= 1;
284 if (incred
->ticket_flags
& KRB5_CCAPI_TKT_FLG_POSTDATED
)
285 cred
->flags
.b
.postdated
= 1;
286 if (incred
->ticket_flags
& KRB5_CCAPI_TKT_FLG_INVALID
)
287 cred
->flags
.b
.invalid
= 1;
288 if (incred
->ticket_flags
& KRB5_CCAPI_TKT_FLG_RENEWABLE
)
289 cred
->flags
.b
.renewable
= 1;
290 if (incred
->ticket_flags
& KRB5_CCAPI_TKT_FLG_INITIAL
)
291 cred
->flags
.b
.initial
= 1;
292 if (incred
->ticket_flags
& KRB5_CCAPI_TKT_FLG_PRE_AUTH
)
293 cred
->flags
.b
.pre_authent
= 1;
294 if (incred
->ticket_flags
& KRB5_CCAPI_TKT_FLG_HW_AUTH
)
295 cred
->flags
.b
.hw_authent
= 1;
296 if (incred
->ticket_flags
& KRB5_CCAPI_TKT_FLG_TRANSIT_POLICY_CHECKED
)
297 cred
->flags
.b
.transited_policy_checked
= 1;
298 if (incred
->ticket_flags
& KRB5_CCAPI_TKT_FLG_OK_AS_DELEGATE
)
299 cred
->flags
.b
.ok_as_delegate
= 1;
300 if (incred
->ticket_flags
& KRB5_CCAPI_TKT_FLG_ANONYMOUS
)
301 cred
->flags
.b
.anonymous
= 1;
306 ret
= krb5_enomem(context
);
309 krb5_free_cred_contents(context
, cred
);
314 free_ccred(cc_credentials_v5_t
*cred
)
318 if (cred
->addresses
) {
319 for (i
= 0; cred
->addresses
[i
] != 0; i
++) {
320 if (cred
->addresses
[i
]->data
)
321 free(cred
->addresses
[i
]->data
);
322 free(cred
->addresses
[i
]);
324 free(cred
->addresses
);
330 memset(cred
, 0, sizeof(*cred
));
333 static krb5_error_code
334 make_ccred_from_cred(krb5_context context
,
335 const krb5_creds
*incred
,
336 cc_credentials_v5_t
*cred
)
341 memset(cred
, 0, sizeof(*cred
));
343 ret
= krb5_unparse_name(context
, incred
->client
, &cred
->client
);
347 ret
= krb5_unparse_name(context
, incred
->server
, &cred
->server
);
351 cred
->keyblock
.type
= incred
->session
.keytype
;
352 cred
->keyblock
.length
= incred
->session
.keyvalue
.length
;
353 cred
->keyblock
.data
= incred
->session
.keyvalue
.data
;
355 cred
->authtime
= incred
->times
.authtime
;
356 cred
->starttime
= incred
->times
.starttime
;
357 cred
->endtime
= incred
->times
.endtime
;
358 cred
->renew_till
= incred
->times
.renew_till
;
360 cred
->ticket
.length
= incred
->ticket
.length
;
361 cred
->ticket
.data
= incred
->ticket
.data
;
363 cred
->second_ticket
.length
= incred
->second_ticket
.length
;
364 cred
->second_ticket
.data
= incred
->second_ticket
.data
;
366 /* XXX this one should also be filled in */
367 cred
->authdata
= NULL
;
369 cred
->addresses
= calloc(incred
->addresses
.len
+ 1,
370 sizeof(cred
->addresses
[0]));
371 if (cred
->addresses
== NULL
) {
377 for (i
= 0; i
< incred
->addresses
.len
; i
++) {
379 addr
= malloc(sizeof(*addr
));
384 addr
->type
= incred
->addresses
.val
[i
].addr_type
;
385 addr
->length
= incred
->addresses
.val
[i
].address
.length
;
386 addr
->data
= malloc(addr
->length
);
387 if (addr
->data
== NULL
) {
392 memcpy(addr
->data
, incred
->addresses
.val
[i
].address
.data
,
394 cred
->addresses
[i
] = addr
;
396 cred
->addresses
[i
] = NULL
;
398 cred
->ticket_flags
= 0;
399 if (incred
->flags
.b
.forwardable
)
400 cred
->ticket_flags
|= KRB5_CCAPI_TKT_FLG_FORWARDABLE
;
401 if (incred
->flags
.b
.forwarded
)
402 cred
->ticket_flags
|= KRB5_CCAPI_TKT_FLG_FORWARDED
;
403 if (incred
->flags
.b
.proxiable
)
404 cred
->ticket_flags
|= KRB5_CCAPI_TKT_FLG_PROXIABLE
;
405 if (incred
->flags
.b
.proxy
)
406 cred
->ticket_flags
|= KRB5_CCAPI_TKT_FLG_PROXY
;
407 if (incred
->flags
.b
.may_postdate
)
408 cred
->ticket_flags
|= KRB5_CCAPI_TKT_FLG_MAY_POSTDATE
;
409 if (incred
->flags
.b
.postdated
)
410 cred
->ticket_flags
|= KRB5_CCAPI_TKT_FLG_POSTDATED
;
411 if (incred
->flags
.b
.invalid
)
412 cred
->ticket_flags
|= KRB5_CCAPI_TKT_FLG_INVALID
;
413 if (incred
->flags
.b
.renewable
)
414 cred
->ticket_flags
|= KRB5_CCAPI_TKT_FLG_RENEWABLE
;
415 if (incred
->flags
.b
.initial
)
416 cred
->ticket_flags
|= KRB5_CCAPI_TKT_FLG_INITIAL
;
417 if (incred
->flags
.b
.pre_authent
)
418 cred
->ticket_flags
|= KRB5_CCAPI_TKT_FLG_PRE_AUTH
;
419 if (incred
->flags
.b
.hw_authent
)
420 cred
->ticket_flags
|= KRB5_CCAPI_TKT_FLG_HW_AUTH
;
421 if (incred
->flags
.b
.transited_policy_checked
)
422 cred
->ticket_flags
|= KRB5_CCAPI_TKT_FLG_TRANSIT_POLICY_CHECKED
;
423 if (incred
->flags
.b
.ok_as_delegate
)
424 cred
->ticket_flags
|= KRB5_CCAPI_TKT_FLG_OK_AS_DELEGATE
;
425 if (incred
->flags
.b
.anonymous
)
426 cred
->ticket_flags
|= KRB5_CCAPI_TKT_FLG_ANONYMOUS
;
433 krb5_clear_error_message(context
);
438 get_cc_name(krb5_acc
*a
)
443 error
= (*a
->ccache
->func
->get_name
)(a
->ccache
, &name
);
447 a
->cache_name
= strdup(name
->data
);
448 (*name
->func
->release
)(name
);
449 if (a
->cache_name
== NULL
)
455 static const char* KRB5_CALLCONV
456 acc_get_name(krb5_context context
,
459 krb5_acc
*a
= ACACHE(id
);
462 if (a
->cache_name
== NULL
) {
464 krb5_principal principal
;
467 ret
= _krb5_get_default_principal_local(context
, &principal
);
471 ret
= krb5_unparse_name(context
, principal
, &name
);
472 krb5_free_principal(context
, principal
);
476 error
= (*a
->context
->func
->create_new_ccache
)(a
->context
,
484 error
= get_cc_name(a
);
489 return a
->cache_name
;
492 static krb5_error_code KRB5_CALLCONV
493 acc_alloc(krb5_context context
, krb5_ccache
*id
)
499 ret
= init_ccapi(context
);
503 ret
= krb5_data_alloc(&(*id
)->data
, sizeof(*a
));
505 krb5_clear_error_message(context
);
511 error
= (*init_func
)(&a
->context
, ccapi_version_3
, NULL
, NULL
);
513 krb5_data_free(&(*id
)->data
);
514 return translate_cc_error(context
, error
);
517 a
->cache_name
= NULL
;
522 static krb5_error_code KRB5_CALLCONV
523 acc_resolve(krb5_context context
, krb5_ccache
*id
, const char *res
)
529 ret
= acc_alloc(context
, id
);
535 error
= (*a
->context
->func
->open_ccache
)(a
->context
, res
, &a
->ccache
);
536 if (error
== ccNoError
) {
538 error
= get_cc_name(a
);
539 if (error
!= ccNoError
) {
540 acc_close(context
, *id
);
542 return translate_cc_error(context
, error
);
545 error
= (*a
->ccache
->func
->get_kdc_time_offset
)(a
->ccache
,
549 context
->kdc_sec_offset
= offset
;
551 } else if (error
== ccErrCCacheNotFound
) {
553 a
->cache_name
= NULL
;
556 return translate_cc_error(context
, error
);
562 static krb5_error_code KRB5_CALLCONV
563 acc_gen_new(krb5_context context
, krb5_ccache
*id
)
568 ret
= acc_alloc(context
, id
);
575 a
->cache_name
= NULL
;
580 static krb5_error_code KRB5_CALLCONV
581 acc_initialize(krb5_context context
,
583 krb5_principal primary_principal
)
585 krb5_acc
*a
= ACACHE(id
);
590 ret
= krb5_unparse_name(context
, primary_principal
, &name
);
594 if (a
->cache_name
== NULL
) {
595 error
= (*a
->context
->func
->create_new_ccache
)(a
->context
,
600 if (error
== ccNoError
)
601 error
= get_cc_name(a
);
603 cc_credentials_iterator_t iter
;
604 cc_credentials_t ccred
;
606 error
= (*a
->ccache
->func
->new_credentials_iterator
)(a
->ccache
, &iter
);
609 return translate_cc_error(context
, error
);
613 error
= (*iter
->func
->next
)(iter
, &ccred
);
616 (*a
->ccache
->func
->remove_credentials
)(a
->ccache
, ccred
);
617 (*ccred
->func
->release
)(ccred
);
619 (*iter
->func
->release
)(iter
);
621 error
= (*a
->ccache
->func
->set_principal
)(a
->ccache
,
626 if (error
== 0 && context
->kdc_sec_offset
)
627 error
= (*a
->ccache
->func
->set_kdc_time_offset
)(a
->ccache
,
629 context
->kdc_sec_offset
);
631 return translate_cc_error(context
, error
);
634 static krb5_error_code KRB5_CALLCONV
635 acc_close(krb5_context context
,
638 krb5_acc
*a
= ACACHE(id
);
641 (*a
->ccache
->func
->release
)(a
->ccache
);
646 a
->cache_name
= NULL
;
649 (*a
->context
->func
->release
)(a
->context
);
652 krb5_data_free(&id
->data
);
656 static krb5_error_code KRB5_CALLCONV
657 acc_destroy(krb5_context context
,
660 krb5_acc
*a
= ACACHE(id
);
664 error
= (*a
->ccache
->func
->destroy
)(a
->ccache
);
668 error
= (a
->context
->func
->release
)(a
->context
);
671 return translate_cc_error(context
, error
);
674 static krb5_error_code KRB5_CALLCONV
675 acc_store_cred(krb5_context context
,
679 krb5_acc
*a
= ACACHE(id
);
680 cc_credentials_union cred
;
681 cc_credentials_v5_t v5cred
;
685 if (a
->ccache
== NULL
) {
686 krb5_set_error_message(context
, KRB5_CC_NOTFOUND
,
687 N_("No API credential found", ""));
688 return KRB5_CC_NOTFOUND
;
691 cred
.version
= cc_credentials_v5
;
692 cred
.credentials
.credentials_v5
= &v5cred
;
694 ret
= make_ccred_from_cred(context
,
700 error
= (*a
->ccache
->func
->store_credentials
)(a
->ccache
, &cred
);
702 ret
= translate_cc_error(context
, error
);
709 static krb5_error_code KRB5_CALLCONV
710 acc_get_principal(krb5_context context
,
712 krb5_principal
*principal
)
714 krb5_acc
*a
= ACACHE(id
);
719 if (a
->ccache
== NULL
) {
720 krb5_set_error_message(context
, KRB5_CC_NOTFOUND
,
721 N_("No API credential found", ""));
722 return KRB5_CC_NOTFOUND
;
725 error
= (*a
->ccache
->func
->get_principal
)(a
->ccache
,
729 return translate_cc_error(context
, error
);
731 ret
= krb5_parse_name(context
, name
->data
, principal
);
733 (*name
->func
->release
)(name
);
737 static krb5_error_code KRB5_CALLCONV
738 acc_get_first (krb5_context context
,
740 krb5_cc_cursor
*cursor
)
742 cc_credentials_iterator_t iter
;
743 krb5_acc
*a
= ACACHE(id
);
746 if (a
->ccache
== NULL
) {
747 krb5_set_error_message(context
, KRB5_CC_NOTFOUND
,
748 N_("No API credential found", ""));
749 return KRB5_CC_NOTFOUND
;
752 error
= (*a
->ccache
->func
->new_credentials_iterator
)(a
->ccache
, &iter
);
754 krb5_clear_error_message(context
);
762 static krb5_error_code KRB5_CALLCONV
763 acc_get_next (krb5_context context
,
765 krb5_cc_cursor
*cursor
,
768 cc_credentials_iterator_t iter
= *cursor
;
769 cc_credentials_t cred
;
774 error
= (*iter
->func
->next
)(iter
, &cred
);
776 return translate_cc_error(context
, error
);
777 if (cred
->data
->version
== cc_credentials_v5
)
779 (*cred
->func
->release
)(cred
);
782 ret
= make_cred_from_ccred(context
,
783 cred
->data
->credentials
.credentials_v5
,
785 (*cred
->func
->release
)(cred
);
789 static krb5_error_code KRB5_CALLCONV
790 acc_end_get (krb5_context context
,
792 krb5_cc_cursor
*cursor
)
794 cc_credentials_iterator_t iter
= *cursor
;
795 (*iter
->func
->release
)(iter
);
799 static krb5_error_code KRB5_CALLCONV
800 acc_remove_cred(krb5_context context
,
805 cc_credentials_iterator_t iter
;
806 krb5_acc
*a
= ACACHE(id
);
807 cc_credentials_t ccred
;
810 char *client
, *server
;
812 if (a
->ccache
== NULL
) {
813 krb5_set_error_message(context
, KRB5_CC_NOTFOUND
,
814 N_("No API credential found", ""));
815 return KRB5_CC_NOTFOUND
;
819 ret
= krb5_unparse_name(context
, cred
->client
, &client
);
825 ret
= krb5_unparse_name(context
, cred
->server
, &server
);
831 error
= (*a
->ccache
->func
->new_credentials_iterator
)(a
->ccache
, &iter
);
835 return translate_cc_error(context
, error
);
838 ret
= KRB5_CC_NOTFOUND
;
840 cc_credentials_v5_t
*v5cred
;
842 error
= (*iter
->func
->next
)(iter
, &ccred
);
846 if (ccred
->data
->version
!= cc_credentials_v5
)
849 v5cred
= ccred
->data
->credentials
.credentials_v5
;
851 if (client
&& strcmp(v5cred
->client
, client
) != 0)
854 if (strcmp(v5cred
->server
, server
) != 0)
857 (*a
->ccache
->func
->remove_credentials
)(a
->ccache
, ccred
);
860 (*ccred
->func
->release
)(ccred
);
863 (*iter
->func
->release
)(iter
);
866 krb5_set_error_message(context
, ret
,
867 N_("Can't find credential %s in cache",
868 "principal"), server
);
875 static krb5_error_code KRB5_CALLCONV
876 acc_set_flags(krb5_context context
,
883 static int KRB5_CALLCONV
884 acc_get_version(krb5_context context
,
891 cc_context_t context
;
892 cc_ccache_iterator_t iter
;
895 static krb5_error_code KRB5_CALLCONV
896 acc_get_cache_first(krb5_context context
, krb5_cc_cursor
*cursor
)
898 struct cache_iter
*iter
;
902 ret
= init_ccapi(context
);
906 iter
= calloc(1, sizeof(*iter
));
908 return krb5_enomem(context
);
910 error
= (*init_func
)(&iter
->context
, ccapi_version_3
, NULL
, NULL
);
913 return translate_cc_error(context
, error
);
916 error
= (*iter
->context
->func
->new_ccache_iterator
)(iter
->context
,
920 krb5_clear_error_message(context
);
927 static krb5_error_code KRB5_CALLCONV
928 acc_get_cache_next(krb5_context context
, krb5_cc_cursor cursor
, krb5_ccache
*id
)
930 struct cache_iter
*iter
= cursor
;
936 error
= (*iter
->iter
->func
->next
)(iter
->iter
, &cache
);
938 return translate_cc_error(context
, error
);
940 ret
= _krb5_cc_allocate(context
, &krb5_acc_ops
, id
);
942 (*cache
->func
->release
)(cache
);
946 ret
= acc_alloc(context
, id
);
948 (*cache
->func
->release
)(cache
);
956 error
= get_cc_name(a
);
958 acc_close(context
, *id
);
960 return translate_cc_error(context
, error
);
965 static krb5_error_code KRB5_CALLCONV
966 acc_end_cache_get(krb5_context context
, krb5_cc_cursor cursor
)
968 struct cache_iter
*iter
= cursor
;
970 (*iter
->iter
->func
->release
)(iter
->iter
);
972 (*iter
->context
->func
->release
)(iter
->context
);
973 iter
->context
= NULL
;
978 static krb5_error_code KRB5_CALLCONV
979 acc_move(krb5_context context
, krb5_ccache from
, krb5_ccache to
)
981 krb5_acc
*afrom
= ACACHE(from
);
982 krb5_acc
*ato
= ACACHE(to
);
985 if (ato
->ccache
== NULL
) {
988 error
= (*afrom
->ccache
->func
->get_principal
)(afrom
->ccache
,
992 return translate_cc_error(context
, error
);
994 error
= (*ato
->context
->func
->create_new_ccache
)(ato
->context
,
998 (*name
->func
->release
)(name
);
1000 return translate_cc_error(context
, error
);
1003 error
= (*ato
->ccache
->func
->move
)(afrom
->ccache
, ato
->ccache
);
1005 acc_destroy(context
, from
);
1007 return translate_cc_error(context
, error
);
1010 static krb5_error_code KRB5_CALLCONV
1011 acc_get_default_name(krb5_context context
, char **str
)
1013 krb5_error_code ret
;
1018 ret
= init_ccapi(context
);
1022 error
= (*init_func
)(&cc
, ccapi_version_3
, NULL
, NULL
);
1024 return translate_cc_error(context
, error
);
1026 error
= (*cc
->func
->get_default_ccache_name
)(cc
, &name
);
1028 (*cc
->func
->release
)(cc
);
1029 return translate_cc_error(context
, error
);
1032 error
= asprintf(str
, "API:%s", name
->data
);
1033 (*name
->func
->release
)(name
);
1034 (*cc
->func
->release
)(cc
);
1036 if (error
< 0 || *str
== NULL
)
1037 return krb5_enomem(context
);
1041 static krb5_error_code KRB5_CALLCONV
1042 acc_set_default(krb5_context context
, krb5_ccache id
)
1044 krb5_acc
*a
= ACACHE(id
);
1047 if (a
->ccache
== NULL
) {
1048 krb5_set_error_message(context
, KRB5_CC_NOTFOUND
,
1049 N_("No API credential found", ""));
1050 return KRB5_CC_NOTFOUND
;
1053 error
= (*a
->ccache
->func
->set_default
)(a
->ccache
);
1055 return translate_cc_error(context
, error
);
1060 static krb5_error_code KRB5_CALLCONV
1061 acc_lastchange(krb5_context context
, krb5_ccache id
, krb5_timestamp
*mtime
)
1063 krb5_acc
*a
= ACACHE(id
);
1067 if (a
->ccache
== NULL
) {
1068 krb5_set_error_message(context
, KRB5_CC_NOTFOUND
,
1069 N_("No API credential found", ""));
1070 return KRB5_CC_NOTFOUND
;
1073 error
= (*a
->ccache
->func
->get_change_time
)(a
->ccache
, &t
);
1075 return translate_cc_error(context
, error
);
1083 * Variable containing the API based credential cache implemention.
1085 * @ingroup krb5_ccache
1088 KRB5_LIB_VARIABLE
const krb5_cc_ops krb5_acc_ops
= {
1089 KRB5_CC_OPS_VERSION
,
1098 NULL
, /* acc_retrieve */
1106 acc_get_cache_first
,
1110 acc_get_default_name
,