* scripts/amd.conf-sample, scripts/amd.conf.5, doc/am-utils.texi,
authorErez Zadok <ezk@cs.sunysb.edu>
Fri, 21 Apr 2006 01:11:50 +0000 (01:11 +0000)
committerErez Zadok <ezk@cs.sunysb.edu>
Fri, 21 Apr 2006 01:11:50 +0000 (01:11 +0000)
NEWS: document new nfs_allow_any_interface parameter.

* include/am_compat.h (INADDR_LOOPBACK): define INADDR_LOOPBACK if
not defined, since some systems don't have it.

* libamu/wire.c (is_interface_local): new boolena function to
determine if address represents any of the local interfaces.
(getwire): more properly check if address equals INADDR_LOOPBACK,
not if IFF_LOOPBACK is not (the latter isn't as correct).

* include/am_utils.h: extern for new is_interface_local() function.

* conf/transp/transp_{sockets,tli}.c: don't define INADDR_LOOPBACK
here but in am_compat.h

* amd/nfs_prot_svc.c (nfs_program_2): if
nfs_allow_any_interface=yes, then allow NFS packets from any local
interface (not just 127.0.0.1).

* amd/conf.c (gopt_nfs_allow_any_interface): implement the new
amd.conf parameter nfs_allow_any_interface.

* amd/amd.h (CFM_NFS_ANY_INTERFACE): define new global flag when
al interfaces are acceptable for local NFS packets.

13 files changed:
ChangeLog
NEWS
amd/amd.h
amd/conf.c
amd/nfs_prot_svc.c
conf/transp/transp_sockets.c
conf/transp/transp_tli.c
doc/am-utils.texi
include/am_compat.h
include/am_utils.h
libamu/wire.c
scripts/amd.conf-sample
scripts/amd.conf.5

index 1e991f13e2ac583c77ad7c0d8d95390c6a179432..699561cec47c112ec4c77074ee7d621ce09d6fea 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,33 @@
+2006-04-20  Erez Zadok  <ezk@cs.sunysb.edu>
+
+       * scripts/amd.conf-sample, scripts/amd.conf.5, doc/am-utils.texi,
+       NEWS: document new nfs_allow_any_interface parameter.
+
+       * include/am_compat.h (INADDR_LOOPBACK): define INADDR_LOOPBACK if
+       not defined, since some systems don't have it.
+
+2006-04-20  Nick Williams <Nick.Williams@morganstanley.com>
+
+       * libamu/wire.c (is_interface_local): new boolena function to
+       determine if address represents any of the local interfaces.
+       (getwire): more properly check if address equals INADDR_LOOPBACK,
+       not if IFF_LOOPBACK is not (the latter isn't as correct).
+
+       * include/am_utils.h: extern for new is_interface_local() function.
+
+       * conf/transp/transp_{sockets,tli}.c: don't define INADDR_LOOPBACK
+       here but in am_compat.h
+
+       * amd/nfs_prot_svc.c (nfs_program_2): if
+       nfs_allow_any_interface=yes, then allow NFS packets from any local
+       interface (not just 127.0.0.1).
+
+       * amd/conf.c (gopt_nfs_allow_any_interface): implement the new
+       amd.conf parameter nfs_allow_any_interface.
+
+       * amd/amd.h (CFM_NFS_ANY_INTERFACE): define new global flag when
+       al interfaces are acceptable for local NFS packets.
+
 2006-04-18  Christos Zoulas  <christos@zoulas.com>
 
        * amd/opts.c: Add support for optionally specifying the hostname
diff --git a/NEWS b/NEWS
index eed764ffc2d121271313a78751c2af648fdb7af1..5e79dda19fcb30be8aca199d0400e5d581da7be2 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,12 @@
 *** Notes specific to am-utils version 6.2a2
 
+New amd.conf global parameter: nfs_allow_any_interface.  By default it is
+set to 'no' which means that Amd accepts local NFS packets only from
+127.0.0.1.  If set to 'yes' then Amd will accept local NFS packets from any
+local interface; this is useful on hosts that may have multiple interfaces
+where the system is forced to send all outgoing packets (even those bound to
+the same host) via an address other than 127.0.0.1.
+
 Add support for specifying the host to match in the mount selectors netgrp
 and netgrpd.  Now one can use either netgrp(<group-name>) or
 netgrp(<group-name>,<host-name>).
index 1f090cdabb3932234b2c5054291907a50e023373..127e37e542974c6244451fa4960a415745417ae5 100644 (file)
--- a/amd/amd.h
+++ b/amd/amd.h
@@ -80,6 +80,7 @@
 #define CFM_FORCED_UNMOUNTS            0x00010000 /* forced unmounts? */
 #define CFM_TRUNCATE_LOG               0x00020000 /* truncate log file? */
 #define CFM_SUN_MAP_SYNTAX             0x00040000 /* Sun map syntax? */
+#define CFM_NFS_ANY_INTERFACE          0x00080000 /* all interfaces are acceptable */
 
 /* defaults global flags: plock, tcpwrappers, and autofs/lofs */
 #define CFM_DEFAULT_FLAGS      (CFM_PROCESS_LOCK|CFM_USE_TCPWRAPPERS|CFM_AUTOFS_USE_LOFS|CFM_DOMAIN_STRIP|CFM_NORMALIZE_SLASHES)
index 7b002a68f458f13bd5ef602e656d12c45b7ed045..b5e3536b0eb8766a91598cff25b00c207c8ac3d6 100644 (file)
@@ -108,6 +108,7 @@ static int gopt_mount_type(const char *val);
 static int gopt_pid_file(const char *val);
 static int gopt_portmap_program(const char *val);
 static int gopt_preferred_amq_port(const char *val);
+static int gopt_nfs_allow_any_interface(const char *val);
 static int gopt_nfs_allow_insecure_port(const char *val);
 static int gopt_nfs_proto(const char *val);
 static int gopt_nfs_retransmit_counter(const char *val);
@@ -191,6 +192,7 @@ static struct _func_map glob_functable[] = {
   {"pid_file",                 gopt_pid_file},
   {"portmap_program",          gopt_portmap_program},
   {"preferred_amq_port",       gopt_preferred_amq_port},
+  {"nfs_allow_any_interface",  gopt_nfs_allow_any_interface},
   {"nfs_allow_insecure_port",  gopt_nfs_allow_insecure_port},
   {"nfs_proto",                        gopt_nfs_proto},
   {"nfs_retransmit_counter",   gopt_nfs_retransmit_counter},
@@ -830,6 +832,22 @@ gopt_preferred_amq_port(const char *val)
 }
 
 
+static int
+gopt_nfs_allow_any_interface(const char *val)
+{
+  if (STREQ(val, "yes")) {
+    gopt.flags |= CFM_NFS_ANY_INTERFACE;
+    return 0;
+  } else if (STREQ(val, "no")) {
+    gopt.flags &= ~CFM_NFS_ANY_INTERFACE;
+    return 0;
+  }
+
+  fprintf(stderr, "conf: unknown value to nfs_allow_insecure_port \"%s\"\n", val);
+  return 1;                    /* unknown value */
+}
+
+
 static int
 gopt_nfs_allow_insecure_port(const char *val)
 {
index 105aac5981a2218de78792f8f02f857fc618159e..0dd6992cf9e7d6ce79c78fc9cc7bb7fee4ca4bf5 100644 (file)
@@ -133,12 +133,20 @@ nfs_program_2(struct svc_req *rqstp, SVCXPRT *transp)
   }
 # endif /* MNT2_NFS_OPT_RESVPORT */
   /* if the address does not match, ignore the request */
-  if (sinp && sinp->sin_addr.s_addr != myipaddr.s_addr) {
-    plog(XLOG_WARNING, "ignoring request from %s:%u, expected %s",
-        inet_dquad(dq, sizeof(dq), sinp->sin_addr.s_addr),
-        ntohs(sinp->sin_port),
-        inet_dquad(dq2, sizeof(dq2), myipaddr.s_addr));
-    return;
+  if (sinp && (sinp->sin_addr.s_addr != myipaddr.s_addr)) {
+    if (gopt.flags & CFM_NFS_ANY_INTERFACE) {
+      if (!is_interface_local(sinp->sin_addr.s_addr)) {
+       plog(XLOG_WARNING, "ignoring request from %s:%u, not a local interface",
+            inet_dquad(dq, sizeof(dq), sinp->sin_addr.s_addr),
+            ntohs(sinp->sin_port));
+      }
+    } else {
+      plog(XLOG_WARNING, "ignoring request from %s:%u, expected %s",
+          inet_dquad(dq, sizeof(dq), sinp->sin_addr.s_addr),
+          ntohs(sinp->sin_port),
+          inet_dquad(dq2, sizeof(dq2), myipaddr.s_addr));
+      return;
+    }
   }
 #endif /* not HAVE_TRANPORT_TYPE_TLI */
 
index 53e16482b513286e6f747dbe9c0e92cf813766f8..36ef2e363f82653d3403789b94e48e65e0ab9595 100644 (file)
 #include <amu.h>
 
 
-/* provide a definition for systems that don't have this */
-#ifndef INADDR_LOOPBACK
-# define INADDR_LOOPBACK       0x7f000001
-#endif /* not INADDR_LOOPBACK */
-
-
 /*
  * find the IP address that can be used to connect to the local host
  */
index 09d829ff00b4f5dce6dfae504ce48f4e1ed2dd11..0cf5f2bd31512c472646da02204531bf81de5fa5 100644 (file)
 
 struct netconfig *nfsncp;
 
-/* provide a definition for systems that don't have this */
-#ifndef INADDR_LOOPBACK
-# define INADDR_LOOPBACK       0x7f000001
-#endif /* not INADDR_LOOPBACK */
 
 /*
  * find the IP address that can be used to connect to the local host
index 398df95d5fd5449b97072721471483561169769d..e72fd8881b52e222d06d63bb8ca5a359db01d6bc 100644 (file)
@@ -4397,6 +4397,7 @@ The following parameters are applicable to the @samp{[global]} section only.
 * log_file Parameter::
 * log_options Parameter::
 * map_reload_interval Parameter::
+* nfs_allow_any_interface Parameter::
 * nfs_allow_insecure_port Parameter::
 * nfs_proto Parameter::
 * nfs_retransmit_counter Parameter::
@@ -4823,7 +4824,7 @@ warnings
 @end table
 
 @c ----------------------------------------------------------------
-@node map_reload_interval Parameter, nfs_allow_insecure_port Parameter, log_options Parameter, Global Parameters
+@node map_reload_interval Parameter, nfs_allow_any_interface Parameter, log_options Parameter, Global Parameters
 @comment  node-name,  next,  previous,  up
 @subsection @t{map_reload_interval} Parameter
 @cindex map_reload_interval Parameter
@@ -4834,21 +4835,34 @@ wait before it checks to see if any maps have changed at their source
 those maps that have changed.
 
 @c ----------------------------------------------------------------
-@node nfs_allow_insecure_port Parameter, nfs_proto Parameter, map_reload_interval Parameter, Global Parameters
+@node nfs_allow_any_interface Parameter, nfs_allow_insecure_port Parameter, map_reload_interval Parameter, Global Parameters
+@comment  node-name,  next,  previous,  up
+@subsection @t{nfs_allow_any_interface} Parameter
+@cindex nfs_allow_any_interface Parameter
+
+(type=string, default=@samp{no}).  Normally @i{Amd} accepts local NFS
+packets only from 127.0.0.1.  If this parameter is set to @samp{yes},
+then @i{amd} will accept local NFS packets from any local interface;
+this is useful on hosts that may have multiple interfaces where the
+system is forced to send all outgoing packets (even those bound to the
+same host) via an address other than 127.0.0.1.
+
+@c ----------------------------------------------------------------
+@node nfs_allow_insecure_port Parameter, nfs_proto Parameter, nfs_allow_any_interface Parameter, Global Parameters
 @comment  node-name,  next,  previous,  up
 @subsection @t{nfs_allow_insecure_port} Parameter
 @cindex nfs_allow_insecure_port Parameter
 
-(type=string, default=@samp{no}).  Normally amd will refuse requests
-coming from unprivileged ports (i.e. ports >= 1024 on Unix systems),
+(type=string, default=@samp{no}).  Normally @i{Amd} will refuse requests
+coming from unprivileged ports (i.e., ports >= 1024 on Unix systems),
 so that only privileged users and the kernel can send NFS requests to
-it. However, some kernels (certain versions of Darwin, MacOS X, and
+it.  However, some kernels (certain versions of Darwin, MacOS X, and
 Linux) have bugs that cause them to use unprivileged ports in certain
-situations, which causes amd to stop dead in its tracks. This
-parameter allows amd to operate normally even on such systems, at the
-expense of a slight decrease in the security of its operations. If you
-see messages like ``ignoring request from foo:1234, port not
-reserved'' in your amd log, try enabling this parameter and give it
+situations, which causes @i{Amd} to stop dead in its tracks.  This
+parameter allows @i{Amd} to operate normally even on such systems, at the
+expense of a slight decrease in the security of its operations.  If
+you see messages like ``ignoring request from foo:1234, port not
+reserved'' in your @i{Amd} log, try enabling this parameter and give it
 another go.
 
 @c ----------------------------------------------------------------
index 99401d1f973b36e27071acce18239532ab0f6f7b..dc3b71d744681d55f4c94a1230c2e8010e63f1cf 100644 (file)
@@ -385,5 +385,9 @@ struct netconfig {
 #ifndef INADDR_NONE
 # define INADDR_NONE   0xffffffffU
 #endif /* INADDR_NONE */
+/* some OSs don't define INADDR_LOOPBACK */
+#ifndef INADDR_LOOPBACK
+# define INADDR_LOOPBACK       0x7f000001
+#endif /* not INADDR_LOOPBACK */
 
 #endif /* not _AM_COMPAT_H */
index 355c55c2ca92f2fa1b67e747ebce1ac073f3a064..3caadd5f9f8791e902a1a689f0cca6a3a0751da3 100644 (file)
@@ -298,6 +298,7 @@ extern char *hasmntstr(mntent_t *, char *);
 extern char *hasmnteq(mntent_t *, char *);
 extern char *haseq(char *);
 extern int is_network_member(const char *net);
+extern int is_interface_local(u_long);
 extern int islocalnet(u_long);
 extern int make_rpc_packet(char *, int, u_long, struct rpc_msg *, voidp, XDRPROC_T_TYPE, AUTH *);
 extern int mkdirs(char *, int);
index b76004346be9a0e77ce5833662f5dfce99a7c315..c1852cdca7f11fefd8dd4ead732b02c4fe244e0d 100644 (file)
@@ -357,6 +357,24 @@ is_network_member(const char *net)
 }
 
 
+/*
+ * Determine whether a IP address (netnum) is one of the local interfaces,
+ * returns TRUE/FALSE.
+ * Does not include the loopback interface: caller needs to check that.
+ */
+int
+is_interface_local(u_long netnum)
+{
+  addrlist *al;
+
+  for (al = localnets; al; al = al->ip_next) {
+    if (al->ip_addr == netnum)
+      return TRUE;
+  }
+  return FALSE;
+}
+
+
 #ifdef HAVE_GETIFADDRS
 void
 getwire(char **name1, char **number1)
@@ -384,10 +402,10 @@ getwire(char **name1, char **number1)
       continue;
 
     /*
-     * If the interface is a loopback, or its not running
+     * If the interface is the loopback, or it's not running,
      * then ignore it.
      */
-    if ((ifap->ifa_flags & IFF_LOOPBACK) != 0)
+    if (S2IN(ifap->ifa_addr) == htonl(INADDR_LOOPBACK))
       continue;
     if ((ifap->ifa_flags & IFF_RUNNING) == 0)
       continue;
@@ -501,13 +519,11 @@ getwire(char **name1, char **number1)
       continue;
 
     /*
-     * If the interface is a loopback, or its not running
+     * If the interface is the loopback, or it's not running,
      * then ignore it.
      */
-#ifdef IFF_LOOPBACK
-    if ((ifr->ifr_flags & IFF_LOOPBACK) != 0)
+    if (address == htonl(INADDR_LOOPBACK))
       continue;
-#endif /* IFF_LOOPBACK */
     /*
      * Fix for 0.0.0.0 loopback on SunOS 3.X which defines IFF_ROUTE
      * instead of IFF_LOOPBACK.
index 76ff7c2fc0fa85ddb014977cd1184d08d0f55d43..4d965787099a25b85c8561299d863a42d65d255f 100644 (file)
@@ -97,7 +97,9 @@ nfs_proto =                   udp | tcp
 # perform Amq service checks via tcpwrappers (tcpd/libwrap)
 use_tcpwrappers =              yes | no
 # allow NFS requests from insecure (>=1024) ports
-nfs_allow_insecure_port =      yes | no
+nfs_allow_insecure_port =      no | yes
+# accept local NFS packets from any local interface, not just 127.0.0.1
+nfs_allow_any_interface =      no | yes
 # address used for local NFS mount and RPC server (default to localhost)
 localhost_address =            foo.example.com | 192.168.1.2
 # number of seconds to timeout before map returns output
index 76c38c7de00c96bba568538ff1ea3ef85cac45d6..2009d3bea12b05dead856790a49cc9470d6ab3c6 100644 (file)
@@ -443,17 +443,25 @@ The number of seconds that Amd will wait before it checks to see if any maps
 have changed at their source (NIS servers, LDAP servers, files, etc.).  Amd
 will reload only those maps that have changed.
 
+.TP
+.BR nfs_allow_any_interface " (string, default=no)"
+Normally Amd accepts local NFS packets only from 127.0.0.1.  If this
+parameter is set to "yes" then Amd will accept local NFS packets from any
+local interface; this is useful on hosts that may have multiple interfaces
+where the system is forced to send all outgoing packets (even those bound to
+the same host) via an address other than 127.0.0.1.
+
 .TP
 .BR nfs_allow_insecure_port " (string, default=no)"
 Normally Amd will refuse requests coming from unprivileged ports (i.e.
 ports >= 1024 on Unix systems), so that only privileged users and the kernel
-can send NFS requests to it. However, some kernels (certain versions of
+can send NFS requests to it.  However, some kernels (certain versions of
 Darwin, MacOS X, and Linux) have bugs that cause them to use unprivileged
-ports in certain situations, which causes Amd to stop dead in its
-tracks. This parameter allows Amd to operate normally even on such systems,
-at the expense of a slight decrease in the security of its operations. If
-you see messages like "ignoring request from foo:1234, port not reserved"
-in your Amd log, try enabling this parameter and give it another go.
+ports in certain situations, which causes Amd to stop dead in its tracks.
+This parameter allows Amd to operate normally even on such systems, at the
+expense of a slight decrease in the security of its operations.  If you see
+messages like "ignoring request from foo:1234, port not reserved" in your
+Amd log, try enabling this parameter and give it another go.
 
 .TP
 .BR nfs_proto " (string, default to trying version tcp then udp)"