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