From Tor.Egge@idt.ntnu.no  Fri Nov 22 20:31:43 1996
Received: from pat.idt.unit.no (pat.idt.unit.no [129.241.103.5])
          by freefall.freebsd.org (8.7.5/8.7.3) with ESMTP id UAA08292
          for <FreeBSD-gnats-submit@freebsd.org>; Fri, 22 Nov 1996 20:31:40 -0800 (PST)
Received: from ikke.idt.unit.no (ikke.idt.unit.no [129.241.111.65]) by pat.idt.unit.no (8.7.5/8.7.3) with ESMTP id FAA28191 for <FreeBSD-gnats-submit@freebsd.org>; Sat, 23 Nov 1996 05:31:36 +0100 (MET)
Received: (from tegge@localhost) by ikke.idt.unit.no (8.8.3/8.7.3) id FAA16781; Sat, 23 Nov 1996 05:31:36 +0100 (MET)
Message-Id: <199611230431.FAA16781@ikke.idt.unit.no>
Date: Sat, 23 Nov 1996 05:31:36 +0100 (MET)
From: Tor Egge <Tor.Egge@idt.ntnu.no>
Reply-To: Tor.Egge@idt.ntnu.no
To: FreeBSD-gnats-submit@freebsd.org
Subject: clients may bind to FreeBSD ypserv refusing to serve them
X-Send-Pr-Version: 3.2

>Number:         2090
>Category:       bin
>Synopsis:       [patch] [nis] clients may bind to FreeBSD ypserv refusing to serve them
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Nov 22 20:40:09 PST 1996
>Closed-Date:    
>Last-Modified:  Mon May 07 04:03:58 UTC 2012
>Originator:     Tor Egge
>Release:        FreeBSD 3.0-CURRENT i386
>Organization:
Norwegian University of Science and Technology, Trondheim, Norway
>Environment:

FreeBSD ikke.idt.unit.no 3.0-CURRENT FreeBSD 3.0-CURRENT #0: Wed Nov 20 18:14:02 MET 1996     root@ikke.idt.unit.no:/usr/src/sys-UP/compile/TEGGE  i386

>Description:

	NetBSD/FreeBSD/SunOS 4 machines uses broadcast via portmapper
	to find an yp server that serves the relevant domain. Since
	the request is forwarded by the local portmapper on the 
	FreeBSD machine, the securenets mechanism is inactive, and
	an positive acknowledge is sent back to the client via the
	portmapper. The client may be bound to an yp server
	that refuses to handle requests from the client. 

>How-To-Repeat:

	Have a FreeBSD machine that runs a local ypserv due to 
	performance reasons. Configure ypserv to run without DNS forwarding, 
	since it is expensive (fork()).	Configure it to only serve 
	local host, to avoid SunOS 4 machines needing DNS forwarding 
	binding to it. Observe that nearby NetBSD/FreeBSD/SunOS 4 machines 
	may bind to the FreeBSD machine, causing problems 
	(e.g. users not being able to login).

>Fix:

	Real Fix:  

		- Add code to portmap that performs the needed 
		  securenets checking, without logging
		  if the request came from the local subnet.

		- Don't use a privileged port when forwarding a query.

		- Don't fork for each forward. It is expensive in
		  an environment with many yp clients present.
		  Use async rpc handling instead.
	      
		- Don't let the ypserv process fork for gethostbyname()
	          lookups. Use async dns lookups instead.
        
	Quick Workaround (which may cause some irrelevant log messages):
Index: Makefile
===================================================================
RCS file: /export/akg1/cvs/src/usr.sbin/portmap/Makefile,v
retrieving revision 1.4
diff -c -r1.4 Makefile
*** Makefile	1994/09/29 09:36:16	1.4
--- Makefile	1996/11/23 03:47:43
***************
*** 2,11 ****
  
  PROG=	portmap
  MAN8=	portmap.8
! SRCS=	portmap.c from_local.c pmap_check.c
  SUBDIR= pmap_set pmap_dump
  
  # -DHOSTS_ACCESS (requires tcpwrapper libraries)
! CFLAGS+=-DCHECK_PORT
  
  .include <bsd.prog.mk>
--- 2,12 ----
  
  PROG=	portmap
  MAN8=	portmap.8
! SRCS=	portmap.c from_local.c pmap_check.c yp_access.c yp_error.c
  SUBDIR= pmap_set pmap_dump
+ .PATH:  ${.CURDIR}/../ypserv
  
  # -DHOSTS_ACCESS (requires tcpwrapper libraries)
! CFLAGS+=-DCHECK_PORT -I${.CURDIR}/../ypserv
  
  .include <bsd.prog.mk>
Index: portmap.c
===================================================================
RCS file: /export/akg1/cvs/src/usr.sbin/portmap/portmap.c,v
retrieving revision 1.4
diff -c -r1.4 portmap.c
*** portmap.c	1996/02/05 15:35:41	1.4
--- portmap.c	1996/11/23 04:01:09
***************
*** 95,100 ****
--- 95,101 ----
  #include <sys/resource.h>
  
  #include "pmap_check.h"
