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