+2004-03-05 Ken Raeburn <raeburn@mit.edu>
+
+ * 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 <jaltman@mit.edu>
* cc_mslsa.c:
/*
* 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
*/
#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
&cc_mcc_entry };
static struct krb5_cc_typelist *cc_typehead = &cc_fcc_entry;
+static k5_mutex_t cc_typelist_lock = K5_MUTEX_INITIALIZER;
/*
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;
}
char *pfx, *cp;
const char *resid;
unsigned int pfxlen;
+ krb5_error_code err;
cp = strchr (name, ':');
if (!cp) {
*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);
2004-03-05 Ken Raeburn <raeburn@mit.edu>
- * 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.
*/
#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;
&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;
/*
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;
}
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) {
*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);
+2004-03-05 Ken Raeburn <raeburn@mit.edu>
+
+ * 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 <raeburn@mit.edu>
* rc_base.c: Delete unused and untested semaphore support.
*/
#include "rc_base.h"
+#include "k5-thread.h"
#define FREE(x) ((void) free((char *) (x)))
};
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;
}
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;
}