summaryrefslogtreecommitdiffstats
path: root/usr.sbin/rpcbind/util.c
diff options
context:
space:
mode:
authorimp <imp@FreeBSD.org>2010-02-09 18:10:56 +0000
committerimp <imp@FreeBSD.org>2010-02-09 18:10:56 +0000
commit4aa0a8fc65254f7aae5a84358fcad1a6986615b9 (patch)
treea2158aca71bda968265d0c2429d6757db51f0ef1 /usr.sbin/rpcbind/util.c
parentbcd7bda0dad6382566dc0e40b8415a24b3f1f778 (diff)
downloadFreeBSD-src-4aa0a8fc65254f7aae5a84358fcad1a6986615b9.zip
FreeBSD-src-4aa0a8fc65254f7aae5a84358fcad1a6986615b9.tar.gz
When you have multiple addresses on the same network on different
interfaces (such as when you are part of a carp pool), and you run rpcbind -h to restrict which interfaces have rpc services, rpcbind can none-the-less return addresses that aren't in the -h list. This patch enforces the rule that when you specify -h on the command line, then services returned from rpcbind must be to one of the addresses listed in -h, or be a loopback address (since localhost is implicit when running -h). The root cause of this is the assumption in addrmerge that there can be only one interface that matches a given network IP address. This turns out not to be the case. To retain historical behavior, I didn't try to fix the routine to prefer the address that the request came into, since I didn't know the side effects that might cause in the normal case. My quick analysis suggests that it wouldn't be a problem, but since this code is tricky I opted for the more conservative patch of only restricting the reply when -h is in effect. Hence, this change will have no effect when you are running rpcbind without -h. Reviewed by: alfred@ Sponsored by: iX Systems MFC after: 2 weeks
Diffstat (limited to 'usr.sbin/rpcbind/util.c')
-rw-r--r--usr.sbin/rpcbind/util.c20
1 files changed, 10 insertions, 10 deletions
diff --git a/usr.sbin/rpcbind/util.c b/usr.sbin/rpcbind/util.c
index 66797a7..9cdfa70 100644
--- a/usr.sbin/rpcbind/util.c
+++ b/usr.sbin/rpcbind/util.c
@@ -58,13 +58,6 @@
#include "rpcbind.h"
-#define SA2SIN(sa) ((struct sockaddr_in *)(sa))
-#define SA2SINADDR(sa) (SA2SIN(sa)->sin_addr)
-#ifdef INET6
-#define SA2SIN6(sa) ((struct sockaddr_in6 *)(sa))
-#define SA2SIN6ADDR(sa) (SA2SIN6(sa)->sin6_addr)
-#endif
-
static struct sockaddr_in *local_in4;
#ifdef INET6
static struct sockaddr_in6 *local_in6;
@@ -176,9 +169,13 @@ addrmerge(struct netbuf *caller, char *serv_uaddr, char *clnt_uaddr,
goto freeit;
/*
- * Loop through all interfaces. For each interface, see if the
- * network portion of its address is equal to that of the client.
- * If so, we have found the interface that we want to use.
+ * Loop through all interfaces. For each interface, see if it
+ * is either the loopback interface (which we always listen
+ * on) or is one of the addresses the program bound to (the
+ * wildcard by default, or a subset if -h is specified) and
+ * the network portion of its address is equal to that of the
+ * client. If so, we have found the interface that we want to
+ * use.
*/
bestif = NULL;
for (ifap = ifp; ifap != NULL; ifap = ifap->ifa_next) {
@@ -189,6 +186,9 @@ addrmerge(struct netbuf *caller, char *serv_uaddr, char *clnt_uaddr,
!(ifap->ifa_flags & IFF_UP))
continue;
+ if (!(ifap->ifa_flags & IFF_LOOPBACK) && !listen_addr(ifsa))
+ continue;
+
switch (hint_sa->sa_family) {
case AF_INET:
/*
OpenPOWER on IntegriCloud