From 42d798d58915cb0463f74e10e32a2b28daabecd9 Mon Sep 17 00:00:00 2001 From: pst Date: Thu, 29 Sep 1994 09:32:22 +0000 Subject: Portmap 3.0 from win.tue.nl --- usr.sbin/portmap/Makefile | 8 +- usr.sbin/portmap/from_local.c | 147 +++++++++++++++++++ usr.sbin/portmap/pmap_check.c | 251 +++++++++++++++++++++++++++++++++ usr.sbin/portmap/pmap_check.h | 11 ++ usr.sbin/portmap/pmap_dump/Makefile | 7 + usr.sbin/portmap/pmap_dump/pmap_dump.c | 63 +++++++++ usr.sbin/portmap/pmap_set/Makefile | 7 + usr.sbin/portmap/pmap_set/pmap_set.c | 70 +++++++++ usr.sbin/portmap/portmap.8 | 2 + usr.sbin/portmap/portmap.c | 66 ++++++++- 10 files changed, 625 insertions(+), 7 deletions(-) create mode 100644 usr.sbin/portmap/from_local.c create mode 100644 usr.sbin/portmap/pmap_check.c create mode 100644 usr.sbin/portmap/pmap_check.h create mode 100644 usr.sbin/portmap/pmap_dump/Makefile create mode 100644 usr.sbin/portmap/pmap_dump/pmap_dump.c create mode 100644 usr.sbin/portmap/pmap_set/Makefile create mode 100644 usr.sbin/portmap/pmap_set/pmap_set.c (limited to 'usr.sbin') diff --git a/usr.sbin/portmap/Makefile b/usr.sbin/portmap/Makefile index 244a192..ded9846 100644 --- a/usr.sbin/portmap/Makefile +++ b/usr.sbin/portmap/Makefile @@ -1,8 +1,10 @@ # @(#)Makefile 8.1 (Berkeley) 6/6/93 PROG= portmap -DPADD= ${LIBRPC} -LDADD= -lrpc -MAN8= portmap.0 +MAN8= portmap.8 +SRCS= portmap.c from_local.c pmap_check.c +SUBDIR= pmap_set pmap_dump + +CFLAGS+=-DCHECK_PORT # -DHOSTS_ACCESS (requires tcpwrapper libraries) .include diff --git a/usr.sbin/portmap/from_local.c b/usr.sbin/portmap/from_local.c new file mode 100644 index 0000000..dc5583a --- /dev/null +++ b/usr.sbin/portmap/from_local.c @@ -0,0 +1,147 @@ + /* + * Check if an address belongs to the local system. Adapted from: + * + * @(#)pmap_svc.c 1.32 91/03/11 Copyright 1984,1990 Sun Microsystems, Inc. + * @(#)get_myaddress.c 2.1 88/07/29 4.0 RPCSRC. + */ + +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * 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 or with the express written consent of + * Sun Microsystems, Inc. + * + * 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 + */ + +#ifndef lint +static char sccsid[] = "@(#) from_local.c 1.2 93/11/16 21:50:02"; +#endif + +#ifdef TEST +#undef perror +#endif + +#include +#include +#include +#include +#include +#include +#include + +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 +#endif + +/* How many interfaces could there be on a computer? */ + +#define MAX_LOCAL 16 +static int num_local = -1; +static struct in_addr addrs[MAX_LOCAL]; + +/* find_local - find all IP addresses for this host */ + +find_local() +{ + struct ifconf ifc; + struct ifreq ifreq; + struct ifreq *ifr; + struct ifreq *the_end; + int sock; + char buf[MAX_LOCAL * sizeof(struct ifreq)]; + + /* Get list of network interfaces. */ + + if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { + perror("socket"); + return (0); + } + ifc.ifc_len = sizeof(buf); + ifc.ifc_buf = buf; + if (ioctl(sock, SIOCGIFCONF, (char *) &ifc) < 0) { + perror("SIOCGIFCONF"); + (void) close(sock); + return (0); + } + /* Get IP address of each active IP network interface. */ + + the_end = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len); + num_local = 0; + for (ifr = ifc.ifc_req; ifr < the_end; ifr++) { + if (ifr->ifr_addr.sa_family == AF_INET) { /* IP net interface */ + ifreq = *ifr; + if (ioctl(sock, SIOCGIFFLAGS, (char *) &ifreq) < 0) { + perror("SIOCGIFFLAGS"); + } else if (ifreq.ifr_flags & IFF_UP) { /* active interface */ + if (ioctl(sock, SIOCGIFADDR, (char *) &ifreq) < 0) { + perror("SIOCGIFADDR"); + } else { + addrs[num_local++] = ((struct sockaddr_in *) + & ifreq.ifr_addr)->sin_addr; + } + } + } + if (num_local >= MAX_LOCAL) + break; + /* Support for variable-length addresses. */ + ifr = (struct ifreq *) ((caddr_t) ifr + + ifr->ifr_addr.sa_len - sizeof(struct sockaddr)); + } + (void) close(sock); + return (num_local); +} + +/* from_local - determine whether request comes from the local system */ + +from_local(addr) +struct sockaddr_in *addr; +{ + int i; + + if (num_local == -1 && find_local() == 0) + syslog(LOG_ERR, "cannot find any active local network interfaces"); + + for (i = 0; i < num_local; i++) { + if (memcmp((char *) &(addr->sin_addr), (char *) &(addrs[i]), + sizeof(struct in_addr)) == 0) + return (TRUE); + } + return (FALSE); +} + +#ifdef TEST + +main() +{ + char *inet_ntoa(); + int i; + + find_local(); + for (i = 0; i < num_local; i++) + printf("%s\n", inet_ntoa(addrs[i])); +} + +#endif diff --git a/usr.sbin/portmap/pmap_check.c b/usr.sbin/portmap/pmap_check.c new file mode 100644 index 0000000..1d1ed61 --- /dev/null +++ b/usr.sbin/portmap/pmap_check.c @@ -0,0 +1,251 @@ + /* + * pmap_check - additional portmap security. + * + * Always reject non-local requests to update the portmapper tables. + * + * Refuse to forward mount requests to the nfs mount daemon. Otherwise, the + * requests would appear to come from the local system, and nfs export + * restrictions could be bypassed. + * + * Refuse to forward requests to the nfsd process. + * + * Refuse to forward requests to NIS (YP) daemons; The only exception is the + * YPPROC_DOMAIN_NONACK broadcast rpc call that is used to establish initial + * contact with the NIS server. + * + * Always allocate an unprivileged port when forwarding a request. + * + * If compiled with -DCHECK_PORT, require that requests to register or + * unregister a privileged port come from a privileged port. This makes it + * more difficult to replace a critical service by a trojan. + * + * If compiled with -DHOSTS_ACCESS, reject requests from hosts that are not + * authorized by the /etc/hosts.{allow,deny} files. The local system is + * always treated as an authorized host. The access control tables are never + * consulted for requests from the local system, and are always consulted + * for requests from other hosts. Access control is based on IP addresses + * only; attempts to map an address to a host name might cause the + * portmapper to hang. + * + * Author: Wietse Venema (wietse@wzv.win.tue.nl), dept. of Mathematics and + * Computing Science, Eindhoven University of Technology, The Netherlands. + */ + +#ifndef lint +static char sccsid[] = "@(#) pmap_check.c 1.6 93/11/21 20:58:59"; +#endif + +#include +#include +#include +#include +#include + +extern char *inet_ntoa(); + +#include "pmap_check.h" + +/* Explicit #defines in case the include files are not available. */ + +#define NFSPROG ((u_long) 100003) +#define MOUNTPROG ((u_long) 100005) +#define YPXPROG ((u_long) 100069) +#define YPPROG ((u_long) 100004) +#define YPPROC_DOMAIN_NONACK ((u_long) 2) +#define MOUNTPROC_MNT ((u_long) 1) + +static void logit(); +static void toggle_verboselog(); +int verboselog = 0; +int allow_severity = LOG_INFO; +int deny_severity = LOG_WARNING; + +/* A handful of macros for "readability". */ + +#define good_client(a) hosts_ctl("portmap", "", inet_ntoa(a->sin_addr), "") + +#define legal_port(a,p) \ + (ntohs((a)->sin_port) < IPPORT_RESERVED || (p) >= IPPORT_RESERVED) + +#define log_bad_port(addr, proc, prog) \ + logit(deny_severity, addr, proc, prog, ": request from unprivileged port") + +#define log_bad_host(addr, proc, prog) \ + logit(deny_severity, addr, proc, prog, ": request from unauthorized host") + +#define log_bad_owner(addr, proc, prog) \ + logit(deny_severity, addr, proc, prog, ": request from non-local host") + +#define log_no_forward(addr, proc, prog) \ + logit(deny_severity, addr, proc, prog, ": request not forwarded") + +#define log_client(addr, proc, prog) \ + logit(allow_severity, addr, proc, prog, "") + +/* check_startup - additional startup code */ + +void check_startup() +{ + + /* + * Give up root privileges so that we can never allocate a privileged + * port when forwarding an rpc request. + */ + if (setuid(1) == -1) { + syslog(LOG_ERR, "setuid(1) failed: %m"); + exit(1); + } + (void) signal(SIGINT, toggle_verboselog); +} + +/* check_default - additional checks for NULL, DUMP, GETPORT and unknown */ + +check_default(addr, proc, prog) +struct sockaddr_in *addr; +u_long proc; +u_long prog; +{ +#ifdef HOSTS_ACCESS + if (!(from_local(addr) || good_client(addr))) { + log_bad_host(addr, proc, prog); + return (FALSE); + } +#endif + if (verboselog) + log_client(addr, proc, prog); + return (TRUE); +} + +/* check_privileged_port - additional checks for privileged-port updates */ + +check_privileged_port(addr, proc, prog, port) +struct sockaddr_in *addr; +u_long proc; +u_long prog; +u_long port; +{ +#ifdef CHECK_PORT + if (!legal_port(addr, port)) { + log_bad_port(addr, proc, prog); + return (FALSE); + } +#endif + return (TRUE); +} + +/* check_setunset - additional checks for update requests */ + +check_setunset(addr, proc, prog, port) +struct sockaddr_in *addr; +u_long proc; +u_long prog; +u_long port; +{ + if (!from_local(addr)) { +#ifdef HOSTS_ACCESS + (void) good_client(addr); /* because of side effects */ +#endif + log_bad_owner(addr, proc, prog); + return (FALSE); + } + if (port && !check_privileged_port(addr, proc, prog, port)) + return (FALSE); + if (verboselog) + log_client(addr, proc, prog); + return (TRUE); +} + +/* check_callit - additional checks for forwarded requests */ + +check_callit(addr, proc, prog, aproc) +struct sockaddr_in *addr; +u_long proc; +u_long prog; +u_long aproc; +{ +#ifdef HOSTS_ACCESS + if (!(from_local(addr) || good_client(addr))) { + log_bad_host(addr, proc, prog); + return (FALSE); + } +#endif + if (prog == PMAPPROG || prog == NFSPROG || prog == YPXPROG || + (prog == MOUNTPROG && aproc == MOUNTPROC_MNT) || + (prog == YPPROG && aproc != YPPROC_DOMAIN_NONACK)) { + log_no_forward(addr, proc, prog); + return (FALSE); + } + if (verboselog) + log_client(addr, proc, prog); + return (TRUE); +} + +/* toggle_verboselog - toggle verbose logging flag */ + +static void toggle_verboselog(sig) +int sig; +{ + (void) signal(sig, toggle_verboselog); + verboselog = !verboselog; +} + +/* logit - report events of interest via the syslog daemon */ + +static void logit(severity, addr, procnum, prognum, text) +int severity; +struct sockaddr_in *addr; +u_long procnum; +u_long prognum; +char *text; +{ + char *procname; + char procbuf[4 * sizeof(u_long)]; + char *progname; + char progbuf[4 * sizeof(u_long)]; + struct rpcent *rpc; + struct proc_map { + u_long code; + char *proc; + }; + struct proc_map *procp; + static struct proc_map procmap[] = { + PMAPPROC_CALLIT, "callit", + PMAPPROC_DUMP, "dump", + PMAPPROC_GETPORT, "getport", + PMAPPROC_NULL, "null", + PMAPPROC_SET, "set", + PMAPPROC_UNSET, "unset", + 0, 0, + }; + + /* + * Fork off a process or the portmap daemon might hang while + * getrpcbynumber() or syslog() does its thing. + */ + + if (fork() == 0) { + + /* Try to map program number to name. */ + + if (prognum == 0) { + progname = ""; + } else if (rpc = getrpcbynumber((int) prognum)) { + progname = rpc->r_name; + } else { + sprintf(progname = progbuf, "%lu", prognum); + } + + /* Try to map procedure number to name. */ + + for (procp = procmap; procp->proc && procp->code != procnum; procp++) + /* void */ ; + if ((procname = procp->proc) == 0) + sprintf(procname = procbuf, "%lu", (u_long) procnum); + + /* Write syslog record. */ + + syslog(severity, "connect from %s to %s(%s)%s", + inet_ntoa(addr->sin_addr), procname, progname, text); + exit(0); + } +} diff --git a/usr.sbin/portmap/pmap_check.h b/usr.sbin/portmap/pmap_check.h new file mode 100644 index 0000000..2c240df --- /dev/null +++ b/usr.sbin/portmap/pmap_check.h @@ -0,0 +1,11 @@ +/* @(#) pmap_check.h 1.3 93/11/21 16:18:53 */ + +extern int from_local(); +extern void check_startup(); +extern int check_default(); +extern int check_setunset(); +extern int check_privileged_port(); +extern int check_callit(); +extern int verboselog; +extern int allow_severity; +extern int deny_severity; diff --git a/usr.sbin/portmap/pmap_dump/Makefile b/usr.sbin/portmap/pmap_dump/Makefile new file mode 100644 index 0000000..0064f28 --- /dev/null +++ b/usr.sbin/portmap/pmap_dump/Makefile @@ -0,0 +1,7 @@ +# @(#)Makefile 8.1 (Berkeley) 6/6/93 + +PROG= pmap_dump +NOMAN= noman + +.include "${.CURDIR}/../../Makefile.inc" +.include diff --git a/usr.sbin/portmap/pmap_dump/pmap_dump.c b/usr.sbin/portmap/pmap_dump/pmap_dump.c new file mode 100644 index 0000000..2bddcbb --- /dev/null +++ b/usr.sbin/portmap/pmap_dump/pmap_dump.c @@ -0,0 +1,63 @@ + /* + * pmap_dump - dump portmapper table in format readable by pmap_set + * + * Author: Wietse Venema (wietse@wzv.win.tue.nl), dept. of Mathematics and + * Computing Science, Eindhoven University of Technology, The Netherlands. + */ + +#ifndef lint +static char sccsid[] = "@(#) pmap_dump.c 1.1 92/06/11 22:53:15"; +#endif + +#include +#include +#ifdef SYSV40 +#include +#include +#else +#include +#endif +#include +#include +#include + +static char *protoname(); + +main(argc, argv) +int argc; +char **argv; +{ + struct sockaddr_in addr; + register struct pmaplist *list; + register struct rpcent *rpc; + + get_myaddress(&addr); + + for (list = pmap_getmaps(&addr); list; list = list->pml_next) { + rpc = getrpcbynumber((int) list->pml_map.pm_prog); + printf("%10lu %4lu %5s %6lu %s\n", + list->pml_map.pm_prog, + list->pml_map.pm_vers, + protoname(list->pml_map.pm_prot), + list->pml_map.pm_port, + rpc ? rpc->r_name : ""); + } +#undef perror + return (fclose(stdout) ? (perror(argv[0]), 1) : 0); +} + +static char *protoname(proto) +u_long proto; +{ + static char buf[BUFSIZ]; + + switch (proto) { + case IPPROTO_UDP: + return ("udp"); + case IPPROTO_TCP: + return ("tcp"); + default: + sprintf(buf, "%lu", proto); + return (buf); + } +} diff --git a/usr.sbin/portmap/pmap_set/Makefile b/usr.sbin/portmap/pmap_set/Makefile new file mode 100644 index 0000000..987e320 --- /dev/null +++ b/usr.sbin/portmap/pmap_set/Makefile @@ -0,0 +1,7 @@ +# @(#)Makefile 8.1 (Berkeley) 6/6/93 + +PROG= pmap_set +NOMAN= noman + +.include "${.CURDIR}/../../Makefile.inc" +.include diff --git a/usr.sbin/portmap/pmap_set/pmap_set.c b/usr.sbin/portmap/pmap_set/pmap_set.c new file mode 100644 index 0000000..ab82fd5 --- /dev/null +++ b/usr.sbin/portmap/pmap_set/pmap_set.c @@ -0,0 +1,70 @@ + /* + * pmap_set - set portmapper table from data produced by pmap_dump + * + * Author: Wietse Venema (wietse@wzv.win.tue.nl), dept. of Mathematics and + * Computing Science, Eindhoven University of Technology, The Netherlands. + */ + +#ifndef lint +static char sccsid[] = "@(#) pmap_set.c 1.1 92/06/11 22:53:16"; +#endif + +#include +#include +#ifdef SYSV40 +#include +#endif +#include +#include + +main(argc, argv) +int argc; +char **argv; +{ + struct sockaddr_in addr; + char buf[BUFSIZ]; + u_long prog; + u_long vers; + int prot; + unsigned port; + + get_myaddress(&addr); + + while (fgets(buf, sizeof(buf), stdin)) { + if (parse_line(buf, &prog, &vers, &prot, &port) == 0) { + fprintf(stderr, "%s: malformed line: %s", argv[0], buf); + return (1); + } + if (pmap_set(prog, vers, prot, (unsigned short) port) == 0) + fprintf(stderr, "not registered: %s", buf); + } + return (0); +} + +/* parse_line - convert line to numbers */ + +parse_line(buf, prog, vers, prot, port) +char *buf; +u_long *prog; +u_long *vers; +int *prot; +unsigned *port; +{ + char proto_name[BUFSIZ]; + + if (sscanf(buf, "%lu %lu %s %u", prog, vers, proto_name, port) != 4) { + return (0); + } + if (strcmp(proto_name, "tcp") == 0) { + *prot = IPPROTO_TCP; + return (1); + } + if (strcmp(proto_name, "udp") == 0) { + *prot = IPPROTO_UDP; + return (1); + } + if (sscanf(proto_name, "%d", prot) == 1) { + return (1); + } + return (0); +} diff --git a/usr.sbin/portmap/portmap.8 b/usr.sbin/portmap/portmap.8 index a651f5f..8edd888 100644 --- a/usr.sbin/portmap/portmap.8 +++ b/usr.sbin/portmap/portmap.8 @@ -94,6 +94,8 @@ Option available: from running as a daemon, and causes errors and debugging information to be printed to the standard error output. +.It Fl v +(verbose) enable verbose logging access control checks. .El .Sh SEE ALSO .Xr inetd.conf 5 , diff --git a/usr.sbin/portmap/portmap.c b/usr.sbin/portmap/portmap.c index 3118a28..6c40795 100644 --- a/usr.sbin/portmap/portmap.c +++ b/usr.sbin/portmap/portmap.c @@ -94,6 +94,8 @@ static char sccsid[] = "@(#)portmap.c 1.32 87/08/06 Copyr 1984 Sun Micro"; #include #include +#include "pmap_check.h" + void reg_service(); void reap(); static void callit(); @@ -111,15 +113,21 @@ main(argc, argv) int len = sizeof(struct sockaddr_in); register struct pmaplist *pml; - while ((c = getopt(argc, argv, "d")) != EOF) { + 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 [-d]\n", argv[0]); + (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); } } @@ -182,6 +190,8 @@ main(argc, argv) (void)svc_register(xprt, PMAPPROG, PMAPVERS, reg_service, FALSE); + /* additional initializations */ + check_startup(); (void)signal(SIGCHLD, reap); svc_run(); syslog(LOG_ERR, "run_svc returned unexpectedly"); @@ -230,6 +240,13 @@ reg_service(rqstp, xprt) 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,6 +255,8 @@ reg_service(rqstp, xprt) /* * 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,6 +269,12 @@ reg_service(rqstp, xprt) if (!svc_getargs(xprt, xdr_pmap, ®)) 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,6 +324,10 @@ reg_service(rqstp, xprt) 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,6 +337,14 @@ reg_service(rqstp, xprt) 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,6 +369,13 @@ reg_service(rqstp, xprt) if (!svc_getargs(xprt, xdr_pmap, ®)) 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,8 +396,16 @@ reg_service(rqstp, xprt) 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(); } @@ -372,6 +424,8 @@ reg_service(rqstp, xprt) break; default: + /* remote host authorization check */ + check_default(svc_getcaller(xprt), rqstp->rq_proc, (u_long) 0); svcerr_noproc(xprt); break; } @@ -384,7 +438,7 @@ reg_service(rqstp, xprt) #define ARGSIZE 9000 struct encap_parms { - u_long arglen; + u_int arglen; char *args; }; @@ -500,6 +554,10 @@ callit(rqstp, xprt) 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) return; -- cgit v1.1