Deleted Added
full compact
inetd.c (56482) inetd.c (56590)
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

--- 28 unchanged lines hidden (view full) ---

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[] =
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

--- 28 unchanged lines hidden (view full) ---

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 56482 2000-01-23 20:17:41Z charnier $";
45 "$FreeBSD: head/usr.sbin/inetd/inetd.c 56590 2000-01-25 14:52:10Z shin $";
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

--- 43 unchanged lines hidden (view full) ---

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.
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

--- 43 unchanged lines hidden (view full) ---

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
105 */
106#include <sys/param.h>
107#include <sys/ioctl.h>
108#include <sys/wait.h>
109#include <sys/time.h>
110#include <sys/resource.h>
111
112#include <netinet/in.h>

--- 12 unchanged lines hidden (view full) ---

125#include <stdio.h>
126#include <stdlib.h>
127#include <string.h>
128#include <syslog.h>
129#include <tcpd.h>
130#include <unistd.h>
131#include <libutil.h>
132#include <sysexits.h>
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>

--- 12 unchanged lines hidden (view full) ---

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>
133
134#include "inetd.h"
135#include "pathnames.h"
136
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
137#ifndef LIBWRAP_ALLOW_FACILITY
138# define LIBWRAP_ALLOW_FACILITY LOG_AUTH
139#endif
140#ifndef LIBWRAP_ALLOW_SEVERITY
141# define LIBWRAP_ALLOW_SEVERITY LOG_INFO
142#endif
143#ifndef LIBWRAP_DENY_FACILITY
144# define LIBWRAP_DENY_FACILITY LOG_AUTH

--- 43 unchanged lines hidden (view full) ---

188fd_set allsock;
189int options;
190int timingout;
191int toomany = TOOMANY;
192int maxchild = MAXCHILD;
193int maxcpm = MAXCPM;
194struct servent *sp;
195struct rpcent *rpc;
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

--- 43 unchanged lines hidden (view full) ---

208fd_set allsock;
209int options;
210int timingout;
211int toomany = TOOMANY;
212int maxchild = MAXCHILD;
213int maxcpm = MAXCPM;
214struct servent *sp;
215struct rpcent *rpc;
196struct in_addr bind_address;
216char *hostname = NULL;
217struct sockaddr_in *bind_sa4;
218int no_v4bind = 1;
219#ifdef INET6
220struct sockaddr_in6 *bind_sa6;
221int no_v6bind = 1;
222#endif
197int signalpipe[2];
198#ifdef SANITY_CHECK
199int nsock;
200#endif
201
202struct servtab *servtab;
203
204extern struct biltin biltins[];

--- 38 unchanged lines hidden (view full) ---

243 char buf[50];
244#ifdef LOGIN_CAP
245 login_cap_t *lc = NULL;
246#endif
247 struct request_info req;
248 int denied;
249 char *service = NULL;
250 char *pnm;
223int signalpipe[2];
224#ifdef SANITY_CHECK
225int nsock;
226#endif
227
228struct servtab *servtab;
229
230extern struct biltin biltins[];

--- 38 unchanged lines hidden (view full) ---

