18360efbdSAlfred Perlstein /* $NetBSD: security.c,v 1.5 2000/06/08 09:01:05 fvdl Exp $ */ 28360efbdSAlfred Perlstein /* $FreeBSD$ */ 38360efbdSAlfred Perlstein 48360efbdSAlfred Perlstein #include <sys/types.h> 58360efbdSAlfred Perlstein #include <sys/time.h> 68360efbdSAlfred Perlstein #include <sys/socket.h> 78360efbdSAlfred Perlstein #include <netinet/in.h> 88360efbdSAlfred Perlstein #include <arpa/inet.h> 98360efbdSAlfred Perlstein #include <rpc/rpc.h> 108360efbdSAlfred Perlstein #include <rpc/rpcb_prot.h> 118360efbdSAlfred Perlstein #include <rpc/pmap_prot.h> 128360efbdSAlfred Perlstein #include <err.h> 1305c4b26eSIan Dowse #include <stdio.h> 148360efbdSAlfred Perlstein #include <stdlib.h> 158360efbdSAlfred Perlstein #include <string.h> 168360efbdSAlfred Perlstein #include <unistd.h> 178360efbdSAlfred Perlstein #include <libutil.h> 188360efbdSAlfred Perlstein #include <syslog.h> 198360efbdSAlfred Perlstein #include <netdb.h> 208360efbdSAlfred Perlstein 218360efbdSAlfred Perlstein /* 228360efbdSAlfred Perlstein * XXX for special case checks in check_callit. 238360efbdSAlfred Perlstein */ 248360efbdSAlfred Perlstein #include <rpcsvc/mount.h> 258360efbdSAlfred Perlstein #include <rpcsvc/rquota.h> 268360efbdSAlfred Perlstein #include <rpcsvc/nfs_prot.h> 278360efbdSAlfred Perlstein #include <rpcsvc/yp.h> 288360efbdSAlfred Perlstein #include <rpcsvc/ypclnt.h> 298360efbdSAlfred Perlstein #include <rpcsvc/yppasswd.h> 308360efbdSAlfred Perlstein 318360efbdSAlfred Perlstein #include "rpcbind.h" 328360efbdSAlfred Perlstein 338360efbdSAlfred Perlstein #ifdef LIBWRAP 348360efbdSAlfred Perlstein # include <tcpd.h> 358360efbdSAlfred Perlstein #ifndef LIBWRAP_ALLOW_FACILITY 368360efbdSAlfred Perlstein # define LIBWRAP_ALLOW_FACILITY LOG_AUTH 378360efbdSAlfred Perlstein #endif 388360efbdSAlfred Perlstein #ifndef LIBWRAP_ALLOW_SEVERITY 398360efbdSAlfred Perlstein # define LIBWRAP_ALLOW_SEVERITY LOG_INFO 408360efbdSAlfred Perlstein #endif 418360efbdSAlfred Perlstein #ifndef LIBWRAP_DENY_FACILITY 428360efbdSAlfred Perlstein # define LIBWRAP_DENY_FACILITY LOG_AUTH 438360efbdSAlfred Perlstein #endif 448360efbdSAlfred Perlstein #ifndef LIBWRAP_DENY_SEVERITY 458360efbdSAlfred Perlstein # define LIBWRAP_DENY_SEVERITY LOG_WARNING 468360efbdSAlfred Perlstein #endif 478360efbdSAlfred Perlstein int allow_severity = LIBWRAP_ALLOW_FACILITY|LIBWRAP_ALLOW_SEVERITY; 488360efbdSAlfred Perlstein int deny_severity = LIBWRAP_DENY_FACILITY|LIBWRAP_DENY_SEVERITY; 498360efbdSAlfred Perlstein #endif 508360efbdSAlfred Perlstein 518360efbdSAlfred Perlstein #ifndef PORTMAP_LOG_FACILITY 528360efbdSAlfred Perlstein # define PORTMAP_LOG_FACILITY LOG_AUTH 538360efbdSAlfred Perlstein #endif 548360efbdSAlfred Perlstein #ifndef PORTMAP_LOG_SEVERITY 558360efbdSAlfred Perlstein # define PORTMAP_LOG_SEVERITY LOG_INFO 568360efbdSAlfred Perlstein #endif 578360efbdSAlfred Perlstein int log_severity = PORTMAP_LOG_FACILITY|PORTMAP_LOG_SEVERITY; 588360efbdSAlfred Perlstein 598360efbdSAlfred Perlstein extern int verboselog; 608360efbdSAlfred Perlstein 618360efbdSAlfred Perlstein int 624180788fSAlfred Perlstein check_access(SVCXPRT *xprt, rpcproc_t proc, void *args, unsigned int rpcbvers) 638360efbdSAlfred Perlstein { 648360efbdSAlfred Perlstein struct netbuf *caller = svc_getrpccaller(xprt); 658360efbdSAlfred Perlstein struct sockaddr *addr = (struct sockaddr *)caller->buf; 668360efbdSAlfred Perlstein #ifdef LIBWRAP 678360efbdSAlfred Perlstein struct request_info req; 688360efbdSAlfred Perlstein #endif 698360efbdSAlfred Perlstein rpcprog_t prog = 0; 708360efbdSAlfred Perlstein rpcb *rpcbp; 718360efbdSAlfred Perlstein struct pmap *pmap; 728360efbdSAlfred Perlstein 738360efbdSAlfred Perlstein /* 748360efbdSAlfred Perlstein * The older PMAP_* equivalents have the same numbers, so 758360efbdSAlfred Perlstein * they are accounted for here as well. 768360efbdSAlfred Perlstein */ 778360efbdSAlfred Perlstein switch (proc) { 788360efbdSAlfred Perlstein case RPCBPROC_GETADDR: 798360efbdSAlfred Perlstein case RPCBPROC_SET: 808360efbdSAlfred Perlstein case RPCBPROC_UNSET: 818360efbdSAlfred Perlstein if (rpcbvers > PMAPVERS) { 828360efbdSAlfred Perlstein rpcbp = (rpcb *)args; 838360efbdSAlfred Perlstein prog = rpcbp->r_prog; 848360efbdSAlfred Perlstein } else { 858360efbdSAlfred Perlstein pmap = (struct pmap *)args; 868360efbdSAlfred Perlstein prog = pmap->pm_prog; 878360efbdSAlfred Perlstein } 888360efbdSAlfred Perlstein if (proc == RPCBPROC_GETADDR) 898360efbdSAlfred Perlstein break; 908360efbdSAlfred Perlstein if (!insecure && !is_loopback(caller)) { 918360efbdSAlfred Perlstein if (verboselog) 928360efbdSAlfred Perlstein logit(log_severity, addr, proc, prog, 938360efbdSAlfred Perlstein " declined (non-loopback sender)"); 948360efbdSAlfred Perlstein return 0; 958360efbdSAlfred Perlstein } 968360efbdSAlfred Perlstein break; 978360efbdSAlfred Perlstein case RPCBPROC_CALLIT: 988360efbdSAlfred Perlstein case RPCBPROC_INDIRECT: 998360efbdSAlfred Perlstein case RPCBPROC_DUMP: 1008360efbdSAlfred Perlstein case RPCBPROC_GETTIME: 1018360efbdSAlfred Perlstein case RPCBPROC_UADDR2TADDR: 1028360efbdSAlfred Perlstein case RPCBPROC_TADDR2UADDR: 1038360efbdSAlfred Perlstein case RPCBPROC_GETVERSADDR: 1048360efbdSAlfred Perlstein case RPCBPROC_GETADDRLIST: 1058360efbdSAlfred Perlstein case RPCBPROC_GETSTAT: 1068360efbdSAlfred Perlstein default: 1074ee5e586SAlfred Perlstein break; 1088360efbdSAlfred Perlstein } 1098360efbdSAlfred Perlstein 1108360efbdSAlfred Perlstein #ifdef LIBWRAP 1118360efbdSAlfred Perlstein if (addr->sa_family == AF_LOCAL) 1128360efbdSAlfred Perlstein return 1; 1138360efbdSAlfred Perlstein request_init(&req, RQ_DAEMON, "rpcbind", RQ_CLIENT_SIN, addr, 0); 1148360efbdSAlfred Perlstein sock_methods(&req); 1158360efbdSAlfred Perlstein if(!hosts_access(&req)) { 1168360efbdSAlfred Perlstein logit(deny_severity, addr, proc, prog, ": request from unauthorized host"); 1178360efbdSAlfred Perlstein return 0; 1188360efbdSAlfred Perlstein } 1198360efbdSAlfred Perlstein #endif 1208360efbdSAlfred Perlstein if (verboselog) 1218360efbdSAlfred Perlstein logit(log_severity, addr, proc, prog, ""); 1228360efbdSAlfred Perlstein return 1; 1238360efbdSAlfred Perlstein } 1248360efbdSAlfred Perlstein 1258360efbdSAlfred Perlstein int 1268360efbdSAlfred Perlstein is_loopback(struct netbuf *nbuf) 1278360efbdSAlfred Perlstein { 1288360efbdSAlfred Perlstein struct sockaddr *addr = (struct sockaddr *)nbuf->buf; 1298360efbdSAlfred Perlstein struct sockaddr_in *sin; 1308360efbdSAlfred Perlstein #ifdef INET6 1318360efbdSAlfred Perlstein struct sockaddr_in6 *sin6; 1328360efbdSAlfred Perlstein #endif 1338360efbdSAlfred Perlstein 1348360efbdSAlfred Perlstein switch (addr->sa_family) { 1358360efbdSAlfred Perlstein case AF_INET: 1368360efbdSAlfred Perlstein if (!oldstyle_local) 1378360efbdSAlfred Perlstein return 0; 1388360efbdSAlfred Perlstein sin = (struct sockaddr_in *)addr; 1398360efbdSAlfred Perlstein return ((sin->sin_addr.s_addr == htonl(INADDR_LOOPBACK)) && 1408360efbdSAlfred Perlstein (ntohs(sin->sin_port) < IPPORT_RESERVED)); 1418360efbdSAlfred Perlstein #ifdef INET6 1428360efbdSAlfred Perlstein case AF_INET6: 1438360efbdSAlfred Perlstein if (!oldstyle_local) 1448360efbdSAlfred Perlstein return 0; 1458360efbdSAlfred Perlstein sin6 = (struct sockaddr_in6 *)addr; 1468360efbdSAlfred Perlstein return (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr) && 1478360efbdSAlfred Perlstein (ntohs(sin6->sin6_port) < IPV6PORT_RESERVED)); 1488360efbdSAlfred Perlstein #endif 1498360efbdSAlfred Perlstein case AF_LOCAL: 1508360efbdSAlfred Perlstein return 1; 1518360efbdSAlfred Perlstein default: 1524ee5e586SAlfred Perlstein break; 1538360efbdSAlfred Perlstein } 1548360efbdSAlfred Perlstein 1558360efbdSAlfred Perlstein return 0; 1568360efbdSAlfred Perlstein } 1578360efbdSAlfred Perlstein 1588360efbdSAlfred Perlstein 1598360efbdSAlfred Perlstein /* logit - report events of interest via the syslog daemon */ 1608360efbdSAlfred Perlstein void 1618360efbdSAlfred Perlstein logit(int severity, struct sockaddr *addr, rpcproc_t procnum, rpcprog_t prognum, 1628360efbdSAlfred Perlstein const char *text) 1638360efbdSAlfred Perlstein { 1648360efbdSAlfred Perlstein const char *procname; 1658360efbdSAlfred Perlstein char procbuf[32]; 1668360efbdSAlfred Perlstein char *progname; 1678360efbdSAlfred Perlstein char progbuf[32]; 1688360efbdSAlfred Perlstein char fromname[NI_MAXHOST]; 1698360efbdSAlfred Perlstein struct rpcent *rpc; 1708360efbdSAlfred Perlstein static const char *procmap[] = { 1718360efbdSAlfred Perlstein /* RPCBPROC_NULL */ "null", 1728360efbdSAlfred Perlstein /* RPCBPROC_SET */ "set", 1738360efbdSAlfred Perlstein /* RPCBPROC_UNSET */ "unset", 1748360efbdSAlfred Perlstein /* RPCBPROC_GETADDR */ "getport/addr", 1758360efbdSAlfred Perlstein /* RPCBPROC_DUMP */ "dump", 1768360efbdSAlfred Perlstein /* RPCBPROC_CALLIT */ "callit", 1778360efbdSAlfred Perlstein /* RPCBPROC_GETTIME */ "gettime", 1788360efbdSAlfred Perlstein /* RPCBPROC_UADDR2TADDR */ "uaddr2taddr", 1798360efbdSAlfred Perlstein /* RPCBPROC_TADDR2UADDR */ "taddr2uaddr", 1808360efbdSAlfred Perlstein /* RPCBPROC_GETVERSADDR */ "getversaddr", 1818360efbdSAlfred Perlstein /* RPCBPROC_INDIRECT */ "indirect", 1828360efbdSAlfred Perlstein /* RPCBPROC_GETADDRLIST */ "getaddrlist", 1838360efbdSAlfred Perlstein /* RPCBPROC_GETSTAT */ "getstat" 1848360efbdSAlfred Perlstein }; 1858360efbdSAlfred Perlstein 1868360efbdSAlfred Perlstein /* 1878360efbdSAlfred Perlstein * Fork off a process or the portmap daemon might hang while 1888360efbdSAlfred Perlstein * getrpcbynumber() or syslog() does its thing. 1898360efbdSAlfred Perlstein */ 1908360efbdSAlfred Perlstein 1918360efbdSAlfred Perlstein if (fork() == 0) { 1928360efbdSAlfred Perlstein setproctitle("logit"); 1938360efbdSAlfred Perlstein 1948360efbdSAlfred Perlstein /* Try to map program number to name. */ 1958360efbdSAlfred Perlstein 1968360efbdSAlfred Perlstein if (prognum == 0) { 1978360efbdSAlfred Perlstein progname = ""; 1988360efbdSAlfred Perlstein } else if ((rpc = getrpcbynumber((int) prognum))) { 1998360efbdSAlfred Perlstein progname = rpc->r_name; 2008360efbdSAlfred Perlstein } else { 2018360efbdSAlfred Perlstein snprintf(progname = progbuf, sizeof(progbuf), "%u", 2028360efbdSAlfred Perlstein (unsigned)prognum); 2038360efbdSAlfred Perlstein } 2048360efbdSAlfred Perlstein 2058360efbdSAlfred Perlstein /* Try to map procedure number to name. */ 2068360efbdSAlfred Perlstein 20705c4b26eSIan Dowse if (procnum >= (sizeof procmap / sizeof (char *))) { 2088360efbdSAlfred Perlstein snprintf(procbuf, sizeof procbuf, "%u", 2098360efbdSAlfred Perlstein (unsigned)procnum); 2108360efbdSAlfred Perlstein procname = procbuf; 2118360efbdSAlfred Perlstein } else 2128360efbdSAlfred Perlstein procname = procmap[procnum]; 2138360efbdSAlfred Perlstein 2148360efbdSAlfred Perlstein /* Write syslog record. */ 2158360efbdSAlfred Perlstein 2168360efbdSAlfred Perlstein if (addr->sa_family == AF_LOCAL) 2178360efbdSAlfred Perlstein strcpy(fromname, "unix"); 2188360efbdSAlfred Perlstein else 2198360efbdSAlfred Perlstein getnameinfo(addr, addr->sa_len, fromname, 2208360efbdSAlfred Perlstein sizeof fromname, NULL, 0, NI_NUMERICHOST); 2218360efbdSAlfred Perlstein 2228360efbdSAlfred Perlstein syslog(severity, "connect from %s to %s(%s)%s", 2238360efbdSAlfred Perlstein fromname, procname, progname, text); 2248360efbdSAlfred Perlstein _exit(0); 2258360efbdSAlfred Perlstein } 2268360efbdSAlfred Perlstein } 2278360efbdSAlfred Perlstein 2288360efbdSAlfred Perlstein int 2294180788fSAlfred Perlstein check_callit(SVCXPRT *xprt, struct r_rmtcall_args *args, int versnum __unused) 2308360efbdSAlfred Perlstein { 2318360efbdSAlfred Perlstein struct sockaddr *sa = (struct sockaddr *)svc_getrpccaller(xprt)->buf; 2328360efbdSAlfred Perlstein 2338360efbdSAlfred Perlstein /* 2348360efbdSAlfred Perlstein * Always allow calling NULLPROC 2358360efbdSAlfred Perlstein */ 2368360efbdSAlfred Perlstein if (args->rmt_proc == 0) 2378360efbdSAlfred Perlstein return 1; 2388360efbdSAlfred Perlstein 2398360efbdSAlfred Perlstein /* 2408360efbdSAlfred Perlstein * XXX - this special casing sucks. 2418360efbdSAlfred Perlstein */ 2428360efbdSAlfred Perlstein switch (args->rmt_prog) { 2438360efbdSAlfred Perlstein case RPCBPROG: 2448360efbdSAlfred Perlstein /* 2458360efbdSAlfred Perlstein * Allow indirect calls to ourselves in insecure mode. 2468360efbdSAlfred Perlstein * The is_loopback checks aren't useful then anyway. 2478360efbdSAlfred Perlstein */ 2488360efbdSAlfred Perlstein if (!insecure) 2498360efbdSAlfred Perlstein goto deny; 2508360efbdSAlfred Perlstein break; 2518360efbdSAlfred Perlstein case MOUNTPROG: 2528360efbdSAlfred Perlstein if (args->rmt_proc != MOUNTPROC_MNT && 2538360efbdSAlfred Perlstein args->rmt_proc != MOUNTPROC_UMNT) 2548360efbdSAlfred Perlstein break; 2558360efbdSAlfred Perlstein goto deny; 2568360efbdSAlfred Perlstein case YPBINDPROG: 2578360efbdSAlfred Perlstein if (args->rmt_proc != YPBINDPROC_SETDOM) 2588360efbdSAlfred Perlstein break; 2598360efbdSAlfred Perlstein /* FALLTHROUGH */ 2608360efbdSAlfred Perlstein case YPPASSWDPROG: 2618360efbdSAlfred Perlstein case NFS_PROGRAM: 2628360efbdSAlfred Perlstein case RQUOTAPROG: 2638360efbdSAlfred Perlstein goto deny; 2648360efbdSAlfred Perlstein case YPPROG: 2658360efbdSAlfred Perlstein switch (args->rmt_proc) { 2668360efbdSAlfred Perlstein case YPPROC_ALL: 2678360efbdSAlfred Perlstein case YPPROC_MATCH: 2688360efbdSAlfred Perlstein case YPPROC_FIRST: 2698360efbdSAlfred Perlstein case YPPROC_NEXT: 2708360efbdSAlfred Perlstein goto deny; 2718360efbdSAlfred Perlstein default: 2724ee5e586SAlfred Perlstein break; 2738360efbdSAlfred Perlstein } 2748360efbdSAlfred Perlstein default: 2754ee5e586SAlfred Perlstein break; 2768360efbdSAlfred Perlstein } 2778360efbdSAlfred Perlstein 2788360efbdSAlfred Perlstein return 1; 2798360efbdSAlfred Perlstein deny: 2808360efbdSAlfred Perlstein #ifdef LIBWRAP 2818360efbdSAlfred Perlstein logit(deny_severity, sa, args->rmt_proc, args->rmt_prog, 2828360efbdSAlfred Perlstein ": indirect call not allowed"); 2838360efbdSAlfred Perlstein #else 2848360efbdSAlfred Perlstein logit(0, sa, args->rmt_proc, args->rmt_prog, 2858360efbdSAlfred Perlstein ": indirect call not allowed"); 2868360efbdSAlfred Perlstein #endif 2878360efbdSAlfred Perlstein return 0; 2888360efbdSAlfred Perlstein } 289