diff options
Diffstat (limited to 'usr.sbin/portmap/portmap.c')
-rw-r--r-- | usr.sbin/portmap/portmap.c | 66 |
1 files changed, 62 insertions, 4 deletions
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, ®)) 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; |