summaryrefslogtreecommitdiffstats
path: root/usr.sbin/portmap
diff options
context:
space:
mode:
authorpst <pst@FreeBSD.org>1994-09-29 09:32:22 +0000
committerpst <pst@FreeBSD.org>1994-09-29 09:32:22 +0000
commit42d798d58915cb0463f74e10e32a2b28daabecd9 (patch)
treec4117ba4737660d583baf74b3e60311b93554437 /usr.sbin/portmap
parent2233bc697f5b3c6554e87ec91137e1740ea659f5 (diff)
downloadFreeBSD-src-42d798d58915cb0463f74e10e32a2b28daabecd9.zip
FreeBSD-src-42d798d58915cb0463f74e10e32a2b28daabecd9.tar.gz
Portmap 3.0 from win.tue.nl
Diffstat (limited to 'usr.sbin/portmap')
-rw-r--r--usr.sbin/portmap/Makefile8
-rw-r--r--usr.sbin/portmap/from_local.c147
-rw-r--r--usr.sbin/portmap/pmap_check.c251
-rw-r--r--usr.sbin/portmap/pmap_check.h11
-rw-r--r--usr.sbin/portmap/pmap_dump/Makefile7
-rw-r--r--usr.sbin/portmap/pmap_dump/pmap_dump.c63
-rw-r--r--usr.sbin/portmap/pmap_set/Makefile7
-rw-r--r--usr.sbin/portmap/pmap_set/pmap_set.c70
-rw-r--r--usr.sbin/portmap/portmap.82
-rw-r--r--usr.sbin/portmap/portmap.c66
10 files changed, 625 insertions, 7 deletions
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 <bsd.prog.mk>
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 <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <net/if.h>
+#include <sys/ioctl.h>
+#include <syslog.h>
+
+#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 <rpc/rpc.h>
+#include <rpc/pmap_prot.h>
+#include <syslog.h>
+#include <netdb.h>
+#include <sys/signal.h>
+
+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 <bsd.prog.mk>
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 <stdio.h>
+#include <sys/types.h>
+#ifdef SYSV40
+#include <netinet/in.h>
+#include <rpc/rpcent.h>
+#else
+#include <netdb.h>
+#endif
+#include <rpc/rpc.h>
+#include <rpc/pmap_clnt.h>
+#include <rpc/pmap_prot.h>
+
+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 <bsd.prog.mk>
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 <stdio.h>
+#include <sys/types.h>
+#ifdef SYSV40
+#include <netinet/in.h>
+#endif
+#include <rpc/rpc.h>
+#include <rpc/pmap_clnt.h>
+
+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 <sys/signal.h>
#include <sys/resource.h>
+#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, &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,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, &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,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;
OpenPOWER on IntegriCloud