[PATCH] rpcbind: Only listen on requested hostnames for NC_TPI_COTS connections

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



There is a check for NC_TPI_CLTS connections which correctly binds only
to the hostnames/addresses given on the commandline (-h option). This
implementation does not take non NC_TPI_CLTS like NC_TPI_COTS and
NC_TPI_COTS_ORD into account. This causes non NC_TPI_CLTS protocols to
listen on the "0.0.0.0" and "::" wildcard addresses.

This patch simplifies the code, and moves the check for NC_TPI_CLTS into
the loop when a bind() for each requested address is done. All
connections, including NC_TPI_COTS and NC_TPI_COTS_ORD can now benefit
from resticted bind()'ing on addresses.

Signed-off-by: Niels de Vos <ndevos@xxxxxxxxxx>
---
 src/rpcbind.c |  230 ++++++++++++++++++++------------------------------------
 1 files changed, 82 insertions(+), 148 deletions(-)

diff --git a/src/rpcbind.c b/src/rpcbind.c
index 9a0504d..3f6c2a9 100644
--- a/src/rpcbind.c
+++ b/src/rpcbind.c
@@ -339,172 +339,103 @@ init_transport(struct netconfig *nconf)
 		hints.ai_socktype = si.si_socktype;
 		hints.ai_protocol = si.si_proto;
 	}
