Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 23 Nov 1996 05:31:36 +0100 (MET)
From:      Tor Egge <Tor.Egge@idt.ntnu.no>
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   bin/2090: clients may bind to FreeBSD ypserv refusing to serve them
Message-ID:  <199611230431.FAA16781@ikke.idt.unit.no>
Resent-Message-ID: <199611230440.UAA08540@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         2090
>Category:       bin
>Synopsis:       clients may bind to FreeBSD ypserv refusing to serve them
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Nov 22 20:40:09 PST 1996
>Last-Modified:
>Originator:     Tor Egge
>Organization:
Norwegian University of Science and Technology, Trondheim, Norway
>Release:        FreeBSD 3.0-CURRENT i386
>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;

>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199611230431.FAA16781>