aboutsummaryrefslogtreecommitdiff
path: root/src/lib/krb5/rcache/rc_dfl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/krb5/rcache/rc_dfl.c')
-rw-r--r--src/lib/krb5/rcache/rc_dfl.c411
1 files changed, 193 insertions, 218 deletions
diff --git a/src/lib/krb5/rcache/rc_dfl.c b/src/lib/krb5/rcache/rc_dfl.c
index cc046e7..596be40 100644
--- a/src/lib/krb5/rcache/rc_dfl.c
+++ b/src/lib/krb5/rcache/rc_dfl.c
@@ -17,19 +17,19 @@
#include <k5-int.h>
/*
-If NOIOSTUFF is defined at compile time, dfl rcaches will be per-process.
-*/
+ * If NOIOSTUFF is defined at compile time, dfl rcaches will be per-process.
+ */
/*
Local stuff:
-static int hash(krb5_donot_replay *rep,int hsize)
+static int hash(krb5_donot_replay *rep, int hsize)
returns hash value of *rep, between 0 and hsize - 1
HASHSIZE
size of hash table (constant), can be preset
-static int cmp(krb5_donot_replay *old,krb5_donot_replay *new,krb5_deltat t)
+static int cmp(krb5_donot_replay *old, krb5_donot_replay *new, krb5_deltat t)
compare old and new; return CMP_REPLAY or CMP_HOHUM
-static int alive (krb5_context, krb5_donot_replay *new,krb5_deltat t)
+static int alive(krb5_context, krb5_donot_replay *new, krb5_deltat t)
see if new is still alive; return CMP_EXPIRED or CMP_HOHUM
CMP_MALLOC, CMP_EXPIRED, CMP_REPLAY, CMP_HOHUM
return codes from cmp(), alive(), and store()
@@ -37,7 +37,7 @@ struct dfl_data
data stored in this cache type, namely "dfl"
struct authlist
multilinked list of reps
-static int rc_store(context, krb5_rcache id,krb5_donot_replay *rep)
+static int rc_store(context, krb5_rcache id, krb5_donot_replay *rep)
store rep in cache id; return CMP_REPLAY if replay, else CMP_MALLOC/CMP_HOHUM
*/
@@ -49,24 +49,26 @@ static int rc_store(context, krb5_rcache id,krb5_donot_replay *rep)
#ifndef EXCESSREPS
#define EXCESSREPS 30
#endif
-/* The rcache will be automatically expunged when the number of expired
-krb5_donot_replays encountered incidentally in searching exceeds the number
-of live krb5_donot_replays by EXCESSREPS. With the defaults here, a typical
-cache might build up some 10K of expired krb5_donot_replays before an automatic
-expunge, with the waste basically independent of the number of stores per
-minute.
-
-The rcache will also automatically be expunged when it encounters more
-than EXCESSREPS expired entries when recovering a cache in
-dfl_recover. */
-
-static int hash(rep, hsize)
-krb5_donot_replay *rep;
-int hsize;
+
+/*
+ * The rcache will be automatically expunged when the number of
+ * expired krb5_donot_replays encountered incidentally in searching
+ * exceeds the number of live krb5_donot_replays by EXCESSREPS. With
+ * the defaults here, a typical cache might build up some 10K of
+ * expired krb5_donot_replays before an automatic expunge, with the
+ * waste basically independent of the number of stores per minute.
+ *
+ * The rcache will also automatically be expunged when it encounters
+ * more than EXCESSREPS expired entries when recovering a cache in
+ * dfl_recover.
+ */
+
+static int
+hash(krb5_donot_replay *rep, int hsize)
{
- return (int) ((((rep->cusec + rep->ctime + *rep->server + *rep->client)
- % hsize) + hsize) % hsize);
- /* We take this opportunity to once again complain about C's idiotic %. */
+ return (int) ((((rep->cusec + rep->ctime + *rep->server + *rep->client)
+ % hsize) + hsize) % hsize);
+ /* We take this opportunity to once again complain about C's idiotic %. */
}
#define CMP_MALLOC -3
@@ -75,124 +77,114 @@ int hsize;
#define CMP_HOHUM 0
/*ARGSUSED*/
-static int cmp(old, new, t)
-krb5_donot_replay *old;
-krb5_donot_replay *new;
-krb5_deltat t;
+static int
+cmp(krb5_donot_replay *old, krb5_donot_replay *new, krb5_deltat t)
{
- if ((old->cusec == new->cusec) && /* most likely to distinguish */
- (old->ctime == new->ctime) &&
- (strcmp(old->client,new->client) == 0) &&
- (strcmp(old->server,new->server) == 0)) /* always true */
- return CMP_REPLAY;
- return CMP_HOHUM;
+ if ((old->cusec == new->cusec) && /* most likely to distinguish */
+ (old->ctime == new->ctime) &&
+ (strcmp(old->client, new->client) == 0) &&
+ (strcmp(old->server, new->server) == 0)) /* always true */
+ return CMP_REPLAY;
+ return CMP_HOHUM;
}
-static int alive(context, new, t)
- krb5_context context;
- krb5_donot_replay *new;
- krb5_deltat t;
+static int
+alive(krb5_context context, krb5_donot_replay *new, krb5_deltat t)
{
- krb5_int32 mytime;
-
- if (krb5_timeofday(context, &mytime))
- return CMP_HOHUM; /* who cares? */
- if (new->ctime + t < mytime) /* I hope we don't have to worry about overflow */
- return CMP_EXPIRED;
- return CMP_HOHUM;
+ krb5_int32 mytime;
+
+ if (krb5_timeofday(context, &mytime))
+ return CMP_HOHUM; /* who cares? */
+ /* I hope we don't have to worry about overflow */
+ if (new->ctime + t < mytime)
+ return CMP_EXPIRED;
+ return CMP_HOHUM;
}
struct dfl_data
- {
- char *name;
- krb5_deltat lifespan;
- int hsize;
- int numhits;
- int nummisses;
- struct authlist **h;
- struct authlist *a;
+{
+ char *name;
+ krb5_deltat lifespan;
+ int hsize;
+ int numhits;
+ int nummisses;
+ struct authlist **h;
+ struct authlist *a;
#ifndef NOIOSTUFF
- krb5_rc_iostuff d;
+ krb5_rc_iostuff d;
#endif
- char recovering;
- }
-;
+ char recovering;
+};
struct authlist
- {
- krb5_donot_replay rep;
- struct authlist *na;
- struct authlist *nh;
- }
-;
+{
+ krb5_donot_replay rep;
+ struct authlist *na;
+ struct authlist *nh;
+};
/* of course, list is backwards from file */
/* hash could be forwards since we have to search on match, but naaaah */
-static int rc_store(context, id, rep)
- krb5_context context;
- krb5_rcache id;
- krb5_donot_replay *rep;
+static int
+rc_store(krb5_context context, krb5_rcache id, krb5_donot_replay *rep)
{
- struct dfl_data *t = (struct dfl_data *)id->data;
- int rephash;
- struct authlist *ta;
-
- rephash = hash(rep,t->hsize);
+ struct dfl_data *t = (struct dfl_data *)id->data;
+ int rephash;
+ struct authlist *ta;
+
+ rephash = hash(rep, t->hsize);
+
+ for (ta = t->h[rephash]; ta; ta = ta->nh) {
+ switch(cmp(&ta->rep, rep, t->lifespan))
+ {
+ case CMP_REPLAY:
+ return CMP_REPLAY;
+ case CMP_HOHUM:
+ if (alive(context, &ta->rep, t->lifespan) == CMP_EXPIRED)
+ t->nummisses++;
+ else
+ t->numhits++;
+ break;
+ default:
+ ; /* wtf? */
+ }
+ }
- for (ta = t->h[rephash];ta;ta = ta->nh)
- switch(cmp(&ta->rep,rep,t->lifespan))
- {
- case CMP_REPLAY: return CMP_REPLAY;
- case CMP_HOHUM: if (alive(context, &ta->rep,t->lifespan) == CMP_EXPIRED)
- t->nummisses++;
- else
- t->numhits++;
- break;
- default: ; /* wtf? */
+ if (!(ta = (struct authlist *) malloc(sizeof(struct authlist))))
+ return CMP_MALLOC;
+ ta->na = t->a; t->a = ta;
+ ta->nh = t->h[rephash]; t->h[rephash] = ta;
+ ta->rep = *rep;
+ if (!(ta->rep.client = strdup(rep->client))) {
+ FREE(ta);
+ return CMP_MALLOC;
+ }
+ if (!(ta->rep.server = strdup(rep->server))) {
+ FREE(ta->rep.client);
+ FREE(ta);
+ return CMP_MALLOC;
}
- if (!(ta = (struct authlist *) malloc(sizeof(struct authlist))))
- return CMP_MALLOC;
- ta->na = t->a; t->a = ta;
- ta->nh = t->h[rephash]; t->h[rephash] = ta;
- ta->rep = *rep;
- if (!(ta->rep.client = strdup(rep->client))) {
- FREE(ta);
- return CMP_MALLOC;
- }
- if (!(ta->rep.server = strdup(rep->server))) {
- FREE(ta->rep.client);
- FREE(ta);
- return CMP_MALLOC;
- }
-
- return CMP_HOHUM;
+ return CMP_HOHUM;
}
char * KRB5_CALLCONV
-krb5_rc_dfl_get_name(context, id)
- krb5_context context;
- krb5_rcache id;
+krb5_rc_dfl_get_name(krb5_context context, krb5_rcache id)
{
- return ((struct dfl_data *) (id->data))->name;
+ return ((struct dfl_data *) (id->data))->name;
}
krb5_error_code KRB5_CALLCONV
-krb5_rc_dfl_get_span(context, id, lifespan)
- krb5_context context;
- krb5_rcache id;
- krb5_deltat *lifespan;
+krb5_rc_dfl_get_span(krb5_context context, krb5_rcache id,
+ krb5_deltat *lifespan)
{
- *lifespan = ((struct dfl_data *) (id->data))->lifespan;
- return 0;
+ *lifespan = ((struct dfl_data *) (id->data))->lifespan;
+ return 0;
}
krb5_error_code KRB5_CALLCONV
-krb5_rc_dfl_init(context, id, lifespan)
- krb5_context context;
-krb5_rcache id;
-krb5_deltat lifespan;
+krb5_rc_dfl_init(krb5_context context, krb5_rcache id, krb5_deltat lifespan)
{
struct dfl_data *t = (struct dfl_data *)id->data;
krb5_error_code retval;
@@ -200,7 +192,7 @@ krb5_deltat lifespan;
t->lifespan = lifespan ? lifespan : context->clockskew;
/* default to clockskew from the context */
#ifndef NOIOSTUFF
- if ((retval = krb5_rc_io_creat(context, &t->d,&t->name)))
+ if ((retval = krb5_rc_io_creat(context, &t->d, &t->name)))
return retval;
if ((krb5_rc_io_write(context, &t->d,
(krb5_pointer) &t->lifespan, sizeof(t->lifespan))
@@ -210,35 +202,32 @@ krb5_deltat lifespan;
return 0;
}
-krb5_error_code krb5_rc_dfl_close_no_free(context, id)
- krb5_context context;
- krb5_rcache id;
+krb5_error_code
+krb5_rc_dfl_close_no_free(krb5_context context, krb5_rcache id)
{
- struct dfl_data *t = (struct dfl_data *)id->data;
- struct authlist *q;
-
- FREE(t->h);
- if (t->name)
- FREE(t->name);
- while ((q = t->a))
- {
- t->a = q->na;
- FREE(q->rep.client);
- FREE(q->rep.server);
- FREE(q);
- }
+ struct dfl_data *t = (struct dfl_data *)id->data;
+ struct authlist *q;
+
+ FREE(t->h);
+ if (t->name)
+ FREE(t->name);
+ while ((q = t->a))
+ {
+ t->a = q->na;
+ FREE(q->rep.client);
+ FREE(q->rep.server);
+ FREE(q);
+ }
#ifndef NOIOSTUFF
- if (t->d.fd >= 0)
- (void) krb5_rc_io_close(context, &t->d);
+ if (t->d.fd >= 0)
+ (void) krb5_rc_io_close(context, &t->d);
#endif
- FREE(t);
- return 0;
+ FREE(t);
+ return 0;
}
krb5_error_code KRB5_CALLCONV
-krb5_rc_dfl_close(context, id)
- krb5_context context;
- krb5_rcache id;
+krb5_rc_dfl_close(krb5_context context, krb5_rcache id)
{
krb5_rc_dfl_close_no_free(context, id);
free(id);
@@ -246,22 +235,17 @@ krb5_rc_dfl_close(context, id)
}
krb5_error_code KRB5_CALLCONV
-krb5_rc_dfl_destroy(context, id)
- krb5_context context;
-krb5_rcache id;
+krb5_rc_dfl_destroy(krb5_context context, krb5_rcache id)
{
#ifndef NOIOSTUFF
- if (krb5_rc_io_destroy(context, &((struct dfl_data *) (id->data))->d))
- return KRB5_RC_IO;
+ if (krb5_rc_io_destroy(context, &((struct dfl_data *) (id->data))->d))
+ return KRB5_RC_IO;
#endif
- return krb5_rc_dfl_close(context, id);
+ return krb5_rc_dfl_close(context, id);
}
krb5_error_code KRB5_CALLCONV
-krb5_rc_dfl_resolve(context, id, name)
- krb5_context context;
- krb5_rcache id;
- char *name;
+krb5_rc_dfl_resolve(krb5_context context, krb5_rcache id, char *name)
{
struct dfl_data *t = 0;
krb5_error_code retval;
@@ -294,7 +278,7 @@ krb5_rc_dfl_resolve(context, id, name)
#endif
t->recovering = 0;
return 0;
-
+
cleanup:
if (t) {
if (t->name)
@@ -306,14 +290,13 @@ cleanup:
return retval;
}
-void krb5_rc_free_entry (context, rep)
- krb5_context context;
- krb5_donot_replay **rep;
+void
+krb5_rc_free_entry(krb5_context context, krb5_donot_replay **rep)
{
krb5_donot_replay *rp = *rep;
-
+
*rep = NULL;
- if (rp)
+ if (rp)
{
if (rp->client)
free(rp->client);
@@ -326,36 +309,34 @@ void krb5_rc_free_entry (context, rep)
}
}
-static krb5_error_code krb5_rc_io_fetch(context, t, rep, maxlen)
- krb5_context context;
- struct dfl_data *t;
- krb5_donot_replay *rep;
- int maxlen;
+static krb5_error_code
+krb5_rc_io_fetch(krb5_context context, struct dfl_data *t,
+ krb5_donot_replay *rep, int maxlen)
{
int len;
krb5_error_code retval;
rep->client = rep->server = 0;
-
- retval = krb5_rc_io_read (context, &t->d, (krb5_pointer) &len, sizeof(len));
- if (retval)
+
+ retval = krb5_rc_io_read(context, &t->d, (krb5_pointer) &len, sizeof(len));
+ if (retval)
return retval;
-
+
if ((len <= 0) || (len >= maxlen))
return KRB5_RC_IO_EOF;
rep->client = malloc (len);
if (!rep->client)
return KRB5_RC_MALLOC;
-
- retval = krb5_rc_io_read (context, &t->d, (krb5_pointer) rep->client, len);
+
+ retval = krb5_rc_io_read(context, &t->d, (krb5_pointer) rep->client, len);
if (retval)
goto errout;
-
- retval = krb5_rc_io_read (context, &t->d, (krb5_pointer) &len, sizeof(len));
+
+ retval = krb5_rc_io_read(context, &t->d, (krb5_pointer) &len, sizeof(len));
if (retval)
goto errout;
-
+
if ((len <= 0) || (len >= maxlen)) {
retval = KRB5_RC_IO_EOF;
goto errout;
@@ -366,21 +347,23 @@ static krb5_error_code krb5_rc_io_fetch(context, t, rep, maxlen)
retval = KRB5_RC_MALLOC;
goto errout;
}
-
- retval = krb5_rc_io_read (context, &t->d, (krb5_pointer) rep->server, len);
+
+ retval = krb5_rc_io_read(context, &t->d, (krb5_pointer) rep->server, len);
if (retval)
goto errout;
-
- retval = krb5_rc_io_read (context, &t->d, (krb5_pointer) &rep->cusec, sizeof(rep->cusec));
+
+ retval = krb5_rc_io_read(context, &t->d, (krb5_pointer) &rep->cusec,
+ sizeof(rep->cusec));
if (retval)
goto errout;
-
- retval = krb5_rc_io_read (context, &t->d, (krb5_pointer) &rep->ctime, sizeof(rep->ctime));
+
+ retval = krb5_rc_io_read(context, &t->d, (krb5_pointer) &rep->ctime,
+ sizeof(rep->ctime));
if (retval)
goto errout;
return 0;
-
+
errout:
if (rep->client)
krb5_xfree(rep->client);
@@ -389,13 +372,11 @@ errout:
rep->client = rep->server = 0;
return retval;
}
-
+
krb5_error_code KRB5_CALLCONV
-krb5_rc_dfl_recover(context, id)
- krb5_context context;
-krb5_rcache id;
+krb5_rc_dfl_recover(krb5_context context, krb5_rcache id)
{
#ifdef NOIOSTUFF
return KRB5_RC_NOIO;
@@ -411,11 +392,12 @@ krb5_rcache id;
return retval;
t->recovering = 1;
-
+
max_size = krb5_rc_io_size(context, &t->d);
-
+
rep = NULL;
- if (krb5_rc_io_read(context, &t->d,(krb5_pointer) &t->lifespan,sizeof(t->lifespan))) {
+ if (krb5_rc_io_read(context, &t->d, (krb5_pointer) &t->lifespan,
+ sizeof(t->lifespan))) {
retval = KRB5_RC_IO;
goto io_fail;
}
@@ -433,19 +415,19 @@ krb5_rcache id;
retval = KRB5_RC_IO;
goto io_fail;
}
-
- retval = krb5_rc_io_fetch (context, t, rep, (int) max_size);
+
+ retval = krb5_rc_io_fetch(context, t, rep, (int) max_size);
if (retval == KRB5_RC_IO_EOF)
break;
else if (retval != 0)
goto io_fail;
-
- if (alive(context, rep,t->lifespan) != CMP_EXPIRED) {
+
+ if (alive(context, rep, t->lifespan) != CMP_EXPIRED) {
if (rc_store(context, id, rep) == CMP_MALLOC) {
retval = KRB5_RC_MALLOC; goto io_fail;
- }
+ }
} else {
expired_entries++;
}
@@ -471,25 +453,23 @@ io_fail:
retval = krb5_rc_dfl_expunge(context, id);
t->recovering = 0;
return retval;
-
+
#endif
}
static krb5_error_code
-krb5_rc_io_store (context, t, rep)
- krb5_context context;
- struct dfl_data *t;
- krb5_donot_replay *rep;
+krb5_rc_io_store(krb5_context context, struct dfl_data *t,
+ krb5_donot_replay *rep)
{
unsigned int clientlen, serverlen, len;
char *buf, *ptr;
krb5_error_code ret;
- clientlen = strlen (rep->client) + 1;
- serverlen = strlen (rep->server) + 1;
+ clientlen = strlen(rep->client) + 1;
+ serverlen = strlen(rep->server) + 1;
len = sizeof(clientlen) + clientlen + sizeof(serverlen) + serverlen +
sizeof(rep->cusec) + sizeof(rep->ctime);
- buf = malloc (len);
+ buf = malloc(len);
if (buf == 0)
return KRB5_RC_MALLOC;
ptr = buf;
@@ -506,31 +486,28 @@ krb5_rc_io_store (context, t, rep)
}
krb5_error_code KRB5_CALLCONV
-krb5_rc_dfl_store(context, id, rep)
- krb5_context context;
-krb5_rcache id;
-krb5_donot_replay *rep;
+krb5_rc_dfl_store(krb5_context context, krb5_rcache id, krb5_donot_replay *rep)
{
krb5_error_code ret;
struct dfl_data *t = (struct dfl_data *)id->data;
- switch(rc_store(context, id,rep)) {
+ switch(rc_store(context, id, rep)) {
case CMP_MALLOC:
- return KRB5_RC_MALLOC;
+ return KRB5_RC_MALLOC;
case CMP_REPLAY:
- return KRB5KRB_AP_ERR_REPEAT;
+ return KRB5KRB_AP_ERR_REPEAT;
case 0: break;
default: /* wtf? */ ;
}
#ifndef NOIOSTUFF
- ret = krb5_rc_io_store (context, t, rep);
+ ret = krb5_rc_io_store(context, t, rep);
if (ret)
return ret;
#endif
- /* Shall we automatically expunge? */
- if (t->nummisses > t->numhits + EXCESSREPS)
+ /* Shall we automatically expunge? */
+ if (t->nummisses > t->numhits + EXCESSREPS)
{
- return krb5_rc_dfl_expunge(context, id);
+ return krb5_rc_dfl_expunge(context, id);
}
#ifndef NOIOSTUFF
else
@@ -539,13 +516,11 @@ krb5_donot_replay *rep;
return KRB5_RC_IO;
}
#endif
- return 0;
+ return 0;
}
krb5_error_code KRB5_CALLCONV
-krb5_rc_dfl_expunge(context, id)
- krb5_context context;
-krb5_rcache id;
+krb5_rc_dfl_expunge(krb5_context context, krb5_rcache id)
{
struct dfl_data *t = (struct dfl_data *)id->data;
#ifdef NOIOSTUFF
@@ -555,24 +530,24 @@ krb5_rcache id;
struct authlist *r;
struct authlist *rt;
- for (q = &t->a;*q;q = qt) {
+ for (q = &t->a; *q; q = qt) {
qt = &(*q)->na;
- if (alive(context, &(*q)->rep,t->lifespan) == CMP_EXPIRED) {
+ if (alive(context, &(*q)->rep, t->lifespan) == CMP_EXPIRED) {
FREE((*q)->rep.client);
FREE((*q)->rep.server);
FREE(*q);
*q = *qt; /* why doesn't this feel right? */
}
}
- for (i = 0;i < t->hsize;i++)
+ for (i = 0; i < t->hsize; i++)
t->h[i] = (struct authlist *) 0;
- for (r = t->a;r;r = r->na) {
- i = hash(&r->rep,t->hsize);
+ for (r = t->a; r; r = r->na) {
+ i = hash(&r->rep, t->hsize);
rt = t->h[i];
t->h[i] = r;
r->nh = rt;
}
-
+
#else
struct authlist *q;
char *name;
@@ -583,8 +558,8 @@ krb5_rcache id;
if (! t->recovering) {
name = t->name;
t->name = 0; /* Clear name so it isn't freed */
- (void) krb5_rc_dfl_close_no_free(context, id);
- retval = krb5_rc_dfl_resolve(context, id, name);
+ (void) krb5_rc_dfl_close_no_free(context, id);
+ retval = krb5_rc_dfl_resolve(context, id, name);
free(name);
if (retval)
return retval;
@@ -606,15 +581,15 @@ krb5_rcache id;
retval = krb5_rc_initialize(context, tmp, lifespan);
if (retval)
return retval;
- for (q = t->a;q;q = q->na) {
- if (krb5_rc_io_store (context, (struct dfl_data *)tmp->data, &q->rep))
+ for (q = t->a; q; q = q->na) {
+ if (krb5_rc_io_store(context, (struct dfl_data *)tmp->data, &q->rep))
return KRB5_RC_IO;
}
if (krb5_rc_io_sync(context, &t->d))
return KRB5_RC_IO;
if (krb5_rc_io_move(context, &t->d, &((struct dfl_data *)tmp->data)->d))
return KRB5_RC_IO;
- (void) krb5_rc_dfl_close(context, tmp);
+ (void) krb5_rc_dfl_close(context, tmp);
#endif
return 0;
}