Portmap 3.0 from win.tue.nl
This commit is contained in:
parent
2233bc697f
commit
42d798d589
@ -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>
|
||||
|
147
usr.sbin/portmap/from_local.c
Normal file
147
usr.sbin/portmap/from_local.c
Normal file
@ -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
|
251
usr.sbin/portmap/pmap_check.c
Normal file
251
usr.sbin/portmap/pmap_check.c
Normal file
@ -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);
|
||||
}
|
||||
}
|
11
usr.sbin/portmap/pmap_check.h
Normal file
11
usr.sbin/portmap/pmap_check.h
Normal file
@ -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;
|
7
usr.sbin/portmap/pmap_dump/Makefile
Normal file
7
usr.sbin/portmap/pmap_dump/Makefile
Normal file
@ -0,0 +1,7 @@
|
||||
# @(#)Makefile 8.1 (Berkeley) 6/6/93
|
||||
|
||||
PROG= pmap_dump
|
||||
NOMAN= noman
|
||||
|
||||
.include "${.CURDIR}/../../Makefile.inc"
|
||||
.include <bsd.prog.mk>
|
63
usr.sbin/portmap/pmap_dump/pmap_dump.c
Normal file
63
usr.sbin/portmap/pmap_dump/pmap_dump.c
Normal file
@ -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);
|
||||
}
|
||||
}
|
7
usr.sbin/portmap/pmap_set/Makefile
Normal file
7
usr.sbin/portmap/pmap_set/Makefile
Normal file
@ -0,0 +1,7 @@
|
||||
# @(#)Makefile 8.1 (Berkeley) 6/6/93
|
||||
|
||||
PROG= pmap_set
|
||||
NOMAN= noman
|
||||
|
||||
.include "${.CURDIR}/../../Makefile.inc"
|
||||
.include <bsd.prog.mk>
|
70
usr.sbin/portmap/pmap_set/pmap_set.c
Normal file
70
usr.sbin/portmap/pmap_set/pmap_set.c
Normal file
@ -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);
|
||||
}
|
@ -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 ,
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user