Module Name:    src
Committed By:   christos
Date:           Wed Aug 16 08:44:40 UTC 2017

Modified Files:
        src/usr.sbin/rpcbind: check_bound.c pmap_svc.c rpcb_stat.c rpcb_svc.c
            rpcb_svc_4.c rpcb_svc_com.c rpcbind.8 rpcbind.c rpcbind.h
            security.c util.c warmstart.c

Log Message:
merge FreeBSD changes:
- fixes CVE-2015-7236
- adds -h hostip to bind, -6 for only ipv6 access, -a for abort gracefully
- documents -w (warmstart)
XXX: should fix warmstart file to go to /var/run instead of /tmp


To generate a diff of this commit:
cvs rdiff -u -r1.6 -r1.7 src/usr.sbin/rpcbind/check_bound.c
cvs rdiff -u -r1.8 -r1.9 src/usr.sbin/rpcbind/pmap_svc.c
cvs rdiff -u -r1.5 -r1.6 src/usr.sbin/rpcbind/rpcb_stat.c \
    src/usr.sbin/rpcbind/rpcbind.h src/usr.sbin/rpcbind/warmstart.c
cvs rdiff -u -r1.3 -r1.4 src/usr.sbin/rpcbind/rpcb_svc.c
cvs rdiff -u -r1.7 -r1.8 src/usr.sbin/rpcbind/rpcb_svc_4.c
cvs rdiff -u -r1.19 -r1.20 src/usr.sbin/rpcbind/rpcb_svc_com.c
cvs rdiff -u -r1.11 -r1.12 src/usr.sbin/rpcbind/rpcbind.8 \
    src/usr.sbin/rpcbind/security.c
cvs rdiff -u -r1.23 -r1.24 src/usr.sbin/rpcbind/rpcbind.c
cvs rdiff -u -r1.20 -r1.21 src/usr.sbin/rpcbind/util.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.sbin/rpcbind/check_bound.c
diff -u src/usr.sbin/rpcbind/check_bound.c:1.6 src/usr.sbin/rpcbind/check_bound.c:1.7
--- src/usr.sbin/rpcbind/check_bound.c:1.6	Sun Nov  8 11:36:28 2015
+++ src/usr.sbin/rpcbind/check_bound.c	Wed Aug 16 04:44:40 2017
@@ -1,32 +1,32 @@
-/*	$NetBSD: check_bound.c,v 1.6 2015/11/08 16:36:28 christos Exp $	*/
+/*	$NetBSD: check_bound.c,v 1.7 2017/08/16 08:44:40 christos Exp $	*/
+/*	$FreeBSD: head/usr.sbin/rpcbind/check_bound.c 300942 2016-05-29 06:01:18Z ngie $ */
 
-/*
- * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part.  Users
- * may copy or modify Sun RPC without charge, but are not authorized
- * to license or distribute it to anyone else except as part of a product or
- * program developed by the user.
- * 
- * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- * 
- * Sun RPC is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- * 
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- * OR ANY PART THEREOF.
- * 
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
- * 
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California  94043
+/*-
+ * Copyright (c) 2009, Sun Microsystems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * - Neither the name of Sun Microsystems, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  */
 /*
  * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc.
@@ -43,7 +43,7 @@ static	char sccsid[] = "@(#)check_bound.
 /*
  * check_bound.c
  * Checks to see whether the program is still bound to the
- * claimed address and returns the univeral merged address
+ * claimed address and returns the universal merged address
  *
  */
 
