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