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