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