@@ -73,7 +73,7 @@ struct fdlist {
 
 static struct fdlist *fdhead;	/* Link list of the check fd's */
 static struct fdlist *fdtail;
-static const char emptystring[] = "";
+static char nullstring[] = "";
 
 static bool_t check_bound(struct fdlist *, const char *uaddr);
 
@@ -98,6 +98,7 @@ check_bound(struct fdlist *fdl, const ch
 
 	fd = __rpc_nconf2fd(fdl->nconf);
 	if (fd < 0) {
+		free(na->buf);
 		free(na);
 		return (TRUE);
 	}
@@ -109,13 +110,14 @@ check_bound(struct fdlist *fdl, const ch
 #else
 	close(fd);
 #endif
+	free(na->buf);
 	free(na);
 
 	return (ans == 0 ? FALSE : TRUE);
 }
 
 int
-add_bndlist(struct netconfig *nconf, struct netbuf *baddr)
+add_bndlist(struct netconfig *nconf, struct netbuf *baddr __unused)
 {
 	struct fdlist *fdl;
 	struct netconfig *newnconf;
@@ -123,7 +125,7 @@ add_bndlist(struct netconfig *nconf, str
 	newnconf = getnetconfigent(nconf->nc_netid);
 	if (newnconf == NULL)
 		return (-1);
-	fdl = (struct fdlist *)malloc((u_int)sizeof (struct fdlist));
+	fdl = malloc(sizeof(struct fdlist));
 	if (fdl == NULL) {
 		freenetconfigent(newnconf);
 		syslog(LOG_ERR, "no memory!");
@@ -175,23 +177,31 @@ mergeaddr(SVCXPRT *xprt, char *netid, ch
 		return (NULL);
 	if (check_bound(fdl, uaddr) == FALSE)
 		/* that server died */
-		return strdup(emptystring);
+		return nullstring;
 	/*
+	 * Try to determine the local address on which the client contacted us,
+	 * so we can send a reply from the same address.  If it's unknown, then
+	 * try to determine which address the client used, and pick a nearby
+	 * local address.
+	 *
 	 * If saddr is not NULL, the remote client may have included the
 	 * address by which it contacted us.  Use that for the "client" uaddr,
 	 * otherwise use the info from the SVCXPRT.
 	 */
-	if (saddr != NULL) {
+	if (xprt->xp_rtaddr.buf != NULL) {
+		c_uaddr = taddr2uaddr(fdl->nconf, &xprt->xp_rtaddr);
+		allocated_uaddr = c_uaddr;
+	} else if (saddr != NULL) {
 		c_uaddr = saddr;
 	} else {
 		c_uaddr = taddr2uaddr(fdl->nconf, svc_getrpccaller(xprt));
-		if (c_uaddr == NULL) {
-			syslog(LOG_ERR, "taddr2uaddr failed for %s",
-				fdl->nconf->nc_netid);
-			return (NULL);
-		}
 		allocated_uaddr = c_uaddr;
 	}
+	if (c_uaddr == NULL) {
+		syslog(LOG_ERR, "taddr2uaddr failed for %s",
+			fdl->nconf->nc_netid);
+		return (NULL);
+	}
 
 #ifdef RPCBIND_DEBUG
 	if (debugging) {
@@ -214,8 +224,7 @@ mergeaddr(SVCXPRT *xprt, char *netid, ch
 		fprintf(stderr, "mergeaddr: uaddr = %s, merged uaddr = %s\n",
 				uaddr, m_uaddr);
 #endif
-	if (allocated_uaddr != NULL)
-		free(allocated_uaddr);
+	free(allocated_uaddr);
 	return (m_uaddr);
 }
 

Index: src/usr.sbin/rpcbind/pmap_svc.c
diff -u src/usr.sbin/rpcbind/pmap_svc.c:1.8 src/usr.sbin/rpcbind/pmap_svc.c:1.9
--- src/usr.sbin/rpcbind/pmap_svc.c:1.8	Sun Nov  8 11:36:28 2015
+++ src/usr.sbin/rpcbind/pmap_svc.c	Wed Aug 16 04:44:40 2017
@@ -1,32 +1,32 @@
-/*	$NetBSD: pmap_svc.c,v 1.8 2015/11/08 16:36:28 christos Exp $	*/
+/*	$NetBSD: pmap_svc.c,v 1.9 2017/08/16 08:44:40 christos Exp $	*/
+/*	$FreeBSD: head/usr.sbin/rpcbind/pmap_svc.c 258564 2013-11-25 16:44:02Z hrs $ */
 
-/*
- * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part.  Users
- * may copy or modify Sun RPC without charge, but are not authorized
- * to license or distribute it to anyone else except as part of a product or
- * program developed by the user.
- * 
- * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- * 
- * Sun RPC is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- * 
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- * OR ANY PART THEREOF.
- * 
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
- * 
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California  94043
+/*-
+ * Copyright (c) 2009, Sun Microsystems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * - Neither the name of Sun Microsystems, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  */
 /*
  * Copyright (c) 1984 - 1991 by Sun Microsystems, Inc.
@@ -165,7 +165,7 @@ find_service_pmap(rpcprog_t prog, rpcver
 }
 
 static bool_t
-pmapproc_change(struct svc_req *rqstp, SVCXPRT *xprt, unsigned long op)
+pmapproc_change(struct svc_req *rqstp __unused, SVCXPRT *xprt, unsigned long op)
 {
 	struct pmap reg;
 	RPCB rpcbreg;
@@ -173,11 +173,6 @@ pmapproc_change(struct svc_req *rqstp, S
 	struct sockcred *sc;
 	char uidbuf[32];
 
-	if (!svc_getargs(xprt, (xdrproc_t) xdr_pmap, (char *)&reg)) {
-		svcerr_decode(xprt);
-		return (FALSE);
-	}
-
 #ifdef RPCBIND_DEBUG
 	if (debugging)
 		fprintf(stderr, "%s request for (%lu, %lu) : ",
@@ -185,6 +180,11 @@ pmapproc_change(struct svc_req *rqstp, S
 		    reg.pm_prog, reg.pm_vers);
 #endif
 
+	if (!svc_getargs(xprt, (xdrproc_t) xdr_pmap, (char *)&reg)) {
+		svcerr_decode(xprt);
+		return (FALSE);
+	}
+
 	if (!check_access(xprt, op, &reg, PMAPVERS)) {
 		svcerr_weakauth(xprt);
 		return FALSE;
@@ -259,7 +259,7 @@ done_change:
 
 /* ARGSUSED */
 static bool_t
-pmapproc_getport(struct svc_req *rqstp, SVCXPRT *xprt)
+pmapproc_getport(struct svc_req *rqstp __unused, SVCXPRT *xprt)
 {
 	struct pmap reg;
 	long lport;
@@ -340,7 +340,7 @@ sendreply:
 
 /* ARGSUSED */
 static bool_t
-pmapproc_dump(struct svc_req *rqstp, SVCXPRT *xprt)
+pmapproc_dump(struct svc_req *rqstp __unused, SVCXPRT *xprt)
 {
 	if (!svc_getargs(xprt, (xdrproc_t)xdr_void, NULL)) {
 		svcerr_decode(xprt);

Index: src/usr.sbin/rpcbind/rpcb_stat.c
diff -u src/usr.sbin/rpcbind/rpcb_stat.c:1.5 src/usr.sbin/rpcbind/rpcb_stat.c:1.6
--- src/usr.sbin/rpcbind/rpcb_stat.c:1.5	Sun May 13 16:03:47 2007
+++ src/usr.sbin/rpcbind/rpcb_stat.c	Wed Aug 16 04:44:40 2017
@@ -1,32 +1,32 @@
-/*	$NetBSD: rpcb_stat.c,v 1.5 2007/05/13 20:03:47 christos Exp $	*/
+/*	$NetBSD: rpcb_stat.c,v 1.6 2017/08/16 08:44:40 christos Exp $	*/
+/* $FreeBSD: head/usr.sbin/rpcbind/rpcb_stat.c 301605 2016-06-08 12:45:22Z ngie $ */
 
-/*
- * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part.  Users
- * may copy or modify Sun RPC without charge, but are not authorized
- * to license or distribute it to anyone else except as part of a product or
- * program developed by the user.
- * 
- * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- * 
- * Sun RPC is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- * 
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- * OR ANY PART THEREOF.
- * 
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
- * 
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California  94043
+/*-
+ * Copyright (c) 2009, Sun Microsystems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * - Neither the name of Sun Microsystems, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  */
 /* #pragma ident   "@(#)rpcb_stat.c 1.7     94/04/25 SMI" */
 
@@ -196,11 +196,9 @@ rpcbs_rmtcall(rpcvers_t rtype, rpcproc_t
 	return;
 }
 
-/*
- */
 void *
-rpcbproc_getstat(void *arg, struct svc_req *req, SVCXPRT *xprt,
-		 rpcvers_t versnum)
+rpcbproc_getstat(void *arg __unused, struct svc_req *req __unused,
+    SVCXPRT *xprt __unused, rpcvers_t versnum __unused)
 {
 	return (void *)&inf;
 }
Index: src/usr.sbin/rpcbind/rpcbind.h
diff -u src/usr.sbin/rpcbind/rpcbind.h:1.5 src/usr.sbin/rpcbind/rpcbind.h:1.6
--- src/usr.sbin/rpcbind/rpcbind.h:1.5	Wed Aug 31 09:32:40 2011
+++ src/usr.sbin/rpcbind/rpcbind.h	Wed Aug 16 04:44:40 2017
@@ -1,33 +1,33 @@
-/*	$NetBSD: rpcbind.h,v 1.5 2011/08/31 13:32:40 joerg Exp $	*/
-
-/*
- * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part.  Users
- * may copy or modify Sun RPC without charge, but are not authorized
- * to license or distribute it to anyone else except as part of a product or
- * program developed by the user.
- * 
- * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- * 
- * Sun RPC is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
+/*	$NetBSD: rpcbind.h,v 1.6 2017/08/16 08:44:40 christos Exp $	*/
+/*	$FreeBSD: head/usr.sbin/rpcbind/rpcbind.h 293229 2016-01-06 00:00:11Z asomers $ */
+/*-
+ * Copyright (c) 2009, Sun Microsystems, Inc.
+ * All rights reserved.
  * 
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- * OR ANY PART THEREOF.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * - Neither the name of Sun Microsystems, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
  * 
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
- * 
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California  94043
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  */
+
 /*
  * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc.
  */
@@ -66,6 +66,9 @@ struct r_rmtcall_args {
 
 extern int debugging;
 extern int doabort;
+#ifdef LIBWRAP
+extern int libwrap;
+#endif
 extern int verboselog;
 extern int insecure;
 extern int oldstyle_local;
@@ -122,7 +125,7 @@ __dead void rpcbind_abort(void);
 void reap(int);
 void toggle_verboselog(int);
 
-int check_access(SVCXPRT *, rpcproc_t, void *, unsigned long);
+int check_access(SVCXPRT *, rpcproc_t, void *, unsigned int);
 int check_callit(SVCXPRT *, struct r_rmtcall_args *, int);
 void logit(int, struct sockaddr *, rpcproc_t, rpcprog_t, const char *);
 int is_loopback(struct netbuf *);
@@ -135,12 +138,20 @@ void write_warmstart(void);
 void read_warmstart(void);
 
 char *addrmerge(struct netbuf *caller, char *serv_uaddr, char *clnt_uaddr,
-		     char *netid);
+    const char *netid);
+int listen_addr(const struct sockaddr *sa);
 void network_init(void);
 struct sockaddr *local_sa(int);
 
 /* For different getaddr semantics */
 #define	RPCB_ALLVERS 0
 #define	RPCB_ONEVERS 1
+/* To convert a struct sockaddr to IPv4 or IPv6 address */
+#define	SA2SIN(sa)	((const struct sockaddr_in *)(sa))
+#define	SA2SINADDR(sa)	(SA2SIN(sa)->sin_addr)
+#ifdef INET6
+#define	SA2SIN6(sa)	((const struct sockaddr_in6 *)(sa))
+#define	SA2SIN6ADDR(sa)	(SA2SIN6(sa)->sin6_addr)
+#endif
 
 #endif /* rpcbind_h */
Index: src/usr.sbin/rpcbind/warmstart.c
diff -u src/usr.sbin/rpcbind/warmstart.c:1.5 src/usr.sbin/rpcbind/warmstart.c:1.6
--- src/usr.sbin/rpcbind/warmstart.c:1.5	Sat Aug  5 21:55:21 2017
+++ src/usr.sbin/rpcbind/warmstart.c	Wed Aug 16 04:44:40 2017
@@ -1,34 +1,36 @@
-/*
- * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part.  Users
- * may copy or modify Sun RPC without charge, but are not authorized
- * to license or distribute it to anyone else except as part of a product or
- * program developed by the user.
- * 
- * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- * 
- * Sun RPC is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- * 
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- * OR ANY PART THEREOF.
- * 
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
- * 
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California  94043
+/*	$NetBSD: warmstart.c,v 1.6 2017/08/16 08:44:40 christos Exp $	*/
+/* $FreeBSD: head/usr.sbin/rpcbind/warmstart.c 258564 2013-11-25 16:44:02Z hrs $*/
+
+/*-
+ * Copyright (c) 2009, Sun Microsystems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * - Neither the name of Sun Microsystems, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  */
 /*
  * warmstart.c
- * Allows for gathering of registrations from a earlier dumped file.
+ * Allows for gathering of registrations from an earlier dumped file.
  *
  * Copyright (c) 1990 by Sun Microsystems, Inc.
  */
@@ -40,7 +42,6 @@
 #include <stdio.h>
 #include <fcntl.h>
 #include <err.h>
-#include <paths.h>
 #include <rpc/rpc.h>
 #include <rpc/rpcb_prot.h>
 #include <rpc/xdr.h>
@@ -60,9 +61,9 @@
 
 
 /* These files keep the pmap_list and rpcb_list in XDR format */
-#define	RPCBFILE	_PATH_VARRUN "rpcbind.file"
+#define	RPCBFILE	"/tmp/rpcbind.file"
 #ifdef PORTMAP
-#define	PMAPFILE	_PATH_VARRUN "portmap.file"
+#define	PMAPFILE	"/tmp/portmap.file"
 #endif
 
 static bool_t write_struct(const char *, xdrproc_t, void *);
@@ -134,9 +135,9 @@ error:	warnx("Will start from scratch");
 void
 write_warmstart(void)
 {
-	(void)write_struct(RPCBFILE, (xdrproc_t) xdr_rpcblist_ptr, &list_rbl);
+	(void)write_struct(RPCBFILE, xdr_rpcblist_ptr, &list_rbl);
 #ifdef PORTMAP
-	(void)write_struct(PMAPFILE, (xdrproc_t) xdr_pmaplist_ptr, &list_pml);
+	(void)write_struct(PMAPFILE, xdr_pmaplist_ptr, &list_pml);
 #endif
 
 }
@@ -150,11 +151,11 @@ read_warmstart(void)
 #endif
 	int ok1, ok2 = TRUE;
 
-	ok1 = read_struct(RPCBFILE, (xdrproc_t) xdr_rpcblist_ptr, &tmp_rpcbl);
+	ok1 = read_struct(RPCBFILE, xdr_rpcblist_ptr, &tmp_rpcbl);
 	if (ok1 == FALSE)
 		return;
 #ifdef PORTMAP
-	ok2 = read_struct(PMAPFILE, (xdrproc_t) xdr_pmaplist_ptr, &tmp_pmapl);
+	ok2 = read_struct(PMAPFILE, xdr_pmaplist_ptr, &tmp_pmapl);
 #endif
 	if (ok2 == FALSE) {
 		xdr_free((xdrproc_t) xdr_rpcblist_ptr, (char *)&tmp_rpcbl);

Index: src/usr.sbin/rpcbind/rpcb_svc.c
diff -u src/usr.sbin/rpcbind/rpcb_svc.c:1.3 src/usr.sbin/rpcbind/rpcb_svc.c:1.4
--- src/usr.sbin/rpcbind/rpcb_svc.c:1.3	Wed Aug 31 12:25:00 2011
+++ src/usr.sbin/rpcbind/rpcb_svc.c	Wed Aug 16 04:44:40 2017
@@ -1,32 +1,32 @@
-/*	$NetBSD: rpcb_svc.c,v 1.3 2011/08/31 16:25:00 plunky Exp $	*/
+/*	$NetBSD: rpcb_svc.c,v 1.4 2017/08/16 08:44:40 christos Exp $	*/
+/*	$FreeBSD: head/usr.sbin/rpcbind/rpcb_svc.c 258564 2013-11-25 16:44:02Z hrs $ */
 
-/*
- * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part.  Users
- * may copy or modify Sun RPC without charge, but are not authorized
- * to license or distribute it to anyone else except as part of a product or
- * program developed by the user.
- * 
- * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- * 
- * Sun RPC is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- * 
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- * OR ANY PART THEREOF.
- * 
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
- * 
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California  94043
+/*-
+ * Copyright (c) 2009, Sun Microsystems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * - Neither the name of Sun Microsystems, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  */
 /*
  * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc.
@@ -203,8 +203,8 @@ done:
  */
 /* ARGSUSED */
 static void *
-rpcbproc_getaddr_3_local(void *arg, struct svc_req *rqstp, SVCXPRT *transp,
-			 rpcvers_t versnum)
+rpcbproc_getaddr_3_local(void *arg, struct svc_req *rqstp __unused,
+    SVCXPRT *transp __unused, rpcvers_t versnum __unused)
 {
 	RPCB *regp = (RPCB *)arg;
 #ifdef RPCBIND_DEBUG
@@ -225,8 +225,8 @@ rpcbproc_getaddr_3_local(void *arg, stru
 
 /* ARGSUSED */
 static void *
-rpcbproc_dump_3_local(void *arg, struct svc_req *rqstp, SVCXPRT *transp,
-		      rpcvers_t versnum)
+rpcbproc_dump_3_local(void *arg __unused, struct svc_req *rqstp __unused,
+    SVCXPRT *transp __unused, rpcvers_t versnum __unused)
 {
 	return ((void *)&list_rbl);
 }

Index: src/usr.sbin/rpcbind/rpcb_svc_4.c
diff -u src/usr.sbin/rpcbind/rpcb_svc_4.c:1.7 src/usr.sbin/rpcbind/rpcb_svc_4.c:1.8
--- src/usr.sbin/rpcbind/rpcb_svc_4.c:1.7	Wed Aug 31 12:25:00 2011
+++ src/usr.sbin/rpcbind/rpcb_svc_4.c	Wed Aug 16 04:44:40 2017
@@ -1,32 +1,32 @@
-/*	$NetBSD: rpcb_svc_4.c,v 1.7 2011/08/31 16:25:00 plunky Exp $	*/
+/*	$NetBSD: rpcb_svc_4.c,v 1.8 2017/08/16 08:44:40 christos Exp $	*/
+/* $FreeBSD: head/usr.sbin/rpcbind/rpcb_svc_4.c 258564 2013-11-25 16:44:02Z hrs $ */
 
-/*
- * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part.  Users
- * may copy or modify Sun RPC without charge, but are not authorized
- * to license or distribute it to anyone else except as part of a product or
- * program developed by the user.
- * 
- * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- * 
- * Sun RPC is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- * 
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- * OR ANY PART THEREOF.
- * 
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
- * 
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California  94043
+/*-
+ * Copyright (c) 2009, Sun Microsystems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * - Neither the name of Sun Microsystems, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  */
 /*
  * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc.
@@ -260,7 +260,7 @@ done:
 /* ARGSUSED */
 static void *
 rpcbproc_getaddr_4_local(void *arg, struct svc_req *rqstp, SVCXPRT *transp,
-			 rpcvers_t rpcbversnum)
+			 rpcvers_t rpcbversnum __unused)
 {
 	RPCB *regp = (RPCB *)arg;
 #ifdef RPCBIND_DEBUG
@@ -290,7 +290,7 @@ rpcbproc_getaddr_4_local(void *arg, stru
 /* ARGSUSED */
 static void *
 rpcbproc_getversaddr_4_local(void *arg, struct svc_req *rqstp, SVCXPRT *transp,
-			     rpcvers_t versnum)
+			     rpcvers_t versnum __unused)
 {
 	RPCB *regp = (RPCB *)arg;
 #ifdef RPCBIND_DEBUG
@@ -317,13 +317,13 @@ rpcbproc_getversaddr_4_local(void *arg, 
  */
 /* ARGSUSED */
 static void *
-rpcbproc_getaddrlist_4_local(void *arg, struct svc_req *rqstp, SVCXPRT *transp,
-			     rpcvers_t versnum)
+rpcbproc_getaddrlist_4_local(void *arg, struct svc_req *rqstp __unused,
+    SVCXPRT *transp, rpcvers_t versnum __unused)
 {
 	RPCB *regp = (RPCB *)arg;
 	static rpcb_entry_list_ptr rlist;
 	register rpcblist_ptr rbl;
-	rpcb_entry_list_ptr rp, tail = NULL;
+	rpcb_entry_list_ptr rp, tail;
 	rpcprog_t prog;
 	rpcvers_t vers;
 	rpcb_entry *a;
@@ -332,6 +332,7 @@ rpcbproc_getaddrlist_4_local(void *arg, 
 	char *saddr, *maddr = NULL;
 
 	free_rpcb_entry_list(&rlist);
+	tail = NULL;
 	prog = regp->r_prog;
 	vers = regp->r_vers;
 	reg_nconf = rpcbind_get_conf(transp->xp_netid);
@@ -360,7 +361,8 @@ rpcbproc_getaddrlist_4_local(void *arg, 
 		}
 #ifdef RPCBIND_DEBUG
 		if (debugging)
-			fprintf(stderr, "\tmerge with: %s\n", rbl->rpcb_map.r_addr);
+			fprintf(stderr, "\tmerge with: %s\n",
+			    rbl->rpcb_map.r_addr);
 #endif
 		if ((maddr = mergeaddr(transp, rbl->rpcb_map.r_netid,
 				rbl->rpcb_map.r_addr, saddr)) == NULL) {
@@ -376,7 +378,6 @@ rpcbproc_getaddrlist_4_local(void *arg, 
 #endif
 			/* The server died. Unset this combination */
 			delete_prog(regp->r_prog);
-			free(maddr);
 			continue;
 		}
 #ifdef RPCBIND_DEBUG
@@ -386,12 +387,9 @@ rpcbproc_getaddrlist_4_local(void *arg, 
 		/*
 		 * Add it to rlist.
 		 */
-		rp = (rpcb_entry_list_ptr)
-			malloc((u_int)sizeof (rpcb_entry_list));
-		if (rp == NULL) {
-			free(maddr);
+		rp = malloc(sizeof(rpcb_entry_list));
+		if (rp == NULL)
 			goto fail;
-		}
 		a = &rp->rpcb_entry_map;
 		a->r_maddr = maddr;
 		a->r_nc_netid = nconf->nc_netid;
@@ -448,8 +446,8 @@ free_rpcb_entry_list(rpcb_entry_list_ptr
 
 /* ARGSUSED */
 static void *
-rpcbproc_dump_4_local(void *arg, struct svc_req *req, SVCXPRT *xprt,
-		      rpcvers_t versnum)
+rpcbproc_dump_4_local(void *arg __unused, struct svc_req *req __unused,
+    SVCXPRT *xprt __unused, rpcvers_t versnum __unused)
 {
 	return ((void *)&list_rbl);
 }

Index: src/usr.sbin/rpcbind/rpcb_svc_com.c
diff -u src/usr.sbin/rpcbind/rpcb_svc_com.c:1.19 src/usr.sbin/rpcbind/rpcb_svc_com.c:1.20
--- src/usr.sbin/rpcbind/rpcb_svc_com.c:1.19	Wed May  3 17:28:00 2017
+++ src/usr.sbin/rpcbind/rpcb_svc_com.c	Wed Aug 16 04:44:40 2017
@@ -1,32 +1,32 @@
-/*	$NetBSD: rpcb_svc_com.c,v 1.19 2017/05/03 21:28:00 christos Exp $	*/
+/*	$NetBSD: rpcb_svc_com.c,v 1.20 2017/08/16 08:44:40 christos Exp $	*/
+/*	$FreeBSD: head/usr.sbin/rpcbind/rpcb_svc_com.c 301770 2016-06-09 22:25:00Z pfg $ */
 
-/*
- * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part.  Users
- * may copy or modify Sun RPC without charge, but are not authorized
- * to license or distribute it to anyone else except as part of a product or
- * program developed by the user.
- * 
- * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- * 
- * Sun RPC is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- * 
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- * OR ANY PART THEREOF.
- * 
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
- * 
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California  94043
+/*-
+ * Copyright (c) 2009, Sun Microsystems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * - Neither the name of Sun Microsystems, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  */
 /*
  * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc.
@@ -46,6 +46,7 @@
 #include <rpc/rpc.h>
 #include <rpc/rpcb_prot.h>
 #include <rpc/rpc_com.h>
+#include <assert.h>
 #include <netconfig.h>
 #include <errno.h>
 #include <syslog.h>
@@ -64,15 +65,15 @@
 #include <rump/rump_syscalls.h>
 #endif
 
-#include "rpcbind.h"
 #include "svc_dg.h"
+#include "rpcbind.h"
 #ifdef RPCBIND_RUMP
 #include "svc_fdset.h"
 #endif
 
 #define RPC_BUF_MAX	65536	/* can be raised if required */
 
-static char emptystring[] = "";
+static char nullstring[] = "";
 static int rpcb_rmtcalls;
 
 struct rmtcallfd_list {
@@ -106,8 +107,8 @@ static bool_t xdr_rmtcall_result(XDR *, 
 static bool_t xdr_opaque_parms(XDR *, struct r_rmtcall_args *);
 static int find_rmtcallfd_by_netid(char *);
 static SVCXPRT *find_rmtcallxprt_by_fd(int);
-static u_int32_t forward_register(u_int32_t, struct netbuf *, int, char *,
-				    rpcproc_t, rpcvers_t);
+static int forward_register(u_int32_t, struct netbuf *, int, char *,
+    rpcproc_t, rpcvers_t, u_int32_t *);
 static struct finfo *forward_find(u_int32_t);
 static int free_slot_by_xid(u_int32_t);
 static int free_slot_by_index(int);
@@ -129,10 +130,10 @@ static int del_pmaplist(RPCB *);
  */
 /* ARGSUSED */
 void *
-rpcbproc_set_com(void *arg, struct svc_req *rqstp, SVCXPRT *transp,
+rpcbproc_set_com(void *arg, struct svc_req *rqstp __unused, SVCXPRT *transp,
 		 rpcvers_t rpcbversnum)
 {
-	RPCB *regp = (RPCB *)arg;
+	RPCB *regp = arg;
 	static bool_t ans;
 	char owner[64];
 
@@ -178,10 +179,9 @@ map_set(RPCB *regp, char *owner)
 	/*
 	 * add to the end of the list
 	 */
-	rbl = (rpcblist_ptr) malloc((u_int)sizeof (RPCBLIST));
-	if (rbl == NULL) {
+	rbl = malloc(sizeof(RPCBLIST));
+	if (rbl == NULL)
 		return (FALSE);
-	}
 	a = &(rbl->rpcb_map);
 	a->r_prog = reg.r_prog;
 	a->r_vers = reg.r_vers;
@@ -190,12 +190,12 @@ map_set(RPCB *regp, char *owner)
 	a->r_owner = strdup(owner);
 	if (!a->r_addr || !a->r_netid || !a->r_owner) {
 		if (a->r_netid)
-			free((void *) a->r_netid);
+			free(a->r_netid);
 		if (a->r_addr)
-			free((void *) a->r_addr);
+			free(a->r_addr);
 		if (a->r_owner)
-			free((void *) a->r_owner);
-		free((void *)rbl);
+			free(a->r_owner);
+		free(rbl);
 		return (FALSE);
 	}
 	rbl->rpcb_next = NULL;
@@ -218,10 +218,10 @@ map_set(RPCB *regp, char *owner)
  */
 /* ARGSUSED */
 void *
-rpcbproc_unset_com(void *arg, struct svc_req *rqstp, SVCXPRT *transp,
+rpcbproc_unset_com(void *arg, struct svc_req *rqstp __unused, SVCXPRT *transp,
 		   rpcvers_t rpcbversnum)
 {
-	RPCB *regp = (RPCB *)arg;
+	RPCB *regp = arg;
 	static bool_t ans;
 	char owner[64];
 
@@ -275,10 +275,10 @@ map_unset(RPCB *regp, const char *owner)
 			list_rbl = rbl;
 		else
 			prev->rpcb_next = rbl;
-		free((void *) tmp->rpcb_map.r_addr);
-		free((void *) tmp->rpcb_map.r_netid);
-		free((void *) tmp->rpcb_map.r_owner);
-		free((void *) tmp);
+		free(tmp->rpcb_map.r_addr);
+		free(tmp->rpcb_map.r_netid);
+		free(tmp->rpcb_map.r_owner);
+		free(tmp);
 	}
 #ifdef PORTMAP
 	if (ans)
@@ -312,15 +312,17 @@ delete_prog(rpcprog_t prog)
 }
 
 void *
-rpcbproc_getaddr_com(RPCB *regp, struct svc_req *rqstp, SVCXPRT *transp,
-		     rpcvers_t rpcbversnum, rpcvers_t verstype)
+rpcbproc_getaddr_com(RPCB *regp, struct svc_req *rqstp __unused,
+    SVCXPRT *transp, rpcvers_t rpcbversnum, rpcvers_t verstype)
 {
 	static char *uaddr;
 	char *saddr = NULL;
 	rpcblist_ptr fnd;
 
-	if (uaddr && uaddr[0])
-		free((void *) uaddr);
+	if (uaddr != NULL && uaddr != nullstring) {
+		free(uaddr);
+		uaddr = NULL;
+	}
 	fnd = find_service(regp->r_prog, regp->r_vers, transp->xp_netid);
 	if (fnd && ((verstype == RPCB_ALLVERS) ||
 		    (regp->r_vers == fnd->rpcb_map.r_vers))) {
@@ -336,10 +338,10 @@ rpcbproc_getaddr_com(RPCB *regp, struct 
 			 * The server died.  Unset all versions of this prog.
 			 */
 			delete_prog(regp->r_prog);
-			uaddr = emptystring;
+			uaddr = nullstring;
 		}
 	} else {
-		uaddr = emptystring;
+		uaddr = nullstring;
 	}
 #ifdef RPCBIND_DEBUG
 	if (debugging)
@@ -353,13 +355,13 @@ rpcbproc_getaddr_com(RPCB *regp, struct 
 
 /* ARGSUSED */
 void *
-rpcbproc_gettime_com(void *arg, struct svc_req *rqstp, SVCXPRT *transp,
-		     rpcvers_t rpcbversnum)
+rpcbproc_gettime_com(void *arg __unused, struct svc_req *rqstp __unused,
+    SVCXPRT *transp __unused, rpcvers_t rpcbversnum __unused)
 {
 	static time_t curtime;
 
 	(void) time(&curtime);
-	return (void *)&curtime;
+	return &curtime;
 }
 
 /*
@@ -368,24 +370,25 @@ rpcbproc_gettime_com(void *arg, struct s
  */
 /* ARGSUSED */
 void *
-rpcbproc_uaddr2taddr_com(void *arg, struct svc_req *rqstp, SVCXPRT *transp,
-			 rpcvers_t rpcbversnum)
+rpcbproc_uaddr2taddr_com(void *arg, struct svc_req *rqstp __unused,
+    SVCXPRT *transp, rpcvers_t rpcbversnum __unused)
 {
-	char **uaddrp = (char **)arg;
+	char **uaddrp = arg;
 	struct netconfig *nconf;
 	static struct netbuf nbuf;
 	static struct netbuf *taddr;
 
 	if (taddr) {
-		free((void *) taddr->buf);
-		free((void *) taddr);
+		free(taddr->buf);
+		free(taddr);
+		taddr = NULL;
 	}
 	if (((nconf = rpcbind_get_conf(transp->xp_netid)) == NULL) ||
 	    ((taddr = uaddr2taddr(nconf, *uaddrp)) == NULL)) {
-		(void) memset((char *)&nbuf, 0, sizeof (struct netbuf));
-		return (void *)&nbuf;
+		(void) memset(&nbuf, 0, sizeof (struct netbuf));
+		return &nbuf;
 	}
-	return (void *)taddr;
+	return taddr;
 }
 
 /*
@@ -394,10 +397,10 @@ rpcbproc_uaddr2taddr_com(void *arg, stru
  */
 /* ARGSUSED */
 void *
-rpcbproc_taddr2uaddr_com(void *arg, struct svc_req *rqstp, SVCXPRT *transp,
-			 rpcvers_t rpcbversnum)
+rpcbproc_taddr2uaddr_com(void *arg, struct svc_req *rqstp __unused,
+    SVCXPRT *transp, rpcvers_t rpcbversnum __unused)
 {
-	struct netbuf *taddr = (struct netbuf *)arg;
+	struct netbuf *taddr = arg;
 	static char *uaddr;
 	struct netconfig *nconf;
 
@@ -409,11 +412,13 @@ rpcbproc_taddr2uaddr_com(void *arg, stru
 		return (&uaddr);
 	}
 #endif /* CHEW_FDS */
-	if (uaddr && !uaddr[0])
-		free((void *) uaddr);
+	if (uaddr != NULL && uaddr != nullstring) {
+		free(uaddr);
+		uaddr = NULL;
+	}
 	if (((nconf = rpcbind_get_conf(transp->xp_netid)) == NULL) ||
 		((uaddr = taddr2uaddr(nconf, taddr)) == NULL)) {
-		uaddr = emptystring;
+		uaddr = nullstring;
 	}
 	return (void *)&uaddr;
 }
@@ -434,9 +439,9 @@ static bool_t
 xdr_rmtcall_args(XDR *xdrs, struct r_rmtcall_args *cap)
 {
 	/* does not get the address or the arguments */
-	if (xdr_u_int32_t(xdrs, &(cap->rmt_prog)) &&
-	    xdr_u_int32_t(xdrs, &(cap->rmt_vers)) &&
-	    xdr_u_int32_t(xdrs, &(cap->rmt_proc))) {
+	if (xdr_rpcprog(xdrs, &(cap->rmt_prog)) &&
+	    xdr_rpcvers(xdrs, &(cap->rmt_vers)) &&
+	    xdr_rpcproc(xdrs, &(cap->rmt_proc))) {
 		return (xdr_encap_parms(xdrs, &(cap->rmt_args)));
 	}
 	return (FALSE);
@@ -510,8 +515,7 @@ create_rmtcall_fd(struct netconfig *ncon
 				"create_rmtcall_fd: svc_tli_create failed\n");
 		return (-1);
 	}
-	rmt = (struct rmtcallfd_list *)malloc((u_int)
-		sizeof (struct rmtcallfd_list));
+	rmt = malloc(sizeof(struct rmtcallfd_list));
 	if (rmt == NULL) {
 		syslog(LOG_ERR, "create_rmtcall_fd: no memory!");
 		return (-1);
@@ -615,7 +619,7 @@ rpcbproc_callit_com(struct svc_req *rqst
 	XDR outxdr;
 	AUTH *auth;
 	int fd = -1;
-	char *uaddr, *m_uaddr, *local_uaddr = NULL;
+	char *uaddr, *m_uaddr = NULL, *local_uaddr = NULL;
 	u_int32_t *xidp;
 	struct __rpc_sockinfo si;
 	struct sockaddr *localsa;
@@ -637,7 +641,7 @@ rpcbproc_callit_com(struct svc_req *rqst
 	/*
 	 * Should be multiple of 4 for XDR.
 	 */
-	sendsz = ((sendsz + 3) / 4) * 4;
+	sendsz = roundup(sendsz, 4);
 	if (sendsz > RPC_BUF_MAX) {
 #ifdef	notyet
 		buf_alloc = alloca(sendsz);		/* not in IDR2? */
@@ -686,7 +690,7 @@ rpcbproc_callit_com(struct svc_req *rqst
 			(unsigned long)a.rmt_proc, transp->xp_netid,
 			uaddr ? uaddr : rpcbind_unknown);
 		if (uaddr)
-			free((void *) uaddr);
+			free(uaddr);
 	}
 #endif
 
@@ -728,16 +732,12 @@ rpcbproc_callit_com(struct svc_req *rqst
 	if (reply_type == RPCBPROC_INDIRECT) {
 		uaddr = mergeaddr(transp, transp->xp_netid,
 			rbl->rpcb_map.r_addr, NULL);
-		if ((uaddr == NULL) || uaddr[0] == '\0') {
+		if (uaddr == NULL || uaddr[0] == '\0') {
 			svcerr_noprog(transp);
-			if (uaddr != NULL) {
-				free((void *) uaddr);
-			}
+			free(uaddr);
 			goto error;
 		}
-		if (uaddr != NULL) {
-			free((void *) uaddr);
-		}
+		free(uaddr);
 	}
 	nconf = rpcbind_get_conf(transp->xp_netid);
 	if (nconf == NULL) {
@@ -768,13 +768,16 @@ rpcbproc_callit_com(struct svc_req *rqst
 	if ((fd = find_rmtcallfd_by_netid(nconf->nc_netid)) == -1) {
 		if (reply_type == RPCBPROC_INDIRECT)
 			svcerr_systemerr(transp);
-		free((void *) m_uaddr);
 		goto error;
 	}
 	xidp = __rpcb_get_dg_xidp(transp);
-	call_msg.rm_xid = forward_register(*xidp,
-			caller, fd, m_uaddr, reply_type, versnum);
-	if (call_msg.rm_xid == 0) {
+	switch (forward_register(*xidp, caller, fd, m_uaddr, reply_type,
+	    versnum, &call_msg.rm_xid)) {
+	case 1:
+		/* Success; forward_register() will free m_uaddr for us. */
+		m_uaddr = NULL;
+		break;
+	case 0:
 		/*
 		 * A duplicate request for the slow server.  Let's not
 		 * beat on it any more.
@@ -782,14 +785,12 @@ rpcbproc_callit_com(struct svc_req *rqst
 		if (debugging)
 			fprintf(stderr,
 			"rpcbproc_callit_com:  duplicate request\n");
-		free((void *) m_uaddr);
 		goto error;
-	} else 	if (call_msg.rm_xid == (uint32_t)-1) {
+	case -1:
 		/*  forward_register failed.  Perhaps no memory. */
 		if (debugging)
 			fprintf(stderr,
 			"rpcbproc_callit_com:  forward_register failed\n");
-		free((void *) m_uaddr);
 		goto error;
 	}
 
@@ -915,23 +916,26 @@ out:
 	if (local_uaddr)
 		free(local_uaddr);
 	if (buf_alloc)
-		free((void *) buf_alloc);
+		free(buf_alloc);
 	if (outbuf_alloc)
-		free((void *) outbuf_alloc);
+		free(outbuf_alloc);
 	if (na) {
 		free(na->buf);
 		free(na);
 	}
+	if (m_uaddr != NULL)
+		free(m_uaddr);
 }
 
 /*
  * Makes an entry into the FIFO for the given request.
- * If duplicate request, returns a 0, else returns the xid of its call.
+ * Returns 1 on success, 0 if this is a duplicate request, or -1 on error.
+ * *callxidp is set to the xid of the call.
  */
-static u_int32_t
+static int
 forward_register(u_int32_t caller_xid, struct netbuf *caller_addr,
-		 int forward_fd, char *uaddr, rpcproc_t reply_type,
-		 rpcvers_t versnum)
+    int forward_fd, char *uaddr, rpcproc_t reply_type,
+     rpcvers_t versnum, u_int32_t *callxidp)
 {
 	int		i;
 	int		j = 0;
@@ -946,7 +950,7 @@ forward_register(u_int32_t caller_xid, s
 		lastxid = time_now * NFORWARD;
 
 	/*
-	 * Check if it is an duplicate entry. Then,
+	 * Check if it is a duplicate entry. Then,
 	 * try to find an empty slot.  If not available, then
 	 * use the slot with the earliest time.
 	 */
@@ -996,8 +1000,12 @@ forward_register(u_int32_t caller_xid, s
 	 */
 	FINFO[j].uaddr = uaddr;
 	lastxid = lastxid + NFORWARD;
+	/* Don't allow a zero xid below. */
+	if ((u_int32_t)(lastxid + NFORWARD) <= NFORWARD)
+		lastxid = NFORWARD;
 	FINFO[j].forward_xid = lastxid + j;	/* encode slot */
-	return (FINFO[j].forward_xid);		/* forward on this xid */
+	*callxidp = FINFO[j].forward_xid;	/* forward on this xid */
+	return (1);
 }
 
 static struct finfo *
@@ -1037,7 +1045,7 @@ free_slot_by_index(int idx)
 		/* XXX may be too big, but can't access xprt array here */
 		if (fi->forward_fd >= *svc_fdset_getmax())
 			(*svc_fdset_getmax())--;
-		free((void *) fi->uaddr);
+		free(fi->uaddr);
 		fi->flag &= ~FINFO_ACTIVE;
 		rpcb_rmtcalls--;
 		return (1);
@@ -1051,16 +1059,35 @@ netbufcmp(struct netbuf *n1, struct netb
 	return ((n1->len != n2->len) || memcmp(n1->buf, n2->buf, n1->len));
 }
 
+static bool_t
+netbuf_copybuf(struct netbuf *dst, const struct netbuf *src)
+{
+	assert(src->len <= src->maxlen);
+
+	if (dst->maxlen < src->len || dst->buf == NULL) {
+		if (dst->buf != NULL)
+			free(dst->buf);
+		if ((dst->buf = calloc(1, src->maxlen)) == NULL)
+			return (FALSE);
+		dst->maxlen = src->maxlen;
+	}
+
+	dst->len = src->len;
+	memcpy(dst->buf, src->buf, src->len);
+
+	return (TRUE);
+}
+
 static struct netbuf *
 netbufdup(struct netbuf *ap)
 {
 	struct netbuf  *np;
 
-	np = (struct netbuf *) malloc(sizeof (struct netbuf) + ap->len);
-	if (np) {
-		np->maxlen = np->len = ap->len;
-		np->buf = ((char *) np) + sizeof (struct netbuf);
-		(void) memcpy(np->buf, ap->buf, ap->len);
+	if ((np = calloc(1, sizeof(struct netbuf))) == NULL)
+		return (NULL);
+	if (netbuf_copybuf(np, ap) == FALSE) {
+		free(np);
+		return (NULL);
 	}
 	return (np);
 }
@@ -1068,7 +1095,9 @@ netbufdup(struct netbuf *ap)
 static void
 netbuffree(struct netbuf *ap)
 {
-	free((void *) ap);
+	free(ap->buf);
+	ap->buf = NULL;
+	free(ap);
 }
 
 
@@ -1150,7 +1179,7 @@ out:
 				fprintf(stderr, "poll returned read fds < ");
 				for (i = 0, p = pollfds; i < nfds; i++, p++)
 					if (p->revents)
-						fprintf(stderr, "%d (0x%x)",
+						fprintf(stderr, "%d (%#x)",
 						    p->fd, p->revents);
 				fprintf(stderr, ">\n");
 			}
@@ -1212,7 +1241,7 @@ xprt_set_caller(SVCXPRT *xprt, struct fi
 {
 	u_int32_t *xidp;
 
-	*(svc_getrpccaller(xprt)) = *(fi->caller_addr);
+	netbuf_copybuf(svc_getrpccaller(xprt), fi->caller_addr);
 	xidp = __rpcb_get_dg_xidp(xprt);
 	*xidp = fi->caller_xid;
 }
@@ -1251,7 +1280,7 @@ handle_reply(int fd, SVCXPRT *xprt)
 		goto done;
 
 	do {
-		fromlen = sizeof ss;
+		fromlen = sizeof(ss);
 		inlen = recvfrom(fd, buffer, RPC_BUF_MAX, 0,
 			    (struct sockaddr *)&ss, &fromlen);
 	} while (inlen < 0 && errno == EINTR);
@@ -1307,7 +1336,7 @@ handle_reply(int fd, SVCXPRT *xprt)
 			a.rmt_uaddr, uaddr ? uaddr : rpcbind_unknown);
 	}
 	if (uaddr)
-		free((void *) uaddr);
+		free(uaddr);
 #endif
 	svc_sendreply(xprt, (xdrproc_t) xdr_rmtcall_result, (char *) &a);
 done:
@@ -1418,7 +1447,7 @@ add_pmaplist(RPCB *arg)
 		/* It is TCP */
 		pmap.pm_prot = IPPROTO_TCP;
 	} else
-		/* Not a IP protocol */
+		/* Not an IP protocol */
 		return (0);
 
 	/* interpret the universal address for TCP/IP */
@@ -1431,7 +1460,7 @@ add_pmaplist(RPCB *arg)
 	/*
 	 * add to END of list
 	 */
-	pml = (struct pmaplist *) malloc((u_int)sizeof (struct pmaplist));
+	pml = malloc(sizeof(struct pmaplist));
 	if (pml == NULL) {
 		(void) syslog(LOG_ERR, "rpcbind: no memory!\n");
 		return (1);
@@ -1470,7 +1499,7 @@ del_pmaplist(RPCB *arg)
 	} else if (arg->r_netid[0] == 0) {
 		prot = 0;	/* Remove all occurrences */
 	} else {
-		/* Not a IP protocol */
+		/* Not an IP protocol */
 		return (0);
 	}
 	for (prevpml = NULL, pml = list_pml; pml; /* cstyle */) {
@@ -1489,7 +1518,7 @@ del_pmaplist(RPCB *arg)
 			list_pml = pml;
 		else
 			prevpml->pml_next = pml;
-		free((void *) fnd);
+		free(fnd);
 	}
 	return (0);
 }

Index: src/usr.sbin/rpcbind/rpcbind.8
diff -u src/usr.sbin/rpcbind/rpcbind.8:1.11 src/usr.sbin/rpcbind/rpcbind.8:1.12
--- src/usr.sbin/rpcbind/rpcbind.8:1.11	Wed Mar 11 10:00:11 2009
+++ src/usr.sbin/rpcbind/rpcbind.8	Wed Aug 16 04:44:40 2017
@@ -1,7 +1,8 @@
-.\" $NetBSD: rpcbind.8,v 1.11 2009/03/11 14:00:11 joerg Exp $
+.\" $NetBSD: rpcbind.8,v 1.12 2017/08/16 08:44:40 christos Exp $
 .\" @(#)rpcbind.1m 1.19 92/09/14 SMI; from SVr4
 .\" Copyright 1989 AT&T
 .\" Copyright 1991 Sun Microsystems, Inc.
+.\" $FreeBSD: head/usr.sbin/rpcbind/rpcbind.8 317163 2017-04-19 20:23:27Z ngie $
 .Dd October 19, 2008
 .Dt RPCBIND 8
 .Os
@@ -10,10 +11,12 @@
 .Nd universal addresses to RPC program number mapper
 .Sh SYNOPSIS
 .Nm
-.Op Fl dilLs
+.Op Fl 6adiLlswW
+.Op Fl h Ar bindip
 .Sh DESCRIPTION
+The
 .Nm
-is a server that converts
+utiltity is a server that converts
 .Tn RPC
 program numbers into
 universal addresses.
@@ -41,8 +44,9 @@ the address where
 .Tn RPC
 requests should be sent.
 .Pp
+The
 .Nm
-should be started before any other RPC service.
+utility should be started before any other RPC service.
 Normally, standard
 .Tn RPC
 servers are started by port monitors, so
@@ -60,8 +64,9 @@ services cannot function correctly in th
 .Nm
 reports the condition and terminates.
 .Pp
+The
 .Nm
-can only be started by the super-user.
+utility can only be started by the super-user.
 .Pp
 Access control is provided by
 .Pa /etc/hosts.allow
@@ -72,17 +77,48 @@ as described in
 with daemon name
 .Nm .
 .Sh OPTIONS
-.Bl -tag -width Ds
+.Bl -tag -width indent
+.It Fl 6
+Bind to AF_INET6 (IPv6) addresses only.
+.It Fl a
+When debugging
+.Pq Fl d ,
+do an abort on errors.
 .It Fl d
 Run in debug mode.
 In this mode,
 .Nm
 will not fork when it starts, will print additional information
-during operation, and will abort on certain errors.
+during operation, and will abort on certain errors if
+.Fl a
+is also specified.
 With this option, the name-to-address translation consistency
 checks are shown in detail.
+.It Fl h Ar bindip
+IP addresses to bind to when servicing TCP and UDP requests.
+This option
+may be specified multiple times and is typically necessary when running
+on a multi-homed host.
+If no
+.Fl h
+option is specified,
+.Nm
+will bind to
+.Dv INADDR_ANY ,
+which could lead to problems on a multi-homed host due to
+.Nm
+returning a UDP packet from a different IP address than it was
+sent to.
+Note that when specifying IP addresses with
+.Fl h ,
+.Nm
+will automatically add
+.Li 127.0.0.1
+and if IPv6 is enabled,
+.Li ::1
+to the list.
 .It Fl i
-.Dq insecure
+.Dq Insecure
 mode.
 Allows calls to SET and UNSET from any host.
 Normally
@@ -103,10 +139,24 @@ to use non-privileged ports for outgoing
 clients from using
 .Nm
 to connect to services from a privileged port.
-.It Fl L
-Allow old-style local connections over the loopback interface.
-Without this flag, local connections are only allowed over a local socket,
-.Pa /var/run/rpcbind.sock
+.It Fl W
+Enable libwrap (TCP wrappers) support.
+.It Fl w
+Enable the warmstart feature.
+.Pp
+The warmstart feature saves RPC registrations on termination.
+Any saved RPC registrations are restored on restart if
+.Fl w
+is specified.
+This feature helps avoid RPC service interruption when restarting
+.Nm .
+warmstart support must be compiled in to
+.Nm .
+Portmap registrations are stored in
+.Pa /tmp/portmap.file .
+.Nm
+registrations are stored in
+.Pa /tmp/rpcbind.file .
 .El
 .Sh NOTES
 All RPC servers must be restarted if
@@ -114,6 +164,12 @@ All RPC servers must be restarted if
 is restarted.
 .Sh FILES
 .Bl -tag -width "/var/run/rpcbind.sock" -compact
+.It Pa /tmp/portmap.file
+saved portmap registrations file.
+.It Pa /tmp/rpcbind.file
+saved
+.Nm
+registrations file.
 .It Pa /var/run/rpcbind.sock
 .It Pa /etc/hosts.allow
 explicit remote host access list.
Index: src/usr.sbin/rpcbind/security.c
diff -u src/usr.sbin/rpcbind/security.c:1.11 src/usr.sbin/rpcbind/security.c:1.12
--- src/usr.sbin/rpcbind/security.c:1.11	Sun Jan 18 05:17:38 2009
+++ src/usr.sbin/rpcbind/security.c	Wed Aug 16 04:44:40 2017
@@ -1,4 +1,5 @@
-/*	$NetBSD: security.c,v 1.11 2009/01/18 10:17:38 lukem Exp $	*/
+/*	$NetBSD: security.c,v 1.12 2017/08/16 08:44:40 christos Exp $	*/
+/*	$FreeBSD: head/usr.sbin/rpcbind/security.c 262860 2014-03-06 17:33:27Z mav $ */
 
 #include <sys/types.h>
 #include <sys/time.h>
@@ -9,6 +10,7 @@
 #include <rpc/rpcb_prot.h>
 #include <rpc/pmap_prot.h>
 #include <err.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
@@ -57,7 +59,7 @@ int log_severity = PORTMAP_LOG_FACILITY|
 extern int verboselog;
 
 int 
-check_access(SVCXPRT *xprt, rpcproc_t proc, void *args, unsigned long rpcbvers)
+check_access(SVCXPRT *xprt, rpcproc_t proc, void *args, unsigned int rpcbvers)
 {
 	struct netbuf *caller = svc_getrpccaller(xprt);
 	struct sockaddr *addr = (struct sockaddr *)caller->buf;
@@ -106,13 +108,15 @@ check_access(SVCXPRT *xprt, rpcproc_t pr
 	}
 
 #ifdef LIBWRAP
-	if (addr->sa_family == AF_LOCAL)
-		return 1;
-	request_init(&req, RQ_DAEMON, "rpcbind", RQ_CLIENT_SIN, addr, 0);
-	sock_methods(&req);
-	if(!hosts_access(&req)) {
-		logit(deny_severity, addr, proc, prog, ": request from unauthorized host");
-		return 0;
+	if (libwrap && addr->sa_family != AF_LOCAL) {
+		request_init(&req, RQ_DAEMON, "rpcbind", RQ_CLIENT_SIN, addr,
+		    0);
+		sock_methods(&req);
+		if(!hosts_access(&req)) {
+			logit(deny_severity, addr, proc, prog,
+			    ": request from unauthorized host");
+			return 0;
+		}
 	}
 #endif
 	if (verboselog)
@@ -224,7 +228,7 @@ logit(int severity, struct sockaddr *add
 }
 
 int
-check_callit(SVCXPRT *xprt, struct r_rmtcall_args *args, int versnum)
+check_callit(SVCXPRT *xprt, struct r_rmtcall_args *args, int versnum __unused)
 {
 	struct sockaddr *sa = (struct sockaddr *)svc_getrpccaller(xprt)->buf;
 
@@ -275,8 +279,12 @@ check_callit(SVCXPRT *xprt, struct r_rmt
 
 	return 1;
 deny:
+#ifdef LIBWRAP
 	logit(deny_severity, sa, args->rmt_proc, args->rmt_prog,
 	    ": indirect call not allowed");
-
+#else
+	logit(0, sa, args->rmt_proc, args->rmt_prog,
+	    ": indirect call not allowed");
+#endif
 	return 0;
 }

Index: src/usr.sbin/rpcbind/rpcbind.c
diff -u src/usr.sbin/rpcbind/rpcbind.c:1.23 src/usr.sbin/rpcbind/rpcbind.c:1.24
--- src/usr.sbin/rpcbind/rpcbind.c:1.23	Sun Nov  8 11:36:28 2015
+++ src/usr.sbin/rpcbind/rpcbind.c	Wed Aug 16 04:44:40 2017
@@ -1,32 +1,31 @@
-/*	$NetBSD: rpcbind.c,v 1.23 2015/11/08 16:36:28 christos Exp $	*/
+/*	$NetBSD: rpcbind.c,v 1.24 2017/08/16 08:44:40 christos Exp $	*/
 
-/*
- * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part.  Users
- * may copy or modify Sun RPC without charge, but are not authorized
- * to license or distribute it to anyone else except as part of a product or
- * program developed by the user.
- * 
- * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- * 
- * Sun RPC is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- * 
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- * OR ANY PART THEREOF.
+/*-
+ * Copyright (c) 2009, Sun Microsystems, Inc.
+ * All rights reserved.
  * 
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * - Neither the name of Sun Microsystems, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
  * 
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California  94043
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  */
 /*
  * Copyright (c) 1984 - 1991 by Sun Microsystems, Inc.
@@ -56,9 +55,12 @@ static	char sccsid[] = "@(#)rpcbind.c 1.
 #include <sys/socket.h>
 #include <sys/un.h>
 #include <rpc/rpc.h>
+#include <rpc/rpc_com.h>
 #ifdef PORTMAP
 #include <netinet/in.h>
 #endif
+#include <arpa/inet.h>
+#include <fcntl.h>
 #include <netdb.h>
 #include <stdio.h>
 #include <netconfig.h>
@@ -94,14 +96,26 @@ rpcblist_ptr list_rbl;	/* A list of vers
 /* who to suid to if -s is given */
 #define RUN_AS  "daemon"
 
-int runasdaemon = 0;
+#define RPCBINDDLOCK "/var/run/rpcbind.lock"
+
+static int runasdaemon = 0;
 int insecure = 0;
 int oldstyle_local = 0;
+#ifdef LIBWRAP
+int libwrap = 0;
+#endif
 int verboselog = 0;
 
+static char **hosts = NULL;
+static struct sockaddr **bound_sa;
+static int ipv6_only = 0;
+static int nhosts = 0;
+static int on = 1;
+static int rpcbindlockfd;
+
 #ifdef WARMSTART
 /* Local Variable */
-static int warmstart = 0;	/* Grab a old copy of registrations */
+static int warmstart = 0;	/* Grab an old copy of registrations */
 #endif
 
 #ifdef PORTMAP
@@ -120,6 +134,7 @@ static int init_transport(struct netconf
 static void rbllist_add(rpcprog_t, rpcvers_t, struct netconfig *,
     struct netbuf *);
 __dead static void terminate(int);
+static void update_bound_sa(void);
 #ifndef RPCBIND_RUMP
 static void parseargs(int, char *[]);
 
@@ -153,9 +168,23 @@ rpcbind_main(void *arg)
 		if (setrlimit(RLIMIT_NOFILE, &rl) < 0)
 			err(EXIT_FAILURE, "setrlimit(RLIMIT_NOFILE)");
 	}
+	update_bound_sa();
+ 
+	/* Check that another rpcbind isn't already running. */
+	if ((rpcbindlockfd = open(RPCBINDDLOCK, O_RDONLY|O_CREAT, 0444)) == -1)
+		err(1, "%s", RPCBINDDLOCK);
+
+	if (flock(rpcbindlockfd, LOCK_EX|LOCK_NB) == -1 && errno == EWOULDBLOCK)
+		errx(1, "another rpcbind is already running. Aborting");
+
+#ifndef RPCBIND_RUMP
+	if (geteuid()) /* This command allowed only to root */
+		errx(EXIT_FAILURE, "Sorry. You are not superuser\n");
+#endif
 	nc_handle = setnetconfig(); 	/* open netconfig file */
 	if (nc_handle == NULL)
 		errx(EXIT_FAILURE, "could not read /etc/netconfig");
+
 #ifdef PORTMAP
 	udptrans = "";
 	tcptrans = "";
@@ -170,8 +199,13 @@ rpcbind_main(void *arg)
 	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);
 
@@ -249,9 +283,14 @@ init_transport(struct netconfig *nconf)
 	int status;	/* bound checking ? */
 	int aicode;
 	int addrlen;
+	int nhostsbak;
+	int bound;
+	u_int32_t host_addr[4];  /* IPv4 or IPv6 */
 	struct sockaddr *sa;
 	struct sockaddr_un sun;
-	const int one = 1;
+#ifndef RPCBIND_RUMP
+	mode_t oldmask;
+#endif
 
 	if ((nconf->nc_semantics != NC_TPI_CLTS) &&
 		(nconf->nc_semantics != NC_TPI_COTS) &&
@@ -273,32 +312,29 @@ init_transport(struct netconfig *nconf)
 	/*
 	 * XXX - using RPC library internal functions.
 	 */
-	if ((fd = __rpc_nconf2fd(nconf)) < 0) {
-		if (errno == EAFNOSUPPORT)
+	if (strcmp(nconf->nc_netid, "local") == 0) {
+		/* 
+		 * For other transports we call this later, for each socket we
+		 * like to bind.
+		 */
+		if ((fd = __rpc_nconf2fd(nconf)) < 0) {
+			int non_fatal = 0;
+			if (errno == EAFNOSUPPORT)
+				non_fatal = 1;
+			syslog(non_fatal ? LOG_DEBUG : LOG_ERR,
+			    "Cannot create socket for `%s'", nconf->nc_netid);
 			return 1;
-		warn("Cannot create socket for `%s'", nconf->nc_netid);
-		return 1;
-	}
+		}
+	} else
+		fd = -1;
 
 	if (!__rpc_nconf2sockinfo(nconf, &si)) {
-		warnx("Cannot get information for `%s'", nconf->nc_netid);
+		syslog(LOG_ERR, "Cannot get information for `%s'",
+		    nconf->nc_netid);
 		return 1;
 	}
 
-	if (si.si_af == AF_INET6) {
-		/*
-		 * We're doing host-based access checks here, so don't allow
-		 * v4-in-v6 to confuse things.
-		 */
-		if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &one,
-		    sizeof one) < 0) {
-			warn("Can't make socket ipv6 only");
-			return 1;
-		}
-	}
-
-
-	if (!strcmp(nconf->nc_netid, "local")) {
+	if (strcmp(nconf->nc_netid, "local") == 0) {
 		(void)memset(&sun, 0, sizeof sun);
 		sun.sun_family = AF_LOCAL;
 #ifdef RPCBIND_RUMP
@@ -319,64 +355,214 @@ init_transport(struct netconfig *nconf)
 		hints.ai_family = si.si_af;
 		hints.ai_socktype = si.si_socktype;
 		hints.ai_protocol = si.si_proto;
-		if ((aicode = getaddrinfo(NULL, servname, &hints, &res)) != 0) {
-			warnx("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;
 	}
 
-	if (bind(fd, sa, addrlen) < 0) {
-		warn("Cannot bind `%s'", nconf->nc_netid);
-		if (res != NULL)
-			freeaddrinfo(res);
-		return 1;
-	}
+	if (strcmp(nconf->nc_netid, "local") != 0) {
+		/*
+		 * If no hosts were specified, just bind to INADDR_ANY.
+		 * Otherwise  make sure 127.0.0.1 is added to the list.
+		 */
+		nhostsbak = nhosts + 1;
+		hosts = realloc(hosts, nhostsbak * sizeof(char *));
+		if (nhostsbak == 1)
+			hosts[0] = __UNCONST("*");
+		else {
+			if (hints.ai_family == AF_INET) {
+				hosts[nhostsbak - 1] = __UNCONST("127.0.0.1");
+			} else if (hints.ai_family == AF_INET6) {
+				hosts[nhostsbak - 1] = __UNCONST("::1");
+			} else
+				return 1;
+		}
+
+		/*
+		 * Bind to specific IPs if asked to
+		 */
+		bound = 0;
+		while (nhostsbak > 0) {
+			--nhostsbak;
+			/*
+			 * XXX - using RPC library internal functions.
+			 */
+			if ((fd = __rpc_nconf2fd(nconf)) < 0) {
+				int non_fatal = 0;
+				if (errno == EAFNOSUPPORT &&
+				    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 address.
+					 */
+					if (inet_pton(AF_INET6,
+					    hosts[nhostsbak], host_addr) == 1) {
+						close(fd);
+						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 address.
+					 */
+					if (inet_pton(AF_INET, hosts[nhostsbak],
+					    host_addr) == 1) {
+						close(fd);
+						continue;
+					}
+				}
+				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;
+				    }
+				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) {
+				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;
+			}
+#ifndef RPCBIND_RUMP
+			oldmask = umask(S_IXUSR|S_IXGRP|S_IXOTH);
+#endif
+			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
+				bound = 1;
 #ifndef RPCBIND_RUMP
-	if (sa->sa_family == AF_LOCAL)
-		if (chmod(sun.sun_path, S_IRWXU|S_IRWXG|S_IRWXO) == -1)
-			warn("Cannot chmod `%s'", sun.sun_path);
+			(void)umask(oldmask);
 #endif
 
-	/* Copy the address */
-	taddr.addr.len = taddr.addr.maxlen = addrlen;
-	taddr.addr.buf = malloc(addrlen);
-	if (taddr.addr.buf == NULL) {
-		warn("Cannot allocate memory for `%s' address",
-		    nconf->nc_netid);
-		if (res != NULL)
-			freeaddrinfo(res);
-		return 1;
-	}
-	(void)memcpy(taddr.addr.buf, sa, addrlen);
+			/* 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 RPCBIND_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 fd=%d\n",
-		    uaddr, fd);
-		(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 (res != NULL)
-		freeaddrinfo(res);
-
-	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 == NULL) {
-		warnx("Could not create service for `%s'", nconf->nc_netid);
-		goto error;
+			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 == NULL) {
+				syslog(LOG_ERR,
+				    "Could not create service for `%s'",
+				    nconf->nc_netid);
+				goto error;
+			}
+		}
+		if (!bound)
+			return 1;
+	} else {
+#ifndef RPCBIND_RUMP
+		oldmask = umask(S_IXUSR|S_IXGRP|S_IXOTH);
+#endif
+		if (bind(fd, sa, addrlen) < 0) {
+			syslog(LOG_ERR, "cannot bind %s: %m", nconf->nc_netid);
+			if (res != NULL)
+				freeaddrinfo(res);
+			return 1;
+		}
+#ifndef RPCBIND_RUMP
+		(void) umask(oldmask);
+#endif
+
+		/* 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 RPCBIND_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;
+		}
 	}
 
 #ifdef PORTMAP
@@ -391,20 +577,22 @@ init_transport(struct netconfig *nconf)
 
 		if (!svc_register(my_xprt, PMAPPROG, PMAPVERS,
 			pmap_service, 0)) {
-			warn("Could not register on `%s'", nconf->nc_netid);
+			syslog(LOG_ERR, "Could not register on `%s'",
+			    nconf->nc_netid);
 			goto error;
 		}
 		pml = malloc(sizeof (struct pmaplist));
 		if (pml == NULL) {
-			warn("Cannot allocate memory");
+			syslog(LOG_ERR, "Cannot allocate memory");
 			goto error;
 		}
+
 		pml->pml_map.pm_prog = PMAPPROG;
 		pml->pml_map.pm_vers = PMAPVERS;
 		pml->pml_map.pm_port = PMAPPORT;
 		if (strcmp(nconf->nc_proto, NC_TCP) == 0) {
 			if (tcptrans[0]) {
-				warnx(
+				syslog(LOG_ERR,
 				    "Cannot have more than one TCP transport");
 				free(pml);
 				goto error;
@@ -412,7 +600,7 @@ init_transport(struct netconfig *nconf)
 			tcptrans = strdup(nconf->nc_netid);
 			if (tcptrans == NULL) {
 				free(pml);
-				warn("Cannot allocate memory");
+				syslog(LOG_ERR, "Cannot allocate memory");
 				goto error;
 			}
 			pml->pml_map.pm_prot = IPPROTO_TCP;
@@ -423,14 +611,14 @@ init_transport(struct netconfig *nconf)
 		} else if (strcmp(nconf->nc_proto, NC_UDP) == 0) {
 			if (udptrans[0]) {
 				free(pml);
-				warnx(
+				syslog(LOG_ERR,
 				"Cannot have more than one UDP transport");
 				goto error;
 			}
 			udptrans = strdup(nconf->nc_netid);
 			if (udptrans == NULL) {
 				free(pml);
-				warn("Cannot allocate memory");
+				syslog(LOG_ERR, "Cannot allocate memory");
 				goto error;
 			}
 			pml->pml_map.pm_prot = IPPROTO_UDP;
@@ -439,13 +627,17 @@ init_transport(struct netconfig *nconf)
 			/* "h1.h2.h3.h4.p1.p2" */
 			udp_uaddr = taddr2uaddr(nconf, &taddr.addr);
 		}
+#ifdef IPPROTO_ST
+		else if (strcmp(nconf->nc_netid, "local") == 0)
+			pml->pml_map.pm_prot = IPPROTO_ST;
+#endif
 		pml->pml_next = list_pml;
 		list_pml = pml;
 
 		/* Add version 3 information */
 		pml = malloc(sizeof (struct pmaplist));
 		if (pml == NULL) {
-			warn("Cannot allocate memory");
+			syslog(LOG_ERR, "Cannot allocate memory");
 			goto error;
 		}
 		pml->pml_map = list_pml->pml_map;
@@ -456,7 +648,7 @@ init_transport(struct netconfig *nconf)
 		/* Add version 4 information */
 		pml = malloc(sizeof (struct pmaplist));
 		if (pml == NULL) {
-			warn("Cannot allocate memory");
+			syslog(LOG_ERR, "Cannot allocate memory");
 			goto error;
 		}
 		pml->pml_map = list_pml->pml_map;
@@ -471,14 +663,16 @@ init_transport(struct netconfig *nconf)
 
 	/* version 3 registration */
 	if (!svc_reg(my_xprt, RPCBPROG, RPCBVERS, rpcb_service_3, NULL)) {
-		warn("Could not register %s version 3", nconf->nc_netid);
+		syslog(LOG_ERR, "Could not register %s version 3",
+		    nconf->nc_netid);
 		goto error;
 	}
 	rbllist_add(RPCBPROG, RPCBVERS, nconf, &taddr.addr);
 
 	/* version 4 registration */
 	if (!svc_reg(my_xprt, RPCBPROG, RPCBVERS4, rpcb_service_4, NULL)) {
-		warn("Could not register %s version 4", nconf->nc_netid);
+		syslog(LOG_ERR, "Could not register %s version 4",
+		    nconf->nc_netid);
 		goto error;
 	}
 	rbllist_add(RPCBPROG, RPCBVERS4, nconf, &taddr.addr);
@@ -530,6 +724,75 @@ error:
 	return (1);
 }
 
+/*
+ * Create the list of addresses that we're bound to.  Normally, this
+ * list is empty because we're listening on the wildcard address
+ * (nhost == 0).  If -h is specified on the command line, then
+ * bound_sa will have a list of the addresses that the program binds
+ * to specifically.  This function takes that list and converts them to
+ * struct sockaddr * and stores them in bound_sa.
+ */
+static void
+update_bound_sa(void)
+{
+	struct addrinfo hints, *res = NULL;
+	int i;
+
+	if (nhosts == 0)
+		return;
+	bound_sa = malloc(sizeof(*bound_sa) * nhosts);
+	memset(&hints, 0, sizeof(hints));
+	hints.ai_family = PF_UNSPEC;
+	for (i = 0; i < nhosts; i++)  {
+		if (getaddrinfo(hosts[i], NULL, &hints, &res) != 0)
+			continue;
+		bound_sa[i] = malloc(res->ai_addrlen);
+		memcpy(bound_sa[i], res->ai_addr, res->ai_addrlen);
+	}
+}
+
+/*
+ * Match the sa against the list of addresses we've bound to.  If
+ * we've not specifically bound to anything, we match everything.
+ * Otherwise, if the IPv4 or IPv6 address matches one of the addresses
+ * in bound_sa, we return true.  If not, we return false.
+ */
+int
+listen_addr(const struct sockaddr *sa)
+{
+	int i;
+
+	/*
+	 * If nhosts == 0, then there were no -h options on the
+	 * command line, so all addresses are addresses we're
+	 * listening to.
+	 */
+	if (nhosts == 0)
+		return 1;
+	for (i = 0; i < nhosts; i++) {
+		if (bound_sa[i] == NULL ||
+		    sa->sa_family != bound_sa[i]->sa_family)
+			continue;
+		switch (sa->sa_family) {
+		case AF_INET:
+		  	if (memcmp(&SA2SINADDR(sa), &SA2SINADDR(bound_sa[i]),
+			    sizeof(struct in_addr)) == 0)
+				return (1);
+			break;
+#ifdef INET6
+		case AF_INET6:
+		  	if (memcmp(&SA2SIN6ADDR(sa), &SA2SIN6ADDR(bound_sa[i]),
+			    sizeof(struct in6_addr)) == 0)
+				return (1);
+			break;
+#endif
+		default:
+			break;
+		}
+	}
+	return (0);
+}
+
 static void
 rbllist_add(rpcprog_t prog, rpcvers_t vers, struct netconfig *nconf,
 	    struct netbuf *addr)
@@ -538,7 +801,7 @@ rbllist_add(rpcprog_t prog, rpcvers_t ve
 
 	rbl = malloc(sizeof(rpcblist));
 	if (rbl == NULL) {
-		warn("Out of memory");
+		syslog(LOG_ERR, "Out of memory");
 		return;
 	}
 
@@ -555,11 +818,13 @@ rbllist_add(rpcprog_t prog, rpcvers_t ve
  * Catch the signal and die
  */
 static void
-terminate(int dummy)
+terminate(int signum __unused)
 {
+	close(rpcbindlockfd);
 #ifdef WARMSTART
 	syslog(LOG_ERR,
-		"rpcbind terminating on signal. Restart with \"rpcbind -w\"");
+	    "rpcbind terminating on signal %d. Restart with \"rpcbind -w\"",
+	    signum);
 	write_warmstart();	/* Dump yourself */
 #endif
 #ifdef RPCBIND_RUMP
@@ -570,7 +835,7 @@ terminate(int dummy)
 }
 
 void
-rpcbind_abort()
+rpcbind_abort(void)
 {
 #ifdef WARMSTART
 	write_warmstart();	/* Dump yourself */
@@ -585,8 +850,21 @@ parseargs(int argc, char *argv[])
 {
 	int c;
 
-	while ((c = getopt(argc, argv, "dwailLs")) != -1) {
+#ifdef WARMSTART
+#define	WSOP	"w"
+#else
+#define	WSOP	""
+#endif
+#ifdef LIBWRAP
+#define WRAPOP	"W"
+#else
+#define WRAPOP	""
+#endif
+	while ((c = getopt(argc, argv, "6adh:iLls" WRAPOP 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 */
@@ -594,6 +872,15 @@ parseargs(int argc, char *argv[])
 		case 'd':
 			debugging = 1;
 			break;
+		case 'h':
+			++nhosts;
+			hosts = realloc(hosts, nhosts * sizeof(char *));
+			if (hosts == NULL)
+				errx(1, "Out of memory");
+			hosts[nhosts - 1] = strdup(optarg);
+			if (hosts[nhosts - 1] == NULL)
+				errx(1, "Out of memory");
+			break;
 		case 'i':
 			insecure = 1;
 			break;
@@ -606,6 +893,11 @@ parseargs(int argc, char *argv[])
 		case 's':
 			runasdaemon = 1;
 			break;
+#ifdef LIBWRAP
+		case 'W':
+			libwrap = 1;
+			break;
+#endif
 #ifdef WARMSTART
 		case 'w':
 			warmstart = 1;
@@ -613,6 +905,9 @@ parseargs(int argc, char *argv[])
 #endif
 		default:	/* error */
 			fprintf(stderr,	"usage: rpcbind [-Idwils]\n");
+			fprintf(stderr,
+			    "Usage: %s [-6adiLls%s%s] [-h bindip]\n",
+			    getprogname(), WRAPOP, WSOP);
 			exit(EXIT_FAILURE);
 		}
 	}
@@ -621,11 +916,13 @@ parseargs(int argc, char *argv[])
 		"-a (abort) specified without -d (debugging) -- ignored.\n");
 	    doabort = 0;
 	}
+#undef WRAPOP
+#undef WSOP
 }
 #endif
 
 void
-reap(int dummy)
+reap(int dummy __unused)
 {
 	int save_errno = errno;
  
@@ -635,7 +932,7 @@ reap(int dummy)
 }
 
 void
-toggle_verboselog(int dummy)
+toggle_verboselog(int dummy __unused)
 {
 	verboselog = !verboselog;
 }

Index: src/usr.sbin/rpcbind/util.c
diff -u src/usr.sbin/rpcbind/util.c:1.20 src/usr.sbin/rpcbind/util.c:1.21
--- src/usr.sbin/rpcbind/util.c:1.20	Sun Nov  8 11:36:28 2015
+++ src/usr.sbin/rpcbind/util.c	Wed Aug 16 04:44:40 2017
@@ -1,4 +1,5 @@
-/*	$NetBSD: util.c,v 1.20 2015/11/08 16:36:28 christos Exp $	*/
+/*	$NetBSD: util.c,v 1.21 2017/08/16 08:44:40 christos Exp $	*/
+/* $FreeBSD: head/usr.sbin/rpcbind/util.c 300973 2016-05-29 20:28:01Z ngie $ */
 
 /*-
  * Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -64,7 +65,8 @@ static int bitmaskcmp(void *, void *, vo
 
 /*
  * For all bits set in "mask", compare the corresponding bits in
- * "dst" and "src", and see if they match.
+ * "dst" and "src", and see if they match. Returns 0 if the addresses
+ * match.
  */
 static int
 bitmaskcmp(void *dst, void *src, void *mask, int bytelen)
@@ -88,7 +90,7 @@ bitmaskcmp(void *dst, void *src, void *m
 
 char *
 addrmerge(struct netbuf *caller, char *serv_uaddr, char *clnt_uaddr,
-	  char *netid)
+    const char *netid)
 {
 	struct ifaddrs *ifap, *ifp, *bestif;
 #ifdef INET6

Reply via email to