From faf10b955b029f8a5c569570bcdbcc56bdf0ce6f Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Mon, 23 May 2005 17:14:22 +0000 Subject: * sunrpc/pm_getport.c (__get_socket): New function. (pmap_getport): Use it to open a non-reserved socket to the portmapper for TCP. * include/rpc/pmap_clnt.h (__get_socket): Declare. * sunrpc/pm_getmaps.c (pmap_getmaps): Use __get_socket to get an non-reserved socket for the portmapper. range to even lower ports. --- sunrpc/pm_getmaps.c | 15 +++++++++++++-- sunrpc/pm_getport.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 62 insertions(+), 5 deletions(-) (limited to 'sunrpc') diff --git a/sunrpc/pm_getmaps.c b/sunrpc/pm_getmaps.c index d1d4ca8..6e304a3 100644 --- a/sunrpc/pm_getmaps.c +++ b/sunrpc/pm_getmaps.c @@ -44,9 +44,12 @@ static char sccsid[] = "@(#)pmap_getmaps.c 1.10 87/08/11 Copyr 1984 Sun Micro"; #include #include #include +#include #include #include #include +#include + /* * Get a copy of the current port maps. @@ -56,13 +59,19 @@ struct pmaplist * pmap_getmaps (struct sockaddr_in *address) { struct pmaplist *head = (struct pmaplist *) NULL; - int socket = -1; struct timeval minutetimeout; CLIENT *client; + bool closeit = false; minutetimeout.tv_sec = 60; minutetimeout.tv_usec = 0; address->sin_port = htons (PMAPPORT); + + /* Don't need a reserver port to get ports from the portmapper */ + int socket = __get_socket (address); + if (socket != -1) + closeit = true; + client = INTUSE(clnttcp_create) (address, PMAPPROG, PMAPVERS, &socket, 50, 500); if (client != (CLIENT *) NULL) @@ -75,7 +84,9 @@ pmap_getmaps (struct sockaddr_in *address) } CLNT_DESTROY (client); } - /* (void)close(socket); CLNT_DESTROY already closed it */ + /* We only need to close the socket here if we opened it. */ + if (closeit) + (void) __close (socket); address->sin_port = 0; return head; } diff --git a/sunrpc/pm_getport.c b/sunrpc/pm_getport.c index 00e1ba9..2d30984 100644 --- a/sunrpc/pm_getport.c +++ b/sunrpc/pm_getport.c @@ -38,6 +38,8 @@ static char sccsid[] = "@(#)pmap_getport.c 1.9 87/08/11 Copyr 1984 Sun Micro"; * Copyright (C) 1984, Sun Microsystems, Inc. */ +#include +#include #include #include #include @@ -49,6 +51,41 @@ static const struct timeval tottimeout = {60, 0}; /* + * Create a socket that is locally bound to a non-reserve port. For + * any failures, -1 is returned which will cause the RPC code to + * create the socket. + */ +int +internal_function +__get_socket (struct sockaddr_in *saddr) +{ + int so = __socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (so < 0) + return -1; + + struct sockaddr_in laddr; + socklen_t namelen = sizeof (laddr); + laddr.sin_family = AF_INET; + laddr.sin_port = 0; + laddr.sin_addr.s_addr = htonl (INADDR_ANY); + + int cc = __bind (so, (struct sockaddr *) &laddr, namelen); + if (__builtin_expect (cc < 0, 0)) + { + fail: + __close (so); + return -1; + } + + cc = __connect (so, (struct sockaddr *) saddr, namelen); + if (__builtin_expect (cc < 0, 0)) + goto fail; + + return so; +} + + +/* * Find the mapped port for program,version. * Calls the pmap service remotely to do the lookup. * Returns 0 if no map exists. @@ -64,11 +101,18 @@ pmap_getport (address, program, version, protocol) int socket = -1; CLIENT *client; struct pmap parms; + bool closeit = false; address->sin_port = htons (PMAPPORT); if (protocol == IPPROTO_TCP) - client = INTUSE(clnttcp_create) (address, PMAPPROG, PMAPVERS, &socket, - RPCSMALLMSGSIZE, RPCSMALLMSGSIZE); + { + /* Don't need a reserved port to get ports from the portmapper. */ + socket = __get_socket(address); + if (socket != -1) + closeit = true; + client = INTUSE(clnttcp_create) (address, PMAPPROG, PMAPVERS, &socket, + RPCSMALLMSGSIZE, RPCSMALLMSGSIZE); + } else client = INTUSE(clntudp_bufcreate) (address, PMAPPROG, PMAPVERS, timeout, &socket, RPCSMALLMSGSIZE, @@ -93,7 +137,9 @@ pmap_getport (address, program, version, protocol) } CLNT_DESTROY (client); } - /* (void)close(socket); CLNT_DESTROY already closed it */ + /* We only need to close the socket here if we opened it. */ + if (closeit) + (void) __close (socket); address->sin_port = 0; return port; } -- cgit v1.1