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