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"));
|