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