From 5c6e6747356f5d473c2c62e818bc24432ddef3e2 Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Tue, 27 Dec 2016 16:44:15 +0100 Subject: sunrpc: Always obtain AF_INET addresses from NSS [BZ #20964] The new __libc_rpc_gethostbyname function calls gethostbyname2_r with an AF_INET argument and is therefore not affected by the RES_USE_INET6 flag. Validated with the following test program, with and without RES_OPTIONS=inet6, against a NFS server. (Link with -lrpcsvc.) #include #include #include #include static void usage (char **argv) { printf ("usage:\n" " %1$s HOST getrpcport\n" " %1$s HOST callrpc\n" " %1$s HOST clnt_create\n", argv[0]); } static void dump_exports (struct exportnode *exports) { while (exports != NULL) { printf ("%s\n", exports->ex_dir); exports = exports->ex_next; } } int main (int argc, char **argv) { if (argc != 3) { usage (argv); return 1; } const char *host = argv[1]; const char *command = argv[2]; if (strcmp (command, "getrpcport") == 0) { int port = getrpcport (host, MOUNTPROG, MOUNTVERS, IPPROTO_UDP); printf ("getrpcport: %d\n", port); } else if (strcmp (command, "callrpc") == 0) { struct exportnode *exports = NULL; int ret = callrpc (host, MOUNTPROG, MOUNTVERS, MOUNTPROC_EXPORT, (xdrproc_t) xdr_void, NULL, (xdrproc_t) xdr_exports, (char *)&exports); if (ret != 0) { clnt_perrno (ret); puts (""); return 1; } dump_exports (exports); } else if (strcmp (command, "clnt_create") == 0) { CLIENT *client = clnt_create (host, MOUNTPROG, MOUNTVERS, "udp"); if (client == NULL) { printf ("error: clnt_create failed\n"); return 1; } struct exportnode *exports = NULL; int ret = CLNT_CALL (client, MOUNTPROC_EXPORT, (xdrproc_t) xdr_void, NULL, (xdrproc_t) xdr_exports, (char *)&exports, ((struct timeval) {15, 0})); if (ret != 0) { clnt_perrno (ret); puts (""); return 1; } dump_exports (exports); } else { usage (argv); return 1; } return 0; } --- sunrpc/clnt_gen.c | 37 ++----------------------------------- 1 file changed, 2 insertions(+), 35 deletions(-) (limited to 'sunrpc/clnt_gen.c') diff --git a/sunrpc/clnt_gen.c b/sunrpc/clnt_gen.c index df34672..8dffaa9 100644 --- a/sunrpc/clnt_gen.c +++ b/sunrpc/clnt_gen.c @@ -45,9 +45,6 @@ CLIENT * clnt_create (const char *hostname, u_long prog, u_long vers, const char *proto) { - struct hostent hostbuf, *h; - size_t hstbuflen; - char *hsttmpbuf; struct protoent protobuf, *p; size_t prtbuflen; char *prttmpbuf; @@ -56,7 +53,6 @@ clnt_create (const char *hostname, u_long prog, u_long vers, int sock; struct timeval tv; CLIENT *client; - int herr; if (strcmp (proto, "unix") == 0) { @@ -78,37 +74,8 @@ clnt_create (const char *hostname, u_long prog, u_long vers, return client; } - hstbuflen = 1024; - hsttmpbuf = __alloca (hstbuflen); - while (__gethostbyname_r (hostname, &hostbuf, hsttmpbuf, hstbuflen, - &h, &herr) != 0 - || h == NULL) - if (herr != NETDB_INTERNAL || errno != ERANGE) - { - get_rpc_createerr().cf_stat = RPC_UNKNOWNHOST; - return NULL; - } - else - { - /* Enlarge the buffer. */ - hstbuflen *= 2; - hsttmpbuf = __alloca (hstbuflen); - } - - if (h->h_addrtype != AF_INET) - { - /* - * Only support INET for now - */ - struct rpc_createerr *ce = &get_rpc_createerr (); - ce->cf_stat = RPC_SYSTEMERROR; - ce->cf_error.re_errno = EAFNOSUPPORT; - return NULL; - } - sin.sin_family = h->h_addrtype; - sin.sin_port = 0; - __bzero (sin.sin_zero, sizeof (sin.sin_zero)); - memcpy ((char *) &sin.sin_addr, h->h_addr, h->h_length); + if (__libc_rpc_gethostbyname (hostname, &sin) != 0) + return NULL; prtbuflen = 1024; prttmpbuf = __alloca (prtbuflen); -- cgit v1.1