inetd.c revision 146187
1/* 2 * Copyright (c) 1983, 1991, 1993, 1994 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 4. Neither the name of the University nor the names of its contributors 14 * may be used to endorse or promote products derived from this software 15 * without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30#ifndef lint 31static const char copyright[] = 32"@(#) Copyright (c) 1983, 1991, 1993, 1994\n\ 33 The Regents of the University of California. All rights reserved.\n"; 34#endif /* not lint */ 35 36#ifndef lint 37#if 0 38static char sccsid[] = "@(#)from: inetd.c 8.4 (Berkeley) 4/13/94"; 39#endif 40#endif /* not lint */ 41 42#include <sys/cdefs.h> 43__FBSDID("$FreeBSD: head/usr.sbin/inetd/inetd.c 146187 2005-05-13 16:31:11Z ume $"); 44 45/* 46 * Inetd - Internet super-server 47 * 48 * This program invokes all internet services as needed. Connection-oriented 49 * services are invoked each time a connection is made, by creating a process. 50 * This process is passed the connection as file descriptor 0 and is expected 51 * to do a getpeername to find out the source host and port. 52 * 53 * Datagram oriented services are invoked when a datagram 54 * arrives; a process is created and passed a pending message 55 * on file descriptor 0. Datagram servers may either connect 56 * to their peer, freeing up the original socket for inetd 57 * to receive further messages on, or ``take over the socket'', 58 * processing all arriving datagrams and, eventually, timing 59 * out. The first type of server is said to be ``multi-threaded''; 60 * the second type of server ``single-threaded''. 61 * 62 * Inetd uses a configuration file which is read at startup 63 * and, possibly, at some later time in response to a hangup signal. 64 * The configuration file is ``free format'' with fields given in the 65 * order shown below. Continuation lines for an entry must begin with 66 * a space or tab. All fields must be present in each entry. 67 * 68 * service name must be in /etc/services 69 * or name a tcpmux service 70 * or specify a unix domain socket 71 * socket type stream/dgram/raw/rdm/seqpacket 72 * protocol tcp[4][6][/faith,ttcp], udp[4][6], unix 73 * wait/nowait single-threaded/multi-threaded 74 * user user to run daemon as 75 * server program full path name 76 * server program arguments maximum of MAXARGS (20) 77 * 78 * TCP services without official port numbers are handled with the 79 * RFC1078-based tcpmux internal service. Tcpmux listens on port 1 for 80 * requests. When a connection is made from a foreign host, the service 81 * requested is passed to tcpmux, which looks it up in the servtab list 82 * and returns the proper entry for the service. Tcpmux returns a 83 * negative reply if the service doesn't exist, otherwise the invoked 84 * server is expected to return the positive reply if the service type in 85 * inetd.conf file has the prefix "tcpmux/". If the service type has the 86 * prefix "tcpmux/+", tcpmux will return the positive reply for the 87 * process; this is for compatibility with older server code, and also 88 * allows you to invoke programs that use stdin/stdout without putting any 89 * special server code in them. Services that use tcpmux are "nowait" 90 * because they do not have a well-known port and hence cannot listen 91 * for new requests. 92 * 93 * For RPC services 94 * service name/version must be in /etc/rpc 95 * socket type stream/dgram/raw/rdm/seqpacket 96 * protocol rpc/tcp[4][6], rpc/udp[4][6] 97 * wait/nowait single-threaded/multi-threaded 98 * user user to run daemon as 99 * server program full path name 100 * server program arguments maximum of MAXARGS 101 * 102 * Comment lines are indicated by a `#' in column 1. 103 * 104 * #ifdef IPSEC 105 * Comment lines that start with "#@" denote IPsec policy string, as described 106 * in ipsec_set_policy(3). This will affect all the following items in 107 * inetd.conf(8). To reset the policy, just use "#@" line. By default, 108 * there's no IPsec policy. 109 * #endif 110 */ 111#include <sys/param.h> 112#include <sys/ioctl.h> 113#include <sys/wait.h> 114#include <sys/time.h> 115#include <sys/resource.h> 116#include <sys/stat.h> 117#include <sys/un.h> 118 119#include <netinet/in.h> 120#include <netinet/tcp.h> 121#include <arpa/inet.h> 122#include <rpc/rpc.h> 123#include <rpc/pmap_clnt.h> 124 125#include <ctype.h> 126#include <errno.h> 127#include <err.h> 128#include <fcntl.h> 129#include <grp.h> 130#include <libutil.h> 131#include <limits.h> 132#include <netdb.h> 133#include <pwd.h> 134#include <signal.h> 135#include <stdio.h> 136#include <stdlib.h> 137#include <string.h> 138#include <sysexits.h> 139#include <syslog.h> 140#include <tcpd.h> 141#include <unistd.h> 142 143#include "inetd.h" 144#include "pathnames.h" 145 146#ifdef IPSEC 147#include <netinet6/ipsec.h> 148#ifndef IPSEC_POLICY_IPSEC /* no ipsec support on old ipsec */ 149#undef IPSEC 150#endif 151#endif 152 153#ifndef LIBWRAP_ALLOW_FACILITY 154# define LIBWRAP_ALLOW_FACILITY LOG_AUTH 155#endif 156#ifndef LIBWRAP_ALLOW_SEVERITY 157# define LIBWRAP_ALLOW_SEVERITY LOG_INFO 158#endif 159#ifndef LIBWRAP_DENY_FACILITY 160# define LIBWRAP_DENY_FACILITY LOG_AUTH 161#endif 162#ifndef LIBWRAP_DENY_SEVERITY 163# define LIBWRAP_DENY_SEVERITY LOG_WARNING 164#endif 165 166#define ISWRAP(sep) \ 167 ( ((wrap_ex && !(sep)->se_bi) || (wrap_bi && (sep)->se_bi)) \ 168 && (sep->se_family == AF_INET || sep->se_family == AF_INET6) \ 169 && ( ((sep)->se_accept && (sep)->se_socktype == SOCK_STREAM) \ 170 || (sep)->se_socktype == SOCK_DGRAM)) 171 172#ifdef LOGIN_CAP 173#include <login_cap.h> 174 175/* see init.c */ 176#define RESOURCE_RC "daemon" 177 178#endif 179 180#ifndef MAXCHILD 181#define MAXCHILD -1 /* maximum number of this service 182 < 0 = no limit */ 183#endif 184 185#ifndef MAXCPM 186#define MAXCPM -1 /* rate limit invocations from a 187 single remote address, 188 < 0 = no limit */ 189#endif 190 191#ifndef MAXPERIP 192#define MAXPERIP -1 /* maximum number of this service 193 from a single remote address, 194 < 0 = no limit */ 195#endif 196 197#ifndef TOOMANY 198#define TOOMANY 256 /* don't start more than TOOMANY */ 199#endif 200#define CNT_INTVL 60 /* servers in CNT_INTVL sec. */ 201#define RETRYTIME (60*10) /* retry after bind or server fail */ 202#define MAX_MAXCHLD 32767 /* max allowable max children */ 203 204#define SIGBLOCK (sigmask(SIGCHLD)|sigmask(SIGHUP)|sigmask(SIGALRM)) 205 206void close_sep(struct servtab *); 207void flag_signal(int); 208void flag_config(int); 209void config(void); 210int cpmip(const struct servtab *, int); 211void endconfig(void); 212struct servtab *enter(struct servtab *); 213void freeconfig(struct servtab *); 214struct servtab *getconfigent(void); 215int matchservent(const char *, const char *, const char *); 216char *nextline(FILE *); 217void addchild(struct servtab *, int); 218void flag_reapchild(int); 219void reapchild(void); 220void enable(struct servtab *); 221void disable(struct servtab *); 222void flag_retry(int); 223void retry(void); 224int setconfig(void); 225void setup(struct servtab *); 226#ifdef IPSEC 227void ipsecsetup(struct servtab *); 228#endif 229void unregisterrpc(register struct servtab *sep); 230static struct conninfo *search_conn(struct servtab *sep, int ctrl); 231static int room_conn(struct servtab *sep, struct conninfo *conn); 232static void addchild_conn(struct conninfo *conn, pid_t pid); 233static void reapchild_conn(pid_t pid); 234static void free_conn(struct conninfo *conn); 235static void resize_conn(struct servtab *sep, int maxperip); 236static void free_connlist(struct servtab *sep); 237static void free_proc(struct procinfo *); 238static struct procinfo *search_proc(pid_t pid, int add); 239static int hashval(char *p, int len); 240 241int allow_severity; 242int deny_severity; 243int wrap_ex = 0; 244int wrap_bi = 0; 245int debug = 0; 246int dolog = 0; 247int maxsock; /* highest-numbered descriptor */ 248fd_set allsock; 249int options; 250int timingout; 251int toomany = TOOMANY; 252int maxchild = MAXCHILD; 253int maxcpm = MAXCPM; 254int maxperip = MAXPERIP; 255struct servent *sp; 256struct rpcent *rpc; 257char *hostname = NULL; 258struct sockaddr_in *bind_sa4; 259int v4bind_ok = 0; 260#ifdef INET6 261struct sockaddr_in6 *bind_sa6; 262int v6bind_ok = 0; 263#endif 264int signalpipe[2]; 265#ifdef SANITY_CHECK 266int nsock; 267#endif 268uid_t euid; 269gid_t egid; 270mode_t mask; 271 272struct servtab *servtab; 273 274extern struct biltin biltins[]; 275 276const char *CONFIG = _PATH_INETDCONF; 277const char *pid_file = _PATH_INETDPID; 278 279struct netconfig *udpconf, *tcpconf, *udp6conf, *tcp6conf; 280 281static LIST_HEAD(, procinfo) proctable[PERIPSIZE]; 282 283int 284getvalue(const char *arg, int *value, const char *whine) 285{ 286 int tmp; 287 char *p; 288 289 tmp = strtol(arg, &p, 0); 290 if (tmp < 0 || *p) { 291 syslog(LOG_ERR, whine, arg); 292 return 1; /* failure */ 293 } 294 *value = tmp; 295 return 0; /* success */ 296} 297 298static sa_family_t 299whichaf(struct request_info *req) 300{ 301 struct sockaddr *sa; 302 303 sa = (struct sockaddr *)req->client->sin; 304 if (sa == NULL) 305 return AF_UNSPEC; 306 if (sa->sa_family == AF_INET6 && 307 IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)sa)->sin6_addr)) 308 return AF_INET; 309 return sa->sa_family; 310} 311 312int 313main(int argc, char **argv) 314{ 315 struct servtab *sep; 316 struct passwd *pwd; 317 struct group *grp; 318 struct sigaction sa, saalrm, sachld, sahup, sapipe; 319 int ch, dofork; 320 pid_t pid; 321 char buf[50]; 322#ifdef LOGIN_CAP 323 login_cap_t *lc = NULL; 324#endif 325 struct request_info req; 326 int denied; 327 char *service = NULL; 328 union { 329 struct sockaddr peer_un; 330 struct sockaddr_in peer_un4; 331 struct sockaddr_in6 peer_un6; 332 struct sockaddr_storage peer_max; 333 } p_un; 334#define peer p_un.peer_un 335#define peer4 p_un.peer_un4 336#define peer6 p_un.peer_un6 337#define peermax p_un.peer_max 338 int i; 339 struct addrinfo hints, *res; 340 const char *servname; 341 int error; 342 struct conninfo *conn; 343 344 openlog("inetd", LOG_PID | LOG_NOWAIT | LOG_PERROR, LOG_DAEMON); 345 346 while ((ch = getopt(argc, argv, "dlwWR:a:c:C:p:s:")) != -1) 347 switch(ch) { 348 case 'd': 349 debug = 1; 350 options |= SO_DEBUG; 351 break; 352 case 'l': 353 dolog = 1; 354 break; 355 case 'R': 356 getvalue(optarg, &toomany, 357 "-R %s: bad value for service invocation rate"); 358 break; 359 case 'c': 360 getvalue(optarg, &maxchild, 361 "-c %s: bad value for maximum children"); 362 break; 363 case 'C': 364 getvalue(optarg, &maxcpm, 365 "-C %s: bad value for maximum children/minute"); 366 break; 367 case 'a': 368 hostname = optarg; 369 break; 370 case 'p': 371 pid_file = optarg; 372 break; 373 case 's': 374 getvalue(optarg, &maxperip, 375 "-s %s: bad value for maximum children per source address"); 376 break; 377 case 'w': 378 wrap_ex++; 379 break; 380 case 'W': 381 wrap_bi++; 382 break; 383 case '?': 384 default: 385 syslog(LOG_ERR, 386 "usage: inetd [-dlwW] [-a address] [-R rate]" 387 " [-c maximum] [-C rate]" 388 " [-p pidfile] [conf-file]"); 389 exit(EX_USAGE); 390 } 391 /* 392 * Initialize Bind Addrs. 393 * When hostname is NULL, wild card bind addrs are obtained from 394 * getaddrinfo(). But getaddrinfo() requires at least one of 395 * hostname or servname is non NULL. 396 * So when hostname is NULL, set dummy value to servname. 397 * Since getaddrinfo() doesn't accept numeric servname, and 398 * we doesn't use ai_socktype of struct addrinfo returned 399 * from getaddrinfo(), we set dummy value to ai_socktype. 400 */ 401 servname = (hostname == NULL) ? "0" /* dummy */ : NULL; 402 403 bzero(&hints, sizeof(struct addrinfo)); 404 hints.ai_flags = AI_PASSIVE; 405 hints.ai_family = AF_UNSPEC; 406 hints.ai_socktype = SOCK_STREAM; /* dummy */ 407 error = getaddrinfo(hostname, servname, &hints, &res); 408 if (error != 0) { 409 syslog(LOG_ERR, "-a %s: %s", hostname, gai_strerror(error)); 410 if (error == EAI_SYSTEM) 411 syslog(LOG_ERR, "%s", strerror(errno)); 412 exit(EX_USAGE); 413 } 414 do { 415 if (res->ai_addr == NULL) { 416 syslog(LOG_ERR, "-a %s: getaddrinfo failed", hostname); 417 exit(EX_USAGE); 418 } 419 switch (res->ai_addr->sa_family) { 420 case AF_INET: 421 if (v4bind_ok) 422 continue; 423 bind_sa4 = (struct sockaddr_in *)res->ai_addr; 424 /* init port num in case servname is dummy */ 425 bind_sa4->sin_port = 0; 426 v4bind_ok = 1; 427 continue; 428#ifdef INET6 429 case AF_INET6: 430 if (v6bind_ok) 431 continue; 432 bind_sa6 = (struct sockaddr_in6 *)res->ai_addr; 433 /* init port num in case servname is dummy */ 434 bind_sa6->sin6_port = 0; 435 v6bind_ok = 1; 436 continue; 437#endif 438 } 439 if (v4bind_ok 440#ifdef INET6 441 && v6bind_ok 442#endif 443 ) 444 break; 445 } while ((res = res->ai_next) != NULL); 446 if (!v4bind_ok 447#ifdef INET6 448 && !v6bind_ok 449#endif 450 ) { 451 syslog(LOG_ERR, "-a %s: unknown address family", hostname); 452 exit(EX_USAGE); 453 } 454 455 euid = geteuid(); 456 egid = getegid(); 457 umask(mask = umask(0777)); 458 459 argc -= optind; 460 argv += optind; 461 462 if (argc > 0) 463 CONFIG = argv[0]; 464 if (access(CONFIG, R_OK) < 0) 465 syslog(LOG_ERR, "Accessing %s: %m, continuing anyway.", CONFIG); 466 if (debug == 0) { 467 FILE *fp; 468 if (daemon(0, 0) < 0) { 469 syslog(LOG_WARNING, "daemon(0,0) failed: %m"); 470 } 471 /* From now on we don't want syslog messages going to stderr. */ 472 closelog(); 473 openlog("inetd", LOG_PID | LOG_NOWAIT, LOG_DAEMON); 474 /* 475 * In case somebody has started inetd manually, we need to 476 * clear the logname, so that old servers run as root do not 477 * get the user's logname.. 478 */ 479 if (setlogin("") < 0) { 480 syslog(LOG_WARNING, "cannot clear logname: %m"); 481 /* no big deal if it fails.. */ 482 } 483 pid = getpid(); 484 fp = fopen(pid_file, "w"); 485 if (fp) { 486 fprintf(fp, "%ld\n", (long)pid); 487 fclose(fp); 488 } else { 489 syslog(LOG_WARNING, "%s: %m", pid_file); 490 } 491 } 492 493 for (i = 0; i < PERIPSIZE; ++i) 494 LIST_INIT(&proctable[i]); 495 496 if (v4bind_ok) { 497 udpconf = getnetconfigent("udp"); 498 tcpconf = getnetconfigent("tcp"); 499 if (udpconf == NULL || tcpconf == NULL) { 500 syslog(LOG_ERR, "unknown rpc/udp or rpc/tcp"); 501 exit(EX_USAGE); 502 } 503 } 504#ifdef INET6 505 if (v6bind_ok) { 506 udp6conf = getnetconfigent("udp6"); 507 tcp6conf = getnetconfigent("tcp6"); 508 if (udp6conf == NULL || tcp6conf == NULL) { 509 syslog(LOG_ERR, "unknown rpc/udp6 or rpc/tcp6"); 510 exit(EX_USAGE); 511 } 512 } 513#endif 514 515 sa.sa_flags = 0; 516 sigemptyset(&sa.sa_mask); 517 sigaddset(&sa.sa_mask, SIGALRM); 518 sigaddset(&sa.sa_mask, SIGCHLD); 519 sigaddset(&sa.sa_mask, SIGHUP); 520 sa.sa_handler = flag_retry; 521 sigaction(SIGALRM, &sa, &saalrm); 522 config(); 523 sa.sa_handler = flag_config; 524 sigaction(SIGHUP, &sa, &sahup); 525 sa.sa_handler = flag_reapchild; 526 sigaction(SIGCHLD, &sa, &sachld); 527 sa.sa_handler = SIG_IGN; 528 sigaction(SIGPIPE, &sa, &sapipe); 529 530 { 531 /* space for daemons to overwrite environment for ps */ 532#define DUMMYSIZE 100 533 char dummy[DUMMYSIZE]; 534 535 (void)memset(dummy, 'x', DUMMYSIZE - 1); 536 dummy[DUMMYSIZE - 1] = '\0'; 537 (void)setenv("inetd_dummy", dummy, 1); 538 } 539 540 if (pipe(signalpipe) != 0) { 541 syslog(LOG_ERR, "pipe: %m"); 542 exit(EX_OSERR); 543 } 544 if (fcntl(signalpipe[0], F_SETFD, FD_CLOEXEC) < 0 || 545 fcntl(signalpipe[1], F_SETFD, FD_CLOEXEC) < 0) { 546 syslog(LOG_ERR, "signalpipe: fcntl (F_SETFD, FD_CLOEXEC): %m"); 547 exit(EX_OSERR); 548 } 549 FD_SET(signalpipe[0], &allsock); 550#ifdef SANITY_CHECK 551 nsock++; 552#endif 553 if (signalpipe[0] > maxsock) 554 maxsock = signalpipe[0]; 555 if (signalpipe[1] > maxsock) 556 maxsock = signalpipe[1]; 557 558 for (;;) { 559 int n, ctrl; 560 fd_set readable; 561 562#ifdef SANITY_CHECK 563 if (nsock == 0) { 564 syslog(LOG_ERR, "%s: nsock=0", __func__); 565 exit(EX_SOFTWARE); 566 } 567#endif 568 readable = allsock; 569 if ((n = select(maxsock + 1, &readable, (fd_set *)0, 570 (fd_set *)0, (struct timeval *)0)) <= 0) { 571 if (n < 0 && errno != EINTR) { 572 syslog(LOG_WARNING, "select: %m"); 573 sleep(1); 574 } 575 continue; 576 } 577 /* handle any queued signal flags */ 578 if (FD_ISSET(signalpipe[0], &readable)) { 579 int nsig; 580 if (ioctl(signalpipe[0], FIONREAD, &nsig) != 0) { 581 syslog(LOG_ERR, "ioctl: %m"); 582 exit(EX_OSERR); 583 } 584 while (--nsig >= 0) { 585 char c; 586 if (read(signalpipe[0], &c, 1) != 1) { 587 syslog(LOG_ERR, "read: %m"); 588 exit(EX_OSERR); 589 } 590 if (debug) 591 warnx("handling signal flag %c", c); 592 switch(c) { 593 case 'A': /* sigalrm */ 594 retry(); 595 break; 596 case 'C': /* sigchld */ 597 reapchild(); 598 break; 599 case 'H': /* sighup */ 600 config(); 601 break; 602 } 603 } 604 } 605 for (sep = servtab; n && sep; sep = sep->se_next) 606 if (sep->se_fd != -1 && FD_ISSET(sep->se_fd, &readable)) { 607 n--; 608 if (debug) 609 warnx("someone wants %s", sep->se_service); 610 dofork = !sep->se_bi || sep->se_bi->bi_fork || ISWRAP(sep); 611 conn = NULL; 612 if (sep->se_accept && sep->se_socktype == SOCK_STREAM) { 613 i = 1; 614 if (ioctl(sep->se_fd, FIONBIO, &i) < 0) 615 syslog(LOG_ERR, "ioctl (FIONBIO, 1): %m"); 616 ctrl = accept(sep->se_fd, (struct sockaddr *)0, 617 (socklen_t *)0); 618 if (debug) 619 warnx("accept, ctrl %d", ctrl); 620 if (ctrl < 0) { 621 if (errno != EINTR) 622 syslog(LOG_WARNING, 623 "accept (for %s): %m", 624 sep->se_service); 625 if (sep->se_accept && 626 sep->se_socktype == SOCK_STREAM) 627 close(ctrl); 628 continue; 629 } 630 i = 0; 631 if (ioctl(sep->se_fd, FIONBIO, &i) < 0) 632 syslog(LOG_ERR, "ioctl1(FIONBIO, 0): %m"); 633 if (ioctl(ctrl, FIONBIO, &i) < 0) 634 syslog(LOG_ERR, "ioctl2(FIONBIO, 0): %m"); 635 if (cpmip(sep, ctrl) < 0) { 636 close(ctrl); 637 continue; 638 } 639 if (dofork && 640 (conn = search_conn(sep, ctrl)) != NULL && 641 !room_conn(sep, conn)) { 642 close(ctrl); 643 continue; 644 } 645 } else 646 ctrl = sep->se_fd; 647 if (dolog && !ISWRAP(sep)) { 648 char pname[INET6_ADDRSTRLEN] = "unknown"; 649 socklen_t sl; 650 sl = sizeof peermax; 651 if (getpeername(ctrl, (struct sockaddr *) 652 &peermax, &sl)) { 653 sl = sizeof peermax; 654 if (recvfrom(ctrl, buf, sizeof(buf), 655 MSG_PEEK, 656 (struct sockaddr *)&peermax, 657 &sl) >= 0) { 658 getnameinfo((struct sockaddr *)&peermax, 659 peer.sa_len, 660 pname, sizeof(pname), 661 NULL, 0, NI_NUMERICHOST); 662 } 663 } else { 664 getnameinfo((struct sockaddr *)&peermax, 665 peer.sa_len, 666 pname, sizeof(pname), 667 NULL, 0, NI_NUMERICHOST); 668 } 669 syslog(LOG_INFO,"%s from %s", sep->se_service, pname); 670 } 671 (void) sigblock(SIGBLOCK); 672 pid = 0; 673 /* 674 * Fork for all external services, builtins which need to 675 * fork and anything we're wrapping (as wrapping might 676 * block or use hosts_options(5) twist). 677 */ 678 if (dofork) { 679 if (sep->se_count++ == 0) 680 (void)gettimeofday(&sep->se_time, (struct timezone *)NULL); 681 else if (toomany > 0 && sep->se_count >= toomany) { 682 struct timeval now; 683 684 (void)gettimeofday(&now, (struct timezone *)NULL); 685 if (now.tv_sec - sep->se_time.tv_sec > 686 CNT_INTVL) { 687 sep->se_time = now; 688 sep->se_count = 1; 689 } else { 690 syslog(LOG_ERR, 691 "%s/%s server failing (looping), service terminated", 692 sep->se_service, sep->se_proto); 693 if (sep->se_accept && 694 sep->se_socktype == SOCK_STREAM) 695 close(ctrl); 696 close_sep(sep); 697 free_conn(conn); 698 sigsetmask(0L); 699 if (!timingout) { 700 timingout = 1; 701 alarm(RETRYTIME); 702 } 703 continue; 704 } 705 } 706 pid = fork(); 707 } 708 if (pid < 0) { 709 syslog(LOG_ERR, "fork: %m"); 710 if (sep->se_accept && 711 sep->se_socktype == SOCK_STREAM) 712 close(ctrl); 713 free_conn(conn); 714 sigsetmask(0L); 715 sleep(1); 716 continue; 717 } 718 if (pid) { 719 addchild_conn(conn, pid); 720 addchild(sep, pid); 721 } 722 sigsetmask(0L); 723 if (pid == 0) { 724 if (dofork) { 725 sigaction(SIGALRM, &saalrm, (struct sigaction *)0); 726 sigaction(SIGCHLD, &sachld, (struct sigaction *)0); 727 sigaction(SIGHUP, &sahup, (struct sigaction *)0); 728 /* SIGPIPE reset before exec */ 729 } 730 /* 731 * Call tcpmux to find the real service to exec. 732 */ 733 if (sep->se_bi && 734 sep->se_bi->bi_fn == (bi_fn_t *) tcpmux) { 735 sep = tcpmux(ctrl); 736 if (sep == NULL) { 737 close(ctrl); 738 _exit(0); 739 } 740 } 741 if (ISWRAP(sep)) { 742 inetd_setproctitle("wrapping", ctrl); 743 service = sep->se_server_name ? 744 sep->se_server_name : sep->se_service; 745 request_init(&req, RQ_DAEMON, service, RQ_FILE, ctrl, 0); 746 fromhost(&req); 747 deny_severity = LIBWRAP_DENY_FACILITY|LIBWRAP_DENY_SEVERITY; 748 allow_severity = LIBWRAP_ALLOW_FACILITY|LIBWRAP_ALLOW_SEVERITY; 749 denied = !hosts_access(&req); 750 if (denied) { 751 syslog(deny_severity, 752 "refused connection from %.500s, service %s (%s%s)", 753 eval_client(&req), service, sep->se_proto, 754 (whichaf(&req) == AF_INET6) ? "6" : ""); 755 if (sep->se_socktype != SOCK_STREAM) 756 recv(ctrl, buf, sizeof (buf), 0); 757 if (dofork) { 758 sleep(1); 759 _exit(0); 760 } 761 } 762 if (dolog) { 763 syslog(allow_severity, 764 "connection from %.500s, service %s (%s%s)", 765 eval_client(&req), service, sep->se_proto, 766 (whichaf(&req) == AF_INET6) ? "6" : ""); 767 } 768 } 769 if (sep->se_bi) { 770 (*sep->se_bi->bi_fn)(ctrl, sep); 771 } else { 772 if (debug) 773 warnx("%d execl %s", 774 getpid(), sep->se_server); 775 /* Clear close-on-exec. */ 776 if (fcntl(ctrl, F_SETFD, 0) < 0) { 777 syslog(LOG_ERR, 778 "%s/%s: fcntl (F_SETFD, 0): %m", 779 sep->se_service, sep->se_proto); 780 _exit(EX_OSERR); 781 } 782 if (ctrl != 0) { 783 dup2(ctrl, 0); 784 close(ctrl); 785 } 786 dup2(0, 1); 787 dup2(0, 2); 788 if ((pwd = getpwnam(sep->se_user)) == NULL) { 789 syslog(LOG_ERR, 790 "%s/%s: %s: no such user", 791 sep->se_service, sep->se_proto, 792 sep->se_user); 793 if (sep->se_socktype != SOCK_STREAM) 794 recv(0, buf, sizeof (buf), 0); 795 _exit(EX_NOUSER); 796 } 797 grp = NULL; 798 if ( sep->se_group != NULL 799 && (grp = getgrnam(sep->se_group)) == NULL 800 ) { 801 syslog(LOG_ERR, 802 "%s/%s: %s: no such group", 803 sep->se_service, sep->se_proto, 804 sep->se_group); 805 if (sep->se_socktype != SOCK_STREAM) 806 recv(0, buf, sizeof (buf), 0); 807 _exit(EX_NOUSER); 808 } 809 if (grp != NULL) 810 pwd->pw_gid = grp->gr_gid; 811#ifdef LOGIN_CAP 812 if ((lc = login_getclass(sep->se_class)) == NULL) { 813 /* error syslogged by getclass */ 814 syslog(LOG_ERR, 815 "%s/%s: %s: login class error", 816 sep->se_service, sep->se_proto, 817 sep->se_class); 818 if (sep->se_socktype != SOCK_STREAM) 819 recv(0, buf, sizeof (buf), 0); 820 _exit(EX_NOUSER); 821 } 822#endif 823 if (setsid() < 0) { 824 syslog(LOG_ERR, 825 "%s: can't setsid(): %m", 826 sep->se_service); 827 /* _exit(EX_OSERR); not fatal yet */ 828 } 829#ifdef LOGIN_CAP 830 if (setusercontext(lc, pwd, pwd->pw_uid, 831 LOGIN_SETALL & ~LOGIN_SETMAC) 832 != 0) { 833 syslog(LOG_ERR, 834 "%s: can't setusercontext(..%s..): %m", 835 sep->se_service, sep->se_user); 836 _exit(EX_OSERR); 837 } 838 login_close(lc); 839#else 840 if (pwd->pw_uid) { 841 if (setlogin(sep->se_user) < 0) { 842 syslog(LOG_ERR, 843 "%s: can't setlogin(%s): %m", 844 sep->se_service, sep->se_user); 845 /* _exit(EX_OSERR); not yet */ 846 } 847 if (setgid(pwd->pw_gid) < 0) { 848 syslog(LOG_ERR, 849 "%s: can't set gid %d: %m", 850 sep->se_service, pwd->pw_gid); 851 _exit(EX_OSERR); 852 } 853 (void) initgroups(pwd->pw_name, 854 pwd->pw_gid); 855 if (setuid(pwd->pw_uid) < 0) { 856 syslog(LOG_ERR, 857 "%s: can't set uid %d: %m", 858 sep->se_service, pwd->pw_uid); 859 _exit(EX_OSERR); 860 } 861 } 862#endif 863 sigaction(SIGPIPE, &sapipe, 864 (struct sigaction *)0); 865 execv(sep->se_server, sep->se_argv); 866 syslog(LOG_ERR, 867 "cannot execute %s: %m", sep->se_server); 868 if (sep->se_socktype != SOCK_STREAM) 869 recv(0, buf, sizeof (buf), 0); 870 } 871 if (dofork) 872 _exit(0); 873 } 874 if (sep->se_accept && sep->se_socktype == SOCK_STREAM) 875 close(ctrl); 876 } 877 } 878} 879 880/* 881 * Add a signal flag to the signal flag queue for later handling 882 */ 883 884void 885flag_signal(int c) 886{ 887 char ch = c; 888 889 if (write(signalpipe[1], &ch, 1) != 1) { 890 syslog(LOG_ERR, "write: %m"); 891 _exit(EX_OSERR); 892 } 893} 894 895/* 896 * Record a new child pid for this service. If we've reached the 897 * limit on children, then stop accepting incoming requests. 898 */ 899 900void 901addchild(struct servtab *sep, pid_t pid) 902{ 903 if (sep->se_maxchild <= 0) 904 return; 905#ifdef SANITY_CHECK 906 if (sep->se_numchild >= sep->se_maxchild) { 907 syslog(LOG_ERR, "%s: %d >= %d", 908 __func__, sep->se_numchild, sep->se_maxchild); 909 exit(EX_SOFTWARE); 910 } 911#endif 912 sep->se_pids[sep->se_numchild++] = pid; 913 if (sep->se_numchild == sep->se_maxchild) 914 disable(sep); 915} 916 917/* 918 * Some child process has exited. See if it's on somebody's list. 919 */ 920 921void 922flag_reapchild(int signo __unused) 923{ 924 flag_signal('C'); 925} 926 927void 928reapchild(void) 929{ 930 int k, status; 931 pid_t pid; 932 struct servtab *sep; 933 934 for (;;) { 935 pid = wait3(&status, WNOHANG, (struct rusage *)0); 936 if (pid <= 0) 937 break; 938 if (debug) 939 warnx("%d reaped, %s %u", pid, 940 WIFEXITED(status) ? "status" : "signal", 941 WIFEXITED(status) ? WEXITSTATUS(status) 942 : WTERMSIG(status)); 943 for (sep = servtab; sep; sep = sep->se_next) { 944 for (k = 0; k < sep->se_numchild; k++) 945 if (sep->se_pids[k] == pid) 946 break; 947 if (k == sep->se_numchild) 948 continue; 949 if (sep->se_numchild == sep->se_maxchild) 950 enable(sep); 951 sep->se_pids[k] = sep->se_pids[--sep->se_numchild]; 952 if (WIFSIGNALED(status) || WEXITSTATUS(status)) 953 syslog(LOG_WARNING, 954 "%s[%d]: exited, %s %u", 955 sep->se_server, pid, 956 WIFEXITED(status) ? "status" : "signal", 957 WIFEXITED(status) ? WEXITSTATUS(status) 958 : WTERMSIG(status)); 959 break; 960 } 961 reapchild_conn(pid); 962 } 963} 964 965void 966flag_config(int signo __unused) 967{ 968 flag_signal('H'); 969} 970 971void 972config(void) 973{ 974 struct servtab *sep, *new, **sepp; 975 long omask; 976 int new_nomapped; 977#ifdef LOGIN_CAP 978 login_cap_t *lc = NULL; 979#endif 980 981 if (!setconfig()) { 982 syslog(LOG_ERR, "%s: %m", CONFIG); 983 return; 984 } 985 for (sep = servtab; sep; sep = sep->se_next) 986 sep->se_checked = 0; 987 while ((new = getconfigent())) { 988 if (getpwnam(new->se_user) == NULL) { 989 syslog(LOG_ERR, 990 "%s/%s: no such user '%s', service ignored", 991 new->se_service, new->se_proto, new->se_user); 992 continue; 993 } 994 if (new->se_group && getgrnam(new->se_group) == NULL) { 995 syslog(LOG_ERR, 996 "%s/%s: no such group '%s', service ignored", 997 new->se_service, new->se_proto, new->se_group); 998 continue; 999 } 1000#ifdef LOGIN_CAP 1001 if ((lc = login_getclass(new->se_class)) == NULL) { 1002 /* error syslogged by getclass */ 1003 syslog(LOG_ERR, 1004 "%s/%s: %s: login class error, service ignored", 1005 new->se_service, new->se_proto, new->se_class); 1006 continue; 1007 } 1008 login_close(lc); 1009#endif 1010 new_nomapped = new->se_nomapped; 1011 for (sep = servtab; sep; sep = sep->se_next) 1012 if (strcmp(sep->se_service, new->se_service) == 0 && 1013 strcmp(sep->se_proto, new->se_proto) == 0 && 1014 sep->se_rpc == new->se_rpc && 1015 sep->se_socktype == new->se_socktype && 1016 sep->se_family == new->se_family) 1017 break; 1018 if (sep != 0) { 1019 int i; 1020 1021#define SWAP(t,a, b) { t c = a; a = b; b = c; } 1022 omask = sigblock(SIGBLOCK); 1023 if (sep->se_nomapped != new->se_nomapped) { 1024 /* for rpc keep old nommaped till unregister */ 1025 if (!sep->se_rpc) 1026 sep->se_nomapped = new->se_nomapped; 1027 sep->se_reset = 1; 1028 } 1029 /* copy over outstanding child pids */ 1030 if (sep->se_maxchild > 0 && new->se_maxchild > 0) { 1031 new->se_numchild = sep->se_numchild; 1032 if (new->se_numchild > new->se_maxchild) 1033 new->se_numchild = new->se_maxchild; 1034 memcpy(new->se_pids, sep->se_pids, 1035 new->se_numchild * sizeof(*new->se_pids)); 1036 } 1037 SWAP(pid_t *, sep->se_pids, new->se_pids); 1038 sep->se_maxchild = new->se_maxchild; 1039 sep->se_numchild = new->se_numchild; 1040 sep->se_maxcpm = new->se_maxcpm; 1041 resize_conn(sep, new->se_maxperip); 1042 sep->se_maxperip = new->se_maxperip; 1043 sep->se_bi = new->se_bi; 1044 /* might need to turn on or off service now */ 1045 if (sep->se_fd >= 0) { 1046 if (sep->se_maxchild > 0 1047 && sep->se_numchild == sep->se_maxchild) { 1048 if (FD_ISSET(sep->se_fd, &allsock)) 1049 disable(sep); 1050 } else { 1051 if (!FD_ISSET(sep->se_fd, &allsock)) 1052 enable(sep); 1053 } 1054 } 1055 sep->se_accept = new->se_accept; 1056 SWAP(char *, sep->se_user, new->se_user); 1057 SWAP(char *, sep->se_group, new->se_group); 1058#ifdef LOGIN_CAP 1059 SWAP(char *, sep->se_class, new->se_class); 1060#endif 1061 SWAP(char *, sep->se_server, new->se_server); 1062 SWAP(char *, sep->se_server_name, new->se_server_name); 1063 for (i = 0; i < MAXARGV; i++) 1064 SWAP(char *, sep->se_argv[i], new->se_argv[i]); 1065#ifdef IPSEC 1066 SWAP(char *, sep->se_policy, new->se_policy); 1067 ipsecsetup(sep); 1068#endif 1069 sigsetmask(omask); 1070 freeconfig(new); 1071 if (debug) 1072 print_service("REDO", sep); 1073 } else { 1074 sep = enter(new); 1075 if (debug) 1076 print_service("ADD ", sep); 1077 } 1078 sep->se_checked = 1; 1079 if (ISMUX(sep)) { 1080 sep->se_fd = -1; 1081 continue; 1082 } 1083 switch (sep->se_family) { 1084 case AF_INET: 1085 if (!v4bind_ok) { 1086 sep->se_fd = -1; 1087 continue; 1088 } 1089 break; 1090#ifdef INET6 1091 case AF_INET6: 1092 if (!v6bind_ok) { 1093 sep->se_fd = -1; 1094 continue; 1095 } 1096 break; 1097#endif 1098 } 1099 if (!sep->se_rpc) { 1100 if (sep->se_family != AF_UNIX) { 1101 sp = getservbyname(sep->se_service, sep->se_proto); 1102 if (sp == 0) { 1103 syslog(LOG_ERR, "%s/%s: unknown service", 1104 sep->se_service, sep->se_proto); 1105 sep->se_checked = 0; 1106 continue; 1107 } 1108 } 1109 switch (sep->se_family) { 1110 case AF_INET: 1111 if (sp->s_port != sep->se_ctrladdr4.sin_port) { 1112 sep->se_ctrladdr4.sin_port = 1113 sp->s_port; 1114 sep->se_reset = 1; 1115 } 1116 break; 1117#ifdef INET6 1118 case AF_INET6: 1119 if (sp->s_port != 1120 sep->se_ctrladdr6.sin6_port) { 1121 sep->se_ctrladdr6.sin6_port = 1122 sp->s_port; 1123 sep->se_reset = 1; 1124 } 1125 break; 1126#endif 1127 } 1128 if (sep->se_reset != 0 && sep->se_fd >= 0) 1129 close_sep(sep); 1130 } else { 1131 rpc = getrpcbyname(sep->se_service); 1132 if (rpc == 0) { 1133 syslog(LOG_ERR, "%s/%s unknown RPC service", 1134 sep->se_service, sep->se_proto); 1135 if (sep->se_fd != -1) 1136 (void) close(sep->se_fd); 1137 sep->se_fd = -1; 1138 continue; 1139 } 1140 if (sep->se_reset != 0 || 1141 rpc->r_number != sep->se_rpc_prog) { 1142 if (sep->se_rpc_prog) 1143 unregisterrpc(sep); 1144 sep->se_rpc_prog = rpc->r_number; 1145 if (sep->se_fd != -1) 1146 (void) close(sep->se_fd); 1147 sep->se_fd = -1; 1148 } 1149 sep->se_nomapped = new_nomapped; 1150 } 1151 sep->se_reset = 0; 1152 if (sep->se_fd == -1) 1153 setup(sep); 1154 } 1155 endconfig(); 1156 /* 1157 * Purge anything not looked at above. 1158 */ 1159 omask = sigblock(SIGBLOCK); 1160 sepp = &servtab; 1161 while ((sep = *sepp)) { 1162 if (sep->se_checked) { 1163 sepp = &sep->se_next; 1164 continue; 1165 } 1166 *sepp = sep->se_next; 1167 if (sep->se_fd >= 0) 1168 close_sep(sep); 1169 if (debug) 1170 print_service("FREE", sep); 1171 if (sep->se_rpc && sep->se_rpc_prog > 0) 1172 unregisterrpc(sep); 1173 freeconfig(sep); 1174 free(sep); 1175 } 1176 (void) sigsetmask(omask); 1177} 1178 1179void 1180unregisterrpc(struct servtab *sep) 1181{ 1182 u_int i; 1183 struct servtab *sepp; 1184 long omask; 1185 struct netconfig *netid4, *netid6; 1186 1187 omask = sigblock(SIGBLOCK); 1188 netid4 = sep->se_socktype == SOCK_DGRAM ? udpconf : tcpconf; 1189 netid6 = sep->se_socktype == SOCK_DGRAM ? udp6conf : tcp6conf; 1190 if (sep->se_family == AF_INET) 1191 netid6 = NULL; 1192 else if (sep->se_nomapped) 1193 netid4 = NULL; 1194 /* 1195 * Conflict if same prog and protocol - In that case one should look 1196 * to versions, but it is not interesting: having separate servers for 1197 * different versions does not work well. 1198 * Therefore one do not unregister if there is a conflict. 1199 * There is also transport conflict if destroying INET when INET46 1200 * exists, or destroying INET46 when INET exists 1201 */ 1202 for (sepp = servtab; sepp; sepp = sepp->se_next) { 1203 if (sepp == sep) 1204 continue; 1205 if (sepp->se_checked == 0 || 1206 !sepp->se_rpc || 1207 strcmp(sep->se_proto, sepp->se_proto) != 0 || 1208 sep->se_rpc_prog != sepp->se_rpc_prog) 1209 continue; 1210 if (sepp->se_family == AF_INET) 1211 netid4 = NULL; 1212 if (sepp->se_family == AF_INET6) { 1213 netid6 = NULL; 1214 if (!sep->se_nomapped) 1215 netid4 = NULL; 1216 } 1217 if (netid4 == NULL && netid6 == NULL) 1218 return; 1219 } 1220 if (debug) 1221 print_service("UNREG", sep); 1222 for (i = sep->se_rpc_lowvers; i <= sep->se_rpc_highvers; i++) { 1223 if (netid4) 1224 rpcb_unset(sep->se_rpc_prog, i, netid4); 1225 if (netid6) 1226 rpcb_unset(sep->se_rpc_prog, i, netid6); 1227 } 1228 if (sep->se_fd != -1) 1229 (void) close(sep->se_fd); 1230 sep->se_fd = -1; 1231 (void) sigsetmask(omask); 1232} 1233 1234void 1235flag_retry(int signo __unused) 1236{ 1237 flag_signal('A'); 1238} 1239 1240void 1241retry(void) 1242{ 1243 struct servtab *sep; 1244 1245 timingout = 0; 1246 for (sep = servtab; sep; sep = sep->se_next) 1247 if (sep->se_fd == -1 && !ISMUX(sep)) 1248 setup(sep); 1249} 1250 1251void 1252setup(struct servtab *sep) 1253{ 1254 int on = 1; 1255 1256 if ((sep->se_fd = socket(sep->se_family, sep->se_socktype, 0)) < 0) { 1257 if (debug) 1258 warn("socket failed on %s/%s", 1259 sep->se_service, sep->se_proto); 1260 syslog(LOG_ERR, "%s/%s: socket: %m", 1261 sep->se_service, sep->se_proto); 1262 return; 1263 } 1264 /* Set all listening sockets to close-on-exec. */ 1265 if (fcntl(sep->se_fd, F_SETFD, FD_CLOEXEC) < 0) { 1266 syslog(LOG_ERR, "%s/%s: fcntl (F_SETFD, FD_CLOEXEC): %m", 1267 sep->se_service, sep->se_proto); 1268 close(sep->se_fd); 1269 return; 1270 } 1271#define turnon(fd, opt) \ 1272setsockopt(fd, SOL_SOCKET, opt, (char *)&on, sizeof (on)) 1273 if (strcmp(sep->se_proto, "tcp") == 0 && (options & SO_DEBUG) && 1274 turnon(sep->se_fd, SO_DEBUG) < 0) 1275 syslog(LOG_ERR, "setsockopt (SO_DEBUG): %m"); 1276 if (turnon(sep->se_fd, SO_REUSEADDR) < 0) 1277 syslog(LOG_ERR, "setsockopt (SO_REUSEADDR): %m"); 1278#ifdef SO_PRIVSTATE 1279 if (turnon(sep->se_fd, SO_PRIVSTATE) < 0) 1280 syslog(LOG_ERR, "setsockopt (SO_PRIVSTATE): %m"); 1281#endif 1282 /* tftpd opens a new connection then needs more infos */ 1283 if ((sep->se_family == AF_INET6) && 1284 (strcmp(sep->se_proto, "udp") == 0) && 1285 (sep->se_accept == 0) && 1286 (setsockopt(sep->se_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, 1287 (char *)&on, sizeof (on)) < 0)) 1288 syslog(LOG_ERR, "setsockopt (IPV6_RECVPKTINFO): %m"); 1289 if (sep->se_family == AF_INET6) { 1290 int flag = sep->se_nomapped ? 1 : 0; 1291 if (setsockopt(sep->se_fd, IPPROTO_IPV6, IPV6_V6ONLY, 1292 (char *)&flag, sizeof (flag)) < 0) 1293 syslog(LOG_ERR, "setsockopt (IPV6_V6ONLY): %m"); 1294 } 1295#undef turnon 1296 if (sep->se_type == TTCP_TYPE) 1297 if (setsockopt(sep->se_fd, IPPROTO_TCP, TCP_NOPUSH, 1298 (char *)&on, sizeof (on)) < 0) 1299 syslog(LOG_ERR, "setsockopt (TCP_NOPUSH): %m"); 1300#ifdef IPV6_FAITH 1301 if (sep->se_type == FAITH_TYPE) { 1302 if (setsockopt(sep->se_fd, IPPROTO_IPV6, IPV6_FAITH, &on, 1303 sizeof(on)) < 0) { 1304 syslog(LOG_ERR, "setsockopt (IPV6_FAITH): %m"); 1305 } 1306 } 1307#endif 1308#ifdef IPSEC 1309 ipsecsetup(sep); 1310#endif 1311 if (sep->se_family == AF_UNIX) { 1312 (void) unlink(sep->se_ctrladdr_un.sun_path); 1313 umask(0777); /* Make socket with conservative permissions */ 1314 } 1315 if (bind(sep->se_fd, (struct sockaddr *)&sep->se_ctrladdr, 1316 sep->se_ctrladdr_size) < 0) { 1317 if (debug) 1318 warn("bind failed on %s/%s", 1319 sep->se_service, sep->se_proto); 1320 syslog(LOG_ERR, "%s/%s: bind: %m", 1321 sep->se_service, sep->se_proto); 1322 (void) close(sep->se_fd); 1323 sep->se_fd = -1; 1324 if (!timingout) { 1325 timingout = 1; 1326 alarm(RETRYTIME); 1327 } 1328 if (sep->se_family == AF_UNIX) 1329 umask(mask); 1330 return; 1331 } 1332 if (sep->se_family == AF_UNIX) { 1333 /* Ick - fch{own,mod} don't work on Unix domain sockets */ 1334 if (chown(sep->se_service, sep->se_sockuid, sep->se_sockgid) < 0) 1335 syslog(LOG_ERR, "chown socket: %m"); 1336 if (chmod(sep->se_service, sep->se_sockmode) < 0) 1337 syslog(LOG_ERR, "chmod socket: %m"); 1338 umask(mask); 1339 } 1340 if (sep->se_rpc) { 1341 u_int i; 1342 socklen_t len = sep->se_ctrladdr_size; 1343 struct netconfig *netid, *netid2 = NULL; 1344 struct sockaddr_in sock; 1345 struct netbuf nbuf, nbuf2; 1346 1347 if (getsockname(sep->se_fd, 1348 (struct sockaddr*)&sep->se_ctrladdr, &len) < 0){ 1349 syslog(LOG_ERR, "%s/%s: getsockname: %m", 1350 sep->se_service, sep->se_proto); 1351 (void) close(sep->se_fd); 1352 sep->se_fd = -1; 1353 return; 1354 } 1355 nbuf.buf = &sep->se_ctrladdr; 1356 nbuf.len = sep->se_ctrladdr.sa_len; 1357 if (sep->se_family == AF_INET) 1358 netid = sep->se_socktype==SOCK_DGRAM? udpconf:tcpconf; 1359 else { 1360 netid = sep->se_socktype==SOCK_DGRAM? udp6conf:tcp6conf; 1361 if (!sep->se_nomapped) { /* INET and INET6 */ 1362 netid2 = netid==udp6conf? udpconf:tcpconf; 1363 memset(&sock, 0, sizeof sock); /* ADDR_ANY */ 1364 nbuf2.buf = &sock; 1365 nbuf2.len = sock.sin_len = sizeof sock; 1366 sock.sin_family = AF_INET; 1367 sock.sin_port = sep->se_ctrladdr6.sin6_port; 1368 } 1369 } 1370 if (debug) 1371 print_service("REG ", sep); 1372 for (i = sep->se_rpc_lowvers; i <= sep->se_rpc_highvers; i++) { 1373 rpcb_unset(sep->se_rpc_prog, i, netid); 1374 rpcb_set(sep->se_rpc_prog, i, netid, &nbuf); 1375 if (netid2) { 1376 rpcb_unset(sep->se_rpc_prog, i, netid2); 1377 rpcb_set(sep->se_rpc_prog, i, netid2, &nbuf2); 1378 } 1379 } 1380 } 1381 if (sep->se_socktype == SOCK_STREAM) 1382 listen(sep->se_fd, 64); 1383 enable(sep); 1384 if (debug) { 1385 warnx("registered %s on %d", 1386 sep->se_server, sep->se_fd); 1387 } 1388} 1389 1390#ifdef IPSEC 1391void 1392ipsecsetup(sep) 1393 struct servtab *sep; 1394{ 1395 char *buf; 1396 char *policy_in = NULL; 1397 char *policy_out = NULL; 1398 int level; 1399 int opt; 1400 1401 switch (sep->se_family) { 1402 case AF_INET: 1403 level = IPPROTO_IP; 1404 opt = IP_IPSEC_POLICY; 1405 break; 1406#ifdef INET6 1407 case AF_INET6: 1408 level = IPPROTO_IPV6; 1409 opt = IPV6_IPSEC_POLICY; 1410 break; 1411#endif 1412 default: 1413 return; 1414 } 1415 1416 if (!sep->se_policy || sep->se_policy[0] == '\0') { 1417 static char def_in[] = "in entrust", def_out[] = "out entrust"; 1418 policy_in = def_in; 1419 policy_out = def_out; 1420 } else { 1421 if (!strncmp("in", sep->se_policy, 2)) 1422 policy_in = sep->se_policy; 1423 else if (!strncmp("out", sep->se_policy, 3)) 1424 policy_out = sep->se_policy; 1425 else { 1426 syslog(LOG_ERR, "invalid security policy \"%s\"", 1427 sep->se_policy); 1428 return; 1429 } 1430 } 1431 1432 if (policy_in != NULL) { 1433 buf = ipsec_set_policy(policy_in, strlen(policy_in)); 1434 if (buf != NULL) { 1435 if (setsockopt(sep->se_fd, level, opt, 1436 buf, ipsec_get_policylen(buf)) < 0 && 1437 debug != 0) 1438 warnx("%s/%s: ipsec initialization failed; %s", 1439 sep->se_service, sep->se_proto, 1440 policy_in); 1441 free(buf); 1442 } else 1443 syslog(LOG_ERR, "invalid security policy \"%s\"", 1444 policy_in); 1445 } 1446 if (policy_out != NULL) { 1447 buf = ipsec_set_policy(policy_out, strlen(policy_out)); 1448 if (buf != NULL) { 1449 if (setsockopt(sep->se_fd, level, opt, 1450 buf, ipsec_get_policylen(buf)) < 0 && 1451 debug != 0) 1452 warnx("%s/%s: ipsec initialization failed; %s", 1453 sep->se_service, sep->se_proto, 1454 policy_out); 1455 free(buf); 1456 } else 1457 syslog(LOG_ERR, "invalid security policy \"%s\"", 1458 policy_out); 1459 } 1460} 1461#endif 1462 1463/* 1464 * Finish with a service and its socket. 1465 */ 1466void 1467close_sep(struct servtab *sep) 1468{ 1469 if (sep->se_fd >= 0) { 1470 if (FD_ISSET(sep->se_fd, &allsock)) 1471 disable(sep); 1472 (void) close(sep->se_fd); 1473 sep->se_fd = -1; 1474 } 1475 sep->se_count = 0; 1476 sep->se_numchild = 0; /* forget about any existing children */ 1477} 1478 1479int 1480matchservent(const char *name1, const char *name2, const char *proto) 1481{ 1482 char **alias, *p; 1483 struct servent *se; 1484 1485 if (strcmp(proto, "unix") == 0) { 1486 if ((p = strrchr(name1, '/')) != NULL) 1487 name1 = p + 1; 1488 if ((p = strrchr(name2, '/')) != NULL) 1489 name2 = p + 1; 1490 } 1491 if (strcmp(name1, name2) == 0) 1492 return(1); 1493 if ((se = getservbyname(name1, proto)) != NULL) { 1494 if (strcmp(name2, se->s_name) == 0) 1495 return(1); 1496 for (alias = se->s_aliases; *alias; alias++) 1497 if (strcmp(name2, *alias) == 0) 1498 return(1); 1499 } 1500 return(0); 1501} 1502 1503struct servtab * 1504enter(struct servtab *cp) 1505{ 1506 struct servtab *sep; 1507 long omask; 1508 1509 sep = (struct servtab *)malloc(sizeof (*sep)); 1510 if (sep == (struct servtab *)0) { 1511 syslog(LOG_ERR, "malloc: %m"); 1512 exit(EX_OSERR); 1513 } 1514 *sep = *cp; 1515 sep->se_fd = -1; 1516 omask = sigblock(SIGBLOCK); 1517 sep->se_next = servtab; 1518 servtab = sep; 1519 sigsetmask(omask); 1520 return (sep); 1521} 1522 1523void 1524enable(struct servtab *sep) 1525{ 1526 if (debug) 1527 warnx( 1528 "enabling %s, fd %d", sep->se_service, sep->se_fd); 1529#ifdef SANITY_CHECK 1530 if (sep->se_fd < 0) { 1531 syslog(LOG_ERR, 1532 "%s: %s: bad fd", __func__, sep->se_service); 1533 exit(EX_SOFTWARE); 1534 } 1535 if (ISMUX(sep)) { 1536 syslog(LOG_ERR, 1537 "%s: %s: is mux", __func__, sep->se_service); 1538 exit(EX_SOFTWARE); 1539 } 1540 if (FD_ISSET(sep->se_fd, &allsock)) { 1541 syslog(LOG_ERR, 1542 "%s: %s: not off", __func__, sep->se_service); 1543 exit(EX_SOFTWARE); 1544 } 1545 nsock++; 1546#endif 1547 FD_SET(sep->se_fd, &allsock); 1548 if (sep->se_fd > maxsock) 1549 maxsock = sep->se_fd; 1550} 1551 1552void 1553disable(struct servtab *sep) 1554{ 1555 if (debug) 1556 warnx( 1557 "disabling %s, fd %d", sep->se_service, sep->se_fd); 1558#ifdef SANITY_CHECK 1559 if (sep->se_fd < 0) { 1560 syslog(LOG_ERR, 1561 "%s: %s: bad fd", __func__, sep->se_service); 1562 exit(EX_SOFTWARE); 1563 } 1564 if (ISMUX(sep)) { 1565 syslog(LOG_ERR, 1566 "%s: %s: is mux", __func__, sep->se_service); 1567 exit(EX_SOFTWARE); 1568 } 1569 if (!FD_ISSET(sep->se_fd, &allsock)) { 1570 syslog(LOG_ERR, 1571 "%s: %s: not on", __func__, sep->se_service); 1572 exit(EX_SOFTWARE); 1573 } 1574 if (nsock == 0) { 1575 syslog(LOG_ERR, "%s: nsock=0", __func__); 1576 exit(EX_SOFTWARE); 1577 } 1578 nsock--; 1579#endif 1580 FD_CLR(sep->se_fd, &allsock); 1581 if (sep->se_fd == maxsock) 1582 maxsock--; 1583} 1584 1585FILE *fconfig = NULL; 1586struct servtab serv; 1587char line[LINE_MAX]; 1588 1589int 1590setconfig(void) 1591{ 1592 1593 if (fconfig != NULL) { 1594 fseek(fconfig, 0L, SEEK_SET); 1595 return (1); 1596 } 1597 fconfig = fopen(CONFIG, "r"); 1598 return (fconfig != NULL); 1599} 1600 1601void 1602endconfig(void) 1603{ 1604 if (fconfig) { 1605 (void) fclose(fconfig); 1606 fconfig = NULL; 1607 } 1608} 1609 1610struct servtab * 1611getconfigent(void) 1612{ 1613 struct servtab *sep = &serv; 1614 int argc; 1615 char *cp, *arg, *s; 1616 char *versp; 1617 static char TCPMUX_TOKEN[] = "tcpmux/"; 1618#define MUX_LEN (sizeof(TCPMUX_TOKEN)-1) 1619#ifdef IPSEC 1620 char *policy; 1621#endif 1622 int v4bind; 1623#ifdef INET6 1624 int v6bind; 1625#endif 1626 int i; 1627 1628#ifdef IPSEC 1629 policy = NULL; 1630#endif 1631more: 1632 v4bind = 0; 1633#ifdef INET6 1634 v6bind = 0; 1635#endif 1636 while ((cp = nextline(fconfig)) != NULL) { 1637#ifdef IPSEC 1638 /* lines starting with #@ is not a comment, but the policy */ 1639 if (cp[0] == '#' && cp[1] == '@') { 1640 char *p; 1641 for (p = cp + 2; p && *p && isspace(*p); p++) 1642 ; 1643 if (*p == '\0') { 1644 if (policy) 1645 free(policy); 1646 policy = NULL; 1647 } else if (ipsec_get_policylen(p) >= 0) { 1648 if (policy) 1649 free(policy); 1650 policy = newstr(p); 1651 } else { 1652 syslog(LOG_ERR, 1653 "%s: invalid ipsec policy \"%s\"", 1654 CONFIG, p); 1655 exit(EX_CONFIG); 1656 } 1657 } 1658#endif 1659 if (*cp == '#' || *cp == '\0') 1660 continue; 1661 break; 1662 } 1663 if (cp == NULL) 1664 return ((struct servtab *)0); 1665 /* 1666 * clear the static buffer, since some fields (se_ctrladdr, 1667 * for example) don't get initialized here. 1668 */ 1669 memset(sep, 0, sizeof *sep); 1670 arg = skip(&cp); 1671 if (cp == NULL) { 1672 /* got an empty line containing just blanks/tabs. */ 1673 goto more; 1674 } 1675 if (arg[0] == ':') { /* :user:group:perm: */ 1676 char *user, *group, *perm; 1677 struct passwd *pw; 1678 struct group *gr; 1679 user = arg+1; 1680 if ((group = strchr(user, ':')) == NULL) { 1681 syslog(LOG_ERR, "no group after user '%s'", user); 1682 goto more; 1683 } 1684 *group++ = '\0'; 1685 if ((perm = strchr(group, ':')) == NULL) { 1686 syslog(LOG_ERR, "no mode after group '%s'", group); 1687 goto more; 1688 } 1689 *perm++ = '\0'; 1690 if ((pw = getpwnam(user)) == NULL) { 1691 syslog(LOG_ERR, "no such user '%s'", user); 1692 goto more; 1693 } 1694 sep->se_sockuid = pw->pw_uid; 1695 if ((gr = getgrnam(group)) == NULL) { 1696 syslog(LOG_ERR, "no such user '%s'", group); 1697 goto more; 1698 } 1699 sep->se_sockgid = gr->gr_gid; 1700 sep->se_sockmode = strtol(perm, &arg, 8); 1701 if (*arg != ':') { 1702 syslog(LOG_ERR, "bad mode '%s'", perm); 1703 goto more; 1704 } 1705 *arg++ = '\0'; 1706 } else { 1707 sep->se_sockuid = euid; 1708 sep->se_sockgid = egid; 1709 sep->se_sockmode = 0200; 1710 } 1711 if (strncmp(arg, TCPMUX_TOKEN, MUX_LEN) == 0) { 1712 char *c = arg + MUX_LEN; 1713 if (*c == '+') { 1714 sep->se_type = MUXPLUS_TYPE; 1715 c++; 1716 } else 1717 sep->se_type = MUX_TYPE; 1718 sep->se_service = newstr(c); 1719 } else { 1720 sep->se_service = newstr(arg); 1721 sep->se_type = NORM_TYPE; 1722 } 1723 arg = sskip(&cp); 1724 if (strcmp(arg, "stream") == 0) 1725 sep->se_socktype = SOCK_STREAM; 1726 else if (strcmp(arg, "dgram") == 0) 1727 sep->se_socktype = SOCK_DGRAM; 1728 else if (strcmp(arg, "rdm") == 0) 1729 sep->se_socktype = SOCK_RDM; 1730 else if (strcmp(arg, "seqpacket") == 0) 1731 sep->se_socktype = SOCK_SEQPACKET; 1732 else if (strcmp(arg, "raw") == 0) 1733 sep->se_socktype = SOCK_RAW; 1734 else 1735 sep->se_socktype = -1; 1736 1737 arg = sskip(&cp); 1738 if (strncmp(arg, "tcp", 3) == 0) { 1739 sep->se_proto = newstr(strsep(&arg, "/")); 1740 if (arg != NULL) { 1741 if (strcmp(arg, "ttcp") == 0) 1742 sep->se_type = TTCP_TYPE; 1743 else if (strcmp(arg, "faith") == 0) 1744 sep->se_type = FAITH_TYPE; 1745 } 1746 } else { 1747 if (sep->se_type == NORM_TYPE && 1748 strncmp(arg, "faith/", 6) == 0) { 1749 arg += 6; 1750 sep->se_type = FAITH_TYPE; 1751 } 1752 sep->se_proto = newstr(arg); 1753 } 1754 if (strncmp(sep->se_proto, "rpc/", 4) == 0) { 1755 memmove(sep->se_proto, sep->se_proto + 4, 1756 strlen(sep->se_proto) + 1 - 4); 1757 sep->se_rpc = 1; 1758 sep->se_rpc_prog = sep->se_rpc_lowvers = 1759 sep->se_rpc_lowvers = 0; 1760 memcpy(&sep->se_ctrladdr4, bind_sa4, 1761 sizeof(sep->se_ctrladdr4)); 1762 if ((versp = rindex(sep->se_service, '/'))) { 1763 *versp++ = '\0'; 1764 switch (sscanf(versp, "%u-%u", 1765 &sep->se_rpc_lowvers, 1766 &sep->se_rpc_highvers)) { 1767 case 2: 1768 break; 1769 case 1: 1770 sep->se_rpc_highvers = 1771 sep->se_rpc_lowvers; 1772 break; 1773 default: 1774 syslog(LOG_ERR, 1775 "bad RPC version specifier; %s", 1776 sep->se_service); 1777 freeconfig(sep); 1778 goto more; 1779 } 1780 } 1781 else { 1782 sep->se_rpc_lowvers = 1783 sep->se_rpc_highvers = 1; 1784 } 1785 } 1786 sep->se_nomapped = 0; 1787 if (strcmp(sep->se_proto, "unix") == 0) { 1788 sep->se_family = AF_UNIX; 1789 } else { 1790 while (isdigit(sep->se_proto[strlen(sep->se_proto) - 1])) { 1791#ifdef INET6 1792 if (sep->se_proto[strlen(sep->se_proto) - 1] == '6') { 1793 sep->se_proto[strlen(sep->se_proto) - 1] = '\0'; 1794 v6bind = 1; 1795 continue; 1796 } 1797#endif 1798 if (sep->se_proto[strlen(sep->se_proto) - 1] == '4') { 1799 sep->se_proto[strlen(sep->se_proto) - 1] = '\0'; 1800 v4bind = 1; 1801 continue; 1802 } 1803 /* illegal version num */ 1804 syslog(LOG_ERR, "bad IP version for %s", sep->se_proto); 1805 freeconfig(sep); 1806 goto more; 1807 } 1808#ifdef INET6 1809 if (v6bind && !v6bind_ok) { 1810 syslog(LOG_INFO, "IPv6 bind is ignored for %s", 1811 sep->se_service); 1812 if (v4bind && v4bind_ok) 1813 v6bind = 0; 1814 else { 1815 freeconfig(sep); 1816 goto more; 1817 } 1818 } 1819 if (v6bind) { 1820 sep->se_family = AF_INET6; 1821 if (!v4bind || !v4bind_ok) 1822 sep->se_nomapped = 1; 1823 } else 1824#endif 1825 { /* default to v4 bind if not v6 bind */ 1826 if (!v4bind_ok) { 1827 syslog(LOG_NOTICE, "IPv4 bind is ignored for %s", 1828 sep->se_service); 1829 freeconfig(sep); 1830 goto more; 1831 } 1832 sep->se_family = AF_INET; 1833 } 1834 } 1835 /* init ctladdr */ 1836 switch(sep->se_family) { 1837 case AF_INET: 1838 memcpy(&sep->se_ctrladdr4, bind_sa4, 1839 sizeof(sep->se_ctrladdr4)); 1840 sep->se_ctrladdr_size = sizeof(sep->se_ctrladdr4); 1841 break; 1842#ifdef INET6 1843 case AF_INET6: 1844 memcpy(&sep->se_ctrladdr6, bind_sa6, 1845 sizeof(sep->se_ctrladdr6)); 1846 sep->se_ctrladdr_size = sizeof(sep->se_ctrladdr6); 1847 break; 1848#endif 1849 case AF_UNIX: 1850 if (strlen(sep->se_service) >= sizeof(sep->se_ctrladdr_un.sun_path)) { 1851 syslog(LOG_ERR, 1852 "domain socket pathname too long for service %s", 1853 sep->se_service); 1854 goto more; 1855 } 1856 memset(&sep->se_ctrladdr, 0, sizeof(sep->se_ctrladdr)); 1857 sep->se_ctrladdr_un.sun_family = sep->se_family; 1858 sep->se_ctrladdr_un.sun_len = strlen(sep->se_service); 1859 strcpy(sep->se_ctrladdr_un.sun_path, sep->se_service); 1860 sep->se_ctrladdr_size = SUN_LEN(&sep->se_ctrladdr_un); 1861 } 1862 arg = sskip(&cp); 1863 if (!strncmp(arg, "wait", 4)) 1864 sep->se_accept = 0; 1865 else if (!strncmp(arg, "nowait", 6)) 1866 sep->se_accept = 1; 1867 else { 1868 syslog(LOG_ERR, 1869 "%s: bad wait/nowait for service %s", 1870 CONFIG, sep->se_service); 1871 goto more; 1872 } 1873 sep->se_maxchild = -1; 1874 sep->se_maxcpm = -1; 1875 sep->se_maxperip = -1; 1876 if ((s = strchr(arg, '/')) != NULL) { 1877 char *eptr; 1878 u_long val; 1879 1880 val = strtoul(s + 1, &eptr, 10); 1881 if (eptr == s + 1 || val > MAX_MAXCHLD) { 1882 syslog(LOG_ERR, 1883 "%s: bad max-child for service %s", 1884 CONFIG, sep->se_service); 1885 goto more; 1886 } 1887 if (debug) 1888 if (!sep->se_accept && val != 1) 1889 warnx("maxchild=%lu for wait service %s" 1890 " not recommended", val, sep->se_service); 1891 sep->se_maxchild = val; 1892 if (*eptr == '/') 1893 sep->se_maxcpm = strtol(eptr + 1, &eptr, 10); 1894 if (*eptr == '/') 1895 sep->se_maxperip = strtol(eptr + 1, &eptr, 10); 1896 /* 1897 * explicitly do not check for \0 for future expansion / 1898 * backwards compatibility 1899 */ 1900 } 1901 if (ISMUX(sep)) { 1902 /* 1903 * Silently enforce "nowait" mode for TCPMUX services 1904 * since they don't have an assigned port to listen on. 1905 */ 1906 sep->se_accept = 1; 1907 if (strcmp(sep->se_proto, "tcp")) { 1908 syslog(LOG_ERR, 1909 "%s: bad protocol for tcpmux service %s", 1910 CONFIG, sep->se_service); 1911 goto more; 1912 } 1913 if (sep->se_socktype != SOCK_STREAM) { 1914 syslog(LOG_ERR, 1915 "%s: bad socket type for tcpmux service %s", 1916 CONFIG, sep->se_service); 1917 goto more; 1918 } 1919 } 1920 sep->se_user = newstr(sskip(&cp)); 1921#ifdef LOGIN_CAP 1922 if ((s = strrchr(sep->se_user, '/')) != NULL) { 1923 *s = '\0'; 1924 sep->se_class = newstr(s + 1); 1925 } else 1926 sep->se_class = newstr(RESOURCE_RC); 1927#endif 1928 if ((s = strrchr(sep->se_user, ':')) != NULL) { 1929 *s = '\0'; 1930 sep->se_group = newstr(s + 1); 1931 } else 1932 sep->se_group = NULL; 1933 sep->se_server = newstr(sskip(&cp)); 1934 if ((sep->se_server_name = rindex(sep->se_server, '/'))) 1935 sep->se_server_name++; 1936 if (strcmp(sep->se_server, "internal") == 0) { 1937 struct biltin *bi; 1938 1939 for (bi = biltins; bi->bi_service; bi++) 1940 if (bi->bi_socktype == sep->se_socktype && 1941 matchservent(bi->bi_service, sep->se_service, 1942 sep->se_proto)) 1943 break; 1944 if (bi->bi_service == 0) { 1945 syslog(LOG_ERR, "internal service %s unknown", 1946 sep->se_service); 1947 goto more; 1948 } 1949 sep->se_accept = 1; /* force accept mode for built-ins */ 1950 sep->se_bi = bi; 1951 } else 1952 sep->se_bi = NULL; 1953 if (sep->se_maxperip < 0) 1954 sep->se_maxperip = maxperip; 1955 if (sep->se_maxcpm < 0) 1956 sep->se_maxcpm = maxcpm; 1957 if (sep->se_maxchild < 0) { /* apply default max-children */ 1958 if (sep->se_bi && sep->se_bi->bi_maxchild >= 0) 1959 sep->se_maxchild = sep->se_bi->bi_maxchild; 1960 else if (sep->se_accept) 1961 sep->se_maxchild = maxchild > 0 ? maxchild : 0; 1962 else 1963 sep->se_maxchild = 1; 1964 } 1965 if (sep->se_maxchild > 0) { 1966 sep->se_pids = malloc(sep->se_maxchild * sizeof(*sep->se_pids)); 1967 if (sep->se_pids == NULL) { 1968 syslog(LOG_ERR, "malloc: %m"); 1969 exit(EX_OSERR); 1970 } 1971 } 1972 argc = 0; 1973 for (arg = skip(&cp); cp; arg = skip(&cp)) 1974 if (argc < MAXARGV) { 1975 sep->se_argv[argc++] = newstr(arg); 1976 } else { 1977 syslog(LOG_ERR, 1978 "%s: too many arguments for service %s", 1979 CONFIG, sep->se_service); 1980 goto more; 1981 } 1982 while (argc <= MAXARGV) 1983 sep->se_argv[argc++] = NULL; 1984 for (i = 0; i < PERIPSIZE; ++i) 1985 LIST_INIT(&sep->se_conn[i]); 1986#ifdef IPSEC 1987 sep->se_policy = policy ? newstr(policy) : NULL; 1988#endif 1989 return (sep); 1990} 1991 1992void 1993freeconfig(struct servtab *cp) 1994{ 1995 int i; 1996 1997 if (cp->se_service) 1998 free(cp->se_service); 1999 if (cp->se_proto) 2000 free(cp->se_proto); 2001 if (cp->se_user) 2002 free(cp->se_user); 2003 if (cp->se_group) 2004 free(cp->se_group); 2005#ifdef LOGIN_CAP 2006 if (cp->se_class) 2007 free(cp->se_class); 2008#endif 2009 if (cp->se_server) 2010 free(cp->se_server); 2011 if (cp->se_pids) 2012 free(cp->se_pids); 2013 for (i = 0; i < MAXARGV; i++) 2014 if (cp->se_argv[i]) 2015 free(cp->se_argv[i]); 2016 free_connlist(cp); 2017#ifdef IPSEC 2018 if (cp->se_policy) 2019 free(cp->se_policy); 2020#endif 2021} 2022 2023 2024/* 2025 * Safe skip - if skip returns null, log a syntax error in the 2026 * configuration file and exit. 2027 */ 2028char * 2029sskip(char **cpp) 2030{ 2031 char *cp; 2032 2033 cp = skip(cpp); 2034 if (cp == NULL) { 2035 syslog(LOG_ERR, "%s: syntax error", CONFIG); 2036 exit(EX_DATAERR); 2037 } 2038 return (cp); 2039} 2040 2041char * 2042skip(char **cpp) 2043{ 2044 char *cp = *cpp; 2045 char *start; 2046 char quote = '\0'; 2047 2048again: 2049 while (*cp == ' ' || *cp == '\t') 2050 cp++; 2051 if (*cp == '\0') { 2052 int c; 2053 2054 c = getc(fconfig); 2055 (void) ungetc(c, fconfig); 2056 if (c == ' ' || c == '\t') 2057 if ((cp = nextline(fconfig))) 2058 goto again; 2059 *cpp = (char *)0; 2060 return ((char *)0); 2061 } 2062 if (*cp == '"' || *cp == '\'') 2063 quote = *cp++; 2064 start = cp; 2065 if (quote) 2066 while (*cp && *cp != quote) 2067 cp++; 2068 else 2069 while (*cp && *cp != ' ' && *cp != '\t') 2070 cp++; 2071 if (*cp != '\0') 2072 *cp++ = '\0'; 2073 *cpp = cp; 2074 return (start); 2075} 2076 2077char * 2078nextline(FILE *fd) 2079{ 2080 char *cp; 2081 2082 if (fgets(line, sizeof (line), fd) == NULL) 2083 return ((char *)0); 2084 cp = strchr(line, '\n'); 2085 if (cp) 2086 *cp = '\0'; 2087 return (line); 2088} 2089 2090char * 2091newstr(const char *cp) 2092{ 2093 char *cr; 2094 2095 if ((cr = strdup(cp != NULL ? cp : ""))) 2096 return (cr); 2097 syslog(LOG_ERR, "strdup: %m"); 2098 exit(EX_OSERR); 2099} 2100 2101void 2102inetd_setproctitle(const char *a, int s) 2103{ 2104 socklen_t size; 2105 struct sockaddr_storage ss; 2106 char buf[80], pbuf[INET6_ADDRSTRLEN]; 2107 2108 size = sizeof(ss); 2109 if (getpeername(s, (struct sockaddr *)&ss, &size) == 0) { 2110 getnameinfo((struct sockaddr *)&ss, size, pbuf, sizeof(pbuf), 2111 NULL, 0, NI_NUMERICHOST); 2112 (void) sprintf(buf, "%s [%s]", a, pbuf); 2113 } else 2114 (void) sprintf(buf, "%s", a); 2115 setproctitle("%s", buf); 2116} 2117 2118int 2119check_loop(const struct sockaddr *sa, const struct servtab *sep) 2120{ 2121 struct servtab *se2; 2122 char pname[INET6_ADDRSTRLEN]; 2123 2124 for (se2 = servtab; se2; se2 = se2->se_next) { 2125 if (!se2->se_bi || se2->se_socktype != SOCK_DGRAM) 2126 continue; 2127 2128 switch (se2->se_family) { 2129 case AF_INET: 2130 if (((const struct sockaddr_in *)sa)->sin_port == 2131 se2->se_ctrladdr4.sin_port) 2132 goto isloop; 2133 continue; 2134#ifdef INET6 2135 case AF_INET6: 2136 if (((const struct sockaddr_in *)sa)->sin_port == 2137 se2->se_ctrladdr4.sin_port) 2138 goto isloop; 2139 continue; 2140#endif 2141 default: 2142 continue; 2143 } 2144 isloop: 2145 getnameinfo(sa, sa->sa_len, pname, sizeof(pname), NULL, 0, 2146 NI_NUMERICHOST); 2147 syslog(LOG_WARNING, "%s/%s:%s/%s loop request REFUSED from %s", 2148 sep->se_service, sep->se_proto, 2149 se2->se_service, se2->se_proto, 2150 pname); 2151 return 1; 2152 } 2153 return 0; 2154} 2155 2156/* 2157 * print_service: 2158 * Dump relevant information to stderr 2159 */ 2160void 2161print_service(const char *action, const struct servtab *sep) 2162{ 2163 fprintf(stderr, 2164 "%s: %s proto=%s accept=%d max=%d user=%s group=%s" 2165#ifdef LOGIN_CAP 2166 "class=%s" 2167#endif 2168 " builtin=%p server=%s" 2169#ifdef IPSEC 2170 " policy=\"%s\"" 2171#endif 2172 "\n", 2173 action, sep->se_service, sep->se_proto, 2174 sep->se_accept, sep->se_maxchild, sep->se_user, sep->se_group, 2175#ifdef LOGIN_CAP 2176 sep->se_class, 2177#endif 2178 (void *) sep->se_bi, sep->se_server 2179#ifdef IPSEC 2180 , (sep->se_policy ? sep->se_policy : "") 2181#endif 2182 ); 2183} 2184 2185#define CPMHSIZE 256 2186#define CPMHMASK (CPMHSIZE-1) 2187#define CHTGRAN 10 2188#define CHTSIZE 6 2189 2190typedef struct CTime { 2191 unsigned long ct_Ticks; 2192 int ct_Count; 2193} CTime; 2194 2195typedef struct CHash { 2196 union { 2197 struct in_addr c4_Addr; 2198 struct in6_addr c6_Addr; 2199 } cu_Addr; 2200#define ch_Addr4 cu_Addr.c4_Addr 2201#define ch_Addr6 cu_Addr.c6_Addr 2202 int ch_Family; 2203 time_t ch_LTime; 2204 char *ch_Service; 2205 CTime ch_Times[CHTSIZE]; 2206} CHash; 2207 2208CHash CHashAry[CPMHSIZE]; 2209 2210int 2211cpmip(const struct servtab *sep, int ctrl) 2212{ 2213 struct sockaddr_storage rss; 2214 socklen_t rssLen = sizeof(rss); 2215 int r = 0; 2216 2217 /* 2218 * If getpeername() fails, just let it through (if logging is 2219 * enabled the condition is caught elsewhere) 2220 */ 2221 2222 if (sep->se_maxcpm > 0 && 2223 getpeername(ctrl, (struct sockaddr *)&rss, &rssLen) == 0 ) { 2224 time_t t = time(NULL); 2225 int hv = 0xABC3D20F; 2226 int i; 2227 int cnt = 0; 2228 CHash *chBest = NULL; 2229 unsigned int ticks = t / CHTGRAN; 2230 struct sockaddr_in *sin4; 2231#ifdef INET6 2232 struct sockaddr_in6 *sin6; 2233#endif 2234 2235 sin4 = (struct sockaddr_in *)&rss; 2236#ifdef INET6 2237 sin6 = (struct sockaddr_in6 *)&rss; 2238#endif 2239 { 2240 char *p; 2241 int addrlen; 2242 2243 switch (rss.ss_family) { 2244 case AF_INET: 2245 p = (char *)&sin4->sin_addr; 2246 addrlen = sizeof(struct in_addr); 2247 break; 2248#ifdef INET6 2249 case AF_INET6: 2250 p = (char *)&sin6->sin6_addr; 2251 addrlen = sizeof(struct in6_addr); 2252 break; 2253#endif 2254 default: 2255 /* should not happen */ 2256 return -1; 2257 } 2258 2259 for (i = 0; i < addrlen; ++i, ++p) { 2260 hv = (hv << 5) ^ (hv >> 23) ^ *p; 2261 } 2262 hv = (hv ^ (hv >> 16)); 2263 } 2264 for (i = 0; i < 5; ++i) { 2265 CHash *ch = &CHashAry[(hv + i) & CPMHMASK]; 2266 2267 if (rss.ss_family == AF_INET && 2268 ch->ch_Family == AF_INET && 2269 sin4->sin_addr.s_addr == ch->ch_Addr4.s_addr && 2270 ch->ch_Service && strcmp(sep->se_service, 2271 ch->ch_Service) == 0) { 2272 chBest = ch; 2273 break; 2274 } 2275#ifdef INET6 2276 if (rss.ss_family == AF_INET6 && 2277 ch->ch_Family == AF_INET6 && 2278 IN6_ARE_ADDR_EQUAL(&sin6->sin6_addr, 2279 &ch->ch_Addr6) != 0 && 2280 ch->ch_Service && strcmp(sep->se_service, 2281 ch->ch_Service) == 0) { 2282 chBest = ch; 2283 break; 2284 } 2285#endif 2286 if (chBest == NULL || ch->ch_LTime == 0 || 2287 ch->ch_LTime < chBest->ch_LTime) { 2288 chBest = ch; 2289 } 2290 } 2291 if ((rss.ss_family == AF_INET && 2292 (chBest->ch_Family != AF_INET || 2293 sin4->sin_addr.s_addr != chBest->ch_Addr4.s_addr)) || 2294 chBest->ch_Service == NULL || 2295 strcmp(sep->se_service, chBest->ch_Service) != 0) { 2296 chBest->ch_Family = sin4->sin_family; 2297 chBest->ch_Addr4 = sin4->sin_addr; 2298 if (chBest->ch_Service) 2299 free(chBest->ch_Service); 2300 chBest->ch_Service = strdup(sep->se_service); 2301 bzero(chBest->ch_Times, sizeof(chBest->ch_Times)); 2302 } 2303#ifdef INET6 2304 if ((rss.ss_family == AF_INET6 && 2305 (chBest->ch_Family != AF_INET6 || 2306 IN6_ARE_ADDR_EQUAL(&sin6->sin6_addr, 2307 &chBest->ch_Addr6) == 0)) || 2308 chBest->ch_Service == NULL || 2309 strcmp(sep->se_service, chBest->ch_Service) != 0) { 2310 chBest->ch_Family = sin6->sin6_family; 2311 chBest->ch_Addr6 = sin6->sin6_addr; 2312 if (chBest->ch_Service) 2313 free(chBest->ch_Service); 2314 chBest->ch_Service = strdup(sep->se_service); 2315 bzero(chBest->ch_Times, sizeof(chBest->ch_Times)); 2316 } 2317#endif 2318 chBest->ch_LTime = t; 2319 { 2320 CTime *ct = &chBest->ch_Times[ticks % CHTSIZE]; 2321 if (ct->ct_Ticks != ticks) { 2322 ct->ct_Ticks = ticks; 2323 ct->ct_Count = 0; 2324 } 2325 ++ct->ct_Count; 2326 } 2327 for (i = 0; i < CHTSIZE; ++i) { 2328 CTime *ct = &chBest->ch_Times[i]; 2329 if (ct->ct_Ticks <= ticks && 2330 ct->ct_Ticks >= ticks - CHTSIZE) { 2331 cnt += ct->ct_Count; 2332 } 2333 } 2334 if ((cnt * 60) / (CHTSIZE * CHTGRAN) > sep->se_maxcpm) { 2335 char pname[INET6_ADDRSTRLEN]; 2336 2337 getnameinfo((struct sockaddr *)&rss, 2338 ((struct sockaddr *)&rss)->sa_len, 2339 pname, sizeof(pname), NULL, 0, 2340 NI_NUMERICHOST); 2341 r = -1; 2342 syslog(LOG_ERR, 2343 "%s from %s exceeded counts/min (limit %d/min)", 2344 sep->se_service, pname, 2345 sep->se_maxcpm); 2346 } 2347 } 2348 return(r); 2349} 2350 2351static struct conninfo * 2352search_conn(struct servtab *sep, int ctrl) 2353{ 2354 struct sockaddr_storage ss; 2355 socklen_t sslen = sizeof(ss); 2356 struct conninfo *conn; 2357 int hv; 2358 char pname[NI_MAXHOST], pname2[NI_MAXHOST]; 2359 2360 if (sep->se_maxperip <= 0) 2361 return NULL; 2362 2363 /* 2364 * If getpeername() fails, just let it through (if logging is 2365 * enabled the condition is caught elsewhere) 2366 */ 2367 if (getpeername(ctrl, (struct sockaddr *)&ss, &sslen) != 0) 2368 return NULL; 2369 2370 switch (ss.ss_family) { 2371 case AF_INET: 2372 hv = hashval((char *)&((struct sockaddr_in *)&ss)->sin_addr, 2373 sizeof(struct in_addr)); 2374 break; 2375#ifdef INET6 2376 case AF_INET6: 2377 hv = hashval((char *)&((struct sockaddr_in6 *)&ss)->sin6_addr, 2378 sizeof(struct in6_addr)); 2379 break; 2380#endif 2381 default: 2382 /* 2383 * Since we only support AF_INET and AF_INET6, just 2384 * let other than AF_INET and AF_INET6 through. 2385 */ 2386 return NULL; 2387 } 2388 2389 if (getnameinfo((struct sockaddr *)&ss, sslen, pname, sizeof(pname), 2390 NULL, 0, NI_NUMERICHOST) != 0) 2391 return NULL; 2392 2393 LIST_FOREACH(conn, &sep->se_conn[hv], co_link) { 2394 if (getnameinfo((struct sockaddr *)&conn->co_addr, 2395 conn->co_addr.ss_len, pname2, sizeof(pname2), NULL, 0, 2396 NI_NUMERICHOST) == 0 && 2397 strcmp(pname, pname2) == 0) 2398 break; 2399 } 2400 2401 if (conn == NULL) { 2402 if ((conn = malloc(sizeof(struct conninfo))) == NULL) { 2403 syslog(LOG_ERR, "malloc: %m"); 2404 exit(EX_OSERR); 2405 } 2406 conn->co_proc = malloc(sep->se_maxperip * sizeof(*conn->co_proc)); 2407 if (conn->co_proc == NULL) { 2408 syslog(LOG_ERR, "malloc: %m"); 2409 exit(EX_OSERR); 2410 } 2411 memcpy(&conn->co_addr, (struct sockaddr *)&ss, sslen); 2412 conn->co_numchild = 0; 2413 LIST_INSERT_HEAD(&sep->se_conn[hv], conn, co_link); 2414 } 2415 2416 /* 2417 * Since a child process is not invoked yet, we cannot 2418 * determine a pid of a child. So, co_proc and co_numchild 2419 * should be filled leter. 2420 */ 2421 2422 return conn; 2423} 2424 2425static int 2426room_conn(struct servtab *sep, struct conninfo *conn) 2427{ 2428 char pname[NI_MAXHOST]; 2429 2430 if (conn->co_numchild >= sep->se_maxperip) { 2431 getnameinfo((struct sockaddr *)&conn->co_addr, 2432 conn->co_addr.ss_len, pname, sizeof(pname), NULL, 0, 2433 NI_NUMERICHOST); 2434 syslog(LOG_ERR, "%s from %s exceeded counts (limit %d)", 2435 sep->se_service, pname, sep->se_maxperip); 2436 return 0; 2437 } 2438 return 1; 2439} 2440 2441static void 2442addchild_conn(struct conninfo *conn, pid_t pid) 2443{ 2444 struct procinfo *proc; 2445 2446 if (conn == NULL) 2447 return; 2448 2449 if ((proc = search_proc(pid, 1)) != NULL) { 2450 if (proc->pr_conn != NULL) { 2451 syslog(LOG_ERR, 2452 "addchild_conn: child already on process list"); 2453 exit(EX_OSERR); 2454 } 2455 proc->pr_conn = conn; 2456 } 2457 2458 conn->co_proc[conn->co_numchild++] = proc; 2459} 2460 2461static void 2462reapchild_conn(pid_t pid) 2463{ 2464 struct procinfo *proc; 2465 struct conninfo *conn; 2466 int i; 2467 2468 if ((proc = search_proc(pid, 0)) == NULL) 2469 return; 2470 if ((conn = proc->pr_conn) == NULL) 2471 return; 2472 for (i = 0; i < conn->co_numchild; ++i) 2473 if (conn->co_proc[i] == proc) { 2474 conn->co_proc[i] = conn->co_proc[--conn->co_numchild]; 2475 break; 2476 } 2477 free_proc(proc); 2478 free_conn(conn); 2479} 2480 2481static void 2482resize_conn(struct servtab *sep, int maxpip) 2483{ 2484 struct conninfo *conn; 2485 int i, j; 2486 2487 if (sep->se_maxperip <= 0) 2488 return; 2489 if (maxpip <= 0) { 2490 free_connlist(sep); 2491 return; 2492 } 2493 for (i = 0; i < PERIPSIZE; ++i) { 2494 LIST_FOREACH(conn, &sep->se_conn[i], co_link) { 2495 for (j = maxpip; j < conn->co_numchild; ++j) 2496 free_proc(conn->co_proc[j]); 2497 conn->co_proc = realloc(conn->co_proc, 2498 maxpip * sizeof(*conn->co_proc)); 2499 if (conn->co_proc == NULL) { 2500 syslog(LOG_ERR, "realloc: %m"); 2501 exit(EX_OSERR); 2502 } 2503 if (conn->co_numchild > maxpip) 2504 conn->co_numchild = maxpip; 2505 } 2506 } 2507} 2508 2509static void 2510free_connlist(struct servtab *sep) 2511{ 2512 struct conninfo *conn; 2513 int i, j; 2514 2515 for (i = 0; i < PERIPSIZE; ++i) { 2516 while ((conn = LIST_FIRST(&sep->se_conn[i])) != NULL) { 2517 for (j = 0; j < conn->co_numchild; ++j) 2518 free_proc(conn->co_proc[j]); 2519 conn->co_numchild = 0; 2520 free_conn(conn); 2521 } 2522 } 2523} 2524 2525static void 2526free_conn(struct conninfo *conn) 2527{ 2528 if (conn == NULL) 2529 return; 2530 if (conn->co_numchild <= 0) { 2531 LIST_REMOVE(conn, co_link); 2532 free(conn->co_proc); 2533 free(conn); 2534 } 2535} 2536 2537static struct procinfo * 2538search_proc(pid_t pid, int add) 2539{ 2540 struct procinfo *proc; 2541 int hv; 2542 2543 hv = hashval((char *)&pid, sizeof(pid)); 2544 LIST_FOREACH(proc, &proctable[hv], pr_link) { 2545 if (proc->pr_pid == pid) 2546 break; 2547 } 2548 if (proc == NULL && add) { 2549 if ((proc = malloc(sizeof(struct procinfo))) == NULL) { 2550 syslog(LOG_ERR, "malloc: %m"); 2551 exit(EX_OSERR); 2552 } 2553 proc->pr_pid = pid; 2554 proc->pr_conn = NULL; 2555 LIST_INSERT_HEAD(&proctable[hv], proc, pr_link); 2556 } 2557 return proc; 2558} 2559 2560static void 2561free_proc(struct procinfo *proc) 2562{ 2563 if (proc == NULL) 2564 return; 2565 LIST_REMOVE(proc, pr_link); 2566 free(proc); 2567} 2568 2569static int 2570hashval(char *p, int len) 2571{ 2572 int i, hv = 0xABC3D20F; 2573 2574 for (i = 0; i < len; ++i, ++p) 2575 hv = (hv << 5) ^ (hv >> 23) ^ *p; 2576 hv = (hv ^ (hv >> 16)) & (PERIPSIZE - 1); 2577 return hv; 2578} 2579