Accepting request 214546 from network

Make rpcinfo -p/-u/-t options support IPv6 (bnc# 859448) (forwarded request 214491 from okir)

OBS-URL: https://build.opensuse.org/request/show/214546
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/rpcbind?expand=0&rev=35
This commit is contained in:
Stephan Kulow 2014-01-22 13:00:28 +00:00 committed by Git OBS Bridge
commit 4fc811d0c1
8 changed files with 518 additions and 0 deletions

View File

@ -0,0 +1,122 @@
From c5033b0f86f3e6a45dcb6cc1d8b5700f1fbba0b8 Mon Sep 17 00:00:00 2001
From: Olaf Kirch <okir@suse.de>
Date: Mon, 20 Jan 2014 11:49:15 +0100
Subject: [PATCH 18/23] rpcinfo ip_ping: clean up client ping/create/destroy
The code doing the actual RPC NULL calls and the handling of
VERSMISMATCH was a bit convoluted. We would destroy and re-create
the client handle, and sometimes the associated file descriptor
would be closed and sometimes not.
Clean this up by introducing a new function ip_ping_one, which
does the actual NULL call to the indicated program version without
destroying the client handle, ever.
Signed-off-by: Olaf Kirch <okir@suse.de>
---
src/rpcinfo.c | 39 ++++++++++++++++++---------------------
1 file changed, 18 insertions(+), 21 deletions(-)
diff --git a/src/rpcinfo.c b/src/rpcinfo.c
index 747eba3..5983b07 100644
--- a/src/rpcinfo.c
+++ b/src/rpcinfo.c
@@ -390,6 +390,19 @@ clnt_com_create (addr, prog, vers, fdp, trans)
return (clnt);
}
+static enum clnt_stat
+ip_ping_one(client, vers)
+ CLIENT *client;
+ u_int32_t vers;
+{
+ struct timeval to = { .tv_sec = 10, .tv_usec = 0 };
+
+ (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);
+}
+
/*
* If portnum is 0, then go and get the address from portmapper, which happens
* transparently through clnt*_create(); If version number is not given, it
@@ -406,7 +419,6 @@ ip_ping (portnum, trans, argc, argv)
{
CLIENT *client;
int fd = RPC_ANYFD;
- struct timeval to;
struct sockaddr_in addr;
enum clnt_stat rpc_stat;
u_long prognum, vers, minvers, maxvers;
@@ -418,8 +430,6 @@ ip_ping (portnum, trans, argc, argv)
usage ();
exit (1);
}
- to.tv_sec = 10;
- to.tv_usec = 0;
prognum = getprognum (argv[1]);
get_inet_address (&addr, argv[0]);
if (argc == 2)
@@ -436,9 +446,7 @@ ip_ping (portnum, trans, argc, argv)
}
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 (argc != 2)
{
/* Version number was known */
@@ -447,8 +455,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 +469,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 +498,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;
}
--
1.7.12.4

View File

@ -0,0 +1,110 @@
From 0a3522bab588d8308769f8696e3e7bc9fe5eb5af Mon Sep 17 00:00:00 2001
From: Olaf Kirch <okir@suse.de>
Date: Mon, 20 Jan 2014 11:43:37 +0100
Subject: [PATCH 19/23] rpcinfo: introduce new helper function ip_getclient
This function tries to obtain the address of a given host/program/version,
using the specified protocol (one of udp or tcp), and create a client
handle for it.
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.
Signed-off-by: Olaf Kirch <okir@suse.de>
---
src/rpcinfo.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 71 insertions(+)
diff --git a/src/rpcinfo.c b/src/rpcinfo.c
index 5983b07..89dee56 100644
--- a/src/rpcinfo.c
+++ b/src/rpcinfo.c
@@ -119,6 +119,7 @@ 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 *);
@@ -649,6 +650,76 @@ get_inet_address (addr, host)
addr->sin_family = AF_INET;
}
}
+
+/*
+ * 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;
+{
+ 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;
+
+ handle = setnetconfig();
+ while ((nconf = getnetconfig(handle)) != NULL)
+ {
+ 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
+ fprintf (stderr, "Cannot find suitable transport for protocol %s\n", proto);
+
+ exit (1);
+ }
+
+ client = clnt_tli_create(RPC_ANYFD, result, &bind_address, prognum, versnum, 0, 0);
+ if (client == NULL)
+ {
+ clnt_pcreateerror(hostname);
+ exit (1);
+ }
+
+ freenetconfigent(result);
+ return client;
+}
#endif /* PORTMAP */
static int
--
1.7.12.4