269 char buf[50];
270#ifdef LOGIN_CAP
271 login_cap_t *lc = NULL;
272#endif
273 struct request_info req;
274 int denied;
275 char *service = NULL;
276 char *pnm;
251 struct sockaddr_in peer;
277 union {
278 struct sockaddr peer_un;
279 struct sockaddr_in peer_un4;
280 struct sockaddr_in6 peer_un6;
281 struct sockaddr_storage peer_max;
282 } p_un;
283#define peer p_un.peer_un
284#define peer4 p_un.peer_un4
285#define peer6 p_un.peer_un6
286#define peermax p_un.peer_max
252 int i;
287 int i;
288 struct addrinfo hints, *res;
289 char *servname;
290 int error;
253
254
255#ifdef OLD_SETPROCTITLE
256 Argv = argv;
257 if (envp == 0 || *envp == 0)
258 envp = argv;
259 while (*envp)
260 envp++;
261 LastArg = envp[-1] + strlen(envp[-1]);
262#endif
263
264 openlog("inetd", LOG_PID | LOG_NOWAIT, LOG_DAEMON);
265
291
292
293#ifdef OLD_SETPROCTITLE
294 Argv = argv;
295 if (envp == 0 || *envp == 0)
296 envp = argv;
297 while (*envp)
298 envp++;
299 LastArg = envp[-1] + strlen(envp[-1]);
300#endif
301
302 openlog("inetd", LOG_PID | LOG_NOWAIT, LOG_DAEMON);
303
266 bind_address.s_addr = htonl(INADDR_ANY);
267 while ((ch = getopt(argc, argv, "dlwWR:a:c:C:p:")) != -1)
268 switch(ch) {
269 case 'd':
270 debug = 1;
271 options |= SO_DEBUG;
272 break;
273 case 'l':
274 log = 1;

--- 6 unchanged lines hidden (view full) ---

281 getvalue(optarg, &maxchild,
282 "-c %s: bad value for maximum children");
283 break;
284 case 'C':
285 getvalue(optarg, &maxcpm,
286 "-C %s: bad value for maximum children/minute");
287 break;
288 case 'a':
304 while ((ch = getopt(argc, argv, "dlwWR:a:c:C:p:")) != -1)
305 switch(ch) {
306 case 'd':
307 debug = 1;
308 options |= SO_DEBUG;
309 break;
310 case 'l':
311 log = 1;

--- 6 unchanged lines hidden (view full) ---

318 getvalue(optarg, &maxchild,
319 "-c %s: bad value for maximum children");
320 break;
321 case 'C':
322 getvalue(optarg, &maxcpm,
323 "-C %s: bad value for maximum children/minute");
324 break;
325 case 'a':
289 if (!inet_aton(optarg, &bind_address)) {
290 syslog(LOG_ERR,
291 "-a %s: invalid IP address", optarg);
292 exit(EX_USAGE);
293 }
326 hostname = optarg;
294 break;
295 case 'p':
296 pid_file = optarg;
297 break;
298 case 'w':
299 wrap_ex++;
300 break;
301 case 'W':
302 wrap_bi++;
303 break;
304 case '?':
305 default:
306 syslog(LOG_ERR,
307 "usage: inetd [-dlwW] [-a address] [-R rate]"
308 " [-c maximum] [-C rate]"
309 " [-p pidfile] [conf-file]");
310 exit(EX_USAGE);
311 }
327 break;
328 case 'p':
329 pid_file = optarg;
330 break;
331 case 'w':
332 wrap_ex++;
333 break;
334 case 'W':
335 wrap_bi++;
336 break;
337 case '?':
338 default:
339 syslog(LOG_ERR,
340 "usage: inetd [-dlwW] [-a address] [-R rate]"
341 " [-c maximum] [-C rate]"
342 " [-p pidfile] [conf-file]");
343 exit(EX_USAGE);
344 }
345 /*
346 * Initialize Bind Addrs.
347 * When hostname is NULL, wild card bind addrs are obtained from
348 * getaddrinfo(). But getaddrinfo() requires at least one of
349 * hostname or servname is non NULL.
350 * So when hostname is NULL, set dummy value to servname.
351 */
352 servname = (hostname == NULL) ? "discard" /* dummy */ : NULL;
353
354 bzero(&hints, sizeof(struct addrinfo));
355 hints.ai_flags = AI_PASSIVE;
356 hints.ai_family = AF_UNSPEC;
357 error = getaddrinfo(hostname, servname, &hints, &res);
358 if (error != 0) {
359 syslog(LOG_ERR, "-a %s: %s", hostname, gai_strerror(error));
360 if (error == EAI_SYSTEM)
361 syslog(LOG_ERR, "%s", strerror(errno));
362 exit(EX_USAGE);
363 }
364 do {
365 if (res->ai_addr == NULL) {
366 syslog(LOG_ERR, "-a %s: getaddrinfo failed", hostname);
367 exit(EX_USAGE);
368 }
369 switch (res->ai_addr->sa_family) {
370 case AF_INET:
371 if (no_v4bind == 0)
372 continue;
373 bind_sa4 = (struct sockaddr_in *)res->ai_addr;
374 /* init port num in case servname is dummy */
375 bind_sa4->sin_port = 0;
376 no_v4bind = 0;
377 continue;
378#ifdef INET6
379 case AF_INET6:
380 if (no_v6bind == 0)
381 continue;
382 bind_sa6 = (struct sockaddr_in6 *)res->ai_addr;
383 /* init port num in case servname is dummy */
384 bind_sa6->sin6_port = 0;
385 no_v6bind = 0;
386 continue;
387#endif
388 }
389 if (no_v4bind == 0
390#ifdef INET6
391 && no_v6bind == 0
392#endif
393 )
394 break;
395 } while ((res = res->ai_next) != NULL);
396 if (no_v4bind != 0
397#ifdef INET6
398 && no_v6bind != 0
399#endif
400 ) {
401 syslog(LOG_ERR, "-a %s: unknown address family", hostname);
402 exit(EX_USAGE);
403 }
404
312 argc -= optind;
313 argv += optind;
314
315 if (argc > 0)
316 CONFIG = argv[0];
317 if (debug == 0) {
318 FILE *fp;
319 if (daemon(0, 0) < 0) {

--- 132 unchanged lines hidden (view full) ---

452 syslog(LOG_ERR, "ioctl2(FIONBIO, 0): %m");
453 if (cpmip(sep, ctrl) < 0) {
454 close(ctrl);
455 continue;
456 }
457 } else
458 ctrl = sep->se_fd;
459 if (log && !ISWRAP(sep)) {
405 argc -= optind;
406 argv += optind;
407
408 if (argc > 0)
409 CONFIG = argv[0];
410 if (debug == 0) {
411 FILE *fp;
412 if (daemon(0, 0) < 0) {

--- 132 unchanged lines hidden (view full) ---

545 syslog(LOG_ERR, "ioctl2(FIONBIO, 0): %m");
546 if (cpmip(sep, ctrl) < 0) {
547 close(ctrl);
548 continue;
549 }
550 } else
551 ctrl = sep->se_fd;
552 if (log && !ISWRAP(sep)) {
553 char pname[INET6_ADDRSTRLEN];
460 pnm = "unknown";
554 pnm = "unknown";
461 i = sizeof peer;
555 i = sizeof peermax;
462 if (getpeername(ctrl, (struct sockaddr *)
556 if (getpeername(ctrl, (struct sockaddr *)
463 &peer, &i)) {
464 i = sizeof peer;
557 &peermax, &i)) {
558 i = sizeof peermax;
465 if (recvfrom(ctrl, buf, sizeof(buf),
466 MSG_PEEK,
559 if (recvfrom(ctrl, buf, sizeof(buf),
560 MSG_PEEK,
467 (struct sockaddr *)&peer, &i) >= 0)
468 pnm = inet_ntoa(peer.sin_addr);
561 (struct sockaddr *)&peermax,
562 &i) >= 0) {
563 getnameinfo((struct sockaddr *)&peermax,
564 sizeof(peermax),
565 pname, sizeof(pname),
566 NULL, 0,
567 NI_NUMERICHOST|
568 NI_WITHSCOPEID);
569 pnm = pname;
570 }
571 } else {
572 getnameinfo((struct sockaddr *)&peermax,
573 sizeof(peermax),
574 pname, sizeof(pname),
575 NULL, 0,
576 NI_NUMERICHOST|
577 NI_WITHSCOPEID);
578 pnm = pname;
469 }
579 }
470 else
471 pnm = inet_ntoa(peer.sin_addr);
472 syslog(LOG_INFO,"%s from %s", sep->se_service, pnm);
473 }
474 (void) sigblock(SIGBLOCK);
475 pid = 0;
476 /*
477 * Fork for all external services, builtins which need to
478 * fork and anything we're wrapping (as wrapping might
479 * block or use hosts_options(5) twist).

--- 298 unchanged lines hidden (view full) ---

778 syslog(LOG_ERR,
779 "%s/%s: %s: login class error, service ignored",
780 new->se_service, new->se_proto, new->se_class);
781 continue;
782 }
783#endif
784 for (sep = servtab; sep; sep = sep->se_next)
785 if (strcmp(sep->se_service, new->se_service) == 0 &&
580 syslog(LOG_INFO,"%s from %s", sep->se_service, pnm);
581 }
582 (void) sigblock(SIGBLOCK);
583 pid = 0;
584 /*
585 * Fork for all external services, builtins which need to
586 * fork and anything we're wrapping (as wrapping might
587 * block or use hosts_options(5) twist).

--- 298 unchanged lines hidden (view full) ---

886 syslog(LOG_ERR,
887 "%s/%s: %s: login class error, service ignored",
888 new->se_service, new->se_proto, new->se_class);
889 continue;
890 }
891#endif
892 for (sep = servtab; sep; sep = sep->se_next)
893 if (strcmp(sep->se_service, new->se_service) == 0 &&
786 strcmp(sep->se_proto, new->se_proto) == 0)
894 strcmp(sep->se_proto, new->se_proto) == 0 &&
895 sep->se_family == new->se_family)
787 break;
788 if (sep != 0) {
789 int i;
790
791#define SWAP(a, b) { typeof(a) c = a; a = b; b = c; }
792 omask = sigblock(SIGBLOCK);
896 break;
897 if (sep != 0) {
898 int i;
899
900#define SWAP(a, b) { typeof(a) c = a; a = b; b = c; }
901 omask = sigblock(SIGBLOCK);
902 if (sep->se_nomapped != new->se_nomapped) {
903 sep->se_nomapped = new->se_nomapped;
904 sep->se_reset = 1;
905 }
793 /* copy over outstanding child pids */
794 if (sep->se_maxchild && new->se_maxchild) {
795 new->se_numchild = sep->se_numchild;
796 if (new->se_numchild > new->se_maxchild)
797 new->se_numchild = new->se_maxchild;
798 memcpy(new->se_pids, sep->se_pids,
799 new->se_numchild * sizeof(*new->se_pids));
800 }

--- 17 unchanged lines hidden (view full) ---

818 SWAP(sep->se_group, new->se_group);
819#ifdef LOGIN_CAP
820 SWAP(sep->se_class, new->se_class);
821#endif
822 SWAP(sep->se_server, new->se_server);
823 SWAP(sep->se_server_name, new->se_server_name);
824 for (i = 0; i < MAXARGV; i++)
825 SWAP(sep->se_argv[i], new->se_argv[i]);
906 /* copy over outstanding child pids */
907 if (sep->se_maxchild && new->se_maxchild) {
908 new->se_numchild = sep->se_numchild;
909 if (new->se_numchild > new->se_maxchild)
910 new->se_numchild = new->se_maxchild;
911 memcpy(new->se_pids, sep->se_pids,
912 new->se_numchild * sizeof(*new->se_pids));
913 }

--- 17 unchanged lines hidden (view full) ---

931 SWAP(sep->se_group, new->se_group);
932#ifdef LOGIN_CAP
933 SWAP(sep->se_class, new->se_class);
934#endif
935 SWAP(sep->se_server, new->se_server);
936 SWAP(sep->se_server_name, new->se_server_name);
937 for (i = 0; i < MAXARGV; i++)
938 SWAP(sep->se_argv[i], new->se_argv[i]);
939#ifdef IPSEC
940 SWAP(sep->se_policy, new->se_policy);
941 ipsecsetup(sep);
942#endif
826 sigsetmask(omask);
827 freeconfig(new);
828 if (debug)
829 print_service("REDO", sep);
830 } else {
831 sep = enter(new);
832 if (debug)
833 print_service("ADD ", sep);
834 }
835 sep->se_checked = 1;
836 if (ISMUX(sep)) {
837 sep->se_fd = -1;
838 continue;
839 }
943 sigsetmask(omask);
944 freeconfig(new);
945 if (debug)
946 print_service("REDO", sep);
947 } else {
948 sep = enter(new);
949 if (debug)
950 print_service("ADD ", sep);
951 }
952 sep->se_checked = 1;
953 if (ISMUX(sep)) {
954 sep->se_fd = -1;
955 continue;
956 }
957 switch (sep->se_family) {
958 case AF_INET:
959 if (no_v4bind != 0) {
960 sep->se_fd = -1;
961 continue;
962 }
963 break;
964#ifdef INET6
965 case AF_INET6:
966 if (no_v6bind != 0) {
967 sep->se_fd = -1;
968 continue;
969 }
970 break;
971#endif
972 }
840 if (!sep->se_rpc) {
841 sp = getservbyname(sep->se_service, sep->se_proto);
842 if (sp == 0) {
843 syslog(LOG_ERR, "%s/%s: unknown service",
973 if (!sep->se_rpc) {
974 sp = getservbyname(sep->se_service, sep->se_proto);
975 if (sp == 0) {
976 syslog(LOG_ERR, "%s/%s: unknown service",
844 sep->se_service, sep->se_proto);
977 sep->se_service, sep->se_proto);
845 sep->se_checked = 0;
846 continue;
847 }
978 sep->se_checked = 0;
979 continue;
980 }
848 if (sp->s_port != sep->se_ctrladdr.sin_port) {
849 sep->se_ctrladdr.sin_family = AF_INET;
850 sep->se_ctrladdr.sin_addr = bind_address;
851 sep->se_ctrladdr.sin_port = sp->s_port;
852 if (sep->se_fd >= 0)
853 close_sep(sep);
981 switch (sep->se_family) {
982 case AF_INET:
983 if (sep->se_ctladdrinitok == 0) {
984 memcpy(&sep->se_ctrladdr4, bind_sa4,
985 sizeof(sep->se_ctrladdr4));
986 sep->se_ctrladdr_size =
987 sizeof(sep->se_ctrladdr4);
988 }
989 if (sp->s_port != sep->se_ctrladdr4.sin_port) {
990 sep->se_ctrladdr4.sin_port =
991 sp->s_port;
992 sep->se_reset = 1;
993 }
994 break;
995#ifdef INET6
996 case AF_INET6:
997 if (sep->se_ctladdrinitok == 0) {
998 memcpy(&sep->se_ctrladdr6, bind_sa6,
999 sizeof(sep->se_ctrladdr6));
1000 sep->se_ctrladdr_size =
1001 sizeof(sep->se_ctrladdr6);
1002 }
1003 if (sp->s_port !=
1004 sep->se_ctrladdr6.sin6_port) {
1005 sep->se_ctrladdr6.sin6_port =
1006 sp->s_port;
1007 sep->se_reset = 1;
1008 }
1009 break;
1010#endif
854 }
1011 }
1012 if (sep->se_reset != 0 && sep->se_fd >= 0)
1013 close_sep(sep);
855 } else {
856 rpc = getrpcbyname(sep->se_service);
857 if (rpc == 0) {
858 syslog(LOG_ERR, "%s/%s unknown RPC service",
859 sep->se_service, sep->se_proto);
860 if (sep->se_fd != -1)
861 (void) close(sep->se_fd);
862 sep->se_fd = -1;

--- 82 unchanged lines hidden (view full) ---

945}
946
947void
948setup(sep)
949 struct servtab *sep;
950{
951 int on = 1;
952
1014 } else {
1015 rpc = getrpcbyname(sep->se_service);
1016 if (rpc == 0) {
1017 syslog(LOG_ERR, "%s/%s unknown RPC service",
1018 sep->se_service, sep->se_proto);
1019 if (sep->se_fd != -1)
1020 (void) close(sep->se_fd);
1021 sep->se_fd = -1;

--- 82 unchanged lines hidden (view full) ---

1104}
1105
1106void
1107setup(sep)
1108 struct servtab *sep;
1109{
1110 int on = 1;
1111
953 if ((sep->se_fd = socket(AF_INET, sep->se_socktype, 0)) < 0) {
1112 if ((sep->se_fd = socket(sep->se_family, sep->se_socktype, 0)) < 0) {
954 if (debug)
955 warn("socket failed on %s/%s",
956 sep->se_service, sep->se_proto);
957 syslog(LOG_ERR, "%s/%s: socket: %m",
958 sep->se_service, sep->se_proto);
959 return;
960 }
961#define turnon(fd, opt) \
962setsockopt(fd, SOL_SOCKET, opt, (char *)&on, sizeof (on))
963 if (strcmp(sep->se_proto, "tcp") == 0 && (options & SO_DEBUG) &&
964 turnon(sep->se_fd, SO_DEBUG) < 0)
965 syslog(LOG_ERR, "setsockopt (SO_DEBUG): %m");
966 if (turnon(sep->se_fd, SO_REUSEADDR) < 0)
967 syslog(LOG_ERR, "setsockopt (SO_REUSEADDR): %m");
968#ifdef SO_PRIVSTATE
969 if (turnon(sep->se_fd, SO_PRIVSTATE) < 0)
970 syslog(LOG_ERR, "setsockopt (SO_PRIVSTATE): %m");
971#endif
1113 if (debug)
1114 warn("socket failed on %s/%s",
1115 sep->se_service, sep->se_proto);
1116 syslog(LOG_ERR, "%s/%s: socket: %m",
1117 sep->se_service, sep->se_proto);
1118 return;
1119 }
1120#define turnon(fd, opt) \
1121setsockopt(fd, SOL_SOCKET, opt, (char *)&on, sizeof (on))
1122 if (strcmp(sep->se_proto, "tcp") == 0 && (options & SO_DEBUG) &&
1123 turnon(sep->se_fd, SO_DEBUG) < 0)
1124 syslog(LOG_ERR, "setsockopt (SO_DEBUG): %m");
1125 if (turnon(sep->se_fd, SO_REUSEADDR) < 0)
1126 syslog(LOG_ERR, "setsockopt (SO_REUSEADDR): %m");
1127#ifdef SO_PRIVSTATE
1128 if (turnon(sep->se_fd, SO_PRIVSTATE) < 0)
1129 syslog(LOG_ERR, "setsockopt (SO_PRIVSTATE): %m");
1130#endif
1131 /* tftpd opens a new connection then needs more infos */
1132 if ((sep->se_family == AF_INET6) &&
1133 (strcmp(sep->se_proto, "udp") == 0) &&
1134 (sep->se_accept == 0) &&
1135 (setsockopt(sep->se_fd, IPPROTO_IPV6, IPV6_PKTINFO,
1136 (char *)&on, sizeof (on)) < 0))
1137 syslog(LOG_ERR, "setsockopt (IPV6_RECVPKTINFO): %m");
1138#ifdef IPV6_BINDV6ONLY
1139 if ((sep->se_family == AF_INET6) &&
1140 (sep->se_nomapped != 0) &&
1141 (setsockopt(sep->se_fd, IPPROTO_IPV6, IPV6_BINDV6ONLY,
1142 (char *)&on, sizeof (on)) < 0))
1143 syslog(LOG_ERR, "setsockopt (IPV6_BINDV6ONLY): %m");
1144#endif /* IPV6_BINDV6ONLY */
972#undef turnon
973 if (sep->se_type == TTCP_TYPE)
974 if (setsockopt(sep->se_fd, IPPROTO_TCP, TCP_NOPUSH,
975 (char *)&on, sizeof (on)) < 0)
976 syslog(LOG_ERR, "setsockopt (TCP_NOPUSH): %m");
1145#undef turnon
1146 if (sep->se_type == TTCP_TYPE)
1147 if (setsockopt(sep->se_fd, IPPROTO_TCP, TCP_NOPUSH,
1148 (char *)&on, sizeof (on)) < 0)
1149 syslog(LOG_ERR, "setsockopt (TCP_NOPUSH): %m");
1150#ifdef IPV6_FAITH
1151 if (sep->se_type == FAITH_TYPE) {
1152 if (setsockopt(sep->se_fd, IPPROTO_IPV6, IPV6_FAITH, &on,
1153 sizeof(on)) < 0) {
1154 syslog(LOG_ERR, "setsockopt (IPV6_FAITH): %m");
1155 }
1156 }
1157#endif
1158#ifdef IPSEC
1159 ipsecsetup(sep);
1160#endif
977 if (bind(sep->se_fd, (struct sockaddr *)&sep->se_ctrladdr,
1161 if (bind(sep->se_fd, (struct sockaddr *)&sep->se_ctrladdr,
978 sizeof (sep->se_ctrladdr)) < 0) {
1162 sep->se_ctrladdr_size) < 0) {
979 if (debug)
980 warn("bind failed on %s/%s",
981 sep->se_service, sep->se_proto);
982 syslog(LOG_ERR, "%s/%s: bind: %m",
983 sep->se_service, sep->se_proto);
984 (void) close(sep->se_fd);
985 sep->se_fd = -1;
986 if (!timingout) {
987 timingout = 1;
988 alarm(RETRYTIME);
989 }
990 return;
991 }
992 if (sep->se_rpc) {
1163 if (debug)
1164 warn("bind failed on %s/%s",
1165 sep->se_service, sep->se_proto);
1166 syslog(LOG_ERR, "%s/%s: bind: %m",
1167 sep->se_service, sep->se_proto);
1168 (void) close(sep->se_fd);
1169 sep->se_fd = -1;
1170 if (!timingout) {
1171 timingout = 1;
1172 alarm(RETRYTIME);
1173 }
1174 return;
1175 }
1176 if (sep->se_rpc) {
993 int i, len = sizeof(struct sockaddr);
1177 int i, len = sep->se_ctrladdr_size;
994
1178
1179 if (sep->se_family != AF_INET) {
1180 syslog(LOG_ERR,
1181 "%s/%s: unsupported address family for rpc",
1182 sep->se_service, sep->se_proto);
1183 (void) close(sep->se_fd);
1184 sep->se_fd = -1;
1185 return;
1186 }
995 if (getsockname(sep->se_fd,
996 (struct sockaddr*)&sep->se_ctrladdr, &len) < 0){
997 syslog(LOG_ERR, "%s/%s: getsockname: %m",
998 sep->se_service, sep->se_proto);
999 (void) close(sep->se_fd);
1000 sep->se_fd = -1;
1001 return;
1002 }
1003 if (debug)
1004 print_service("REG ", sep);
1005 for (i = sep->se_rpc_lowvers; i <= sep->se_rpc_highvers; i++) {
1006 pmap_unset(sep->se_rpc_prog, i);
1007 pmap_set(sep->se_rpc_prog, i,
1008 (sep->se_socktype == SOCK_DGRAM)
1009 ? IPPROTO_UDP : IPPROTO_TCP,
1187 if (getsockname(sep->se_fd,
1188 (struct sockaddr*)&sep->se_ctrladdr, &len) < 0){
1189 syslog(LOG_ERR, "%s/%s: getsockname: %m",
1190 sep->se_service, sep->se_proto);
1191 (void) close(sep->se_fd);
1192 sep->se_fd = -1;
1193 return;
1194 }
1195 if (debug)
1196 print_service("REG ", sep);
1197 for (i = sep->se_rpc_lowvers; i <= sep->se_rpc_highvers; i++) {
1198 pmap_unset(sep->se_rpc_prog, i);
1199 pmap_set(sep->se_rpc_prog, i,
1200 (sep->se_socktype == SOCK_DGRAM)
1201 ? IPPROTO_UDP : IPPROTO_TCP,
1010 ntohs(sep->se_ctrladdr.sin_port));
1202 ntohs(sep->se_ctrladdr4.sin_port));
1011 }
1203 }
1012
1013 }
1014 if (sep->se_socktype == SOCK_STREAM)
1015 listen(sep->se_fd, 64);
1016 enable(sep);
1017 if (debug) {
1018 warnx("registered %s on %d",
1019 sep->se_server, sep->se_fd);
1020 }
1021}
1022
1204 }
1205 if (sep->se_socktype == SOCK_STREAM)
1206 listen(sep->se_fd, 64);
1207 enable(sep);
1208 if (debug) {
1209 warnx("registered %s on %d",
1210 sep->se_server, sep->se_fd);
1211 }
1212}
1213
1214#ifdef IPSEC
1215void
1216ipsecsetup(sep)
1217 struct servtab *sep;
1218{
1219 char *buf;
1220 char *policy_in = NULL;
1221 char *policy_out = NULL;
1222 int level;
1223 int opt;
1224
1225 switch (sep->se_family) {
1226 case AF_INET:
1227 level = IPPROTO_IP;
1228 opt = IP_IPSEC_POLICY;
1229 break;
1230#ifdef INET6
1231 case AF_INET6:
1232 level = IPPROTO_IPV6;
1233 opt = IPV6_IPSEC_POLICY;
1234 break;
1235#endif
1236 default:
1237 return;
1238 }
1239
1240 if (!sep->se_policy || sep->se_policy[0] == '\0') {
1241 policy_in = "in entrust";
1242 policy_out = "out entrust";
1243 } else {
1244 if (!strncmp("in", sep->se_policy, 2))
1245 policy_in = sep->se_policy;
1246 else if (!strncmp("out", sep->se_policy, 3))
1247 policy_out = sep->se_policy;
1248 else {
1249 syslog(LOG_ERR, "invalid security policy \"%s\"",
1250 sep->se_policy);
1251 return;
1252 }
1253 }
1254
1255 if (policy_in != NULL) {
1256 buf = ipsec_set_policy(policy_in, strlen(policy_in));
1257 if (buf != NULL) {
1258 if (setsockopt(sep->se_fd, level, opt,
1259 buf, ipsec_get_policylen(buf)) < 0) {
1260 syslog(LOG_ERR,
1261 "%s/%s: ipsec initialization failed; %s",
1262 sep->se_service, sep->se_proto,
1263 policy_in);
1264 }
1265 free(buf);
1266 } else
1267 syslog(LOG_ERR, "invalid security policy \"%s\"",
1268 policy_in);
1269 }
1270 if (policy_out != NULL) {
1271 buf = ipsec_set_policy(policy_out, strlen(policy_out));
1272 if (buf != NULL) {
1273 if (setsockopt(sep->se_fd, level, opt,
1274 buf, ipsec_get_policylen(buf)) < 0) {
1275 syslog(LOG_ERR,
1276 "%s/%s: ipsec initialization failed; %s",
1277 sep->se_service, sep->se_proto,
1278 policy_out);
1279 }
1280 free(buf);
1281 } else
1282 syslog(LOG_ERR, "invalid security policy \"%s\"",
1283 policy_out);
1284 }
1285}
1286#endif
1287
1023/*
1024 * Finish with a service and its socket.
1025 */
1026void
1027close_sep(sep)
1028 struct servtab *sep;
1029{
1030 if (sep->se_fd >= 0) {

--- 137 unchanged lines hidden (view full) ---

1168getconfigent()
1169{
1170 struct servtab *sep = &serv;
1171 int argc;
1172 char *cp, *arg, *s;
1173 char *versp;
1174 static char TCPMUX_TOKEN[] = "tcpmux/";
1175#define MUX_LEN (sizeof(TCPMUX_TOKEN)-1)
1288/*
1289 * Finish with a service and its socket.
1290 */
1291void
1292close_sep(sep)
1293 struct servtab *sep;
1294{
1295 if (sep->se_fd >= 0) {

--- 137 unchanged lines hidden (view full) ---

1433getconfigent()
1434{
1435 struct servtab *sep = &serv;
1436 int argc;
1437 char *cp, *arg, *s;
1438 char *versp;
1439 static char TCPMUX_TOKEN[] = "tcpmux/";
1440#define MUX_LEN (sizeof(TCPMUX_TOKEN)-1)
1441#ifdef IPSEC
1442 char *policy = NULL;
1443#endif
1444 int v4bind = 0;
1445#ifdef INET6
1446 int v6bind = 0;
1447#endif
1176
1177more:
1448
1449more:
1178 while ((cp = nextline(fconfig)) && (*cp == '#' || *cp == '\0'))
1179 ;
1450 while ((cp = nextline(fconfig)) != NULL) {
1451#ifdef IPSEC
1452 /* lines starting with #@ is not a comment, but the policy */
1453 if (cp[0] == '#' && cp[1] == '@') {
1454 char *p;
1455 for (p = cp + 2; p && *p && isspace(*p); p++)
1456 ;
1457 if (*p == '\0') {
1458 if (policy)
1459 free(policy);
1460 policy = NULL;
1461 } else if (ipsec_get_policylen(p) >= 0) {
1462 if (policy)
1463 free(policy);
1464 policy = newstr(p);
1465 } else {
1466 syslog(LOG_ERR,
1467 "%s: invalid ipsec policy \"%s\"",
1468 CONFIG, p);
1469 exit(EX_CONFIG);
1470 }
1471 }
1472#endif
1473 if (*cp == '#' || *cp == '\0')
1474 continue;
1475 break;
1476 }
1180 if (cp == NULL)
1181 return ((struct servtab *)0);
1182 /*
1183 * clear the static buffer, since some fields (se_ctrladdr,
1184 * for example) don't get initialized here.
1185 */
1186 memset((caddr_t)sep, 0, sizeof *sep);
1187 arg = skip(&cp);

--- 23 unchanged lines hidden (view full) ---

1211 else if (strcmp(arg, "seqpacket") == 0)
1212 sep->se_socktype = SOCK_SEQPACKET;
1213 else if (strcmp(arg, "raw") == 0)
1214 sep->se_socktype = SOCK_RAW;
1215 else
1216 sep->se_socktype = -1;
1217
1218 arg = sskip(&cp);
1477 if (cp == NULL)
1478 return ((struct servtab *)0);
1479 /*
1480 * clear the static buffer, since some fields (se_ctrladdr,
1481 * for example) don't get initialized here.
1482 */
1483 memset((caddr_t)sep, 0, sizeof *sep);
1484 arg = skip(&cp);

--- 23 unchanged lines hidden (view full) ---

1508 else if (strcmp(arg, "seqpacket") == 0)
1509 sep->se_socktype = SOCK_SEQPACKET;
1510 else if (strcmp(arg, "raw") == 0)
1511 sep->se_socktype = SOCK_RAW;
1512 else
1513 sep->se_socktype = -1;
1514
1515 arg = sskip(&cp);
1219 if (strcmp(arg, "tcp/ttcp") == 0) {
1220 sep->se_type = TTCP_TYPE;
1221 sep->se_proto = newstr("tcp");
1222 } else {
1516 if (strncmp(arg, "tcp", 3) == 0) {
1517 sep->se_proto = newstr(strsep(&arg, "/"));
1518 if (arg != NULL) {
1519 if (strcmp(arg, "ttcp") == 0)
1520 sep->se_type = TTCP_TYPE;
1521 else if (strcmp(arg, "faith") == 0)
1522 sep->se_type = FAITH_TYPE;
1523 }
1524 } else
1223 sep->se_proto = newstr(arg);
1525 sep->se_proto = newstr(arg);
1224 }
1225 if (strncmp(sep->se_proto, "rpc/", 4) == 0) {
1526 if (strncmp(sep->se_proto, "rpc/", 4) == 0) {
1527 if (sep->se_family != AF_INET) {
1528 syslog(LOG_ERR, "IPv6 for RPC is not supported yet");
1529 freeconfig(sep);
1530 goto more;
1531 }
1226 memmove(sep->se_proto, sep->se_proto + 4,
1227 strlen(sep->se_proto) + 1 - 4);
1228 sep->se_rpc = 1;
1229 sep->se_rpc_prog = sep->se_rpc_lowvers =
1230 sep->se_rpc_lowvers = 0;
1532 memmove(sep->se_proto, sep->se_proto + 4,
1533 strlen(sep->se_proto) + 1 - 4);
1534 sep->se_rpc = 1;
1535 sep->se_rpc_prog = sep->se_rpc_lowvers =
1536 sep->se_rpc_lowvers = 0;
1231 sep->se_ctrladdr.sin_family = AF_INET;
1232 sep->se_ctrladdr.sin_port = 0;
1233 sep->se_ctrladdr.sin_addr = bind_address;
1537 memcpy(&sep->se_ctrladdr4, bind_sa4,
1538 sizeof(sep->se_ctrladdr4));
1234 if ((versp = rindex(sep->se_service, '/'))) {
1235 *versp++ = '\0';
1236 switch (sscanf(versp, "%d-%d",
1237 &sep->se_rpc_lowvers,
1238 &sep->se_rpc_highvers)) {
1239 case 2:
1240 break;
1241 case 1:

--- 8 unchanged lines hidden (view full) ---

1250 goto more;
1251 }
1252 }
1253 else {
1254 sep->se_rpc_lowvers =
1255 sep->se_rpc_highvers = 1;
1256 }
1257 }
1539 if ((versp = rindex(sep->se_service, '/'))) {
1540 *versp++ = '\0';
1541 switch (sscanf(versp, "%d-%d",
1542 &sep->se_rpc_lowvers,
1543 &sep->se_rpc_highvers)) {
1544 case 2:
1545 break;
1546 case 1:

--- 8 unchanged lines hidden (view full) ---

1555 goto more;
1556 }
1557 }
1558 else {
1559 sep->se_rpc_lowvers =
1560 sep->se_rpc_highvers = 1;
1561 }
1562 }
1563 sep->se_nomapped = 0;
1564 while (isdigit(sep->se_proto[strlen(sep->se_proto) - 1])) {
1565#ifdef INET6
1566 if (sep->se_proto[strlen(sep->se_proto) - 1] == '6') {
1567 if (no_v6bind != 0) {
1568 syslog(LOG_INFO, "IPv6 bind is ignored for %s",
1569 sep->se_service);
1570 freeconfig(sep);
1571 goto more;
1572 }
1573 sep->se_proto[strlen(sep->se_proto) - 1] = '\0';
1574 v6bind = 1;
1575 continue;
1576 }
1577#endif
1578 if (sep->se_proto[strlen(sep->se_proto) - 1] == '4') {
1579 sep->se_proto[strlen(sep->se_proto) - 1] = '\0';
1580 v4bind = 1;
1581 continue;
1582 }
1583 /* illegal version num */
1584 syslog(LOG_ERR, "bad IP version for %s", sep->se_proto);
1585 freeconfig(sep);
1586 goto more;
1587 }
1588#ifdef INET6
1589 if (v6bind != 0) {
1590 sep->se_family = AF_INET6;
1591 if (v4bind == 0 || no_v4bind != 0)
1592 sep->se_nomapped = 1;
1593 }
1594#endif
1595 else { /* default to v4 bind if not v6 bind */
1596 if (no_v4bind != 0) {
1597 syslog(LOG_INFO, "IPv4 bind is ignored for %s",
1598 sep->se_service);
1599 freeconfig(sep);
1600 goto more;
1601 }
1602 sep->se_family = AF_INET;
1603 }
1604 /* init ctladdr */
1605 switch(sep->se_family) {
1606 case AF_INET:
1607 memcpy(&sep->se_ctrladdr4, bind_sa4,
1608 sizeof(sep->se_ctrladdr4));
1609 sep->se_ctrladdr_size = sizeof(sep->se_ctrladdr4);
1610 sep->se_ctladdrinitok = 1;
1611 break;
1612#ifdef INET6
1613 case AF_INET6:
1614 memcpy(&sep->se_ctrladdr6, bind_sa6,
1615 sizeof(sep->se_ctrladdr6));
1616 sep->se_ctrladdr_size = sizeof(sep->se_ctrladdr6);
1617 sep->se_ctladdrinitok = 1;
1618 break;
1619#endif
1620 }
1258 arg = sskip(&cp);
1259 if (!strncmp(arg, "wait", 4))
1260 sep->se_accept = 0;
1261 else if (!strncmp(arg, "nowait", 6))
1262 sep->se_accept = 1;
1263 else {
1264 syslog(LOG_ERR,
1265 "%s: bad wait/nowait for service %s",

--- 101 unchanged lines hidden (view full) ---

1367 } else {
1368 syslog(LOG_ERR,
1369 "%s: too many arguments for service %s",
1370 CONFIG, sep->se_service);
1371 goto more;
1372 }
1373 while (argc <= MAXARGV)
1374 sep->se_argv[argc++] = NULL;
1621 arg = sskip(&cp);
1622 if (!strncmp(arg, "wait", 4))
1623 sep->se_accept = 0;
1624 else if (!strncmp(arg, "nowait", 6))
1625 sep->se_accept = 1;
1626 else {
1627 syslog(LOG_ERR,
1628 "%s: bad wait/nowait for service %s",

--- 101 unchanged lines hidden (view full) ---

1730 } else {
1731 syslog(LOG_ERR,
1732 "%s: too many arguments for service %s",
1733 CONFIG, sep->se_service);
1734 goto more;
1735 }
1736 while (argc <= MAXARGV)
1737 sep->se_argv[argc++] = NULL;
1738#ifdef IPSEC
1739 sep->se_policy = policy ? newstr(policy) : NULL;
1740#endif
1375 return (sep);
1376}
1377
1378void
1379freeconfig(cp)
1380 struct servtab *cp;
1381{
1382 int i;

--- 12 unchanged lines hidden (view full) ---

1395#endif
1396 if (cp->se_server)
1397 free(cp->se_server);
1398 if (cp->se_pids)
1399 free(cp->se_pids);
1400 for (i = 0; i < MAXARGV; i++)
1401 if (cp->se_argv[i])
1402 free(cp->se_argv[i]);
1741 return (sep);
1742}
1743
1744void
1745freeconfig(cp)
1746 struct servtab *cp;
1747{
1748 int i;

--- 12 unchanged lines hidden (view full) ---

1761#endif
1762 if (cp->se_server)
1763 free(cp->se_server);
1764 if (cp->se_pids)
1765 free(cp->se_pids);
1766 for (i = 0; i < MAXARGV; i++)
1767 if (cp->se_argv[i])
1768 free(cp->se_argv[i]);
1769#ifdef IPSEC
1770 if (cp->se_policy)
1771 free(cp->se_policy);
1772#endif
1403}
1404
1405
1406/*
1407 * Safe skip - if skip returns null, log a syntax error in the
1408 * configuration file and exit.
1409 */
1410char *

--- 74 unchanged lines hidden (view full) ---

1485#ifdef OLD_SETPROCTITLE
1486void
1487inetd_setproctitle(a, s)
1488 char *a;
1489 int s;
1490{
1491 int size;
1492 char *cp;
1773}
1774
1775
1776/*
1777 * Safe skip - if skip returns null, log a syntax error in the
1778 * configuration file and exit.
1779 */
1780char *

--- 74 unchanged lines hidden (view full) ---

1855#ifdef OLD_SETPROCTITLE
1856void
1857inetd_setproctitle(a, s)
1858 char *a;
1859 int s;
1860{
1861 int size;
1862 char *cp;
1493 struct sockaddr_in sin;
1494 char buf[80];
1863 struct sockaddr_storage ss;
1864 char buf[80], pbuf[INET6_ADDRSTRLEN];
1495
1496 cp = Argv[0];
1865
1866 cp = Argv[0];
1497 size = sizeof(sin);
1498 if (getpeername(s, (struct sockaddr *)&sin, &size) == 0)
1499 (void) sprintf(buf, "-%s [%s]", a, inet_ntoa(sin.sin_addr));
1500 else
1867 size = sizeof(ss);
1868 if (getpeername(s, (struct sockaddr *)&ss, &size) == 0) {
1869 getnameinfo((struct sockaddr *)&ss, size, pbuf, sizeof(pbuf),
1870 NULL, 0, NI_NUMERICHOST|NI_WITHSCOPEID);
1871 (void) sprintf(buf, "-%s [%s]", a, pbuf);
1872 } else
1501 (void) sprintf(buf, "-%s", a);
1502 strncpy(cp, buf, LastArg - cp);
1503 cp += strlen(cp);
1504 while (cp < LastArg)
1505 *cp++ = ' ';
1506}
1507#else
1508void
1509inetd_setproctitle(a, s)
1510 char *a;
1511 int s;
1512{
1513 int size;
1873 (void) sprintf(buf, "-%s", a);
1874 strncpy(cp, buf, LastArg - cp);
1875 cp += strlen(cp);
1876 while (cp < LastArg)
1877 *cp++ = ' ';
1878}
1879#else
1880void
1881inetd_setproctitle(a, s)
1882 char *a;
1883 int s;
1884{
1885 int size;
1514 struct sockaddr_in sin;
1515 char buf[80];
1886 struct sockaddr_storage ss;
1887 char buf[80], pbuf[INET6_ADDRSTRLEN];
1516
1888
1517 size = sizeof(sin);
1518 if (getpeername(s, (struct sockaddr *)&sin, &size) == 0)
1519 (void) sprintf(buf, "%s [%s]", a, inet_ntoa(sin.sin_addr));
1520 else
1889 size = sizeof(ss);
1890 if (getpeername(s, (struct sockaddr *)&ss, &size) == 0) {
1891 getnameinfo((struct sockaddr *)&ss, size, pbuf, sizeof(pbuf),
1892 NULL, 0, NI_NUMERICHOST|NI_WITHSCOPEID);
1893 (void) sprintf(buf, "%s [%s]", a, pbuf);
1894 } else
1521 (void) sprintf(buf, "%s", a);
1522 setproctitle("%s", buf);
1523}
1524#endif
1525
1526
1527/*
1528 * Internet services provided internally by inetd:
1529 */
1530
1895 (void) sprintf(buf, "%s", a);
1896 setproctitle("%s", buf);
1897}
1898#endif
1899
1900
1901/*
1902 * Internet services provided internally by inetd:
1903 */
1904
1531int check_loop(sin, sep)
1532 struct sockaddr_in *sin;
1905int check_loop(sa, sep)
1906 struct sockaddr *sa;
1533 struct servtab *sep;
1534{
1535 struct servtab *se2;
1907 struct servtab *sep;
1908{
1909 struct servtab *se2;
1910 char pname[INET6_ADDRSTRLEN];
1536
1537 for (se2 = servtab; se2; se2 = se2->se_next) {
1538 if (!se2->se_bi || se2->se_socktype != SOCK_DGRAM)
1539 continue;
1540
1911
1912 for (se2 = servtab; se2; se2 = se2->se_next) {
1913 if (!se2->se_bi || se2->se_socktype != SOCK_DGRAM)
1914 continue;
1915
1541 if (sin->sin_port == se2->se_ctrladdr.sin_port) {
1542 syslog(LOG_WARNING,
1543 "%s/%s:%s/%s loop request REFUSED from %s",
1544 sep->se_service, sep->se_proto,
1545 se2->se_service, se2->se_proto,
1546 inet_ntoa(sin->sin_addr));
1547 return 1;
1916 switch (se2->se_family) {
1917 case AF_INET:
1918 if (((struct sockaddr_in *)sa)->sin_port ==
1919 se2->se_ctrladdr4.sin_port)
1920 goto isloop;
1921 continue;
1922#ifdef INET6
1923 case AF_INET6:
1924 if (((struct sockaddr_in *)sa)->sin_port ==
1925 se2->se_ctrladdr4.sin_port)
1926 goto isloop;
1927 continue;
1928#endif
1929 default:
1930 continue;
1548 }
1931 }
1932 isloop:
1933 getnameinfo(sa, sa->sa_len, pname, sizeof(pname), NULL, 0,
1934 NI_NUMERICHOST|NI_WITHSCOPEID);
1935 syslog(LOG_WARNING, "%s/%s:%s/%s loop request REFUSED from %s",
1936 sep->se_service, sep->se_proto,
1937 se2->se_service, se2->se_proto,
1938 pname);
1939 return 1;
1549 }
1550 return 0;
1551}
1552
1553/*
1554 * print_service:
1555 * Dump relevant information to stderr
1556 */
1557void
1558print_service(action, sep)
1559 char *action;
1560 struct servtab *sep;
1561{
1562 fprintf(stderr,
1940 }
1941 return 0;
1942}
1943
1944/*
1945 * print_service:
1946 * Dump relevant information to stderr
1947 */
1948void
1949print_service(action, sep)
1950 char *action;
1951 struct servtab *sep;
1952{
1953 fprintf(stderr,
1954 "%s: %s proto=%s accept=%d max=%d user=%s group=%s"
1563#ifdef LOGIN_CAP
1955#ifdef LOGIN_CAP
1564 "%s: %s proto=%s accept=%d max=%d user=%s group=%s class=%s builtin=%p server=%s\n",
1565#else
1566 "%s: %s proto=%s accept=%d max=%d user=%s group=%s builtin=%p server=%s\n",
1956 "class=%s"
1567#endif
1957#endif
1958 " builtin=%p server=%s"
1959#ifdef IPSEC
1960 " policy=\"%s\""
1961#endif
1962 "\n",
1568 action, sep->se_service, sep->se_proto,
1569 sep->se_accept, sep->se_maxchild, sep->se_user, sep->se_group,
1570#ifdef LOGIN_CAP
1571 sep->se_class,
1572#endif
1963 action, sep->se_service, sep->se_proto,
1964 sep->se_accept, sep->se_maxchild, sep->se_user, sep->se_group,
1965#ifdef LOGIN_CAP
1966 sep->se_class,
1967#endif
1573 (void *) sep->se_bi, sep->se_server);
1968 (void *) sep->se_bi, sep->se_server
1969#ifdef IPSEC
1970 , (sep->se_policy ? sep->se_policy : "")
1971#endif
1972 );
1574}
1575
1576#define CPMHSIZE 256
1577#define CPMHMASK (CPMHSIZE-1)
1578#define CHTGRAN 10
1579#define CHTSIZE 6
1580
1581typedef struct CTime {
1582 unsigned long ct_Ticks;
1583 int ct_Count;
1584} CTime;
1585
1586typedef struct CHash {
1973}
1974
1975#define CPMHSIZE 256
1976#define CPMHMASK (CPMHSIZE-1)
1977#define CHTGRAN 10
1978#define CHTSIZE 6
1979
1980typedef struct CTime {
1981 unsigned long ct_Ticks;
1982 int ct_Count;
1983} CTime;
1984
1985typedef struct CHash {
1587 struct in_addr ch_Addr;
1986 union {
1987 struct in_addr c4_Addr;
1988 struct in6_addr c6_Addr;
1989 } cu_Addr;
1990#define ch_Addr4 cu_Addr.c4_Addr
1991#define ch_Addr6 cu_Addr.c6_Addr
1992 int ch_Family;
1588 time_t ch_LTime;
1589 char *ch_Service;
1590 CTime ch_Times[CHTSIZE];
1591} CHash;
1592
1593CHash CHashAry[CPMHSIZE];
1594
1595int
1596cpmip(sep, ctrl)
1597 struct servtab *sep;
1598 int ctrl;
1599{
1993 time_t ch_LTime;
1994 char *ch_Service;
1995 CTime ch_Times[CHTSIZE];
1996} CHash;
1997
1998CHash CHashAry[CPMHSIZE];
1999
2000int
2001cpmip(sep, ctrl)
2002 struct servtab *sep;
2003 int ctrl;
2004{
1600 struct sockaddr_in rsin;
1601 int rsinLen = sizeof(rsin);
2005 struct sockaddr_storage rss;
2006 int rssLen = sizeof(rss);
1602 int r = 0;
1603
1604 /*
1605 * If getpeername() fails, just let it through (if logging is
1606 * enabled the condition is caught elsewhere)
1607 */
1608
1609 if (sep->se_maxcpm > 0 &&
2007 int r = 0;
2008
2009 /*
2010 * If getpeername() fails, just let it through (if logging is
2011 * enabled the condition is caught elsewhere)
2012 */
2013
2014 if (sep->se_maxcpm > 0 &&
1610 getpeername(ctrl, (struct sockaddr *)&rsin, &rsinLen) == 0 ) {
2015 getpeername(ctrl, (struct sockaddr *)&rss, &rssLen) == 0 ) {
1611 time_t t = time(NULL);
1612 int hv = 0xABC3D20F;
1613 int i;
1614 int cnt = 0;
1615 CHash *chBest = NULL;
1616 unsigned int ticks = t / CHTGRAN;
2016 time_t t = time(NULL);
2017 int hv = 0xABC3D20F;
2018 int i;
2019 int cnt = 0;
2020 CHash *chBest = NULL;
2021 unsigned int ticks = t / CHTGRAN;
2022 struct sockaddr_in *sin;
2023#ifdef INET6
2024 struct sockaddr_in6 *sin6;
2025#endif
1617
2026
2027 sin = (struct sockaddr_in *)&rss;
2028#ifdef INET6
2029 sin6 = (struct sockaddr_in6 *)&rss;
2030#endif
1618 {
1619 char *p;
2031 {
2032 char *p;
1620 int i;
2033 int i, addrlen;
1621
2034
1622 for (i = 0, p = (char *)&rsin.sin_addr;
1623 i < sizeof(rsin.sin_addr);
1624 ++i, ++p) {
2035 switch (rss.ss_family) {
2036 case AF_INET:
2037 p = (char *)&sin->sin_addr;
2038 addrlen = sizeof(struct in_addr);
2039 break;
2040#ifdef INET6
2041 case AF_INET6:
2042 p = (char *)&sin6->sin6_addr;
2043 addrlen = sizeof(struct in6_addr);
2044 break;
2045#endif
2046 default:
2047 /* should not happen */
2048 return -1;
2049 }
2050
2051 for (i = 0; i < addrlen; ++i, ++p) {
1625 hv = (hv << 5) ^ (hv >> 23) ^ *p;
1626 }
1627 hv = (hv ^ (hv >> 16));
1628 }
1629 for (i = 0; i < 5; ++i) {
1630 CHash *ch = &CHashAry[(hv + i) & CPMHMASK];
1631
2052 hv = (hv << 5) ^ (hv >> 23) ^ *p;
2053 }
2054 hv = (hv ^ (hv >> 16));
2055 }
2056 for (i = 0; i < 5; ++i) {
2057 CHash *ch = &CHashAry[(hv + i) & CPMHMASK];
2058
1632 if (rsin.sin_addr.s_addr == ch->ch_Addr.s_addr &&
2059 if (rss.ss_family == AF_INET &&
2060 ch->ch_Family == AF_INET &&
2061 sin->sin_addr.s_addr == ch->ch_Addr4.s_addr &&
1633 ch->ch_Service && strcmp(sep->se_service,
1634 ch->ch_Service) == 0) {
1635 chBest = ch;
1636 break;
1637 }
2062 ch->ch_Service && strcmp(sep->se_service,
2063 ch->ch_Service) == 0) {
2064 chBest = ch;
2065 break;
2066 }
2067#ifdef INET6
2068 if (rss.ss_family == AF_INET6 &&
2069 ch->ch_Family == AF_INET6 &&
2070 IN6_ARE_ADDR_EQUAL(&sin6->sin6_addr,
2071 &ch->ch_Addr6) != 0 &&
2072 ch->ch_Service && strcmp(sep->se_service,
2073 ch->ch_Service) == 0) {
2074 chBest = ch;
2075 break;
2076 }
2077#endif
1638 if (chBest == NULL || ch->ch_LTime == 0 ||
1639 ch->ch_LTime < chBest->ch_LTime) {
1640 chBest = ch;
1641 }
1642 }
2078 if (chBest == NULL || ch->ch_LTime == 0 ||
2079 ch->ch_LTime < chBest->ch_LTime) {
2080 chBest = ch;
2081 }
2082 }
1643 if (rsin.sin_addr.s_addr != chBest->ch_Addr.s_addr ||
2083 if ((rss.ss_family == AF_INET &&
2084 (chBest->ch_Family != AF_INET ||
2085 sin->sin_addr.s_addr != chBest->ch_Addr4.s_addr)) ||
1644 chBest->ch_Service == NULL ||
1645 strcmp(sep->se_service, chBest->ch_Service) != 0) {
2086 chBest->ch_Service == NULL ||
2087 strcmp(sep->se_service, chBest->ch_Service) != 0) {
1646 chBest->ch_Addr = rsin.sin_addr;
2088 chBest->ch_Family = sin->sin_family;
2089 chBest->ch_Addr4 = sin->sin_addr;
1647 if (chBest->ch_Service)
1648 free(chBest->ch_Service);
1649 chBest->ch_Service = strdup(sep->se_service);
1650 bzero(chBest->ch_Times, sizeof(chBest->ch_Times));
1651 }
2090 if (chBest->ch_Service)
2091 free(chBest->ch_Service);
2092 chBest->ch_Service = strdup(sep->se_service);
2093 bzero(chBest->ch_Times, sizeof(chBest->ch_Times));
2094 }
2095#ifdef INET6
2096 if ((rss.ss_family == AF_INET6 &&
2097 (chBest->ch_Family != AF_INET6 ||
2098 IN6_ARE_ADDR_EQUAL(&sin6->sin6_addr,
2099 &chBest->ch_Addr6) == 0)) ||
2100 chBest->ch_Service == NULL ||
2101 strcmp(sep->se_service, chBest->ch_Service) != 0) {
2102 chBest->ch_Family = sin6->sin6_family;
2103 chBest->ch_Addr6 = sin6->sin6_addr;
2104 if (chBest->ch_Service)
2105 free(chBest->ch_Service);
2106 chBest->ch_Service = strdup(sep->se_service);
2107 bzero(chBest->ch_Times, sizeof(chBest->ch_Times));
2108 }
2109#endif
1652 chBest->ch_LTime = t;
1653 {
1654 CTime *ct = &chBest->ch_Times[ticks % CHTSIZE];
1655 if (ct->ct_Ticks != ticks) {
1656 ct->ct_Ticks = ticks;
1657 ct->ct_Count = 0;
1658 }
1659 ++ct->ct_Count;
1660 }
1661 for (i = 0; i < CHTSIZE; ++i) {
1662 CTime *ct = &chBest->ch_Times[i];
1663 if (ct->ct_Ticks <= ticks &&
1664 ct->ct_Ticks >= ticks - CHTSIZE) {
1665 cnt += ct->ct_Count;
1666 }
1667 }
1668 if (cnt * (CHTSIZE * CHTGRAN) / 60 > sep->se_maxcpm) {
2110 chBest->ch_LTime = t;
2111 {
2112 CTime *ct = &chBest->ch_Times[ticks % CHTSIZE];
2113 if (ct->ct_Ticks != ticks) {
2114 ct->ct_Ticks = ticks;
2115 ct->ct_Count = 0;
2116 }
2117 ++ct->ct_Count;
2118 }
2119 for (i = 0; i < CHTSIZE; ++i) {
2120 CTime *ct = &chBest->ch_Times[i];
2121 if (ct->ct_Ticks <= ticks &&
2122 ct->ct_Ticks >= ticks - CHTSIZE) {
2123 cnt += ct->ct_Count;
2124 }
2125 }
2126 if (cnt * (CHTSIZE * CHTGRAN) / 60 > sep->se_maxcpm) {
2127 char pname[INET6_ADDRSTRLEN];
2128
2129 getnameinfo((struct sockaddr *)&rss,
2130 ((struct sockaddr *)&rss)->sa_len,
2131 pname, sizeof(pname), NULL, 0,
2132 NI_NUMERICHOST|NI_WITHSCOPEID);
1669 r = -1;
1670 syslog(LOG_ERR,
1671 "%s from %s exceeded counts/min (limit %d/min)",
2133 r = -1;
2134 syslog(LOG_ERR,
2135 "%s from %s exceeded counts/min (limit %d/min)",
1672 sep->se_service, inet_ntoa(rsin.sin_addr),
2136 sep->se_service, pname,
1673 sep->se_maxcpm);
1674 }
1675 }
1676 return(r);
1677}
2137 sep->se_maxcpm);
2138 }
2139 }
2140 return(r);
2141}