1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 /* 26 * Copyright 2014 Nexenta Systems, Inc. All rights reserved. 27 */ 28 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 29 /* All Rights Reserved */ 30 /* 31 * University Copyright- Copyright (c) 1982, 1986, 1988 32 * The Regents of the University of California 33 * All Rights Reserved 34 * 35 * University Acknowledgment- Portions of this document are derived from 36 * software developed by the University of California, Berkeley, and its 37 * contributors. 38 */ 39 40 /* 41 * This is an implementation of RCPBIND according the RFC 1833: Binding 42 * Protocols for ONC RPC Version 2. The RFC specifies three versions of the 43 * binding protocol: 44 * 45 * 1) RPCBIND Version 3 (Section 2.2.1 of the RFC) 46 * 2) RPCBIND, Version 4 (Section 2.2.2 of the RFC) 47 * 3) Port Mapper Program Protocol (Section 3 of the RFC) 48 * 49 * Where the "Port Mapper Program Protocol" is refered as Version 2 of the 50 * binding protocol. The implementation of the Version 2 of the binding 51 * protocol is compiled in only in a case the PORTMAP macro is defined (by 52 * default it is defined). 53 * 54 * The implementation is based on top of the networking services library - 55 * libnsl(3lib) and uses Automatic MT mode (see rcp_control(3nsl) and 56 * svc_run(3nsl) for more details). 57 * 58 * Usually, when a thread handles an RPCBIND procedure (one that arrived from a 59 * client), it obtains the data for the response internally, and immediately 60 * sends the response back to the client. The only exception to this rule are 61 * remote (aka indirect) RPC calls, for example RPCBPROC_INDIRECT. Such 62 * procedures are designed to forward the RPC request from the client to some 63 * other RPC service specified by the client, wait for the result, and forward 64 * the result back to the client. This is implemented in rpcbproc_callit_com(). 65 * 66 * The response from the other (remote) RPC service is handled in 67 * handle_reply(), where the thread waiting in rpcbproc_callit_com() is woken 68 * up to finish the handling and to send (forward) the response back to the 69 * client. 70 * 71 * The thread implementing the indirect RPC call might be blocked in the 72 * rpcbproc_callit_com() waiting for the response from the other RPC service 73 * for very long time. During this time the thread is unable to handle other 74 * RPCBIND requests. To avoid a case when all threads are waiting in 75 * rpcbproc_callit_com() and there is no free thread able to handle other 76 * RPCBIND requests, the implementation has reserved eight threads to never be 77 * used for the remote RPC calls. The number of active remote RPC calls is in 78 * rpcb_rmtcalls, the upper limit of such calls is in rpcb_rmtcalls_max. 79 * 80 * In addition to the worker threads described above, there are two other 81 * threads. The logthread() thread is responsible for asynchronous logging to 82 * syslog. The terminate() thread is signal handler responsible for reload of 83 * the rpcbind configuration (on SIGHUP), or for gracefully shutting down 84 * rpcbind (otherwise). 85 * 86 * There are two global lists used for holding the information about the 87 * registered services: list_rbl is for Version 3 and 4 of the binding 88 * protocol, and list_pml is for Version 2. To protect these lists, two global 89 * readers/writer locks are defined and heavily used across the rpcbind 90 * implementation: list_rbl_lock protecting list_rbl, and list_pml_lock, 91 * protecting list_pml. 92 * 93 * The defined locking order is: list_rbl_lock first, list_pml_lock second. 94 */ 95 96 #include <dlfcn.h> 97 #include <stdio.h> 98 #include <stdio_ext.h> 99 #include <sys/types.h> 100 #include <unistd.h> 101 #include <stdlib.h> 102 #include <string.h> 103 #include <rpc/rpc.h> 104 #include <netconfig.h> 105 #include <netdir.h> 106 #include <errno.h> 107 #include <sys/wait.h> 108 #include <signal.h> 109 #include <string.h> 110 #include <stdlib.h> 111 #include <thread.h> 112 #include <synch.h> 113 #include <stdarg.h> 114 #ifdef PORTMAP 115 #include <netinet/in.h> 116 #endif 117 #include <arpa/inet.h> 118 #include <sys/termios.h> 119 #include "rpcbind.h" 120 #include <sys/syslog.h> 121 #include <sys/stat.h> 122 #include <syslog.h> 123 #include <string.h> 124 #include <sys/time.h> 125 #include <sys/resource.h> 126 #include <rpcsvc/daemon_utils.h> 127 #include <priv_utils.h> 128 #include <libscf.h> 129 #include <sys/ccompile.h> 130 #include <zone.h> 131 #include <ctype.h> 132 #include <limits.h> 133 #include <assert.h> 134 135 static sigset_t sigwaitset; 136 137 static void terminate(void); 138 static void detachfromtty(void); 139 static void parseargs(int, char *[]); 140 static void rbllist_add(ulong_t, ulong_t, struct netconfig *, struct netbuf *); 141 static int init_transport(struct netconfig *); 142 static int check_netconfig(void); 143 144 static boolean_t check_hostserv(struct netconfig *, const char *, const char *); 145 static int setopt_reuseaddr(int); 146 static int setopt_anon_mlp(int); 147 static int setup_callit(int); 148 149 static void rpcb_check_init(void); 150 151 /* Global variables */ 152 int debugging = 0; /* Tell me what's going on */ 153 static int ipv6flag = 0; 154 int doabort = 0; /* When debugging, do an abort on errors */ 155 static int listen_backlog; 156 static const int reserved_threads = 8; 157 158 /* 159 * list_rbl_lock protects list_rbl 160 * lock order: list_rbl_lock, list_pml_lock 161 */ 162 rwlock_t list_rbl_lock = DEFAULTRWLOCK; 163 rpcblist_ptr list_rbl; /* A list of version 3/4 rpcbind services */ 164 165 char *loopback_dg; /* Datagram loopback transport, for set and unset */ 166 char *loopback_vc; /* COTS loopback transport, for set and unset */ 167 char *loopback_vc_ord; /* COTS_ORD loopback transport, for set and unset */ 168 169 volatile boolean_t verboselog = B_FALSE; 170 volatile boolean_t wrap_enabled = B_FALSE; 171 volatile boolean_t allow_indirect = B_TRUE; 172 volatile boolean_t local_only = B_TRUE; 173 174 /* Local Variable */ 175 static int warmstart = 0; /* Grab a old copy of registrations */ 176 177 #ifdef PORTMAP 178 /* 179 * list_pml_lock protects list_pml 180 * lock order: list_rbl_lock, list_pml_lock 181 */ 182 rwlock_t list_pml_lock = DEFAULTRWLOCK; 183 PMAPLIST *list_pml; /* A list of version 2 rpcbind services */ 184 185 char *udptrans; /* Name of UDP transport */ 186 char *tcptrans; /* Name of TCP transport */ 187 char *udp_uaddr; /* Universal UDP address */ 188 char *tcp_uaddr; /* Universal TCP address */ 189 #endif 190 static char servname[] = "rpcbind"; 191 static char superuser[] = "superuser"; 192 193 static const char daemon_dir[] = DAEMON_DIR; 194 195 static void 196 block_signals(void) 197 { 198 (void) sigemptyset(&sigwaitset); 199 (void) sigaddset(&sigwaitset, SIGINT); 200 (void) sigaddset(&sigwaitset, SIGTERM); 201 (void) sigaddset(&sigwaitset, SIGQUIT); 202 (void) sigaddset(&sigwaitset, SIGHUP); 203 (void) sigprocmask(SIG_BLOCK, &sigwaitset, NULL); 204 205 /* ignore other signals that could get sent */ 206 (void) signal(SIGUSR1, SIG_IGN); 207 (void) signal(SIGUSR2, SIG_IGN); 208 } 209 210 int 211 main(int argc, char *argv[]) 212 { 213 struct netconfig *nconf; 214 void *nc_handle; /* Net config handle */ 215 struct rlimit rl; 216 int rpc_svc_fdunlim = 1; 217 int rpc_svc_mode = RPC_SVC_MT_AUTO; 218 int maxrecsz = RPC_MAXDATASIZE; 219 boolean_t can_do_mlp; 220 221 block_signals(); 222 223 parseargs(argc, argv); 224 225 if (getrlimit(RLIMIT_NOFILE, &rl) != 0) { 226 syslog(LOG_ERR, "getrlimit failed"); 227 } else { 228 rl.rlim_cur = rl.rlim_max; 229 if (setrlimit(RLIMIT_NOFILE, &rl) != 0) 230 syslog(LOG_ERR, "setrlimit failed"); 231 } 232 (void) enable_extended_FILE_stdio(-1, -1); 233 234 openlog("rpcbind", LOG_CONS, LOG_DAEMON); 235 236 /* 237 * Create the daemon directory in /var/run 238 */ 239 if (mkdir(daemon_dir, DAEMON_DIR_MODE) == 0 || errno == EEXIST) { 240 chmod(daemon_dir, DAEMON_DIR_MODE); 241 chown(daemon_dir, DAEMON_UID, DAEMON_GID); 242 } else { 243 syslog(LOG_ERR, "failed to create \"%s\": %m", daemon_dir); 244 } 245 246 /* 247 * These privileges are required for the t_bind check rpcbind uses 248 * to determine whether a service is still live or not. 249 */ 250 can_do_mlp = priv_ineffect(PRIV_NET_BINDMLP); 251 if (__init_daemon_priv(PU_RESETGROUPS|PU_CLEARLIMITSET, DAEMON_UID, 252 DAEMON_GID, PRIV_NET_PRIVADDR, PRIV_SYS_NFS, 253 can_do_mlp ? PRIV_NET_BINDMLP : NULL, NULL) == -1) { 254 fprintf(stderr, "Insufficient privileges\n"); 255 exit(1); 256 } 257 258 myzone = getzoneid(); 259 260 /* 261 * Set number of file descriptors to unlimited 262 */ 263 if (!rpc_control(RPC_SVC_USE_POLLFD, &rpc_svc_fdunlim)) { 264 syslog(LOG_INFO, "unable to set number of FD to unlimited"); 265 } 266 267 /* 268 * Tell RPC that we want automatic thread mode. 269 * A new thread will be spawned for each request. 270 */ 271 if (!rpc_control(RPC_SVC_MTMODE_SET, &rpc_svc_mode)) { 272 syslog(LOG_ERR, "unable to set automatic MT mode"); 273 exit(1); 274 } 275 276 /* 277 * Enable non-blocking mode and maximum record size checks for 278 * connection oriented transports. 279 */ 280 if (!rpc_control(RPC_SVC_CONNMAXREC_SET, &maxrecsz)) { 281 syslog(LOG_INFO, "unable to set RPC max record size"); 282 } 283 284 { 285 /* 286 * rpcbind is the first application to encounter the 287 * various netconfig files. check_netconfig() verifies 288 * that they are set up correctly and complains loudly 289 * if not. 290 */ 291 int trouble; 292 293 trouble = check_netconfig(); 294 if (trouble) { 295 syslog(LOG_ERR, "%s: found %d errors with network " 296 "configuration files. Exiting.", argv[0], trouble); 297 fprintf(stderr, "%s: found %d errors with network " 298 "configuration files. Exiting.\n", 299 argv[0], trouble); 300 exit(1); 301 } 302 } 303 304 loopback_dg = ""; 305 loopback_vc = ""; 306 loopback_vc_ord = ""; 307 #ifdef PORTMAP 308 udptrans = ""; 309 tcptrans = ""; 310 #endif 311 312 ipv6flag = Is_ipv6present(); 313 rpcb_check_init(); 314 315 nc_handle = setnetconfig(); /* open netconfig file */ 316 if (nc_handle == NULL) { 317 syslog(LOG_ERR, "could not read /etc/netconfig"); 318 exit(1); 319 } 320 while ((nconf = getnetconfig(nc_handle)) != NULL) { 321 if (nconf->nc_flag & NC_VISIBLE) 322 init_transport(nconf); 323 } 324 endnetconfig(nc_handle); 325 326 if ((loopback_dg[0] == NULL) && (loopback_vc[0] == NULL) && 327 (loopback_vc_ord[0] == NULL)) { 328 syslog(LOG_ERR, "could not find loopback transports"); 329 exit(1); 330 } 331 332 if (warmstart) { 333 read_warmstart(); 334 } 335 336 /* Create terminate signal handler for graceful exit */ 337 if (thr_create(NULL, 0, (void *(*)(void *))terminate, NULL, 0, NULL)) { 338 syslog(LOG_ERR, "Failed to create terminate thread"); 339 exit(1); 340 } 341 342 if (debugging) { 343 printf("rpcbind debugging enabled."); 344 if (doabort) { 345 printf(" Will abort on errors!\n"); 346 } else { 347 printf("\n"); 348 } 349 } else { 350 detachfromtty(); 351 } 352 353 /* These are basic privileges we do not need */ 354 __fini_daemon_priv(PRIV_PROC_EXEC, PRIV_PROC_SESSION, 355 PRIV_FILE_LINK_ANY, PRIV_PROC_INFO, (char *)NULL); 356 357 svc_run(); 358 syslog(LOG_ERR, "svc_run returned unexpectedly"); 359 rpcbind_abort(); 360 /* NOTREACHED */ 361 } 362 363 /* 364 * Increments a counter each time a problem is found with the network 365 * configuration information. 366 */ 367 static int 368 check_netconfig(void) 369 { 370 void *nc; 371 void *dlcookie; 372 int busted = 0; 373 int i; 374 int lo_clts_found = 0, lo_cots_found = 0, lo_cotsord_found = 0; 375 struct netconfig *nconf, *np; 376 struct stat sb; 377 378 nc = setnetconfig(); 379 if (nc == NULL) { 380 if (debugging) 381 fprintf(stderr, 382 "setnetconfig() failed: %s\n", nc_sperror()); 383 syslog(LOG_ALERT, "setnetconfig() failed: %s", nc_sperror()); 384 return (1); 385 } 386 while ((np = getnetconfig(nc)) != NULL) { 387 if ((np->nc_flag & NC_VISIBLE) == 0) 388 continue; 389 if (debugging) 390 fprintf(stderr, "checking netid \"%s\"\n", 391 np->nc_netid); 392 if (strcmp(np->nc_protofmly, NC_LOOPBACK) == 0) 393 switch (np->nc_semantics) { 394 case NC_TPI_CLTS: 395 lo_clts_found = 1; 396 break; 397 398 case NC_TPI_COTS: 399 lo_cots_found = 1; 400 break; 401 402 case NC_TPI_COTS_ORD: 403 lo_cotsord_found = 1; 404 break; 405 } 406 if (stat(np->nc_device, &sb) == -1 && errno == ENOENT) { 407 if (debugging) 408 fprintf(stderr, "\tdevice %s does not exist\n", 409 np->nc_device); 410 syslog(LOG_ERR, "netid %s: device %s does not exist", 411 np->nc_netid, np->nc_device); 412 busted++; 413 } else 414 if (debugging) 415 fprintf(stderr, "\tdevice %s present\n", 416 np->nc_device); 417 for (i = 0; i < np->nc_nlookups; i++) { 418 char *libname = np->nc_lookups[i]; 419 420 if ((dlcookie = dlopen(libname, RTLD_LAZY)) == NULL) { 421 char *dlerrstr; 422 423 dlerrstr = dlerror(); 424 if (debugging) { 425 fprintf(stderr, "\tnetid %s: dlopen of " 426 "name-to-address library %s " 427 "failed\ndlerror: %s", 428 np->nc_netid, libname, 429 dlerrstr ? dlerrstr : ""); 430 } 431 syslog(LOG_ERR, "netid %s: dlopen of " 432 "name-to-address library %s failed", 433 np->nc_netid, libname); 434 if (dlerrstr) 435 syslog(LOG_ERR, "%s", dlerrstr); 436 busted++; 437 } else { 438 if (debugging) 439 fprintf(stderr, "\tdlopen of " 440 "name-to-address library %s " 441 "succeeded\n", libname); 442 (void) dlclose(dlcookie); 443 } 444 } 445 nconf = getnetconfigent(np->nc_netid); 446 447 if (!check_hostserv(nconf, HOST_SELF, "")) 448 busted++; 449 if (!check_hostserv(nconf, HOST_SELF_CONNECT, "")) 450 busted++; 451 if (!check_hostserv(nconf, HOST_SELF, "rpcbind")) 452 busted++; 453 if (!check_hostserv(nconf, HOST_SELF_CONNECT, "rpcbind")) 454 busted++; 455 456 freenetconfigent(nconf); 457 } 458 endnetconfig(nc); 459 460 if (lo_clts_found) { 461 if (debugging) 462 fprintf(stderr, "Found CLTS loopback transport\n"); 463 } else { 464 syslog(LOG_ALERT, "no CLTS loopback transport found\n"); 465 if (debugging) 466 fprintf(stderr, "no CLTS loopback transport found\n"); 467 } 468 if (lo_cots_found) { 469 if (debugging) 470 fprintf(stderr, "Found COTS loopback transport\n"); 471 } else { 472 syslog(LOG_ALERT, "no COTS loopback transport found\n"); 473 if (debugging) 474 fprintf(stderr, "no COTS loopback transport found\n"); 475 } 476 if (lo_cotsord_found) { 477 if (debugging) 478 fprintf(stderr, "Found COTS ORD loopback transport\n"); 479 } else { 480 syslog(LOG_ALERT, "no COTS ORD loopback transport found\n"); 481 if (debugging) 482 fprintf(stderr, 483 "no COTS ORD loopback transport found\n"); 484 } 485 486 return (busted); 487 } 488 489 /* 490 * Adds the entry into the rpcbind database. 491 * If PORTMAP, then for UDP and TCP, it adds the entries for version 2 also 492 * Returns 0 if succeeds, else fails 493 */ 494 static int 495 init_transport(struct netconfig *nconf) 496 { 497 int fd; 498 struct t_bind *taddr, *baddr; 499 SVCXPRT *my_xprt; 500 struct nd_addrlist *nas; 501 struct nd_hostserv hs; 502 static int msgprt = 0; 503 504 if ((nconf->nc_semantics != NC_TPI_CLTS) && 505 (nconf->nc_semantics != NC_TPI_COTS) && 506 (nconf->nc_semantics != NC_TPI_COTS_ORD)) 507 return (1); /* not my type */ 508 509 if ((strcmp(nconf->nc_protofmly, NC_INET6) == 0) && !ipv6flag) { 510 if (!msgprt) 511 syslog(LOG_DEBUG, "/etc/netconfig has IPv6 entries but " 512 "IPv6 is not configured"); 513 msgprt++; 514 return (1); 515 } 516 517 if ((fd = t_open(nconf->nc_device, O_RDWR, NULL)) < 0) { 518 syslog(LOG_ERR, "%s: cannot open connection: %s", 519 nconf->nc_netid, t_errlist[t_errno]); 520 return (1); 521 } 522 523 if (is_system_labeled() && 524 (strcmp(nconf->nc_protofmly, NC_INET) == 0 || 525 strcmp(nconf->nc_protofmly, NC_INET6) == 0) && 526 setopt_anon_mlp(fd) == -1) { 527 syslog(LOG_ERR, "%s: couldn't set SO_ANON_MLP option", 528 nconf->nc_netid); 529 } 530 531 /* 532 * Negotiate for returning the ucred of the caller. This should 533 * done before enabling the endpoint for service via 534 * t_bind() so that requests to rpcbind contain the uid. 535 */ 536 svc_fd_negotiate_ucred(fd); 537 538 taddr = (struct t_bind *)t_alloc(fd, T_BIND, T_ADDR); 539 baddr = (struct t_bind *)t_alloc(fd, T_BIND, T_ADDR); 540 if ((baddr == NULL) || (taddr == NULL)) { 541 syslog(LOG_ERR, "%s: cannot allocate netbuf: %s", 542 nconf->nc_netid, t_errlist[t_errno]); 543 exit(1); 544 } 545 546 /* Get rpcbind's address on this transport */ 547 hs.h_host = HOST_SELF; 548 hs.h_serv = servname; 549 if (netdir_getbyname(nconf, &hs, &nas)) 550 goto error; 551 552 /* Copy the address */ 553 taddr->addr.len = nas->n_addrs->len; 554 memcpy(taddr->addr.buf, nas->n_addrs->buf, (int)nas->n_addrs->len); 555 netdir_free((char *)nas, ND_ADDRLIST); 556 557 if (nconf->nc_semantics == NC_TPI_CLTS) 558 taddr->qlen = 0; 559 else 560 taddr->qlen = listen_backlog; 561 562 if (strcmp(nconf->nc_proto, NC_TCP) == 0) { 563 /* 564 * Sm: If we are running then set SO_REUSEADDR option 565 * so that we can bind to our preferred address even if 566 * previous connections are in FIN_WAIT state 567 */ 568 if (setopt_reuseaddr(fd) == -1) { 569 syslog(LOG_ERR, "Couldn't set SO_REUSEADDR option"); 570 } 571 } 572 573 if (t_bind(fd, taddr, baddr) != 0) { 574 syslog(LOG_ERR, "%s: cannot bind: %s", 575 nconf->nc_netid, t_errlist[t_errno]); 576 goto error; 577 } 578 579 if (nconf->nc_semantics != NC_TPI_CLTS && taddr->qlen != baddr->qlen) 580 syslog(LOG_NOTICE, "%s: unable to set listen backlog to %d " 581 "(negotiated: %d)", nconf->nc_netid, taddr->qlen, 582 baddr->qlen); 583 584 if (memcmp(taddr->addr.buf, baddr->addr.buf, (int)baddr->addr.len)) { 585 syslog(LOG_ERR, "%s: address in use", nconf->nc_netid); 586 goto error; 587 } 588 589 my_xprt = svc_tli_create(fd, nconf, baddr, 0, 0); 590 if (my_xprt == NULL) { 591 syslog(LOG_ERR, "%s: could not create service", 592 nconf->nc_netid); 593 goto error; 594 } 595 596 /* set up multicast address for RPC CALL_IT, IPv6 */ 597 598 if ((strcmp(nconf->nc_protofmly, NC_INET6) == 0) && 599 (strcmp(nconf->nc_proto, NC_UDP) == 0)) { 600 if (setup_callit(fd) < 0) { 601 syslog(LOG_ERR, "Unable to join IPv6 multicast group " 602 "for rpc broadcast %s", RPCB_MULTICAST_ADDR); 603 } 604 } 605 606 if (strcmp(nconf->nc_proto, NC_TCP) == 0) { 607 svc_control(my_xprt, SVCSET_KEEPALIVE, (void *) TRUE); 608 } 609 610 #ifdef PORTMAP 611 /* 612 * Register both the versions for tcp/ip and udp/ip 613 */ 614 if ((strcmp(nconf->nc_protofmly, NC_INET) == 0) && 615 ((strcmp(nconf->nc_proto, NC_TCP) == 0) || 616 (strcmp(nconf->nc_proto, NC_UDP) == 0))) { 617 PMAPLIST *pml; 618 619 if (!svc_register(my_xprt, PMAPPROG, PMAPVERS, 620 pmap_service, NULL)) { 621 syslog(LOG_ERR, "could not register on %s", 622 nconf->nc_netid); 623 goto error; 624 } 625 pml = malloc(sizeof (PMAPLIST)); 626 if (pml == NULL) { 627 syslog(LOG_ERR, "no memory!"); 628 exit(1); 629 } 630 pml->pml_map.pm_prog = PMAPPROG; 631 pml->pml_map.pm_vers = PMAPVERS; 632 pml->pml_map.pm_port = PMAPPORT; 633 if (strcmp(nconf->nc_proto, NC_TCP) == 0) { 634 if (tcptrans[0]) { 635 syslog(LOG_ERR, 636 "cannot have more than one TCP transport"); 637 goto error; 638 } 639 tcptrans = strdup(nconf->nc_netid); 640 pml->pml_map.pm_prot = IPPROTO_TCP; 641 642 /* Let's snarf the universal address */ 643 /* "h1.h2.h3.h4.p1.p2" */ 644 tcp_uaddr = taddr2uaddr(nconf, &baddr->addr); 645 } else { 646 if (udptrans[0]) { 647 syslog(LOG_ERR, 648 "cannot have more than one UDP transport"); 649 goto error; 650 } 651 udptrans = strdup(nconf->nc_netid); 652 pml->pml_map.pm_prot = IPPROTO_UDP; 653 654 /* Let's snarf the universal address */ 655 /* "h1.h2.h3.h4.p1.p2" */ 656 udp_uaddr = taddr2uaddr(nconf, &baddr->addr); 657 } 658 pml->pml_next = list_pml; 659 list_pml = pml; 660 661 /* Add version 3 information */ 662 pml = malloc(sizeof (PMAPLIST)); 663 if (pml == NULL) { 664 syslog(LOG_ERR, "no memory!"); 665 exit(1); 666 } 667 pml->pml_map = list_pml->pml_map; 668 pml->pml_map.pm_vers = RPCBVERS; 669 pml->pml_next = list_pml; 670 list_pml = pml; 671 672 /* Add version 4 information */ 673 pml = malloc(sizeof (PMAPLIST)); 674 if (pml == NULL) { 675 syslog(LOG_ERR, "no memory!"); 676 exit(1); 677 } 678 pml->pml_map = list_pml->pml_map; 679 pml->pml_map.pm_vers = RPCBVERS4; 680 pml->pml_next = list_pml; 681 list_pml = pml; 682 683 /* Also add version 2 stuff to rpcbind list */ 684 rbllist_add(PMAPPROG, PMAPVERS, nconf, &baddr->addr); 685 } 686 #endif 687 688 /* version 3 registration */ 689 if (!svc_reg(my_xprt, RPCBPROG, RPCBVERS, rpcb_service_3, NULL)) { 690 syslog(LOG_ERR, "could not register %s version 3", 691 nconf->nc_netid); 692 goto error; 693 } 694 rbllist_add(RPCBPROG, RPCBVERS, nconf, &baddr->addr); 695 696 /* version 4 registration */ 697 if (!svc_reg(my_xprt, RPCBPROG, RPCBVERS4, rpcb_service_4, NULL)) { 698 syslog(LOG_ERR, "could not register %s version 4", 699 nconf->nc_netid); 700 goto error; 701 } 702 rbllist_add(RPCBPROG, RPCBVERS4, nconf, &baddr->addr); 703 704 if (strcmp(nconf->nc_protofmly, NC_LOOPBACK) == 0) { 705 if (nconf->nc_semantics == NC_TPI_CLTS) 706 loopback_dg = strdup(nconf->nc_netid); 707 else if (nconf->nc_semantics == NC_TPI_COTS) 708 loopback_vc = strdup(nconf->nc_netid); 709 else if (nconf->nc_semantics == NC_TPI_COTS_ORD) 710 loopback_vc_ord = strdup(nconf->nc_netid); 711 } 712 713 /* decide if bound checking works for this transport */ 714 (void) add_bndlist(nconf, taddr, baddr); 715 716 /* 717 * rmtcall only supported on CLTS transports for now. 718 */ 719 if (nconf->nc_semantics == NC_TPI_CLTS) 720 (void) create_rmtcall_fd(nconf); 721 722 (void) t_free((char *)taddr, T_BIND); 723 (void) t_free((char *)baddr, T_BIND); 724 return (0); 725 error: 726 (void) t_free((char *)taddr, T_BIND); 727 (void) t_free((char *)baddr, T_BIND); 728 (void) t_close(fd); 729 return (1); 730 } 731 732 static void 733 rbllist_add(ulong_t prog, ulong_t vers, struct netconfig *nconf, 734 struct netbuf *addr) 735 { 736 rpcblist_ptr rbl; 737 738 rbl = malloc(sizeof (rpcblist)); 739 if (rbl == NULL) { 740 syslog(LOG_ERR, "no memory!"); 741 exit(1); 742 } 743 744 rbl->rpcb_map.r_prog = prog; 745 rbl->rpcb_map.r_vers = vers; 746 rbl->rpcb_map.r_netid = strdup(nconf->nc_netid); 747 rbl->rpcb_map.r_addr = taddr2uaddr(nconf, addr); 748 if (rbl->rpcb_map.r_addr == NULL) 749 rbl->rpcb_map.r_addr = strdup(""); 750 rbl->rpcb_map.r_owner = strdup(superuser); 751 752 if (rbl->rpcb_map.r_netid == NULL || rbl->rpcb_map.r_addr == NULL || 753 rbl->rpcb_map.r_owner == NULL) { 754 syslog(LOG_ERR, "no memory!"); 755 exit(1); 756 } 757 758 rbl->rpcb_next = list_rbl; /* Attach to global list */ 759 list_rbl = rbl; 760 } 761 762 /* 763 * Catch the signal and die, if not SIGHUP 764 */ 765 static void 766 terminate(void) 767 { 768 int sig; 769 770 for (;;) { 771 sig = sigwait(&sigwaitset); 772 if (sig == SIGHUP) { 773 rpcb_check_init(); 774 continue; 775 } 776 if (sig != -1 || errno != EINTR) 777 break; 778 } 779 780 syslog(LOG_ERR, "rpcbind terminating on signal %d.", sig); 781 782 rw_wrlock(&list_rbl_lock); 783 #ifdef PORTMAP 784 rw_wrlock(&list_pml_lock); 785 #endif 786 write_warmstart(); /* Dump yourself */ 787 788 exit(2); 789 } 790 791 void 792 rpcbind_abort(void) 793 { 794 /* 795 * We need to hold write locks to make sure 796 * write_warmstart() is executed exactly once 797 */ 798 rw_wrlock(&list_rbl_lock); 799 #ifdef PORTMAP 800 rw_wrlock(&list_pml_lock); 801 #endif 802 write_warmstart(); /* Dump yourself */ 803 804 abort(); 805 } 806 807 /* 808 * detach from tty 809 */ 810 static void 811 detachfromtty(void) 812 { 813 close(0); 814 close(1); 815 close(2); 816 switch (forkall()) { 817 case (pid_t)-1: 818 perror("fork"); 819 break; 820 case 0: 821 break; 822 default: 823 exit(0); 824 } 825 setsid(); 826 (void) open("/dev/null", O_RDWR, 0); 827 dup(0); 828 dup(0); 829 } 830 831 static int 832 convert_int(int *val, char *str) 833 { 834 long lval; 835 836 if (str == NULL || !isdigit(*str)) 837 return (-1); 838 839 lval = strtol(str, &str, 10); 840 if (*str != '\0' || lval > INT_MAX) 841 return (-2); 842 843 *val = (int)lval; 844 return (0); 845 } 846 847 static int get_smf_iprop(const char *, int, int, int); 848 849 /* get command line options */ 850 static void 851 parseargs(int argc, char *argv[]) 852 { 853 int c; 854 int tmp; 855 856 listen_backlog = get_smf_iprop("listen_backlog", 64, 1, INT_MAX); 857 858 while ((c = getopt(argc, argv, "dwal:")) != EOF) { 859 switch (c) { 860 case 'd': 861 debugging = 1; 862 break; 863 case 'a': 864 doabort = 1; /* when debugging, do an abort on */ 865 break; /* errors; for rpcbind developers */ 866 /* only! */ 867 case 'w': 868 warmstart = 1; 869 break; 870 871 case 'l': 872 if (convert_int(&tmp, optarg) != 0 || tmp < 1) { 873 (void) fprintf(stderr, "%s: invalid " 874 "listen_backlog option, using defaults\n", 875 argv[0]); 876 break; 877 } 878 listen_backlog = tmp; 879 break; 880 default: /* error */ 881 fprintf(stderr, 882 "usage: rpcbind [-d] [-w] [-l listen_backlog]\n"); 883 exit(1); 884 } 885 } 886 if (doabort && !debugging) { 887 fprintf(stderr, 888 "-a (abort) specified without -d " 889 "(debugging) -- ignored.\n"); 890 doabort = 0; 891 } 892 } 893 894 static int 895 setopt_int(int fd, int level, int name, int value) 896 { 897 struct t_optmgmt req, resp; 898 struct { 899 struct opthdr opt; 900 int value; 901 } optdata; 902 903 optdata.opt.level = level; 904 optdata.opt.name = name; 905 optdata.opt.len = sizeof (int); 906 907 optdata.value = value; 908 909 req.flags = T_NEGOTIATE; 910 req.opt.len = sizeof (optdata); 911 req.opt.buf = (char *)&optdata; 912 913 resp.flags = 0; 914 resp.opt.buf = (char *)&optdata; 915 resp.opt.maxlen = sizeof (optdata); 916 917 if (t_optmgmt(fd, &req, &resp) < 0 || resp.flags != T_SUCCESS) { 918 t_error("t_optmgmt"); 919 return (-1); 920 } 921 return (0); 922 } 923 924 static int 925 setopt_reuseaddr(int fd) 926 { 927 return (setopt_int(fd, SOL_SOCKET, SO_REUSEADDR, 1)); 928 } 929 930 static int 931 setopt_anon_mlp(int fd) 932 { 933 return (setopt_int(fd, SOL_SOCKET, SO_ANON_MLP, 1)); 934 } 935 936 static int 937 setup_callit(int fd) 938 { 939 struct ipv6_mreq mreq; 940 struct t_optmgmt req, resp; 941 struct opthdr *opt; 942 char reqbuf[ sizeof (struct ipv6_mreq) + 24]; 943 struct ipv6_mreq *pmreq; 944 945 opt = (struct opthdr *)reqbuf; 946 947 opt->level = IPPROTO_IPV6; 948 opt->name = IPV6_ADD_MEMBERSHIP; 949 opt->len = sizeof (struct ipv6_mreq); 950 951 /* multicast address */ 952 (void) inet_pton(AF_INET6, RPCB_MULTICAST_ADDR, 953 mreq.ipv6mr_multiaddr.s6_addr); 954 mreq.ipv6mr_interface = 0; 955 956 /* insert it into opt */ 957 pmreq = (struct ipv6_mreq *)&reqbuf[sizeof (struct opthdr)]; 958 memcpy(pmreq, &mreq, sizeof (struct ipv6_mreq)); 959 960 req.flags = T_NEGOTIATE; 961 req.opt.len = sizeof (struct opthdr) + opt->len; 962 req.opt.buf = (char *)opt; 963 964 resp.flags = 0; 965 resp.opt.buf = reqbuf; 966 resp.opt.maxlen = sizeof (reqbuf); 967 968 if (t_optmgmt(fd, &req, &resp) < 0 || resp.flags != T_SUCCESS) { 969 t_error("t_optmgmt"); 970 return (-1); 971 } 972 return (0); 973 } 974 975 static boolean_t 976 check_hostserv(struct netconfig *nconf, const char *host, const char *serv) 977 { 978 struct nd_hostserv nh; 979 struct nd_addrlist *na; 980 const char *hostname = host; 981 const char *servname = serv; 982 int retval; 983 984 if (strcmp(host, HOST_SELF) == 0) 985 hostname = "HOST_SELF"; 986 else if (strcmp(host, HOST_SELF_CONNECT) == 0) 987 hostname = "HOST_SELF_CONNECT"; 988 989 if (serv[0] == '\0') 990 servname = "<any>"; 991 992 nh.h_host = (char *)host; 993 nh.h_serv = (char *)serv; 994 995 retval = netdir_getbyname(nconf, &nh, &na); 996 if (retval != ND_OK || na->n_cnt == 0) { 997 if (retval == ND_OK) 998 netdir_free(na, ND_ADDRLIST); 999 1000 syslog(LOG_ALERT, "netid %s: cannot find an address for host " 1001 "%s, service \"%s\"", nconf->nc_netid, hostname, servname); 1002 if (debugging) { 1003 (void) fprintf(stderr, "\tnetdir_getbyname for %s, " 1004 "service \"%s\" failed\n", hostname, servname); 1005 } 1006 return (B_FALSE); 1007 } 1008 netdir_free(na, ND_ADDRLIST); 1009 1010 if (debugging) { 1011 (void) fprintf(stderr, "\tnetdir_getbyname for %s, service " 1012 "service \"%s\" succeeded\n", hostname, servname); 1013 } 1014 return (B_TRUE); 1015 } 1016 1017 /* Maximum outstanding syslog requests */ 1018 #define MAXLOG 100 1019 /* Maximum length: the messages generated are fairly short; no hostnames. */ 1020 #define MAXMSG 128 1021 1022 typedef struct logmsg { 1023 struct logmsg *log_next; 1024 int log_pri; 1025 char log_msg[MAXMSG]; 1026 } logmsg; 1027 1028 static logmsg *loghead = NULL; 1029 static logmsg **logtailp = &loghead; 1030 static mutex_t logmutex = DEFAULTMUTEX; 1031 static cond_t logcond = DEFAULTCV; 1032 static int logcount = 0; 1033 1034 /* ARGSUSED */ 1035 static void * __NORETURN 1036 logthread(void *arg) 1037 { 1038 for (;;) { 1039 logmsg *msg; 1040 (void) mutex_lock(&logmutex); 1041 while ((msg = loghead) == NULL) 1042 (void) cond_wait(&logcond, &logmutex); 1043 1044 loghead = msg->log_next; 1045 logcount--; 1046 if (loghead == NULL) { 1047 logtailp = &loghead; 1048 logcount = 0; 1049 } 1050 (void) mutex_unlock(&logmutex); 1051 syslog(msg->log_pri, "%s", msg->log_msg); 1052 free(msg); 1053 } 1054 /* NOTREACHED */ 1055 } 1056 1057 static boolean_t 1058 get_smf_prop(const char *var, boolean_t def_val) 1059 { 1060 scf_simple_prop_t *prop; 1061 uint8_t *val = NULL; 1062 boolean_t res = def_val; 1063 1064 prop = scf_simple_prop_get(NULL, NULL, "config", var); 1065 if (prop != NULL) { 1066 if ((val = scf_simple_prop_next_boolean(prop)) != NULL) 1067 res = (*val == 0) ? B_FALSE : B_TRUE; 1068 scf_simple_prop_free(prop); 1069 } 1070 1071 if (prop == NULL || val == NULL) { 1072 syslog(LOG_ALERT, "no value for config/%s (%s). " 1073 "Using default \"%s\"", var, scf_strerror(scf_error()), 1074 def_val ? "true" : "false"); 1075 } 1076 1077 return (res); 1078 } 1079 1080 static int 1081 get_smf_iprop(const char *var, int def_val, int min, int max) 1082 { 1083 scf_simple_prop_t *prop; 1084 int64_t *val = NULL; 1085 int res = def_val; 1086 1087 prop = scf_simple_prop_get(NULL, NULL, "config", var); 1088 if (prop != NULL) { 1089 if ((val = scf_simple_prop_next_integer(prop)) != NULL) { 1090 if (*val < min || *val > max) 1091 syslog(LOG_ALERT, "value for config/%s out of " 1092 "range. Using default %d", var, def_val); 1093 else 1094 res = (int)*val; 1095 } 1096 scf_simple_prop_free(prop); 1097 } 1098 1099 if (prop == NULL || val == NULL) { 1100 syslog(LOG_ALERT, "no value for config/%s (%s). " 1101 "Using default %d", var, scf_strerror(scf_error()), 1102 def_val); 1103 } 1104 1105 return (res); 1106 } 1107 1108 /* 1109 * Initialize: read the configuration parameters from SMF. 1110 * This function must be idempotent because it can be called from the 1111 * signal handler. 1112 */ 1113 static void 1114 rpcb_check_init(void) 1115 { 1116 thread_t tid; 1117 int max_threads; 1118 static int thr_running; 1119 1120 wrap_enabled = get_smf_prop("enable_tcpwrappers", B_FALSE); 1121 verboselog = get_smf_prop("verbose_logging", B_FALSE); 1122 allow_indirect = get_smf_prop("allow_indirect", B_TRUE); 1123 local_only = get_smf_prop("local_only", B_TRUE); 1124 1125 if (wrap_enabled && !thr_running) { 1126 (void) thr_create(NULL, 0, logthread, NULL, THR_DETACHED, &tid); 1127 thr_running = 1; 1128 } 1129 1130 /* 1131 * Set the maximum number of threads. 1132 */ 1133 max_threads = get_smf_iprop("max_threads", 72, 1, INT_MAX); 1134 if (!rpc_control(RPC_SVC_THRMAX_SET, &max_threads)) { 1135 int tmp; 1136 1137 /* 1138 * The following rpc_control() call cannot fail 1139 */ 1140 if (!rpc_control(RPC_SVC_THRMAX_GET, &tmp)) 1141 assert(0); 1142 1143 if (tmp != max_threads) { 1144 syslog(LOG_ERR, "setting max_threads to %d failed, " 1145 "using %d worker threads", max_threads, tmp); 1146 max_threads = tmp; 1147 } 1148 } 1149 1150 /* 1151 * Set rpcb_rmtcalls_max. 1152 */ 1153 if (max_threads < reserved_threads) 1154 set_rpcb_rmtcalls_max(0); 1155 else 1156 set_rpcb_rmtcalls_max(max_threads - reserved_threads); 1157 } 1158 1159 /* 1160 * qsyslog() - queue a request for syslog(); if syslog blocks, the other 1161 * thread blocks; we make sure we don't run out of memory by allowing 1162 * only a limited number of outstandig syslog() requests. 1163 */ 1164 void 1165 qsyslog(int pri, const char *fmt, ...) 1166 { 1167 logmsg *msg = malloc(sizeof (*msg)); 1168 va_list ap; 1169 1170 if (msg == NULL) 1171 return; 1172 1173 msg->log_pri = pri; 1174 1175 va_start(ap, fmt); 1176 (void) vsnprintf(msg->log_msg, sizeof (msg->log_msg), fmt, ap); 1177 va_end(ap); 1178 1179 msg->log_next = NULL; 1180 1181 (void) mutex_lock(&logmutex); 1182 if (logcount < MAXLOG) { 1183 if (logcount == 0) 1184 (void) cond_signal(&logcond); 1185 logcount++; 1186 *logtailp = msg; 1187 logtailp = &msg->log_next; 1188 (void) mutex_unlock(&logmutex); 1189 } else { 1190 (void) mutex_unlock(&logmutex); 1191 free(msg); 1192 } 1193 } 1194