For keytab, ccache, and rcache type registries, use const more, and
authorKen Raeburn <raeburn@mit.edu>
Sat, 6 Mar 2004 03:16:02 +0000 (03:16 +0000)
committerKen Raeburn <raeburn@mit.edu>
Sat, 6 Mar 2004 03:16:02 +0000 (03:16 +0000)
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
src/lib/krb5/ccache/ccbase.c
src/lib/krb5/keytab/ChangeLog
src/lib/krb5/keytab/ktbase.c
src/lib/krb5/rcache/ChangeLog
src/lib/krb5/rcache/rc_base.c

index e0ae8919c7effa88713c7678f8967350d2f71d98..c63bad19b47d6a21f8b5410acdf232b349ec22be 100644 (file)
@@ -1,3 +1,11 @@
+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:
index f17870663ad20c562242cad331cd733f4c00014e..9fff1ef0eaf7b10e300e22b65bd255ea22eaa513 100644 (file)
@@ -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
  */
 
 #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);
index b5a9e41e4e5664f373a1203cabf08090ebfce47a..20bb4c7159d3cc3a0d18f115d9cb543af782e0d9 100644 (file)
@@ -1,6 +1,10 @@
 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.
index 6e199d685f32b3b63e2d3371137b9bd9a1e64771..c415361bbb9c3e51c60f5342d3716a4360415f1f 100644 (file)
@@ -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);
index c71e5f8515750e6e80bd988d64ef60ad98af7d85..a096114f28d753d7b2ea0f516cb97eb86233c81a 100644 (file)
@@ -1,3 +1,10 @@
+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.
index 40651787ce624e12fef218d29bfd91f9059564f7..5758c20bcb5092165eeba429ec8aa38076bad5ff 100644 (file)
@@ -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;
 }