1 /* 2 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 7 /* 8 * lib/krb5/rcache/rc_base.c 9 * 10 * This file of the Kerberos V5 software is derived from public-domain code 11 * contributed by Daniel J. Bernstein, <brnstnd@acf10.nyu.edu>. 12 * 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 /* Solaris Kerberos */ 27 #define FREE_RC(x) ((void) free((char *) (x))) 28 29 struct krb5_rc_typelist { 30 const krb5_rc_ops *ops; 31 struct krb5_rc_typelist *next; 32 }; 33 static struct krb5_rc_typelist none = { &krb5_rc_none_ops, 0 }; 34 static struct krb5_rc_typelist rc_mem_type = { &krb5_rc_mem_ops, &none }; 35 static struct krb5_rc_typelist krb5_rc_typelist_dfl = { &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 /* Solaris Kerberos */ 42 int retval; 43 44 retval = k5_mutex_finish_init(&grcache.lock); 45 if (retval) 46 return (retval); 47 48 return k5_mutex_finish_init(&rc_typelist_lock); 49 } 50 void krb5int_rc_terminate(void) 51 { 52 struct krb5_rc_typelist *t, *t_next; 53 /* Solaris Kerberos */ 54 struct mem_data *tgr = (struct mem_data *)grcache.data; 55 struct authlist *q, *qt; 56 int i; 57 58 k5_mutex_destroy(&grcache.lock); 59 60 if (tgr != NULL) { 61 if (tgr->name) 62 free(tgr->name); 63 for (i = 0; i < tgr->hsize; i++) 64 for (q = tgr->h[i]; q; q = qt) { 65 qt = q->nh; 66 free(q->rep.server); 67 free(q->rep.client); 68 free(q); 69 } 70 if (tgr->h) 71 free(tgr->h); 72 free(tgr); 73 } 74 75 k5_mutex_destroy(&rc_typelist_lock); 76 for (t = typehead; t != &krb5_rc_typelist_dfl; t = t_next) { 77 t_next = t->next; 78 free(t); 79 } 80 } 81 82 /*ARGSUSED*/ 83 krb5_error_code krb5_rc_register_type(krb5_context context, 84 const krb5_rc_ops *ops) 85 { 86 struct krb5_rc_typelist *t; 87 krb5_error_code err; 88 err = k5_mutex_lock(&rc_typelist_lock); 89 if (err) 90 return err; 91 for (t = typehead;t && strcmp(t->ops->type,ops->type);t = t->next) 92 ; 93 if (t) { 94 k5_mutex_unlock(&rc_typelist_lock); 95 return KRB5_RC_TYPE_EXISTS; 96 } 97 t = (struct krb5_rc_typelist *) malloc(sizeof(struct krb5_rc_typelist)); 98 if (t == NULL) { 99 k5_mutex_unlock(&rc_typelist_lock); 100 return KRB5_RC_MALLOC; 101 } 102 t->next = typehead; 103 t->ops = ops; 104 typehead = t; 105 k5_mutex_unlock(&rc_typelist_lock); 106 return 0; 107 } 108 109 /*ARGSUSED*/ 110 krb5_error_code krb5_rc_resolve_type(krb5_context context, krb5_rcache *id, 111 char *type) 112 { 113 struct krb5_rc_typelist *t; 114 krb5_error_code err; 115 err = k5_mutex_lock(&rc_typelist_lock); 116 if (err) 117 return err; 118 for (t = typehead;t && strcmp(t->ops->type,type);t = t->next) 119 ; 120 if (!t) { 121 k5_mutex_unlock(&rc_typelist_lock); 122 return KRB5_RC_TYPE_NOTFOUND; 123 } 124 /* allocate *id? nah */ 125 (*id)->ops = t->ops; 126 k5_mutex_unlock(&rc_typelist_lock); 127 return k5_mutex_init(&(*id)->lock); 128 } 129 130 /*ARGSUSED*/ 131 char * krb5_rc_get_type(krb5_context context, krb5_rcache id) 132 { 133 return id->ops->type; 134 } 135 136 char * krb5_rc_default_type(krb5_context context) 137 { 138 /* 139 * Solaris Kerberos/SUNW14resync 140 * MIT's is "dfl" but we now have FILE and MEMORY instead. 141 * And we only support the KRB5RCNAME env var. 142 */ 143 return ("FILE"); 144 } 145 146 /*ARGSUSED*/ 147 char * krb5_rc_default_name(krb5_context context) 148 { 149 char *s; 150 if ((s = getenv("KRB5RCNAME"))) 151 return s; 152 else 153 return (char *) 0; 154 } 155 156 krb5_error_code 157 krb5_rc_default(krb5_context context, krb5_rcache *id) 158 { 159 krb5_error_code retval; 160 161 if (!(*id = (krb5_rcache )malloc(sizeof(**id)))) 162 return KRB5_RC_MALLOC; 163 164 if ((retval = krb5_rc_resolve_type(context, id, 165 krb5_rc_default_type(context)))) { 166 FREE_RC(*id); 167 return retval; 168 } 169 if ((retval = krb5_rc_resolve(context, *id, 170 krb5_rc_default_name(context)))) { 171 k5_mutex_destroy(&(*id)->lock); 172 FREE_RC(*id); 173 return retval; 174 } 175 (*id)->magic = KV5M_RCACHE; 176 return retval; 177 } 178 179 180 krb5_error_code krb5_rc_resolve_full(krb5_context context, krb5_rcache *id, char *string_name) 181 { 182 char *type; 183 char *residual; 184 krb5_error_code retval; 185 unsigned int diff; 186 187 if (!(residual = strchr(string_name,':'))) 188 return KRB5_RC_PARSE; 189 190 diff = residual - string_name; 191 if (!(type = malloc(diff + 1))) 192 return KRB5_RC_MALLOC; 193 (void) strncpy(type, string_name, diff); 194 type[residual - string_name] = '\0'; 195 196 if (!(*id = (krb5_rcache) malloc(sizeof(**id)))) { 197 FREE_RC(type); 198 return KRB5_RC_MALLOC; 199 } 200 201 if ((retval = krb5_rc_resolve_type(context, id,type))) { 202 FREE_RC(type); 203 FREE_RC(*id); 204 return retval; 205 } 206 FREE_RC(type); 207 if ((retval = krb5_rc_resolve(context, *id,residual + 1))) { 208 k5_mutex_destroy(&(*id)->lock); 209 FREE_RC(*id); 210 return retval; 211 } 212 (*id)->magic = KV5M_RCACHE; 213 return retval; 214 } 215 216