-	if (nconf->nc_semantics == NC_TPI_CLTS) {
+
+	/*
+	 * If no hosts were specified, just bind to INADDR_ANY.  Otherwise
+	 * make sure 127.0.0.1 is added to the list.
+	 */
+	nhostsbak = nhosts;
+	nhostsbak++;
+	hosts = realloc(hosts, nhostsbak * sizeof(char *));
+	if (nhostsbak == 1)
+		hosts[0] = "*";
+	else {
+		if (hints.ai_family == AF_INET) {
+			hosts[nhostsbak - 1] = "127.0.0.1";
+		} else if (hints.ai_family == AF_INET6) {
+			hosts[nhostsbak - 1] = "::1";
+		} else
+			return 1;
+	}
+
+       /*
+	* Bind to specific IPs if asked to
+	*/
+	checkbind = 0;
+	while (nhostsbak > 0) {
+		--nhostsbak;
 		/*
-		 * If no hosts were specified, just bind to INADDR_ANY.  Otherwise
-		 * make sure 127.0.0.1 is added to the list.
+		 * XXX - using RPC library internal functions.
 		 */
-		nhostsbak = nhosts;
-		nhostsbak++;
-		hosts = realloc(hosts, nhostsbak * sizeof(char *));
-		if (nhostsbak == 1)
-			hosts[0] = "*";
-		else {
-			if (hints.ai_family == AF_INET) {
-				hosts[nhostsbak - 1] = "127.0.0.1";
-			} else if (hints.ai_family == AF_INET6) {
-				hosts[nhostsbak - 1] = "::1";
-			} else
-				return 1;
+		if ((fd = __rpc_nconf2fd(nconf)) < 0) {
+			syslog(LOG_ERR, "cannot create socket for %s",
+			    nconf->nc_netid);
+			return (1);
 		}
-
-	       /*
-		* Bind to specific IPs if asked to
-		*/
-		checkbind = 0;
-		while (nhostsbak > 0) {
-			--nhostsbak;
-			/*
-			 * XXX - using RPC library internal functions.
-			 */
-			if ((fd = __rpc_nconf2fd(nconf)) < 0) {
-				syslog(LOG_ERR, "cannot create socket for %s",
-				    nconf->nc_netid);
-				return (1);
+		switch (hints.ai_family) {
+		case AF_INET:
+			if (inet_pton(AF_INET, hosts[nhostsbak],
+			    host_addr) == 1) {
+				hints.ai_flags &= AI_NUMERICHOST;
+			} else {
+				/*
+				 * Skip if we have an AF_INET6 adress.
+				 */
+				if (inet_pton(AF_INET6,
+				    hosts[nhostsbak], host_addr) == 1)
+					continue;
 			}
-			switch (hints.ai_family) {
-			case AF_INET:
+			break;
+		case AF_INET6:
+			if (inet_pton(AF_INET6, hosts[nhostsbak],
+			    host_addr) == 1) {
+				hints.ai_flags &= AI_NUMERICHOST;
+			} else {
+				/*
+				 * Skip if we have an AF_INET adress.
+				 */
 				if (inet_pton(AF_INET, hosts[nhostsbak],
-				    host_addr) == 1) {
-					hints.ai_flags &= AI_NUMERICHOST;
-				} else {
-					/*
-					 * Skip if we have an AF_INET6 adress.
-					 */
-					if (inet_pton(AF_INET6,
-					    hosts[nhostsbak], host_addr) == 1)
-						continue;
-				}
-				break;
-			case AF_INET6:
-				if (inet_pton(AF_INET6, hosts[nhostsbak],
-				    host_addr) == 1) {
-					hints.ai_flags &= AI_NUMERICHOST;
-				} else {
-					/*
-					 * Skip if we have an AF_INET adress.
-					 */
-					if (inet_pton(AF_INET, hosts[nhostsbak],
-					    host_addr) == 1)
-						continue;
-				}
-	        		break;
-			default:
-				break;
+				    host_addr) == 1)
+					continue;
 			}
+			break;
+		default:
+			break;
+		}
 
-			/*
-			 * If no hosts were specified, just bind to INADDR_ANY
-			 */
-			if (strcmp("*", hosts[nhostsbak]) == 0)
-				hosts[nhostsbak] = NULL;
+		/*
+		 * If no hosts were specified, just bind to INADDR_ANY
+		 */
+		if (strcmp("*", hosts[nhostsbak]) == 0)
+			hosts[nhostsbak] = NULL;
 
+		if ((strcmp(nconf->nc_netid, "local") != 0) &&
+		    (strcmp(nconf->nc_netid, "unix") != 0)) {
 			if ((aicode = getaddrinfo(hosts[nhostsbak],
-			    servname, &hints, &res)) != 0) {
+			    servname, &hints, &res))!= 0) {
 			  if ((aicode = getaddrinfo(hosts[nhostsbak],
-						    "portmapper", &hints, &res)) != 0) {
-				syslog(LOG_ERR,
+					    "portmapper", &hints, &res))!= 0) {
+			    syslog(LOG_ERR,
 				    "cannot get local address for %s: %s",
 				    nconf->nc_netid, gai_strerror(aicode));
-				continue;
+			    continue;
 			  }
 			}
 			addrlen = res->ai_addrlen;
 			sa = (struct sockaddr *)res->ai_addr;
-			oldmask = umask(S_IXUSR|S_IXGRP|S_IXOTH);
-                        if (bind(fd, sa, addrlen) != 0) {
-				syslog(LOG_ERR, "cannot bind %s on %s: %m",
-					(hosts[nhostsbak] == NULL) ? "*" :
-					hosts[nhostsbak], nconf->nc_netid);
-				if (res != NULL)
-					freeaddrinfo(res);
-				continue;
-			} else
-				checkbind++;
-			(void) umask(oldmask);
-
-			/* Copy the address */
-			taddr.addr.maxlen = taddr.addr.len = addrlen;
-			taddr.addr.buf = malloc(addrlen);
-			if (taddr.addr.buf == NULL) {
-				syslog(LOG_ERR,
-				    "cannot allocate memory for %s address",
-				    nconf->nc_netid);
+		}
+		oldmask = umask(S_IXUSR|S_IXGRP|S_IXOTH);
+		if (nconf->nc_semantics != NC_TPI_CLTS) {
+			/* NC_TPI_COTS and NC_TPI_COTS_ORD etc */
+			__rpc_fd2sockinfo(fd, &si);
+			if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on,
+			    sizeof(on)) != 0) {
+				syslog(LOG_ERR, "cannot set SO_REUSEADDR on %s",
+					nconf->nc_netid);
 				if (res != NULL)
 					freeaddrinfo(res);
 				return 1;
 			}
-			memcpy(taddr.addr.buf, sa, addrlen);
-#ifdef RPCBIND_DEBUG
-			if (debugging) {
-				/*
-				 * for debugging print out our universal
-				 * address
-				 */
-				char *uaddr;
-				struct netbuf nb;
-				int sa_size = 0;
-
-				nb.buf = sa;
-				switch( sa->sa_family){
-				case AF_INET:
-				  sa_size = sizeof (struct sockaddr_in);
-				  break;
-				case AF_INET6:
-				  sa_size = sizeof (struct sockaddr_in6);				 
-				  break;
-				}
-				nb.len = nb.maxlen = sa_size;
-				uaddr = taddr2uaddr(nconf, &nb);
-				(void) fprintf(stderr,
-				    "rpcbind : my address is %s\n", uaddr);
-				(void) free(uaddr);
-			}
-#endif
-			my_xprt = (SVCXPRT *)svc_tli_create(fd, nconf, &taddr, 
-                                RPC_MAXDATASIZE, RPC_MAXDATASIZE);
-			if (my_xprt == (SVCXPRT *)NULL) {
-				syslog(LOG_ERR, "%s: could not create service", 
-                                        nconf->nc_netid);
-				goto error;
-			}
-		}
-		if (!checkbind)
-			return 1;
-	} else {	/* NC_TPI_COTS */
-		if ((strcmp(nconf->nc_netid, "local") != 0) &&
-		    (strcmp(nconf->nc_netid, "unix") != 0)) {
-			if ((aicode = getaddrinfo(NULL, servname, &hints, &res))!= 0) {
-			  if ((aicode = getaddrinfo(NULL, "portmapper", &hints, &res))!= 0) {
-			  printf("cannot get local address for %s: %s",  nconf->nc_netid, gai_strerror(aicode));
-			  syslog(LOG_ERR,
-				    "cannot get local address for %s: %s",
-				    nconf->nc_netid, gai_strerror(aicode));
-				return 1;
-			  }
-			}
-			addrlen = res->ai_addrlen;
-			sa = (struct sockaddr *)res->ai_addr;
-		}
-		oldmask = umask(S_IXUSR|S_IXGRP|S_IXOTH);
-		__rpc_fd2sockinfo(fd, &si);
-		if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on,
-				sizeof(on)) != 0) {
-			syslog(LOG_ERR, "cannot set SO_REUSEADDR on %s",
-				nconf->nc_netid);
-			if (res != NULL)
-				freeaddrinfo(res);
-			return 1;
 		}
 		if (bind(fd, sa, addrlen) < 0) {
 			syslog(LOG_ERR, "cannot bind %s: %m", nconf->nc_netid);
@@ -530,7 +461,7 @@ init_transport(struct netconfig *nconf)
 			/* for debugging print out our universal address */
 			char *uaddr;
 			struct netbuf nb;
-		        int sa_size2 = 0;
+			int sa_size2 = 0;
 
 			nb.buf = sa;
 			switch( sa->sa_family){
@@ -551,13 +482,16 @@ init_transport(struct netconfig *nconf)
 
 		listen(fd, SOMAXCONN);
 
-		my_xprt = (SVCXPRT *)svc_tli_create(fd, nconf, &taddr, RPC_MAXDATASIZE, RPC_MAXDATASIZE);
+		my_xprt = (SVCXPRT *)svc_tli_create(fd, nconf, &taddr,
+			    RPC_MAXDATASIZE, RPC_MAXDATASIZE);
 		if (my_xprt == (SVCXPRT *)NULL) {
 			syslog(LOG_ERR, "%s: could not create service",
 					nconf->nc_netid);
 			goto error;
 		}
 	}
+	if (!checkbind)
+		return 1;
 
 #ifdef PORTMAP
 	/*
-- 
1.7.7.6

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux