summaryrefslogtreecommitdiffstats
path: root/crypto/heimdal/lib/krb5/acache.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/heimdal/lib/krb5/acache.c')
-rw-r--r--crypto/heimdal/lib/krb5/acache.c447
1 files changed, 304 insertions, 143 deletions
diff --git a/crypto/heimdal/lib/krb5/acache.c b/crypto/heimdal/lib/krb5/acache.c
index 30a6d90..19eeecd 100644
--- a/crypto/heimdal/lib/krb5/acache.c
+++ b/crypto/heimdal/lib/krb5/acache.c
@@ -1,34 +1,36 @@
/*
- * Copyright (c) 2004 - 2007 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden).
- * All rights reserved.
+ * Copyright (c) 2004 - 2007 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:
+ * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
*
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
*
- * 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.
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
*
- * 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.
+ * 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.
*
- * 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.
+ * 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"
@@ -37,14 +39,15 @@
#include <dlfcn.h>
#endif
-RCSID("$Id: acache.c 22099 2007-12-03 17:14:34Z lha $");
+#ifndef KCM_IS_API_CACHE
-/* XXX should we fetch these for each open ? */
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;
+static void *cc_handle;
#endif
typedef struct krb5_acc {
@@ -53,7 +56,7 @@ typedef struct krb5_acc {
cc_ccache_t ccache;
} krb5_acc;
-static krb5_error_code acc_close(krb5_context, krb5_ccache);
+static krb5_error_code KRB5_CALLCONV acc_close(krb5_context, krb5_ccache);
#define ACACHE(X) ((krb5_acc *)(X)->data.data)
@@ -68,14 +71,15 @@ static const struct {
{ 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)
{
- int i;
- krb5_clear_error_string(context);
+ 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;
@@ -85,21 +89,25 @@ translate_cc_error(krb5_context context, cc_int32 error)
static krb5_error_code
init_ccapi(krb5_context context)
{
- const char *lib;
+ const char *lib = NULL;
HEIMDAL_MUTEX_lock(&acc_mutex);
if (init_func) {
HEIMDAL_MUTEX_unlock(&acc_mutex);
- krb5_clear_error_string(context);
+ if (context)
+ krb5_clear_error_message(context);
return 0;
}
- lib = krb5_config_get_string(context, NULL,
- "libdefaults", "ccapi_library",
- NULL);
+ 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
@@ -110,19 +118,42 @@ init_ccapi(krb5_context context)
#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
- 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);
+ 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) {
- krb5_set_error_string(context, "Failed to find cc_initialize"
- "in %s: %s", lib, dlerror());
+ 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;
}
@@ -130,10 +161,28 @@ init_ccapi(krb5_context context)
return 0;
#else
HEIMDAL_MUTEX_unlock(&acc_mutex);
- krb5_set_error_string(context, "no support for shared object");
+ 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,
@@ -141,7 +190,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));
@@ -180,13 +229,13 @@ make_cred_from_ccred(krb5_context context,
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)
@@ -201,16 +250,16 @@ make_cred_from_ccred(krb5_context context,
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,
@@ -220,7 +269,7 @@ make_cred_from_ccred(krb5_context context,
goto nomem;
}
}
-
+
cred->flags.i = 0;
if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_FORWARDABLE)
cred->flags.b.forwardable = 1;
@@ -252,11 +301,11 @@ make_cred_from_ccred(krb5_context context,
cred->flags.b.anonymous = 1;
return 0;
-
+
nomem:
ret = ENOMEM;
- krb5_set_error_string(context, "malloc - out of memory");
-
+ krb5_set_error_message(context, ret, N_("malloc: out of memory", "malloc"));
+
fail:
krb5_free_cred_contents(context, cred);
return ret;
@@ -288,7 +337,7 @@ make_ccred_from_cred(krb5_context context,
cc_credentials_v5_t *cred)
{
krb5_error_code ret;
- int i;
+ size_t i;
memset(cred, 0, sizeof(*cred));
@@ -317,8 +366,8 @@ make_ccred_from_cred(krb5_context context,
/* XXX this one should also be filled in */
cred->authdata = NULL;
-
- cred->addresses = calloc(incred->addresses.len + 1,
+
+ cred->addresses = calloc(incred->addresses.len + 1,
sizeof(cred->addresses[0]));
if (cred->addresses == NULL) {
@@ -337,10 +386,11 @@ make_ccred_from_cred(krb5_context context,
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,
+ memcpy(addr->data, incred->addresses.val[i].address.data,
addr->length);
cred->addresses[i] = addr;
}
@@ -378,49 +428,69 @@ make_ccred_from_cred(krb5_context context,
return 0;
-fail:
+fail:
free_ccred(cred);
- krb5_clear_error_string(context);
+ krb5_clear_error_message(context);
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;
}
-static const char*
+static const char* KRB5_CALLCONV
acc_get_name(krb5_context context,
krb5_ccache id)
{
krb5_acc *a = ACACHE(id);
- static char n[255];
- char *name;
+ int32_t error;
+
+ if (a->cache_name == NULL) {
+ krb5_error_code ret;
+ krb5_principal principal;
+ char *name;
- name = get_cc_name(a->ccache);
- if (name == NULL) {
- krb5_set_error_string(context, "malloc: out of memory");
- return NULL;
+ 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;
}
- strlcpy(n, name, sizeof(n));
- free(name);
- return n;
+
+ return a->cache_name;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
acc_alloc(krb5_context context, krb5_ccache *id)
{
krb5_error_code ret;
@@ -433,10 +503,10 @@ acc_alloc(krb5_context context, krb5_ccache *id)
ret = krb5_data_alloc(&(*id)->data, sizeof(*a));
if (ret) {
- krb5_clear_error_string(context);
+ krb5_clear_error_message(context);
return ret;
}
-
+
a = ACACHE(*id);
error = (*init_func)(&a->context, ccapi_version_3, NULL, NULL);
@@ -450,7 +520,7 @@ acc_alloc(krb5_context context, krb5_ccache *id)
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
acc_resolve(krb5_context context, krb5_ccache *id, const char *res)
{
krb5_error_code ret;
@@ -463,20 +533,25 @@ acc_resolve(krb5_context context, krb5_ccache *id, const char *res)
a = ACACHE(*id);
- error = (*a->context->func->open_ccache)(a->context, res,
- &a->ccache);
- if (error == 0) {
- a->cache_name = get_cc_name(a->ccache);
- if (a->cache_name == NULL) {
+ 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;
- krb5_set_error_string(context, "malloc: out of memory");
- return ENOMEM;
+ 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;
- error = 0;
} else {
*id = NULL;
return translate_cc_error(context, error);
@@ -485,7 +560,7 @@ acc_resolve(krb5_context context, krb5_ccache *id, const char *res)
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
acc_gen_new(krb5_context context, krb5_ccache *id)
{
krb5_error_code ret;
@@ -503,7 +578,7 @@ acc_gen_new(krb5_context context, krb5_ccache *id)
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
acc_initialize(krb5_context context,
krb5_ccache id,
krb5_principal primary_principal)
@@ -517,16 +592,47 @@ acc_initialize(krb5_context context,
if (ret)
return ret;
- error = (*a->context->func->create_new_ccache)(a->context,
- cc_credentials_v5,
- name,
- &a->ccache);
- free(name);
+ 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
+static krb5_error_code KRB5_CALLCONV
acc_close(krb5_context context,
krb5_ccache id)
{
@@ -540,13 +646,15 @@ 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;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
acc_destroy(krb5_context context,
krb5_ccache id)
{
@@ -564,7 +672,7 @@ acc_destroy(krb5_context context,
return translate_cc_error(context, error);
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
acc_store_cred(krb5_context context,
krb5_ccache id,
krb5_creds *creds)
@@ -574,16 +682,17 @@ acc_store_cred(krb5_context context,
cc_credentials_v5_t v5cred;
krb5_error_code ret;
cc_int32 error;
-
+
if (a->ccache == NULL) {
- krb5_set_error_string(context, "No API credential found");
+ 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,
+ ret = make_ccred_from_cred(context,
creds,
&v5cred);
if (ret)
@@ -598,7 +707,7 @@ acc_store_cred(krb5_context context,
return ret;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
acc_get_principal(krb5_context context,
krb5_ccache id,
krb5_principal *principal)
@@ -609,7 +718,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,
+ N_("No API credential found", ""));
return KRB5_CC_NOTFOUND;
}
@@ -618,14 +728,14 @@ acc_get_principal(krb5_context context,
&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
+static krb5_error_code KRB5_CALLCONV
acc_get_first (krb5_context context,
krb5_ccache id,
krb5_cc_cursor *cursor)
@@ -633,15 +743,16 @@ acc_get_first (krb5_context context,
cc_credentials_iterator_t iter;
krb5_acc *a = ACACHE(id);
int32_t error;
-
+
if (a->ccache == NULL) {
- krb5_set_error_string(context, "No API credential found");
+ 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_string(context);
+ krb5_clear_error_message(context);
return ENOENT;
}
*cursor = iter;
@@ -649,7 +760,7 @@ acc_get_first (krb5_context context,
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
acc_get_next (krb5_context context,
krb5_ccache id,
krb5_cc_cursor *cursor,
@@ -669,14 +780,14 @@ acc_get_next (krb5_context context,
(*cred->func->release)(cred);
}
- ret = make_cred_from_ccred(context,
+ ret = make_cred_from_ccred(context,
cred->data->credentials.credentials_v5,
creds);
(*cred->func->release)(cred);
return ret;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
acc_end_get (krb5_context context,
krb5_ccache id,
krb5_cc_cursor *cursor)
@@ -686,7 +797,7 @@ acc_end_get (krb5_context context,
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
acc_remove_cred(krb5_context context,
krb5_ccache id,
krb5_flags which,
@@ -698,9 +809,10 @@ acc_remove_cred(krb5_context context,
krb5_error_code ret;
cc_int32 error;
char *client, *server;
-
+
if (a->ccache == NULL) {
- krb5_set_error_string(context, "No API credential found");
+ krb5_set_error_message(context, KRB5_CC_NOTFOUND,
+ N_("No API credential found", ""));
return KRB5_CC_NOTFOUND;
}
@@ -752,15 +864,16 @@ 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,
+ N_("Can't find credential %s in cache",
+ "principal"), server);
free(server);
free(client);
return ret;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
acc_set_flags(krb5_context context,
krb5_ccache id,
krb5_flags flags)
@@ -768,19 +881,19 @@ acc_set_flags(krb5_context context,
return 0;
}
-static krb5_error_code
+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
+static krb5_error_code KRB5_CALLCONV
acc_get_cache_first(krb5_context context, krb5_cc_cursor *cursor)
{
struct cache_iter *iter;
@@ -793,7 +906,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;
}
@@ -807,14 +920,14 @@ acc_get_cache_first(krb5_context context, krb5_cc_cursor *cursor)
&iter->iter);
if (error) {
free(iter);
- krb5_clear_error_string(context);
+ krb5_clear_error_message(context);
return ENOENT;
}
*cursor = iter;
return 0;
}
-static krb5_error_code
+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;
@@ -843,17 +956,16 @@ 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;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
acc_end_cache_get(krb5_context context, krb5_cc_cursor cursor)
{
struct cache_iter *iter = cursor;
@@ -866,7 +978,7 @@ acc_end_cache_get(krb5_context context, krb5_cc_cursor cursor)
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
acc_move(krb5_context context, krb5_ccache from, krb5_ccache to)
{
krb5_acc *afrom = ACACHE(from);
@@ -881,7 +993,7 @@ acc_move(krb5_context context, krb5_ccache from, krb5_ccache to)
&name);
if (error)
return translate_cc_error(context, error);
-
+
error = (*ato->context->func->create_new_ccache)(ato->context,
cc_credentials_v5,
name->data,
@@ -891,13 +1003,15 @@ acc_move(krb5_context context, krb5_ccache from, krb5_ccache to)
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
-acc_default_name(krb5_context context, char **str)
+static krb5_error_code KRB5_CALLCONV
+acc_get_default_name(krb5_context context, char **str)
{
krb5_error_code ret;
cc_context_t cc;
@@ -917,18 +1031,58 @@ acc_default_name(krb5_context context, char **str)
(*cc->func->release)(cc);
return translate_cc_error(context, error);
}
-
- asprintf(str, "API:%s", name->data);
+
+ 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");
+ 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.
@@ -936,7 +1090,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,
@@ -957,5 +1112,11 @@ 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,
+ acc_lastchange,
+ NULL,
+ NULL,
};
+
+#endif
OpenPOWER on IntegriCloud