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