diff -r -u darwin-portmap/portmap.c new_portmap/portmap.c
--- darwin-portmap/portmap.c	Fri Feb 16 13:35:03 2001
+++ new_portmap/portmap.c	Sat Feb 17 19:39:50 2001
@@ -55,13 +55,17 @@
  */
 
 #ifndef lint
-static char copyright[] =
+static const char copyright[] =
 "@(#) Copyright (c) 1990, 1993\n\
 	The Regents of the University of California.  All rights reserved.\n";
 #endif /* not lint */
 
 #ifndef lint
+#if 0
 static char sccsid[] = "@(#)portmap.c	8.1 (Berkeley) 6/6/93";
+#endif
+static const char rcsid[] =
+  "$FreeBSD: src/usr.sbin/portmap/portmap.c,v 1.10 2000/01/15 23:08:29 brian Exp $";
 #endif /* not lint */
 
 /*
@@ -81,37 +85,38 @@
  * 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
  */
 
+#include <err.h>
 #include <errno.h>
-#include <rpc/rpc.h>
-#include <rpc/pmap_prot.h>
+#include <netdb.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <syslog.h>
 #include <unistd.h>
-#include <netdb.h>
+#include <rpc/rpc.h>
+#include <rpc/pmap_prot.h>
 #include <sys/socket.h>
 #include <sys/ioctl.h>
 #include <sys/wait.h>
@@ -128,16 +133,18 @@
 static int have_tag_network = 0;
 static struct timeval last_network_stat = {0, 0};
 
-void reg_service();
-void reap();
-static void callit();
+#include "pmap_check.h"
+
+extern int get_myaddress();
+static void reg_service __P((struct svc_req *, SVCXPRT *));
+static void reap __P((int));
+static void callit __P((struct svc_req *, SVCXPRT *));
+static void usage __P((void));
+
 struct pmaplist *pmaplist;
 int debugging = 0;
-extern int errno;
 extern int svc_maxfd;
 
-extern int get_myaddress();
-
 static void
 portmap_svc_run()
 {
@@ -183,23 +190,24 @@
 	int len = sizeof(struct sockaddr_in);
 	register struct pmaplist *pml;
 
-	while ((c = getopt(argc, argv, "d")) != EOF) {
+	while ((c = getopt(argc, argv, "dv")) != -1) {
 		switch (c) {
 
 		case 'd':
 			debugging = 1;
 			break;
 
+		case 'v':
+			verboselog = 1;
+			break;
+
 		default:
-			(void) fprintf(stderr, "usage: %s [-d]\n", argv[0]);
-			exit(1);
+			usage();
 		}
 	}
 
-	if (!debugging && daemon(0, 0)) {
-		(void) fprintf(stderr, "portmap: fork: %s", strerror(errno));
-		exit(1);
-	}
+	if (!debugging && daemon(0, 0))
+		err(1, "fork");
 
 	openlog("portmap", debugging ? LOG_PID | LOG_PERROR : LOG_PID,
 	    LOG_DAEMON);
@@ -235,7 +243,7 @@
 		exit(1);
 	}
 	if (bind(sock, (struct sockaddr *)&addr, len) != 0) {
-		syslog(LOG_ERR, "cannot bind udp: %m");
+		syslog(LOG_ERR, "cannot bind tcp: %m");
 		exit(1);
 	}
 	if ((xprt = svctcp_create(sock, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE))
@@ -257,20 +265,27 @@
 	/* initialize "network.nidb" timer */
 	gettimeofday(&last_network_stat, NULL);
 
+	/* additional initializations */
+	check_startup();
 	(void)signal(SIGCHLD, reap);
 	portmap_svc_run();
-	syslog(LOG_ERR, "run_svc returned unexpectedly");
+	syslog(LOG_ERR, "portmap_svc_run returned unexpectedly");
 	abort();
 }
 
+static void
+usage()
+{
+	fprintf(stderr, "usage: portmap [-dv]\n");
+	exit(1);
+}
+
 #ifndef lint
 /* need to override perror calls in rpc library */
-__private_extern__
 void
 perror(what)
 	const char *what;
 {
-
 	syslog(LOG_ERR, "%s: %m", what);
 }
 #endif
@@ -293,10 +308,10 @@
 	return (hit);
 }
 
