diff options
Diffstat (limited to 'src/kdc')
-rw-r--r-- | src/kdc/ChangeLog | 102 | ||||
-rw-r--r-- | src/kdc/dispatch.c | 4 | ||||
-rw-r--r-- | src/kdc/do_as_req.c | 2 | ||||
-rw-r--r-- | src/kdc/do_tgs_req.c | 7 | ||||
-rw-r--r-- | src/kdc/kdc_preauth.c | 22 | ||||
-rw-r--r-- | src/kdc/kdc_util.c | 176 | ||||
-rw-r--r-- | src/kdc/kdc_util.h | 6 | ||||
-rw-r--r-- | src/kdc/kerberos_v4.c | 32 | ||||
-rw-r--r-- | src/kdc/main.c | 6 | ||||
-rw-r--r-- | src/kdc/replay.c | 42 |
10 files changed, 337 insertions, 62 deletions
diff --git a/src/kdc/ChangeLog b/src/kdc/ChangeLog index dd74460..29a7f66 100644 --- a/src/kdc/ChangeLog +++ b/src/kdc/ChangeLog @@ -1,3 +1,105 @@ +Tue Jul 21 20:29:38 1998 Tom Yu <tlyu@mit.edu> + + * replay.c (kdc_check_lookaside): + (kdc_insert_lookaside): Add code to originating address of packet, + as krb4 initial ticket requests don't contain an address. This + would cause a subtle problem wherein two simultaneous krb4 initial + ticket requests for the same principal originating from different + addresses would result in both replies containing the same + address. + + * kdc_util.h: Modify prototype for lookaside functions. + + * dispatch.c (dispatch): Update to new calling conventions of the + lookaside functions. + +Fri May 8 18:46:59 1998 Theodore Y. Ts'o <tytso@mit.edu> + + * kerberos_v4.c (krb4_stime): Print 4 digit years in Krb4 log + entries to avoid Y2K issues. + +Fri Mar 20 17:13:46 1998 Tom Yu <tlyu@mit.edu> + + * kdc_util.c (add_to_transited): Check lengths, fix up comma + quoting somewhat (though things are still way broken). + +Thu Feb 5 19:09:06 1998 Tom Yu <tlyu@mit.edu> + + * kerberos_v4.c: Fix up call to klog, also delete logic to check + whether v4 processing is disabled (relies on code that is only in + the mainline). + +Wed Feb 4 14:15:20 1998 Theodore Y. Ts'o <tytso@mit.edu> + + * kerberos_v4.c (process_v4): Check the length of the incoming V4 + packet before copying it into the KTEXT_ST variable. + (kerberos_v4): Make sure the strings in the V4 request + structures aren't no longer than they are allowed to be. + +Fri Jan 16 03:33:50 1998 Tom Yu <tlyu@mit.edu> + + * do_tgs_req.c: Add some explicit settings of errcode so that the + cleanup code doesn't try to construct a bogus error reply, which + was causing coredumps in the lookaside code. + +Mon Nov 24 19:57:48 1997 Theodore Y. Ts'o <tytso@mit.edu> + + * do_tgs_req.c (process_tgs_req): Add check to make sure cname and + sname are non-NULL when syslogging an error because the + principals don't match. + + * kdc_util.c (limit_string): Check to make sure the input string + is non-NULL before operating on it. + +Wed Sep 24 11:56:50 1997 Ezra Peisach <epeisach@kangaroo.mit.edu> + + * kdc_util.c (add_to_transited): Fix up memory leaks, clean out + new memory allocated, allocate buffers to max size + needed. [based on krb5-kdc/461 by Ken Hornstein]. + +Wed Jul 30 18:29:19 1997 Tom Yu <tlyu@mit.edu> + + * kdc_util.c: + * main.c: Don't use an rcache. + +Tue Jul 15 01:55:56 1997 Tom Yu <tlyu@mit.edu> + + * kdc_preauth.c (get_sam_edata): Don't goto cleanup if SAM is not + used; this prevents freeing an unallocated keyblock. + +Thu May 29 21:08:24 1997 Theodore Y. Ts'o <tytso@mit.edu> + + * do_as_req.c (process_as_req), do_tgs_req (process_tgs_req): Use + limit_string() to make sure the length of cname and sname + are reasonable. + + * kdc_util.c (limit_string): New function which limits the strings + that will end up in log files to "reasonable" lengths. + +Wed Jan 1 22:56:16 1997 Ezra Peisach <epeisach@mit.edu> + + * kdc_preauth.c (get_sam_edata): Use proper interface to + krb5_db_get_principal. Also if SAM is not an option, do + not return as a possible type to client. [krb5-kdc/310] + +Sat Nov 23 17:26:22 1996 Mark Eichin <eichin@kitten.gen.ma.us> + + * [krb5-libs/149] only generate requests that you can actually + handle. + + Tue Sep 3 22:53:56 1996 Mark Eichin <eichin@cygnus.com> + + * kdc_preauth.c (get_preauth_hint_list): detect ap->get_edata + return status and don't pass back hint if it failed. + (get_etype_info): malloc one more word in entry for end marker. + +Wed Nov 20 11:25:05 1996 Barry Jaspan <bjaspan@mit.edu> + + * main.c (initialize_realms): krb5_aprof_init can succeed while + leaving aprof == NULL, but krb5_aprof_finish will fail. This is + just more grossness that needs to be redone when the kdc.conf + interface is reworked. + Thu Nov 7 12:27:21 1996 Theodore Ts'o <tytso@rsts-11.mit.edu> * kdc_preauth.c (check_padata): Fixed error handling; in order for diff --git a/src/kdc/dispatch.c b/src/kdc/dispatch.c index a94173c..7446ea5 100644 --- a/src/kdc/dispatch.c +++ b/src/kdc/dispatch.c @@ -43,7 +43,7 @@ dispatch(pkt, from, portnum, response) /* decode incoming packet, and dispatch */ /* try the replay lookaside buffer */ - if (kdc_check_lookaside(pkt, response)) { + if (kdc_check_lookaside(pkt, from, response)) { /* a hit! */ krb5_klog_syslog(LOG_INFO, "DISPATCH: replay found and re-transmitted"); return 0; @@ -72,7 +72,7 @@ dispatch(pkt, from, portnum, response) retval = KRB5KRB_AP_ERR_MSG_TYPE; /* put the response into the lookaside buffer */ if (!retval) - kdc_insert_lookaside(pkt, *response); + kdc_insert_lookaside(pkt, from, *response); return retval; } diff --git a/src/kdc/do_as_req.c b/src/kdc/do_as_req.c index cf999fe..bb2ca80 100644 --- a/src/kdc/do_as_req.c +++ b/src/kdc/do_as_req.c @@ -99,6 +99,7 @@ krb5_data **response; /* filled in with a response packet */ status = "UNPARSING_CLIENT"; goto errout; } + limit_string(cname); if (!request->server) { status = "NULL_SERVER"; errcode = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN; @@ -108,6 +109,7 @@ krb5_data **response; /* filled in with a response packet */ status = "UNPARSING_SERVER"; goto errout; } + limit_string(sname); c_nprincs = 1; if ((errcode = krb5_db_get_principal(kdc_context, request->client, diff --git a/src/kdc/do_tgs_req.c b/src/kdc/do_tgs_req.c index 0ea2df1..242a6c3 100644 --- a/src/kdc/do_tgs_req.c +++ b/src/kdc/do_tgs_req.c @@ -130,6 +130,7 @@ krb5_data **response; /* filled in with a response packet */ } if (!header_ticket) { + errcode = KRB5_NO_TKT_SUPPLIED; /* XXX? */ status="UNEXPECTED NULL in header_ticket"; goto cleanup; } @@ -419,6 +420,7 @@ tgt_again: if (!(scratch.data = malloc(request->authorization_data.ciphertext.length))) { status = "AUTH_NOMEM"; + errcode = ENOMEM; goto cleanup; } /* do any necessary key pre-processing */ @@ -525,8 +527,11 @@ tgt_again: &tmp))) tmp = 0; krb5_klog_syslog(LOG_INFO, "TGS_REQ %s(%d): 2ND_TKT_MISMATCH: authtime %d, %s for %s, 2nd tkt client %s", - fromstring, portnum, authtime, cname, sname, + fromstring, portnum, authtime, + cname ? cname : "<unknown client>", + sname ? sname : "<unknown server>", tmp ? tmp : "<unknown>"); + errcode = KRB5KDC_ERR_SERVER_NOMATCH; goto cleanup; } diff --git a/src/kdc/kdc_preauth.c b/src/kdc/kdc_preauth.c index 0350068..4c28b0b 100644 --- a/src/kdc/kdc_preauth.c +++ b/src/kdc/kdc_preauth.c @@ -203,8 +203,15 @@ void get_preauth_hint_list(request, client, server, e_data) memset(*pa, 0, sizeof(krb5_pa_data)); (*pa)->magic = KV5M_PA_DATA; (*pa)->pa_type = ap->type; - if (ap->get_edata) - (ap->get_edata)(kdc_context, request, client, server, *pa); + if (ap->get_edata) { + retval = (ap->get_edata)(kdc_context, request, client, server, *pa); + if (retval) { + /* just failed on this type, continue */ + free(*pa); + *pa = 0; + continue; + } + } pa++; } retval = encode_krb5_padata_sequence((const krb5_pa_data **) pa_data, @@ -433,7 +440,7 @@ get_etype_info(context, request, client, server, pa_data) salt.data = 0; - entry = malloc((client->n_key_data * 2) * sizeof(krb5_etype_info_entry *)); + entry = malloc((client->n_key_data * 2 + 1) * sizeof(krb5_etype_info_entry *)); if (entry == NULL) return ENOMEM; entry[0] = NULL; @@ -630,7 +637,8 @@ get_sam_edata(context, request, client, server, pa_data) { char *uname; - int npr = 1, more; + int npr = 1; + krb5_boolean more; krb5_db_entry assoc; krb5_key_data *assoc_key; krb5_principal newp; @@ -656,7 +664,7 @@ get_sam_edata(context, request, client, server, pa_data) strlen(sam_ptr->name); npr = 1; retval = krb5_db_get_principal(kdc_context, newp, &assoc, &npr, &more); - if(!retval) { + if(!retval && npr) { sc.sam_type = sam_ptr->sam_type; break; } @@ -690,7 +698,9 @@ get_sam_edata(context, request, client, server, pa_data) } /* now we can use encrypting_key... */ } - } + } else + /* SAM is not an option - so don't return as hint */ + return KRB5_PREAUTH_BAD_TYPE; krb5_princ_component(kdc_context,newp,probeslot)->data = 0; krb5_princ_component(kdc_context,newp,probeslot)->length = 0; diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c index a711a27..f93b3d2 100644 --- a/src/kdc/kdc_util.c +++ b/src/kdc/kdc_util.c @@ -207,10 +207,11 @@ kdc_process_tgs_req(request, from, pkt, ticket, subkey) if ((retval = krb5_auth_con_setaddrs(kdc_context, auth_context, NULL, from->address)) ) goto cleanup_auth_context; - +#ifdef USE_RCACHE if ((retval = krb5_auth_con_setrcache(kdc_context, auth_context, kdc_rcache))) goto cleanup_auth_context; +#endif /* if ((retval = kdc_get_server_key(apreq->ticket, &key, &kvno))) @@ -232,6 +233,7 @@ kdc_process_tgs_req(request, from, pkt, ticket, subkey) apreq->ticket->server, kdc_active_realm->realm_keytab, NULL, ticket))) { +#ifdef USE_RCACHE /* * I'm not so sure that this is right, but it's better than nothing * at all. @@ -256,6 +258,7 @@ kdc_process_tgs_req(request, from, pkt, ticket, subkey) } } else goto cleanup_auth_context; +#endif } /* "invalid flag" tickets can must be used to validate */ @@ -315,7 +318,9 @@ cleanup_authenticator: cleanup_auth_context: /* We do not want the free of the auth_context to close the rcache */ +#ifdef USE_RCACHE (void) krb5_auth_con_setrcache(kdc_context, auth_context, 0); +#endif krb5_auth_con_free(kdc_context, auth_context); cleanup: @@ -530,9 +535,10 @@ add_to_transited(tgt_trans, new_trans, tgs, client, server) krb5_principal client; krb5_principal server; { + krb5_error_code retval; char *realm; char *trans; - char *otrans; + char *otrans, *otrans_ptr; /* The following are for stepping through the transited field */ @@ -541,6 +547,7 @@ add_to_transited(tgt_trans, new_trans, tgs, client, server) char current[MAX_REALM_LN]; char exp[MAX_REALM_LN]; /* Expanded current realm name */ + int i; int clst, nlst; /* count of last character in current and next */ int pl, pl1; /* prefix length */ int added; /* TRUE = new realm has been added */ @@ -553,35 +560,52 @@ add_to_transited(tgt_trans, new_trans, tgs, client, server) realm[krb5_princ_realm(kdc_context, tgs)->length] = '\0'; if (!(otrans = (char *) malloc(tgt_trans->length+1))) { + free(realm); return(ENOMEM); } memcpy(otrans, tgt_trans->data, tgt_trans->length); otrans[tgt_trans->length] = '\0'; - - if (!(trans = (char *) malloc(strlen(realm) + strlen(otrans) + 1))) { - return(ENOMEM); + /* Keep track of start so we can free */ + otrans_ptr = otrans; + + /* +1 for null, + +1 for extra comma which may be added between + +1 for potential space when leading slash in realm */ + if (!(trans = (char *) malloc(strlen(realm) + strlen(otrans) + 3))) { + retval = ENOMEM; + goto fail; } if (new_trans->data) free(new_trans->data); new_trans->data = trans; + new_trans->length = 0; + + trans[0] = '\0'; /* For the purpose of appending, the realm preceding the first */ /* realm in the transited field is considered the null realm */ prev[0] = '\0'; - /***** In next statement, need to keep reading if the , was quoted *****/ /* read field into current */ - - if (sscanf(otrans, "%[^,]", current) == 1) { - otrans += strlen(current); - } - else { - current[0] = '\0'; + for (i = 0; *otrans != '\0';) { + if (*otrans == '\\') + if (*(++otrans) == '\0') + break; + else + continue; + if (*otrans == ',') { + otrans++; + break; + } + current[i++] = *otrans++; + if (i >= MAX_REALM_LN) { + retval = KRB5KRB_AP_ERR_ILL_CR_TKT; + goto fail; + } } + current[i] = '\0'; - if (otrans[0] == ',') otrans++; - added = (krb5_princ_realm(kdc_context, client)->length == strlen(realm) && !strncmp(krb5_princ_realm(kdc_context, client)->data, realm, strlen(realm))) || (krb5_princ_realm(kdc_context, server)->length == strlen(realm) && @@ -597,29 +621,43 @@ add_to_transited(tgt_trans, new_trans, tgs, client, server) } else if ((current[0] == '/') && (prev[0] == '/')) { strcpy(exp, prev); + if (strlen(exp) + strlen(current) + 1 >= MAX_REALM_LN) { + retval = KRB5KRB_AP_ERR_ILL_CR_TKT; + goto fail; + } strcat(exp, current); } else if (current[clst] == '.') { strcpy(exp, current); + if (strlen(exp) + strlen(current) + 1 >= MAX_REALM_LN) { + retval = KRB5KRB_AP_ERR_ILL_CR_TKT; + goto fail; + } strcat(exp, prev); } else { strcpy(exp, current); } - /***** next statement, need to keep reading if the , was quoted *****/ /* read field into next */ - - if (sscanf(otrans, "%[^,]", next) == 1) { - otrans += strlen(next); - nlst = strlen(next) - 1; - } - else { - next[0] = '\0'; - nlst = 0; + for (i = 0; *otrans != '\0';) { + if (*otrans == '\\') + if (*(++otrans) == '\0') + break; + else + continue; + if (*otrans == ',') { + otrans++; + break; + } + next[i++] = *otrans++; + if (i >= MAX_REALM_LN) { + retval = KRB5KRB_AP_ERR_ILL_CR_TKT; + goto fail; + } } - - if (otrans[0] == ',') otrans++; + next[i] = '\0'; + nlst = i - 1; if (!strcmp(exp, realm)) added = TRUE; @@ -640,6 +678,10 @@ add_to_transited(tgt_trans, new_trans, tgs, client, server) if ((next[nlst] != '.') && (next[0] != '/') && (pl = subrealm(exp, realm))) { added = TRUE; + if (strlen(current) + (pl>0?pl:-pl) + 2 >= MAX_REALM_LN) { + retval = KRB5KRB_AP_ERR_ILL_CR_TKT; + goto fail; + } strcat(current, ","); if (pl > 0) { strncat(current, realm, pl); @@ -663,6 +705,10 @@ add_to_transited(tgt_trans, new_trans, tgs, client, server) added = TRUE; current[0] = '\0'; if ((pl1 = subrealm(prev,realm))) { + if (strlen(current) + (pl1>0?pl1:-pl1) + 1 >= MAX_REALM_LN) { + retval = KRB5KRB_AP_ERR_ILL_CR_TKT; + goto fail; + } if (pl1 > 0) { strncat(current, realm, pl1); } @@ -672,10 +718,22 @@ add_to_transited(tgt_trans, new_trans, tgs, client, server) } else { /* If not a subrealm */ if ((realm[0] == '/') && prev[0]) { - strcat(current, " "); + if (strlen(current) + 2 >= MAX_REALM_LN) { + retval = KRB5KRB_AP_ERR_ILL_CR_TKT; + goto fail; + } + strcat(current, " "); } + if (strlen(current) + strlen(realm) + 1 >= MAX_REALM_LN) { + retval = KRB5KRB_AP_ERR_ILL_CR_TKT; + goto fail; + } strcat(current, realm); } + if (strlen(current) + (pl>0?pl:-pl) + 2 >= MAX_REALM_LN) { + retval = KRB5KRB_AP_ERR_ILL_CR_TKT; + goto fail; + } strcat(current,","); if (pl > 0) { strncat(current, exp, pl); @@ -686,7 +744,17 @@ add_to_transited(tgt_trans, new_trans, tgs, client, server) } } - if (new_trans->length != 0) strcat(trans, ","); + if (new_trans->length != 0) { + if (strlen(trans) + 2 >= MAX_REALM_LN) { + retval = KRB5KRB_AP_ERR_ILL_CR_TKT; + goto fail; + } + strcat(trans, ","); + } + if (strlen(trans) + strlen(current) + 1 >= MAX_REALM_LN) { + retval = KRB5KRB_AP_ERR_ILL_CR_TKT; + goto fail; + } strcat(trans, current); new_trans->length = strlen(trans) + 1; @@ -695,13 +763,33 @@ add_to_transited(tgt_trans, new_trans, tgs, client, server) } if (!added) { - if (new_trans->length != 0) strcat(trans, ","); - if((realm[0] == '/') && trans[0]) strcat(trans, " "); + if (new_trans->length != 0) { + if (strlen(trans) + 2 >= MAX_REALM_LN) { + retval = KRB5KRB_AP_ERR_ILL_CR_TKT; + goto fail; + } + strcat(trans, ","); + } + if((realm[0] == '/') && trans[0]) { + if (strlen(trans) + 2 >= MAX_REALM_LN) { + retval = KRB5KRB_AP_ERR_ILL_CR_TKT; + goto fail; + } + strcat(trans, " "); + } + if (strlen(trans) + strlen(realm) + 1 >= MAX_REALM_LN) { + retval = KRB5KRB_AP_ERR_ILL_CR_TKT; + goto fail; + } strcat(trans, realm); new_trans->length = strlen(trans) + 1; } - return(0); + retval = 0; +fail: + free(realm); + free(otrans_ptr); + return (retval); } /* @@ -912,7 +1000,7 @@ krb5_data *data; { unsigned char *estream; /* end of stream */ int classes; /* # classes seen so far this level */ - int levels = 0; /* levels seen so far */ + unsigned int levels = 0; /* levels seen so far */ int lastlevel = 1000; /* last level seen */ int length; /* various lengths */ int tag; /* tag number */ @@ -1375,8 +1463,26 @@ get_salt_from_key(context, client, client_key, salt) return 0; } +/* + * Limit strings to a "reasonable" length to prevent crowding out of + * other useful information in the log entry + */ +#define NAME_LENGTH_LIMIT 128 - - - - +void limit_string(char *name) +{ + int i; + + if (!name) + return; + + if (strlen(name) < NAME_LENGTH_LIMIT) + return; + + i = NAME_LENGTH_LIMIT-4; + name[i++] = '.'; + name[i++] = '.'; + name[i++] = '.'; + name[i] = '\0'; + return; +} diff --git a/src/kdc/kdc_util.h b/src/kdc/kdc_util.h index b869f6f..c9e0d23 100644 --- a/src/kdc/kdc_util.h +++ b/src/kdc/kdc_util.h @@ -145,8 +145,10 @@ krb5_error_code return_padata krb5_key_data *client_key, krb5_keyblock *encrypting_key)); /* replay.c */ -krb5_boolean kdc_check_lookaside PROTOTYPE((krb5_data *, krb5_data **)); -void kdc_insert_lookaside PROTOTYPE((krb5_data *, krb5_data *)); +krb5_boolean kdc_check_lookaside PROTOTYPE((krb5_data *, krb5_fulladdr *, + krb5_data **)); +void kdc_insert_lookaside PROTOTYPE((krb5_data *, krb5_fulladdr *, + krb5_data *)); /* which way to convert key? */ #define CONVERT_INTO_DB 0 diff --git a/src/kdc/kerberos_v4.c b/src/kdc/kerberos_v4.c index db074d9..cea4bf0 100644 --- a/src/kdc/kerberos_v4.c +++ b/src/kdc/kerberos_v4.c @@ -82,6 +82,7 @@ char * v4_klog KRB5_PROTOTYPE((int, const char *, ...)); #else char * v4_klog KRB5_PROTOTYPE((int, char *, va_dcl)); #endif +#define klog v4_klog /* take this out when we don't need it anymore */ int krbONE = 1; @@ -104,7 +105,7 @@ static Principal a_name_data; /* for requesting user */ static Principal s_name_data; /* for services requested */ static C_Block session_key; -static char log_text[128]; +static char log_text[512]; static char *lt; static int more; @@ -190,6 +191,10 @@ krb5_data **resp; /* convert v5 packet structure to v5's. * this copy is gross, but necessary: */ + if (pkt->length > MAX_KTXT_LEN) { + (void) klog(L_KRB_PERR, "V4 request too long."); + return KRB5KRB_ERR_FIELD_TOOLONG; + } v4_pkt.length = pkt->length; memcpy( v4_pkt.dat, pkt->data, pkt->length); @@ -218,7 +223,6 @@ int type_2_v5err[] = { 0, /* 0 No error */ KRB_AP_ERR_BADVERSION /* L_KRB_PWARN 16 Protocol warning messages */ }; #endif -#define klog v4_klog #ifdef HAVE_STDARG_H char * v4_klog( int type, const char *format, ...) #else @@ -448,6 +452,21 @@ kerb_get_principal(name, inst, principal, maxn, more) *more = (int) more5 || (nprinc > maxn); return( nprinc); } + +static void str_length_check(str, max_size) + char *str; + int max_size; +{ + int i; + char *cp; + + for (i=0, cp = str; i < max_size-1; i++, cp++) { + if (*cp == 0) + return; + } + *cp = 0; +} + void kerberos_v4(client, pkt) struct sockaddr_in *client; @@ -528,8 +547,11 @@ kerberos_v4(client, pkt) /* set up and correct for byte order and alignment */ req_name_ptr = (char *) pkt_a_name(pkt); + str_length_check(req_name_ptr, ANAME_SZ); req_inst_ptr = (char *) pkt_a_inst(pkt); + str_length_check(req_inst_ptr, INST_SZ); req_realm_ptr = (char *) pkt_a_realm(pkt); + str_length_check(req_realm_ptr, REALM_SZ); memcpy(&req_time_ws, pkt_time_ws(pkt), sizeof(req_time_ws)); /* time has to be diddled */ if (swap_bytes) { @@ -540,7 +562,9 @@ kerberos_v4(client, pkt) req_life = (u_long) (*ptr++); service = ptr; + str_length_check(service, SNAME_SZ); instance = ptr + strlen(service) + 1; + str_length_check(instance, INST_SZ); rpkt = &rpkt_st; @@ -672,7 +696,9 @@ kerberos_v4(client, pkt) req_life = (u_long) (*ptr++); service = ptr; + str_length_check(service, SNAME_SZ); instance = ptr + strlen(service) + 1; + str_length_check(instance, INST_SZ); klog(L_APPL_REQ, "APPL Request %s.%s@%s on %s for %s.%s", ad->pname, ad->pinst, ad->prealm, @@ -872,7 +898,7 @@ static char *krb4_stime(t) adjusted_time = *t /* - CONVERT_TIME_EPOCH */; tm = localtime(&adjusted_time); - (void) sprintf(st,"%2d-%s-%02d %02d:%02d:%02d",tm->tm_mday, + (void) sprintf(st,"%4d-%s-%02d %02d:%02d:%02d",tm->tm_mday+1900, month_sname(tm->tm_mon + 1),tm->tm_year, tm->tm_hour, tm->tm_min, tm->tm_sec); return st; diff --git a/src/kdc/main.c b/src/kdc/main.c index dd4ae76..2dff8fc 100644 --- a/src/kdc/main.c +++ b/src/kdc/main.c @@ -721,7 +721,9 @@ initialize_realms(kcontext, argc, argv) hierarchy[2] = (char *) NULL; if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &default_ports)) default_ports = 0; - krb5_aprof_finish(aprof); + /* aprof_init can return 0 with aprof == NULL */ + if (aprof) + krb5_aprof_finish(aprof); } if (default_ports == 0) default_ports = strdup(DEFAULT_KDC_PORTLIST); @@ -803,6 +805,7 @@ initialize_realms(kcontext, argc, argv) } } +#ifdef USE_RCACHE /* * Now handle the replay cache. */ @@ -810,6 +813,7 @@ initialize_realms(kcontext, argc, argv) com_err(argv[0], retval, "while initializing KDC replay cache"); exit(1); } +#endif /* Ensure that this is set for our first request. */ kdc_active_realm = kdc_realmlist[0]; diff --git a/src/kdc/replay.c b/src/kdc/replay.c index 1ec38a3..ffd14fe 100644 --- a/src/kdc/replay.c +++ b/src/kdc/replay.c @@ -36,6 +36,7 @@ typedef struct _krb5_kdc_replay_ent { time_t db_age; krb5_data *req_packet; krb5_data *reply_packet; + krb5_address *addr; /* XXX should these not be pointers? */ } krb5_kdc_replay_ent; static krb5_kdc_replay_ent root_ptr = {0}; @@ -46,13 +47,16 @@ static int max_hits_per_entry = 0; static int num_entries = 0; #define STALE_TIME 2*60 /* two minutes */ -#define STALE(ptr) ((abs((ptr)->timein - timenow) >= STALE_TIME) || \ +#define STALE(ptr) ((abs((ptr)->timein - timenow) >= STALE_TIME) || \ ((ptr)->db_age != db_age)) -#define MATCH(ptr) (((ptr)->req_packet->length == inpkt->length) && \ - !memcmp((ptr)->req_packet->data, inpkt->data, inpkt->length) && \ +#define MATCH(ptr) (((ptr)->req_packet->length == inpkt->length) && \ + !memcmp((ptr)->req_packet->data, inpkt->data, \ + inpkt->length) && \ + ((ptr)->addr->length == from->address->length) && \ + !memcmp((ptr)->addr->contents, from->address, \ + from->address->length)&& \ ((ptr)->db_age == db_age)) - /* XXX Todo: quench the size of the queue... */ @@ -61,9 +65,10 @@ static int num_entries = 0; FALSE if the caller should do the work */ krb5_boolean -kdc_check_lookaside(inpkt, outpkt) -register krb5_data *inpkt; -register krb5_data **outpkt; +kdc_check_lookaside(inpkt, from, outpkt) + register krb5_data *inpkt; + register krb5_fulladdr *from; + register krb5_data **outpkt; { krb5_int32 timenow; register krb5_kdc_replay_ent *eptr, *last, *hold; @@ -71,7 +76,7 @@ register krb5_data **outpkt; if (krb5_timeofday(kdc_context, &timenow) || krb5_db_get_age(kdc_context, 0, &db_age)) - return FALSE; + return FALSE; calls++; @@ -98,6 +103,7 @@ register krb5_data **outpkt; max_hits_per_entry = max(max_hits_per_entry, eptr->num_hits); krb5_free_data(kdc_context, eptr->req_packet); krb5_free_data(kdc_context, eptr->reply_packet); + krb5_free_address(kdc_context, eptr->addr); hold = eptr; last->next = eptr->next; eptr = last; @@ -115,9 +121,10 @@ register krb5_data **outpkt; already there, and can fail softly due to other weird errors. */ void -kdc_insert_lookaside(inpkt, outpkt) -register krb5_data *inpkt; -register krb5_data *outpkt; +kdc_insert_lookaside(inpkt, from, outpkt) + register krb5_data *inpkt; + register krb5_fulladdr *from; + register krb5_data *outpkt; { register krb5_kdc_replay_ent *eptr; krb5_int32 timenow; @@ -125,7 +132,7 @@ register krb5_data *outpkt; if (krb5_timeofday(kdc_context, &timenow) || krb5_db_get_age(kdc_context, 0, &db_age)) - return; + return; /* this is a new entry */ eptr = (krb5_kdc_replay_ent *)calloc(1, sizeof(*eptr)); @@ -133,6 +140,11 @@ register krb5_data *outpkt; return; eptr->timein = timenow; eptr->db_age = db_age; + /* + * This is going to hurt a lot malloc()-wise due to the need to + * allocate memory for the krb5_data and krb5_address elements. + * ARGH! + */ if (krb5_copy_data(kdc_context, inpkt, &eptr->req_packet)) { krb5_xfree(eptr); return; @@ -142,6 +154,12 @@ register krb5_data *outpkt; krb5_xfree(eptr); return; } + if (krb5_copy_addr(kdc_context, from->address, &eptr->addr)) { + krb5_free_data(kdc_context, eptr->req_packet); + krb5_free_data(kdc_context, eptr->reply_packet); + free(eptr); + return; + } eptr->next = root_ptr.next; root_ptr.next = eptr; num_entries++; |