003 File Manager
Current Path:
/usr/src/crypto/heimdal/lib/krb5
usr
/
src
/
crypto
/
heimdal
/
lib
/
krb5
/
π
..
π
Makefile.am
(7.68 KB)
π
Makefile.in
(224.98 KB)
π
acache.c
(26.87 KB)
π
acl.c
(7.58 KB)
π
add_et_list.c
(2.2 KB)
π
addr_families.c
(38.89 KB)
π
aes-test.c
(22.56 KB)
π
aname_to_localname.c
(2.83 KB)
π
appdefault.c
(4.41 KB)
π
asn1_glue.c
(2.37 KB)
π
auth_context.c
(14.97 KB)
π
build_ap_req.c
(2.77 KB)
π
build_auth.c
(5.5 KB)
π
cache.c
(41.88 KB)
π
ccache_plugin.h
(1.67 KB)
π
changepw.c
(20.59 KB)
π
codec.c
(6.1 KB)
π
config_file.c
(31.7 KB)
π
constants.c
(2.51 KB)
π
context.c
(37.71 KB)
π
convert_creds.c
(3.46 KB)
π
copy_host_realm.c
(2.66 KB)
π
crc.c
(2.19 KB)
π
creds.c
(8.75 KB)
π
crypto-aes.c
(4.62 KB)
π
crypto-algs.c
(3.04 KB)
π
crypto-arcfour.c
(8.78 KB)
π
crypto-des-common.c
(4.37 KB)
π
crypto-des.c
(8.8 KB)
π
crypto-des3.c
(5.36 KB)
π
crypto-evp.c
(5.45 KB)
π
crypto-null.c
(2.55 KB)
π
crypto-pk.c
(8.4 KB)
π
crypto-rand.c
(3.43 KB)
π
crypto-stubs.c
(3.1 KB)
π
crypto.c
(66.51 KB)
π
crypto.h
(6.5 KB)
π
data.c
(5.66 KB)
π
deprecated.c
(14.72 KB)
π
derived-key-test.c
(6.48 KB)
π
digest.c
(31.6 KB)
π
doxygen.c
(25.72 KB)
π
eai_to_heim_errno.c
(3.46 KB)
π
error_string.c
(8.93 KB)
π
expand_hostname.c
(5.59 KB)
π
expand_path.c
(12.35 KB)
π
fcache.c
(25.36 KB)
π
free.c
(2.01 KB)
π
free_host_realm.c
(2.1 KB)
π
generate_seq_number.c
(2.03 KB)
π
generate_subkey.c
(2.6 KB)
π
get_addrs.c
(8.2 KB)
π
get_cred.c
(38.45 KB)
π
get_default_principal.c
(4.47 KB)
π
get_default_realm.c
(2.74 KB)
π
get_for_creds.c
(13.48 KB)
π
get_host_realm.c
(7.06 KB)
π
get_in_tkt.c
(14.45 KB)
π
get_port.c
(2.04 KB)
π
heim_err.et
(1.7 KB)
π
init_creds.c
(12.11 KB)
π
init_creds_pw.c
(52.57 KB)
π
k524_err.et
(577 B)
π
kcm.c
(26.55 KB)
π
kcm.h
(2.83 KB)
π
kerberos.8
(4.14 KB)
π
keyblock.c
(5.31 KB)
π
keytab.c
(23.88 KB)
π
keytab_any.c
(6.48 KB)
π
keytab_file.c
(19.7 KB)
π
keytab_keyfile.c
(10.74 KB)
π
keytab_memory.c
(6.29 KB)
π
krb5-private.h
(12.91 KB)
π
krb5-protos.h
(113.43 KB)
π
krb5-v4compat.h
(4.44 KB)
π
krb5.conf.5
(18.31 KB)
π
krb5.h
(29.75 KB)
π
krb5.moduli
(1.11 KB)
π
krb524_convert_creds_kdc.3
(3.12 KB)
π
krb5_425_conv_principal.3
(7.02 KB)
π
krb5_acl_match_file.3
(3.49 KB)
π
krb5_aname_to_localname.3
(2.87 KB)
π
krb5_appdefault.3
(3.08 KB)
π
krb5_auth_context.3
(10.8 KB)
π
krb5_c_make_checksum.3
(6.92 KB)
π
krb5_ccapi.h
(7.52 KB)
π
krb5_check_transited.3
(3.28 KB)
π
krb5_create_checksum.3
(6.02 KB)
π
krb5_creds.3
(3.31 KB)
π
krb5_digest.3
(6.57 KB)
π
krb5_eai_to_heim_errno.3
(2.4 KB)
π
krb5_encrypt.3
(7 KB)
π
krb5_err.et
(12.86 KB)
π
krb5_find_padata.3
(2.53 KB)
π
krb5_generate_random_block.3
(2.1 KB)
π
krb5_get_all_client_addrs.3
(2.83 KB)
π
krb5_get_credentials.3
(5.03 KB)
π
krb5_get_creds.3
(5.28 KB)
π
krb5_get_forwarded_creds.3
(2.74 KB)
π
krb5_get_in_cred.3
(7.46 KB)
π
krb5_get_init_creds.3
(11.03 KB)
π
krb5_get_krbhst.3
(3.26 KB)
π
krb5_getportbyname.3
(2.32 KB)
π
krb5_init_context.3
(7.88 KB)
π
krb5_is_thread_safe.3
(2.24 KB)
π
krb5_krbhst_init.3
(5.67 KB)
π
krb5_locl.h
(8.47 KB)
π
krb5_mk_req.3
(5.18 KB)
π
krb5_mk_safe.3
(2.78 KB)
π
krb5_openlog.3
(7.96 KB)
π
krb5_parse_name.3
(2.57 KB)
π
krb5_principal.3
(11.85 KB)
π
krb5_rcache.3
(4.21 KB)
π
krb5_rd_error.3
(3.33 KB)
π
krb5_rd_safe.3
(2.77 KB)
π
krb5_set_default_realm.3
(4.29 KB)
π
krb5_set_password.3
(4.11 KB)
π
krb5_string_to_key.3
(4.39 KB)
π
krb5_timeofday.3
(3.33 KB)
π
krb5_verify_init_creds.3
(3.51 KB)
π
krb5_verify_user.3
(6.71 KB)
π
krb_err.et
(2.55 KB)
π
krbhst-test.c
(3.02 KB)
π
krbhst.c
(26.94 KB)
π
kuserok.c
(8.14 KB)
π
locate_plugin.h
(2.36 KB)
π
log.c
(11.94 KB)
π
mcache.c
(11.54 KB)
π
misc.c
(3.9 KB)
π
mit_glue.c
(11.14 KB)
π
mk_error.c
(3.23 KB)
π
mk_priv.c
(4.54 KB)
π
mk_rep.c
(3.99 KB)
π
mk_req.c
(3.58 KB)
π
mk_req_ext.c
(4.78 KB)
π
mk_safe.c
(4.36 KB)
π
n-fold-test.c
(4.14 KB)
π
n-fold.c
(3.8 KB)
π
net_read.c
(1.86 KB)
π
net_write.c
(3.05 KB)
π
pac.c
(28.37 KB)
π
padata.c
(2.35 KB)
π
parse-name-test.c
(5.81 KB)
π
pcache.c
(2.33 KB)
π
pkinit.c
(63.8 KB)
π
plugin.c
(13.71 KB)
π
principal.c
(28.4 KB)
π
prog_setup.c
(2.34 KB)
π
prompter_posix.c
(2.45 KB)
π
rd_cred.c
(9.44 KB)
π
rd_error.c
(3.83 KB)
π
rd_priv.c
(5.38 KB)
π
rd_rep.c
(3.72 KB)
π
rd_req.c
(25.6 KB)
π
rd_safe.c
(6.34 KB)
π
read_message.c
(3.22 KB)
π
recvauth.c
(6.16 KB)
π
replay.c
(8.24 KB)
π
salt-aes.c
(3.34 KB)
π
salt-arcfour.c
(3.24 KB)
π
salt-des.c
(6.68 KB)
π
salt-des3.c
(4.36 KB)
π
salt.c
(9 KB)
π
scache.c
(32.86 KB)
π
send_to_kdc.c
(16.06 KB)
π
send_to_kdc_plugin.h
(2.22 KB)
π
sendauth.c
(6.12 KB)
π
set_default_realm.c
(3.01 KB)
π
sock_principal.c
(2.52 KB)
π
store-int.c
(2.14 KB)
π
store-int.h
(2.07 KB)
π
store-test.c
(3.63 KB)
π
store.c
(35.77 KB)
π
store_emem.c
(5.06 KB)
π
store_fd.c
(3.4 KB)
π
store_mem.c
(5.42 KB)
π
string-to-key-test.c
(5.75 KB)
π
test_acl.c
(4.56 KB)
π
test_addr.c
(7.27 KB)
π
test_alname.c
(4.28 KB)
π
test_cc.c
(19.39 KB)
π
test_config.c
(7.92 KB)
π
test_crypto.c
(5.68 KB)
π
test_crypto_wrapping.c
(4.48 KB)
π
test_forward.c
(3.64 KB)
π
test_get_addrs.c
(3.21 KB)
π
test_hostname.c
(3.82 KB)
π
test_keytab.c
(7.42 KB)
π
test_kuserok.c
(2.9 KB)
π
test_mem.c
(2.21 KB)
π
test_pac.c
(15.1 KB)
π
test_pkinit_dh2key.c
(6.9 KB)
π
test_plugin.c
(3.4 KB)
π
test_prf.c
(3.21 KB)
π
test_princ.c
(10.44 KB)
π
test_renew.c
(3.22 KB)
π
test_store.c
(7.96 KB)
π
test_time.c
(2.57 KB)
π
ticket.c
(21.91 KB)
π
time.c
(3.84 KB)
π
transited.c
(11.11 KB)
π
verify_init.c
(6.47 KB)
π
verify_krb5_conf.8
(3.41 KB)
π
verify_krb5_conf.c
(20.63 KB)
π
verify_user.c
(7 KB)
π
version-script.map
(18.82 KB)
π
version.c
(1.71 KB)
π
warn.c
(8.98 KB)
π
write_message.c
(2.87 KB)
Editing: acache.c
/* * Copyright (c) 2004 - 2007 Kungliga Tekniska HΓΆgskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * * Portions Copyright (c) 2009 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * 3. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "krb5_locl.h" #include <krb5_ccapi.h> #ifdef HAVE_DLFCN_H #include <dlfcn.h> #endif #ifndef KCM_IS_API_CACHE static HEIMDAL_MUTEX acc_mutex = HEIMDAL_MUTEX_INITIALIZER; static cc_initialize_func init_func; static void (KRB5_CALLCONV *set_target_uid)(uid_t); static void (KRB5_CALLCONV *clear_target)(void); #ifdef HAVE_DLOPEN static void *cc_handle; #endif typedef struct krb5_acc { char *cache_name; cc_context_t context; cc_ccache_t ccache; } krb5_acc; static krb5_error_code KRB5_CALLCONV acc_close(krb5_context, krb5_ccache); #define ACACHE(X) ((krb5_acc *)(X)->data.data) static const struct { cc_int32 error; krb5_error_code ret; } cc_errors[] = { { ccErrBadName, KRB5_CC_BADNAME }, { ccErrCredentialsNotFound, KRB5_CC_NOTFOUND }, { ccErrCCacheNotFound, KRB5_FCC_NOFILE }, { ccErrContextNotFound, KRB5_CC_NOTFOUND }, { ccIteratorEnd, KRB5_CC_END }, { ccErrNoMem, KRB5_CC_NOMEM }, { ccErrServerUnavailable, KRB5_CC_NOSUPP }, { ccErrInvalidCCache, KRB5_CC_BADNAME }, { ccNoError, 0 } }; static krb5_error_code translate_cc_error(krb5_context context, cc_int32 error) { size_t i; krb5_clear_error_message(context); for(i = 0; i < sizeof(cc_errors)/sizeof(cc_errors[0]); i++) if (cc_errors[i].error == error) return cc_errors[i].ret; return KRB5_FCC_INTERNAL; } static krb5_error_code init_ccapi(krb5_context context) { const char *lib = NULL; HEIMDAL_MUTEX_lock(&acc_mutex); if (init_func) { HEIMDAL_MUTEX_unlock(&acc_mutex); if (context) krb5_clear_error_message(context); return 0; } if (context) lib = krb5_config_get_string(context, NULL, "libdefaults", "ccapi_library", NULL); if (lib == NULL) { #ifdef __APPLE__ lib = "/System/Library/Frameworks/Kerberos.framework/Kerberos"; #elif defined(KRB5_USE_PATH_TOKENS) && defined(_WIN32) lib = "%{LIBDIR}/libkrb5_cc.dll"; #else lib = "/usr/lib/libkrb5_cc.so"; #endif } #ifdef HAVE_DLOPEN #ifndef RTLD_LAZY #define RTLD_LAZY 0 #endif #ifndef RTLD_LOCAL #define RTLD_LOCAL 0 #endif #ifdef KRB5_USE_PATH_TOKENS { char * explib = NULL; if (_krb5_expand_path_tokens(context, lib, &explib) == 0) { cc_handle = dlopen(explib, RTLD_LAZY|RTLD_LOCAL); free(explib); } } #else cc_handle = dlopen(lib, RTLD_LAZY|RTLD_LOCAL); #endif if (cc_handle == NULL) { HEIMDAL_MUTEX_unlock(&acc_mutex); if (context) krb5_set_error_message(context, KRB5_CC_NOSUPP, N_("Failed to load API cache module %s", "file"), lib); return KRB5_CC_NOSUPP; } init_func = (cc_initialize_func)dlsym(cc_handle, "cc_initialize"); set_target_uid = (void (KRB5_CALLCONV *)(uid_t)) dlsym(cc_handle, "krb5_ipc_client_set_target_uid"); clear_target = (void (KRB5_CALLCONV *)(void)) dlsym(cc_handle, "krb5_ipc_client_clear_target"); HEIMDAL_MUTEX_unlock(&acc_mutex); if (init_func == NULL) { if (context) krb5_set_error_message(context, KRB5_CC_NOSUPP, N_("Failed to find cc_initialize" "in %s: %s", "file, error"), lib, dlerror()); dlclose(cc_handle); return KRB5_CC_NOSUPP; } return 0; #else HEIMDAL_MUTEX_unlock(&acc_mutex); if (context) krb5_set_error_message(context, KRB5_CC_NOSUPP, N_("no support for shared object", "")); return KRB5_CC_NOSUPP; #endif } void _heim_krb5_ipc_client_set_target_uid(uid_t uid) { init_ccapi(NULL); if (set_target_uid != NULL) (*set_target_uid)(uid); } void _heim_krb5_ipc_client_clear_target(void) { init_ccapi(NULL); if (clear_target != NULL) (*clear_target)(); } static krb5_error_code make_cred_from_ccred(krb5_context context, const cc_credentials_v5_t *incred, krb5_creds *cred) { krb5_error_code ret; unsigned int i; memset(cred, 0, sizeof(*cred)); ret = krb5_parse_name(context, incred->client, &cred->client); if (ret) goto fail; ret = krb5_parse_name(context, incred->server, &cred->server); if (ret) goto fail; cred->session.keytype = incred->keyblock.type; cred->session.keyvalue.length = incred->keyblock.length; cred->session.keyvalue.data = malloc(incred->keyblock.length); if (cred->session.keyvalue.data == NULL) goto nomem; memcpy(cred->session.keyvalue.data, incred->keyblock.data, incred->keyblock.length); cred->times.authtime = incred->authtime; cred->times.starttime = incred->starttime; cred->times.endtime = incred->endtime; cred->times.renew_till = incred->renew_till; ret = krb5_data_copy(&cred->ticket, incred->ticket.data, incred->ticket.length); if (ret) goto nomem; ret = krb5_data_copy(&cred->second_ticket, incred->second_ticket.data, incred->second_ticket.length); if (ret) goto nomem; cred->authdata.val = NULL; cred->authdata.len = 0; cred->addresses.val = NULL; cred->addresses.len = 0; for (i = 0; incred->authdata && incred->authdata[i]; i++) ; if (i) { cred->authdata.val = calloc(i, sizeof(cred->authdata.val[0])); if (cred->authdata.val == NULL) goto nomem; cred->authdata.len = i; for (i = 0; i < cred->authdata.len; i++) { cred->authdata.val[i].ad_type = incred->authdata[i]->type; ret = krb5_data_copy(&cred->authdata.val[i].ad_data, incred->authdata[i]->data, incred->authdata[i]->length); if (ret) goto nomem; } } for (i = 0; incred->addresses && incred->addresses[i]; i++) ; if (i) { cred->addresses.val = calloc(i, sizeof(cred->addresses.val[0])); if (cred->addresses.val == NULL) goto nomem; cred->addresses.len = i; for (i = 0; i < cred->addresses.len; i++) { cred->addresses.val[i].addr_type = incred->addresses[i]->type; ret = krb5_data_copy(&cred->addresses.val[i].address, incred->addresses[i]->data, incred->addresses[i]->length); if (ret) goto nomem; } } cred->flags.i = 0; if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_FORWARDABLE) cred->flags.b.forwardable = 1; if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_FORWARDED) cred->flags.b.forwarded = 1; if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_PROXIABLE) cred->flags.b.proxiable = 1; if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_PROXY) cred->flags.b.proxy = 1; if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_MAY_POSTDATE) cred->flags.b.may_postdate = 1; if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_POSTDATED) cred->flags.b.postdated = 1; if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_INVALID) cred->flags.b.invalid = 1; if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_RENEWABLE) cred->flags.b.renewable = 1; if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_INITIAL) cred->flags.b.initial = 1; if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_PRE_AUTH) cred->flags.b.pre_authent = 1; if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_HW_AUTH) cred->flags.b.hw_authent = 1; if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_TRANSIT_POLICY_CHECKED) cred->flags.b.transited_policy_checked = 1; if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_OK_AS_DELEGATE) cred->flags.b.ok_as_delegate = 1; if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_ANONYMOUS) cred->flags.b.anonymous = 1; return 0; nomem: ret = ENOMEM; krb5_set_error_message(context, ret, N_("malloc: out of memory", "malloc")); fail: krb5_free_cred_contents(context, cred); return ret; } static void free_ccred(cc_credentials_v5_t *cred) { int i; if (cred->addresses) { for (i = 0; cred->addresses[i] != 0; i++) { if (cred->addresses[i]->data) free(cred->addresses[i]->data); free(cred->addresses[i]); } free(cred->addresses); } if (cred->server) free(cred->server); if (cred->client) free(cred->client); memset(cred, 0, sizeof(*cred)); } static krb5_error_code make_ccred_from_cred(krb5_context context, const krb5_creds *incred, cc_credentials_v5_t *cred) { krb5_error_code ret; size_t i; memset(cred, 0, sizeof(*cred)); ret = krb5_unparse_name(context, incred->client, &cred->client); if (ret) goto fail; ret = krb5_unparse_name(context, incred->server, &cred->server); if (ret) goto fail; cred->keyblock.type = incred->session.keytype; cred->keyblock.length = incred->session.keyvalue.length; cred->keyblock.data = incred->session.keyvalue.data; cred->authtime = incred->times.authtime; cred->starttime = incred->times.starttime; cred->endtime = incred->times.endtime; cred->renew_till = incred->times.renew_till; cred->ticket.length = incred->ticket.length; cred->ticket.data = incred->ticket.data; cred->second_ticket.length = incred->second_ticket.length; cred->second_ticket.data = incred->second_ticket.data; /* XXX this one should also be filled in */ cred->authdata = NULL; cred->addresses = calloc(incred->addresses.len + 1, sizeof(cred->addresses[0])); if (cred->addresses == NULL) { ret = ENOMEM; goto fail; } for (i = 0; i < incred->addresses.len; i++) { cc_data *addr; addr = malloc(sizeof(*addr)); if (addr == NULL) { ret = ENOMEM; goto fail; } addr->type = incred->addresses.val[i].addr_type; addr->length = incred->addresses.val[i].address.length; addr->data = malloc(addr->length); if (addr->data == NULL) { free(addr); ret = ENOMEM; goto fail; } memcpy(addr->data, incred->addresses.val[i].address.data, addr->length); cred->addresses[i] = addr; } cred->addresses[i] = NULL; cred->ticket_flags = 0; if (incred->flags.b.forwardable) cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_FORWARDABLE; if (incred->flags.b.forwarded) cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_FORWARDED; if (incred->flags.b.proxiable) cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_PROXIABLE; if (incred->flags.b.proxy) cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_PROXY; if (incred->flags.b.may_postdate) cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_MAY_POSTDATE; if (incred->flags.b.postdated) cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_POSTDATED; if (incred->flags.b.invalid) cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_INVALID; if (incred->flags.b.renewable) cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_RENEWABLE; if (incred->flags.b.initial) cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_INITIAL; if (incred->flags.b.pre_authent) cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_PRE_AUTH; if (incred->flags.b.hw_authent) cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_HW_AUTH; if (incred->flags.b.transited_policy_checked) cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_TRANSIT_POLICY_CHECKED; if (incred->flags.b.ok_as_delegate) cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_OK_AS_DELEGATE; if (incred->flags.b.anonymous) cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_ANONYMOUS; return 0; fail: free_ccred(cred); krb5_clear_error_message(context); return ret; } static cc_int32 get_cc_name(krb5_acc *a) { cc_string_t name; cc_int32 error; error = (*a->ccache->func->get_name)(a->ccache, &name); if (error) return error; a->cache_name = strdup(name->data); (*name->func->release)(name); if (a->cache_name == NULL) return ccErrNoMem; return ccNoError; } static const char* KRB5_CALLCONV acc_get_name(krb5_context context, krb5_ccache id) { krb5_acc *a = ACACHE(id); int32_t error; if (a->cache_name == NULL) { krb5_error_code ret; krb5_principal principal; char *name; ret = _krb5_get_default_principal_local(context, &principal); if (ret) return NULL; ret = krb5_unparse_name(context, principal, &name); krb5_free_principal(context, principal); if (ret) return NULL; error = (*a->context->func->create_new_ccache)(a->context, cc_credentials_v5, name, &a->ccache); krb5_xfree(name); if (error) return NULL; error = get_cc_name(a); if (error) return NULL; } return a->cache_name; } static krb5_error_code KRB5_CALLCONV acc_alloc(krb5_context context, krb5_ccache *id) { krb5_error_code ret; cc_int32 error; krb5_acc *a; ret = init_ccapi(context); if (ret) return ret; ret = krb5_data_alloc(&(*id)->data, sizeof(*a)); if (ret) { krb5_clear_error_message(context); return ret; } a = ACACHE(*id); error = (*init_func)(&a->context, ccapi_version_3, NULL, NULL); if (error) { krb5_data_free(&(*id)->data); return translate_cc_error(context, error); } a->cache_name = NULL; return 0; } static krb5_error_code KRB5_CALLCONV acc_resolve(krb5_context context, krb5_ccache *id, const char *res) { krb5_error_code ret; cc_int32 error; krb5_acc *a; ret = acc_alloc(context, id); if (ret) return ret; a = ACACHE(*id); error = (*a->context->func->open_ccache)(a->context, res, &a->ccache); if (error == ccNoError) { cc_time_t offset; error = get_cc_name(a); if (error != ccNoError) { acc_close(context, *id); *id = NULL; return translate_cc_error(context, error); } error = (*a->ccache->func->get_kdc_time_offset)(a->ccache, cc_credentials_v5, &offset); if (error == 0) context->kdc_sec_offset = offset; } else if (error == ccErrCCacheNotFound) { a->ccache = NULL; a->cache_name = NULL; } else { *id = NULL; return translate_cc_error(context, error); } return 0; } static krb5_error_code KRB5_CALLCONV acc_gen_new(krb5_context context, krb5_ccache *id) { krb5_error_code ret; krb5_acc *a; ret = acc_alloc(context, id); if (ret) return ret; a = ACACHE(*id); a->ccache = NULL; a->cache_name = NULL; return 0; } static krb5_error_code KRB5_CALLCONV acc_initialize(krb5_context context, krb5_ccache id, krb5_principal primary_principal) { krb5_acc *a = ACACHE(id); krb5_error_code ret; int32_t error; char *name; ret = krb5_unparse_name(context, primary_principal, &name); if (ret) return ret; if (a->cache_name == NULL) { error = (*a->context->func->create_new_ccache)(a->context, cc_credentials_v5, name, &a->ccache); free(name); if (error == ccNoError) error = get_cc_name(a); } else { cc_credentials_iterator_t iter; cc_credentials_t ccred; error = (*a->ccache->func->new_credentials_iterator)(a->ccache, &iter); if (error) { free(name); return translate_cc_error(context, error); } while (1) { error = (*iter->func->next)(iter, &ccred); if (error) break; (*a->ccache->func->remove_credentials)(a->ccache, ccred); (*ccred->func->release)(ccred); } (*iter->func->release)(iter); error = (*a->ccache->func->set_principal)(a->ccache, cc_credentials_v5, name); } if (error == 0 && context->kdc_sec_offset) error = (*a->ccache->func->set_kdc_time_offset)(a->ccache, cc_credentials_v5, context->kdc_sec_offset); return translate_cc_error(context, error); } static krb5_error_code KRB5_CALLCONV acc_close(krb5_context context, krb5_ccache id) { krb5_acc *a = ACACHE(id); if (a->ccache) { (*a->ccache->func->release)(a->ccache); a->ccache = NULL; } if (a->cache_name) { free(a->cache_name); a->cache_name = NULL; } if (a->context) { (*a->context->func->release)(a->context); a->context = NULL; } krb5_data_free(&id->data); return 0; } static krb5_error_code KRB5_CALLCONV acc_destroy(krb5_context context, krb5_ccache id) { krb5_acc *a = ACACHE(id); cc_int32 error = 0; if (a->ccache) { error = (*a->ccache->func->destroy)(a->ccache); a->ccache = NULL; } if (a->context) { error = (a->context->func->release)(a->context); a->context = NULL; } return translate_cc_error(context, error); } static krb5_error_code KRB5_CALLCONV acc_store_cred(krb5_context context, krb5_ccache id, krb5_creds *creds) { krb5_acc *a = ACACHE(id); cc_credentials_union cred; cc_credentials_v5_t v5cred; krb5_error_code ret; cc_int32 error; if (a->ccache == NULL) { krb5_set_error_message(context, KRB5_CC_NOTFOUND, N_("No API credential found", "")); return KRB5_CC_NOTFOUND; } cred.version = cc_credentials_v5; cred.credentials.credentials_v5 = &v5cred; ret = make_ccred_from_cred(context, creds, &v5cred); if (ret) return ret; error = (*a->ccache->func->store_credentials)(a->ccache, &cred); if (error) ret = translate_cc_error(context, error); free_ccred(&v5cred); return ret; } static krb5_error_code KRB5_CALLCONV acc_get_principal(krb5_context context, krb5_ccache id, krb5_principal *principal) { krb5_acc *a = ACACHE(id); krb5_error_code ret; int32_t error; cc_string_t name; if (a->ccache == NULL) { krb5_set_error_message(context, KRB5_CC_NOTFOUND, N_("No API credential found", "")); return KRB5_CC_NOTFOUND; } error = (*a->ccache->func->get_principal)(a->ccache, cc_credentials_v5, &name); if (error) return translate_cc_error(context, error); ret = krb5_parse_name(context, name->data, principal); (*name->func->release)(name); return ret; } static krb5_error_code KRB5_CALLCONV acc_get_first (krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor) { cc_credentials_iterator_t iter; krb5_acc *a = ACACHE(id); int32_t error; if (a->ccache == NULL) { krb5_set_error_message(context, KRB5_CC_NOTFOUND, N_("No API credential found", "")); return KRB5_CC_NOTFOUND; } error = (*a->ccache->func->new_credentials_iterator)(a->ccache, &iter); if (error) { krb5_clear_error_message(context); return ENOENT; } *cursor = iter; return 0; } static krb5_error_code KRB5_CALLCONV acc_get_next (krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor, krb5_creds *creds) { cc_credentials_iterator_t iter = *cursor; cc_credentials_t cred; krb5_error_code ret; int32_t error; while (1) { error = (*iter->func->next)(iter, &cred); if (error) return translate_cc_error(context, error); if (cred->data->version == cc_credentials_v5) break; (*cred->func->release)(cred); } ret = make_cred_from_ccred(context, cred->data->credentials.credentials_v5, creds); (*cred->func->release)(cred); return ret; } static krb5_error_code KRB5_CALLCONV acc_end_get (krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor) { cc_credentials_iterator_t iter = *cursor; (*iter->func->release)(iter); return 0; } static krb5_error_code KRB5_CALLCONV acc_remove_cred(krb5_context context, krb5_ccache id, krb5_flags which, krb5_creds *cred) { cc_credentials_iterator_t iter; krb5_acc *a = ACACHE(id); cc_credentials_t ccred; krb5_error_code ret; cc_int32 error; char *client, *server; if (a->ccache == NULL) { krb5_set_error_message(context, KRB5_CC_NOTFOUND, N_("No API credential found", "")); return KRB5_CC_NOTFOUND; } if (cred->client) { ret = krb5_unparse_name(context, cred->client, &client); if (ret) return ret; } else client = NULL; ret = krb5_unparse_name(context, cred->server, &server); if (ret) { free(client); return ret; } error = (*a->ccache->func->new_credentials_iterator)(a->ccache, &iter); if (error) { free(server); free(client); return translate_cc_error(context, error); } ret = KRB5_CC_NOTFOUND; while (1) { cc_credentials_v5_t *v5cred; error = (*iter->func->next)(iter, &ccred); if (error) break; if (ccred->data->version != cc_credentials_v5) goto next; v5cred = ccred->data->credentials.credentials_v5; if (client && strcmp(v5cred->client, client) != 0) goto next; if (strcmp(v5cred->server, server) != 0) goto next; (*a->ccache->func->remove_credentials)(a->ccache, ccred); ret = 0; next: (*ccred->func->release)(ccred); } (*iter->func->release)(iter); if (ret) krb5_set_error_message(context, ret, N_("Can't find credential %s in cache", "principal"), server); free(server); free(client); return ret; } static krb5_error_code KRB5_CALLCONV acc_set_flags(krb5_context context, krb5_ccache id, krb5_flags flags) { return 0; } static int KRB5_CALLCONV acc_get_version(krb5_context context, krb5_ccache id) { return 0; } struct cache_iter { cc_context_t context; cc_ccache_iterator_t iter; }; static krb5_error_code KRB5_CALLCONV acc_get_cache_first(krb5_context context, krb5_cc_cursor *cursor) { struct cache_iter *iter; krb5_error_code ret; cc_int32 error; ret = init_ccapi(context); if (ret) return ret; iter = calloc(1, sizeof(*iter)); if (iter == NULL) { krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } error = (*init_func)(&iter->context, ccapi_version_3, NULL, NULL); if (error) { free(iter); return translate_cc_error(context, error); } error = (*iter->context->func->new_ccache_iterator)(iter->context, &iter->iter); if (error) { free(iter); krb5_clear_error_message(context); return ENOENT; } *cursor = iter; return 0; } static krb5_error_code KRB5_CALLCONV acc_get_cache_next(krb5_context context, krb5_cc_cursor cursor, krb5_ccache *id) { struct cache_iter *iter = cursor; cc_ccache_t cache; krb5_acc *a; krb5_error_code ret; int32_t error; error = (*iter->iter->func->next)(iter->iter, &cache); if (error) return translate_cc_error(context, error); ret = _krb5_cc_allocate(context, &krb5_acc_ops, id); if (ret) { (*cache->func->release)(cache); return ret; } ret = acc_alloc(context, id); if (ret) { (*cache->func->release)(cache); free(*id); return ret; } a = ACACHE(*id); a->ccache = cache; error = get_cc_name(a); if (error) { acc_close(context, *id); *id = NULL; return translate_cc_error(context, error); } return 0; } static krb5_error_code KRB5_CALLCONV acc_end_cache_get(krb5_context context, krb5_cc_cursor cursor) { struct cache_iter *iter = cursor; (*iter->iter->func->release)(iter->iter); iter->iter = NULL; (*iter->context->func->release)(iter->context); iter->context = NULL; free(iter); return 0; } static krb5_error_code KRB5_CALLCONV acc_move(krb5_context context, krb5_ccache from, krb5_ccache to) { krb5_acc *afrom = ACACHE(from); krb5_acc *ato = ACACHE(to); int32_t error; if (ato->ccache == NULL) { cc_string_t name; error = (*afrom->ccache->func->get_principal)(afrom->ccache, cc_credentials_v5, &name); if (error) return translate_cc_error(context, error); error = (*ato->context->func->create_new_ccache)(ato->context, cc_credentials_v5, name->data, &ato->ccache); (*name->func->release)(name); if (error) return translate_cc_error(context, error); } error = (*ato->ccache->func->move)(afrom->ccache, ato->ccache); acc_destroy(context, from); return translate_cc_error(context, error); } static krb5_error_code KRB5_CALLCONV acc_get_default_name(krb5_context context, char **str) { krb5_error_code ret; cc_context_t cc; cc_string_t name; int32_t error; ret = init_ccapi(context); if (ret) return ret; error = (*init_func)(&cc, ccapi_version_3, NULL, NULL); if (error) return translate_cc_error(context, error); error = (*cc->func->get_default_ccache_name)(cc, &name); if (error) { (*cc->func->release)(cc); return translate_cc_error(context, error); } error = asprintf(str, "API:%s", name->data); (*name->func->release)(name); (*cc->func->release)(cc); if (error < 0 || *str == NULL) { krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); return ENOMEM; } return 0; } static krb5_error_code KRB5_CALLCONV acc_set_default(krb5_context context, krb5_ccache id) { krb5_acc *a = ACACHE(id); cc_int32 error; if (a->ccache == NULL) { krb5_set_error_message(context, KRB5_CC_NOTFOUND, N_("No API credential found", "")); return KRB5_CC_NOTFOUND; } error = (*a->ccache->func->set_default)(a->ccache); if (error) return translate_cc_error(context, error); return 0; } static krb5_error_code KRB5_CALLCONV acc_lastchange(krb5_context context, krb5_ccache id, krb5_timestamp *mtime) { krb5_acc *a = ACACHE(id); cc_int32 error; cc_time_t t; if (a->ccache == NULL) { krb5_set_error_message(context, KRB5_CC_NOTFOUND, N_("No API credential found", "")); return KRB5_CC_NOTFOUND; } error = (*a->ccache->func->get_change_time)(a->ccache, &t); if (error) return translate_cc_error(context, error); *mtime = t; return 0; } /** * Variable containing the API based credential cache implemention. * * @ingroup krb5_ccache */ KRB5_LIB_VARIABLE const krb5_cc_ops krb5_acc_ops = { KRB5_CC_OPS_VERSION, "API", acc_get_name, acc_resolve, acc_gen_new, acc_initialize, acc_destroy, acc_close, acc_store_cred, NULL, /* acc_retrieve */ acc_get_principal, acc_get_first, acc_get_next, acc_end_get, acc_remove_cred, acc_set_flags, acc_get_version, acc_get_cache_first, acc_get_cache_next, acc_end_cache_get, acc_move, acc_get_default_name, acc_set_default, acc_lastchange, NULL, NULL, }; #endif
Upload File
Create Folder