-/* 
+/*
  * 1 OK, 0 not
  */
-void
+static void
 reg_service(rqstp, xprt)
 	struct svc_req *rqstp;
 	SVCXPRT *xprt;
@@ -305,15 +320,24 @@
 	struct pmaplist *pml, *prevpml, *fnd;
 	int ans, port;
 	caddr_t t;
-	
+
+	/*
+	 * Later wrappers change the logging severity on the fly. Reset to
+	 * defaults before handling the next request.
+	 */
+	allow_severity = LOG_INFO;
+	deny_severity = LOG_WARNING;
+
 	if (debugging)
-		(void) fprintf(stderr, "server: about do a switch\n");
+		(void) fprintf(stderr, "server: about to do a switch\n");
 	switch (rqstp->rq_proc) {
 
 	case PMAPPROC_NULL:
 		/*
 		 * Null proc call
 		 */
+		/* remote host authorization check */
+		check_default(svc_getcaller(xprt), rqstp->rq_proc, (u_long) 0);
 		if (!svc_sendreply(xprt, xdr_void, (caddr_t)0) && debugging) {
 			abort();
 		}
@@ -323,9 +347,15 @@
 		/*
 		 * Set a program,version to port mapping
 		 */
-		if (!svc_getargs(xprt, xdr_pmap, &reg))
+		if (!svc_getargs(xprt, xdr_pmap, (caddr_t)&reg))
 			svcerr_decode(xprt);
 		else {
+			/* reject non-local requests, protect priv. ports */
+			if (!check_setunset(svc_getcaller(xprt),
+			    rqstp->rq_proc, reg.pm_prog, reg.pm_port)) {
+				ans = 0;
+				goto done;
+			}
 			/*
 			 * check to see if already used
 			 * find_service returns a hit even if
@@ -342,7 +372,7 @@
 					goto done;
 				}
 			} else {
-				/* 
+				/*
 				 * add to END of list
 				 */
 				pml = (struct pmaplist *)
@@ -371,10 +401,14 @@
 		/*
 		 * Remove a program,version to port mapping.
 		 */
-		if (!svc_getargs(xprt, xdr_pmap, &reg))
+		if (!svc_getargs(xprt, xdr_pmap, (caddr_t)&reg))
 			svcerr_decode(xprt);
 		else {
 			ans = 0;
+			/* reject non-local requests */
+			if (!check_setunset(svc_getcaller(xprt),
+			    rqstp->rq_proc, reg.pm_prog, (u_long) 0))
+				goto done;
 			for (prevpml = NULL, pml = pmaplist; pml != NULL; ) {
 				if ((pml->pml_map.pm_prog != reg.pm_prog) ||
 					(pml->pml_map.pm_vers != reg.pm_vers)) {
@@ -384,6 +418,14 @@
 					continue;
 				}
 				/* found it; pml moves forward, prevpml stays */
+				/* privileged port check */
+				if (!check_privileged_port(svc_getcaller(xprt),
+				    rqstp->rq_proc,
+				    reg.pm_prog,
+				    pml->pml_map.pm_port)) {
+					ans = 0;
+					break;
+				}
 				ans = 1;
 				t = (caddr_t)pml;
 				pml = pml->pml_next;
@@ -405,9 +447,16 @@
 		/*
 		 * Lookup the mapping for a program,version and return its port
 		 */
-		if (!svc_getargs(xprt, xdr_pmap, &reg))
+		if (!svc_getargs(xprt, xdr_pmap, (caddr_t)&reg))
 			svcerr_decode(xprt);
 		else {
+			/* remote host authorization check */
+			if (!check_default(svc_getcaller(xprt),
+			    rqstp->rq_proc,
+			    reg.pm_prog)) {
+				ans = 0;
+				goto done;
+			}
 			fnd = find_service(reg.pm_prog, reg.pm_vers, reg.pm_prot);
 			if (fnd)
 				port = fnd->pml_map.pm_port;
@@ -428,8 +477,16 @@
 		if (!svc_getargs(xprt, xdr_void, NULL))
 			svcerr_decode(xprt);
 		else {
+			/* remote host authorization check */
+			struct pmaplist *p;
+			if (!check_default(svc_getcaller(xprt),
+			    rqstp->rq_proc, (u_long) 0)) {
+				p = 0;	/* send empty list */
+			} else {
+				p = pmaplist;
+			}
 			if ((!svc_sendreply(xprt, xdr_pmaplist,
-			    (caddr_t)&pmaplist)) && debugging) {
+			    (caddr_t)&p)) && debugging) {
 				(void) fprintf(stderr, "svc_sendreply\n");
 				abort();
 			}
@@ -441,13 +498,15 @@
 		 * Calls a procedure on the local machine.  If the requested
 		 * procedure is not registered this procedure does not return
 		 * error information!!
-		 * This procedure is only supported on rpc/udp and calls via 
+		 * This procedure is only supported on rpc/udp and calls via
 		 * rpc/udp.  It passes null authentication parameters.
 		 */
 		callit(rqstp, xprt);
 		break;
 
 	default:
+		/* remote host authorization check */
+		check_default(svc_getcaller(xprt), rqstp->rq_proc, (u_long) 0);
 		svcerr_noproc(xprt);
 		break;
 	}
@@ -460,7 +519,7 @@
 #define ARGSIZE 9000
 
 struct encap_parms {
-	u_long arglen;
+	u_int arglen;
 	char *args;
 };
 
@@ -469,7 +528,8 @@
 	XDR *xdrs;
 	struct encap_parms *epp;
 {
-	return (xdr_bytes(xdrs, &(epp->args), (int *)&(epp->arglen), ARGSIZE));
+
+	return (xdr_bytes(xdrs, &(epp->args), &(epp->arglen), ARGSIZE));
 }
 
 struct rmtcallargs {
@@ -482,8 +542,8 @@
 
 static bool_t
 xdr_rmtcall_args(xdrs, cap)
-	register XDR *xdrs;
-	register struct rmtcallargs *cap;
+	XDR *xdrs;
+	struct rmtcallargs *cap;
 {
 
 	/* does not get a port number */
@@ -497,8 +557,8 @@
 
 static bool_t
 xdr_rmtcall_result(xdrs, cap)
-	register XDR *xdrs;
-	register struct rmtcallargs *cap;
+	XDR *xdrs;
+	struct rmtcallargs *cap;
 {
 	if (xdr_u_long(xdrs, &(cap->rmt_port)))
 		return (xdr_encap_parms(xdrs, &(cap->rmt_args)));
@@ -514,7 +574,6 @@
 	XDR *xdrs;
 	struct rmtcallargs *cap;
 {
-
 	return (xdr_opaque(xdrs, cap->rmt_args.args, cap->rmt_args.arglen));
 }
 
@@ -524,7 +583,7 @@
  */
 static bool_t
 xdr_len_opaque_parms(xdrs, cap)
-	register XDR *xdrs;
+	XDR *xdrs;
 	struct rmtcallargs *cap;
 {
 	register u_int beginpos, lowpos, highpos, currpos, pos;
@@ -552,7 +611,7 @@
  * a machine should shut-up instead of complain, less the requestor be
  * overrun with complaints at the expense of not hearing a valid reply ...
  *
- * This now forks so that the program & process that it calls can call 
+ * This now forks so that the program & process that it calls can call
  * back to the portmapper.
  */
 static void
@@ -578,7 +637,11 @@
 	timeout.tv_sec = 5;
 	timeout.tv_usec = 0;
 	a.rmt_args.args = buf;
-	if (!svc_getargs(xprt, xdr_rmtcall_args, &a))
+	if (!svc_getargs(xprt, xdr_rmtcall_args, (caddr_t)&a))
+		return;
+	/* host and service access control */
+	if (!check_callit(svc_getcaller(xprt),
+	    rqstp->rq_proc, a.rmt_prog, a.rmt_proc))
 		return;
 
 	/*
@@ -654,8 +717,13 @@
 	exit(0);
 }
 
-void
-reap()
+static void
+reap(sig)
+	int sig;
 {
+	int save_errno;
+
+	save_errno = errno;
 	while (wait3((int *)NULL, WNOHANG, (struct rusage *)NULL) > 0);
+	errno = save_errno;
 }
