Blame SOURCES/autofs-5.0.7-fix-portmap-lookup.patch

304803
autofs-5.0.7 - fix portmap lookup
304803
304803
From: Ian Kent <ikent@redhat.com>
304803
304803
The autofs RPC library has fallen behind some.
304803
304803
When using IPv6 (rpbbind) version 3 or 4 is available whereas with IPv4
304803
(portmap) verions 2 and 3 are available.
304803
304803
autofs uses the version defined by PMAPVERS in the portmap include files
304803
whereas it should be using the RPCBVERS defines when using libtirpc.
304803
304803
In addition /etc/rpc should be used for program number lookup and
304803
/etc/services should be used to lookup rpcbind/protmap port number.
304803
304803
This incompatibility only shows up when using IPv6 only.
304803
---
304803
 CHANGELOG           |    1 
304803
 aclocal.m4          |    2 +
304803
 configure           |   80 +++++++++++++++++++++++++++++++++++++++++++++
304803
 include/config.h.in |    6 +++
304803
 lib/rpc_subs.c      |   92 ++++++++++++++++++++++++++++++++++++++++++++++++----
304803
 5 files changed, 175 insertions(+), 6 deletions(-)
304803
304803
--- autofs-5.0.7.orig/CHANGELOG
304803
+++ autofs-5.0.7/CHANGELOG
304803
@@ -62,6 +62,7 @@
304803
 - try and cleanup after dumpmaps.
304803
 - teach dumpmaps to output simple key value pairs.
304803
 - fix get_nfs_info() probe.
304803
+- fix portmap lookup.
304803
 
304803
 25/07/2012 autofs-5.0.7
304803
 =======================
304803
--- autofs-5.0.7.orig/aclocal.m4
304803
+++ autofs-5.0.7/aclocal.m4
304803
@@ -421,6 +421,8 @@ if test "$af_have_libtirpc" = "yes"; the
304803
     TIRPCLIB="-ltirpc"
304803
 fi
304803
 
304803
+AC_CHECK_FUNCS([getrpcbyname getservbyname])
304803
+
304803
 # restore flags
304803
 CFLAGS="$af_check_libtirpc_save_cflags"
304803
 LDFLAGS="$af_check_libtirpc_save_ldflags"
304803
--- autofs-5.0.7.orig/configure
304803
+++ autofs-5.0.7/configure
304803
@@ -1559,6 +1559,73 @@ fi
304803
 
304803
 } # ac_fn_c_try_link
304803
 
304803
+# ac_fn_c_check_func LINENO FUNC VAR
304803
+# ----------------------------------
304803
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
304803
+ac_fn_c_check_func ()
304803
+{
304803
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
304803
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
304803
+$as_echo_n "checking for $2... " >&6; }
304803
+if eval \${$3+:} false; then :
304803
+  $as_echo_n "(cached) " >&6
304803
+else
304803
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
304803
+/* end confdefs.h.  */
304803
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
304803
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
304803
+#define $2 innocuous_$2
304803
+
304803
+/* System header to define __stub macros and hopefully few prototypes,
304803
+    which can conflict with char $2 (); below.
304803
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
304803
+    <limits.h> exists even on freestanding compilers.  */
304803
+
304803
+#ifdef __STDC__
304803
+# include <limits.h>
304803
+#else
304803
+# include <assert.h>
304803
+#endif
304803
+
304803
+#undef $2
304803
+
304803
+/* Override any GCC internal prototype to avoid an error.
304803
+   Use char because int might match the return type of a GCC
304803
+   builtin and then its argument prototype would still apply.  */
304803
+#ifdef __cplusplus
304803
+extern "C"
304803
+#endif
304803
+char $2 ();
304803
+/* The GNU C library defines this for functions which it implements
304803
+    to always fail with ENOSYS.  Some functions are actually named
304803
+    something starting with __ and the normal name is an alias.  */
304803
+#if defined __stub_$2 || defined __stub___$2
304803
+choke me
304803
+#endif
304803
+
304803
+int
304803
+main ()
304803
+{
304803
+return $2 ();
304803
+  ;
304803
+  return 0;
304803
+}
304803
+_ACEOF
304803
+if ac_fn_c_try_link "$LINENO"; then :
304803
+  eval "$3=yes"
304803
+else
304803
+  eval "$3=no"
304803
+fi
304803
+rm -f core conftest.err conftest.$ac_objext \
304803
+    conftest$ac_exeext conftest.$ac_ext
304803
+fi
304803
+eval ac_res=\$$3
304803
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
304803
+$as_echo "$ac_res" >&6; }
304803
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
304803
+
304803
+} # ac_fn_c_check_func
304803
+
304803
 # ac_fn_c_try_cpp LINENO
