From b577efbd36c4fabe18bb5281d180c2ddce28fee7 Mon Sep 17 00:00:00 2001 From: Ken Raeburn Date: Sat, 6 Mar 2004 03:16:02 +0000 Subject: [PATCH] For keytab, ccache, and rcache type registries, use const more, and use a mutex to protect manipulation of the lists. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@16153 dc483132-0cff-0310-8789-dd5450dbe970 --- src/lib/krb5/ccache/ChangeLog | 8 +++++++ src/lib/krb5/ccache/ccbase.c | 39 +++++++++++++++++++++++++++-------- src/lib/krb5/keytab/ChangeLog | 6 +++++- src/lib/krb5/keytab/ktbase.c | 38 +++++++++++++++++++++++++++------- src/lib/krb5/rcache/ChangeLog | 7 +++++++ src/lib/krb5/rcache/rc_base.c | 24 ++++++++++++++++++--- 6 files changed, 101 insertions(+), 21 deletions(-) diff --git a/src/lib/krb5/ccache/ChangeLog b/src/lib/krb5/ccache/ChangeLog index e0ae8919c..c63bad19b 100644 --- a/src/lib/krb5/ccache/ChangeLog +++ b/src/lib/krb5/ccache/ChangeLog @@ -1,3 +1,11 @@ +2004-03-05 Ken Raeburn + + * ccbase.c: Include k5-thread.h. + (struct krb5_cc_typelist): Ops pointer now points to const. + (cc_typelist_lock): New mutex var. + (krb5_cc_register, krb5_cc_resolve): Lock it while working with + the type list. + 2004-02-04 Jeffrey Altman * cc_mslsa.c: diff --git a/src/lib/krb5/ccache/ccbase.c b/src/lib/krb5/ccache/ccbase.c index f17870663..9fff1ef0e 100644 --- a/src/lib/krb5/ccache/ccbase.c +++ b/src/lib/krb5/ccache/ccbase.c @@ -1,7 +1,7 @@ /* * lib/krb5/ccache/ccbase.c * - * Copyright 1990 by the Massachusetts Institute of Technology. + * Copyright 1990,2004 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may @@ -28,14 +28,14 @@ */ #include "k5-int.h" +#include "k5-thread.h" #include "fcc.h" -struct krb5_cc_typelist - { - krb5_cc_ops *ops; - struct krb5_cc_typelist *next; - }; +struct krb5_cc_typelist { + const krb5_cc_ops *ops; + struct krb5_cc_typelist *next; +}; extern const krb5_cc_ops krb5_mcc_ops; #ifdef _WIN32 @@ -50,6 +50,7 @@ static struct krb5_cc_typelist cc_fcc_entry = { &krb5_cc_file_ops, &cc_mcc_entry }; static struct krb5_cc_typelist *cc_typehead = &cc_fcc_entry; +static k5_mutex_t cc_typelist_lock = K5_MUTEX_INITIALIZER; /* @@ -61,20 +62,31 @@ krb5_error_code KRB5_CALLCONV krb5_cc_register(krb5_context context, krb5_cc_ops *ops, krb5_boolean override) { struct krb5_cc_typelist *t; + krb5_error_code err; + + err = k5_mutex_lock(&cc_typelist_lock); + if (err) + return err; for (t = cc_typehead;t && strcmp(t->ops->prefix,ops->prefix);t = t->next) ; if (t) { if (override) { t->ops = ops; + k5_mutex_unlock(&cc_typelist_lock); return 0; - } else + } else { + k5_mutex_unlock(&cc_typelist_lock); return KRB5_CC_TYPE_EXISTS; + } } - if (!(t = (struct krb5_cc_typelist *) malloc(sizeof(*t)))) + if (!(t = (struct krb5_cc_typelist *) malloc(sizeof(*t)))) { + k5_mutex_unlock(&cc_typelist_lock); return ENOMEM; + } t->next = cc_typehead; t->ops = ops; cc_typehead = t; + k5_mutex_unlock(&cc_typelist_lock); return 0; } @@ -95,6 +107,7 @@ krb5_cc_resolve (krb5_context context, const char *name, krb5_ccache *cache) char *pfx, *cp; const char *resid; unsigned int pfxlen; + krb5_error_code err; cp = strchr (name, ':'); if (!cp) { @@ -116,12 +129,20 @@ krb5_cc_resolve (krb5_context context, const char *name, krb5_ccache *cache) *cache = (krb5_ccache) 0; + err = k5_mutex_lock(&cc_typelist_lock); + if (err) { + free(pfx); + return err; + } for (tlist = cc_typehead; tlist; tlist = tlist->next) { if (strcmp (tlist->ops->prefix, pfx) == 0) { + krb5_error_code (*ccresolver)() = tlist->ops->resolve; + k5_mutex_unlock(&cc_typelist_lock); free(pfx); - return (*tlist->ops->resolve)(context, cache, resid); + return (*ccresolver)(context, cache, resid); } } + k5_mutex_unlock(&cc_typelist_lock); if (krb5_cc_dfl_ops && !strcmp (pfx, krb5_cc_dfl_ops->prefix)) { free (pfx); return (*krb5_cc_dfl_ops->resolve)(context, cache, resid); diff --git a/src/lib/krb5/keytab/ChangeLog b/src/lib/krb5/keytab/ChangeLog index b5a9e41e4..20bb4c715 100644 --- a/src/lib/krb5/keytab/ChangeLog +++ b/src/lib/krb5/keytab/ChangeLog @@ -1,6 +1,10 @@ 2004-03-05 Ken Raeburn - * ktbase.c (krb5_kt_register): Ops table is now const. + * ktbase.c: Include k5-thread.h. + (k5_typehead_lock): New mutex variable. + (krb5_kt_register, krb5_kt_resolve): Lock it while accessing the + type list. + (krb5_kt_register): Ops table is now const. (struct krb5_kt_typelist): "next" pointer now points to const. (krb5_kt_typelist_wrfile, krb5_kt_typelist_file, krb5_kt_typelist_srvtab): Now const. diff --git a/src/lib/krb5/keytab/ktbase.c b/src/lib/krb5/keytab/ktbase.c index 6e199d685..c415361bb 100644 --- a/src/lib/krb5/keytab/ktbase.c +++ b/src/lib/krb5/keytab/ktbase.c @@ -28,6 +28,7 @@ */ #include "k5-int.h" +#include "k5-thread.h" extern const krb5_kt_ops krb5_ktf_ops; extern const krb5_kt_ops krb5_ktf_writable_ops; @@ -50,6 +51,8 @@ const static struct krb5_kt_typelist krb5_kt_typelist_srvtab = { &krb5_kt_typelist_file }; static const struct krb5_kt_typelist *kt_typehead = &krb5_kt_typelist_srvtab; +/* Lock for protecting the type list. */ +static k5_mutex_t kt_typehead_lock = K5_MUTEX_INITIALIZER; /* @@ -60,17 +63,27 @@ static const struct krb5_kt_typelist *kt_typehead = &krb5_kt_typelist_srvtab; krb5_error_code KRB5_CALLCONV krb5_kt_register(krb5_context context, const krb5_kt_ops *ops) { - struct krb5_kt_typelist *t; - for (t = kt_typehead;t && strcmp(t->ops->prefix,ops->prefix);t = t->next) + const struct krb5_kt_typelist *t; + struct krb5_kt_typelist *newt; + krb5_error_code err; + + err = k5_mutex_lock(&kt_typehead_lock); + if (err) + return err; + for (t = kt_typehead; t && strcmp(t->ops->prefix,ops->prefix);t = t->next) ; if (t) { + k5_mutex_unlock(&kt_typehead_lock); return KRB5_KT_TYPE_EXISTS; } - if (!(t = (struct krb5_kt_typelist *) malloc(sizeof(*t)))) + if (!(newt = (struct krb5_kt_typelist *) malloc(sizeof(*t)))) { + k5_mutex_unlock(&kt_typehead_lock); return ENOMEM; - t->next = kt_typehead; - t->ops = ops; - kt_typehead = t; + } + newt->next = kt_typehead; + newt->ops = ops; + kt_typehead = newt; + k5_mutex_unlock(&kt_typehead_lock); return 0; } @@ -87,10 +100,11 @@ krb5_kt_register(krb5_context context, const krb5_kt_ops *ops) krb5_error_code KRB5_CALLCONV krb5_kt_resolve (krb5_context context, const char *name, krb5_keytab *ktid) { - struct krb5_kt_typelist *tlist; + const struct krb5_kt_typelist *tlist; char *pfx; unsigned int pfxlen; const char *cp, *resid; + krb5_error_code err; cp = strchr (name, ':'); if (!cp) { @@ -109,7 +123,15 @@ krb5_kt_resolve (krb5_context context, const char *name, krb5_keytab *ktid) *ktid = (krb5_keytab) 0; - for (tlist = kt_typehead; tlist; tlist = tlist->next) { + err = k5_mutex_lock(&kt_typehead_lock); + if (err) + return err; + tlist = kt_typehead; + /* Don't need to hold the lock, since entries are never modified + or removed once they're in the list. Just need to protect + access to the list head variable itself. */ + k5_mutex_unlock(&kt_typehead_lock); + for (; tlist; tlist = tlist->next) { if (strcmp (tlist->ops->prefix, pfx) == 0) { free(pfx); return (*tlist->ops->resolve)(context, resid, ktid); diff --git a/src/lib/krb5/rcache/ChangeLog b/src/lib/krb5/rcache/ChangeLog index c71e5f851..a096114f2 100644 --- a/src/lib/krb5/rcache/ChangeLog +++ b/src/lib/krb5/rcache/ChangeLog @@ -1,3 +1,10 @@ +2004-03-05 Ken Raeburn + + * rc_base.c: Include k5-thread.h. + (rc_typelist_lock): New mutex var. + (krb5_rc_register_type, krb5_rc_resolve_type): Lock it while + working with the type list. + 2004-03-03 Ken Raeburn * rc_base.c: Delete unused and untested semaphore support. diff --git a/src/lib/krb5/rcache/rc_base.c b/src/lib/krb5/rcache/rc_base.c index 40651787c..5758c20bc 100644 --- a/src/lib/krb5/rcache/rc_base.c +++ b/src/lib/krb5/rcache/rc_base.c @@ -12,6 +12,7 @@ */ #include "rc_base.h" +#include "k5-thread.h" #define FREE(x) ((void) free((char *) (x))) @@ -21,21 +22,31 @@ struct krb5_rc_typelist { }; static struct krb5_rc_typelist krb5_rc_typelist_dfl = { &krb5_rc_dfl_ops, 0 }; static struct krb5_rc_typelist *typehead = &krb5_rc_typelist_dfl; +static k5_mutex_t rc_typelist_lock = K5_MUTEX_INITIALIZER; krb5_error_code krb5_rc_register_type(krb5_context context, const krb5_rc_ops *ops) { struct krb5_rc_typelist *t; + krb5_error_code err; + err = k5_mutex_lock(&rc_typelist_lock); + if (err) + return err; for (t = typehead;t && strcmp(t->ops->type,ops->type);t = t->next) ; - if (t) + if (t) { + k5_mutex_unlock(&rc_typelist_lock); return KRB5_RC_TYPE_EXISTS; + } t = (struct krb5_rc_typelist *) malloc(sizeof(struct krb5_rc_typelist)); - if (t == NULL) + if (t == NULL) { + k5_mutex_unlock(&rc_typelist_lock); return KRB5_RC_MALLOC; + } t->next = typehead; t->ops = ops; typehead = t; + k5_mutex_unlock(&rc_typelist_lock); return 0; } @@ -43,12 +54,19 @@ krb5_error_code krb5_rc_resolve_type(krb5_context context, krb5_rcache *id, char *type) { struct krb5_rc_typelist *t; + krb5_error_code err; + err = k5_mutex_lock(&rc_typelist_lock); + if (err) + return err; for (t = typehead;t && strcmp(t->ops->type,type);t = t->next) ; - if (!t) + if (!t) { + k5_mutex_unlock(&rc_typelist_lock); return KRB5_RC_TYPE_NOTFOUND; + } /* allocate *id? nah */ (*id)->ops = t->ops; + k5_mutex_unlock(&rc_typelist_lock); return 0; } -- 2.26.2