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