1 /* $OpenBSD: portmap.c,v 1.18 2000/07/31 17:28:26 deraadt Exp $ */ 2 3 /*- 4 * Copyright (c) 1996, 1997 Theo de Raadt (OpenBSD). All rights reserved. 5 * Copyright (c) 1990 The Regents of the University of California. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by the University of 19 * California, Berkeley and its contributors. 20 * 4. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 */ 36 37 #ifndef lint 38 char copyright[] = 39 "@(#) Copyright (c) 1990 The Regents of the University of California.\n\ 40 All rights reserved.\n"; 41 #endif /* not lint */ 42 43 #ifndef lint 44 #if 0 45 static char sccsid[] = "from: @(#)portmap.c 5.4 (Berkeley) 4/19/91"; 46 #else 47 static char rcsid[] = "$OpenBSD: portmap.c,v 1.18 2000/07/31 17:28:26 deraadt Exp $"; 48 #endif 49 #endif /* not lint */ 50 51 /* 52 @(#)portmap.c 2.3 88/08/11 4.0 RPCSRC 53 static char sccsid[] = "@(#)portmap.c 1.32 87/08/06 Copyr 1984 Sun Micro"; 54 */ 55 56 /* 57 * portmap.c, Implements the program,version to port number mapping for 58 * rpc. 59 */ 60 61 /* 62 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 63 * unrestricted use provided that this legend is included on all tape 64 * media and as a part of the software program in whole or part. Users 65 * may copy or modify Sun RPC without charge, but are not authorized 66 * to license or distribute it to anyone else except as part of a product or 67 * program developed by the user. 68 * 69 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 70 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 71 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 72 * 73 * Sun RPC is provided with no support and without any obligation on the 74 * part of Sun Microsystems, Inc. to assist in its use, correction, 75 * modification or enhancement. 76 * 77 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 78 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 79 * OR ANY PART THEREOF. 80 * 81 * In no event will Sun Microsystems, Inc. be liable for any lost revenue 82 * or profits or other special, indirect and consequential damages, even if 83 * Sun has been advised of the possibility of such damages. 84 * 85 * Sun Microsystems, Inc. 86 * 2550 Garcia Avenue 87 * Mountain View, California 94043 88 */ 89 90 #include <rpc/rpc.h> 91 #include <rpc/pmap_prot.h> 92 #include <stdio.h> 93 #include <stdlib.h> 94 #include <string.h> 95 #include <syslog.h> 96 #include <unistd.h> 97 #include <netdb.h> 98 #include <sys/socket.h> 99 #include <sys/ioctl.h> 100 #include <sys/wait.h> 101 #include <sys/signal.h> 102 #include <sys/resource.h> 103 #include <rpcsvc/nfs_prot.h> 104 #include <arpa/inet.h> 105 106 void reg_service __P((struct svc_req *, SVCXPRT *)); 107 void reap __P((void)); 108 void callit __P((struct svc_req *, SVCXPRT *)); 109 int check_callit __P((struct sockaddr_in *, u_long, u_long, u_long)); 110 111 struct pmaplist *pmaplist; 112 int debugging = 0; 113 extern int errno; 114 115 SVCXPRT *ludpxprt, *ltcpxprt; 116 117 int 118 main(argc, argv) 119 int argc; 120 char **argv; 121 { 122 SVCXPRT *xprt; 123 int sock, lsock, c; 124 struct sockaddr_in addr, laddr; 125 int on = 1; 126 int len = sizeof(struct sockaddr_in); 127 register struct pmaplist *pml; 128 129 while ((c = getopt(argc, argv, "d")) != -1) { 130 switch (c) { 131 132 case 'd': 133 debugging = 1; 134 break; 135 136 default: 137 (void) fprintf(stderr, "usage: %s [-d]\n", argv[0]); 138 exit(1); 139 } 140 } 141 142 if (!debugging && daemon(0, 0)) { 143 (void) fprintf(stderr, "portmap: fork: %s", strerror(errno)); 144 exit(1); 145 } 146 147 openlog("portmap", debugging ? LOG_PID | LOG_PERROR : LOG_PID, 148 LOG_DAEMON); 149 150 bzero((char *)&addr, sizeof addr); 151 addr.sin_addr.s_addr = 0; 152 addr.sin_family = AF_INET; 153 addr.sin_addr.s_addr = htonl(INADDR_ANY); 154 addr.sin_port = htons(PMAPPORT); 155 156 bzero((char *)&laddr, sizeof laddr); 157 laddr.sin_addr.s_addr = 0; 158 laddr.sin_family = AF_INET; 159 laddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 160 laddr.sin_port = htons(PMAPPORT); 161 162 if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { 163 syslog(LOG_ERR, "cannot create udp socket: %m"); 164 exit(1); 165 } 166 setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof on); 167 if (bind(sock, (struct sockaddr *)&addr, len) != 0) { 168 syslog(LOG_ERR, "cannot bind udp: %m"); 169 exit(1); 170 } 171 172 if ((xprt = svcudp_create(sock)) == (SVCXPRT *)NULL) { 173 syslog(LOG_ERR, "couldn't do udp_create"); 174 exit(1); 175 } 176 177 if ((lsock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { 178 syslog(LOG_ERR, "cannot create udp socket: %m"); 179 exit(1); 180 } 181 setsockopt(lsock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof on); 182 if (bind(lsock, (struct sockaddr *)&laddr, len) != 0) { 183 syslog(LOG_ERR, "cannot bind local udp: %m"); 184 exit(1); 185 } 186 187 if ((ludpxprt = svcudp_create(lsock)) == (SVCXPRT *)NULL) { 188 syslog(LOG_ERR, "couldn't do udp_create"); 189 exit(1); 190 } 191 192 /* make an entry for ourself */ 193 pml = (struct pmaplist *)malloc((u_int)sizeof(struct pmaplist)); 194 pml->pml_next = 0; 195 pml->pml_map.pm_prog = PMAPPROG; 196 pml->pml_map.pm_vers = PMAPVERS; 197 pml->pml_map.pm_prot = IPPROTO_UDP; 198 pml->pml_map.pm_port = PMAPPORT; 199 pmaplist = pml; 200 201 if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { 202 syslog(LOG_ERR, "cannot create tcp socket: %m"); 203 exit(1); 204 } 205 setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof on); 206 if (bind(sock, (struct sockaddr *)&addr, len) != 0) { 207 syslog(LOG_ERR, "cannot bind tcp: %m"); 208 exit(1); 209 } 210 if ((xprt = svctcp_create(sock, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE)) 211 == (SVCXPRT *)NULL) { 212 syslog(LOG_ERR, "couldn't do tcp_create"); 213 exit(1); 214 } 215 216 if ((lsock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { 217 syslog(LOG_ERR, "cannot create tcp socket: %m"); 218 exit(1); 219 } 220 setsockopt(lsock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof on); 221 if (bind(lsock, (struct sockaddr *)&laddr, len) != 0) { 222 syslog(LOG_ERR, "cannot bind tcp: %m"); 223 exit(1); 224 } 225 if ((ltcpxprt = svctcp_create(lsock, RPCSMALLMSGSIZE, 226 RPCSMALLMSGSIZE)) == (SVCXPRT *)NULL) { 227 syslog(LOG_ERR, "couldn't do tcp_create"); 228 exit(1); 229 } 230 231 /* make an entry for ourself */ 232 pml = (struct pmaplist *)malloc((u_int)sizeof(struct pmaplist)); 233 pml->pml_map.pm_prog = PMAPPROG; 234 pml->pml_map.pm_vers = PMAPVERS; 235 pml->pml_map.pm_prot = IPPROTO_TCP; 236 pml->pml_map.pm_port = PMAPPORT; 237 pml->pml_next = pmaplist; 238 pmaplist = pml; 239 240 (void)svc_register(xprt, PMAPPROG, PMAPVERS, reg_service, FALSE); 241 242 (void)signal(SIGCHLD, (void (*)())reap); 243 svc_run(); 244 syslog(LOG_ERR, "svc_run returned unexpectedly"); 245 abort(); 246 } 247 248 #ifndef lint 249 /* need to override perror calls in rpc library */ 250 void 251 perror(what) 252 const char *what; 253 { 254 255 syslog(LOG_ERR, "%s: %m", what); 256 } 257 #endif 258 259 struct pmaplist * 260 find_service(prog, vers, prot) 261 u_long prog, vers, prot; 262 { 263 register struct pmaplist *hit = NULL; 264 register struct pmaplist *pml; 265 266 for (pml = pmaplist; pml != NULL; pml = pml->pml_next) { 267 if ((pml->pml_map.pm_prog != prog) || 268 (pml->pml_map.pm_prot != prot)) 269 continue; 270 hit = pml; 271 if (pml->pml_map.pm_vers == vers) 272 break; 273 } 274 return (hit); 275 } 276 277 /* 278 * 1 OK, 0 not 279 */ 280 void 281 reg_service(rqstp, xprt) 282 struct svc_req *rqstp; 283 SVCXPRT *xprt; 284 { 285 struct pmap reg; 286 struct pmaplist *pml, *prevpml, *fnd; 287 struct sockaddr_in *fromsin; 288 long ans = 0, port; 289 caddr_t t; 290 291 fromsin = svc_getcaller(xprt); 292 293 if (debugging) 294 (void) fprintf(stderr, "server: about to do a switch\n"); 295 switch (rqstp->rq_proc) { 296 297 case PMAPPROC_NULL: 298 /* 299 * Null proc call 300 */ 301 if (!svc_sendreply(xprt, xdr_void, (caddr_t)0) && debugging) { 302 abort(); 303 } 304 break; 305 306 case PMAPPROC_SET: 307 /* 308 * Set a program,version to port mapping 309 */ 310 if (xprt != ltcpxprt && xprt != ludpxprt) { 311 syslog(LOG_WARNING, 312 "non-local set attempt (might be from %s)", 313 inet_ntoa(fromsin->sin_addr)); 314 svcerr_noproc(xprt); 315 return; 316 } 317 if (!svc_getargs(xprt, xdr_pmap, (caddr_t)®)) { 318 svcerr_decode(xprt); 319 break; 320 } 321 322 /* 323 * check to see if already used 324 * find_service returns a hit even if 325 * the versions don't match, so check for it 326 */ 327 fnd = find_service(reg.pm_prog, reg.pm_vers, reg.pm_prot); 328 if (fnd && fnd->pml_map.pm_vers == reg.pm_vers) { 329 if (fnd->pml_map.pm_port == reg.pm_port) 330 ans = 1; 331 goto done; 332 } 333 334 if (debugging) 335 printf("set: prog %u vers %u port %u\n", 336 reg.pm_prog, reg.pm_vers, reg.pm_port); 337 338 if (reg.pm_port & ~0xffff) 339 goto done; 340 341 /* 342 * only permit localhost root to create 343 * mappings pointing at sensitive ports 344 */ 345 if ((reg.pm_port < IPPORT_RESERVED || 346 reg.pm_port == NFS_PORT) && 347 htons(fromsin->sin_port) >= IPPORT_RESERVED) { 348 syslog(LOG_WARNING, 349 "resvport set attempt by non-root"); 350 goto done; 351 } 352 353 /* 354 * add to END of list 355 */ 356 pml = (struct pmaplist *)malloc(sizeof(struct pmaplist)); 357 pml->pml_map = reg; 358 pml->pml_next = 0; 359 if (pmaplist == 0) { 360 pmaplist = pml; 361 } else { 362 for (fnd = pmaplist; fnd->pml_next != 0; 363 fnd = fnd->pml_next); 364 fnd->pml_next = pml; 365 } 366 ans = 1; 367 done: 368 if ((!svc_sendreply(xprt, xdr_long, (caddr_t)&ans)) && 369 debugging) { 370 (void) fprintf(stderr, "svc_sendreply\n"); 371 abort(); 372 } 373 break; 374 375 case PMAPPROC_UNSET: 376 /* 377 * Remove a program,version to port mapping. 378 */ 379 if (xprt != ltcpxprt && xprt != ludpxprt) { 380 syslog(LOG_WARNING, 381 "non-local unset attempt (might be from %s)", 382 inet_ntoa(fromsin->sin_addr)); 383 svcerr_noproc(xprt); 384 return; 385 } 386 if (!svc_getargs(xprt, xdr_pmap, (caddr_t)®)) { 387 svcerr_decode(xprt); 388 break; 389 } 390 for (prevpml = NULL, pml = pmaplist; pml != NULL; ) { 391 if ((pml->pml_map.pm_prog != reg.pm_prog) || 392 (pml->pml_map.pm_vers != reg.pm_vers)) { 393 /* both pml & prevpml move forwards */ 394 prevpml = pml; 395 pml = pml->pml_next; 396 continue; 397 } 398 if ((pml->pml_map.pm_port < IPPORT_RESERVED || 399 pml->pml_map.pm_port == NFS_PORT) && 400 htons(fromsin->sin_port) >= IPPORT_RESERVED) { 401 syslog(LOG_WARNING, 402 "resvport unset attempt by non-root"); 403 break; 404 } 405 406 /* found it; pml moves forward, prevpml stays */ 407 ans = 1; 408 t = (caddr_t)pml; 409 pml = pml->pml_next; 410 if (prevpml == NULL) 411 pmaplist = pml; 412 else 413 prevpml->pml_next = pml; 414 free(t); 415 } 416 if ((!svc_sendreply(xprt, xdr_long, (caddr_t)&ans)) && 417 debugging) { 418 fprintf(stderr, "svc_sendreply\n"); 419 abort(); 420 } 421 break; 422 423 case PMAPPROC_GETPORT: 424 /* 425 * Lookup the mapping for a program,version and return its port 426 */ 427 if (!svc_getargs(xprt, xdr_pmap, (caddr_t)®)) { 428 svcerr_decode(xprt); 429 break; 430 } 431 fnd = find_service(reg.pm_prog, reg.pm_vers, reg.pm_prot); 432 if (fnd) 433 port = fnd->pml_map.pm_port; 434 else 435 port = 0; 436 if ((!svc_sendreply(xprt, xdr_long, (caddr_t)&port)) && 437 debugging) { 438 fprintf(stderr, "svc_sendreply\n"); 439 abort(); 440 } 441 break; 442 443 case PMAPPROC_DUMP: 444 /* 445 * Return the current set of mapped program,version 446 */ 447 if (!svc_getargs(xprt, xdr_void, NULL)) { 448 svcerr_decode(xprt); 449 break; 450 } 451 if (!svc_sendreply(xprt, xdr_pmaplist, (caddr_t)&pmaplist) && 452 debugging) { 453 fprintf(stderr, "svc_sendreply\n"); 454 abort(); 455 } 456 break; 457 458 case PMAPPROC_CALLIT: 459 /* 460 * Calls a procedure on the local machine. If the requested 461 * procedure is not registered this procedure does not return 462 * error information!! 463 * This procedure is only supported on rpc/udp and calls via 464 * rpc/udp. It passes null authentication parameters. 465 */ 466 callit(rqstp, xprt); 467 break; 468 469 default: 470 svcerr_noproc(xprt); 471 break; 472 } 473 } 474 475 476 /* 477 * Stuff for the rmtcall service 478 */ 479 #define ARGSIZE 9000 480 481 struct encap_parms { 482 u_int arglen; 483 char *args; 484 }; 485 486 static bool_t 487 xdr_encap_parms(xdrs, epp) 488 XDR *xdrs; 489 struct encap_parms *epp; 490 { 491 492 return (xdr_bytes(xdrs, &(epp->args), &(epp->arglen), ARGSIZE)); 493 } 494 495 struct rmtcallargs { 496 u_long rmt_prog; 497 u_long rmt_vers; 498 u_long rmt_port; 499 u_long rmt_proc; 500 struct encap_parms rmt_args; 501 }; 502 503 static bool_t 504 xdr_rmtcall_args(xdrs, cap) 505 register XDR *xdrs; 506 register struct rmtcallargs *cap; 507 { 508 509 /* does not get a port number */ 510 if (xdr_u_long(xdrs, &(cap->rmt_prog)) && 511 xdr_u_long(xdrs, &(cap->rmt_vers)) && 512 xdr_u_long(xdrs, &(cap->rmt_proc))) { 513 return (xdr_encap_parms(xdrs, &(cap->rmt_args))); 514 } 515 return (FALSE); 516 } 517 518 static bool_t 519 xdr_rmtcall_result(xdrs, cap) 520 register XDR *xdrs; 521 register struct rmtcallargs *cap; 522 { 523 if (xdr_u_long(xdrs, &(cap->rmt_port))) 524 return (xdr_encap_parms(xdrs, &(cap->rmt_args))); 525 return (FALSE); 526 } 527 528 /* 529 * only worries about the struct encap_parms part of struct rmtcallargs. 530 * The arglen must already be set!! 531 */ 532 static bool_t 533 xdr_opaque_parms(xdrs, cap) 534 XDR *xdrs; 535 struct rmtcallargs *cap; 536 { 537 538 return (xdr_opaque(xdrs, cap->rmt_args.args, cap->rmt_args.arglen)); 539 } 540 541 /* 542 * This routine finds and sets the length of incoming opaque paraters 543 * and then calls xdr_opaque_parms. 544 */ 545 static bool_t 546 xdr_len_opaque_parms(xdrs, cap) 547 register XDR *xdrs; 548 struct rmtcallargs *cap; 549 { 550 register u_int beginpos, lowpos, highpos, currpos, pos; 551 552 beginpos = lowpos = pos = xdr_getpos(xdrs); 553 highpos = lowpos + ARGSIZE; 554 while ((int)(highpos - lowpos) >= 0) { 555 currpos = (lowpos + highpos) / 2; 556 if (xdr_setpos(xdrs, currpos)) { 557 pos = currpos; 558 lowpos = currpos + 1; 559 } else { 560 highpos = currpos - 1; 561 } 562 } 563 xdr_setpos(xdrs, beginpos); 564 cap->rmt_args.arglen = pos - beginpos; 565 return (xdr_opaque_parms(xdrs, cap)); 566 } 567 568 /* 569 * Call a remote procedure service 570 * This procedure is very quiet when things go wrong. 571 * The proc is written to support broadcast rpc. In the broadcast case, 572 * a machine should shut-up instead of complain, less the requestor be 573 * overrun with complaints at the expense of not hearing a valid reply ... 574 * 575 * This now forks so that the program & process that it calls can call 576 * back to the portmapper. 577 */ 578 void 579 callit(rqstp, xprt) 580 struct svc_req *rqstp; 581 SVCXPRT *xprt; 582 { 583 struct rmtcallargs a; 584 struct pmaplist *pml; 585 u_short port; 586 struct sockaddr_in me; 587 pid_t pid; 588 int so = -1, dontblock = 1; 589 CLIENT *client; 590 struct authunix_parms *au = (struct authunix_parms *)rqstp->rq_clntcred; 591 struct timeval timeout; 592 char buf[ARGSIZE]; 593 594 timeout.tv_sec = 5; 595 timeout.tv_usec = 0; 596 a.rmt_args.args = buf; 597 if (!svc_getargs(xprt, xdr_rmtcall_args, (caddr_t)&a)) 598 return; 599 if (!check_callit(svc_getcaller(xprt), rqstp->rq_proc, 600 a.rmt_prog, a.rmt_proc)) 601 return; 602 if ((pml = find_service(a.rmt_prog, a.rmt_vers, 603 (u_long)IPPROTO_UDP)) == NULL) 604 return; 605 606 /* 607 * fork a child to do the work. Parent immediately returns. 608 * Child exits upon completion. 609 */ 610 if ((pid = fork()) != 0) { 611 if (pid == -1) 612 syslog(LOG_ERR, "CALLIT (prog %lu): fork: %m", 613 a.rmt_prog); 614 return; 615 } 616 port = pml->pml_map.pm_port; 617 get_myaddress(&me); 618 me.sin_port = htons(port); 619 620 /* Avoid implicit binding to reserved port by clntudp_create() */ 621 so = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 622 if (so == -1) 623 exit(1); 624 if (ioctl(so, FIONBIO, &dontblock) == -1) 625 exit(1); 626 627 client = clntudp_create(&me, a.rmt_prog, a.rmt_vers, timeout, &so); 628 if (client != (CLIENT *)NULL) { 629 if (rqstp->rq_cred.oa_flavor == AUTH_UNIX) 630 client->cl_auth = authunix_create(au->aup_machname, 631 au->aup_uid, au->aup_gid, au->aup_len, au->aup_gids); 632 a.rmt_port = (u_long)port; 633 if (clnt_call(client, a.rmt_proc, xdr_opaque_parms, &a, 634 xdr_len_opaque_parms, &a, timeout) == RPC_SUCCESS) 635 svc_sendreply(xprt, xdr_rmtcall_result, (caddr_t)&a); 636 AUTH_DESTROY(client->cl_auth); 637 clnt_destroy(client); 638 } 639 (void)close(so); 640 exit(0); 641 } 642 643 void 644 reap() 645 { 646 int save_errno = errno; 647 648 while (wait3(NULL, WNOHANG, NULL) > 0) 649 ; 650 errno = save_errno; 651 } 652 653 #define NFSPROG ((u_long) 100003) 654 #define MOUNTPROG ((u_long) 100005) 655 #define YPXPROG ((u_long) 100069) 656 #define YPPROG ((u_long) 100004) 657 #define YPPROC_DOMAIN_NONACK ((u_long) 2) 658 #define MOUNTPROC_MNT ((u_long) 1) 659 #define XXXPROC_NOP ((u_long) 0) 660 661 int 662 check_callit(addr, proc, prog, aproc) 663 struct sockaddr_in *addr; 664 u_long proc; 665 u_long prog; 666 u_long aproc; 667 { 668 if ((prog == PMAPPROG && aproc != XXXPROC_NOP) || 669 (prog == NFSPROG && aproc != XXXPROC_NOP) || 670 (prog == YPXPROG && aproc != XXXPROC_NOP) || 671 (prog == MOUNTPROG && aproc == MOUNTPROC_MNT) || 672 (prog == YPPROG && aproc != YPPROC_DOMAIN_NONACK)) { 673 syslog(LOG_WARNING, 674 "callit prog %d aproc %d (might be from %s)", 675 (int)prog, (int)aproc, inet_ntoa(addr->sin_addr)); 676 return (FALSE); 677 } 678 return (TRUE); 679 } 680