1 /* $NetBSD: inetd.c,v 1.122 2014/04/05 23:36:10 khorben Exp $ */ 2 3 /*- 4 * Copyright (c) 1998, 2003 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 9 * NASA Ames Research Center and by Matthias Scheler. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 /* 34 * Copyright (c) 1983, 1991, 1993, 1994 35 * The Regents of the University of California. All rights reserved. 36 * 37 * Redistribution and use in source and binary forms, with or without 38 * modification, are permitted provided that the following conditions 39 * are met: 40 * 1. Redistributions of source code must retain the above copyright 41 * notice, this list of conditions and the following disclaimer. 42 * 2. Redistributions in binary form must reproduce the above copyright 43 * notice, this list of conditions and the following disclaimer in the 44 * documentation and/or other materials provided with the distribution. 45 * 3. Neither the name of the University nor the names of its contributors 46 * may be used to endorse or promote products derived from this software 47 * without specific prior written permission. 48 * 49 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 50 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 52 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 59 * SUCH DAMAGE. 60 */ 61 62 #include <sys/cdefs.h> 63 #ifndef lint 64 __COPYRIGHT("@(#) Copyright (c) 1983, 1991, 1993, 1994\ 65 The Regents of the University of California. All rights reserved."); 66 #if 0 67 static char sccsid[] = "@(#)inetd.c 8.4 (Berkeley) 4/13/94"; 68 #else 69 __RCSID("$NetBSD: inetd.c,v 1.122 2014/04/05 23:36:10 khorben Exp $"); 70 #endif 71 #endif /* not lint */ 72 73 /* 74 * Inetd - Internet super-server 75 * 76 * This program invokes all internet services as needed. Connection-oriented 77 * services are invoked each time a connection is made, by creating a process. 78 * This process is passed the connection as file descriptor 0 and is expected 79 * to do a getpeername to find out the source host and port. 80 * 81 * Datagram oriented services are invoked when a datagram 82 * arrives; a process is created and passed a pending message 83 * on file descriptor 0. Datagram servers may either connect 84 * to their peer, freeing up the original socket for inetd 85 * to receive further messages on, or ``take over the socket'', 86 * processing all arriving datagrams and, eventually, timing 87 * out. The first type of server is said to be ``multi-threaded''; 88 * the second type of server ``single-threaded''. 89 * 90 * Inetd uses a configuration file which is read at startup 91 * and, possibly, at some later time in response to a hangup signal. 92 * The configuration file is ``free format'' with fields given in the 93 * order shown below. Continuation lines for an entry must being with 94 * a space or tab. All fields must be present in each entry. 95 * 96 * service name must be in /etc/services or must 97 * name a tcpmux service 98 * socket type[:accf[,arg]] stream/dgram/raw/rdm/seqpacket, 99 only stream can name an accept filter 100 * protocol must be in /etc/protocols 101 * wait/nowait[:max] single-threaded/multi-threaded, max # 102 * user[:group] user/group to run daemon as 103 * server program full path name 104 * server program arguments maximum of MAXARGS (20) 105 * 106 * For RPC services 107 * service name/version must be in /etc/rpc 108 * socket type stream/dgram/raw/rdm/seqpacket 109 * protocol must be in /etc/protocols 110 * wait/nowait[:max] single-threaded/multi-threaded 111 * user[:group] user to run daemon as 112 * server program full path name 113 * server program arguments maximum of MAXARGS (20) 114 * 115 * For non-RPC services, the "service name" can be of the form 116 * hostaddress:servicename, in which case the hostaddress is used 117 * as the host portion of the address to listen on. If hostaddress 118 * consists of a single `*' character, INADDR_ANY is used. 119 * 120 * A line can also consist of just 121 * hostaddress: 122 * where hostaddress is as in the preceding paragraph. Such a line must 123 * have no further fields; the specified hostaddress is remembered and 124 * used for all further lines that have no hostaddress specified, 125 * until the next such line (or EOF). (This is why * is provided to 126 * allow explicit specification of INADDR_ANY.) A line 127 * *: 128 * is implicitly in effect at the beginning of the file. 129 * 130 * The hostaddress specifier may (and often will) contain dots; 131 * the service name must not. 132 * 133 * For RPC services, host-address specifiers are accepted and will 134 * work to some extent; however, because of limitations in the 135 * portmapper interface, it will not work to try to give more than 136 * one line for any given RPC service, even if the host-address 137 * specifiers are different. 138 * 139 * TCP services without official port numbers are handled with the 140 * RFC1078-based tcpmux internal service. Tcpmux listens on port 1 for 141 * requests. When a connection is made from a foreign host, the service 142 * requested is passed to tcpmux, which looks it up in the servtab list 143 * and returns the proper entry for the service. Tcpmux returns a 144 * negative reply if the service doesn't exist, otherwise the invoked 145 * server is expected to return the positive reply if the service type in 146 * inetd.conf file has the prefix "tcpmux/". If the service type has the 147 * prefix "tcpmux/+", tcpmux will return the positive reply for the 148 * process; this is for compatibility with older server code, and also 149 * allows you to invoke programs that use stdin/stdout without putting any 150 * special server code in them. Services that use tcpmux are "nowait" 151 * because they do not have a well-known port and hence cannot listen 152 * for new requests. 153 * 154 * Comment lines are indicated by a `#' in column 1. 155 * 156 * #ifdef IPSEC 157 * Comment lines that start with "#@" denote IPsec policy string, as described 158 * in ipsec_set_policy(3). This will affect all the following items in 159 * inetd.conf(8). To reset the policy, just use "#@" line. By default, 160 * there's no IPsec policy. 161 * #endif 162 */ 163 164 /* 165 * Here's the scoop concerning the user:group feature: 166 * 167 * 1) set-group-option off. 168 * 169 * a) user = root: NO setuid() or setgid() is done 170 * 171 * b) other: setuid() 172 * setgid(primary group as found in passwd) 173 * initgroups(name, primary group) 174 * 175 * 2) set-group-option on. 176 * 177 * a) user = root: NO setuid() 178 * setgid(specified group) 179 * NO initgroups() 180 * 181 * b) other: setuid() 182 * setgid(specified group) 183 * initgroups(name, specified group) 184 * 185 */ 186 187 #include <sys/param.h> 188 #include <sys/stat.h> 189 #include <sys/ioctl.h> 190 #include <sys/socket.h> 191 #include <sys/un.h> 192 #include <sys/wait.h> 193 #include <sys/time.h> 194 #include <sys/resource.h> 195 #include <sys/event.h> 196 197 #ifndef NO_RPC 198 #define RPC 199 #endif 200 201 #include <net/if.h> 202 203 #include <netinet/in.h> 204 #include <arpa/inet.h> 205 #ifdef RPC 206 #include <rpc/rpc.h> 207 #include <rpc/rpcb_clnt.h> 208 #include <netconfig.h> 209 #endif 210 211 #include <ctype.h> 212 #include <errno.h> 213 #include <fcntl.h> 214 #include <grp.h> 215 #include <netdb.h> 216 #include <pwd.h> 217 #include <signal.h> 218 #include <stdio.h> 219 #include <stdlib.h> 220 #include <string.h> 221 #include <syslog.h> 222 #include <unistd.h> 223 #include <util.h> 224 #include <ifaddrs.h> 225 226 #include "pathnames.h" 227 228 #ifdef IPSEC 229 #include <netipsec/ipsec.h> 230 #ifndef IPSEC_POLICY_IPSEC /* no ipsec support on old ipsec */ 231 #undef IPSEC 232 #endif 233 #include "ipsec.h" 234 #endif 235 236 #ifdef LIBWRAP 237 # include <tcpd.h> 238 #ifndef LIBWRAP_ALLOW_FACILITY 239 # define LIBWRAP_ALLOW_FACILITY LOG_AUTH 240 #endif 241 #ifndef LIBWRAP_ALLOW_SEVERITY 242 # define LIBWRAP_ALLOW_SEVERITY LOG_INFO 243 #endif 244 #ifndef LIBWRAP_DENY_FACILITY 245 # define LIBWRAP_DENY_FACILITY LOG_AUTH 246 #endif 247 #ifndef LIBWRAP_DENY_SEVERITY 248 # define LIBWRAP_DENY_SEVERITY LOG_WARNING 249 #endif 250 int allow_severity = LIBWRAP_ALLOW_FACILITY|LIBWRAP_ALLOW_SEVERITY; 251 int deny_severity = LIBWRAP_DENY_FACILITY|LIBWRAP_DENY_SEVERITY; 252 #endif 253 254 #define TOOMANY 40 /* don't start more than TOOMANY */ 255 #define CNT_INTVL 60 /* servers in CNT_INTVL sec. */ 256 #define RETRYTIME (60*10) /* retry after bind or server fail */ 257 258 #define A_CNT(a) (sizeof (a) / sizeof (a[0])) 259 260 int debug; 261 #ifdef LIBWRAP 262 int lflag; 263 #endif 264 int maxsock; 265 #ifndef __minix 266 int kq; 267 #else /* __minix */ 268 int sig_pipe[2]; 269 sigset_t sig_mask, old_mask; 270 #endif /* __minix */ 271 int options; 272 int timingout; 273 const int niflags = NI_NUMERICHOST | NI_NUMERICSERV; 274 275 #ifndef OPEN_MAX 276 #define OPEN_MAX 64 277 #endif 278 279 /* Reserve some descriptors, 3 stdio + at least: 1 log, 1 conf. file */ 280 #define FD_MARGIN (8) 281 rlim_t rlim_ofile_cur = OPEN_MAX; 282 283 struct rlimit rlim_ofile; 284 285 struct kevent changebuf[64]; 286 size_t changes; 287 288 struct servtab { 289 char *se_hostaddr; /* host address to listen on */ 290 char *se_service; /* name of service */ 291 int se_socktype; /* type of socket to use */ 292 int se_family; /* address family */ 293 char *se_proto; /* protocol used */ 294 int se_sndbuf; /* sndbuf size */ 295 int se_rcvbuf; /* rcvbuf size */ 296 int se_rpcprog; /* rpc program number */ 297 int se_rpcversl; /* rpc program lowest version */ 298 int se_rpcversh; /* rpc program highest version */ 299 #define isrpcservice(sep) ((sep)->se_rpcversl != 0) 300 pid_t se_wait; /* single threaded server */ 301 short se_checked; /* looked at during merge */ 302 char *se_user; /* user name to run as */ 303 char *se_group; /* group name to run as */ 304 struct biltin *se_bi; /* if built-in, description */ 305 char *se_server; /* server program */ 306 #define MAXARGV 20 307 char *se_argv[MAXARGV+1]; /* program arguments */ 308 #ifdef IPSEC 309 char *se_policy; /* IPsec poilcy string */ 310 #endif 311 struct accept_filter_arg se_accf; /* accept filter for stream service */ 312 int se_fd; /* open descriptor */ 313 int se_type; /* type */ 314 union { 315 struct sockaddr se_un_ctrladdr; 316 struct sockaddr_in se_un_ctrladdr_in; 317 struct sockaddr_in6 se_un_ctrladdr_in6; 318 struct sockaddr_un se_un_ctrladdr_un; 319 } se_un; /* bound address */ 320 #define se_ctrladdr se_un.se_un_ctrladdr 321 #define se_ctrladdr_in se_un.se_un_ctrladdr_in 322 #define se_ctrladdr_un se_un.se_un_ctrladdr_un 323 int se_ctrladdr_size; 324 int se_max; /* max # of instances of this service */ 325 int se_count; /* number started since se_time */ 326 struct timeval se_time; /* start of se_count */ 327 struct servtab *se_next; 328 } *servtab; 329 330 #define NORM_TYPE 0 331 #define MUX_TYPE 1 332 #define MUXPLUS_TYPE 2 333 #define FAITH_TYPE 3 334 #define ISMUX(sep) (((sep)->se_type == MUX_TYPE) || \ 335 ((sep)->se_type == MUXPLUS_TYPE)) 336 #define ISMUXPLUS(sep) ((sep)->se_type == MUXPLUS_TYPE) 337 338 339 static void chargen_dg(int, struct servtab *); 340 static void chargen_stream(int, struct servtab *); 341 static void close_sep(struct servtab *); 342 static void config(void); 343 static void daytime_dg(int, struct servtab *); 344 static void daytime_stream(int, struct servtab *); 345 static void discard_dg(int, struct servtab *); 346 static void discard_stream(int, struct servtab *); 347 static void echo_dg(int, struct servtab *); 348 static void echo_stream(int, struct servtab *); 349 static void endconfig(void); 350 static struct servtab *enter(struct servtab *); 351 static void freeconfig(struct servtab *); 352 static struct servtab *getconfigent(void); 353 __dead static void goaway(void); 354 static void machtime_dg(int, struct servtab *); 355 static void machtime_stream(int, struct servtab *); 356 static char *newstr(const char *); 357 static char *nextline(FILE *); 358 static void print_service(const char *, struct servtab *); 359 static void reapchild(void); 360 static void retry(void); 361 static void run_service(int, struct servtab *, int); 362 static int setconfig(void); 363 static void setup(struct servtab *); 364 static char *sskip(char **); 365 static char *skip(char **); 366 static void tcpmux(int, struct servtab *); 367 __dead static void usage(void); 368 static void register_rpc(struct servtab *); 369 static void unregister_rpc(struct servtab *); 370 static void bump_nofile(void); 371 static void inetd_setproctitle(char *, int); 372 static void initring(void); 373 static uint32_t machtime(void); 374 static int port_good_dg(struct sockaddr *); 375 static int dg_broadcast(struct in_addr *); 376 #ifndef __minix 377 static int my_kevent(const struct kevent *, size_t, struct kevent *, 378 size_t); 379 static struct kevent * allocchange(void); 380 #endif /* !__minix */ 381 static int get_line(int, char *, int); 382 static void spawn(struct servtab *, int); 383 384 struct biltin { 385 const char *bi_service; /* internally provided service name */ 386 int bi_socktype; /* type of socket supported */ 387 short bi_fork; /* 1 if should fork before call */ 388 short bi_wait; /* 1 if should wait for child */ 389 void (*bi_fn)(int, struct servtab *); 390 /* function which performs it */ 391 } biltins[] = { 392 /* Echo received data */ 393 { "echo", SOCK_STREAM, 1, 0, echo_stream }, 394 { "echo", SOCK_DGRAM, 0, 0, echo_dg }, 395 396 /* Internet /dev/null */ 397 { "discard", SOCK_STREAM, 1, 0, discard_stream }, 398 { "discard", SOCK_DGRAM, 0, 0, discard_dg }, 399 400 /* Return 32 bit time since 1970 */ 401 { "time", SOCK_STREAM, 0, 0, machtime_stream }, 402 { "time", SOCK_DGRAM, 0, 0, machtime_dg }, 403 404 /* Return human-readable time */ 405 { "daytime", SOCK_STREAM, 0, 0, daytime_stream }, 406 { "daytime", SOCK_DGRAM, 0, 0, daytime_dg }, 407 408 /* Familiar character generator */ 409 { "chargen", SOCK_STREAM, 1, 0, chargen_stream }, 410 { "chargen", SOCK_DGRAM, 0, 0, chargen_dg }, 411 412 { "tcpmux", SOCK_STREAM, 1, 0, tcpmux }, 413 414 { NULL, 0, 0, 0, NULL } 415 }; 416 417 /* list of "bad" ports. I.e. ports that are most obviously used for 418 * "cycling packets" denial of service attacks. See /etc/services. 419 * List must end with port number "0". 420 */ 421 422 u_int16_t bad_ports[] = { 7, 9, 13, 19, 37, 0 }; 423 424 425 #define NUMINT (sizeof(intab) / sizeof(struct inent)) 426 const char *CONFIG = _PATH_INETDCONF; 427 428 static int my_signals[] = 429 { SIGALRM, SIGHUP, SIGCHLD, SIGTERM, SIGINT, SIGPIPE }; 430 431 #ifdef __minix 432 /* 433 * NetBSD uses kqueue to catch signals, while (explicitly) ignoring them at the 434 * process level. We (MINIX3) do catch the signals at the process level, 435 * instead sending them into select() using a pipe (djb's self-pipe trick). 436 * That is safe, except it may interrupt system calls other than our select(), 437 * so we also have to set appropriate signal masks (clearing them upon fork). 438 */ 439 static void 440 got_signal(int sig) 441 { 442 443 (void) write(sig_pipe[1], &sig, sizeof(sig)); 444 } 445 #endif /* __minix */ 446 447 int 448 main(int argc, char *argv[]) 449 { 450 int ch, n, reload = 1; 451 452 while ((ch = getopt(argc, argv, 453 #ifdef LIBWRAP 454 "dl" 455 #else 456 "d" 457 #endif 458 )) != -1) 459 switch(ch) { 460 case 'd': 461 debug = 1; 462 options |= SO_DEBUG; 463 break; 464 #ifdef LIBWRAP 465 case 'l': 466 lflag = 1; 467 break; 468 #endif 469 case '?': 470 default: 471 usage(); 472 } 473 argc -= optind; 474 argv += optind; 475 476 if (argc > 0) 477 CONFIG = argv[0]; 478 479 if (!debug) 480 daemon(0, 0); 481 openlog("inetd", LOG_PID | LOG_NOWAIT, LOG_DAEMON); 482 pidfile(NULL); 483 484 #ifndef __minix 485 kq = kqueue(); 486 if (kq < 0) { 487 syslog(LOG_ERR, "kqueue: %m"); 488 return (EXIT_FAILURE); 489 } 490 #else /* __minix */ 491 if (pipe2(sig_pipe, O_CLOEXEC | O_NONBLOCK) != 0) { 492 syslog(LOG_ERR, "pipe2: %m"); 493 return (EXIT_FAILURE); 494 } 495 496 /* Block all signals until the first select() call.. just easier. */ 497 sigfillset(&sig_mask); 498 (void) sigprocmask(SIG_SETMASK, &sig_mask, &old_mask); 499 sig_mask = old_mask; 500 #endif /* __minix */ 501 502 if (getrlimit(RLIMIT_NOFILE, &rlim_ofile) < 0) { 503 syslog(LOG_ERR, "getrlimit: %m"); 504 } else { 505 rlim_ofile_cur = rlim_ofile.rlim_cur; 506 if (rlim_ofile_cur == RLIM_INFINITY) /* ! */ 507 rlim_ofile_cur = OPEN_MAX; 508 } 509 510 for (n = 0; n < (int)A_CNT(my_signals); n++) { 511 int signum; 512 513 signum = my_signals[n]; 514 #ifndef __minix 515 if (signum != SIGCHLD) 516 (void) signal(signum, SIG_IGN); 517 518 if (signum != SIGPIPE) { 519 struct kevent *ev; 520 521 ev = allocchange(); 522 EV_SET(ev, signum, EVFILT_SIGNAL, EV_ADD | EV_ENABLE, 523 0, 0, 0); 524 } 525 #else /* __minix */ 526 /* The above code ignores but does not "catch" SIGPIPE. */ 527 if (signum != SIGPIPE) 528 (void) signal(signum, got_signal); 529 else 530 (void) signal(signum, SIG_IGN); 531 sigaddset(&sig_mask, signum); 532 #endif /* __minix */ 533 } 534 535 for (;;) { 536 int ctrl; 537 #ifndef __minix 538 struct kevent eventbuf[64], *ev; 539 #else 540 fd_set fds; 541 int sig, highfd; 542 #endif /* !__minix */ 543 struct servtab *sep; 544 545 if (reload) { 546 reload = 0; 547 config(); 548 } 549 550 #ifdef __minix 551 FD_ZERO(&fds); 552 FD_SET(sig_pipe[0], &fds); 553 highfd = sig_pipe[0]; 554 555 for (sep = servtab; sep != NULL; sep = sep->se_next) 556 if (sep->se_fd != -1 && (unsigned)sep->se_wait <= 1) { 557 FD_SET(sep->se_fd, &fds); 558 if (highfd < sep->se_fd) 559 highfd = sep->se_fd; 560 } 561 562 /* 563 * Unblock all the signals we want to catch for the duration of 564 * the select() call. We do not yet have pselect(), but the 565 * lack of atomicity does not affect correctness here, because 566 * all the signals go through the pipe anyway--that is also why 567 * we reissue the select() even if we did catch a signal. 568 */ 569 (void) sigprocmask(SIG_SETMASK, &old_mask, NULL); 570 571 while (select(highfd + 1, &fds, NULL, NULL, NULL) == -1 && 572 errno == EINTR); 573 574 (void) sigprocmask(SIG_SETMASK, &sig_mask, NULL); 575 576 if (FD_ISSET(sig_pipe[0], &fds)) { 577 while (read(sig_pipe[0], &sig, sizeof(sig)) != -1) { 578 switch (sig) { 579 #else /* !__minix */ 580 n = my_kevent(changebuf, changes, eventbuf, A_CNT(eventbuf)); 581 changes = 0; 582 583 for (ev = eventbuf; n > 0; ev++, n--) { 584 if (ev->filter == EVFILT_SIGNAL) { 585 switch (ev->ident) { 586 #endif /* !__minix */ 587 case SIGALRM: 588 retry(); 589 break; 590 case SIGCHLD: 591 reapchild(); 592 break; 593 case SIGTERM: 594 case SIGINT: 595 goaway(); 596 break; 597 case SIGHUP: 598 reload = 1; 599 break; 600 } 601 continue; 602 } 603 #ifdef __minix 604 } 605 606 for (sep = servtab; sep != NULL; sep = sep->se_next) { 607 if (sep->se_fd == -1 || (unsigned)sep->se_wait > 1 || 608 !FD_ISSET(sep->se_fd, &fds)) 609 continue; 610 #else /* !__minix */ 611 if (ev->filter != EVFILT_READ) 612 continue; 613 sep = (struct servtab *)ev->udata; 614 /* Paranoia */ 615 if ((int)ev->ident != sep->se_fd) 616 continue; 617 #endif /* !__minix */ 618 if (debug) 619 fprintf(stderr, "someone wants %s\n", 620 sep->se_service); 621 if (!sep->se_wait && sep->se_socktype == SOCK_STREAM) { 622 /* XXX here do the libwrap check-before-accept*/ 623 ctrl = accept(sep->se_fd, NULL, NULL); 624 if (debug) 625 fprintf(stderr, "accept, ctrl %d\n", 626 ctrl); 627 if (ctrl < 0) { 628 if (errno != EINTR) 629 syslog(LOG_WARNING, 630 "accept (for %s): %m", 631 sep->se_service); 632 continue; 633 } 634 } else 635 ctrl = sep->se_fd; 636 spawn(sep, ctrl); 637 } 638 } 639 } 640 641 static void 642 spawn(struct servtab *sep, int ctrl) 643 { 644 int dofork; 645 pid_t pid; 646 647 pid = 0; 648 #ifdef LIBWRAP_INTERNAL 649 dofork = 1; 650 #else 651 dofork = (sep->se_bi == 0 || sep->se_bi->bi_fork); 652 #endif 653 if (dofork) { 654 if (sep->se_count++ == 0) 655 (void)gettimeofday(&sep->se_time, NULL); 656 else if (sep->se_count >= sep->se_max) { 657 struct timeval now; 658 659 (void)gettimeofday(&now, NULL); 660 if (now.tv_sec - sep->se_time.tv_sec > CNT_INTVL) { 661 sep->se_time = now; 662 sep->se_count = 1; 663 } else { 664 syslog(LOG_ERR, 665 "%s/%s max spawn rate (%d in %d seconds) " 666 "exceeded; service not started", 667 sep->se_service, sep->se_proto, 668 sep->se_max, CNT_INTVL); 669 if (!sep->se_wait && sep->se_socktype == 670 SOCK_STREAM) 671 close(ctrl); 672 close_sep(sep); 673 if (!timingout) { 674 timingout = 1; 675 alarm(RETRYTIME); 676 } 677 return; 678 } 679 } 680 pid = fork(); 681 if (pid < 0) { 682 syslog(LOG_ERR, "fork: %m"); 683 if (!sep->se_wait && sep->se_socktype == SOCK_STREAM) 684 close(ctrl); 685 sleep(1); 686 return; 687 } 688 if (pid != 0 && sep->se_wait) { 689 #ifndef __minix 690 struct kevent *ev; 691 692 sep->se_wait = pid; 693 ev = allocchange(); 694 EV_SET(ev, sep->se_fd, EVFILT_READ, 695 EV_DELETE, 0, 0, 0); 696 #endif /* !__minix */ 697 } 698 if (pid == 0) { 699 size_t n; 700 701 for (n = 0; n < A_CNT(my_signals); n++) 702 (void) signal(my_signals[n], SIG_DFL); 703 #ifdef __minix 704 close(sig_pipe[0]); 705 close(sig_pipe[1]); 706 707 (void) sigprocmask(SIG_SETMASK, &old_mask, NULL); 708 #endif /* __minix */ 709 if (debug) 710 setsid(); 711 } 712 } 713 if (pid == 0) { 714 run_service(ctrl, sep, dofork); 715 if (dofork) 716 exit(0); 717 } 718 if (!sep->se_wait && sep->se_socktype == SOCK_STREAM) 719 close(ctrl); 720 } 721 722 static void 723 run_service(int ctrl, struct servtab *sep, int didfork) 724 { 725 struct passwd *pwd; 726 struct group *grp = NULL; /* XXX gcc */ 727 char buf[NI_MAXSERV]; 728 struct servtab *s; 729 #ifdef LIBWRAP 730 char abuf[BUFSIZ]; 731 struct request_info req; 732 int denied; 733 char *service = NULL; /* XXX gcc */ 734 #endif 735 736 #ifdef LIBWRAP 737 #ifndef LIBWRAP_INTERNAL 738 if (sep->se_bi == 0) 739 #endif 740 if (!sep->se_wait && sep->se_socktype == SOCK_STREAM) { 741 request_init(&req, RQ_DAEMON, sep->se_argv[0] ? 742 sep->se_argv[0] : sep->se_service, RQ_FILE, ctrl, NULL); 743 fromhost(&req); 744 denied = !hosts_access(&req); 745 if (denied || lflag) { 746 if (getnameinfo(&sep->se_ctrladdr, 747 (socklen_t)sep->se_ctrladdr.sa_len, NULL, 0, 748 buf, sizeof(buf), 0) != 0) { 749 /* shouldn't happen */ 750 (void)snprintf(buf, sizeof buf, "%d", 751 ntohs(sep->se_ctrladdr_in.sin_port)); 752 } 753 service = buf; 754 if (req.client->sin) { 755 sockaddr_snprintf(abuf, sizeof(abuf), "%a", 756 req.client->sin); 757 } else { 758 strcpy(abuf, "(null)"); 759 } 760 } 761 if (denied) { 762 syslog(deny_severity, 763 "refused connection from %.500s(%s), service %s (%s)", 764 eval_client(&req), abuf, service, sep->se_proto); 765 goto reject; 766 } 767 if (lflag) { 768 syslog(allow_severity, 769 "connection from %.500s(%s), service %s (%s)", 770 eval_client(&req), abuf, service, sep->se_proto); 771 } 772 } 773 #endif /* LIBWRAP */ 774 775 if (sep->se_bi) { 776 if (didfork) { 777 for (s = servtab; s; s = s->se_next) 778 if (s->se_fd != -1 && s->se_fd != ctrl) { 779 close(s->se_fd); 780 s->se_fd = -1; 781 } 782 } 783 (*sep->se_bi->bi_fn)(ctrl, sep); 784 } else { 785 if ((pwd = getpwnam(sep->se_user)) == NULL) { 786 syslog(LOG_ERR, "%s/%s: %s: No such user", 787 sep->se_service, sep->se_proto, sep->se_user); 788 goto reject; 789 } 790 if (sep->se_group && 791 (grp = getgrnam(sep->se_group)) == NULL) { 792 syslog(LOG_ERR, "%s/%s: %s: No such group", 793 sep->se_service, sep->se_proto, sep->se_group); 794 goto reject; 795 } 796 if (pwd->pw_uid) { 797 if (sep->se_group) 798 pwd->pw_gid = grp->gr_gid; 799 if (setgid(pwd->pw_gid) < 0) { 800 syslog(LOG_ERR, 801 "%s/%s: can't set gid %d: %m", sep->se_service, 802 sep->se_proto, pwd->pw_gid); 803 goto reject; 804 } 805 (void) initgroups(pwd->pw_name, 806 pwd->pw_gid); 807 if (setuid(pwd->pw_uid) < 0) { 808 syslog(LOG_ERR, 809 "%s/%s: can't set uid %d: %m", sep->se_service, 810 sep->se_proto, pwd->pw_uid); 811 goto reject; 812 } 813 } else if (sep->se_group) { 814 (void) setgid((gid_t)grp->gr_gid); 815 } 816 if (debug) 817 fprintf(stderr, "%d execl %s\n", 818 getpid(), sep->se_server); 819 /* Set our control descriptor to not close-on-exec... */ 820 if (fcntl(ctrl, F_SETFD, 0) < 0) 821 syslog(LOG_ERR, "fcntl (%d, F_SETFD, 0): %m", ctrl); 822 /* ...and dup it to stdin, stdout, and stderr. */ 823 if (ctrl != 0) { 824 dup2(ctrl, 0); 825 close(ctrl); 826 ctrl = 0; 827 } 828 dup2(0, 1); 829 dup2(0, 2); 830 if (rlim_ofile.rlim_cur != rlim_ofile_cur && 831 setrlimit(RLIMIT_NOFILE, &rlim_ofile) < 0) 832 syslog(LOG_ERR, "setrlimit: %m"); 833 execv(sep->se_server, sep->se_argv); 834 syslog(LOG_ERR, "cannot execute %s: %m", sep->se_server); 835 reject: 836 if (sep->se_socktype != SOCK_STREAM) 837 recv(ctrl, buf, sizeof (buf), 0); 838 _exit(1); 839 } 840 } 841 842 static void 843 reapchild(void) 844 { 845 int status; 846 pid_t pid; 847 struct servtab *sep; 848 849 for (;;) { 850 pid = wait3(&status, WNOHANG, NULL); 851 if (pid <= 0) 852 break; 853 if (debug) 854 (void) fprintf(stderr, "%d reaped, status %#x\n", 855 pid, status); 856 for (sep = servtab; sep != NULL; sep = sep->se_next) 857 if (sep->se_wait == pid) { 858 #ifndef __minix 859 struct kevent *ev; 860 #endif /* !__minix */ 861 862 if (WIFEXITED(status) && WEXITSTATUS(status)) 863 syslog(LOG_WARNING, 864 "%s: exit status %u", 865 sep->se_server, WEXITSTATUS(status)); 866 else if (WIFSIGNALED(status)) 867 syslog(LOG_WARNING, 868 "%s: exit signal %u", 869 sep->se_server, WTERMSIG(status)); 870 sep->se_wait = 1; 871 #ifndef __minix 872 ev = allocchange(); 873 EV_SET(ev, sep->se_fd, EVFILT_READ, 874 EV_ADD | EV_ENABLE, 0, 0, (intptr_t)sep); 875 #endif /* !__minix */ 876 if (debug) 877 fprintf(stderr, "restored %s, fd %d\n", 878 sep->se_service, sep->se_fd); 879 } 880 } 881 } 882 883 static void 884 config(void) 885 { 886 struct servtab *sep, *cp, **sepp; 887 size_t n; 888 889 if (!setconfig()) { 890 syslog(LOG_ERR, "%s: %m", CONFIG); 891 return; 892 } 893 for (sep = servtab; sep != NULL; sep = sep->se_next) 894 sep->se_checked = 0; 895 while ((cp = getconfigent()) != NULL) { 896 for (sep = servtab; sep != NULL; sep = sep->se_next) 897 if (strcmp(sep->se_service, cp->se_service) == 0 && 898 strcmp(sep->se_hostaddr, cp->se_hostaddr) == 0 && 899 strcmp(sep->se_proto, cp->se_proto) == 0 && 900 ISMUX(sep) == ISMUX(cp)) 901 break; 902 if (sep != NULL) { 903 int i; 904 905 #define SWAP(type, a, b) {type c = a; a = b; b = c;} 906 907 /* 908 * sep->se_wait may be holding the pid of a daemon 909 * that we're waiting for. If so, don't overwrite 910 * it unless the config file explicitly says don't 911 * wait. 912 */ 913 if (cp->se_bi == 0 && 914 (sep->se_wait == 1 || cp->se_wait == 0)) 915 sep->se_wait = cp->se_wait; 916 SWAP(char *, sep->se_user, cp->se_user); 917 SWAP(char *, sep->se_group, cp->se_group); 918 SWAP(char *, sep->se_server, cp->se_server); 919 for (i = 0; i < MAXARGV; i++) 920 SWAP(char *, sep->se_argv[i], cp->se_argv[i]); 921 #ifdef IPSEC 922 SWAP(char *, sep->se_policy, cp->se_policy); 923 #endif 924 SWAP(int, cp->se_type, sep->se_type); 925 SWAP(int, cp->se_max, sep->se_max); 926 #undef SWAP 927 if (isrpcservice(sep)) 928 unregister_rpc(sep); 929 sep->se_rpcversl = cp->se_rpcversl; 930 sep->se_rpcversh = cp->se_rpcversh; 931 freeconfig(cp); 932 if (debug) 933 print_service("REDO", sep); 934 } else { 935 sep = enter(cp); 936 if (debug) 937 print_service("ADD ", sep); 938 } 939 sep->se_checked = 1; 940 941 switch (sep->se_family) { 942 case AF_LOCAL: 943 if (sep->se_fd != -1) 944 break; 945 n = strlen(sep->se_service); 946 if (n >= sizeof(sep->se_ctrladdr_un.sun_path)) { 947 syslog(LOG_ERR, "%s: address too long", 948 sep->se_service); 949 sep->se_checked = 0; 950 continue; 951 } 952 (void)unlink(sep->se_service); 953 strlcpy(sep->se_ctrladdr_un.sun_path, 954 sep->se_service, n); 955 sep->se_ctrladdr_un.sun_family = AF_LOCAL; 956 sep->se_ctrladdr_size = (int)(n + 957 sizeof(sep->se_ctrladdr_un) - 958 sizeof(sep->se_ctrladdr_un.sun_path)); 959 if (!ISMUX(sep)) 960 setup(sep); 961 break; 962 case AF_INET: 963 #ifdef INET6 964 case AF_INET6: 965 #endif 966 { 967 struct addrinfo hints, *res; 968 char *host; 969 const char *port; 970 int error; 971 int s; 972 973 /* check if the family is supported */ 974 s = socket(sep->se_family, SOCK_DGRAM, 0); 975 if (s < 0) { 976 syslog(LOG_WARNING, 977 "%s/%s: %s: the address family is not " 978 "supported by the kernel", 979 sep->se_service, sep->se_proto, 980 sep->se_hostaddr); 981 sep->se_checked = 0; 982 continue; 983 } 984 close(s); 985 986 memset(&hints, 0, sizeof(hints)); 987 hints.ai_family = sep->se_family; 988 hints.ai_socktype = sep->se_socktype; 989 hints.ai_flags = AI_PASSIVE; 990 if (!strcmp(sep->se_hostaddr, "*")) 991 host = NULL; 992 else 993 host = sep->se_hostaddr; 994 if (isrpcservice(sep) || ISMUX(sep)) 995 port = "0"; 996 else 997 port = sep->se_service; 998 error = getaddrinfo(host, port, &hints, &res); 999 if (error) { 1000 if (error == EAI_SERVICE) { 1001 /* gai_strerror not friendly enough */ 1002 syslog(LOG_WARNING, "%s/%s: " 1003 "unknown service", 1004 sep->se_service, sep->se_proto); 1005 } else { 1006 syslog(LOG_ERR, "%s/%s: %s: %s", 1007 sep->se_service, sep->se_proto, 1008 sep->se_hostaddr, 1009 gai_strerror(error)); 1010 } 1011 sep->se_checked = 0; 1012 continue; 1013 } 1014 if (res->ai_next) { 1015 syslog(LOG_ERR, 1016 "%s/%s: %s: resolved to multiple addr", 1017 sep->se_service, sep->se_proto, 1018 sep->se_hostaddr); 1019 sep->se_checked = 0; 1020 freeaddrinfo(res); 1021 continue; 1022 } 1023 memcpy(&sep->se_ctrladdr, res->ai_addr, 1024 res->ai_addrlen); 1025 if (ISMUX(sep)) { 1026 sep->se_fd = -1; 1027 freeaddrinfo(res); 1028 continue; 1029 } 1030 sep->se_ctrladdr_size = res->ai_addrlen; 1031 freeaddrinfo(res); 1032 #ifdef RPC 1033 if (isrpcservice(sep)) { 1034 struct rpcent *rp; 1035 1036 sep->se_rpcprog = atoi(sep->se_service); 1037 if (sep->se_rpcprog == 0) { 1038 rp = getrpcbyname(sep->se_service); 1039 if (rp == 0) { 1040 syslog(LOG_ERR, 1041 "%s/%s: unknown service", 1042 sep->se_service, 1043 sep->se_proto); 1044 sep->se_checked = 0; 1045 continue; 1046 } 1047 sep->se_rpcprog = rp->r_number; 1048 } 1049 if (sep->se_fd == -1 && !ISMUX(sep)) 1050 setup(sep); 1051 if (sep->se_fd != -1) 1052 register_rpc(sep); 1053 } else 1054 #endif 1055 { 1056 if (sep->se_fd >= 0) 1057 close_sep(sep); 1058 if (sep->se_fd == -1 && !ISMUX(sep)) 1059 setup(sep); 1060 } 1061 } 1062 } 1063 } 1064 endconfig(); 1065 /* 1066 * Purge anything not looked at above. 1067 */ 1068 sepp = &servtab; 1069 while ((sep = *sepp) != NULL) { 1070 if (sep->se_checked) { 1071 sepp = &sep->se_next; 1072 continue; 1073 } 1074 *sepp = sep->se_next; 1075 if (sep->se_fd >= 0) 1076 close_sep(sep); 1077 if (isrpcservice(sep)) 1078 unregister_rpc(sep); 1079 if (sep->se_family == AF_LOCAL) 1080 (void)unlink(sep->se_service); 1081 if (debug) 1082 print_service("FREE", sep); 1083 freeconfig(sep); 1084 free(sep); 1085 } 1086 } 1087 1088 static void 1089 retry(void) 1090 { 1091 struct servtab *sep; 1092 1093 timingout = 0; 1094 for (sep = servtab; sep != NULL; sep = sep->se_next) { 1095 if (sep->se_fd == -1 && !ISMUX(sep)) { 1096 switch (sep->se_family) { 1097 case AF_LOCAL: 1098 case AF_INET: 1099 #ifdef INET6 1100 case AF_INET6: 1101 #endif 1102 setup(sep); 1103 if (sep->se_fd >= 0 && isrpcservice(sep)) 1104 register_rpc(sep); 1105 break; 1106 } 1107 } 1108 } 1109 } 1110 1111 static void 1112 goaway(void) 1113 { 1114 struct servtab *sep; 1115 1116 for (sep = servtab; sep != NULL; sep = sep->se_next) { 1117 if (sep->se_fd == -1) 1118 continue; 1119 1120 switch (sep->se_family) { 1121 case AF_LOCAL: 1122 (void)unlink(sep->se_service); 1123 break; 1124 case AF_INET: 1125 #ifdef INET6 1126 case AF_INET6: 1127 #endif 1128 if (sep->se_wait == 1 && isrpcservice(sep)) 1129 unregister_rpc(sep); 1130 break; 1131 } 1132 (void)close(sep->se_fd); 1133 sep->se_fd = -1; 1134 } 1135 exit(0); 1136 } 1137 1138 static void 1139 setup(struct servtab *sep) 1140 { 1141 int on = 1; 1142 #ifdef INET6 1143 int off = 0; 1144 #endif 1145 #ifndef __minix 1146 struct kevent *ev; 1147 #endif /* !__minix */ 1148 1149 if ((sep->se_fd = socket(sep->se_family, sep->se_socktype, 0)) < 0) { 1150 if (debug) 1151 fprintf(stderr, "socket failed on %s/%s: %s\n", 1152 sep->se_service, sep->se_proto, strerror(errno)); 1153 syslog(LOG_ERR, "%s/%s: socket: %m", 1154 sep->se_service, sep->se_proto); 1155 return; 1156 } 1157 /* Set all listening sockets to close-on-exec. */ 1158 if (fcntl(sep->se_fd, F_SETFD, FD_CLOEXEC) < 0) { 1159 syslog(LOG_ERR, "%s/%s: fcntl(F_SETFD, FD_CLOEXEC): %m", 1160 sep->se_service, sep->se_proto); 1161 close(sep->se_fd); 1162 sep->se_fd = -1; 1163 return; 1164 } 1165 1166 #define turnon(fd, opt) \ 1167 setsockopt(fd, SOL_SOCKET, opt, &on, (socklen_t)sizeof(on)) 1168 if (strcmp(sep->se_proto, "tcp") == 0 && (options & SO_DEBUG) && 1169 turnon(sep->se_fd, SO_DEBUG) < 0) 1170 syslog(LOG_ERR, "setsockopt (SO_DEBUG): %m"); 1171 if (turnon(sep->se_fd, SO_REUSEADDR) < 0) 1172 syslog(LOG_ERR, "setsockopt (SO_REUSEADDR): %m"); 1173 #undef turnon 1174 1175 /* Set the socket buffer sizes, if specified. */ 1176 if (sep->se_sndbuf != 0 && setsockopt(sep->se_fd, SOL_SOCKET, 1177 SO_SNDBUF, &sep->se_sndbuf, (socklen_t)sizeof(sep->se_sndbuf)) < 0) 1178 syslog(LOG_ERR, "setsockopt (SO_SNDBUF %d): %m", 1179 sep->se_sndbuf); 1180 if (sep->se_rcvbuf != 0 && setsockopt(sep->se_fd, SOL_SOCKET, 1181 SO_RCVBUF, &sep->se_rcvbuf, (socklen_t)sizeof(sep->se_rcvbuf)) < 0) 1182 syslog(LOG_ERR, "setsockopt (SO_RCVBUF %d): %m", 1183 sep->se_rcvbuf); 1184 #ifdef INET6 1185 if (sep->se_family == AF_INET6) { 1186 int *v; 1187 v = (sep->se_type == FAITH_TYPE) ? &on : &off; 1188 if (setsockopt(sep->se_fd, IPPROTO_IPV6, IPV6_FAITH, 1189 v, (socklen_t)sizeof(*v)) < 0) 1190 syslog(LOG_ERR, "setsockopt (IPV6_FAITH): %m"); 1191 } 1192 #endif 1193 #ifdef IPSEC 1194 if (ipsecsetup(sep->se_family, sep->se_fd, sep->se_policy) < 0 && 1195 sep->se_policy) { 1196 syslog(LOG_ERR, "%s/%s: ipsec setup failed", 1197 sep->se_service, sep->se_proto); 1198 (void)close(sep->se_fd); 1199 sep->se_fd = -1; 1200 return; 1201 } 1202 #endif 1203 1204 if (bind(sep->se_fd, &sep->se_ctrladdr, 1205 (socklen_t)sep->se_ctrladdr_size) < 0) { 1206 if (debug) 1207 fprintf(stderr, "bind failed on %s/%s: %s\n", 1208 sep->se_service, sep->se_proto, strerror(errno)); 1209 syslog(LOG_ERR, "%s/%s: bind: %m", 1210 sep->se_service, sep->se_proto); 1211 (void) close(sep->se_fd); 1212 sep->se_fd = -1; 1213 if (!timingout) { 1214 timingout = 1; 1215 alarm(RETRYTIME); 1216 } 1217 return; 1218 } 1219 if (sep->se_socktype == SOCK_STREAM) 1220 listen(sep->se_fd, 10); 1221 1222 /* Set the accept filter, if specified. To be done after listen.*/ 1223 if (sep->se_accf.af_name[0] != 0 && setsockopt(sep->se_fd, SOL_SOCKET, 1224 SO_ACCEPTFILTER, &sep->se_accf, 1225 (socklen_t)sizeof(sep->se_accf)) < 0) 1226 syslog(LOG_ERR, "setsockopt(SO_ACCEPTFILTER %s): %m", 1227 sep->se_accf.af_name); 1228 1229 #ifndef __minix 1230 ev = allocchange(); 1231 EV_SET(ev, sep->se_fd, EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, 1232 (intptr_t)sep); 1233 #endif /* !__minix */ 1234 if (sep->se_fd > maxsock) { 1235 maxsock = sep->se_fd; 1236 if (maxsock > (int)(rlim_ofile_cur - FD_MARGIN)) 1237 bump_nofile(); 1238 } 1239 if (debug) 1240 fprintf(stderr, "registered %s on %d\n", 1241 sep->se_server, sep->se_fd); 1242 } 1243 1244 /* 1245 * Finish with a service and its socket. 1246 */ 1247 static void 1248 close_sep(struct servtab *sep) 1249 { 1250 if (sep->se_fd >= 0) { 1251 (void) close(sep->se_fd); 1252 sep->se_fd = -1; 1253 } 1254 sep->se_count = 0; 1255 } 1256 1257 static void 1258 register_rpc(struct servtab *sep) 1259 { 1260 #ifdef RPC 1261 struct netbuf nbuf; 1262 struct sockaddr_storage ss; 1263 struct netconfig *nconf; 1264 socklen_t socklen; 1265 int n; 1266 1267 if ((nconf = getnetconfigent(sep->se_proto+4)) == NULL) { 1268 syslog(LOG_ERR, "%s: getnetconfigent failed", 1269 sep->se_proto); 1270 return; 1271 } 1272 socklen = sizeof ss; 1273 if (getsockname(sep->se_fd, (struct sockaddr *)(void *)&ss, &socklen) < 0) { 1274 syslog(LOG_ERR, "%s/%s: getsockname: %m", 1275 sep->se_service, sep->se_proto); 1276 return; 1277 } 1278 1279 nbuf.buf = &ss; 1280 nbuf.len = ss.ss_len; 1281 nbuf.maxlen = sizeof (struct sockaddr_storage); 1282 for (n = sep->se_rpcversl; n <= sep->se_rpcversh; n++) { 1283 if (debug) 1284 fprintf(stderr, "rpcb_set: %u %d %s %s\n", 1285 sep->se_rpcprog, n, nconf->nc_netid, 1286 taddr2uaddr(nconf, &nbuf)); 1287 (void)rpcb_unset((unsigned int)sep->se_rpcprog, (unsigned int)n, nconf); 1288 if (!rpcb_set((unsigned int)sep->se_rpcprog, (unsigned int)n, nconf, &nbuf)) 1289 syslog(LOG_ERR, "rpcb_set: %u %d %s %s%s", 1290 sep->se_rpcprog, n, nconf->nc_netid, 1291 taddr2uaddr(nconf, &nbuf), clnt_spcreateerror("")); 1292 } 1293 #endif /* RPC */ 1294 } 1295 1296 static void 1297 unregister_rpc(struct servtab *sep) 1298 { 1299 #ifdef RPC 1300 int n; 1301 struct netconfig *nconf; 1302 1303 if ((nconf = getnetconfigent(sep->se_proto+4)) == NULL) { 1304 syslog(LOG_ERR, "%s: getnetconfigent failed", 1305 sep->se_proto); 1306 return; 1307 } 1308 1309 for (n = sep->se_rpcversl; n <= sep->se_rpcversh; n++) { 1310 if (debug) 1311 fprintf(stderr, "rpcb_unset(%u, %d, %s)\n", 1312 sep->se_rpcprog, n, nconf->nc_netid); 1313 if (!rpcb_unset((unsigned int)sep->se_rpcprog, (unsigned int)n, nconf)) 1314 syslog(LOG_ERR, "rpcb_unset(%u, %d, %s) failed\n", 1315 sep->se_rpcprog, n, nconf->nc_netid); 1316 } 1317 #endif /* RPC */ 1318 } 1319 1320 1321 static struct servtab * 1322 enter(struct servtab *cp) 1323 { 1324 struct servtab *sep; 1325 1326 sep = malloc(sizeof (*sep)); 1327 if (sep == NULL) { 1328 syslog(LOG_ERR, "Out of memory."); 1329 exit(1); 1330 } 1331 *sep = *cp; 1332 sep->se_fd = -1; 1333 sep->se_rpcprog = -1; 1334 sep->se_next = servtab; 1335 servtab = sep; 1336 return (sep); 1337 } 1338 1339 FILE *fconfig = NULL; 1340 struct servtab serv; 1341 char line[LINE_MAX]; 1342 char *defhost; 1343 #ifdef IPSEC 1344 static char *policy = NULL; 1345 #endif 1346 1347 static int 1348 setconfig(void) 1349 { 1350 if (defhost) 1351 free(defhost); 1352 defhost = newstr("*"); 1353 #ifdef IPSEC 1354 if (policy) 1355 free(policy); 1356 policy = NULL; 1357 #endif 1358 if (fconfig != NULL) { 1359 fseek(fconfig, 0L, SEEK_SET); 1360 return (1); 1361 } 1362 fconfig = fopen(CONFIG, "r"); 1363 return (fconfig != NULL); 1364 } 1365 1366 static void 1367 endconfig(void) 1368 { 1369 if (fconfig != NULL) { 1370 (void) fclose(fconfig); 1371 fconfig = NULL; 1372 } 1373 if (defhost != NULL) { 1374 free(defhost); 1375 defhost = NULL; 1376 } 1377 } 1378 1379 static struct servtab * 1380 getconfigent(void) 1381 { 1382 struct servtab *sep = &serv; 1383 int argc, val; 1384 char *cp, *cp0, *arg, *buf0, *buf1, *sz0, *sz1; 1385 static char TCPMUX_TOKEN[] = "tcpmux/"; 1386 #define MUX_LEN (sizeof(TCPMUX_TOKEN)-1) 1387 char *hostdelim; 1388 1389 more: 1390 while ((cp = nextline(fconfig)) != NULL) { 1391 #ifdef IPSEC 1392 /* lines starting with #@ is not a comment, but the policy */ 1393 if (cp[0] == '#' && cp[1] == '@') { 1394 char *p; 1395 for (p = cp + 2; p && *p && isspace((unsigned char)*p); p++) 1396 ; 1397 if (*p == '\0') { 1398 if (policy) 1399 free(policy); 1400 policy = NULL; 1401 } else { 1402 if (ipsecsetup_test(p) < 0) { 1403 syslog(LOG_ERR, 1404 "%s: invalid ipsec policy \"%s\"", 1405 CONFIG, p); 1406 exit(1); 1407 } else { 1408 if (policy) 1409 free(policy); 1410 policy = newstr(p); 1411 } 1412 } 1413 } 1414 #endif 1415 if (*cp == '#' || *cp == '\0') 1416 continue; 1417 break; 1418 } 1419 if (cp == NULL) 1420 return (NULL); 1421 /* 1422 * clear the static buffer, since some fields (se_ctrladdr, 1423 * for example) don't get initialized here. 1424 */ 1425 memset(sep, 0, sizeof *sep); 1426 arg = skip(&cp); 1427 if (cp == NULL) { 1428 /* got an empty line containing just blanks/tabs. */ 1429 goto more; 1430 } 1431 /* Check for a host name. */ 1432 hostdelim = strrchr(arg, ':'); 1433 if (hostdelim) { 1434 *hostdelim = '\0'; 1435 if (arg[0] == '[' && hostdelim > arg && hostdelim[-1] == ']') { 1436 hostdelim[-1] = '\0'; 1437 sep->se_hostaddr = newstr(arg + 1); 1438 } else 1439 sep->se_hostaddr = newstr(arg); 1440 arg = hostdelim + 1; 1441 /* 1442 * If the line is of the form `host:', then just change the 1443 * default host for the following lines. 1444 */ 1445 if (*arg == '\0') { 1446 arg = skip(&cp); 1447 if (cp == NULL) { 1448 free(defhost); 1449 defhost = sep->se_hostaddr; 1450 goto more; 1451 } 1452 } 1453 } else 1454 sep->se_hostaddr = newstr(defhost); 1455 if (strncmp(arg, TCPMUX_TOKEN, MUX_LEN) == 0) { 1456 char *c = arg + MUX_LEN; 1457 if (*c == '+') { 1458 sep->se_type = MUXPLUS_TYPE; 1459 c++; 1460 } else 1461 sep->se_type = MUX_TYPE; 1462 sep->se_service = newstr(c); 1463 } else { 1464 sep->se_service = newstr(arg); 1465 sep->se_type = NORM_TYPE; 1466 } 1467 1468 arg = sskip(&cp); 1469 if (strncmp(arg, "stream", sizeof("stream") - 1) == 0) { 1470 char *accf, *accf_arg; 1471 1472 sep->se_socktype = SOCK_STREAM; 1473 1474 /* one and only one accept filter */ 1475 accf = strchr(arg, ':'); 1476 if (accf) { 1477 if (accf != strrchr(arg, ':') ||/* more than one */ 1478 *(accf + 1) == '\0') { /* nothing beyond */ 1479 sep->se_socktype = -1; 1480 } else { 1481 accf++; /* skip delimiter */ 1482 strlcpy(sep->se_accf.af_name, accf, 1483 sizeof(sep->se_accf.af_name)); 1484 accf_arg = strchr(accf, ','); 1485 if (accf_arg) { /* zero or one arg, no more */ 1486 if (strrchr(accf, ',') != accf_arg) { 1487 sep->se_socktype = -1; 1488 } else { 1489 accf_arg++; 1490 strlcpy(sep->se_accf.af_arg, 1491 accf_arg, 1492 sizeof(sep->se_accf.af_arg)); 1493 } 1494 } 1495 } 1496 } 1497 } 1498 1499 else if (strcmp(arg, "dgram") == 0) 1500 sep->se_socktype = SOCK_DGRAM; 1501 else if (strcmp(arg, "rdm") == 0) 1502 sep->se_socktype = SOCK_RDM; 1503 else if (strcmp(arg, "seqpacket") == 0) 1504 sep->se_socktype = SOCK_SEQPACKET; 1505 else if (strcmp(arg, "raw") == 0) 1506 sep->se_socktype = SOCK_RAW; 1507 else 1508 sep->se_socktype = -1; 1509 1510 arg = sskip(&cp); 1511 if (sep->se_type == NORM_TYPE && 1512 strncmp(arg, "faith/", strlen("faith/")) == 0) { 1513 arg += strlen("faith/"); 1514 sep->se_type = FAITH_TYPE; 1515 } 1516 sep->se_proto = newstr(arg); 1517 1518 #define MALFORMED(arg) \ 1519 do { \ 1520 syslog(LOG_ERR, "%s: malformed buffer size option `%s'", \ 1521 sep->se_service, (arg)); \ 1522 goto more; \ 1523 /*NOTREACHED*/ \ 1524 } while (/*CONSTCOND*/0) 1525 1526 #define GETVAL(arg) \ 1527 do { \ 1528 if (!isdigit((unsigned char)*(arg))) \ 1529 MALFORMED(arg); \ 1530 val = (int)strtol((arg), &cp0, 10); \ 1531 if (cp0 != NULL) { \ 1532 if (cp0[1] != '\0') \ 1533 MALFORMED((arg)); \ 1534 if (cp0[0] == 'k') \ 1535 val *= 1024; \ 1536 if (cp0[0] == 'm') \ 1537 val *= 1024 * 1024; \ 1538 } \ 1539 if (val < 1) { \ 1540 syslog(LOG_ERR, "%s: invalid buffer size `%s'", \ 1541 sep->se_service, (arg)); \ 1542 goto more; \ 1543 } \ 1544 /*NOTREACHED*/ \ 1545 } while (/*CONSTCOND*/0) 1546 1547 #define ASSIGN(arg) \ 1548 do { \ 1549 if (strcmp((arg), "sndbuf") == 0) \ 1550 sep->se_sndbuf = val; \ 1551 else if (strcmp((arg), "rcvbuf") == 0) \ 1552 sep->se_rcvbuf = val; \ 1553 else \ 1554 MALFORMED((arg)); \ 1555 } while (/*CONSTCOND*/0) 1556 1557 /* 1558 * Extract the send and receive buffer sizes before parsing 1559 * the protocol. 1560 */ 1561 sep->se_sndbuf = sep->se_rcvbuf = 0; 1562 buf0 = buf1 = sz0 = sz1 = NULL; 1563 if ((buf0 = strchr(sep->se_proto, ',')) != NULL) { 1564 /* Not meaningful for Tcpmux services. */ 1565 if (ISMUX(sep)) { 1566 syslog(LOG_ERR, "%s: can't specify buffer sizes for " 1567 "tcpmux services", sep->se_service); 1568 goto more; 1569 } 1570 1571 /* Skip the , */ 1572 *buf0++ = '\0'; 1573 1574 /* Check to see if another socket buffer size was specified. */ 1575 if ((buf1 = strchr(buf0, ',')) != NULL) { 1576 /* Skip the , */ 1577 *buf1++ = '\0'; 1578 1579 /* Make sure a 3rd one wasn't specified. */ 1580 if (strchr(buf1, ',') != NULL) { 1581 syslog(LOG_ERR, "%s: too many buffer sizes", 1582 sep->se_service); 1583 goto more; 1584 } 1585 1586 /* Locate the size. */ 1587 if ((sz1 = strchr(buf1, '=')) == NULL) 1588 MALFORMED(buf1); 1589 1590 /* Skip the = */ 1591 *sz1++ = '\0'; 1592 } 1593 1594 /* Locate the size. */ 1595 if ((sz0 = strchr(buf0, '=')) == NULL) 1596 MALFORMED(buf0); 1597 1598 /* Skip the = */ 1599 *sz0++ = '\0'; 1600 1601 GETVAL(sz0); 1602 ASSIGN(buf0); 1603 1604 if (buf1 != NULL) { 1605 GETVAL(sz1); 1606 ASSIGN(buf1); 1607 } 1608 } 1609 1610 #undef ASSIGN 1611 #undef GETVAL 1612 #undef MALFORMED 1613 1614 if (strcmp(sep->se_proto, "unix") == 0) { 1615 sep->se_family = AF_LOCAL; 1616 } else { 1617 val = (int)strlen(sep->se_proto); 1618 if (!val) { 1619 syslog(LOG_ERR, "%s: invalid protocol specified", 1620 sep->se_service); 1621 goto more; 1622 } 1623 val = sep->se_proto[val - 1]; 1624 switch (val) { 1625 case '4': /*tcp4 or udp4*/ 1626 sep->se_family = AF_INET; 1627 break; 1628 #ifdef INET6 1629 case '6': /*tcp6 or udp6*/ 1630 sep->se_family = AF_INET6; 1631 break; 1632 #endif 1633 default: 1634 sep->se_family = AF_INET; /*will become AF_INET6*/ 1635 break; 1636 } 1637 if (strncmp(sep->se_proto, "rpc/", 4) == 0) { 1638 #ifdef RPC 1639 char *cp1, *ccp; 1640 cp1 = strchr(sep->se_service, '/'); 1641 if (cp1 == 0) { 1642 syslog(LOG_ERR, "%s: no rpc version", 1643 sep->se_service); 1644 goto more; 1645 } 1646 *cp1++ = '\0'; 1647 sep->se_rpcversl = sep->se_rpcversh = 1648 (int)strtol(cp1, &ccp, 0); 1649 if (ccp == cp1) { 1650 badafterall: 1651 syslog(LOG_ERR, "%s/%s: bad rpc version", 1652 sep->se_service, cp1); 1653 goto more; 1654 } 1655 if (*ccp == '-') { 1656 cp1 = ccp + 1; 1657 sep->se_rpcversh = (int)strtol(cp1, &ccp, 0); 1658 if (ccp == cp1) 1659 goto badafterall; 1660 } 1661 #else 1662 syslog(LOG_ERR, "%s: rpc services not suported", 1663 sep->se_service); 1664 goto more; 1665 #endif /* RPC */ 1666 } 1667 } 1668 arg = sskip(&cp); 1669 { 1670 char *cp1; 1671 if ((cp1 = strchr(arg, ':')) == NULL) 1672 cp1 = strchr(arg, '.'); 1673 if (cp1 != NULL) { 1674 *cp1++ = '\0'; 1675 sep->se_max = atoi(cp1); 1676 } else 1677 sep->se_max = TOOMANY; 1678 } 1679 sep->se_wait = strcmp(arg, "wait") == 0; 1680 if (ISMUX(sep)) { 1681 /* 1682 * Silently enforce "nowait" for TCPMUX services since 1683 * they don't have an assigned port to listen on. 1684 */ 1685 sep->se_wait = 0; 1686 1687 if (strncmp(sep->se_proto, "tcp", 3)) { 1688 syslog(LOG_ERR, 1689 "%s: bad protocol for tcpmux service %s", 1690 CONFIG, sep->se_service); 1691 goto more; 1692 } 1693 if (sep->se_socktype != SOCK_STREAM) { 1694 syslog(LOG_ERR, 1695 "%s: bad socket type for tcpmux service %s", 1696 CONFIG, sep->se_service); 1697 goto more; 1698 } 1699 } 1700 sep->se_user = newstr(sskip(&cp)); 1701 if ((sep->se_group = strchr(sep->se_user, ':')) != NULL) 1702 *sep->se_group++ = '\0'; 1703 else if ((sep->se_group = strchr(sep->se_user, '.')) != NULL) 1704 *sep->se_group++ = '\0'; 1705 1706 sep->se_server = newstr(sskip(&cp)); 1707 if (strcmp(sep->se_server, "internal") == 0) { 1708 struct biltin *bi; 1709 1710 for (bi = biltins; bi->bi_service; bi++) 1711 if (bi->bi_socktype == sep->se_socktype && 1712 strcmp(bi->bi_service, sep->se_service) == 0) 1713 break; 1714 if (bi->bi_service == 0) { 1715 syslog(LOG_ERR, "internal service %s unknown", 1716 sep->se_service); 1717 goto more; 1718 } 1719 sep->se_bi = bi; 1720 sep->se_wait = bi->bi_wait; 1721 } else 1722 sep->se_bi = NULL; 1723 argc = 0; 1724 for (arg = skip(&cp); cp; arg = skip(&cp)) { 1725 if (argc < MAXARGV) 1726 sep->se_argv[argc++] = newstr(arg); 1727 } 1728 while (argc <= MAXARGV) 1729 sep->se_argv[argc++] = NULL; 1730 #ifdef IPSEC 1731 sep->se_policy = policy ? newstr(policy) : NULL; 1732 #endif 1733 return (sep); 1734 } 1735 1736 static void 1737 freeconfig(struct servtab *cp) 1738 { 1739 int i; 1740 1741 if (cp->se_hostaddr) 1742 free(cp->se_hostaddr); 1743 if (cp->se_service) 1744 free(cp->se_service); 1745 if (cp->se_proto) 1746 free(cp->se_proto); 1747 if (cp->se_user) 1748 free(cp->se_user); 1749 /* Note: se_group is part of the newstr'ed se_user */ 1750 if (cp->se_server) 1751 free(cp->se_server); 1752 for (i = 0; i < MAXARGV; i++) 1753 if (cp->se_argv[i]) 1754 free(cp->se_argv[i]); 1755 #ifdef IPSEC 1756 if (cp->se_policy) 1757 free(cp->se_policy); 1758 #endif 1759 } 1760 1761 1762 /* 1763 * Safe skip - if skip returns null, log a syntax error in the 1764 * configuration file and exit. 1765 */ 1766 static char * 1767 sskip(char **cpp) 1768 { 1769 char *cp; 1770 1771 cp = skip(cpp); 1772 if (cp == NULL) { 1773 syslog(LOG_ERR, "%s: syntax error", CONFIG); 1774 exit(1); 1775 } 1776 return (cp); 1777 } 1778 1779 static char * 1780 skip(char **cpp) 1781 { 1782 char *cp = *cpp; 1783 char *start; 1784 char quote; 1785 1786 if (*cpp == NULL) 1787 return (NULL); 1788 1789 again: 1790 while (*cp == ' ' || *cp == '\t') 1791 cp++; 1792 if (*cp == '\0') { 1793 int c; 1794 1795 c = getc(fconfig); 1796 (void) ungetc(c, fconfig); 1797 if (c == ' ' || c == '\t') 1798 if ((cp = nextline(fconfig)) != NULL) 1799 goto again; 1800 *cpp = NULL; 1801 return (NULL); 1802 } 1803 start = cp; 1804 quote = '\0'; 1805 while (*cp && (quote || (*cp != ' ' && *cp != '\t'))) { 1806 if (*cp == '\'' || *cp == '"') { 1807 if (quote && *cp != quote) 1808 cp++; 1809 else { 1810 if (quote) 1811 quote = '\0'; 1812 else 1813 quote = *cp; 1814 memmove(cp, cp+1, strlen(cp)); 1815 } 1816 } else 1817 cp++; 1818 } 1819 if (*cp != '\0') 1820 *cp++ = '\0'; 1821 *cpp = cp; 1822 return (start); 1823 } 1824 1825 static char * 1826 nextline(FILE *fd) 1827 { 1828 char *cp; 1829 1830 if (fgets(line, (int)sizeof(line), fd) == NULL) 1831 return (NULL); 1832 cp = strchr(line, '\n'); 1833 if (cp) 1834 *cp = '\0'; 1835 return (line); 1836 } 1837 1838 static char * 1839 newstr(const char *cp) 1840 { 1841 char *dp; 1842 if ((dp = strdup((cp != NULL) ? cp : "")) != NULL) 1843 return (dp); 1844 syslog(LOG_ERR, "strdup: %m"); 1845 exit(1); 1846 /*NOTREACHED*/ 1847 } 1848 1849 static void 1850 inetd_setproctitle(char *a, int s) 1851 { 1852 socklen_t size; 1853 struct sockaddr_storage ss; 1854 char hbuf[NI_MAXHOST]; 1855 const char *hp; 1856 struct sockaddr *sa; 1857 1858 size = sizeof(ss); 1859 sa = (struct sockaddr *)(void *)&ss; 1860 if (getpeername(s, sa, &size) == 0) { 1861 if (getnameinfo(sa, size, hbuf, (socklen_t)sizeof(hbuf), NULL, 1862 0, niflags) != 0) 1863 hp = "?"; 1864 else 1865 hp = hbuf; 1866 setproctitle("-%s [%s]", a, hp); 1867 } else 1868 setproctitle("-%s", a); 1869 } 1870 1871 static void 1872 bump_nofile(void) 1873 { 1874 #define FD_CHUNK 32 1875 struct rlimit rl; 1876 1877 if (getrlimit(RLIMIT_NOFILE, &rl) < 0) { 1878 syslog(LOG_ERR, "getrlimit: %m"); 1879 return; 1880 } 1881 rl.rlim_cur = MIN(rl.rlim_max, rl.rlim_cur + FD_CHUNK); 1882 if (rl.rlim_cur <= rlim_ofile_cur) { 1883 syslog(LOG_ERR, 1884 "bump_nofile: cannot extend file limit, max = %d", 1885 (int)rl.rlim_cur); 1886 return; 1887 } 1888 1889 if (setrlimit(RLIMIT_NOFILE, &rl) < 0) { 1890 syslog(LOG_ERR, "setrlimit: %m"); 1891 return; 1892 } 1893 1894 rlim_ofile_cur = rl.rlim_cur; 1895 return; 1896 } 1897 1898 /* 1899 * Internet services provided internally by inetd: 1900 */ 1901 #define BUFSIZE 4096 1902 1903 /* ARGSUSED */ 1904 static void 1905 echo_stream(int s, struct servtab *sep) /* Echo service -- echo data back */ 1906 { 1907 char buffer[BUFSIZE]; 1908 ssize_t i; 1909 1910 inetd_setproctitle(sep->se_service, s); 1911 while ((i = read(s, buffer, sizeof(buffer))) > 0 && 1912 write(s, buffer, (size_t)i) > 0) 1913 ; 1914 } 1915 1916 /* ARGSUSED */ 1917 static void 1918 echo_dg(int s, struct servtab *sep) /* Echo service -- echo data back */ 1919 { 1920 char buffer[BUFSIZE]; 1921 ssize_t i; 1922 socklen_t size; 1923 struct sockaddr_storage ss; 1924 struct sockaddr *sa; 1925 1926 sa = (struct sockaddr *)(void *)&ss; 1927 size = sizeof(ss); 1928 if ((i = recvfrom(s, buffer, sizeof(buffer), 0, sa, &size)) < 0) 1929 return; 1930 if (port_good_dg(sa)) 1931 (void) sendto(s, buffer, (size_t)i, 0, sa, size); 1932 } 1933 1934 /* ARGSUSED */ 1935 static void 1936 discard_stream(int s, struct servtab *sep) /* Discard service -- ignore data */ 1937 { 1938 char buffer[BUFSIZE]; 1939 1940 inetd_setproctitle(sep->se_service, s); 1941 while ((errno = 0, read(s, buffer, sizeof(buffer)) > 0) || 1942 errno == EINTR) 1943 ; 1944 } 1945 1946 /* ARGSUSED */ 1947 static void 1948 discard_dg(int s, struct servtab *sep) /* Discard service -- ignore data */ 1949 1950 { 1951 char buffer[BUFSIZE]; 1952 1953 (void) read(s, buffer, sizeof(buffer)); 1954 } 1955 1956 #define LINESIZ 72 1957 char ring[128]; 1958 char *endring; 1959 1960 static void 1961 initring(void) 1962 { 1963 int i; 1964 1965 endring = ring; 1966 1967 for (i = 0; i <= 128; ++i) 1968 if (isprint(i)) 1969 *endring++ = i; 1970 } 1971 1972 /* ARGSUSED */ 1973 static void 1974 chargen_stream(int s,struct servtab *sep) /* Character generator */ 1975 { 1976 size_t len; 1977 char *rs, text[LINESIZ+2]; 1978 1979 inetd_setproctitle(sep->se_service, s); 1980 1981 if (!endring) { 1982 initring(); 1983 rs = ring; 1984 } 1985 1986 text[LINESIZ] = '\r'; 1987 text[LINESIZ + 1] = '\n'; 1988 for (rs = ring;;) { 1989 if ((len = endring - rs) >= LINESIZ) 1990 memmove(text, rs, LINESIZ); 1991 else { 1992 memmove(text, rs, len); 1993 memmove(text + len, ring, LINESIZ - len); 1994 } 1995 if (++rs == endring) 1996 rs = ring; 1997 if (write(s, text, sizeof(text)) != sizeof(text)) 1998 break; 1999 } 2000 } 2001 2002 /* ARGSUSED */ 2003 static void 2004 chargen_dg(int s, struct servtab *sep) /* Character generator */ 2005 { 2006 struct sockaddr_storage ss; 2007 struct sockaddr *sa; 2008 static char *rs; 2009 size_t len; 2010 socklen_t size; 2011 char text[LINESIZ+2]; 2012 2013 if (endring == 0) { 2014 initring(); 2015 rs = ring; 2016 } 2017 2018 sa = (struct sockaddr *)(void *)&ss; 2019 size = sizeof(ss); 2020 if (recvfrom(s, text, sizeof(text), 0, sa, &size) < 0) 2021 return; 2022 2023 if (!port_good_dg(sa)) 2024 return; 2025 2026 if ((len = endring - rs) >= LINESIZ) 2027 memmove(text, rs, LINESIZ); 2028 else { 2029 memmove(text, rs, len); 2030 memmove(text + len, ring, LINESIZ - len); 2031 } 2032 if (++rs == endring) 2033 rs = ring; 2034 text[LINESIZ] = '\r'; 2035 text[LINESIZ + 1] = '\n'; 2036 (void) sendto(s, text, sizeof(text), 0, sa, size); 2037 } 2038 2039 /* 2040 * Return a machine readable date and time, in the form of the 2041 * number of seconds since midnight, Jan 1, 1900. Since gettimeofday 2042 * returns the number of seconds since midnight, Jan 1, 1970, 2043 * we must add 2208988800 seconds to this figure to make up for 2044 * some seventy years Bell Labs was asleep. 2045 */ 2046 2047 static uint32_t 2048 machtime(void) 2049 { 2050 struct timeval tv; 2051 2052 if (gettimeofday(&tv, NULL) < 0) { 2053 if (debug) 2054 fprintf(stderr, "Unable to get time of day\n"); 2055 return (0); 2056 } 2057 #define OFFSET ((uint32_t)25567 * 24*60*60) 2058 return (htonl((uint32_t)(tv.tv_sec + OFFSET))); 2059 #undef OFFSET 2060 } 2061 2062 /* ARGSUSED */ 2063 static void 2064 machtime_stream(int s, struct servtab *sep) 2065 { 2066 uint32_t result; 2067 2068 result = machtime(); 2069 (void) write(s, &result, sizeof(result)); 2070 } 2071 2072 /* ARGSUSED */ 2073 void 2074 machtime_dg(int s, struct servtab *sep) 2075 { 2076 uint32_t result; 2077 struct sockaddr_storage ss; 2078 struct sockaddr *sa; 2079 socklen_t size; 2080 2081 sa = (struct sockaddr *)(void *)&ss; 2082 size = sizeof(ss); 2083 if (recvfrom(s, &result, sizeof(result), 0, sa, &size) < 0) 2084 return; 2085 if (!port_good_dg(sa)) 2086 return; 2087 result = machtime(); 2088 (void)sendto(s, &result, sizeof(result), 0, sa, size); 2089 } 2090 2091 /* ARGSUSED */ 2092 static void 2093 daytime_stream(int s,struct servtab *sep) 2094 /* Return human-readable time of day */ 2095 { 2096 char buffer[256]; 2097 time_t clk; 2098 int len; 2099 2100 clk = time((time_t *) 0); 2101 2102 len = snprintf(buffer, sizeof buffer, "%.24s\r\n", ctime(&clk)); 2103 (void) write(s, buffer, len); 2104 } 2105 2106 /* ARGSUSED */ 2107 void 2108 daytime_dg(int s, struct servtab *sep) 2109 /* Return human-readable time of day */ 2110 { 2111 char buffer[256]; 2112 time_t clk; 2113 struct sockaddr_storage ss; 2114 struct sockaddr *sa; 2115 socklen_t size; 2116 int len; 2117 2118 clk = time((time_t *) 0); 2119 2120 sa = (struct sockaddr *)(void *)&ss; 2121 size = sizeof(ss); 2122 if (recvfrom(s, buffer, sizeof(buffer), 0, sa, &size) < 0) 2123 return; 2124 if (!port_good_dg(sa)) 2125 return; 2126 len = snprintf(buffer, sizeof buffer, "%.24s\r\n", ctime(&clk)); 2127 (void) sendto(s, buffer, len, 0, sa, size); 2128 } 2129 2130 /* 2131 * print_service: 2132 * Dump relevant information to stderr 2133 */ 2134 static void 2135 print_service(const char *action, struct servtab *sep) 2136 { 2137 2138 if (isrpcservice(sep)) 2139 fprintf(stderr, 2140 "%s: %s rpcprog=%d, rpcvers = %d/%d, proto=%s, wait.max=%d.%d, user:group=%s:%s builtin=%lx server=%s" 2141 #ifdef IPSEC 2142 " policy=\"%s\"" 2143 #endif 2144 "\n", 2145 action, sep->se_service, 2146 sep->se_rpcprog, sep->se_rpcversh, sep->se_rpcversl, sep->se_proto, 2147 sep->se_wait, sep->se_max, sep->se_user, sep->se_group, 2148 (long)sep->se_bi, sep->se_server 2149 #ifdef IPSEC 2150 , (sep->se_policy ? sep->se_policy : "") 2151 #endif 2152 ); 2153 else 2154 fprintf(stderr, 2155 "%s: %s proto=%s%s, wait.max=%d.%d, user:group=%s:%s builtin=%lx server=%s" 2156 #ifdef IPSEC 2157 " policy=%s" 2158 #endif 2159 "\n", 2160 action, sep->se_service, 2161 sep->se_type == FAITH_TYPE ? "faith/" : "", 2162 sep->se_proto, 2163 sep->se_wait, sep->se_max, sep->se_user, sep->se_group, 2164 (long)sep->se_bi, sep->se_server 2165 #ifdef IPSEC 2166 , (sep->se_policy ? sep->se_policy : "") 2167 #endif 2168 ); 2169 } 2170 2171 static void 2172 usage(void) 2173 { 2174 #ifdef LIBWRAP 2175 (void)fprintf(stderr, "usage: %s [-dl] [conf]\n", getprogname()); 2176 #else 2177 (void)fprintf(stderr, "usage: %s [-d] [conf]\n", getprogname()); 2178 #endif 2179 exit(1); 2180 } 2181 2182 2183 /* 2184 * Based on TCPMUX.C by Mark K. Lottor November 1988 2185 * sri-nic::ps:<mkl>tcpmux.c 2186 */ 2187 2188 static int /* # of characters upto \r,\n or \0 */ 2189 get_line(int fd, char *buf, int len) 2190 { 2191 int count = 0; 2192 ssize_t n; 2193 2194 do { 2195 n = read(fd, buf, len-count); 2196 if (n == 0) 2197 return (count); 2198 if (n < 0) 2199 return (-1); 2200 while (--n >= 0) { 2201 if (*buf == '\r' || *buf == '\n' || *buf == '\0') 2202 return (count); 2203 count++; 2204 buf++; 2205 } 2206 } while (count < len); 2207 return (count); 2208 } 2209 2210 #define MAX_SERV_LEN (256+2) /* 2 bytes for \r\n */ 2211 2212 #define strwrite(fd, buf) (void) write(fd, buf, sizeof(buf)-1) 2213 2214 static void 2215 tcpmux(int ctrl, struct servtab *sep) 2216 { 2217 char service[MAX_SERV_LEN+1]; 2218 int len; 2219 2220 /* Get requested service name */ 2221 if ((len = get_line(ctrl, service, MAX_SERV_LEN)) < 0) { 2222 strwrite(ctrl, "-Error reading service name\r\n"); 2223 goto reject; 2224 } 2225 service[len] = '\0'; 2226 2227 if (debug) 2228 fprintf(stderr, "tcpmux: someone wants %s\n", service); 2229 2230 /* 2231 * Help is a required command, and lists available services, 2232 * one per line. 2233 */ 2234 if (!strcasecmp(service, "help")) { 2235 strwrite(ctrl, "+Available services:\r\n"); 2236 strwrite(ctrl, "help\r\n"); 2237 for (sep = servtab; sep != NULL; sep = sep->se_next) { 2238 if (!ISMUX(sep)) 2239 continue; 2240 (void)write(ctrl, sep->se_service, 2241 strlen(sep->se_service)); 2242 strwrite(ctrl, "\r\n"); 2243 } 2244 goto reject; 2245 } 2246 2247 /* Try matching a service in inetd.conf with the request */ 2248 for (sep = servtab; sep != NULL; sep = sep->se_next) { 2249 if (!ISMUX(sep)) 2250 continue; 2251 if (!strcasecmp(service, sep->se_service)) { 2252 if (ISMUXPLUS(sep)) 2253 strwrite(ctrl, "+Go\r\n"); 2254 run_service(ctrl, sep, 1 /* forked */); 2255 return; 2256 } 2257 } 2258 strwrite(ctrl, "-Service not available\r\n"); 2259 reject: 2260 _exit(1); 2261 } 2262 2263 /* 2264 * check if the address/port where send data to is one of the obvious ports 2265 * that are used for denial of service attacks like two echo ports 2266 * just echoing data between them 2267 */ 2268 static int 2269 port_good_dg(struct sockaddr *sa) 2270 { 2271 struct in_addr in; 2272 struct sockaddr_in *sin; 2273 #ifdef INET6 2274 struct in6_addr *in6; 2275 struct sockaddr_in6 *sin6; 2276 #endif 2277 u_int16_t port; 2278 int i; 2279 char hbuf[NI_MAXHOST]; 2280 2281 switch (sa->sa_family) { 2282 case AF_INET: 2283 sin = (struct sockaddr_in *)(void *)sa; 2284 in.s_addr = ntohl(sin->sin_addr.s_addr); 2285 port = ntohs(sin->sin_port); 2286 #ifdef INET6 2287 v4chk: 2288 #endif 2289 if (IN_MULTICAST(in.s_addr)) 2290 goto bad; 2291 switch ((in.s_addr & 0xff000000) >> 24) { 2292 case 0: case 127: case 255: 2293 goto bad; 2294 } 2295 if (dg_broadcast(&in)) 2296 goto bad; 2297 break; 2298 #ifdef INET6 2299 case AF_INET6: 2300 sin6 = (struct sockaddr_in6 *)(void *)sa; 2301 in6 = &sin6->sin6_addr; 2302 port = ntohs(sin6->sin6_port); 2303 if (IN6_IS_ADDR_MULTICAST(in6) || IN6_IS_ADDR_UNSPECIFIED(in6)) 2304 goto bad; 2305 if (IN6_IS_ADDR_V4MAPPED(in6) || IN6_IS_ADDR_V4COMPAT(in6)) { 2306 memcpy(&in, &in6->s6_addr[12], sizeof(in)); 2307 in.s_addr = ntohl(in.s_addr); 2308 goto v4chk; 2309 } 2310 break; 2311 #endif 2312 default: 2313 /* XXX unsupported af, is it safe to assume it to be safe? */ 2314 return (1); 2315 } 2316 2317 for (i = 0; bad_ports[i] != 0; i++) { 2318 if (port == bad_ports[i]) 2319 goto bad; 2320 } 2321 2322 return (1); 2323 2324 bad: 2325 if (getnameinfo(sa, sa->sa_len, hbuf, (socklen_t)sizeof(hbuf), NULL, 0, 2326 niflags) != 0) 2327 strlcpy(hbuf, "?", sizeof(hbuf)); 2328 syslog(LOG_WARNING,"Possible DoS attack from %s, Port %d", 2329 hbuf, port); 2330 return (0); 2331 } 2332 2333 /* XXX need optimization */ 2334 static int 2335 dg_broadcast(struct in_addr *in) 2336 { 2337 struct ifaddrs *ifa, *ifap; 2338 struct sockaddr_in *sin; 2339 2340 if (getifaddrs(&ifap) < 0) 2341 return (0); 2342 for (ifa = ifap; ifa; ifa = ifa->ifa_next) { 2343 if (ifa->ifa_addr->sa_family != AF_INET || 2344 (ifa->ifa_flags & IFF_BROADCAST) == 0) 2345 continue; 2346 sin = (struct sockaddr_in *)(void *)ifa->ifa_broadaddr; 2347 if (sin->sin_addr.s_addr == in->s_addr) { 2348 freeifaddrs(ifap); 2349 return (1); 2350 } 2351 } 2352 freeifaddrs(ifap); 2353 return (0); 2354 } 2355 2356 #ifndef __minix 2357 static int 2358 my_kevent(const struct kevent *changelist, size_t nchanges, 2359 struct kevent *eventlist, size_t nevents) 2360 { 2361 int result; 2362 2363 while ((result = kevent(kq, changelist, nchanges, eventlist, nevents, 2364 NULL)) < 0) 2365 if (errno != EINTR) { 2366 syslog(LOG_ERR, "kevent: %m"); 2367 exit(EXIT_FAILURE); 2368 } 2369 2370 return (result); 2371 } 2372 2373 static struct kevent * 2374 allocchange(void) 2375 { 2376 if (changes == A_CNT(changebuf)) { 2377 (void) my_kevent(changebuf, A_CNT(changebuf), NULL, 0); 2378 changes = 0; 2379 } 2380 2381 return (&changebuf[changes++]); 2382 } 2383 #endif /* !__minix */ 2384