304803
 # ----------------------
304803
 # Try to preprocess conftest.$ac_ext, and return whether this succeeded.
304803
@@ -3161,6 +3228,19 @@ $as_echo "#define TIRPC_WORKAROUND 1" >>
304803
     TIRPCLIB="-ltirpc"
304803
 fi
304803
 
304803
+for ac_func in getrpcbyname getservbyname
304803
+do :
304803
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
304803
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
304803
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
304803
+  cat >>confdefs.h <<_ACEOF
304803
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
304803
+_ACEOF
304803
+
304803
+fi
304803
+done
304803
+
304803
+
304803
 # restore flags
304803
 CFLAGS="$af_check_libtirpc_save_cflags"
304803
 LDFLAGS="$af_check_libtirpc_save_ldflags"
304803
--- autofs-5.0.7.orig/include/config.h.in
304803
+++ autofs-5.0.7/include/config.h.in
304803
@@ -21,6 +21,12 @@
304803
 /* define if you have E4FSCK */
304803
 #undef HAVE_E4FSCK
304803
 
304803
+/* Define to 1 if you have the `getrpcbyname' function. */
304803
+#undef HAVE_GETRPCBYNAME
304803
+
304803
+/* Define to 1 if you have the `getservbyname' function. */
304803
+#undef HAVE_GETSERVBYNAME
304803
+
304803
 /* Define to 1 if you have the <inttypes.h> header file. */
304803
 #undef HAVE_INTTYPES_H
304803
 
304803
--- autofs-5.0.7.orig/lib/rpc_subs.c
304803
+++ autofs-5.0.7/lib/rpc_subs.c
304803
@@ -43,6 +43,14 @@
304803
                 } while (0)
304803
 #endif
304803
 
304803
+#ifdef WITH_LIBTIRPC
304803
+const rpcprog_t rpcb_prog = RPCBPROG;
304803
+const rpcvers_t rpcb_version = RPCBVERS;
304803
+#else
304803
+const rpcprog_t rpcb_prog = PMAPPROG;
304803
+const rpcvers_t rpcb_version = PMAPVERS;
304803
+#endif
304803
+
304803
 #include "mount.h"
304803
 #include "rpc_subs.h"
304803
 #include "automount.h"
