d17f0b5f35
datagram requests. Adds an internal symbol to libkrb5 which the KDC will need if listening on loopback is enabled. The default might be better changed from FALSE to TRUE so that the default matches what we do with stream sockets. Or maybe that should be the default anyway, with no configuration option. FIXME: doesn't add documentation anywhere.
248 lines
8.5 KiB
Diff
248 lines
8.5 KiB
Diff
Provide an option to make the KDC also listen on loopback interfaces for
|
|
datagram requests. Adds an internal symbol to libkrb5 which the KDC
|
|
needs if listening on loopback is enabled.
|
|
|
|
The default might be better changed from FALSE to TRUE so that the
|
|
default matches what we do with stream sockets.
|
|
|
|
FIXME: doesn't add documentation anywhere.
|
|
|
|
diff -up src/include/foreachaddr.h src/include/foreachaddr.h
|
|
--- src/include/foreachaddr.h 2004-05-05 18:44:46.000000000 -0400
|
|
+++ src/include/foreachaddr.h 2008-04-04 15:39:28.000000000 -0400
|
|
@@ -62,3 +62,18 @@ krb5int_foreach_localaddr (/*@null@*/ vo
|
|
;
|
|
|
|
#define foreach_localaddr krb5int_foreach_localaddr
|
|
+
|
|
+extern int
|
|
+krb5int_foreach_localaddr_ext (/*@null@*/ void *data,
|
|
+ int (*pass1fn) (/*@null@*/ void *,
|
|
+ struct sockaddr *) /*@*/,
|
|
+ /*@null@*/ krb5_boolean (*skipfn) (/*@null@*/ struct sockaddr *, int) /*@*/,
|
|
+ /*@null@*/ int (*betweenfn) (/*@null@*/ void *) /*@*/,
|
|
+ /*@null@*/ int (*pass2fn) (/*@null@*/ void *,
|
|
+ struct sockaddr *) /*@*/)
|
|
+#if defined(DEBUG) || defined(TEST)
|
|
+ /*@modifies fileSystem@*/
|
|
+#endif
|
|
+ ;
|
|
+
|
|
+#define foreach_localaddr_ext krb5int_foreach_localaddr_ext
|
|
diff -up src/kdc/kdc_util.h src/kdc/kdc_util.h
|
|
--- src/kdc/kdc_util.h 2008-04-04 16:28:18.000000000 -0400
|
|
+++ src/kdc/kdc_util.h 2008-04-04 16:51:27.000000000 -0400
|
|
@@ -126,6 +126,7 @@ krb5_error_code kdc_initialize_rcache (k
|
|
krb5_error_code setup_server_realm (krb5_principal);
|
|
|
|
/* network.c */
|
|
+void process_listen_loopback (krb5_boolean);
|
|
krb5_error_code listen_and_process (const char *);
|
|
krb5_error_code setup_network (const char *);
|
|
krb5_error_code closedown_network (const char *);
|
|
diff -up src/kdc/main.c src/kdc/main.c
|
|
--- src/kdc/main.c 2008-04-04 16:22:43.000000000 -0400
|
|
+++ src/kdc/main.c 2008-04-04 16:55:22.000000000 -0400
|
|
@@ -422,6 +422,7 @@ initialize_realms(krb5_context kcontext,
|
|
krb5_enctype menctype = ENCTYPE_UNKNOWN;
|
|
kdc_realm_t *rdatap;
|
|
krb5_boolean manual = FALSE;
|
|
+ krb5_boolean listen_loopback = FALSE;
|
|
char *default_udp_ports = 0;
|
|
char *default_tcp_ports = 0;
|
|
krb5_pointer aprof;
|
|
@@ -448,6 +449,9 @@ initialize_realms(krb5_context kcontext,
|
|
if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &v4mode))
|
|
v4mode = 0;
|
|
#endif
|
|
+ hierarchy[1] = "kdc_listen_loopback";
|
|
+ if (krb5_aprof_get_boolean(aprof, hierarchy, TRUE, &listen_loopback))
|
|
+ listen_loopback = FALSE;
|
|
/* aprof_init can return 0 with aprof == NULL */
|
|
if (aprof)
|
|
krb5_aprof_finish(aprof);
|
|
@@ -587,6 +591,8 @@ initialize_realms(krb5_context kcontext,
|
|
free(v4mode);
|
|
#endif
|
|
|
|
+ process_listen_loopback(listen_loopback);
|
|
+
|
|
/*
|
|
* Check to see if we processed any realms.
|
|
*/
|
|
diff -up src/kdc/network.c src/kdc/network.c
|
|
--- src/kdc/network.c 2008-04-04 15:39:28.000000000 -0400
|
|
+++ src/kdc/network.c 2008-04-04 16:51:44.000000000 -0400
|
|
@@ -221,6 +221,7 @@ static SET(u_short) udp_port_data, tcp_p
|
|
#include "cm.h"
|
|
|
|
static struct select_state sstate;
|
|
+static krb5_boolean listen_loopback;
|
|
|
|
static krb5_error_code add_udp_port(int port)
|
|
{
|
|
@@ -604,6 +605,12 @@ scan_for_newlines:
|
|
}
|
|
#endif
|
|
|
|
+void
|
|
+process_listen_loopback(krb5_boolean listen_loop)
|
|
+{
|
|
+ listen_loopback = listen_loop;
|
|
+}
|
|
+
|
|
/* XXX */
|
|
extern int krb5int_debug_sendto_kdc;
|
|
extern void (*krb5int_sendtokdc_debug_handler)(const void*, size_t);
|
|
@@ -662,7 +669,9 @@ setup_network(const char *prog)
|
|
so we might need only one UDP socket; fall back to binding
|
|
sockets on each address only if IPV6_PKTINFO isn't
|
|
supported. */
|
|
- if (foreach_localaddr (&setup_data, setup_udp_port, 0, 0)) {
|
|
+ if (listen_loopback ?
|
|
+ foreach_localaddr_ext (&setup_data, setup_udp_port, 0, 0, 0) :
|
|
+ foreach_localaddr (&setup_data, setup_udp_port, 0, 0)) {
|
|
return setup_data.retval;
|
|
}
|
|
setup_tcp_listener_ports(&setup_data);
|
|
diff -up src/lib/krb5/os/localaddr.c src/lib/krb5/os/localaddr.c
|
|
--- src/lib/krb5/os/localaddr.c 2005-04-13 12:55:43.000000000 -0400
|
|
+++ src/lib/krb5/os/localaddr.c 2008-04-04 15:39:28.000000000 -0400
|
|
@@ -242,6 +242,17 @@ addr_eq (const struct sockaddr *s1, cons
|
|
}
|
|
#endif
|
|
|
|
+static krb5_boolean
|
|
+skip_loopback (struct sockaddr *addr, int flags)
|
|
+{
|
|
+#ifdef IFF_LOOPBACK
|
|
+ if (flags & IFF_LOOPBACK) {
|
|
+ return TRUE;
|
|
+ }
|
|
+#endif
|
|
+ return FALSE;
|
|
+}
|
|
+
|
|
#ifndef HAVE_IFADDRS_H
|
|
/*@-usereleased@*/ /* lclint doesn't understand realloc */
|
|
static /*@null@*/ void *
|
|
@@ -413,14 +424,27 @@ get_linux_ipv6_addrs ()
|
|
indication, it should do it via some field pointed to by the DATA
|
|
argument. */
|
|
|
|
-#ifdef HAVE_IFADDRS_H
|
|
-
|
|
int
|
|
foreach_localaddr (/*@null@*/ void *data,
|
|
int (*pass1fn) (/*@null@*/ void *, struct sockaddr *) /*@*/,
|
|
/*@null@*/ int (*betweenfn) (/*@null@*/ void *) /*@*/,
|
|
/*@null@*/ int (*pass2fn) (/*@null@*/ void *,
|
|
struct sockaddr *) /*@*/)
|
|
+{
|
|
+ return foreach_localaddr_ext(data, pass1fn,
|
|
+ &skip_loopback, betweenfn,
|
|
+ pass2fn);
|
|
+}
|
|
+
|
|
+#ifdef HAVE_IFADDRS_H
|
|
+
|
|
+int
|
|
+foreach_localaddr_ext (/*@null@*/ void *data,
|
|
+ int (*pass1fn) (/*@null@*/ void *, struct sockaddr *) /*@*/,
|
|
+ /*@null@*/ krb5_boolean (*skipfn) (/*@null@*/ struct sockaddr *, int) /*@*/,
|
|
+ /*@null@*/ int (*betweenfn) (/*@null@*/ void *) /*@*/,
|
|
+ /*@null@*/ int (*pass2fn) (/*@null@*/ void *,
|
|
+ struct sockaddr *) /*@*/)
|
|
#if defined(DEBUG) || defined(TEST)
|
|
/*@modifies fileSystem@*/
|
|
#endif
|
|
@@ -436,7 +460,7 @@ foreach_localaddr (/*@null@*/ void *data
|
|
#endif
|
|
if ((ifp->ifa_flags & IFF_UP) == 0)
|
|
continue;
|
|
- if (ifp->ifa_flags & IFF_LOOPBACK) {
|
|
+ if (skipfn && (*skipfn)(ifp->ifa_addr, ifp->ifa_flags)) {
|
|
/* Pretend it's not up, so the second pass will skip
|
|
it. */
|
|
ifp->ifa_flags &= ~IFF_UP;
|
|
@@ -459,7 +483,7 @@ foreach_localaddr (/*@null@*/ void *data
|
|
for (ifp2 = ifp_head; ifp2 && ifp2 != ifp; ifp2 = ifp2->ifa_next) {
|
|
if ((ifp2->ifa_flags & IFF_UP) == 0)
|
|
continue;
|
|
- if (ifp2->ifa_flags & IFF_LOOPBACK)
|
|
+ if (skipfn && (*skipfn)(ifp2->ifa_addr, ifp2->ifa_flags))
|
|
continue;
|
|
if (addr_eq (ifp->ifa_addr, ifp2->ifa_addr)) {
|
|
match = 1;
|
|
@@ -488,11 +512,12 @@ foreach_localaddr (/*@null@*/ void *data
|
|
#elif defined (SIOCGLIFNUM) && defined(HAVE_STRUCT_LIFCONF) /* Solaris 8 and later; Sol 7? */
|
|
|
|
int
|
|
-foreach_localaddr (/*@null@*/ void *data,
|
|
- int (*pass1fn) (/*@null@*/ void *, struct sockaddr *) /*@*/,
|
|
- /*@null@*/ int (*betweenfn) (/*@null@*/ void *) /*@*/,
|
|
- /*@null@*/ int (*pass2fn) (/*@null@*/ void *,
|
|
- struct sockaddr *) /*@*/)
|
|
+foreach_localaddr_ext (/*@null@*/ void *data,
|
|
+ int (*pass1fn) (/*@null@*/ void *, struct sockaddr *) /*@*/,
|
|
+ /*@null@*/ int (*skipfn) (/*@null@*/ struct sockaddr *, int) /*@*/,
|
|
+ /*@null@*/ int (*betweenfn) (/*@null@*/ void *) /*@*/,
|
|
+ /*@null@*/ int (*pass2fn) (/*@null@*/ void *,
|
|
+ struct sockaddr *) /*@*/)
|
|
#if defined(DEBUG) || defined(TEST)
|
|
/*@modifies fileSystem@*/
|
|
#endif
|
|
@@ -583,13 +608,12 @@ foreach_localaddr (/*@null@*/ void *data
|
|
}
|
|
/*@=moduncon@*/
|
|
|
|
-#ifdef IFF_LOOPBACK
|
|
- /* None of the current callers want loopback addresses. */
|
|
- if (lifreq.lifr_flags & IFF_LOOPBACK) {
|
|
- Tprintf ((" loopback\n"));
|
|
+ if (skipfn && (*skipfn)(lifreq.lifr_addr, lifreq.lifr_flags))
|
|
+ if (skipfn && (skipfn == &skip_loopback))
|
|
+ Tprintf ((" loopback\n"));
|
|
goto skip;
|
|
}
|
|
-#endif
|
|
+
|
|
/* Ignore interfaces that are down. */
|
|
if ((lifreq.lifr_flags & IFF_UP) == 0) {
|
|
Tprintf ((" down\n"));
|
|
@@ -755,13 +779,12 @@ foreach_localaddr (/*@null@*/ void *data
|
|
}
|
|
/*@=moduncon@*/
|
|
|
|
-#ifdef IFF_LOOPBACK
|
|
/* None of the current callers want loopback addresses. */
|
|
- if (lifreq.iflr_flags & IFF_LOOPBACK) {
|
|
- Tprintf ((" loopback\n"));
|
|
+ if (skipfn && (*skipfn)(ifp2->ifa_addr, lifreq.lifr_flags))
|
|
+ if (skipfn && (skipfn == &skip_loopback))
|
|
+ Tprintf ((" loopback\n"));
|
|
goto skip;
|
|
}
|
|
-#endif
|
|
/* Ignore interfaces that are down. */
|
|
if ((lifreq.iflr_flags & IFF_UP) == 0) {
|
|
Tprintf ((" down\n"));
|
|
@@ -971,13 +994,12 @@ foreach_localaddr (/*@null@*/ void *data
|
|
}
|
|
/*@=moduncon@*/
|
|
|
|
-#ifdef IFF_LOOPBACK
|
|
- /* None of the current callers want loopback addresses. */
|
|
- if (ifreq.ifr_flags & IFF_LOOPBACK) {
|
|
- Tprintf ((" loopback\n"));
|
|
+ if (skipfn && (*skipfn)(NULL, ifreq.ifr_flags))
|
|
+ if (skipfn && (skipfn == &skip_loopback))
|
|
+ Tprintf ((" loopback\n"));
|
|
goto skip;
|
|
}
|
|
-#endif
|
|
+
|
|
/* Ignore interfaces that are down. */
|
|
if ((ifreq.ifr_flags & IFF_UP) == 0) {
|
|
Tprintf ((" down\n"));
|