1 /* 2 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 #pragma ident "%Z%%M% %I% %E% SMI" 7 8 /* 9 * lib/krb5/rcache/rc_base.c 10 * 11 * This file of the Kerberos V5 software is derived from public-domain code 12 * contributed by Daniel J. Bernstein, <brnstnd@acf10.nyu.edu>. 13 */ 14 15 16 /* 17 * Base "glue" functions for the replay cache. 18 */ 19 20 #include "rc_base.h" 21 #include "rc_common.h" 22 #include "rc_mem.h" 23 #include "rc_file.h" 24 #include <k5-thread.h> 25 26 #define FREE_RC(x) ((void) free((char *) (x))) 27 28 struct krb5_rc_typelist 29 { 30 const krb5_rc_ops *ops; 31 struct krb5_rc_typelist *next; 32 }; 33 static struct krb5_rc_typelist rc_mem_type = { &krb5_rc_mem_ops, 0 }; 34 static struct krb5_rc_typelist krb5_rc_typelist_dfl = 35 { &krb5_rc_file_ops, &rc_mem_type }; 36 static struct krb5_rc_typelist *typehead = &krb5_rc_typelist_dfl; 37 static k5_mutex_t rc_typelist_lock = K5_MUTEX_PARTIAL_INITIALIZER; 38 39 int krb5int_rc_finish_init(void) 40 { 41 return k5_mutex_finish_init(&rc_typelist_lock); 42 } 43 void krb5int_rc_terminate(void) 44 { 45 struct krb5_rc_typelist *t, *t_next; 46 k5_mutex_destroy(&rc_typelist_lock); 47 for (t = typehead; t != &krb5_rc_typelist_dfl; t = t_next) { 48 t_next = t->next; 49 free(t); 50 } 51 } 52 53 /*ARGSUSED*/ 54 krb5_error_code krb5_rc_register_type(krb5_context context, 55 const krb5_rc_ops *ops) 56 { 57 struct krb5_rc_typelist *t; 58 krb5_error_code err; 59 60 err = k5_mutex_lock(&rc_typelist_lock); 61 if (err) 62 return err; 63 64 for (t = typehead;t && strcmp(t->ops->type,ops->type);t = t->next) 65 ; 66 if (t) { 67 k5_mutex_unlock(&rc_typelist_lock); 68 return KRB5_RC_TYPE_EXISTS; 69 } 70 71 t = (struct krb5_rc_typelist *) malloc(sizeof(struct krb5_rc_typelist)); 72 if (t == NULL) { 73 k5_mutex_unlock(&rc_typelist_lock); 74 return KRB5_RC_MALLOC; 75 } 76 t->next = typehead; 77 t->ops = ops; 78 typehead = t; 79 80 k5_mutex_unlock(&rc_typelist_lock); 81 return 0; 82 } 83 84 /*ARGSUSED*/ 85 krb5_error_code krb5_rc_resolve_type(krb5_context context, krb5_rcache *id, 86 char *type) 87 { 88 struct krb5_rc_typelist *t; 89 krb5_error_code err; 90 err = k5_mutex_lock(&rc_typelist_lock); 91 if (err) 92 return err; 93 for (t = typehead;t && strcmp(t->ops->type,type);t = t->next) 94 ; 95 if (!t) { 96 k5_mutex_unlock(&rc_typelist_lock); 97 return KRB5_RC_TYPE_NOTFOUND; 98 } 99 /* allocate *id? nah */ 100 (*id)->ops = t->ops; 101 k5_mutex_unlock(&rc_typelist_lock); 102 return k5_mutex_init(&(*id)->lock); 103 } 104 105 /*ARGSUSED*/ 106 char * krb5_rc_get_type(krb5_context context, krb5_rcache id) 107 { 108 return id->ops->type; 109 } 110 111 char * krb5_rc_default_type(krb5_context context) 112 { 113 char *s; 114 if ((s = getenv("KRB5RCACHETYPE"))) 115 return s; 116 else 117 /* 118 * Solaris Kerberos/SUNW14resync 119 * MIT's is "dfl" but we now have FILE and MEMORY instead. 120 */ 121 return "FILE"; 122 } 123 124 /*ARGSUSED*/ 125 char * krb5_rc_default_name(krb5_context context) 126 { 127 char *s; 128 if ((s = getenv("KRB5RCNAME"))) 129 return s; 130 else 131 return (char *) 0; 132 } 133 134 krb5_error_code 135 krb5_rc_default(krb5_context context, krb5_rcache *id) 136 { 137 krb5_error_code retval; 138 139 if (!(*id = (krb5_rcache )malloc(sizeof(**id)))) 140 return KRB5_RC_MALLOC; 141 142 retval = krb5_rc_resolve(context, *id, 143 krb5_rc_default_name(context)); 144 if (retval) { 145 k5_mutex_destroy(&(*id)->lock); 146 FREE_RC(*id); 147 return retval; 148 } 149 (*id)->magic = KV5M_RCACHE; 150 return retval; 151 } 152 153 krb5_error_code krb5_rc_resolve_full(krb5_context context, krb5_rcache *id, char *string_name) 154 { 155 char *type; 156 char *residual; 157 krb5_error_code retval; 158 unsigned int diff; 159 160 if (!(residual = strchr(string_name,':'))) 161 return KRB5_RC_PARSE; 162 163 diff = residual - string_name; 164 if (!(type = malloc(diff + 1))) 165 return KRB5_RC_MALLOC; 166 (void) strncpy(type, string_name, diff); 167 type[residual - string_name] = '\0'; 168 169 if (!(*id = (krb5_rcache) malloc(sizeof(**id)))) { 170 FREE_RC(type); 171 return KRB5_RC_MALLOC; 172 } 173 174 if ((retval = krb5_rc_resolve_type(context, id,type))) { 175 FREE_RC(type); 176 k5_mutex_destroy(&(*id)->lock); 177 FREE_RC(*id); 178 return retval; 179 } 180 FREE_RC(type); 181 retval = krb5_rc_resolve(context, *id, residual + 1); 182 if (retval) { 183 k5_mutex_destroy(&(*id)->lock); 184 FREE_RC(*id); 185 return retval; 186 } 187 (*id)->magic = KV5M_RCACHE; 188 return retval; 189 } 190 191