From owner-freebsd-bugs Fri Nov 22 20:40:22 1996 Return-Path: owner-bugs Received: (from root@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id UAA08563 for bugs-outgoing; Fri, 22 Nov 1996 20:40:22 -0800 (PST) Received: (from gnats@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id UAA08540; Fri, 22 Nov 1996 20:40:17 -0800 (PST) Resent-Date: Fri, 22 Nov 1996 20:40:17 -0800 (PST) Resent-Message-Id: <199611230440.UAA08540@freefall.freebsd.org> Resent-From: gnats (GNATS Management) Resent-To: freebsd-bugs Resent-Reply-To: FreeBSD-gnats@freefall.FreeBSD.org, Tor.Egge@idt.ntnu.no 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 ; 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 ; 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 Reply-To: Tor.Egge@idt.ntnu.no To: FreeBSD-gnats-submit@freebsd.org X-Send-Pr-Version: 3.2 Subject: bin/2090: clients may bind to FreeBSD ypserv refusing to serve them Sender: owner-bugs@freebsd.org X-Loop: FreeBSD.org Precedence: bulk >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 --- 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 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 #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: