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