From 2e732d2ef148ee4788cd7269461f2f6ef3ce668f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Love=20H=C3=B6rnquist=20=C3=85strand?= Date: Tue, 22 Jul 2003 19:50:11 +0000 Subject: [PATCH] Provide locking around the creation of the global krb5_context. Add destruction/creation functions for the thread specific storage that the error string handling is using. git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@12493 ec53bebd-3082-4978-b11e-865c3cabbd6b --- lib/gssapi/init.c | 73 ++++++++++++++++++++++++++++++++++++++++-- lib/gssapi/krb5/init.c | 73 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 140 insertions(+), 6 deletions(-) diff --git a/lib/gssapi/init.c b/lib/gssapi/init.c index ec63bcfc4..c036b3e5a 100644 --- a/lib/gssapi/init.c +++ b/lib/gssapi/init.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2001, 2003 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -35,10 +35,77 @@ RCSID("$Id$"); +static HEIMDAL_MUTEX gssapi_krb5_context_mutex = HEIMDAL_MUTEX_INITIALIZER; +static int created_key; +static HEIMDAL_thread_key gssapi_context_key; + +static void +gssapi_destroy_thread_context(void *ptr) +{ + struct gssapi_thr_context *ctx = ptr; + + if (ctx == NULL) + return; + if (ctx->error_string) + free(ctx->error_string); + HEIMDAL_MUTEX_destroy(&ctx->mutex); + free(ctx); +} + + +struct gssapi_thr_context * +gssapi_get_thread_context(int createp) +{ + struct gssapi_thr_context *ctx; + int ret; + + HEIMDAL_MUTEX_lock(&gssapi_krb5_context_mutex); + + if (!created_key) + abort(); + ctx = HEIMDAL_getspecific(gssapi_context_key); + if (ctx == NULL) { + if (!createp) + goto fail; + ctx = malloc(sizeof(*ctx)); + if (ctx == NULL) + goto fail; + ctx->error_string = NULL; + HEIMDAL_MUTEX_init(&ctx->mutex); + HEIMDAL_setspecific(gssapi_context_key, ctx, ret); + if (ret) + goto fail; + } + HEIMDAL_MUTEX_unlock(&gssapi_krb5_context_mutex); + return ctx; + fail: + HEIMDAL_MUTEX_unlock(&gssapi_krb5_context_mutex); + if (ctx) + free(ctx); + return NULL; +} + krb5_error_code gssapi_krb5_init (void) { + krb5_error_code ret = 0; + + HEIMDAL_MUTEX_lock(&gssapi_krb5_context_mutex); + if(gssapi_krb5_context == NULL) - return krb5_init_context (&gssapi_krb5_context); - return 0; + ret = krb5_init_context (&gssapi_krb5_context); + if (ret == 0 && !created_key) { + HEIMDAL_key_create(&gssapi_context_key, + gssapi_destroy_thread_context, + ret); + if (ret) { + krb5_free_context(gssapi_krb5_context); + gssapi_krb5_context = NULL; + } else + created_key = 1; + } + + HEIMDAL_MUTEX_unlock(&gssapi_krb5_context_mutex); + + return ret; } diff --git a/lib/gssapi/krb5/init.c b/lib/gssapi/krb5/init.c index ec63bcfc4..c036b3e5a 100644 --- a/lib/gssapi/krb5/init.c +++ b/lib/gssapi/krb5/init.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2001, 2003 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -35,10 +35,77 @@ RCSID("$Id$"); +static HEIMDAL_MUTEX gssapi_krb5_context_mutex = HEIMDAL_MUTEX_INITIALIZER; +static int created_key; +static HEIMDAL_thread_key gssapi_context_key; + +static void +gssapi_destroy_thread_context(void *ptr) +{ + struct gssapi_thr_context *ctx = ptr; + + if (ctx == NULL) + return; + if (ctx->error_string) + free(ctx->error_string); + HEIMDAL_MUTEX_destroy(&ctx->mutex); + free(ctx); +} + + +struct gssapi_thr_context * +gssapi_get_thread_context(int createp) +{ + struct gssapi_thr_context *ctx; + int ret; + + HEIMDAL_MUTEX_lock(&gssapi_krb5_context_mutex); + + if (!created_key) + abort(); + ctx = HEIMDAL_getspecific(gssapi_context_key); + if (ctx == NULL) { + if (!createp) + goto fail; + ctx = malloc(sizeof(*ctx)); + if (ctx == NULL) + goto fail; + ctx->error_string = NULL; + HEIMDAL_MUTEX_init(&ctx->mutex); + HEIMDAL_setspecific(gssapi_context_key, ctx, ret); + if (ret) + goto fail; + } + HEIMDAL_MUTEX_unlock(&gssapi_krb5_context_mutex); + return ctx; + fail: + HEIMDAL_MUTEX_unlock(&gssapi_krb5_context_mutex); + if (ctx) + free(ctx); + return NULL; +} + krb5_error_code gssapi_krb5_init (void) { + krb5_error_code ret = 0; + + HEIMDAL_MUTEX_lock(&gssapi_krb5_context_mutex); + if(gssapi_krb5_context == NULL) - return krb5_init_context (&gssapi_krb5_context); - return 0; + ret = krb5_init_context (&gssapi_krb5_context); + if (ret == 0 && !created_key) { + HEIMDAL_key_create(&gssapi_context_key, + gssapi_destroy_thread_context, + ret); + if (ret) { + krb5_free_context(gssapi_krb5_context); + gssapi_krb5_context = NULL; + } else + created_key = 1; + } + + HEIMDAL_MUTEX_unlock(&gssapi_krb5_context_mutex); + + return ret; }