304803
@@ -259,6 +267,9 @@ static int rpc_do_create_client(struct s
304803
 		laddr = (struct sockaddr *) &in4_laddr;
304803
 		in4_raddr->sin_port = htons(info->port);
304803
 		slen = sizeof(struct sockaddr_in);
304803
+		/* Use rpcbind v2 for AF_INET */
304803
+		if (info->program == rpcb_prog)
304803
+			info->version = PMAPVERS;
304803
 	} else if (addr->sa_family == AF_INET6) {
304803
 		struct sockaddr_in6 *in6_raddr = (struct sockaddr_in6 *) addr;
304803
 		in6_laddr.sin6_family = AF_INET6;
304803
@@ -315,6 +326,63 @@ static int rpc_do_create_client(struct s
304803
 }
304803
 #endif
304803
 
304803
+#if defined(HAVE_GETRPCBYNAME) || defined(HAVE_GETSERVBYNAME)
304803
+static pthread_mutex_t rpcb_mutex = PTHREAD_MUTEX_INITIALIZER;
304803
+#endif
304803
+
304803
+static rpcprog_t rpc_getrpcbyname(const rpcprog_t program)
304803
+{
304803
+#ifdef HAVE_GETRPCBYNAME
304803
+	static const char *rpcb_pgmtbl[] = {
304803
+		"rpcbind", "portmap", "portmapper", "sunrpc", NULL,
304803
+	};
304803
+	struct rpcent *entry;
304803
+	rpcprog_t prog_number;
304803
+	unsigned int i;
304803
+
304803
+	pthread_mutex_lock(&rpcb_mutex);
304803
+	for (i = 0; rpcb_pgmtbl[i] != NULL; i++) {
304803
+		entry = getrpcbyname(rpcb_pgmtbl[i]);
304803
+		if (entry) {
304803
+			prog_number = entry->r_number;
304803
+			pthread_mutex_unlock(&rpcb_mutex);
304803
+			return prog_number;
304803
+		}
304803
+	}
304803
+	pthread_mutex_unlock(&rpcb_mutex);
304803
+#endif
304803
+	return program;
304803
+}
304803
+
304803
+static unsigned short rpc_getrpcbport(const int proto)
304803
+{
304803
+#ifdef HAVE_GETSERVBYNAME
304803
+	static const char *rpcb_netnametbl[] = {
304803
+		"rpcbind", "portmapper", "sunrpc", NULL,
304803
+	};
304803
+	struct servent *entry;
304803
+	struct protoent *p_ent;
304803
+	unsigned short port;
304803
+	unsigned int i;
304803
+
304803
+	pthread_mutex_lock(&rpcb_mutex);
304803
+	p_ent = getprotobynumber(proto);
304803
+	if (!p_ent)
304803
+		goto done;
304803
+	for (i = 0; rpcb_netnametbl[i] != NULL; i++) {
304803
+		entry = getservbyname(rpcb_netnametbl[i], p_ent->p_name);
304803
+		if (entry) {
304803
+			port = entry->s_port;
304803
+			pthread_mutex_unlock(&rpcb_mutex);
304803
+			return port;
304803
+		}
304803
+	}
304803
+done:
304803
+	pthread_mutex_unlock(&rpcb_mutex);
304803
+#endif
304803
+	return (unsigned short) PMAPPORT;
304803
+}
304803
+
304803
 /*
304803
  * Create an RPC client
304803
  */
304803
@@ -510,9 +578,15 @@ int rpc_portmap_getclient(struct conn_in
304803
 	info->host = host;
304803
 	info->addr = addr;
304803
 	info->addr_len = addr_len;
304803
-	info->program = PMAPPROG;
304803
-	info->port = PMAPPORT;
304803
-	info->version = PMAPVERS;
304803
+	info->program = rpc_getrpcbyname(rpcb_prog);
304803
+	info->port = ntohs(rpc_getrpcbport(proto));
304803
+	/*
304803
+	 * When using libtirpc we might need to change the rpcbind version
304803
+	 * to qurey AF_INET addresses. Since we might not have an address
304803
+	 * yet set AF_INET rpcbind version in rpc_do_create_client() when
304803
+	 * we always have an address.
304803
+	 */
304803
+	info->version = rpcb_version;
304803
 	info->proto = proto;
304803
 	info->send_sz = RPCSMALLMSGSIZE;
304803
 	info->recv_sz = RPCSMALLMSGSIZE;
304803
@@ -555,9 +629,15 @@ int rpc_portmap_getport(struct conn_info
304803
 		pmap_info.host = info->host;
304803
 		pmap_info.addr = info->addr;
304803
 		pmap_info.addr_len = info->addr_len;
304803
-		pmap_info.port = PMAPPORT;
304803
-		pmap_info.program = PMAPPROG;
304803
-		pmap_info.version = PMAPVERS;
304803
+		pmap_info.port = ntohs(rpc_getrpcbport(info->proto));
304803
+		pmap_info.program = rpc_getrpcbyname(rpcb_prog);
304803
+		/*
304803
+		 * When using libtirpc we might need to change the rpcbind
304803
+		 * version to qurey AF_INET addresses. Since we might not
304803
+		 * have an address yet set AF_INET rpcbind version in
304803
+		 * rpc_do_create_client() when we always have an address.
304803
+		 */
304803
+		pmap_info.version = rpcb_version;
304803
 		pmap_info.proto = info->proto;
304803
 		pmap_info.send_sz = RPCSMALLMSGSIZE;
304803
 		pmap_info.recv_sz = RPCSMALLMSGSIZE;