*** portmap.c.bsd	Sun May  3 22:39:52 1992
--- portmap.c	Sun Nov 21 16:22:31 1993
***************
*** 83,99 ****
  #include <rpc/rpc.h>
  #include <rpc/pmap_prot.h>
  #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
  #include <syslog.h>
- #include <unistd.h>
  #include <netdb.h>
  #include <sys/socket.h>
  #include <sys/ioctl.h>
  #include <sys/wait.h>
  #include <sys/signal.h>
  #include <sys/resource.h>
  
  void reg_service();
  void reap();
  static void callit();
--- 83,115 ----
  #include <rpc/rpc.h>
  #include <rpc/pmap_prot.h>
  #include <stdio.h>
  #include <syslog.h>
  #include <netdb.h>
  #include <sys/socket.h>
  #include <sys/ioctl.h>
  #include <sys/wait.h>
  #include <sys/signal.h>
+ #include <sys/time.h>
  #include <sys/resource.h>
+ #ifdef SYSV40
+ #include <netinet/in.h>
+ #endif
  
+ extern char *strerror();
+ extern char *malloc();
+ 
+ #ifndef LOG_PERROR
+ #define LOG_PERROR 0
+ #endif
+ 
+ #ifndef LOG_DAEMON
+ #define LOG_DAEMON 0
+ #endif
+ 
+ #ifndef svc_getcaller		/* SYSV4 */
+ #  define svc_getcaller svc_getrpccaller
+ #endif
+ 
  void reg_service();
  void reap();
  static void callit();
***************
*** 101,106 ****
--- 117,124 ----
  int debugging = 0;
  extern int errno;
  
+ #include "pmap_check.h"
+ 
  main(argc, argv)
  	int argc;
  	char **argv;
***************
*** 111,117 ****
  	int len = sizeof(struct sockaddr_in);
  	register struct pmaplist *pml;
  
! 	while ((c = getopt(argc, argv, "d")) != EOF) {
  		switch (c) {
  
  		case 'd':
--- 129,135 ----
  	int len = sizeof(struct sockaddr_in);
  	register struct pmaplist *pml;
  
! 	while ((c = getopt(argc, argv, "dv")) != EOF) {
  		switch (c) {
  
  		case 'd':
***************
*** 118,125 ****
  			debugging = 1;
  			break;
  
  		default:
! 			(void) fprintf(stderr, "usage: %s [-d]\n", argv[0]);
  			exit(1);
  		}
  	}
--- 136,149 ----
  			debugging = 1;
  			break;
  
+ 		case 'v':
+ 			verboselog = 1;
+ 			break;
+ 
  		default:
! 			(void) fprintf(stderr, "usage: %s [-dv]\n", argv[0]);
! 			(void) fprintf(stderr, "-d: debugging mode\n");
! 			(void) fprintf(stderr, "-v: verbose logging\n");
  			exit(1);
  		}
  	}
***************
*** 129,136 ****
  		exit(1);
  	}
  
  	openlog("portmap", debugging ? LOG_PID | LOG_PERROR : LOG_PID,
! 	    LOG_DAEMON);
  
  	if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
  		syslog(LOG_ERR, "cannot create udp socket: %m");
--- 153,164 ----
  		exit(1);
  	}
  
+ #ifdef LOG_MAIL
  	openlog("portmap", debugging ? LOG_PID | LOG_PERROR : LOG_PID,
! 	    FACILITY);
! #else
! 	openlog("portmap", debugging ? LOG_PID | LOG_PERROR : LOG_PID);
! #endif
  
  	if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
  		syslog(LOG_ERR, "cannot create udp socket: %m");
***************
*** 182,188 ****
--- 210,222 ----
  
  	(void)svc_register(xprt, PMAPPROG, PMAPVERS, reg_service, FALSE);
  
+ 	/* additional initializations */
+ 	check_startup();
+ #ifdef IGNORE_SIGCHLD			/* Lionel Cons <cons@dxcern.cern.ch> */
+ 	(void)signal(SIGCHLD, SIG_IGN);
+ #else
  	(void)signal(SIGCHLD, reap);
+ #endif
  	svc_run();
  	syslog(LOG_ERR, "run_svc returned unexpectedly");
  	abort();
***************
*** 230,235 ****
--- 264,276 ----
  	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");
  	switch (rqstp->rq_proc) {
***************
*** 238,243 ****
--- 279,286 ----
  		/*
  		 * 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();
  		}
***************
*** 250,255 ****
--- 293,304 ----
  		if (!svc_getargs(xprt, xdr_pmap, &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
***************
*** 299,304 ****
--- 348,357 ----
  			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)) {
***************
*** 308,313 ****
--- 361,374 ----
  					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;
***************
*** 332,337 ****
--- 393,405 ----
  		if (!svc_getargs(xprt, xdr_pmap, &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;
***************
*** 352,359 ****
  		if (!svc_getargs(xprt, xdr_void, NULL))
  			svcerr_decode(xprt);
  		else {
  			if ((!svc_sendreply(xprt, xdr_pmaplist,
! 			    (caddr_t)&pmaplist)) && debugging) {
  				(void) fprintf(stderr, "svc_sendreply\n");
  				abort();
  			}
--- 420,435 ----
  		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)&p)) && debugging) {
  				(void) fprintf(stderr, "svc_sendreply\n");
  				abort();
  			}
***************
*** 372,377 ****
--- 448,455 ----
  		break;
  
  	default:
+ 		/* remote host authorization check */
+ 		check_default(svc_getcaller(xprt), rqstp->rq_proc, (u_long) 0);
  		svcerr_noproc(xprt);
  		break;
  	}
***************
*** 499,504 ****
--- 577,586 ----
  	timeout.tv_usec = 0;
  	a.rmt_args.args = buf;
  	if (!svc_getargs(xprt, xdr_rmtcall_args, &a))
+ 		return;
+ 	/* host and service access control */
+ 	if (!check_callit(svc_getcaller(xprt), 
+ 	    rqstp->rq_proc, a.rmt_prog, a.rmt_proc))
  		return;
  	if ((pml = find_service(a.rmt_prog, a.rmt_vers,
  	    (u_long)IPPROTO_UDP)) == NULL)
*** daemon.c.bsd	Sun May  3 22:45:10 1992
--- daemon.c	Thu Jun 11 22:53:12 1992
***************
*** 35,44 ****
  static char sccsid[] = "@(#)daemon.c	5.3 (Berkeley) 12/28/90";
  #endif /* LIBC_SCCS and not lint */
  
! #include <sys/fcntl.h>
! #include <unistd.h>
! #include <paths.h>
  
  daemon(nochdir, noclose)
  	int nochdir, noclose;
  {
--- 35,50 ----
  static char sccsid[] = "@(#)daemon.c	5.3 (Berkeley) 12/28/90";
  #endif /* LIBC_SCCS and not lint */
  
! #include <fcntl.h>
  
+ /* From unistd.h */
+ #define STDIN_FILENO	0
+ #define STDOUT_FILENO	1
+ #define STDERR_FILENO	2
+ 
+ /* From paths.h */
+ #define _PATH_DEVNULL	"/dev/null"
+ 
  daemon(nochdir, noclose)
  	int nochdir, noclose;
  {
***************
*** 62,65 ****
--- 68,72 ----
  				(void) close(devnull);
  		}
  	}
+ 	return(0);
  }
