From 954c01728e0c7485b72c9a5d5737e5f6bd0cf0b9 Mon Sep 17 00:00:00 2001 From: Heimdal Import User Date: Mon, 11 Jul 2005 01:16:55 +0000 Subject: r8302: import mini HEIMDAL into the tree (This used to be commit 118be28a7aef233799956615a99d1a2a74dac175) --- source4/heimdal/lib/krb5/acache.c | 781 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 781 insertions(+) create mode 100644 source4/heimdal/lib/krb5/acache.c (limited to 'source4/heimdal/lib/krb5/acache.c') diff --git a/source4/heimdal/lib/krb5/acache.c b/source4/heimdal/lib/krb5/acache.c new file mode 100644 index 0000000000..75f5315c71 --- /dev/null +++ b/source4/heimdal/lib/krb5/acache.c @@ -0,0 +1,781 @@ +/* + * Copyright (c) 2004 - 2005 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * 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 +#ifdef HAVE_DLFCN_H +#include +#endif + +RCSID("$Id: acache.c,v 1.11 2005/06/16 19:32:44 lha Exp $"); + +/* XXX should we fetch these for each open ? */ +static HEIMDAL_MUTEX acc_mutex = HEIMDAL_MUTEX_INITIALIZER; +static cc_initialize_func init_func; + +#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 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_BADNAME }, + { ccNoError, 0 } +}; + +static krb5_error_code +translate_cc_error(krb5_context context, cc_int32 error) +{ + int i; + krb5_clear_error_string(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; + + HEIMDAL_MUTEX_lock(&acc_mutex); + if (init_func) { + HEIMDAL_MUTEX_unlock(&acc_mutex); + krb5_clear_error_string(context); + return 0; + } + + lib = krb5_config_get_string(context, NULL, + "libdefaults", "ccapi_library", + NULL); + if (lib == NULL) { +#ifdef __APPLE__ + lib = "/System/Library/Frameworks/Kerberos.framework/Kerberos"; +#else + lib = "/usr/lib/libkrb5_cc.so"; +#endif + } + +#ifdef HAVE_DLOPEN + cc_handle = dlopen(lib, 0); + if (cc_handle == NULL) { + HEIMDAL_MUTEX_unlock(&acc_mutex); + krb5_set_error_string(context, "Failed to load %s", lib); + return ccErrServerUnavailable; + } + + init_func = dlsym(cc_handle, "cc_initialize"); + HEIMDAL_MUTEX_unlock(&acc_mutex); + if (init_func == NULL) { + krb5_set_error_string(context, "Failed to find cc_initialize" + "in %s: %s", lib, dlerror()); + dlclose(cc_handle); + return ccErrServerUnavailable; + } + + return 0; +#else + HEIMDAL_MUTEX_unlock(&acc_mutex); + krb5_set_error_string(context, "no support for shared object"); + return ccErrServerUnavailable; +#endif +} + +static krb5_error_code +make_cred_from_ccred(krb5_context context, + const cc_credentials_v5_t *incred, + krb5_creds *cred) +{ + krb5_error_code ret; + 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 = malloc(sizeof(cred->authdata.val[0]) * i); + if (cred->authdata.val == NULL) + goto nomem; + cred->authdata.len = i; + memset(cred->authdata.val, 0, sizeof(cred->authdata.val[0]) * 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 = malloc(sizeof(cred->addresses.val[0]) * i); + if (cred->addresses.val == NULL) + goto nomem; + cred->addresses.len = i; + memset(cred->addresses.val, 0, sizeof(cred->addresses.val[0]) * 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.b = int2TicketFlags(incred->ticket_flags); /* XXX */ + return 0; + +nomem: + ret = ENOMEM; + krb5_set_error_string(context, "malloc - out of memory"); + +fail: + krb5_free_creds_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; + int 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)); + 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) { + 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 = TicketFlags2int(incred->flags.b); /* XXX */ + return 0; + +fail: + free_ccred(cred); + + krb5_clear_error_string(context); + return ret; +} + +static char * +get_cc_name(cc_ccache_t cache) +{ + cc_string_t name; + cc_int32 error; + char *str; + + error = (*cache->func->get_name)(cache, &name); + if (error) + return NULL; + + str = strdup(name->data); + (*name->func->release)(name); + return str; +} + + +static const char* +acc_get_name(krb5_context context, + krb5_ccache id) +{ + krb5_acc *a = ACACHE(id); + static char n[255]; + char *name; + + name = get_cc_name(a->ccache); + if (name == NULL) { + krb5_set_error_string(context, "malloc: out of memory"); + return NULL; + } + strlcpy(n, name, sizeof(n)); + free(name); + return n; +} + +static krb5_error_code +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_string(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 +get_default_principal(krb5_context context, char **p) +{ + krb5_error_code ret; + krb5_principal principal; + + *p = NULL; + + ret = _krb5_get_default_principal_local(context, &principal); + if (ret) + return ret; + + ret = krb5_unparse_name(context, principal, p); + krb5_free_principal(context, principal); + return ret; +} + +static krb5_error_code +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); + + if (res == NULL || res[0] == '\0') { + error = (*a->context->func->open_default_ccache)(a->context, + &a->ccache); + if (error == ccErrCCacheNotFound) { + char *p; + + ret = get_default_principal(context, &p); + if (ret == 0) { + error = (*a->context->func->create_default_ccache)(a->context, + cc_credentials_v5, + p, + &a->ccache); + free(p); + } + } + if (error == 0) + a->cache_name = get_cc_name(a->ccache); + } else { + error = (*a->context->func->open_ccache)(a->context, res, &a->ccache); + if (error == 0) + a->cache_name = strdup(res); + } + if (error != 0) { + *id = NULL; + return translate_cc_error(context, error); + } + if (a->cache_name == NULL) { + acc_close(context, *id); + *id = NULL; + krb5_set_error_string(context, "malloc: out of memory"); + return ENOMEM; + } + + return 0; +} + +static krb5_error_code +acc_gen_new(krb5_context context, krb5_ccache *id) +{ + krb5_error_code ret; + cc_int32 error; + krb5_acc *a; + char *p; + + ret = get_default_principal(context, &p); + + ret = acc_alloc(context, id); + if (ret) { + free(p); + return ret; + } + + a = ACACHE(*id); + + error = (*a->context->func->create_new_ccache)(a->context, + cc_credentials_v5, + p, &a->ccache); + free(p); + if (error) { + *id = NULL; + return translate_cc_error(context, error); + } + a->cache_name = get_cc_name(a->ccache); + if (a->cache_name == NULL) { + acc_close(context, *id); + *id = NULL; + krb5_set_error_string(context, "malloc: out of memory"); + return ENOMEM; + } + return 0; +} + +static krb5_error_code +acc_initialize(krb5_context context, + krb5_ccache id, + krb5_principal primary_principal) +{ + cc_credentials_iterator_t iter; + krb5_acc *a = ACACHE(id); + cc_credentials_t ccred; + krb5_error_code ret; + int32_t error; + char *name; + + ret = krb5_unparse_name(context, primary_principal, &name); + if (ret) + return ret; + + if (a->ccache == NULL) { + error = (*a->context->func->create_new_ccache)(a->context, + cc_credentials_v5, + name, + &a->ccache); + } else { + + 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); + } + + free(name); + + return translate_cc_error(context, error); +} + +static krb5_error_code +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; + } + (*a->context->func->release)(a->context); + a->context = NULL; + krb5_data_free(&id->data); + return 0; +} + +static krb5_error_code +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; + } + return translate_cc_error(context, error); +} + +static krb5_error_code +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; + + 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 +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) + return ENOENT; + + 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 +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; + + error = (*a->ccache->func->new_credentials_iterator)(a->ccache, &iter); + if (error) + return ENOENT; + *cursor = iter; + return 0; +} + + +static krb5_error_code +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 +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 +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 (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_string(context, "Can't find credential %s in cache", + server); + free(server); + free(client); + + return ret; +} + +static krb5_error_code +acc_set_flags(krb5_context context, + krb5_ccache id, + krb5_flags flags) +{ + return 0; +} + +static krb5_error_code +acc_get_version(krb5_context context, + krb5_ccache id) +{ + return 0; +} + +const krb5_cc_ops krb5_acc_ops = { + "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 +}; -- cgit From 4019064c5d866015a0d78b32dd051ec1dacf8ebf Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 25 Oct 2005 13:43:37 +0000 Subject: r11294: Update Heimdal in Samba4 to lorikeet-heimdal (which is in turn updated to CVS of 2005-10-24). Andrew Bartlett (This used to be commit 939d4f340feaad15d0a6a5da79feba2b2558f174) --- source4/heimdal/lib/krb5/acache.c | 110 +++++++++++++++++++++++++++++++++++--- 1 file changed, 103 insertions(+), 7 deletions(-) (limited to 'source4/heimdal/lib/krb5/acache.c') diff --git a/source4/heimdal/lib/krb5/acache.c b/source4/heimdal/lib/krb5/acache.c index 75f5315c71..7cf2c65d89 100644 --- a/source4/heimdal/lib/krb5/acache.c +++ b/source4/heimdal/lib/krb5/acache.c @@ -37,7 +37,7 @@ #include #endif -RCSID("$Id: acache.c,v 1.11 2005/06/16 19:32:44 lha Exp $"); +RCSID("$Id: acache.c,v 1.14 2005/10/03 08:44:18 lha Exp $"); /* XXX should we fetch these for each open ? */ static HEIMDAL_MUTEX acc_mutex = HEIMDAL_MUTEX_INITIALIZER; @@ -67,7 +67,7 @@ static const struct { { ccErrContextNotFound, KRB5_CC_NOTFOUND }, { ccIteratorEnd, KRB5_CC_END }, { ccErrNoMem, KRB5_CC_NOMEM }, - { ccErrServerUnavailable, KRB5_CC_BADNAME }, + { ccErrServerUnavailable, KRB5_CC_NOSUPP }, { ccNoError, 0 } }; @@ -110,7 +110,7 @@ init_ccapi(krb5_context context) if (cc_handle == NULL) { HEIMDAL_MUTEX_unlock(&acc_mutex); krb5_set_error_string(context, "Failed to load %s", lib); - return ccErrServerUnavailable; + return KRB5_CC_NOSUPP; } init_func = dlsym(cc_handle, "cc_initialize"); @@ -119,14 +119,14 @@ init_ccapi(krb5_context context) krb5_set_error_string(context, "Failed to find cc_initialize" "in %s: %s", lib, dlerror()); dlclose(cc_handle); - return ccErrServerUnavailable; + return KRB5_CC_NOSUPP; } return 0; #else HEIMDAL_MUTEX_unlock(&acc_mutex); krb5_set_error_string(context, "no support for shared object"); - return ccErrServerUnavailable; + return KRB5_CC_NOSUPP; #endif } @@ -633,8 +633,10 @@ acc_get_first (krb5_context context, int32_t error; error = (*a->ccache->func->new_credentials_iterator)(a->ccache, &iter); - if (error) + if (error) { + krb5_clear_error_string(context); return ENOENT; + } *cursor = iter; return 0; } @@ -761,6 +763,97 @@ acc_get_version(krb5_context context, return 0; } +struct cache_iter { + cc_context_t context; + cc_ccache_iterator_t iter; +}; + +static krb5_error_code +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_string(context, "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_string(context); + return ENOENT; + } + *cursor = iter; + return 0; +} + +static krb5_error_code +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; + + a->cache_name = get_cc_name(a->ccache); + if (a->cache_name == NULL) { + acc_close(context, *id); + *id = NULL; + krb5_set_error_string(context, "malloc: out of memory"); + return ENOMEM; + } + return 0; +} + +static krb5_error_code +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; +} + const krb5_cc_ops krb5_acc_ops = { "API", acc_get_name, @@ -777,5 +870,8 @@ const krb5_cc_ops krb5_acc_ops = { acc_end_get, acc_remove_cred, acc_set_flags, - acc_get_version + acc_get_version, + acc_get_cache_first, + acc_get_cache_next, + acc_end_cache_get }; -- cgit From c33f6b2c370379dfd010600adc59e7439f1318f7 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 24 Apr 2006 09:36:24 +0000 Subject: r15192: Update Samba4 to use current lorikeet-heimdal. Andrew Bartlett (This used to be commit f0e538126c5cb29ca14ad0d8281eaa0a715ed94f) --- source4/heimdal/lib/krb5/acache.c | 64 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 61 insertions(+), 3 deletions(-) (limited to 'source4/heimdal/lib/krb5/acache.c') diff --git a/source4/heimdal/lib/krb5/acache.c b/source4/heimdal/lib/krb5/acache.c index 7cf2c65d89..b38104fc2d 100644 --- a/source4/heimdal/lib/krb5/acache.c +++ b/source4/heimdal/lib/krb5/acache.c @@ -37,7 +37,7 @@ #include #endif -RCSID("$Id: acache.c,v 1.14 2005/10/03 08:44:18 lha Exp $"); +RCSID("$Id: acache.c,v 1.15 2006/03/27 04:22:23 lha Exp $"); /* XXX should we fetch these for each open ? */ static HEIMDAL_MUTEX acc_mutex = HEIMDAL_MUTEX_INITIALIZER; @@ -218,7 +218,36 @@ make_cred_from_ccred(krb5_context context, } } - cred->flags.b = int2TicketFlags(incred->ticket_flags); /* XXX */ + 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: @@ -310,7 +339,36 @@ make_ccred_from_cred(krb5_context context, } cred->addresses[i] = NULL; - cred->ticket_flags = TicketFlags2int(incred->flags.b); /* XXX */ + 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: -- cgit From 3c1e780ec7e16dc6667402bbc65708bf9a5c062f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 7 Nov 2006 06:59:56 +0000 Subject: r19604: This is a massive commit, and I appologise in advance for it's size. This merges Samba4 with lorikeet-heimdal, which itself has been tracking Heimdal CVS for the past couple of weeks. This is such a big change because Heimdal reorganised it's internal structures, with the mechglue merge, and because many of our 'wishes' have been granted: we now have DCE_STYLE GSSAPI, send_to_kdc hooks and many other features merged into the mainline code. We have adapted to upstream's choice of API in these cases. In gensec_gssapi and gensec_krb5, we either expect a valid PAC, or NO PAC. This matches windows behavour. We also have an option to require the PAC to be present (which allows us to automate the testing of this code). This also includes a restructure of how the kerberos dependencies are handled, due to the fallout of the merge. Andrew Bartlett (This used to be commit 4826f1735197c2a471d771495e6d4c1051b4c471) --- source4/heimdal/lib/krb5/acache.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/heimdal/lib/krb5/acache.c') diff --git a/source4/heimdal/lib/krb5/acache.c b/source4/heimdal/lib/krb5/acache.c index b38104fc2d..004926bc89 100644 --- a/source4/heimdal/lib/krb5/acache.c +++ b/source4/heimdal/lib/krb5/acache.c @@ -37,7 +37,7 @@ #include #endif -RCSID("$Id: acache.c,v 1.15 2006/03/27 04:22:23 lha Exp $"); +RCSID("$Id: acache.c,v 1.16 2006/10/19 11:41:38 lha Exp $"); /* XXX should we fetch these for each open ? */ static HEIMDAL_MUTEX acc_mutex = HEIMDAL_MUTEX_INITIALIZER; @@ -113,7 +113,7 @@ init_ccapi(krb5_context context) return KRB5_CC_NOSUPP; } - init_func = dlsym(cc_handle, "cc_initialize"); + init_func = (cc_initialize_func)dlsym(cc_handle, "cc_initialize"); HEIMDAL_MUTEX_unlock(&acc_mutex); if (init_func == NULL) { krb5_set_error_string(context, "Failed to find cc_initialize" -- cgit From f7242f643763ccb6e10801af4ce53d0873e2d3e1 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 10 Jan 2007 01:57:32 +0000 Subject: r20640: Commit part 2/2 Update Heimdal to match current lorikeet-heimdal. This includes integrated PAC hooks, so Samba doesn't have to handle this any more. This also brings in the PKINIT code, hence so many new files. Andrew Bartlett (This used to be commit 351f7040f7bb73b9a60b22b564686f7c2f98a729) --- source4/heimdal/lib/krb5/acache.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'source4/heimdal/lib/krb5/acache.c') diff --git a/source4/heimdal/lib/krb5/acache.c b/source4/heimdal/lib/krb5/acache.c index 004926bc89..d20c24699b 100644 --- a/source4/heimdal/lib/krb5/acache.c +++ b/source4/heimdal/lib/krb5/acache.c @@ -37,7 +37,7 @@ #include #endif -RCSID("$Id: acache.c,v 1.16 2006/10/19 11:41:38 lha Exp $"); +RCSID("$Id: acache.c,v 1.17 2007/01/08 15:31:01 lha Exp $"); /* XXX should we fetch these for each open ? */ static HEIMDAL_MUTEX acc_mutex = HEIMDAL_MUTEX_INITIALIZER; @@ -106,7 +106,12 @@ init_ccapi(krb5_context context) } #ifdef HAVE_DLOPEN - cc_handle = dlopen(lib, 0); + +#ifndef RTLD_LAZY +#define RTLD_LAZY 0 +#endif + + cc_handle = dlopen(lib, RTLD_LAZY); if (cc_handle == NULL) { HEIMDAL_MUTEX_unlock(&acc_mutex); krb5_set_error_string(context, "Failed to load %s", lib); -- cgit From 91adebe749beb0dc23cacaea316cb2b724776aad Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 13 Jun 2007 05:44:24 +0000 Subject: r23456: Update Samba4 to current lorikeet-heimdal. Andrew Bartlett (This used to be commit ae0f81ab235c72cceb120bcdeb051a483cf3cc4f) --- source4/heimdal/lib/krb5/acache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/heimdal/lib/krb5/acache.c') diff --git a/source4/heimdal/lib/krb5/acache.c b/source4/heimdal/lib/krb5/acache.c index d20c24699b..999ce7f120 100644 --- a/source4/heimdal/lib/krb5/acache.c +++ b/source4/heimdal/lib/krb5/acache.c @@ -37,7 +37,7 @@ #include #endif -RCSID("$Id: acache.c,v 1.17 2007/01/08 15:31:01 lha Exp $"); +RCSID("$Id: acache.c 19764 2007-01-08 15:31:01Z lha $"); /* XXX should we fetch these for each open ? */ static HEIMDAL_MUTEX acc_mutex = HEIMDAL_MUTEX_INITIALIZER; -- cgit From 9e6b0c28712ee77ce878809c8576826a3ba08d95 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 19 Mar 2008 10:17:42 +1100 Subject: Merge lorikeet-heimdal -r 787 into Samba4 tree. Andrew Bartlett (This used to be commit d88b530522d3cef67c24422bd5182fb875d87ee2) --- source4/heimdal/lib/krb5/acache.c | 270 +++++++++++++++++++++++--------------- 1 file changed, 167 insertions(+), 103 deletions(-) (limited to 'source4/heimdal/lib/krb5/acache.c') diff --git a/source4/heimdal/lib/krb5/acache.c b/source4/heimdal/lib/krb5/acache.c index 999ce7f120..775239cf6d 100644 --- a/source4/heimdal/lib/krb5/acache.c +++ b/source4/heimdal/lib/krb5/acache.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 - 2005 Kungliga Tekniska Högskolan + * Copyright (c) 2004 - 2007 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -37,7 +37,7 @@ #include #endif -RCSID("$Id: acache.c 19764 2007-01-08 15:31:01Z lha $"); +RCSID("$Id: acache.c 22669 2008-03-09 23:39:25Z lha $"); /* XXX should we fetch these for each open ? */ static HEIMDAL_MUTEX acc_mutex = HEIMDAL_MUTEX_INITIALIZER; @@ -188,11 +188,10 @@ make_cred_from_ccred(krb5_context context, ; if (i) { - cred->authdata.val = malloc(sizeof(cred->authdata.val[0]) * i); + cred->authdata.val = calloc(i, sizeof(cred->authdata.val[0])); if (cred->authdata.val == NULL) goto nomem; cred->authdata.len = i; - memset(cred->authdata.val, 0, sizeof(cred->authdata.val[0]) * 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, @@ -207,11 +206,10 @@ make_cred_from_ccred(krb5_context context, ; if (i) { - cred->addresses.val = malloc(sizeof(cred->addresses.val[0]) * i); + cred->addresses.val = calloc(i, sizeof(cred->addresses.val[0])); if (cred->addresses.val == NULL) goto nomem; cred->addresses.len = i; - memset(cred->addresses.val, 0, sizeof(cred->addresses.val[0]) * i); for (i = 0; i < cred->addresses.len; i++) { cred->addresses.val[i].addr_type = incred->addresses[i]->type; @@ -260,7 +258,7 @@ nomem: krb5_set_error_string(context, "malloc - out of memory"); fail: - krb5_free_creds_contents(context, cred); + krb5_free_cred_contents(context, cred); return ret; } @@ -331,6 +329,10 @@ make_ccred_from_cred(krb5_context context, 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); @@ -383,20 +385,21 @@ fail: return ret; } -static char * -get_cc_name(cc_ccache_t cache) +static cc_int32 +get_cc_name(krb5_acc *a) { cc_string_t name; cc_int32 error; - char *str; - error = (*cache->func->get_name)(cache, &name); + error = (*a->ccache->func->get_name)(a->ccache, &name); if (error) - return NULL; + return error; - str = strdup(name->data); + a->cache_name = strdup(name->data); (*name->func->release)(name); - return str; + if (a->cache_name == NULL) + return ccErrNoMem; + return ccNoError; } @@ -405,17 +408,36 @@ acc_get_name(krb5_context context, krb5_ccache id) { krb5_acc *a = ACACHE(id); - static char n[255]; - char *name; + int32_t error; - name = get_cc_name(a->ccache); - if (name == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); - return NULL; - } - strlcpy(n, name, sizeof(n)); - free(name); - return n; + 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 @@ -448,23 +470,6 @@ acc_alloc(krb5_context context, krb5_ccache *id) return 0; } -static krb5_error_code -get_default_principal(krb5_context context, char **p) -{ - krb5_error_code ret; - krb5_principal principal; - - *p = NULL; - - ret = _krb5_get_default_principal_local(context, &principal); - if (ret) - return ret; - - ret = krb5_unparse_name(context, principal, p); - krb5_free_principal(context, principal); - return ret; -} - static krb5_error_code acc_resolve(krb5_context context, krb5_ccache *id, const char *res) { @@ -478,38 +483,22 @@ acc_resolve(krb5_context context, krb5_ccache *id, const char *res) a = ACACHE(*id); - if (res == NULL || res[0] == '\0') { - error = (*a->context->func->open_default_ccache)(a->context, - &a->ccache); - if (error == ccErrCCacheNotFound) { - char *p; - - ret = get_default_principal(context, &p); - if (ret == 0) { - error = (*a->context->func->create_default_ccache)(a->context, - cc_credentials_v5, - p, - &a->ccache); - free(p); - } + error = (*a->context->func->open_ccache)(a->context, res, &a->ccache); + if (error == ccNoError) { + error = get_cc_name(a); + if (error != ccNoError) { + acc_close(context, *id); + *id = NULL; + return translate_cc_error(context, error); } - if (error == 0) - a->cache_name = get_cc_name(a->ccache); + } else if (error == ccErrCCacheNotFound) { + a->ccache = NULL; + a->cache_name = NULL; + error = 0; } else { - error = (*a->context->func->open_ccache)(a->context, res, &a->ccache); - if (error == 0) - a->cache_name = strdup(res); - } - if (error != 0) { *id = NULL; return translate_cc_error(context, error); } - if (a->cache_name == NULL) { - acc_close(context, *id); - *id = NULL; - krb5_set_error_string(context, "malloc: out of memory"); - return ENOMEM; - } return 0; } @@ -518,35 +507,17 @@ static krb5_error_code acc_gen_new(krb5_context context, krb5_ccache *id) { krb5_error_code ret; - cc_int32 error; krb5_acc *a; - char *p; - - ret = get_default_principal(context, &p); ret = acc_alloc(context, id); - if (ret) { - free(p); + if (ret) return ret; - } a = ACACHE(*id); - error = (*a->context->func->create_new_ccache)(a->context, - cc_credentials_v5, - p, &a->ccache); - free(p); - if (error) { - *id = NULL; - return translate_cc_error(context, error); - } - a->cache_name = get_cc_name(a->ccache); - if (a->cache_name == NULL) { - acc_close(context, *id); - *id = NULL; - krb5_set_error_string(context, "malloc: out of memory"); - return ENOMEM; - } + a->ccache = NULL; + a->cache_name = NULL; + return 0; } @@ -555,9 +526,7 @@ acc_initialize(krb5_context context, krb5_ccache id, krb5_principal primary_principal) { - cc_credentials_iterator_t iter; krb5_acc *a = ACACHE(id); - cc_credentials_t ccred; krb5_error_code ret; int32_t error; char *name; @@ -566,12 +535,17 @@ acc_initialize(krb5_context context, if (ret) return ret; - if (a->ccache == NULL) { + if (a->cache_name == NULL) { error = (*a->context->func->create_new_ccache)(a->context, cc_credentials_v5, name, &a->ccache); - } else { + 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) { @@ -593,8 +567,6 @@ acc_initialize(krb5_context context, name); } - free(name); - return translate_cc_error(context, error); } @@ -629,6 +601,10 @@ acc_destroy(krb5_context context, 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); } @@ -643,6 +619,11 @@ acc_store_cred(krb5_context context, krb5_error_code ret; cc_int32 error; + if (a->ccache == NULL) { + krb5_set_error_string(context, "No API credential found"); + return KRB5_CC_NOTFOUND; + } + cred.version = cc_credentials_v5; cred.credentials.credentials_v5 = &v5cred; @@ -671,8 +652,10 @@ acc_get_principal(krb5_context context, int32_t error; cc_string_t name; - if (a->ccache == NULL) - return ENOENT; + if (a->ccache == NULL) { + krb5_set_error_string(context, "No API credential found"); + return KRB5_CC_NOTFOUND; + } error = (*a->ccache->func->get_principal)(a->ccache, cc_credentials_v5, @@ -695,6 +678,11 @@ acc_get_first (krb5_context context, krb5_acc *a = ACACHE(id); int32_t error; + if (a->ccache == NULL) { + krb5_set_error_string(context, "No API credential found"); + return KRB5_CC_NOTFOUND; + } + error = (*a->ccache->func->new_credentials_iterator)(a->ccache, &iter); if (error) { krb5_clear_error_string(context); @@ -755,6 +743,11 @@ acc_remove_cred(krb5_context context, cc_int32 error; char *client, *server; + if (a->ccache == NULL) { + krb5_set_error_string(context, "No API credential found"); + return KRB5_CC_NOTFOUND; + } + if (cred->client) { ret = krb5_unparse_name(context, cred->client, &client); if (ret) @@ -894,12 +887,11 @@ acc_get_cache_next(krb5_context context, krb5_cc_cursor cursor, krb5_ccache *id) a = ACACHE(*id); a->ccache = cache; - a->cache_name = get_cc_name(a->ccache); - if (a->cache_name == NULL) { + error = get_cc_name(a); + if (error) { acc_close(context, *id); *id = NULL; - krb5_set_error_string(context, "malloc: out of memory"); - return ENOMEM; + return translate_cc_error(context, error); } return 0; } @@ -917,6 +909,76 @@ acc_end_cache_get(krb5_context context, krb5_cc_cursor cursor) return 0; } +static krb5_error_code +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); + return translate_cc_error(context, error); +} + +static krb5_error_code +acc_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); + } + + asprintf(str, "API:%s", name->data); + (*name->func->release)(name); + (*cc->func->release)(cc); + + if (*str == NULL) { + krb5_set_error_string(context, "out of memory"); + return ENOMEM; + } + return 0; +} + + +/** + * Variable containing the API based credential cache implemention. + * + * @ingroup krb5_ccache + */ + const krb5_cc_ops krb5_acc_ops = { "API", acc_get_name, @@ -936,5 +998,7 @@ const krb5_cc_ops krb5_acc_ops = { acc_get_version, acc_get_cache_first, acc_get_cache_next, - acc_end_cache_get + acc_end_cache_get, + acc_move, + acc_default_name }; -- cgit From a925f039ee382df0f3be434108416bab0d17e8c0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 1 Aug 2008 07:08:51 +0200 Subject: heimdal: update to lorikeet-heimdal rev 801 metze (This used to be commit d6c54a66fb23c784ef221a3c1cf766b72bdb5a0b) --- source4/heimdal/lib/krb5/acache.c | 71 +++++++++++++++++++++++++++------------ 1 file changed, 50 insertions(+), 21 deletions(-) (limited to 'source4/heimdal/lib/krb5/acache.c') diff --git a/source4/heimdal/lib/krb5/acache.c b/source4/heimdal/lib/krb5/acache.c index 775239cf6d..8dd8687005 100644 --- a/source4/heimdal/lib/krb5/acache.c +++ b/source4/heimdal/lib/krb5/acache.c @@ -37,7 +37,7 @@ #include #endif -RCSID("$Id: acache.c 22669 2008-03-09 23:39:25Z lha $"); +RCSID("$Id: acache.c 23316 2008-06-23 04:32:32Z lha $"); /* XXX should we fetch these for each open ? */ static HEIMDAL_MUTEX acc_mutex = HEIMDAL_MUTEX_INITIALIZER; @@ -68,6 +68,7 @@ static const struct { { ccIteratorEnd, KRB5_CC_END }, { ccErrNoMem, KRB5_CC_NOMEM }, { ccErrServerUnavailable, KRB5_CC_NOSUPP }, + { ccErrInvalidCCache, KRB5_CC_BADNAME }, { ccNoError, 0 } }; @@ -114,15 +115,17 @@ init_ccapi(krb5_context context) cc_handle = dlopen(lib, RTLD_LAZY); if (cc_handle == NULL) { HEIMDAL_MUTEX_unlock(&acc_mutex); - krb5_set_error_string(context, "Failed to load %s", lib); + krb5_set_error_message(context, KRB5_CC_NOSUPP, + "Failed to load %s", lib); return KRB5_CC_NOSUPP; } init_func = (cc_initialize_func)dlsym(cc_handle, "cc_initialize"); HEIMDAL_MUTEX_unlock(&acc_mutex); if (init_func == NULL) { - krb5_set_error_string(context, "Failed to find cc_initialize" - "in %s: %s", lib, dlerror()); + krb5_set_error_message(context, KRB5_CC_NOSUPP, + "Failed to find cc_initialize" + "in %s: %s", lib, dlerror()); dlclose(cc_handle); return KRB5_CC_NOSUPP; } @@ -130,7 +133,7 @@ init_ccapi(krb5_context context) return 0; #else HEIMDAL_MUTEX_unlock(&acc_mutex); - krb5_set_error_string(context, "no support for shared object"); + krb5_set_error_message(context, KRB5_CC_NOSUPP, "no support for shared object"); return KRB5_CC_NOSUPP; #endif } @@ -141,7 +144,7 @@ make_cred_from_ccred(krb5_context context, krb5_creds *cred) { krb5_error_code ret; - int i; + unsigned int i; memset(cred, 0, sizeof(*cred)); @@ -255,7 +258,7 @@ make_cred_from_ccred(krb5_context context, nomem: ret = ENOMEM; - krb5_set_error_string(context, "malloc - out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); fail: krb5_free_cred_contents(context, cred); @@ -584,8 +587,10 @@ acc_close(krb5_context context, free(a->cache_name); a->cache_name = NULL; } - (*a->context->func->release)(a->context); - a->context = NULL; + if (a->context) { + (*a->context->func->release)(a->context); + a->context = NULL; + } krb5_data_free(&id->data); return 0; } @@ -620,7 +625,8 @@ acc_store_cred(krb5_context context, cc_int32 error; if (a->ccache == NULL) { - krb5_set_error_string(context, "No API credential found"); + krb5_set_error_message(context, KRB5_CC_NOTFOUND, + "No API credential found"); return KRB5_CC_NOTFOUND; } @@ -653,7 +659,8 @@ acc_get_principal(krb5_context context, cc_string_t name; if (a->ccache == NULL) { - krb5_set_error_string(context, "No API credential found"); + krb5_set_error_message(context, KRB5_CC_NOTFOUND, + "No API credential found"); return KRB5_CC_NOTFOUND; } @@ -679,7 +686,8 @@ acc_get_first (krb5_context context, int32_t error; if (a->ccache == NULL) { - krb5_set_error_string(context, "No API credential found"); + krb5_set_error_message(context, KRB5_CC_NOTFOUND, + "No API credential found"); return KRB5_CC_NOTFOUND; } @@ -744,7 +752,8 @@ acc_remove_cred(krb5_context context, char *client, *server; if (a->ccache == NULL) { - krb5_set_error_string(context, "No API credential found"); + krb5_set_error_message(context, KRB5_CC_NOTFOUND, + "No API credential found"); return KRB5_CC_NOTFOUND; } @@ -796,8 +805,8 @@ acc_remove_cred(krb5_context context, (*iter->func->release)(iter); if (ret) - krb5_set_error_string(context, "Can't find credential %s in cache", - server); + krb5_set_error_message(context, ret, + "Can't find credential %s in cache", server); free(server); free(client); @@ -812,7 +821,7 @@ acc_set_flags(krb5_context context, return 0; } -static krb5_error_code +static int acc_get_version(krb5_context context, krb5_ccache id) { @@ -837,7 +846,7 @@ acc_get_cache_first(krb5_context context, krb5_cc_cursor *cursor) iter = calloc(1, sizeof(*iter)); if (iter == NULL) { - krb5_set_error_string(context, "malloc - out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -940,7 +949,7 @@ acc_move(krb5_context context, krb5_ccache from, krb5_ccache to) } static krb5_error_code -acc_default_name(krb5_context context, char **str) +acc_get_default_name(krb5_context context, char **str) { krb5_error_code ret; cc_context_t cc; @@ -966,12 +975,30 @@ acc_default_name(krb5_context context, char **str) (*cc->func->release)(cc); if (*str == NULL) { - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ENOMEM, "out of memory"); return ENOMEM; } return 0; } +static krb5_error_code +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, + "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; +} /** * Variable containing the API based credential cache implemention. @@ -979,7 +1006,8 @@ acc_default_name(krb5_context context, char **str) * @ingroup krb5_ccache */ -const krb5_cc_ops krb5_acc_ops = { +KRB5_LIB_VARIABLE const krb5_cc_ops krb5_acc_ops = { + KRB5_CC_OPS_VERSION, "API", acc_get_name, acc_resolve, @@ -1000,5 +1028,6 @@ const krb5_cc_ops krb5_acc_ops = { acc_get_cache_next, acc_end_cache_get, acc_move, - acc_default_name + acc_get_default_name, + acc_set_default }; -- cgit From 243321b4bbe273cf3a9105ca132caa2b53e2f263 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 26 Aug 2008 19:35:52 +0200 Subject: heimdal: import heimdal's trunk svn rev 23697 + lorikeet-heimdal patches This is based on f56a3b1846c7d462542f2e9527f4d0ed8a34748d in my heimdal-wip repo. metze (This used to be commit 467a1f2163a63cdf1a4c83a69473db50e8794f53) --- source4/heimdal/lib/krb5/acache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/heimdal/lib/krb5/acache.c') diff --git a/source4/heimdal/lib/krb5/acache.c b/source4/heimdal/lib/krb5/acache.c index 8dd8687005..fb38abedfd 100644 --- a/source4/heimdal/lib/krb5/acache.c +++ b/source4/heimdal/lib/krb5/acache.c @@ -37,7 +37,7 @@ #include #endif -RCSID("$Id: acache.c 23316 2008-06-23 04:32:32Z lha $"); +RCSID("$Id$"); /* XXX should we fetch these for each open ? */ static HEIMDAL_MUTEX acc_mutex = HEIMDAL_MUTEX_INITIALIZER; -- cgit