diff --git a/0018-rpcinfo-ip_ping-clean-up-client-ping-create-destroy.patch b/0018-rpcinfo-ip_ping-clean-up-client-ping-create-destroy.patch new file mode 100644 index 0000000..1629491 --- /dev/null +++ b/0018-rpcinfo-ip_ping-clean-up-client-ping-create-destroy.patch @@ -0,0 +1,122 @@ +From c5033b0f86f3e6a45dcb6cc1d8b5700f1fbba0b8 Mon Sep 17 00:00:00 2001 +From: Olaf Kirch +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 +--- + 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 + diff --git a/0019-rpcinfo-introduce-new-helper-function-ip_getclient.patch b/0019-rpcinfo-introduce-new-helper-function-ip_getclient.patch new file mode 100644 index 0000000..1b3c65a --- /dev/null +++ b/0019-rpcinfo-introduce-new-helper-function-ip_getclient.patch @@ -0,0 +1,110 @@ +From 0a3522bab588d8308769f8696e3e7bc9fe5eb5af Mon Sep 17 00:00:00 2001 +From: Olaf Kirch +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 +--- + 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 + diff --git a/0020-rpcinfo-make-t-u-options-support-IPv6-addresses-too.patch b/0020-rpcinfo-make-t-u-options-support-IPv6-addresses-too.patch new file mode 100644 index 0000000..e388036 --- /dev/null +++ b/0020-rpcinfo-make-t-u-options-support-IPv6-addresses-too.patch @@ -0,0 +1,71 @@ +From 00ad3e8c82610179177d02c5490c941907fcd109 Mon Sep 17 00:00:00 2001 +From: Olaf Kirch +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 +--- + 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 + diff --git a/0021-rpcinfo-remove-obsolete-function-clnt_com_create.patch b/0021-rpcinfo-remove-obsolete-function-clnt_com_create.patch new file mode 100644 index 0000000..622ca3b --- /dev/null +++ b/0021-rpcinfo-remove-obsolete-function-clnt_com_create.patch @@ -0,0 +1,67 @@ +From 59ac2533d7eb9e9f7faed968846d4b11cc2c3123 Mon Sep 17 00:00:00 2001 +From: Olaf Kirch +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 +--- + 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 + diff --git a/0022-Make-rpcinfo-p-support-IPv6-addresses-too.patch b/0022-Make-rpcinfo-p-support-IPv6-addresses-too.patch new file mode 100644 index 0000000..38b4261 --- /dev/null +++ b/0022-Make-rpcinfo-p-support-IPv6-addresses-too.patch @@ -0,0 +1,47 @@ +From b0921131b08c81c33498c6b0b91f8ddf55d73e2f Mon Sep 17 00:00:00 2001 +From: Olaf Kirch +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 " 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 +--- + 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 + diff --git a/0023-rpcinfo-remove-obsolete-function-get_inet_address.patch b/0023-rpcinfo-remove-obsolete-function-get_inet_address.patch new file mode 100644 index 0000000..b1be713 --- /dev/null +++ b/0023-rpcinfo-remove-obsolete-function-get_inet_address.patch @@ -0,0 +1,76 @@ +From f1190d2cb5331282e7b3dda7dcf08d9832d183dd Mon Sep 17 00:00:00 2001 +From: Olaf Kirch +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 +--- + 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 + diff --git a/rpcbind.changes b/rpcbind.changes index 1bc76b2..990c35f 100644 --- a/rpcbind.changes +++ b/rpcbind.changes @@ -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 diff --git a/rpcbind.spec b/rpcbind.spec index f0abb29..340445c 100644 --- a/rpcbind.spec +++ b/rpcbind.spec @@ -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