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