diff options
Diffstat (limited to 'src/kdc/network.c')
-rw-r--r-- | src/kdc/network.c | 72 |
1 files changed, 61 insertions, 11 deletions
diff --git a/src/kdc/network.c b/src/kdc/network.c index 6150499649..98f074cce7 100644 --- a/src/kdc/network.c +++ b/src/kdc/network.c @@ -527,26 +527,28 @@ setup_tcp_listener_ports(struct socksetup *data) /* Sockets are created, prepare to listen on them. */ if (s4 >= 0) { - FD_SET(s4, &sstate.rfds); - if (s4 >= sstate.max) - sstate.max = s4 + 1; if (add_tcp_listener_fd(data, s4) == 0) close(s4); - else + else { + FD_SET(s4, &sstate.rfds); + if (s4 >= sstate.max) + sstate.max = s4 + 1; krb5_klog_syslog(LOG_INFO, "listening on fd %d: tcp %s", s4, paddr((struct sockaddr *)&sin4)); + } } #ifdef KRB5_USE_INET6 if (s6 >= 0) { - FD_SET(s6, &sstate.rfds); - if (s6 >= sstate.max) - sstate.max = s6 + 1; if (add_tcp_listener_fd(data, s6) == 0) { close(s6); s6 = -1; - } else + } else { + FD_SET(s6, &sstate.rfds); + if (s6 >= sstate.max) + sstate.max = s6 + 1; krb5_klog_syslog(LOG_INFO, "listening on fd %d: tcp %s", s6, paddr((struct sockaddr *)&sin6)); + } if (s4 < 0) krb5_klog_syslog(LOG_INFO, "assuming IPv6 socket accepts IPv4"); @@ -665,9 +667,6 @@ setup_udp_port_1(struct socksetup *data, struct sockaddr *addr, return 1; } } - FD_SET (sock, &sstate.rfds); - if (sock >= sstate.max) - sstate.max = sock + 1; krb5_klog_syslog (LOG_INFO, "listening on fd %d: udp %s%s", sock, paddr((struct sockaddr *)addr), pktinfo ? " (pktinfo)" : ""); @@ -675,6 +674,9 @@ setup_udp_port_1(struct socksetup *data, struct sockaddr *addr, close(sock); return 1; } + FD_SET (sock, &sstate.rfds); + if (sock >= sstate.max) + sstate.max = sock + 1; } return 0; } @@ -1154,6 +1156,38 @@ send_to_from(int s, void *buf, size_t len, int flags, #endif } +static krb5_error_code +make_too_big_error (krb5_data **out) +{ + krb5_error errpkt; + krb5_error_code retval; + krb5_data *scratch; + + memset(&errpkt, 0, sizeof(errpkt)); + + retval = krb5_us_timeofday(kdc_context, &errpkt.stime, &errpkt.susec); + if (retval) + return retval; + errpkt.error = KRB_ERR_RESPONSE_TOO_BIG; + errpkt.server = tgs_server; + errpkt.client = NULL; + errpkt.text.length = 0; + errpkt.text.data = 0; + errpkt.e_data.length = 0; + errpkt.e_data.data = 0; + scratch = malloc(sizeof(*scratch)); + if (scratch == NULL) + return ENOMEM; + retval = krb5_mk_error(kdc_context, &errpkt, scratch); + if (retval) { + free(scratch); + return retval; + } + + *out = scratch; + return 0; +} + static void process_packet(struct connection *conn, const char *prog, int selflags) { @@ -1208,6 +1242,16 @@ static void process_packet(struct connection *conn, const char *prog, } if (response == NULL) return; + if (response->length > max_dgram_reply_size) { + krb5_free_data(kdc_context, response); + retval = make_too_big_error(&response); + if (retval) { + krb5_klog_syslog(LOG_ERR, + "error constructing KRB_ERR_RESPONSE_TOO_BIG error: %s", + error_message(retval)); + return; + } + } cc = send_to_from(port_fd, response->data, (socklen_t) response->length, 0, (struct sockaddr *)&saddr, saddr_len, (struct sockaddr *)&daddr, daddr_len); @@ -1554,7 +1598,13 @@ listen_and_process(const char *prog) while (!signal_requests_exit) { if (signal_requests_hup) { + int k; + krb5_klog_reopen(kdc_context); + for (k = 0; k < kdc_numrealms; k++) + krb5_db_invoke(kdc_realmlist[k]->realm_context, + KRB5_KDB_METHOD_REFRESH_POLICY, + NULL, NULL); signal_requests_hup = 0; } |