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