summaryrefslogtreecommitdiffstats
path: root/usr.sbin
diff options
context:
space:
mode:
authormatteo <matteo@FreeBSD.org>2007-04-23 07:09:25 +0000
committermatteo <matteo@FreeBSD.org>2007-04-23 07:09:25 +0000
commitcaf8c9cda16f3804f93f34046fdd127c292e18f2 (patch)
treef48db0df78730336c174be22bda16f7d6b02b272 /usr.sbin
parent11f5869ec4504da88b92ffb900d23f2634676a7a (diff)
downloadFreeBSD-src-caf8c9cda16f3804f93f34046fdd127c292e18f2.zip
FreeBSD-src-caf8c9cda16f3804f93f34046fdd127c292e18f2.tar.gz
1)Make it possible for rpcbind(8) to bind TCP listening socket to an IP
other than INADDR_ANY. 2) Add the -6 option to specify "IPv6 only". Glanced at by: bms Requested by: bms [2] PR: bin/84494 [1] Approved by: silence from maintainer (~2 weeks) [1] MFC after: 2 weeks
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/rpcbind/rpcbind.88
-rw-r--r--usr.sbin/rpcbind/rpcbind.c409
2 files changed, 181 insertions, 236 deletions
diff --git a/usr.sbin/rpcbind/rpcbind.8 b/usr.sbin/rpcbind/rpcbind.8
index 950d366..0ecf895 100644
--- a/usr.sbin/rpcbind/rpcbind.8
+++ b/usr.sbin/rpcbind/rpcbind.8
@@ -2,7 +2,7 @@
.\" Copyright 1989 AT&T
.\" Copyright 1991 Sun Microsystems, Inc.
.\" $FreeBSD$
-.Dd November 29, 2006
+.Dd April 23, 2007
.Dt RPCBIND 8
.Os
.Sh NAME
@@ -10,7 +10,7 @@
.Nd universal addresses to RPC program number mapper
.Sh SYNOPSIS
.Nm
-.Op Fl adiLls
+.Op Fl 6adiLls
.Op Fl h Ar bindip
.Sh DESCRIPTION
The
@@ -68,6 +68,8 @@ The
utility can only be started by the super-user.
.Sh OPTIONS
.Bl -tag -width indent
+.It Fl 6
+Bind to AF_INET6 (IPv6) addresses only.
.It Fl a
When debugging
.Pq Fl d ,
@@ -83,7 +85,7 @@ is also specified.
With this option, the name-to-address translation consistency
checks are shown in detail.
.It Fl h Ar bindip
-Specify specific IP addresses to bind to for UDP requests.
+Specify specific IP addresses to bind to for TCP and UDP requests.
This option
may be specified multiple times and is typically necessary when running
on a multi-homed host.
diff --git a/usr.sbin/rpcbind/rpcbind.c b/usr.sbin/rpcbind/rpcbind.c
index 46370ec..0125cb4 100644
--- a/usr.sbin/rpcbind/rpcbind.c
+++ b/usr.sbin/rpcbind/rpcbind.c
@@ -92,6 +92,7 @@ int oldstyle_local = 0;
int verboselog = 0;
char **hosts = NULL;
+int ipv6_only = 0;
int nhosts = 0;
int on = 1;
int rpcbindlockfd;
@@ -173,8 +174,12 @@ main(int argc, char *argv[])
init_transport(nconf);
while ((nconf = getnetconfig(nc_handle))) {
- if (nconf->nc_flag & NC_VISIBLE)
- init_transport(nconf);
+ if (nconf->nc_flag & NC_VISIBLE)
+ if (ipv6_only == 1 && strcmp(nconf->nc_protofmly,
+ "inet") == 0) {
+ /* DO NOTHING */
+ } else
+ init_transport(nconf);
}
endnetconfig(nc_handle);
@@ -252,261 +257,196 @@ init_transport(struct netconfig *nconf)
mode_t oldmask;
if ((nconf->nc_semantics != NC_TPI_CLTS) &&
- (nconf->nc_semantics != NC_TPI_COTS) &&
- (nconf->nc_semantics != NC_TPI_COTS_ORD))
- return (1); /* not my type */
+ (nconf->nc_semantics != NC_TPI_COTS) &&
+ (nconf->nc_semantics != NC_TPI_COTS_ORD))
+ return (1); /* not my type */
#ifdef ND_DEBUG
if (debugging) {
- int i;
- char **s;
-
- (void) fprintf(stderr, "%s: %ld lookup routines :\n",
- nconf->nc_netid, nconf->nc_nlookups);
- for (i = 0, s = nconf->nc_lookups; i < nconf->nc_nlookups;
- i++, s++)
- fprintf(stderr, "[%d] - %s\n", i, *s);
+ int i;
+ char **s;
+
+ (void)fprintf(stderr, "%s: %ld lookup routines :\n",
+ nconf->nc_netid, nconf->nc_nlookups);
+ for (i = 0, s = nconf->nc_lookups; i < nconf->nc_nlookups;
+ i++, s++)
+ fprintf(stderr, "[%d] - %s\n", i, *s);
}
#endif
/*
- * XXX - using RPC library internal functions. For NC_TPI_CLTS
- * we call this later, for each socket we like to bind.
+ * XXX - using RPC library internal functions.
*/
- if (nconf->nc_semantics != NC_TPI_CLTS) {
- if ((fd = __rpc_nconf2fd(nconf)) < 0) {
- int non_fatal = 0;
-
- if (errno == EPROTONOSUPPORT)
- non_fatal = 1;
- syslog(non_fatal?LOG_DEBUG:LOG_ERR, "cannot create socket for %s",
- nconf->nc_netid);
- return (1);
- }
- }
if (!__rpc_nconf2sockinfo(nconf, &si)) {
- syslog(LOG_ERR, "cannot get information for %s",
- nconf->nc_netid);
- return (1);
+ syslog(LOG_ERR, "cannot get information for %s",
+ nconf->nc_netid);
+ return (1);
}
if ((strcmp(nconf->nc_netid, "local") == 0) ||
(strcmp(nconf->nc_netid, "unix") == 0)) {
- memset(&sun, 0, sizeof sun);
- sun.sun_family = AF_LOCAL;
- unlink(_PATH_RPCBINDSOCK);
- strcpy(sun.sun_path, _PATH_RPCBINDSOCK);
- sun.sun_len = SUN_LEN(&sun);
- addrlen = sizeof (struct sockaddr_un);
- sa = (struct sockaddr *)&sun;
+ memset(&sun, 0, sizeof sun);
+ sun.sun_family = AF_LOCAL;
+ unlink(_PATH_RPCBINDSOCK);
+ strcpy(sun.sun_path, _PATH_RPCBINDSOCK);
+ sun.sun_len = SUN_LEN(&sun);
+ addrlen = sizeof (struct sockaddr_un);
+ sa = (struct sockaddr *)&sun;
} else {
- /* Get rpcbind's address on this transport */
+ /* Get rpcbind's address on this transport */
- memset(&hints, 0, sizeof hints);
- hints.ai_flags = AI_PASSIVE;
- hints.ai_family = si.si_af;
- hints.ai_socktype = si.si_socktype;
- hints.ai_protocol = si.si_proto;
+ memset(&hints, 0, sizeof hints);
+ hints.ai_flags = AI_PASSIVE;
+ hints.ai_family = si.si_af;
+ hints.ai_socktype = si.si_socktype;
+ hints.ai_protocol = si.si_proto;
+ }
+ /*
+ * 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;
}
- 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 = 1;
- 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;
- }
- 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;
- }
- if (setsockopt(fd, IPPROTO_IPV6,
- IPV6_V6ONLY, &on, sizeof on) < 0) {
- syslog(LOG_ERR,
- "can't set v6-only binding for "
- "udp6 socket: %m");
- continue;
- }
- break;
- default:
- break;
- }
-
- /*
- * If no hosts were specified, just bind to INADDR_ANY
- */
- if (strcmp("*", hosts[nhostsbak]) == 0)
- hosts[nhostsbak] = NULL;
-
- if ((aicode = getaddrinfo(hosts[nhostsbak],
- servname, &hints, &res)) != 0) {
- syslog(LOG_ERR,
- "cannot get local address for %s: %s",
- nconf->nc_netid, gai_strerror(aicode));
- 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.len = taddr.addr.maxlen = addrlen;
- taddr.addr.buf = malloc(addrlen);
- if (taddr.addr.buf == NULL) {
- syslog(LOG_ERR,
- "cannot allocate memory for %s address",
- nconf->nc_netid);
- if (res != NULL)
- freeaddrinfo(res);
- return 1;
- }
- memcpy(taddr.addr.buf, sa, addrlen);
-#ifdef ND_DEBUG
- if (debugging) {
- /*
- * for debugging print out our universal
- * address
- */
- char *uaddr;
- struct netbuf nb;
-
- nb.buf = sa;
- nb.len = nb.maxlen = sa->sa_len;
- uaddr = taddr2uaddr(nconf, &nb);
- (void) fprintf(stderr,
- "rpcbind : my address is %s\n", uaddr);
- (void) free(uaddr);
- }
-#endif
-
- if (nconf->nc_semantics != NC_TPI_CLTS)
- listen(fd, SOMAXCONN);
- 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;
- }
+ /*
+ * Bind to specific IPs if asked to
+ */
+ checkbind = 1;
+ while (nhostsbak > 0) {
+ --nhostsbak;
+ /*
+ * XXX - using RPC library internal functions.
+ */
+ if ((fd = __rpc_nconf2fd(nconf)) < 0) {
+ int non_fatal = 0;
+ if (errno == EPROTONOSUPPORT &&
+ nconf->nc_semantics != NC_TPI_CLTS)
+ non_fatal = 1;
+ syslog(non_fatal ? LOG_DEBUG : 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;
}
- if (!checkbind)
- return 1;
- } else {
- if ((strcmp(nconf->nc_netid, "local") != 0) &&
- (strcmp(nconf->nc_netid, "unix") != 0)) {
- if ((aicode = getaddrinfo(NULL, servname, &hints, &res))
- != 0) {
- 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;
+ 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;
}
- oldmask = umask(S_IXUSR|S_IXGRP|S_IXOTH);
- if (bind(fd, sa, addrlen) < 0) {
- syslog(LOG_ERR, "cannot bind %s: %m", nconf->nc_netid);
- if (res != NULL)
- freeaddrinfo(res);
- return 1;
+ if (setsockopt(fd, IPPROTO_IPV6,
+ IPV6_V6ONLY, &on, sizeof on) < 0) {
+ syslog(LOG_ERR,
+ "can't set v6-only binding for "
+ "ipv6 socket: %m");
+ continue;
}
- (void) umask(oldmask);
-
- /* Copy the address */
- taddr.addr.len = taddr.addr.maxlen = addrlen;
- taddr.addr.buf = malloc(addrlen);
- if (taddr.addr.buf == NULL) {
- syslog(LOG_ERR, "cannot allocate memory for %s address",
- nconf->nc_netid);
- if (res != NULL)
- freeaddrinfo(res);
- return 1;
+ break;
+ default:
+ break;
+ }
+
+ /*
+ * 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) {
+ syslog(LOG_ERR,
+ "cannot get local address for %s: %s",
+ nconf->nc_netid, gai_strerror(aicode));
+ continue;
}
- memcpy(taddr.addr.buf, sa, addrlen);
+ 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.len = taddr.addr.maxlen = addrlen;
+ taddr.addr.buf = malloc(addrlen);
+ if (taddr.addr.buf == NULL) {
+ syslog(LOG_ERR,
+ "cannot allocate memory for %s address",
+ nconf->nc_netid);
+ if (res != NULL)
+ freeaddrinfo(res);
+ return 1;
+ }
+ memcpy(taddr.addr.buf, sa, addrlen);
#ifdef ND_DEBUG
- if (debugging) {
- /* for debugging print out our universal address */
- char *uaddr;
- struct netbuf nb;
-
- nb.buf = sa;
- nb.len = nb.maxlen = sa->sa_len;
- uaddr = taddr2uaddr(nconf, &nb);
- (void) fprintf(stderr, "rpcbind : my address is %s\n",
- uaddr);
- (void) free(uaddr);
- }
+ if (debugging) {
+ /*
+ * for debugging print out our universal
+ * address
+ */
+ char *uaddr;
+ struct netbuf nb;
+
+ nb.buf = sa;
+ nb.len = nb.maxlen = sa->sa_len;
+ uaddr = taddr2uaddr(nconf, &nb);
+ (void)fprintf(stderr,
+ "rpcbind : my address is %s\n", uaddr);
+ (void)free(uaddr);
+ }
#endif
- if (nconf->nc_semantics != NC_TPI_CLTS)
- listen(fd, SOMAXCONN);
+ if (nconf->nc_semantics != NC_TPI_CLTS)
+ listen(fd, SOMAXCONN);
- 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;
- }
+ 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
/*
@@ -704,8 +644,11 @@ parseargs(int argc, char *argv[])
#else
#define WSOP ""
#endif
- while ((c = getopt(argc, argv, "adh:iLls" WSOP)) != -1) {
+ while ((c = getopt(argc, argv, "6adh:iLls" WSOP)) != -1) {
switch (c) {
+ case '6':
+ ipv6_only = 1;
+ break;
case 'a':
doabort = 1; /* when debugging, do an abort on */
break; /* errors; for rpcbind developers */
@@ -741,7 +684,7 @@ parseargs(int argc, char *argv[])
#endif
default: /* error */
fprintf(stderr,
- "usage: rpcbind [-adiLls%s] [-h bindip]\n",
+ "usage: rpcbind [-6adiLls%s] [-h bindip]\n",
WSOP);
exit (1);
}
OpenPOWER on IntegriCloud