View File

@ -0,0 +1,71 @@
From 00ad3e8c82610179177d02c5490c941907fcd109 Mon Sep 17 00:00:00 2001
From: Olaf Kirch <okir@suse.de>
Date: Mon, 20 Jan 2014 12:26:40 +0100
Subject: [PATCH 20/23] rpcinfo: make -t/-u options support IPv6 addresses,
too
Currently, rpcinfo supports two ways to test whether a given
service is alive.
For IPv4 hosts, you can use -u and -t. But for IPv6, you need
to use "rpcinfo -a" and specify the host through a universal
address, which is fairly inconvenient.
This patch modifies ip_ping to allow using -u and -t for IPv6
addresses and hosts as well.
Signed-off-by: Olaf Kirch <okir@suse.de>
---
src/rpcinfo.c | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/src/rpcinfo.c b/src/rpcinfo.c
index 89dee56..3fea753 100644
--- a/src/rpcinfo.c
+++ b/src/rpcinfo.c
@@ -412,16 +412,15 @@ ip_ping_one(client, vers)
* 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 sockaddr_in addr;
enum clnt_stat rpc_stat;
+ const char *hostname;
u_long prognum, vers, minvers, maxvers;
struct rpc_err rpcerr;
int failure = 0;
@@ -431,8 +430,9 @@ ip_ping (portnum, trans, argc, argv)
usage ();
exit (1);
}
+
+ hostname = argv[0];
prognum = getprognum (argv[1]);
- get_inet_address (&addr, argv[0]);
if (argc == 2)
{ /* Version number not known */
/*
@@ -445,8 +445,9 @@ ip_ping (portnum, trans, argc, argv)
{
vers = getvers (argv[2]);
}
- addr.sin_port = htons (portnum);
- client = clnt_com_create (&addr, prognum, vers, &fd, trans);
+
+ client = ip_getclient(hostname, prognum, vers, proto);
+
rpc_stat = ip_ping_one(client, vers);
if (argc != 2)
{
--
1.7.12.4

View File

@ -0,0 +1,67 @@
From 59ac2533d7eb9e9f7faed968846d4b11cc2c3123 Mon Sep 17 00:00:00 2001
From: Olaf Kirch <okir@suse.de>
Date: Mon, 20 Jan 2014 12:51:29 +0100
Subject: [PATCH 21/23] rpcinfo: remove obsolete function clnt_com_create
Signed-off-by: Olaf Kirch <okir@suse.de>
---
src/rpcinfo.c | 36 ------------------------------------
1 file changed, 36 deletions(-)
diff --git a/src/rpcinfo.c b/src/rpcinfo.c
index 3fea753..0da5628 100644
--- a/src/rpcinfo.c
+++ b/src/rpcinfo.c
@@ -115,8 +115,6 @@ 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);
@@ -357,40 +355,6 @@ 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;
-{
- CLIENT *clnt;
-
- if (strcmp (trans, "tcp") == 0)
- {
- clnt = clnttcp_create (addr, prog, vers, fdp, 0, 0);
- }
- else
- {
- struct timeval to;
-
- 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);
-}
-
static enum clnt_stat
ip_ping_one(client, vers)
CLIENT *client;
--
1.7.12.4

View File

@ -0,0 +1,47 @@
From b0921131b08c81c33498c6b0b91f8ddf55d73e2f Mon Sep 17 00:00:00 2001
From: Olaf Kirch <okir@suse.de>
Date: Mon, 20 Jan 2014 13:08:18 +0100
Subject: [PATCH 22/23] Make rpcinfo -p support IPv6 addresses, too
While this is not strictly necessary (you can use "rpcinfo <hostname>" instead),
some older scripts may rely on rpcinfo to work with just about any hostname.
Let's be gentle with them. It doesn't cost us much.
Signed-off-by: Olaf Kirch <okir@suse.de>
---
src/rpcinfo.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/src/rpcinfo.c b/src/rpcinfo.c
index 0da5628..2981240 100644
--- a/src/rpcinfo.c
+++ b/src/rpcinfo.c
@@ -484,7 +484,6 @@ pmapdump (argc, argv)
int argc;
char **argv;
{
- struct sockaddr_in server_addr;
struct pmaplist *head = NULL;
int socket = RPC_ANYSOCK;
struct timeval minutetimeout;
@@ -502,10 +501,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);
--
1.7.12.4

View File

@ -0,0 +1,76 @@
From f1190d2cb5331282e7b3dda7dcf08d9832d183dd Mon Sep 17 00:00:00 2001
From: Olaf Kirch <okir@suse.de>
Date: Mon, 20 Jan 2014 13:09:46 +0100
Subject: [PATCH 23/23] rpcinfo: remove obsolete function get_inet_address
Signed-off-by: Olaf Kirch <okir@suse.de>
---
src/rpcinfo.c | 45 ---------------------------------------------
1 file changed, 45 deletions(-)
diff --git a/src/rpcinfo.c b/src/rpcinfo.c
index 2981240..2c7d897 100644
--- a/src/rpcinfo.c
+++ b/src/rpcinfo.c
@@ -116,7 +116,6 @@ struct rpcbdump_short
#ifdef PORTMAP
static void ip_ping (u_short, char *, 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
@@ -574,50 +573,6 @@ pmapdump (argc, argv)
}
}
-static void
-get_inet_address (addr, host)
- struct sockaddr_in *addr;
- char *host;
-{
- struct netconfig *nconf;
- struct addrinfo hints, *res;
- int error;
-
- (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)
- {
- if ((nconf = __rpc_getconfip ("udp")) == NULL &&
- (nconf = __rpc_getconfip ("tcp")) == NULL)
- {
- fprintf (stderr, "rpcinfo: couldn't find a suitable transport\n");
- exit (1);
- }
- 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);
- }
- }
- else
- {
- addr->sin_family = AF_INET;
- }
-}
-
/*
* Try to obtain the address of a given host/program/version, using the
* specified protocol (one of udp or tcp).
--
1.7.12.4

View File

@ -1,3 +1,15 @@
-------------------------------------------------------------------
Mon Jan 20 12:26:55 UTC 2014 - okir@suse.com
- Make rpcinfo -p/-u/-t options support IPv6 (bnc# 859448)
Added:
0018-rpcinfo-ip_ping-clean-up-client-ping-create-destroy.patch
0019-rpcinfo-introduce-new-helper-function-ip_getclient.patch
0020-rpcinfo-make-t-u-options-support-IPv6-addresses-too.patch
0021-rpcinfo-remove-obsolete-function-clnt_com_create.patch
0022-Make-rpcinfo-p-support-IPv6-addresses-too.patch
0023-rpcinfo-remove-obsolete-function-get_inet_address.patch
-------------------------------------------------------------------
Tue Jan 14 16:18:49 UTC 2014 - okir@suse.com

View File

@ -49,6 +49,13 @@ Patch12: 0013-When-using-systemd-activation-make-rpcbind-notify-sy.patch
Patch13: 0014-Notify-systemd-unconditionally.patch
Patch14: 0015-Pull-the-sysconfig-file-into-rpcbind.service-and-use.patch
Patch15: 0016-configure-check-for-nss.h.patch
Patch16: 0018-rpcinfo-ip_ping-clean-up-client-ping-create-destroy.patch
Patch17: 0019-rpcinfo-introduce-new-helper-function-ip_getclient.patch
Patch18: 0020-rpcinfo-make-t-u-options-support-IPv6-addresses-too.patch
Patch19: 0021-rpcinfo-remove-obsolete-function-clnt_com_create.patch
Patch20: 0022-Make-rpcinfo-p-support-IPv6-addresses-too.patch
Patch21: 0023-rpcinfo-remove-obsolete-function-get_inet_address.patch
%define statefile /var/lib/portmap.state
BuildRequires: pkgconfig(systemd)
%{?systemd_requires}
@ -87,6 +94,12 @@ cp %{SOURCE4} .
%patch13 -p1
%patch14 -p1
%patch15 -p1
%patch16 -p1
%patch17 -p1
%patch18 -p1
%patch19 -p1
%patch20 -p1
%patch21 -p1
%build
autoreconf -fiv