summaryrefslogtreecommitdiffstats
path: root/src/kdc/network.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/kdc/network.c')
-rw-r--r--src/kdc/network.c72
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;
}