rc_file.c (505d05c7) rc_file.c (159d09a2)
1/*
1/*
2 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
2 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
5
3 * Use is subject to license terms.
4 */
5
6#pragma ident "%Z%%M% %I% %E% SMI"
7
8/*
9 * lib/krb5/rcache/rc_file.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
6
7/*
8 * lib/krb5/rcache/rc_file.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 * An implementation for the default replay cache type.
18 */
16/*
17 * An implementation for the default replay cache type.
18 */
19/* Solaris Kerberos */
20#define FREE_RC(x) ((void) free((char *) (x)))
19#include "rc_common.h"
20#include "rc_file.h"
21
22/*
23 * Solaris: The NOIOSTUFF macro has been taken out for the Solaris version
24 * of this module, because this has been split into a separate mem rcache.
25 */
26
27/* of course, list is backwards from file */
28/* hash could be forwards since we have to search on match, but naaaah */
29
21#include "rc_common.h"
22#include "rc_file.h"
23
24/*
25 * Solaris: The NOIOSTUFF macro has been taken out for the Solaris version
26 * of this module, because this has been split into a separate mem rcache.
27 */
28
29/* of course, list is backwards from file */
30/* hash could be forwards since we have to search on match, but naaaah */
31
30static int rc_store(context, id, rep)
31 krb5_context context;
32 krb5_rcache id;
33 krb5_donot_replay *rep;
32static int
33rc_store(krb5_context context, krb5_rcache id, krb5_donot_replay *rep)
34{
35 struct file_data *t = (struct file_data *)id->data;
36 int rephash;
37 struct authlist *ta;
38 krb5_int32 time;
39
34{
35 struct file_data *t = (struct file_data *)id->data;
36 int rephash;
37 struct authlist *ta;
38 krb5_int32 time;
39
40 rephash = hash(rep,t->hsize);
40 rephash = hash(rep, t->hsize);
41
42 /* Solaris: calling krb_timeofday() here, once for better perf. */
43 krb5_timeofday(context, &time);
44
45 /* Solaris: calling alive() on rep since it doesn't make sense to store an
46 * expired replay.
47 */
48 if (alive(context, rep, t->lifespan, time) == CMP_EXPIRED){
49 return CMP_EXPIRED;
50 }
51
41
42 /* Solaris: calling krb_timeofday() here, once for better perf. */
43 krb5_timeofday(context, &time);
44
45 /* Solaris: calling alive() on rep since it doesn't make sense to store an
46 * expired replay.
47 */
48 if (alive(context, rep, t->lifespan, time) == CMP_EXPIRED){
49 return CMP_EXPIRED;
50 }
51
52 for (ta = t->h[rephash]; ta; ta = ta->nh)
52 for (ta = t->h[rephash]; ta; ta = ta->nh) {
53 switch(cmp(&ta->rep, rep))
54 {
53 switch(cmp(&ta->rep, rep))
54 {
55 case CMP_REPLAY: return CMP_REPLAY;
56 case CMP_HOHUM: if (alive(context, &ta->rep, t->lifespan, time)
57 == CMP_EXPIRED)
58 t->nummisses++;
59 else
60 t->numhits++;
61 break;
62 default: ; /* wtf? */
55 case CMP_REPLAY:
56 return CMP_REPLAY;
57 case CMP_HOHUM:
58 if (alive(context, &ta->rep, t->lifespan, time) == CMP_EXPIRED)
59 t->nummisses++;
60 else
61 t->numhits++;
62 break;
63 default:
64 ; /* wtf? */
63 }
65 }
66 }
64
65 if (!(ta = (struct authlist *) malloc(sizeof(struct authlist))))
66 return CMP_MALLOC;
67 ta->rep = *rep;
68 if (!(ta->rep.client = strdup(rep->client))) {
67
68 if (!(ta = (struct authlist *) malloc(sizeof(struct authlist))))
69 return CMP_MALLOC;
70 ta->rep = *rep;
71 if (!(ta->rep.client = strdup(rep->client))) {
69 free(ta);
72 FREE_RC(ta);
70 return CMP_MALLOC;
71 }
72 if (!(ta->rep.server = strdup(rep->server))) {
73 return CMP_MALLOC;
74 }
75 if (!(ta->rep.server = strdup(rep->server))) {
73 free(ta->rep.client);
74 free(ta);
76 FREE_RC(ta->rep.client);
77 FREE_RC(ta);
75 return CMP_MALLOC;
76 }
77 ta->na = t->a; t->a = ta;
78 ta->nh = t->h[rephash]; t->h[rephash] = ta;
79
80 return CMP_HOHUM;
81}
82
83/*ARGSUSED*/
84char * KRB5_CALLCONV
78 return CMP_MALLOC;
79 }
80 ta->na = t->a; t->a = ta;
81 ta->nh = t->h[rephash]; t->h[rephash] = ta;
82
83 return CMP_HOHUM;
84}
85
86/*ARGSUSED*/
87char * KRB5_CALLCONV
85krb5_rc_file_get_name(context, id)
86 krb5_context context;
87 krb5_rcache id;
88krb5_rc_file_get_name(krb5_context context, krb5_rcache id)
88{
89 return ((struct file_data *) (id->data))->name;
90}
91
92/*ARGSUSED*/
93krb5_error_code KRB5_CALLCONV
89{
90 return ((struct file_data *) (id->data))->name;
91}
92
93/*ARGSUSED*/
94krb5_error_code KRB5_CALLCONV
94krb5_rc_file_get_span(context, id, lifespan)
95 krb5_context context;
96 krb5_rcache id;
97 krb5_deltat *lifespan;
95krb5_rc_file_get_span(krb5_context context, krb5_rcache id,
96 krb5_deltat *lifespan)
98{
99 krb5_error_code err;
100 struct file_data *t;
101
102 err = k5_mutex_lock(&id->lock);
103 if (err)
104 return err;
105 t = (struct file_data *) id->data;
106 *lifespan = t->lifespan;
107 k5_mutex_unlock(&id->lock);
108 return 0;
109}
110
97{
98 krb5_error_code err;
99 struct file_data *t;
100
101 err = k5_mutex_lock(&id->lock);
102 if (err)
103 return err;
104 t = (struct file_data *) id->data;
105 *lifespan = t->lifespan;
106 k5_mutex_unlock(&id->lock);
107 return 0;
108}
109
111krb5_error_code KRB5_CALLCONV
112krb5_rc_file_init_locked(context, id, lifespan)
113 krb5_context context;
114 krb5_rcache id;
115 krb5_deltat lifespan;
110static krb5_error_code KRB5_CALLCONV
111krb5_rc_file_init_locked(krb5_context context, krb5_rcache id, krb5_deltat lifespan)
116{
117 struct file_data *t = (struct file_data *)id->data;
118 krb5_error_code retval;
119
120 t->lifespan = lifespan ? lifespan : context->clockskew;
121 /* default to clockskew from the context */
112{
113 struct file_data *t = (struct file_data *)id->data;
114 krb5_error_code retval;
115
116 t->lifespan = lifespan ? lifespan : context->clockskew;
117 /* default to clockskew from the context */
122 if ((retval = krb5_rc_io_creat(context, &t->d, &t->name)))
118 if ((retval = krb5_rc_io_creat(context, &t->d, &t->name))) {
123 return retval;
119 return retval;
120 }
124 if ((krb5_rc_io_write(context, &t->d,
125 (krb5_pointer) &t->lifespan, sizeof(t->lifespan))
121 if ((krb5_rc_io_write(context, &t->d,
122 (krb5_pointer) &t->lifespan, sizeof(t->lifespan))
126 || krb5_rc_io_sync(context, &t->d)))
123 || krb5_rc_io_sync(context, &t->d))) {
127 return KRB5_RC_IO;
124 return KRB5_RC_IO;
125 }
128 return 0;
129}
130
131krb5_error_code KRB5_CALLCONV
132krb5_rc_file_init(krb5_context context, krb5_rcache id, krb5_deltat lifespan)
133{
134 krb5_error_code retval;
135
136 retval = k5_mutex_lock(&id->lock);
137 if (retval)
138 return retval;
139 retval = krb5_rc_file_init_locked(context, id, lifespan);
140 k5_mutex_unlock(&id->lock);
141 return retval;
142}
143
126 return 0;
127}
128
129krb5_error_code KRB5_CALLCONV
130krb5_rc_file_init(krb5_context context, krb5_rcache id, krb5_deltat lifespan)
131{
132 krb5_error_code retval;
133
134 retval = k5_mutex_lock(&id->lock);
135 if (retval)
136 return retval;
137 retval = krb5_rc_file_init_locked(context, id, lifespan);
138 k5_mutex_unlock(&id->lock);
139 return retval;
140}
141
144krb5_error_code krb5_rc_file_close_no_free(context, id)
145 krb5_context context;
146 krb5_rcache id;
142/* Called with the mutex already locked. */
143krb5_error_code
144krb5_rc_file_close_no_free(krb5_context context, krb5_rcache id)
147{
145{
148 struct file_data *t = (struct file_data *)id->data;
149 struct authlist *q;
146 struct file_data *t = (struct file_data *)id->data;
147 struct authlist *q;
150
148
151 if (t->h)
152 free(t->h);
153 if (t->name)
154 free(t->name);
155
156 while ((q = t->a) != NULL)
157 {
158 t->a = q->na;
159 free(q->rep.client);
160 free(q->rep.server);
161 free(q);
162 }
149 if (t->h)
150 FREE_RC(t->h);
151 if (t->name)
152 FREE_RC(t->name);
153 while ((q = t->a))
154 {
155 t->a = q->na;
156 FREE_RC(q->rep.client);
157 FREE_RC(q->rep.server);
158 FREE_RC(q);
159 }
163 if (t->d.fd >= 0)
164 (void) krb5_rc_io_close(context, &t->d);
160 if (t->d.fd >= 0)
161 (void) krb5_rc_io_close(context, &t->d);
165 free(t);
166 id->data = NULL;
167 return 0;
162 FREE_RC(t);
163 id->data = NULL;
164 return 0;
168}
169
170krb5_error_code KRB5_CALLCONV
165}
166
167krb5_error_code KRB5_CALLCONV
171krb5_rc_file_close(context, id)
172 krb5_context context;
173 krb5_rcache id;
168krb5_rc_file_close(krb5_context context, krb5_rcache id)
174{
175 krb5_error_code retval;
176 retval = k5_mutex_lock(&id->lock);
177 if (retval)
178 return retval;
179 krb5_rc_file_close_no_free(context, id);
180 k5_mutex_unlock(&id->lock);
181 k5_mutex_destroy(&id->lock);
182 free(id);
183 return 0;
184}
185
186krb5_error_code KRB5_CALLCONV
169{
170 krb5_error_code retval;
171 retval = k5_mutex_lock(&id->lock);
172 if (retval)
173 return retval;
174 krb5_rc_file_close_no_free(context, id);
175 k5_mutex_unlock(&id->lock);
176 k5_mutex_destroy(&id->lock);
177 free(id);
178 return 0;
179}
180
181krb5_error_code KRB5_CALLCONV
187krb5_rc_file_destroy(context, id)
188 krb5_context context;
189 krb5_rcache id;
182krb5_rc_file_destroy(krb5_context context, krb5_rcache id)
190{
191 if (krb5_rc_io_destroy(context, &((struct file_data *) (id->data))->d))
192 return KRB5_RC_IO;
193 return krb5_rc_file_close(context, id);
194}
195
196/*ARGSUSED*/
197krb5_error_code KRB5_CALLCONV
183{
184 if (krb5_rc_io_destroy(context, &((struct file_data *) (id->data))->d))
185 return KRB5_RC_IO;
186 return krb5_rc_file_close(context, id);
187}
188
189/*ARGSUSED*/
190krb5_error_code KRB5_CALLCONV
198krb5_rc_file_resolve(context, id, name)
199 krb5_context context;
200 krb5_rcache id;
201 char *name;
191krb5_rc_file_resolve(krb5_context context, krb5_rcache id, char *name)
202{
203 struct file_data *t = 0;
204 krb5_error_code retval;
205
206 /* allocate id? no */
207 if (!(t = (struct file_data *) malloc(sizeof(struct file_data))))
208 return KRB5_RC_MALLOC;
209 id->data = (krb5_pointer) t;

--- 28 unchanged lines hidden (view full) ---

238 krb5_xfree(t->h);
239 krb5_xfree(t);
240 id->data = NULL;
241 }
242 return retval;
243}
244
245/*ARGSUSED*/
192{
193 struct file_data *t = 0;
194 krb5_error_code retval;
195
196 /* allocate id? no */
197 if (!(t = (struct file_data *) malloc(sizeof(struct file_data))))
198 return KRB5_RC_MALLOC;
199 id->data = (krb5_pointer) t;

--- 28 unchanged lines hidden (view full) ---

228 krb5_xfree(t->h);
229 krb5_xfree(t);
230 id->data = NULL;
231 }
232 return retval;
233}
234
235/*ARGSUSED*/
246void krb5_rc_free_entry (context, rep)
247 krb5_context context;
248 krb5_donot_replay **rep;
236void
237krb5_rc_free_entry(krb5_context context, krb5_donot_replay **rep)
249{
250 krb5_donot_replay *rp = *rep;
251
252 *rep = NULL;
253 if (rp)
254 {
255 if (rp->client)
256 free(rp->client);
257
258 if (rp->server)
259 free(rp->server);
260 rp->client = NULL;
261 rp->server = NULL;
262 free(rp);
263 }
264}
265
238{
239 krb5_donot_replay *rp = *rep;
240
241 *rep = NULL;
242 if (rp)
243 {
244 if (rp->client)
245 free(rp->client);
246
247 if (rp->server)
248 free(rp->server);
249 rp->client = NULL;
250 rp->server = NULL;
251 free(rp);
252 }
253}
254
266static krb5_error_code krb5_rc_io_fetch(context, t, rep, maxlen)
267 krb5_context context;
268 struct file_data *t;
269 krb5_donot_replay *rep;
270 int maxlen;
255static krb5_error_code
256krb5_rc_io_fetch(krb5_context context, struct file_data *t,
257 krb5_donot_replay *rep, int maxlen)
271{
258{
272 int len;
259 unsigned int len;
273 krb5_error_code retval;
274
275 rep->client = rep->server = 0;
276
260 krb5_error_code retval;
261
262 rep->client = rep->server = 0;
263
277 retval = krb5_rc_io_read (context, &t->d, (krb5_pointer) &len, sizeof(len));
264 retval = krb5_rc_io_read(context, &t->d, (krb5_pointer) &len,
265 sizeof(len));
278 if (retval)
279 return retval;
280
281 if ((len <= 0) || (len >= maxlen))
282 return KRB5_RC_IO_EOF;
283
284 rep->client = malloc (len);
285 if (!rep->client)
286 return KRB5_RC_MALLOC;
287
266 if (retval)
267 return retval;
268
269 if ((len <= 0) || (len >= maxlen))
270 return KRB5_RC_IO_EOF;
271
272 rep->client = malloc (len);
273 if (!rep->client)
274 return KRB5_RC_MALLOC;
275
288 retval = krb5_rc_io_read (context, &t->d, (krb5_pointer) rep->client, len);
276 retval = krb5_rc_io_read(context, &t->d, (krb5_pointer) rep->client, len);
289 if (retval)
290 goto errout;
291
277 if (retval)
278 goto errout;
279
292 retval = krb5_rc_io_read (context, &t->d, (krb5_pointer) &len, sizeof(len));
280 retval = krb5_rc_io_read(context, &t->d, (krb5_pointer) &len,
281 sizeof(len));
293 if (retval)
294 goto errout;
295
296 if ((len <= 0) || (len >= maxlen)) {
297 retval = KRB5_RC_IO_EOF;
298 goto errout;
299 }
300
301 rep->server = malloc (len);
302 if (!rep->server) {
303 retval = KRB5_RC_MALLOC;
304 goto errout;
305 }
306
282 if (retval)
283 goto errout;
284
285 if ((len <= 0) || (len >= maxlen)) {
286 retval = KRB5_RC_IO_EOF;
287 goto errout;
288 }
289
290 rep->server = malloc (len);
291 if (!rep->server) {
292 retval = KRB5_RC_MALLOC;
293 goto errout;
294 }
295
307 retval = krb5_rc_io_read (context, &t->d, (krb5_pointer) rep->server, len);
296 retval = krb5_rc_io_read(context, &t->d, (krb5_pointer) rep->server, len);
308 if (retval)
309 goto errout;
310
297 if (retval)
298 goto errout;
299
311 retval = krb5_rc_io_read (context, &t->d, (krb5_pointer) &rep->cusec, sizeof(rep->cusec));
300 retval = krb5_rc_io_read(context, &t->d, (krb5_pointer) &rep->cusec,
301 sizeof(rep->cusec));
312 if (retval)
313 goto errout;
314
302 if (retval)
303 goto errout;
304
315 retval = krb5_rc_io_read (context, &t->d, (krb5_pointer) &rep->ctime, sizeof(rep->ctime));
305 retval = krb5_rc_io_read(context, &t->d, (krb5_pointer) &rep->ctime,
306 sizeof(rep->ctime));
316 if (retval)
317 goto errout;
318
319 return 0;
320
321errout:
322 if (rep->client)
323 krb5_xfree(rep->client);
324 if (rep->server)
325 krb5_xfree(rep->server);
326 rep->client = rep->server = 0;
327 return retval;
328}
329
307 if (retval)
308 goto errout;
309
310 return 0;
311
312errout:
313 if (rep->client)
314 krb5_xfree(rep->client);
315 if (rep->server)
316 krb5_xfree(rep->server);
317 rep->client = rep->server = 0;
318 return retval;
319}
320
321
330static krb5_error_code
331krb5_rc_file_expunge_locked(krb5_context context, krb5_rcache id);
332
333static krb5_error_code
322static krb5_error_code
323krb5_rc_file_expunge_locked(krb5_context context, krb5_rcache id);
324
325static krb5_error_code
334krb5_rc_file_recover_locked(context, id)
335 krb5_context context;
336 krb5_rcache id;
326krb5_rc_file_recover_locked(krb5_context context, krb5_rcache id)
337{
338 struct file_data *t = (struct file_data *)id->data;
339 krb5_donot_replay *rep = 0;
340 krb5_error_code retval;
341 long max_size;
342 int expired_entries = 0;
343
327{
328 struct file_data *t = (struct file_data *)id->data;
329 krb5_donot_replay *rep = 0;
330 krb5_error_code retval;
331 long max_size;
332 int expired_entries = 0;
333
344 if ((retval = krb5_rc_io_open(context, &t->d, t->name)))
334 if ((retval = krb5_rc_io_open(context, &t->d, t->name))) {
345 return retval;
335 return retval;
336 }
346
347 t->recovering = 1;
348
349 max_size = krb5_rc_io_size(context, &t->d);
350
351 rep = NULL;
337
338 t->recovering = 1;
339
340 max_size = krb5_rc_io_size(context, &t->d);
341
342 rep = NULL;
352 if (krb5_rc_io_read(context, &t->d,(krb5_pointer) &t->lifespan,sizeof(t->lifespan))) {
343 if (krb5_rc_io_read(context, &t->d, (krb5_pointer) &t->lifespan,
344 sizeof(t->lifespan))) {
353 retval = KRB5_RC_IO;
354 goto io_fail;
355 }
356
357 if (!(rep = (krb5_donot_replay *) malloc(sizeof(krb5_donot_replay)))) {
358 retval = KRB5_RC_MALLOC;
359 goto io_fail;
360 }

--- 22 unchanged lines hidden (view full) ---

383 case CMP_MALLOC:
384 retval = KRB5_RC_MALLOC;
385 goto io_fail;
386 break;
387 }
388 /*
389 * free fields allocated by rc_io_fetch
390 */
345 retval = KRB5_RC_IO;
346 goto io_fail;
347 }
348
349 if (!(rep = (krb5_donot_replay *) malloc(sizeof(krb5_donot_replay)))) {
350 retval = KRB5_RC_MALLOC;
351 goto io_fail;
352 }

--- 22 unchanged lines hidden (view full) ---

375 case CMP_MALLOC:
376 retval = KRB5_RC_MALLOC;
377 goto io_fail;
378 break;
379 }
380 /*
381 * free fields allocated by rc_io_fetch
382 */
391 free(rep->server);
392 free(rep->client);
383 FREE_RC(rep->server);
384 FREE_RC(rep->client);
393 rep->server = 0;
394 rep->client = 0;
395 }
396 retval = 0;
397 krb5_rc_io_unmark(context, &t->d);
398 /*
399 * An automatic expunge here could remove the need for
400 * mark/unmark but that would be inefficient.
401 */
402io_fail:
403 krb5_rc_free_entry(context, &rep);
404 if (retval)
405 krb5_rc_io_close(context, &t->d);
406 else if (expired_entries > EXCESSREPS)
407 retval = krb5_rc_file_expunge_locked(context, id);
408 t->recovering = 0;
409 return retval;
410}
411
385 rep->server = 0;
386 rep->client = 0;
387 }
388 retval = 0;
389 krb5_rc_io_unmark(context, &t->d);
390 /*
391 * An automatic expunge here could remove the need for
392 * mark/unmark but that would be inefficient.
393 */
394io_fail:
395 krb5_rc_free_entry(context, &rep);
396 if (retval)
397 krb5_rc_io_close(context, &t->d);
398 else if (expired_entries > EXCESSREPS)
399 retval = krb5_rc_file_expunge_locked(context, id);
400 t->recovering = 0;
401 return retval;
402}
403
412
413krb5_error_code KRB5_CALLCONV
414krb5_rc_file_recover(krb5_context context, krb5_rcache id)
415{
416 krb5_error_code ret;
417 ret = k5_mutex_lock(&id->lock);
418 if (ret)
419 return ret;
420 ret = krb5_rc_file_recover_locked(context, id);

--- 12 unchanged lines hidden (view full) ---

433 return retval;
434 retval = krb5_rc_file_recover_locked(context, id);
435 if (retval)
436 retval = krb5_rc_file_init_locked(context, id, lifespan);
437 k5_mutex_unlock(&id->lock);
438 return retval;
439}
440
404krb5_error_code KRB5_CALLCONV
405krb5_rc_file_recover(krb5_context context, krb5_rcache id)
406{
407 krb5_error_code ret;
408 ret = k5_mutex_lock(&id->lock);
409 if (ret)
410 return ret;
411 ret = krb5_rc_file_recover_locked(context, id);

--- 12 unchanged lines hidden (view full) ---

424 return retval;
425 retval = krb5_rc_file_recover_locked(context, id);
426 if (retval)
427 retval = krb5_rc_file_init_locked(context, id, lifespan);
428 k5_mutex_unlock(&id->lock);
429 return retval;
430}
431
441
442static krb5_error_code
432static krb5_error_code
443krb5_rc_io_store (context, t, rep)
444 krb5_context context;
445 struct file_data *t;
446 krb5_donot_replay *rep;
433krb5_rc_io_store(krb5_context context, struct file_data *t,
434 krb5_donot_replay *rep)
447{
448 int clientlen, serverlen, len;
449 char *buf, *ptr;
450 krb5_error_code ret;
451
435{
436 int clientlen, serverlen, len;
437 char *buf, *ptr;
438 krb5_error_code ret;
439
452 clientlen = strlen (rep->client) + 1;
453 serverlen = strlen (rep->server) + 1;
440 clientlen = strlen(rep->client) + 1;
441 serverlen = strlen(rep->server) + 1;
454 len = sizeof(clientlen) + clientlen + sizeof(serverlen) + serverlen +
455 sizeof(rep->cusec) + sizeof(rep->ctime);
442 len = sizeof(clientlen) + clientlen + sizeof(serverlen) + serverlen +
443 sizeof(rep->cusec) + sizeof(rep->ctime);
456 buf = malloc (len);
444 buf = malloc(len);
457 if (buf == 0)
458 return KRB5_RC_MALLOC;
459 ptr = buf;
460 memcpy(ptr, &clientlen, sizeof(clientlen)); ptr += sizeof(clientlen);
461 memcpy(ptr, rep->client, clientlen); ptr += clientlen;
462 memcpy(ptr, &serverlen, sizeof(serverlen)); ptr += sizeof(serverlen);
463 memcpy(ptr, rep->server, serverlen); ptr += serverlen;
464 memcpy(ptr, &rep->cusec, sizeof(rep->cusec)); ptr += sizeof(rep->cusec);
465 memcpy(ptr, &rep->ctime, sizeof(rep->ctime)); ptr += sizeof(rep->ctime);
466
467 ret = krb5_rc_io_write(context, &t->d, buf, len);
468 free(buf);
469 return ret;
470}
471
472static krb5_error_code krb5_rc_file_expunge_locked(krb5_context, krb5_rcache);
473
474krb5_error_code KRB5_CALLCONV
445 if (buf == 0)
446 return KRB5_RC_MALLOC;
447 ptr = buf;
448 memcpy(ptr, &clientlen, sizeof(clientlen)); ptr += sizeof(clientlen);
449 memcpy(ptr, rep->client, clientlen); ptr += clientlen;
450 memcpy(ptr, &serverlen, sizeof(serverlen)); ptr += sizeof(serverlen);
451 memcpy(ptr, rep->server, serverlen); ptr += serverlen;
452 memcpy(ptr, &rep->cusec, sizeof(rep->cusec)); ptr += sizeof(rep->cusec);
453 memcpy(ptr, &rep->ctime, sizeof(rep->ctime)); ptr += sizeof(rep->ctime);
454
455 ret = krb5_rc_io_write(context, &t->d, buf, len);
456 free(buf);
457 return ret;
458}
459
460static krb5_error_code krb5_rc_file_expunge_locked(krb5_context, krb5_rcache);
461
462krb5_error_code KRB5_CALLCONV
475krb5_rc_file_store(context, id, rep)
476 krb5_context context;
477 krb5_rcache id;
478 krb5_donot_replay *rep;
463krb5_rc_file_store(krb5_context context, krb5_rcache id, krb5_donot_replay *rep)
479{
480 krb5_error_code ret;
481 struct file_data *t;
482
483 ret = k5_mutex_lock(&id->lock);
484 if (ret)
485 return ret;
486

--- 12 unchanged lines hidden (view full) ---

499 case CMP_HOHUM: break;
500 default: /* wtf? */ ;
501 }
502 ret = krb5_rc_io_store (context, t, rep);
503 if (ret) {
504 k5_mutex_unlock(&id->lock);
505 return ret;
506 }
464{
465 krb5_error_code ret;
466 struct file_data *t;
467
468 ret = k5_mutex_lock(&id->lock);
469 if (ret)
470 return ret;
471

--- 12 unchanged lines hidden (view full) ---

484 case CMP_HOHUM: break;
485 default: /* wtf? */ ;
486 }
487 ret = krb5_rc_io_store (context, t, rep);
488 if (ret) {
489 k5_mutex_unlock(&id->lock);
490 return ret;
491 }
507 /* Shall we automatically expunge? */
508 if (t->nummisses > t->numhits + EXCESSREPS)
492 /* Shall we automatically expunge? */
493 if (t->nummisses > t->numhits + EXCESSREPS)
509 {
510 ret = krb5_rc_file_expunge_locked(context, id);
511 k5_mutex_unlock(&id->lock);
512 return ret;
513 }
514 else
515 {
516 if (krb5_rc_io_sync(context, &t->d)) {
517 k5_mutex_unlock(&id->lock);
518 return KRB5_RC_IO;
519 }
520 }
494 {
495 ret = krb5_rc_file_expunge_locked(context, id);
496 k5_mutex_unlock(&id->lock);
497 return ret;
498 }
499 else
500 {
501 if (krb5_rc_io_sync(context, &t->d)) {
502 k5_mutex_unlock(&id->lock);
503 return KRB5_RC_IO;
504 }
505 }
521 k5_mutex_unlock(&id->lock);
522 return 0;
506 k5_mutex_unlock(&id->lock);
507 return 0;
523}
524
525static krb5_error_code
508}
509
510static krb5_error_code
526krb5_rc_file_expunge_locked(context, id)
527 krb5_context context;
528 krb5_rcache id;
511krb5_rc_file_expunge_locked(krb5_context context, krb5_rcache id)
529{
530 struct file_data *t = (struct file_data *)id->data;
531 struct authlist *q;
532 char *name;
533 krb5_error_code retval = 0;
534 krb5_rcache tmp;
535 krb5_deltat lifespan = t->lifespan; /* save original lifespan */
536
537 if (! t->recovering) {
538 name = t->name;
539 t->name = 0; /* Clear name so it isn't freed */
512{
513 struct file_data *t = (struct file_data *)id->data;
514 struct authlist *q;
515 char *name;
516 krb5_error_code retval = 0;
517 krb5_rcache tmp;
518 krb5_deltat lifespan = t->lifespan; /* save original lifespan */
519
520 if (! t->recovering) {
521 name = t->name;
522 t->name = 0; /* Clear name so it isn't freed */
540 (void) krb5_rc_file_close_no_free(context, id);
541 retval = krb5_rc_file_resolve(context, id, name);
523 (void) krb5_rc_file_close_no_free(context, id);
524 retval = krb5_rc_file_resolve(context, id, name);
542 free(name);
543 if (retval)
544 return retval;
545 retval = krb5_rc_file_recover_locked(context, id);
546 if (retval)
547 return retval;
548 t = (struct file_data *)id->data; /* point to recovered cache */
549 }
550
551 tmp = (krb5_rcache) malloc(sizeof(*tmp));
552 if (!tmp)
553 return ENOMEM;
554
555 retval = k5_mutex_init(&tmp->lock);
556 if (retval) {
525 free(name);
526 if (retval)
527 return retval;
528 retval = krb5_rc_file_recover_locked(context, id);
529 if (retval)
530 return retval;
531 t = (struct file_data *)id->data; /* point to recovered cache */
532 }
533
534 tmp = (krb5_rcache) malloc(sizeof(*tmp));
535 if (!tmp)
536 return ENOMEM;
537
538 retval = k5_mutex_init(&tmp->lock);
539 if (retval) {
557 free (tmp);
558 return retval;
540 free(tmp);
541 return retval;
559 }
560
561 tmp->ops = &krb5_rc_file_ops;
562 if ((retval = krb5_rc_file_resolve(context, tmp, 0)) != 0)
563 goto out;
564 if ((retval = krb5_rc_initialize(context, tmp, lifespan)) != 0)
565 goto out;
566 for (q = t->a;q;q = q->na) {

--- 33 unchanged lines hidden ---
542 }
543
544 tmp->ops = &krb5_rc_file_ops;
545 if ((retval = krb5_rc_file_resolve(context, tmp, 0)) != 0)
546 goto out;
547 if ((retval = krb5_rc_initialize(context, tmp, lifespan)) != 0)
548 goto out;
549 for (q = t->a;q;q = q->na) {

--- 33 unchanged lines hidden ---