Home | History | Annotate | Download | only in rcache
      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 (at) 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