add mutex for global variables, clean up returned error codes,

implement storing addresses into the ccapi


git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@14665 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
Love Hörnquist Åstrand
2005-03-19 17:41:22 +00:00
parent de0e232d51
commit d87eb9758e

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2004 Kungliga Tekniska H<>gskolan * Copyright (c) 2004 - 2005 Kungliga Tekniska H<>gskolan
* (Royal Institute of Technology, Stockholm, Sweden). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
@@ -39,10 +39,9 @@
RCSID("$Id$"); RCSID("$Id$");
/* XXX should we fetch these for each open ? */ /* XXX should we fetch these for each open ? */
static HEIMDAL_MUTEX acc_mutex = HEIMDAL_MUTEX_INITIALIZER;
static void *cc_handle; static void *cc_handle;
static cc_initialize_func init_func; static cc_initialize_func init_func;
typedef struct krb5_acc { typedef struct krb5_acc {
@@ -51,6 +50,8 @@ typedef struct krb5_acc {
cc_ccache_t ccache; cc_ccache_t ccache;
} krb5_acc; } krb5_acc;
static krb5_error_code acc_close(krb5_context, krb5_ccache);
#define ACACHE(X) ((krb5_acc *)(X)->data.data) #define ACACHE(X) ((krb5_acc *)(X)->data.data)
static const char *default_acc_name = "Initial default cache"; static const char *default_acc_name = "Initial default cache";
@@ -65,6 +66,7 @@ static const struct {
{ ccErrContextNotFound, KRB5_CC_NOTFOUND }, { ccErrContextNotFound, KRB5_CC_NOTFOUND },
{ ccIteratorEnd, KRB5_CC_END }, { ccIteratorEnd, KRB5_CC_END },
{ ccErrNoMem, KRB5_CC_NOMEM }, { ccErrNoMem, KRB5_CC_NOMEM },
{ ccErrServerUnavailable, KRB5_CC_BADNAME },
{ ccNoError, 0 } { ccNoError, 0 }
}; };
@@ -84,7 +86,9 @@ init_ccapi(krb5_context context)
{ {
const char *lib; const char *lib;
HEIMDAL_MUTEX_lock(&acc_mutex);
if (init_func) { if (init_func) {
HEIMDAL_MUTEX_unlock(&acc_mutex);
krb5_clear_error_string(context); krb5_clear_error_string(context);
return 0; return 0;
} }
@@ -103,23 +107,26 @@ init_ccapi(krb5_context context)
#ifdef HAVE_DLOPEN #ifdef HAVE_DLOPEN
cc_handle = dlopen(lib, 0); cc_handle = dlopen(lib, 0);
if (cc_handle == NULL) { if (cc_handle == NULL) {
HEIMDAL_MUTEX_unlock(&acc_mutex);
krb5_set_error_string(context, "Failed to load %s", lib); krb5_set_error_string(context, "Failed to load %s", lib);
return ENOENT; return ccErrServerUnavailable;
} }
init_func = dlsym(cc_handle, "cc_initialize"); init_func = dlsym(cc_handle, "cc_initialize");
HEIMDAL_MUTEX_unlock(&acc_mutex);
if (init_func == NULL) { if (init_func == NULL) {
krb5_set_error_string(context, "Failed to find cc_initialize" krb5_set_error_string(context, "Failed to find cc_initialize"
"in %s: %s", lib, dlerror()); "in %s: %s", lib, dlerror());
dlclose(cc_handle); dlclose(cc_handle);
return ENOENT; return ccErrServerUnavailable;
} }
#else
krb5_set_error_string(context, "no support for shared object");
return ENOENT;
#endif
return 0; 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 static krb5_error_code
@@ -222,12 +229,33 @@ fail:
return ret; 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 static krb5_error_code
make_ccred_from_cred(krb5_context context, make_ccred_from_cred(krb5_context context,
const krb5_creds *incred, const krb5_creds *incred,
cc_credentials_v5_t *cred) cc_credentials_v5_t *cred)
{ {
krb5_error_code ret; krb5_error_code ret;
int i;
memset(cred, 0, sizeof(*cred)); memset(cred, 0, sizeof(*cred));
@@ -236,10 +264,8 @@ make_ccred_from_cred(krb5_context context,
goto fail; goto fail;
ret = krb5_unparse_name(context, incred->server, &cred->server); ret = krb5_unparse_name(context, incred->server, &cred->server);
if (ret) { if (ret)
free(cred->client);
goto fail; goto fail;
}
cred->keyblock.type = incred->session.keytype; cred->keyblock.type = incred->session.keytype;
cred->keyblock.length = incred->session.keyvalue.length; cred->keyblock.length = incred->session.keyvalue.length;
@@ -260,10 +286,36 @@ make_ccred_from_cred(krb5_context context,
cred->authdata = NULL; cred->authdata = NULL;
cred->addresses = NULL; cred->addresses = 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 */ cred->ticket_flags = TicketFlags2int(incred->flags.b); /* XXX */
return 0; return 0;
fail: fail:
free_ccred(cred);
krb5_clear_error_string(context); krb5_clear_error_string(context);
return ret; return ret;
} }
@@ -289,26 +341,29 @@ acc_get_name(krb5_context context,
return n; return n;
} }
static cc_int32 static krb5_error_code
acc_alloc(krb5_context context, krb5_ccache *id) acc_alloc(krb5_context context, krb5_ccache *id)
{ {
krb5_acc *a; krb5_error_code ret;
cc_int32 error; cc_int32 error;
krb5_acc *a;
error = init_ccapi(context); ret = init_ccapi(context);
if (error) if (ret)
return error; return ret;
error = krb5_data_alloc(&(*id)->data, sizeof(*a)); ret = krb5_data_alloc(&(*id)->data, sizeof(*a));
if (error) if (ret) {
return error; krb5_clear_error_string(context);
return ret;
}
a = ACACHE(*id); a = ACACHE(*id);
error = (*init_func)(&a->context, ccapi_version_3, NULL, NULL); error = (*init_func)(&a->context, ccapi_version_3, NULL, NULL);
if (error) { if (error) {
krb5_data_free(&(*id)->data); krb5_data_free(&(*id)->data);
return error; return translate_cc_error(context, error);
} }
a->name = NULL; a->name = NULL;
@@ -319,12 +374,13 @@ acc_alloc(krb5_context context, krb5_ccache *id)
static krb5_error_code static krb5_error_code
acc_resolve(krb5_context context, krb5_ccache *id, const char *res) acc_resolve(krb5_context context, krb5_ccache *id, const char *res)
{ {
krb5_acc *a; krb5_error_code ret;
cc_int32 error; cc_int32 error;
krb5_acc *a;
error = acc_alloc(context, id); ret = acc_alloc(context, id);
if (error) if (ret)
return translate_cc_error(context, error); return ret;
a = ACACHE(*id); a = ACACHE(*id);
@@ -345,12 +401,13 @@ acc_resolve(krb5_context context, krb5_ccache *id, const char *res)
static krb5_error_code static krb5_error_code
acc_gen_new(krb5_context context, krb5_ccache *id) acc_gen_new(krb5_context context, krb5_ccache *id)
{ {
krb5_acc *a; krb5_error_code ret;
cc_int32 error; cc_int32 error;
krb5_acc *a;
error = acc_alloc(context, id); ret = acc_alloc(context, id);
if (error) if (ret)
return translate_cc_error(context, error); return ret;
a = ACACHE(*id); a = ACACHE(*id);
@@ -365,6 +422,7 @@ acc_gen_new(krb5_context context, krb5_ccache *id)
&a->ccache); &a->ccache);
a->name = strdup(default_acc_name); a->name = strdup(default_acc_name);
} }
return translate_cc_error(context, error); return translate_cc_error(context, error);
} }
@@ -474,9 +532,10 @@ acc_store_cred(krb5_context context,
return ret; return ret;
error = (*a->ccache->func->store_credentials)(a->ccache, &cred); error = (*a->ccache->func->store_credentials)(a->ccache, &cred);
if (error)
ret = translate_cc_error(context, error);
free(v5cred.server); free_ccred(&v5cred);
free(v5cred.client);
return ret; return ret;
} }