+ #include "yp_extern.h"
  
  void reg_service();
  void reap();
***************
*** 103,108 ****
--- 104,114 ----
  int debugging = 0;
  extern int errno;
  
+ char *yp_dir = _PATH_YP;
+ int debug = 0;
+ char *progname = "portmap";
+ int _rpcpmstart;		/* Started by a port monitor ? */
+ 
  main(argc, argv)
  	int argc;
  	char **argv;
***************
*** 113,136 ****
  	int len = sizeof(struct sockaddr_in);
  	register struct pmaplist *pml;
  
! 	while ((c = getopt(argc, argv, "dv")) != EOF) {
  		switch (c) {
  
  		case 'd':
  			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);
  		}
  	}
  
  	if (!debugging && daemon(0, 0)) {
  		(void) fprintf(stderr, "portmap: fork: %s", strerror(errno));
--- 119,148 ----
  	int len = sizeof(struct sockaddr_in);
  	register struct pmaplist *pml;
  
! 	while ((c = getopt(argc, argv, "dvp:")) != EOF) {
  		switch (c) {
  
  		case 'd':
  			debugging = 1;
+ 			debug = 1;
  			break;
  
  		case 'v':
  			verboselog = 1;
  			break;
+ 		case 'p':
+ 		        yp_dir = optarg;
+ 			break;
  
  		default:
! 			(void) fprintf(stderr, "usage: %s [-dv] [-p path]\n", argv[0]);
  			(void) fprintf(stderr, "-d: debugging mode\n");
  			(void) fprintf(stderr, "-v: verbose logging\n");
+ 			(void) fprintf(stderr, "-p: specify NIS directory\n");
  			exit(1);
  		}
  	}
+ 	load_securenets();
  
  	if (!debugging && daemon(0, 0)) {
  		(void) fprintf(stderr, "portmap: fork: %s", strerror(errno));
***************
*** 524,529 ****
--- 536,546 ----
  	return (xdr_opaque_parms(xdrs, cap));
  }
  
+ /* Explicit #defines in case the include files are not available. */
+ 
+ #define YPPROG          ((u_long) 100004)
+ #define YPPROC_DOMAIN_NONACK ((u_long) 2)
+ 
  /*
   * Call a remote procedure service
   * This procedure is very quiet when things go wrong.
***************
*** 558,563 ****
--- 575,588 ----
  	if (!check_callit(svc_getcaller(xprt),
  	    rqstp->rq_proc, a.rmt_prog, a.rmt_proc))
  		return;
+ 
+ 	/* Avoid lying to naive ypbind implementations */
+ 	if (a.rmt_prog==YPPROG && a.rmt_proc == YPPROC_DOMAIN_NONACK &&
+ 	    yp_access(NULL, (struct svc_req *)rqstp)) {
+ 	  return;
+ 	}
+ 
+ 
  	if ((pml = find_service(a.rmt_prog, a.rmt_vers,
  	    (u_long)IPPROTO_UDP)) == NULL)
  		return;

>Release-Note:
>Audit-Trail:

From: Peter Wemm <peter@spinner.DIALix.COM>
To: Bill Paul <wpaul@skynet.ctr.columbia.edu>
Cc: Tor.Egge@idt.ntnu.no, freebsd-gnats-submit@freebsd.org
Subject: Re: bin/2090: clients may bind to FreeBSD ypserv refusing to 
 serve them
Date: Sat, 23 Nov 1996 14:22:13 +0800

 Bill Paul wrote:
 > > 		- Don't let the ypserv process fork for gethostbyname()
 > > 	          lookups. Use async dns lookups instead.
 > 
 > This has been on my mind for a while, but it's fallen victim to a
 > severe lack of round tuits. One reason I've been putting it off is
 > that doing this 'correctly' would probably mean bolting some of the
 > BIND code directly onto ypserv. This would lead to yet another upgrade 
 > headache when new BIND versions are released.
 
 Another option is to fork() once and have the parent and child communicate 
 over a pipe.  This is a pretty common approach, especially for things like 
 WWW caches (eg: squid, harvest cached), MUD game drivers, etc.
 
 FWIW, there's an async DNS resolver in the later versions of the irc 
 servers, but I seem to recall that it's been contaminated with GPL code.
 
 Cheers,
 -Peter
 
 
State-Changed-From-To: open->suspended 
State-Changed-By: phk 
State-Changed-When: Mon May 25 01:00:12 PDT 1998 
State-Changed-Why:  
Awaiting committer 
State-Changed-From-To: suspended->open 
State-Changed-By: eadler 
State-Changed-When: Mon May 7 04:03:57 UTC 2012 
State-Changed-Why:  
we don't use suspeended for this state 

http://www.freebsd.org/cgi/query-pr.cgi?pr=2090 
>Unformatted:
