[rpcbind] Updated to the latest rc release: rpcbind-0_2_3-rc1 (bz 1095021)

Steve Dickson steved at fedoraproject.org
Wed Feb 4 14:20:11 UTC 2015


commit 77df14f7eababeb17af6398eecfaee1ea716f9ee
Author: Steve Dickson <steved at redhat.com>
Date:   Wed Feb 4 09:17:49 2015 -0500

    Updated to the latest rc release: rpcbind-0_2_3-rc1 (bz 1095021)
    
    Signed-off-by: Steve Dickson <steved at redhat.com>

 rpcbind-0.2.2-rc1.patch       |   34 ---
 rpcbind-0.2.2-rc2.patch       |   73 ------
 rpcbind-0.2.2-rc3.patch       |  132 ----------
 rpcbind-0.2.2-warmstart.patch |   31 ---
 rpcbind-0.2.3-rc2.patch       |  532 +++++++++++++++++++++++++++++++++++++++++
 rpcbind.spec                  |    9 +-
 6 files changed, 537 insertions(+), 274 deletions(-)
---
diff --git a/rpcbind-0.2.3-rc2.patch b/rpcbind-0.2.3-rc2.patch
new file mode 100644
index 0000000..868098a
--- /dev/null
+++ b/rpcbind-0.2.3-rc2.patch
@@ -0,0 +1,532 @@
+diff --git a/Makefile.am b/Makefile.am
+index c99566d..ea5725f 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -13,7 +13,7 @@ AM_CPPFLAGS = \
+ 	$(TIRPC_CFLAGS)
+ 
+ if DEBUG
+-AM_CPPFLAGS +=	-DRPCBIND_DEBUG -DSVC_RUN_DEBUG -DDEBUG_RMTCALL
++AM_CPPFLAGS +=	-DRPCBIND_DEBUG -DDEBUG_RMTCALL
+ AM_CPPFLAGS +=	-DND_DEBUG -DBIND_DEBUG
+ endif
+ 
+diff --git a/configure.ac b/configure.ac
+index 75e7e71..27496c7 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -55,4 +55,6 @@ AS_IF([test x$enable_libwrap = xyes], [
+ 
+ AC_SEARCH_LIBS([pthread_create], [pthread])
+ 
++AC_CHECK_HEADERS(nss.h)
++
+ AC_OUTPUT([Makefile])
+diff --git a/src/rpcbind.c b/src/rpcbind.c
+index f7c71ee..35c45f5 100644
+--- a/src/rpcbind.c
++++ b/src/rpcbind.c
+@@ -50,6 +50,7 @@
+ #include <sys/file.h>
+ #include <sys/socket.h>
+ #include <sys/un.h>
++#include <netinet/in.h>
+ #include <rpc/rpc.h>
+ #include <rpc/rpc_com.h>
+ #ifdef PORTMAP
+@@ -268,6 +269,13 @@ main(int argc, char *argv[])
+ 
+ 	network_init();
+ 
++#ifdef SYSTEMD
++	/* Try to notify system of successful startup, regardless of whether we
++	 * used systemd socket activation or not. When started from the command
++	 * line, this should not hurt either.
++	 */
++	sd_notify(0, "READY=1");
++#endif
+ 	my_svc_run();
+ 	syslog(LOG_ERR, "svc_run returned unexpectedly");
+ 	rpcbind_abort();
+@@ -277,6 +285,31 @@ main(int argc, char *argv[])
+ }
+ 
+ /*
++ * Normally systemd will open sockets in dual ipv4/ipv6 mode.
++ * That won't work with netconfig and we'll only match
++ * the ipv6 socket. Convert it to IPV6_V6ONLY and issue
++ * a warning for the user to fix their systemd config.
++ */
++static int
++handle_ipv6_socket(int fd)
++{
++	int opt;
++	socklen_t len = sizeof(opt);
++
++	if (getsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &opt, &len)) {
++		syslog(LOG_ERR, "failed to get ipv6 socket opts: %m");
++		return -1;
++	}
++
++	if (opt) /* socket is already in V6ONLY mode */
++		return 0;
++
++	syslog(LOG_ERR, "systemd has passed an IPv4/IPv6 dual-mode socket.");
++	syslog(LOG_ERR, "Please fix your systemd config by specifying IPv4 and IPv6 sockets separately and using BindIPv6Only=ipv6-only.");
++	return -1;
++}
++
++/*
+  * Adds the entry into the rpcbind database.
+  * If PORTMAP, then for UDP and TCP, it adds the entries for version 2 also
+  * Returns 0 if succeeds, else fails
+@@ -361,6 +394,9 @@ init_transport(struct netconfig *nconf)
+ 			goto error;
+ 		}
+ 
++		if (sa.sa.sa_family == AF_INET6 && handle_ipv6_socket(fd))
++		        goto error;
++
+ 		/* Copy the address */
+ 		taddr.addr.maxlen = taddr.addr.len = addrlen;
+ 		taddr.addr.buf = malloc(addrlen);
+@@ -389,18 +425,6 @@ init_transport(struct netconfig *nconf)
+ 	if (my_xprt != NULL)
+ 		goto got_socket;
+ 
+-	/*
+-	 * XXX - using RPC library internal functions. For NC_TPI_CLTS
+-	 * we call this later, for each socket we like to bind.
+-	 */
+-	if (nconf->nc_semantics != NC_TPI_CLTS) {
+-		if ((fd = __rpc_nconf2fd(nconf)) < 0) {
+-			syslog(LOG_ERR, "cannot create socket for %s",
+-			    nconf->nc_netid);
+-			return (1);
+-		}
+-	}
+-
+ 	if ((strcmp(nconf->nc_netid, "local") == 0) ||
+ 	    (strcmp(nconf->nc_netid, "unix") == 0)) {
+ 		memset(&sun, 0, sizeof sun);
+@@ -451,11 +475,13 @@ init_transport(struct netconfig *nconf)
+ 				    nconf->nc_netid);
+ 				return (1);
+ 			}
++
++			hints.ai_flags &= ~AI_NUMERICHOST;
+ 			switch (hints.ai_family) {
+ 			case AF_INET:
+ 				if (inet_pton(AF_INET, hosts[nhostsbak],
+ 				    host_addr) == 1) {
+-					hints.ai_flags &= AI_NUMERICHOST;
++					hints.ai_flags |= AI_NUMERICHOST;
+ 				} else {
+ 					/*
+ 					 * Skip if we have an AF_INET6 adress.
+@@ -468,7 +494,7 @@ init_transport(struct netconfig *nconf)
+ 			case AF_INET6:
+ 				if (inet_pton(AF_INET6, hosts[nhostsbak],
+ 				    host_addr) == 1) {
+-					hints.ai_flags &= AI_NUMERICHOST;
++					hints.ai_flags |= AI_NUMERICHOST;
+ 				} else {
+ 					/*
+ 					 * Skip if we have an AF_INET adress.
+@@ -561,6 +587,12 @@ init_transport(struct netconfig *nconf)
+ 		if (!checkbind)
+ 			return 1;
+ 	} else {	/* NC_TPI_COTS */
++		if ((fd = __rpc_nconf2fd(nconf)) < 0) {
++			syslog(LOG_ERR, "cannot create socket for %s",
++			    nconf->nc_netid);
++			return (1);
++		}
++
+ 		if ((strcmp(nconf->nc_netid, "local") != 0) &&
+ 		    (strcmp(nconf->nc_netid, "unix") != 0)) {
+ 			if ((aicode = getaddrinfo(NULL, servname, &hints, &res))!= 0) {
+diff --git a/src/rpcinfo.c b/src/rpcinfo.c
+index 747eba3..9b46864 100644
+--- a/src/rpcinfo.c
++++ b/src/rpcinfo.c
+@@ -115,10 +115,8 @@ struct rpcbdump_short
+ 
+ #ifdef PORTMAP
+ static void ip_ping (u_short, char *, int, char **);
+-static CLIENT *clnt_com_create (struct sockaddr_in *, u_long, u_long, int *,
+-				char *);
+ static void pmapdump (int, char **);
+-static void get_inet_address (struct sockaddr_in *, char *);
++static CLIENT *ip_getclient(const char *hostname, rpcprog_t prognum, rpcvers_t versnum, const char *proto);
+ #endif
+ 
+ static bool_t reply_proc (void *, struct netbuf *, struct netconfig *);
+@@ -356,38 +354,17 @@ local_rpcb (rpcprog_t prog, rpcvers_t vers)
+ }
+ 
+ #ifdef PORTMAP
+-static CLIENT *
+-clnt_com_create (addr, prog, vers, fdp, trans)
+-     struct sockaddr_in *addr;
+-     u_long prog;
+-     u_long vers;
+-     int *fdp;
+-     char *trans;
++static enum clnt_stat
++ip_ping_one(client, vers)
++     CLIENT *client;
++     u_int32_t vers;
+ {
+-  CLIENT *clnt;
+-
+-  if (strcmp (trans, "tcp") == 0)
+-    {
+-      clnt = clnttcp_create (addr, prog, vers, fdp, 0, 0);
+-    }
+-  else
+-    {
+-      struct timeval to;
++  struct timeval to = { .tv_sec = 10, .tv_usec = 0 };
+ 
+-      to.tv_sec = 5;
+-      to.tv_usec = 0;
+-      clnt = clntudp_create (addr, prog, vers, to, fdp);
+-    }
+-  if (clnt == (CLIENT *) NULL)
+-    {
+-      clnt_pcreateerror ("rpcinfo");
+-      if (vers == MIN_VERS)
+-	printf ("program %lu is not available\n", prog);
+-      else
+-	printf ("program %lu version %lu is not available\n", prog, vers);
+-      exit (1);
+-    }
+-  return (clnt);
++  (void) CLNT_CONTROL (client, CLSET_VERS, &vers);
++  return CLNT_CALL (client, NULLPROC, (xdrproc_t) xdr_void,
++		    (char *) NULL, (xdrproc_t) xdr_void, (char *) NULL,
++		    to);
+ }
+ 
+ /*
+@@ -398,17 +375,15 @@ clnt_com_create (addr, prog, vers, fdp, trans)
+  * version 0 calls succeeds, it tries for MAXVERS call and repeats the same.
+  */
+ static void
+-ip_ping (portnum, trans, argc, argv)
++ip_ping (portnum, proto, argc, argv)
+      u_short portnum;
+-     char *trans;
++     char *proto;
+      int argc;
+      char **argv;
+ {
+   CLIENT *client;
+-  int fd = RPC_ANYFD;
+-  struct timeval to;
+-  struct sockaddr_in addr;
+   enum clnt_stat rpc_stat;
++  const char *hostname;
+   u_long prognum, vers, minvers, maxvers;
+   struct rpc_err rpcerr;
+   int failure = 0;
+@@ -418,10 +393,9 @@ ip_ping (portnum, trans, argc, argv)
+       usage ();
+       exit (1);
+     }
+-  to.tv_sec = 10;
+-  to.tv_usec = 0;
++
++  hostname = argv[0];
+   prognum = getprognum (argv[1]);
+-  get_inet_address (&addr, argv[0]);
+   if (argc == 2)
+     {				/* Version number not known */
+       /*
+@@ -434,11 +408,10 @@ ip_ping (portnum, trans, argc, argv)
+     {
+       vers = getvers (argv[2]);
+     }
+-  addr.sin_port = htons (portnum);
+-  client = clnt_com_create (&addr, prognum, vers, &fd, trans);
+-  rpc_stat = CLNT_CALL (client, NULLPROC, (xdrproc_t) xdr_void,
+-			(char *) NULL, (xdrproc_t) xdr_void, (char *) NULL,
+-			to);
++
++  client = ip_getclient(hostname, prognum, vers, proto);
++
++  rpc_stat = ip_ping_one(client, vers);
+   if (argc != 2)
+     {
+       /* Version number was known */
+@@ -447,8 +420,8 @@ ip_ping (portnum, trans, argc, argv)
+       (void) CLNT_DESTROY (client);
+       return;
+     }
++
+   /* Version number not known */
+-  (void) CLNT_CONTROL (client, CLSET_FD_NCLOSE, (char *) NULL);
+   if (rpc_stat == RPC_PROGVERSMISMATCH)
+     {
+       clnt_geterr (client, &rpcerr);
+@@ -461,12 +434,7 @@ ip_ping (portnum, trans, argc, argv)
+        * Oh dear, it DOES support version 0.
+        * Let's try version MAX_VERS.
+        */
+-      (void) CLNT_DESTROY (client);
+-      addr.sin_port = htons (portnum);
+-      client = clnt_com_create (&addr, prognum, MAX_VERS, &fd, trans);
+-      rpc_stat = CLNT_CALL (client, NULLPROC, (xdrproc_t) xdr_void,
+-			    (char *) NULL, (xdrproc_t) xdr_void,
+-			    (char *) NULL, to);
++      rpc_stat = ip_ping_one(client, MAX_VERS);
+       if (rpc_stat == RPC_PROGVERSMISMATCH)
+ 	{
+ 	  clnt_geterr (client, &rpcerr);
+@@ -495,21 +463,15 @@ ip_ping (portnum, trans, argc, argv)
+       (void) pstatus (client, prognum, (u_long) 0);
+       exit (1);
+     }
+-  (void) CLNT_DESTROY (client);
+   for (vers = minvers; vers <= maxvers; vers++)
+     {
+-      addr.sin_port = htons (portnum);
+-      client = clnt_com_create (&addr, prognum, vers, &fd, trans);
+-      rpc_stat = CLNT_CALL (client, NULLPROC, (xdrproc_t) xdr_void,
+-			    (char *) NULL, (xdrproc_t) xdr_void,
+-			    (char *) NULL, to);
++      rpc_stat = ip_ping_one(client, vers);
+       if (pstatus (client, prognum, vers) < 0)
+ 	failure = 1;
+-      (void) CLNT_DESTROY (client);
+     }
+   if (failure)
+     exit (1);
+-  (void) close (fd);
++  (void) CLNT_DESTROY (client);
+   return;
+ }
+ 
+@@ -521,9 +483,7 @@ pmapdump (argc, argv)
+      int argc;
+      char **argv;
+ {
+-  struct sockaddr_in server_addr;
+   struct pmaplist *head = NULL;
+-  int socket = RPC_ANYSOCK;
+   struct timeval minutetimeout;
+   register CLIENT *client;
+   struct rpcent *rpc;
+@@ -539,10 +499,13 @@ pmapdump (argc, argv)
+   if (argc == 1)
+     {
+       host = argv[0];
+-      get_inet_address (&server_addr, host);
+-      server_addr.sin_port = htons (PMAPPORT);
+-      client = clnttcp_create (&server_addr, PMAPPROG, PMAPVERS,
+-			       &socket, 50, 500);
++
++      /* This is a little bit more complicated than it should be.
++       * ip_getclient will do an rpcb_getaddr call to identify the
++       * port of the portmapper - but it works, and it's easier than
++       * creating a copy of ip_getclient that avoids the getaddr call.
++       */
++      client = ip_getclient(host, PMAPPROG, PMAPVERS, "tcp");
+     }
+   else
+     client = local_rpcb (PMAPPROG, PMAPVERS);
+@@ -609,48 +572,74 @@ pmapdump (argc, argv)
+     }
+ }
+ 
+-static void
+-get_inet_address (addr, host)
+-     struct sockaddr_in *addr;
+-     char *host;
++/*
++ * Try to obtain the address of a given host/program/version, using the
++ * specified protocol (one of udp or tcp).
++ * This loops over all netconfig entries (according to the order given by
++ * netpath and the config file), and tries to resolve the hostname, and obtain
++ * the address using rpcb_getaddr.
++ */
++CLIENT *
++ip_getclient(hostname, prognum, versnum, proto)
++     const char *hostname;
++     rpcprog_t prognum;
++     rpcvers_t versnum;
++     const char *proto;
+ {
+-  struct netconfig *nconf;
+-  struct addrinfo hints, *res;
+-  int error;
++  void *handle;
++  enum clnt_stat saved_stat = RPC_SUCCESS;
++  struct netconfig *nconf, *result = NULL;
++  struct netbuf bind_address;
++  struct sockaddr_storage __sa;
++  CLIENT *client;
++
++  memset(&bind_address, 0, sizeof(bind_address));
++  bind_address.maxlen = sizeof(__sa);
++  bind_address.buf = &__sa;
+ 
+-  (void) memset ((char *) addr, 0, sizeof (*addr));
+-  addr->sin_addr.s_addr = inet_addr (host);
+-  if (addr->sin_addr.s_addr == -1 || addr->sin_addr.s_addr == 0)
++  handle = setnetconfig();
++  while ((nconf = getnetconfig(handle)) != NULL)
+     {
+-      if ((nconf = __rpc_getconfip ("udp")) == NULL &&
+-	  (nconf = __rpc_getconfip ("tcp")) == NULL)
+-	{
+-	  fprintf (stderr, "rpcinfo: couldn't find a suitable transport\n");
+-	  exit (1);
+-	}
++      if (!strcmp(nconf->nc_proto, proto)) {
++        if (rpcb_getaddr(prognum, versnum, nconf, &bind_address, hostname))
++          {
++	    result = getnetconfigent(nconf->nc_netid);
++	    endnetconfig(handle);
++	    break;
++	  }
++
++        if (rpc_createerr.cf_stat != RPC_UNKNOWNHOST)
++          {
++            clnt_pcreateerror (hostname);
++	    exit (1);
++	  }
++
++	saved_stat = rpc_createerr.cf_stat;
++      }
++    }
++
++  if (result == NULL)
++    {
++      if (saved_stat != RPC_SUCCESS)
++        {
++          rpc_createerr.cf_stat = saved_stat;
++          clnt_pcreateerror (hostname);
++        }
+       else
+-	{
+-	  memset (&hints, 0, sizeof hints);
+-	  hints.ai_family = AF_INET;
+-	  if ((error = getaddrinfo (host, "rpcbind", &hints, &res)) != 0 &&
+-              (error = getaddrinfo (host, "portmapper", &hints, &res)) != 0)
+-	    {
+-	      fprintf (stderr, "rpcinfo: %s: %s\n",
+-		       host, gai_strerror (error));
+-	      exit (1);
+-	    }
+-	  else
+-	    {
+-	      memcpy (addr, res->ai_addr, res->ai_addrlen);
+-	      freeaddrinfo (res);
+-	    }
+-	  (void) freenetconfigent (nconf);
+-	}
++        fprintf (stderr, "Cannot find suitable transport for protocol %s\n", proto);
++
++      exit (1);
+     }
+-  else
++
++  client = clnt_tli_create(RPC_ANYFD, result, &bind_address, prognum, versnum, 0, 0);
++  if (client == NULL)
+     {
+-      addr->sin_family = AF_INET;
++      clnt_pcreateerror(hostname);
++      exit (1);
+     }
++
++  freenetconfigent(result);
++  return client;
+ }
+ #endif /* PORTMAP */
+ 
+diff --git a/src/util.c b/src/util.c
+index 7d56479..a6c835b 100644
+--- a/src/util.c
++++ b/src/util.c
+@@ -71,9 +71,6 @@ static struct sockaddr_in6 *local_in6;
+ #endif
+ 
+ static int bitmaskcmp __P((void *, void *, void *, int));
+-#ifdef INET6
+-static void in6_fillscopeid __P((struct sockaddr_in6 *));
+-#endif
+ 
+ /*
+  * For all bits set in "mask", compare the corresponding bits in
+@@ -93,28 +90,6 @@ bitmaskcmp(void *dst, void *src, void *mask, int bytelen)
+ }
+ 
+ /*
+- * Similar to code in ifconfig.c. Fill in the scope ID for link-local
+- * addresses returned by getifaddrs().
+- */
+-#ifdef INET6
+-static void
+-in6_fillscopeid(struct sockaddr_in6 *sin6)
+-{
+-	u_int16_t ifindex;
+-	u_int16_t *addr;
+-
+-        if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
+-		addr = (u_int16_t *)&sin6->sin6_addr.s6_addr[2];
+-		ifindex = ntohs(*addr);
+-		if (sin6->sin6_scope_id == 0 && ifindex != 0) {
+-			sin6->sin6_scope_id = ifindex;
+-			*addr = 0;
+-		}
+-	}
+-}
+-#endif
+-
+-/*
+  * Find a server address that can be used by `caller' to contact
+  * the local service specified by `serv_uaddr'. If `clnt_uaddr' is
+  * non-NULL, it is used instead of `caller' as a hint suggesting
+@@ -211,7 +186,6 @@ addrmerge(struct netbuf *caller, char *serv_uaddr, char *clnt_uaddr,
+ 			 * a link-local address then use the scope id to see
+ 			 * which one.
+ 			 */
+-			in6_fillscopeid(SA2SIN6(ifsa));
+ 			if (IN6_IS_ADDR_LINKLOCAL(&SA2SIN6ADDR(ifsa)) &&
+ 			    IN6_IS_ADDR_LINKLOCAL(&SA2SIN6ADDR(caller_sa)) &&
+ 			    IN6_IS_ADDR_LINKLOCAL(&SA2SIN6ADDR(hint_sa))) {
+diff --git a/src/warmstart.c b/src/warmstart.c
+index d1bb971..e2f325d 100644
+--- a/src/warmstart.c
++++ b/src/warmstart.c
+@@ -49,7 +49,7 @@
+ #include "rpcbind.h"
+ 
+ #ifndef RPCBIND_STATEDIR
+-#define RPCBIND_STATEDIR "/tmp"
++#define RPCBIND_STATEDIR "/run"
+ #endif
+ 
+ /* These files keep the pmap_list and rpcb_list in XDR format */
+@@ -101,14 +101,15 @@ read_struct(char *filename, xdrproc_t structproc, void *list)
+ {
+ 	FILE *fp;
+ 	XDR xdrs;
+-	 
++
+ 	if (debugging)
+ 		fprintf(stderr, "rpcbind: using '%s' startup file\n", filename);
+ 
+ 	if ((fp = fopen(filename, "r")) == NULL) {
+-		syslog(LOG_ERR,
+-			"Cannot open '%s' file for reading, errno %d (%s)", 
+-			filename, errno, strerror(errno));
++		if (errno != ENOENT)
++			syslog(LOG_ERR,
++				"Cannot open '%s' file for reading, errno %d (%s)",
++				filename, errno, strerror(errno));
+ 		goto error;
+ 	}
+ 
diff --git a/rpcbind.spec b/rpcbind.spec
index d96f0e1..545f065 100644
--- a/rpcbind.spec
+++ b/rpcbind.spec
@@ -1,6 +1,6 @@
 Name:           rpcbind
 Version:        0.2.2
-Release:        1.1%{?dist}
+Release:        2.0%{?dist}
 Summary:        Universal Addresses to RPC Program Number Mapper
 Group:          System Environment/Daemons
 License:        BSD
@@ -12,8 +12,7 @@ Source1: rpcbind.service
 Source2: rpcbind.socket
 Source3: rpcbind.sysconfig
 
-Patch001: rpcbind-0.2.3-rc1.patch
-Patch002: rpcbind-0.2.2-warmstart.patch
+Patch001: rpcbind-0.2.3-rc2.patch
 
 Requires: glibc-common setup
 Conflicts: man-pages < 2.43-12
@@ -36,7 +35,6 @@ RPC calls on a server on that machine.
 %setup -q
 
 %patch001 -p1
-%patch002 -p1
 
 %build
 %ifarch s390 s390x
@@ -128,6 +126,9 @@ fi
 %dir %attr(700,rpc,rpc) /var/lib/rpcbind
 
 %changelog
+* Wed Feb  4 2015 Steve Dickson <steved at redhat.com> - 0.2.2-2.0
+- Updated to the latest rc release: rpcbind-0_2_3-rc1 (bz 1095021)
+
 * Wed Dec 17 2014 Steve Dickson <steved at redhat.com> - 0.2.2-1.1
 - Fixed NULL fp problem remove error message on warmstart patch
 


More information about the scm-commits mailing list