3 4#include <sys/types.h> 5#include <sys/time.h> 6#include <sys/socket.h> 7#include <netinet/in.h> 8#include <arpa/inet.h> 9#include <rpc/rpc.h> 10#include <rpc/rpcb_prot.h> 11#include <rpc/pmap_prot.h> 12#include <err.h> 13#include <stdio.h> 14#include <stdlib.h> 15#include <string.h> 16#include <unistd.h> 17#include <libutil.h> 18#include <syslog.h> 19#include <netdb.h> 20 21/* 22 * XXX for special case checks in check_callit. 23 */ 24#include <rpcsvc/mount.h> 25#include <rpcsvc/rquota.h> 26#include <rpcsvc/nfs_prot.h> 27#include <rpcsvc/yp.h> 28#include <rpcsvc/ypclnt.h> 29#include <rpcsvc/yppasswd.h> 30 31#include "rpcbind.h" 32 33#ifdef LIBWRAP 34# include <tcpd.h> 35#ifndef LIBWRAP_ALLOW_FACILITY 36# define LIBWRAP_ALLOW_FACILITY LOG_AUTH 37#endif 38#ifndef LIBWRAP_ALLOW_SEVERITY 39# define LIBWRAP_ALLOW_SEVERITY LOG_INFO 40#endif 41#ifndef LIBWRAP_DENY_FACILITY 42# define LIBWRAP_DENY_FACILITY LOG_AUTH 43#endif 44#ifndef LIBWRAP_DENY_SEVERITY 45# define LIBWRAP_DENY_SEVERITY LOG_WARNING 46#endif 47int allow_severity = LIBWRAP_ALLOW_FACILITY|LIBWRAP_ALLOW_SEVERITY; 48int deny_severity = LIBWRAP_DENY_FACILITY|LIBWRAP_DENY_SEVERITY; 49#endif 50 51#ifndef PORTMAP_LOG_FACILITY 52# define PORTMAP_LOG_FACILITY LOG_AUTH 53#endif 54#ifndef PORTMAP_LOG_SEVERITY 55# define PORTMAP_LOG_SEVERITY LOG_INFO 56#endif 57int log_severity = PORTMAP_LOG_FACILITY|PORTMAP_LOG_SEVERITY; 58 59extern int verboselog; 60 61int 62check_access(SVCXPRT *xprt, rpcproc_t proc, void *args, unsigned int rpcbvers) 63{ 64 struct netbuf *caller = svc_getrpccaller(xprt); 65 struct sockaddr *addr = (struct sockaddr *)caller->buf; 66#ifdef LIBWRAP 67 struct request_info req; 68#endif 69 rpcprog_t prog = 0; 70 rpcb *rpcbp; 71 struct pmap *pmap; 72 73 /* 74 * The older PMAP_* equivalents have the same numbers, so 75 * they are accounted for here as well. 76 */ 77 switch (proc) { 78 case RPCBPROC_GETADDR: 79 case RPCBPROC_SET: 80 case RPCBPROC_UNSET: 81 if (rpcbvers > PMAPVERS) { 82 rpcbp = (rpcb *)args; 83 prog = rpcbp->r_prog; 84 } else { 85 pmap = (struct pmap *)args; 86 prog = pmap->pm_prog; 87 } 88 if (proc == RPCBPROC_GETADDR) 89 break; 90 if (!insecure && !is_loopback(caller)) { 91 if (verboselog) 92 logit(log_severity, addr, proc, prog, 93 " declined (non-loopback sender)"); 94 return 0; 95 } 96 break; 97 case RPCBPROC_CALLIT: 98 case RPCBPROC_INDIRECT: 99 case RPCBPROC_DUMP: 100 case RPCBPROC_GETTIME: 101 case RPCBPROC_UADDR2TADDR: 102 case RPCBPROC_TADDR2UADDR: 103 case RPCBPROC_GETVERSADDR: 104 case RPCBPROC_GETADDRLIST: 105 case RPCBPROC_GETSTAT: 106 default: 107 break; 108 } 109 110#ifdef LIBWRAP
| 3 4#include <sys/types.h> 5#include <sys/time.h> 6#include <sys/socket.h> 7#include <netinet/in.h> 8#include <arpa/inet.h> 9#include <rpc/rpc.h> 10#include <rpc/rpcb_prot.h> 11#include <rpc/pmap_prot.h> 12#include <err.h> 13#include <stdio.h> 14#include <stdlib.h> 15#include <string.h> 16#include <unistd.h> 17#include <libutil.h> 18#include <syslog.h> 19#include <netdb.h> 20 21/* 22 * XXX for special case checks in check_callit. 23 */ 24#include <rpcsvc/mount.h> 25#include <rpcsvc/rquota.h> 26#include <rpcsvc/nfs_prot.h> 27#include <rpcsvc/yp.h> 28#include <rpcsvc/ypclnt.h> 29#include <rpcsvc/yppasswd.h> 30 31#include "rpcbind.h" 32 33#ifdef LIBWRAP 34# include <tcpd.h> 35#ifndef LIBWRAP_ALLOW_FACILITY 36# define LIBWRAP_ALLOW_FACILITY LOG_AUTH 37#endif 38#ifndef LIBWRAP_ALLOW_SEVERITY 39# define LIBWRAP_ALLOW_SEVERITY LOG_INFO 40#endif 41#ifndef LIBWRAP_DENY_FACILITY 42# define LIBWRAP_DENY_FACILITY LOG_AUTH 43#endif 44#ifndef LIBWRAP_DENY_SEVERITY 45# define LIBWRAP_DENY_SEVERITY LOG_WARNING 46#endif 47int allow_severity = LIBWRAP_ALLOW_FACILITY|LIBWRAP_ALLOW_SEVERITY; 48int deny_severity = LIBWRAP_DENY_FACILITY|LIBWRAP_DENY_SEVERITY; 49#endif 50 51#ifndef PORTMAP_LOG_FACILITY 52# define PORTMAP_LOG_FACILITY LOG_AUTH 53#endif 54#ifndef PORTMAP_LOG_SEVERITY 55# define PORTMAP_LOG_SEVERITY LOG_INFO 56#endif 57int log_severity = PORTMAP_LOG_FACILITY|PORTMAP_LOG_SEVERITY; 58 59extern int verboselog; 60 61int 62check_access(SVCXPRT *xprt, rpcproc_t proc, void *args, unsigned int rpcbvers) 63{ 64 struct netbuf *caller = svc_getrpccaller(xprt); 65 struct sockaddr *addr = (struct sockaddr *)caller->buf; 66#ifdef LIBWRAP 67 struct request_info req; 68#endif 69 rpcprog_t prog = 0; 70 rpcb *rpcbp; 71 struct pmap *pmap; 72 73 /* 74 * The older PMAP_* equivalents have the same numbers, so 75 * they are accounted for here as well. 76 */ 77 switch (proc) { 78 case RPCBPROC_GETADDR: 79 case RPCBPROC_SET: 80 case RPCBPROC_UNSET: 81 if (rpcbvers > PMAPVERS) { 82 rpcbp = (rpcb *)args; 83 prog = rpcbp->r_prog; 84 } else { 85 pmap = (struct pmap *)args; 86 prog = pmap->pm_prog; 87 } 88 if (proc == RPCBPROC_GETADDR) 89 break; 90 if (!insecure && !is_loopback(caller)) { 91 if (verboselog) 92 logit(log_severity, addr, proc, prog, 93 " declined (non-loopback sender)"); 94 return 0; 95 } 96 break; 97 case RPCBPROC_CALLIT: 98 case RPCBPROC_INDIRECT: 99 case RPCBPROC_DUMP: 100 case RPCBPROC_GETTIME: 101 case RPCBPROC_UADDR2TADDR: 102 case RPCBPROC_TADDR2UADDR: 103 case RPCBPROC_GETVERSADDR: 104 case RPCBPROC_GETADDRLIST: 105 case RPCBPROC_GETSTAT: 106 default: 107 break; 108 } 109 110#ifdef LIBWRAP
|
111 if (addr->sa_family == AF_LOCAL) 112 return 1; 113 request_init(&req, RQ_DAEMON, "rpcbind", RQ_CLIENT_SIN, addr, 0); 114 sock_methods(&req); 115 if(!hosts_access(&req)) { 116 logit(deny_severity, addr, proc, prog, ": request from unauthorized host"); 117 return 0;
| 111 if (libwrap && addr->sa_family != AF_LOCAL) { 112 request_init(&req, RQ_DAEMON, "rpcbind", RQ_CLIENT_SIN, addr, 113 0); 114 sock_methods(&req); 115 if(!hosts_access(&req)) { 116 logit(deny_severity, addr, proc, prog, 117 ": request from unauthorized host"); 118 return 0; 119 }
|
118 } 119#endif 120 if (verboselog) 121 logit(log_severity, addr, proc, prog, ""); 122 return 1; 123} 124 125int 126is_loopback(struct netbuf *nbuf) 127{ 128 struct sockaddr *addr = (struct sockaddr *)nbuf->buf; 129 struct sockaddr_in *sin; 130#ifdef INET6 131 struct sockaddr_in6 *sin6; 132#endif 133 134 switch (addr->sa_family) { 135 case AF_INET: 136 if (!oldstyle_local) 137 return 0; 138 sin = (struct sockaddr_in *)addr; 139 return ((sin->sin_addr.s_addr == htonl(INADDR_LOOPBACK)) && 140 (ntohs(sin->sin_port) < IPPORT_RESERVED)); 141#ifdef INET6 142 case AF_INET6: 143 if (!oldstyle_local) 144 return 0; 145 sin6 = (struct sockaddr_in6 *)addr; 146 return (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr) && 147 (ntohs(sin6->sin6_port) < IPV6PORT_RESERVED)); 148#endif 149 case AF_LOCAL: 150 return 1; 151 default: 152 break; 153 } 154 155 return 0; 156} 157 158 159/* logit - report events of interest via the syslog daemon */ 160void 161logit(int severity, struct sockaddr *addr, rpcproc_t procnum, rpcprog_t prognum, 162 const char *text) 163{ 164 const char *procname; 165 char procbuf[32]; 166 char *progname; 167 char progbuf[32]; 168 char fromname[NI_MAXHOST]; 169 struct rpcent *rpc; 170 static const char *procmap[] = { 171 /* RPCBPROC_NULL */ "null", 172 /* RPCBPROC_SET */ "set", 173 /* RPCBPROC_UNSET */ "unset", 174 /* RPCBPROC_GETADDR */ "getport/addr", 175 /* RPCBPROC_DUMP */ "dump", 176 /* RPCBPROC_CALLIT */ "callit", 177 /* RPCBPROC_GETTIME */ "gettime", 178 /* RPCBPROC_UADDR2TADDR */ "uaddr2taddr", 179 /* RPCBPROC_TADDR2UADDR */ "taddr2uaddr", 180 /* RPCBPROC_GETVERSADDR */ "getversaddr", 181 /* RPCBPROC_INDIRECT */ "indirect", 182 /* RPCBPROC_GETADDRLIST */ "getaddrlist", 183 /* RPCBPROC_GETSTAT */ "getstat" 184 }; 185 186 /* 187 * Fork off a process or the portmap daemon might hang while 188 * getrpcbynumber() or syslog() does its thing. 189 */ 190 191 if (fork() == 0) { 192 setproctitle("logit"); 193 194 /* Try to map program number to name. */ 195 196 if (prognum == 0) { 197 progname = ""; 198 } else if ((rpc = getrpcbynumber((int) prognum))) { 199 progname = rpc->r_name; 200 } else { 201 snprintf(progname = progbuf, sizeof(progbuf), "%u", 202 (unsigned)prognum); 203 } 204 205 /* Try to map procedure number to name. */ 206 207 if (procnum >= (sizeof procmap / sizeof (char *))) { 208 snprintf(procbuf, sizeof procbuf, "%u", 209 (unsigned)procnum); 210 procname = procbuf; 211 } else 212 procname = procmap[procnum]; 213 214 /* Write syslog record. */ 215 216 if (addr->sa_family == AF_LOCAL) 217 strcpy(fromname, "local"); 218 else 219 getnameinfo(addr, addr->sa_len, fromname, 220 sizeof fromname, NULL, 0, NI_NUMERICHOST); 221 222 syslog(severity, "connect from %s to %s(%s)%s", 223 fromname, procname, progname, text); 224 _exit(0); 225 } 226} 227 228int 229check_callit(SVCXPRT *xprt, struct r_rmtcall_args *args, int versnum __unused) 230{ 231 struct sockaddr *sa = (struct sockaddr *)svc_getrpccaller(xprt)->buf; 232 233 /* 234 * Always allow calling NULLPROC 235 */ 236 if (args->rmt_proc == 0) 237 return 1; 238 239 /* 240 * XXX - this special casing sucks. 241 */ 242 switch (args->rmt_prog) { 243 case RPCBPROG: 244 /* 245 * Allow indirect calls to ourselves in insecure mode. 246 * The is_loopback checks aren't useful then anyway. 247 */ 248 if (!insecure) 249 goto deny; 250 break; 251 case MOUNTPROG: 252 if (args->rmt_proc != MOUNTPROC_MNT && 253 args->rmt_proc != MOUNTPROC_UMNT) 254 break; 255 goto deny; 256 case YPBINDPROG: 257 if (args->rmt_proc != YPBINDPROC_SETDOM) 258 break; 259 /* FALLTHROUGH */ 260 case YPPASSWDPROG: 261 case NFS_PROGRAM: 262 case RQUOTAPROG: 263 goto deny; 264 case YPPROG: 265 switch (args->rmt_proc) { 266 case YPPROC_ALL: 267 case YPPROC_MATCH: 268 case YPPROC_FIRST: 269 case YPPROC_NEXT: 270 goto deny; 271 default: 272 break; 273 } 274 default: 275 break; 276 } 277 278 return 1; 279deny: 280#ifdef LIBWRAP 281 logit(deny_severity, sa, args->rmt_proc, args->rmt_prog, 282 ": indirect call not allowed"); 283#else 284 logit(0, sa, args->rmt_proc, args->rmt_prog, 285 ": indirect call not allowed"); 286#endif 287 return 0; 288}
| 120 } 121#endif 122 if (verboselog) 123 logit(log_severity, addr, proc, prog, ""); 124 return 1; 125} 126 127int 128is_loopback(struct netbuf *nbuf) 129{ 130 struct sockaddr *addr = (struct sockaddr *)nbuf->buf; 131 struct sockaddr_in *sin; 132#ifdef INET6 133 struct sockaddr_in6 *sin6; 134#endif 135 136 switch (addr->sa_family) { 137 case AF_INET: 138 if (!oldstyle_local) 139 return 0; 140 sin = (struct sockaddr_in *)addr; 141 return ((sin->sin_addr.s_addr == htonl(INADDR_LOOPBACK)) && 142 (ntohs(sin->sin_port) < IPPORT_RESERVED)); 143#ifdef INET6 144 case AF_INET6: 145 if (!oldstyle_local) 146 return 0; 147 sin6 = (struct sockaddr_in6 *)addr; 148 return (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr) && 149 (ntohs(sin6->sin6_port) < IPV6PORT_RESERVED)); 150#endif 151 case AF_LOCAL: 152 return 1; 153 default: 154 break; 155 } 156 157 return 0; 158} 159 160 161/* logit - report events of interest via the syslog daemon */ 162void 163logit(int severity, struct sockaddr *addr, rpcproc_t procnum, rpcprog_t prognum, 164 const char *text) 165{ 166 const char *procname; 167 char procbuf[32]; 168 char *progname; 169 char progbuf[32]; 170 char fromname[NI_MAXHOST]; 171 struct rpcent *rpc; 172 static const char *procmap[] = { 173 /* RPCBPROC_NULL */ "null", 174 /* RPCBPROC_SET */ "set", 175 /* RPCBPROC_UNSET */ "unset", 176 /* RPCBPROC_GETADDR */ "getport/addr", 177 /* RPCBPROC_DUMP */ "dump", 178 /* RPCBPROC_CALLIT */ "callit", 179 /* RPCBPROC_GETTIME */ "gettime", 180 /* RPCBPROC_UADDR2TADDR */ "uaddr2taddr", 181 /* RPCBPROC_TADDR2UADDR */ "taddr2uaddr", 182 /* RPCBPROC_GETVERSADDR */ "getversaddr", 183 /* RPCBPROC_INDIRECT */ "indirect", 184 /* RPCBPROC_GETADDRLIST */ "getaddrlist", 185 /* RPCBPROC_GETSTAT */ "getstat" 186 }; 187 188 /* 189 * Fork off a process or the portmap daemon might hang while 190 * getrpcbynumber() or syslog() does its thing. 191 */ 192 193 if (fork() == 0) { 194 setproctitle("logit"); 195 196 /* Try to map program number to name. */ 197 198 if (prognum == 0) { 199 progname = ""; 200 } else if ((rpc = getrpcbynumber((int) prognum))) { 201 progname = rpc->r_name; 202 } else { 203 snprintf(progname = progbuf, sizeof(progbuf), "%u", 204 (unsigned)prognum); 205 } 206 207 /* Try to map procedure number to name. */ 208 209 if (procnum >= (sizeof procmap / sizeof (char *))) { 210 snprintf(procbuf, sizeof procbuf, "%u", 211 (unsigned)procnum); 212 procname = procbuf; 213 } else 214 procname = procmap[procnum]; 215 216 /* Write syslog record. */ 217 218 if (addr->sa_family == AF_LOCAL) 219 strcpy(fromname, "local"); 220 else 221 getnameinfo(addr, addr->sa_len, fromname, 222 sizeof fromname, NULL, 0, NI_NUMERICHOST); 223 224 syslog(severity, "connect from %s to %s(%s)%s", 225 fromname, procname, progname, text); 226 _exit(0); 227 } 228} 229 230int 231check_callit(SVCXPRT *xprt, struct r_rmtcall_args *args, int versnum __unused) 232{ 233 struct sockaddr *sa = (struct sockaddr *)svc_getrpccaller(xprt)->buf; 234 235 /* 236 * Always allow calling NULLPROC 237 */ 238 if (args->rmt_proc == 0) 239 return 1; 240 241 /* 242 * XXX - this special casing sucks. 243 */ 244 switch (args->rmt_prog) { 245 case RPCBPROG: 246 /* 247 * Allow indirect calls to ourselves in insecure mode. 248 * The is_loopback checks aren't useful then anyway. 249 */ 250 if (!insecure) 251 goto deny; 252 break; 253 case MOUNTPROG: 254 if (args->rmt_proc != MOUNTPROC_MNT && 255 args->rmt_proc != MOUNTPROC_UMNT) 256 break; 257 goto deny; 258 case YPBINDPROG: 259 if (args->rmt_proc != YPBINDPROC_SETDOM) 260 break; 261 /* FALLTHROUGH */ 262 case YPPASSWDPROG: 263 case NFS_PROGRAM: 264 case RQUOTAPROG: 265 goto deny; 266 case YPPROG: 267 switch (args->rmt_proc) { 268 case YPPROC_ALL: 269 case YPPROC_MATCH: 270 case YPPROC_FIRST: 271 case YPPROC_NEXT: 272 goto deny; 273 default: 274 break; 275 } 276 default: 277 break; 278 } 279 280 return 1; 281deny: 282#ifdef LIBWRAP 283 logit(deny_severity, sa, args->rmt_proc, args->rmt_prog, 284 ": indirect call not allowed"); 285#else 286 logit(0, sa, args->rmt_proc, args->rmt_prog, 287 ": indirect call not allowed"); 288#endif 289 return 0; 290}
|