Get rid of casts of free() argument to char*, except where it's
[krb5.git] / src / lib / krb5 / rcache / rc_base.c
1 /* -*- mode: c; indent-tabs-mode: nil -*- */
2 /*
3  * lib/krb5/rcache/rc_base.c
4  *
5  * This file of the Kerberos V5 software is derived from public-domain code
6  * contributed by Daniel J. Bernstein, <brnstnd@acf10.nyu.edu>.
7  *
8  */
9
10 /*
11  * Base "glue" functions for the replay cache.
12  */
13
14 #include "rc_base.h"
15 #include "rc-int.h"
16 #include "k5-thread.h"
17
18 struct krb5_rc_typelist {
19     const krb5_rc_ops *ops;
20     struct krb5_rc_typelist *next;
21 };
22 static struct krb5_rc_typelist none = { &krb5_rc_none_ops, 0 };
23 static struct krb5_rc_typelist krb5_rc_typelist_dfl = { &krb5_rc_dfl_ops, &none };
24 static struct krb5_rc_typelist *typehead = &krb5_rc_typelist_dfl;
25 static k5_mutex_t rc_typelist_lock = K5_MUTEX_PARTIAL_INITIALIZER;
26
27 int krb5int_rc_finish_init(void)
28 {
29     return k5_mutex_finish_init(&rc_typelist_lock);
30 }
31 void krb5int_rc_terminate(void)
32 {
33     struct krb5_rc_typelist *t, *t_next;
34     k5_mutex_destroy(&rc_typelist_lock);
35     for (t = typehead; t != &krb5_rc_typelist_dfl; t = t_next) {
36         t_next = t->next;
37         free(t);
38     }
39 }
40
41 krb5_error_code krb5_rc_register_type(krb5_context context,
42                                       const krb5_rc_ops *ops)
43 {
44     struct krb5_rc_typelist *t;
45     krb5_error_code err;
46     err = k5_mutex_lock(&rc_typelist_lock);
47     if (err)
48         return err;
49     for (t = typehead;t && strcmp(t->ops->type,ops->type);t = t->next)
50         ;
51     if (t) {
52         k5_mutex_unlock(&rc_typelist_lock);
53         return KRB5_RC_TYPE_EXISTS;
54     }
55     t = (struct krb5_rc_typelist *) malloc(sizeof(struct krb5_rc_typelist));
56     if (t == NULL) {
57         k5_mutex_unlock(&rc_typelist_lock);
58         return KRB5_RC_MALLOC;
59     }
60     t->next = typehead;
61     t->ops = ops;
62     typehead = t;
63     k5_mutex_unlock(&rc_typelist_lock);
64     return 0;
65 }
66
67 krb5_error_code krb5_rc_resolve_type(krb5_context context, krb5_rcache *id,
68                                      char *type)
69 {
70     struct krb5_rc_typelist *t;
71     krb5_error_code err;
72     err = k5_mutex_lock(&rc_typelist_lock);
73     if (err)
74         return err;
75     for (t = typehead;t && strcmp(t->ops->type,type);t = t->next)
76         ;
77     if (!t) {
78         k5_mutex_unlock(&rc_typelist_lock);
79         return KRB5_RC_TYPE_NOTFOUND;
80     }
81     /* allocate *id? nah */
82     (*id)->ops = t->ops;
83     k5_mutex_unlock(&rc_typelist_lock);
84     return k5_mutex_init(&(*id)->lock);
85 }
86
87 char * krb5_rc_get_type(krb5_context context, krb5_rcache id)
88 {
89     return id->ops->type;
90 }
91
92 char * krb5_rc_default_type(krb5_context context)
93 {
94     char *s;
95     if ((s = getenv("KRB5RCACHETYPE")))
96         return s;
97     else
98         return "dfl";
99 }
100
101 char * krb5_rc_default_name(krb5_context context)
102 {
103     char *s;
104     if ((s = getenv("KRB5RCACHENAME")))
105         return s;
106     else
107         return (char *) 0;
108 }
109
110 krb5_error_code
111 krb5_rc_default(krb5_context context, krb5_rcache *id)
112 {
113     krb5_error_code retval;
114
115     if (!(*id = (krb5_rcache )malloc(sizeof(**id))))
116         return KRB5_RC_MALLOC;
117
118     if ((retval = krb5_rc_resolve_type(context, id,
119                                        krb5_rc_default_type(context)))) {
120         free(*id);
121         return retval;
122     }
123     if ((retval = krb5_rc_resolve(context, *id,
124                                   krb5_rc_default_name(context)))) {
125         k5_mutex_destroy(&(*id)->lock);
126         free(*id);
127         return retval;
128     }
129     (*id)->magic = KV5M_RCACHE;
130     return retval;
131 }
132
133
134 krb5_error_code krb5_rc_resolve_full(krb5_context context, krb5_rcache *idptr,
135                                      char *string_name)
136 {
137     char *type;
138     char *residual;
139     krb5_error_code retval;
140     unsigned int diff;
141     krb5_rcache id;
142
143     *idptr = NULL;
144
145     if (!(residual = strchr(string_name,':')))
146         return KRB5_RC_PARSE;
147
148     diff = residual - string_name;
149     if (!(type = malloc(diff + 1)))
150         return KRB5_RC_MALLOC;
151     (void) strncpy(type, string_name, diff);
152     type[residual - string_name] = '\0';
153
154     if (!(id = (krb5_rcache) malloc(sizeof(*id)))) {
155         free(type);
156         return KRB5_RC_MALLOC;
157     }
158
159     if ((retval = krb5_rc_resolve_type(context, &id,type))) {
160         free(type);
161         free(id);
162         return retval;
163     }
164     free(type);
165     if ((retval = krb5_rc_resolve(context, id,residual + 1))) {
166         k5_mutex_destroy(&id->lock);
167         free(id);
168         return retval;
169     }
170     id->magic = KV5M_RCACHE;
171     *idptr = id;
172     return retval;
173 }