2021-10-12 22:08:04 +03:00
|
|
|
/* $NetBSD: inetd.c,v 1.137 2021/10/12 19:08:04 christos Exp $ */
|
1998-05-01 05:57:26 +04:00
|
|
|
|
|
|
|
/*-
|
2003-02-13 14:47:27 +03:00
|
|
|
* Copyright (c) 1998, 2003 The NetBSD Foundation, Inc.
|
1998-05-01 05:57:26 +04:00
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* This code is derived from software contributed to The NetBSD Foundation
|
|
|
|
* by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
|
2003-02-13 14:47:27 +03:00
|
|
|
* NASA Ames Research Center and by Matthias Scheler.
|
1998-05-01 05:57:26 +04:00
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
|
|
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
|
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
|
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
|
|
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*/
|
1997-03-13 17:15:40 +03:00
|
|
|
|
1993-03-21 12:45:37 +03:00
|
|
|
/*
|
1997-03-13 20:22:23 +03:00
|
|
|
* Copyright (c) 1983, 1991, 1993, 1994
|
|
|
|
* The Regents of the University of California. All rights reserved.
|
1993-03-21 12:45:37 +03:00
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
2003-08-07 15:25:11 +04:00
|
|
|
* 3. Neither the name of the University nor the names of its contributors
|
1993-03-21 12:45:37 +03:00
|
|
|
* may be used to endorse or promote products derived from this software
|
|
|
|
* without specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
|
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
|
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
|
* SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
|
1997-10-05 20:40:24 +04:00
|
|
|
#include <sys/cdefs.h>
|
1993-03-21 12:45:37 +03:00
|
|
|
#ifndef lint
|
2008-07-21 17:36:57 +04:00
|
|
|
__COPYRIGHT("@(#) Copyright (c) 1983, 1991, 1993, 1994\
|
|
|
|
The Regents of the University of California. All rights reserved.");
|
1997-03-13 20:22:23 +03:00
|
|
|
#if 0
|
|
|
|
static char sccsid[] = "@(#)inetd.c 8.4 (Berkeley) 4/13/94";
|
|
|
|
#else
|
2021-10-12 22:08:04 +03:00
|
|
|
__RCSID("$NetBSD: inetd.c,v 1.137 2021/10/12 19:08:04 christos Exp $");
|
1997-03-13 20:22:23 +03:00
|
|
|
#endif
|
1993-03-21 12:45:37 +03:00
|
|
|
#endif /* not lint */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Inetd - Internet super-server
|
|
|
|
*
|
1997-03-13 20:22:23 +03:00
|
|
|
* This program invokes all internet services as needed. Connection-oriented
|
|
|
|
* services are invoked each time a connection is made, by creating a process.
|
|
|
|
* This process is passed the connection as file descriptor 0 and is expected
|
|
|
|
* to do a getpeername to find out the source host and port.
|
1993-03-21 12:45:37 +03:00
|
|
|
*
|
|
|
|
* Datagram oriented services are invoked when a datagram
|
|
|
|
* arrives; a process is created and passed a pending message
|
|
|
|
* on file descriptor 0. Datagram servers may either connect
|
|
|
|
* to their peer, freeing up the original socket for inetd
|
|
|
|
* to receive further messages on, or ``take over the socket'',
|
|
|
|
* processing all arriving datagrams and, eventually, timing
|
|
|
|
* out. The first type of server is said to be ``multi-threaded'';
|
1996-12-31 02:38:18 +03:00
|
|
|
* the second type of server ``single-threaded''.
|
1993-03-21 12:45:37 +03:00
|
|
|
*
|
|
|
|
* Inetd uses a configuration file which is read at startup
|
|
|
|
* and, possibly, at some later time in response to a hangup signal.
|
|
|
|
* The configuration file is ``free format'' with fields given in the
|
|
|
|
* order shown below. Continuation lines for an entry must being with
|
|
|
|
* a space or tab. All fields must be present in each entry.
|
|
|
|
*
|
1997-03-13 20:22:23 +03:00
|
|
|
* service name must be in /etc/services or must
|
|
|
|
* name a tcpmux service
|
2008-08-04 07:55:47 +04:00
|
|
|
* socket type[:accf[,arg]] stream/dgram/raw/rdm/seqpacket,
|
|
|
|
only stream can name an accept filter
|
1993-03-21 12:45:37 +03:00
|
|
|
* protocol must be in /etc/protocols
|
2009-10-23 02:50:35 +04:00
|
|
|
* wait/nowait[:max] single-threaded/multi-threaded, max #
|
1999-10-07 01:54:10 +04:00
|
|
|
* user[:group] user/group to run daemon as
|
1993-03-21 12:45:37 +03:00
|
|
|
* server program full path name
|
2017-11-28 14:51:11 +03:00
|
|
|
* server program arguments maximum of MAXARGV (64)
|
1993-03-21 12:45:37 +03:00
|
|
|
*
|
1993-06-11 04:36:31 +04:00
|
|
|
* For RPC services
|
2021-09-03 22:33:51 +03:00
|
|
|
* service name/version must be in /etc/rpc
|
1993-06-11 04:36:31 +04:00
|
|
|
* socket type stream/dgram/raw/rdm/seqpacket
|
|
|
|
* protocol must be in /etc/protocols
|
2009-10-23 02:50:35 +04:00
|
|
|
* wait/nowait[:max] single-threaded/multi-threaded
|
1999-10-07 01:54:10 +04:00
|
|
|
* user[:group] user to run daemon as
|
1993-06-11 04:36:31 +04:00
|
|
|
* server program full path name
|
2017-11-28 14:51:11 +03:00
|
|
|
* server program arguments maximum of MAXARGV (64)
|
1993-10-13 14:22:48 +03:00
|
|
|
*
|
1996-12-31 02:38:18 +03:00
|
|
|
* For non-RPC services, the "service name" can be of the form
|
|
|
|
* hostaddress:servicename, in which case the hostaddress is used
|
|
|
|
* as the host portion of the address to listen on. If hostaddress
|
|
|
|
* consists of a single `*' character, INADDR_ANY is used.
|
|
|
|
*
|
|
|
|
* A line can also consist of just
|
|
|
|
* hostaddress:
|
|
|
|
* where hostaddress is as in the preceding paragraph. Such a line must
|
|
|
|
* have no further fields; the specified hostaddress is remembered and
|
|
|
|
* used for all further lines that have no hostaddress specified,
|
|
|
|
* until the next such line (or EOF). (This is why * is provided to
|
|
|
|
* allow explicit specification of INADDR_ANY.) A line
|
|
|
|
* *:
|
|
|
|
* is implicitly in effect at the beginning of the file.
|
|
|
|
*
|
|
|
|
* The hostaddress specifier may (and often will) contain dots;
|
|
|
|
* the service name must not.
|
|
|
|
*
|
|
|
|
* For RPC services, host-address specifiers are accepted and will
|
|
|
|
* work to some extent; however, because of limitations in the
|
|
|
|
* portmapper interface, it will not work to try to give more than
|
|
|
|
* one line for any given RPC service, even if the host-address
|
|
|
|
* specifiers are different.
|
|
|
|
*
|
1997-03-13 20:22:23 +03:00
|
|
|
* TCP services without official port numbers are handled with the
|
|
|
|
* RFC1078-based tcpmux internal service. Tcpmux listens on port 1 for
|
|
|
|
* requests. When a connection is made from a foreign host, the service
|
|
|
|
* requested is passed to tcpmux, which looks it up in the servtab list
|
|
|
|
* and returns the proper entry for the service. Tcpmux returns a
|
|
|
|
* negative reply if the service doesn't exist, otherwise the invoked
|
|
|
|
* server is expected to return the positive reply if the service type in
|
|
|
|
* inetd.conf file has the prefix "tcpmux/". If the service type has the
|
|
|
|
* prefix "tcpmux/+", tcpmux will return the positive reply for the
|
|
|
|
* process; this is for compatibility with older server code, and also
|
|
|
|
* allows you to invoke programs that use stdin/stdout without putting any
|
|
|
|
* special server code in them. Services that use tcpmux are "nowait"
|
|
|
|
* because they do not have a well-known port and hence cannot listen
|
|
|
|
* for new requests.
|
|
|
|
*
|
1993-03-21 12:45:37 +03:00
|
|
|
* Comment lines are indicated by a `#' in column 1.
|
1999-07-02 08:48:19 +04:00
|
|
|
*
|
|
|
|
* #ifdef IPSEC
|
|
|
|
* Comment lines that start with "#@" denote IPsec policy string, as described
|
|
|
|
* in ipsec_set_policy(3). This will affect all the following items in
|
|
|
|
* inetd.conf(8). To reset the policy, just use "#@" line. By default,
|
|
|
|
* there's no IPsec policy.
|
|
|
|
* #endif
|
1993-03-21 12:45:37 +03:00
|
|
|
*/
|
1993-10-13 14:22:48 +03:00
|
|
|
|
|
|
|
/*
|
1999-10-07 01:54:10 +04:00
|
|
|
* Here's the scoop concerning the user:group feature:
|
1993-10-13 14:22:48 +03:00
|
|
|
*
|
|
|
|
* 1) set-group-option off.
|
1996-12-31 02:38:18 +03:00
|
|
|
*
|
1993-10-13 14:22:48 +03:00
|
|
|
* a) user = root: NO setuid() or setgid() is done
|
1996-12-31 02:38:18 +03:00
|
|
|
*
|
1993-10-13 14:22:48 +03:00
|
|
|
* b) other: setuid()
|
|
|
|
* setgid(primary group as found in passwd)
|
|
|
|
* initgroups(name, primary group)
|
1996-12-31 02:38:18 +03:00
|
|
|
*
|
1993-10-13 14:22:48 +03:00
|
|
|
* 2) set-group-option on.
|
1996-12-31 02:38:18 +03:00
|
|
|
*
|
1993-10-13 14:22:48 +03:00
|
|
|
* a) user = root: NO setuid()
|
|
|
|
* setgid(specified group)
|
|
|
|
* NO initgroups()
|
1996-12-31 02:38:18 +03:00
|
|
|
*
|
1993-10-13 14:22:48 +03:00
|
|
|
* b) other: setuid()
|
|
|
|
* setgid(specified group)
|
|
|
|
* initgroups(name, specified group)
|
1996-12-31 02:38:18 +03:00
|
|
|
*
|
1993-10-13 14:22:48 +03:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <sys/param.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <sys/ioctl.h>
|
|
|
|
#include <sys/wait.h>
|
|
|
|
#include <sys/resource.h>
|
2003-02-12 11:52:03 +03:00
|
|
|
#include <sys/event.h>
|
Inetd enhancements by James Browning, Gabe Coffland, Alex Gavin, Solomon Ritzow
Described in:
https://www.mail-archive.com/tech-userlevel@netbsd.org/msg03114.html
And developed in:
https://github.com/ritzow/src/pull/1
From their notes:
All new functionality should be explained by the updated manpage.
The manpage has been refactored a bit: A new section "Directives"
has been added and the information about default hostnames and
IPsec directives has been moved there, and the new file include
directive information is also there.
getconfigent has the most major changes. A newline is no longer
read immediately, but is called only by a "goto more" (inside an
if(false) block). This allows multiple definitions or directives
to exist on a single line for anything that doesn't terminate using
a newline. This means a key-values service definition can be followed
by another key-values service definition, a positional definition,
or an ipsec, hostname, or .include directive on the same line.
memset is no longer used explicitly to clear the servtab structure,
a function init_servtab() is used instead, which uses a C struct
initializer.
The servtab se_group field is its own allocation now, and not just
a pointer into the user:group string.
Refactored some stuff out of getconfigent to separate functions
for use by parse_v2.c. These functions in inetd.c are named with
the form parse_*()
parse_v2.c only has code for parsing a key-values service definition
into a provided servtab. It should not have anything that affects
global state other than line and line_number.
Some function prototypes, structures, and #defines have been moved
from inetd.c to inetd.h.
The function config_root replaces config as the function called on
a config file load/reload. The code removed from the end of
config(void) is now called in config_root, so it is not run on each
recursive config call.
setconfig(void) was removed and its code added into config_root
because that is the only place it is called, and redundant checks
for non-null globals were removed because they are always freed by
endconfig. The fseek code was also removed because the config files
are always closed by endconfig.
Rate limiting code was updated to add a per-service per-IP rate
limiting form. Some of that code was refactored out of other places
into functions with names in the form rl_*()
We have not added any of the license or version information to the
new files parse_v2.c, parse_v2.h, and inetd.h and we have not
updated the license or version info for inetd.c.
Security related:
The behavior when reading invalid IPsec strings has changed. Inetd
no longer exits, it quits reading the current config file instead.
Could this impact program security?
We have not checked for memory leaks. Solomon tried to use dmalloc
without success. getconfigent seemed to have a memory leak at each
"goto more". It seems like inetd has never free'd allocated strings
when throwing away erroneous service definitions during parsing
(i.e. when "goto more" is called when parsing fields). OpenBSD's
version calls freeconfig on "goto more"
(https://github.com/openbsd/src/blob/c5eae130d6c937080c3d30d124e8c8b86db7d625/usr.sbin/inetd/inetd.c#L1049)
but NetBSD only calls it when service definitions are no longer
needed. This has been fixed. freeconfig is called immediately before
any "goto more". There shouldn't be any time when a servtab is in
an invalid state where freeconfig would break.
2021-08-29 12:54:18 +03:00
|
|
|
#include <sys/socket.h>
|
2021-10-12 22:08:04 +03:00
|
|
|
#include <sys/queue.h>
|
Inetd enhancements by James Browning, Gabe Coffland, Alex Gavin, Solomon Ritzow
Described in:
https://www.mail-archive.com/tech-userlevel@netbsd.org/msg03114.html
And developed in:
https://github.com/ritzow/src/pull/1
From their notes:
All new functionality should be explained by the updated manpage.
The manpage has been refactored a bit: A new section "Directives"
has been added and the information about default hostnames and
IPsec directives has been moved there, and the new file include
directive information is also there.
getconfigent has the most major changes. A newline is no longer
read immediately, but is called only by a "goto more" (inside an
if(false) block). This allows multiple definitions or directives
to exist on a single line for anything that doesn't terminate using
a newline. This means a key-values service definition can be followed
by another key-values service definition, a positional definition,
or an ipsec, hostname, or .include directive on the same line.
memset is no longer used explicitly to clear the servtab structure,
a function init_servtab() is used instead, which uses a C struct
initializer.
The servtab se_group field is its own allocation now, and not just
a pointer into the user:group string.
Refactored some stuff out of getconfigent to separate functions
for use by parse_v2.c. These functions in inetd.c are named with
the form parse_*()
parse_v2.c only has code for parsing a key-values service definition
into a provided servtab. It should not have anything that affects
global state other than line and line_number.
Some function prototypes, structures, and #defines have been moved
from inetd.c to inetd.h.
The function config_root replaces config as the function called on
a config file load/reload. The code removed from the end of
config(void) is now called in config_root, so it is not run on each
recursive config call.
setconfig(void) was removed and its code added into config_root
because that is the only place it is called, and redundant checks
for non-null globals were removed because they are always freed by
endconfig. The fseek code was also removed because the config files
are always closed by endconfig.
Rate limiting code was updated to add a per-service per-IP rate
limiting form. Some of that code was refactored out of other places
into functions with names in the form rl_*()
We have not added any of the license or version information to the
new files parse_v2.c, parse_v2.h, and inetd.h and we have not
updated the license or version info for inetd.c.
Security related:
The behavior when reading invalid IPsec strings has changed. Inetd
no longer exits, it quits reading the current config file instead.
Could this impact program security?
We have not checked for memory leaks. Solomon tried to use dmalloc
without success. getconfigent seemed to have a memory leak at each
"goto more". It seems like inetd has never free'd allocated strings
when throwing away erroneous service definitions during parsing
(i.e. when "goto more" is called when parsing fields). OpenBSD's
version calls freeconfig on "goto more"
(https://github.com/openbsd/src/blob/c5eae130d6c937080c3d30d124e8c8b86db7d625/usr.sbin/inetd/inetd.c#L1049)
but NetBSD only calls it when service definitions are no longer
needed. This has been fixed. freeconfig is called immediately before
any "goto more". There shouldn't be any time when a servtab is in
an invalid state where freeconfig would break.
2021-08-29 12:54:18 +03:00
|
|
|
|
1993-10-13 14:22:48 +03:00
|
|
|
|
1999-08-02 05:12:21 +04:00
|
|
|
#ifndef NO_RPC
|
1993-10-13 14:22:48 +03:00
|
|
|
#define RPC
|
1999-08-02 05:12:21 +04:00
|
|
|
#endif
|
1993-10-13 14:22:48 +03:00
|
|
|
|
2002-06-05 14:03:31 +04:00
|
|
|
#include <net/if.h>
|
|
|
|
|
1997-03-13 20:22:23 +03:00
|
|
|
#ifdef RPC
|
|
|
|
#include <rpc/rpc.h>
|
2000-06-03 03:17:55 +04:00
|
|
|
#include <rpc/rpcb_clnt.h>
|
|
|
|
#include <netconfig.h>
|
1997-03-13 20:22:23 +03:00
|
|
|
#endif
|
1993-03-21 12:45:37 +03:00
|
|
|
|
1998-05-01 05:57:26 +04:00
|
|
|
#include <ctype.h>
|
Inetd enhancements by James Browning, Gabe Coffland, Alex Gavin, Solomon Ritzow
Described in:
https://www.mail-archive.com/tech-userlevel@netbsd.org/msg03114.html
And developed in:
https://github.com/ritzow/src/pull/1
From their notes:
All new functionality should be explained by the updated manpage.
The manpage has been refactored a bit: A new section "Directives"
has been added and the information about default hostnames and
IPsec directives has been moved there, and the new file include
directive information is also there.
getconfigent has the most major changes. A newline is no longer
read immediately, but is called only by a "goto more" (inside an
if(false) block). This allows multiple definitions or directives
to exist on a single line for anything that doesn't terminate using
a newline. This means a key-values service definition can be followed
by another key-values service definition, a positional definition,
or an ipsec, hostname, or .include directive on the same line.
memset is no longer used explicitly to clear the servtab structure,
a function init_servtab() is used instead, which uses a C struct
initializer.
The servtab se_group field is its own allocation now, and not just
a pointer into the user:group string.
Refactored some stuff out of getconfigent to separate functions
for use by parse_v2.c. These functions in inetd.c are named with
the form parse_*()
parse_v2.c only has code for parsing a key-values service definition
into a provided servtab. It should not have anything that affects
global state other than line and line_number.
Some function prototypes, structures, and #defines have been moved
from inetd.c to inetd.h.
The function config_root replaces config as the function called on
a config file load/reload. The code removed from the end of
config(void) is now called in config_root, so it is not run on each
recursive config call.
setconfig(void) was removed and its code added into config_root
because that is the only place it is called, and redundant checks
for non-null globals were removed because they are always freed by
endconfig. The fseek code was also removed because the config files
are always closed by endconfig.
Rate limiting code was updated to add a per-service per-IP rate
limiting form. Some of that code was refactored out of other places
into functions with names in the form rl_*()
We have not added any of the license or version information to the
new files parse_v2.c, parse_v2.h, and inetd.h and we have not
updated the license or version info for inetd.c.
Security related:
The behavior when reading invalid IPsec strings has changed. Inetd
no longer exits, it quits reading the current config file instead.
Could this impact program security?
We have not checked for memory leaks. Solomon tried to use dmalloc
without success. getconfigent seemed to have a memory leak at each
"goto more". It seems like inetd has never free'd allocated strings
when throwing away erroneous service definitions during parsing
(i.e. when "goto more" is called when parsing fields). OpenBSD's
version calls freeconfig on "goto more"
(https://github.com/openbsd/src/blob/c5eae130d6c937080c3d30d124e8c8b86db7d625/usr.sbin/inetd/inetd.c#L1049)
but NetBSD only calls it when service definitions are no longer
needed. This has been fixed. freeconfig is called immediately before
any "goto more". There shouldn't be any time when a servtab is in
an invalid state where freeconfig would break.
2021-08-29 12:54:18 +03:00
|
|
|
#include <err.h>
|
1993-03-21 12:45:37 +03:00
|
|
|
#include <errno.h>
|
1997-03-13 23:15:04 +03:00
|
|
|
#include <fcntl.h>
|
Inetd enhancements by James Browning, Gabe Coffland, Alex Gavin, Solomon Ritzow
Described in:
https://www.mail-archive.com/tech-userlevel@netbsd.org/msg03114.html
And developed in:
https://github.com/ritzow/src/pull/1
From their notes:
All new functionality should be explained by the updated manpage.
The manpage has been refactored a bit: A new section "Directives"
has been added and the information about default hostnames and
IPsec directives has been moved there, and the new file include
directive information is also there.
getconfigent has the most major changes. A newline is no longer
read immediately, but is called only by a "goto more" (inside an
if(false) block). This allows multiple definitions or directives
to exist on a single line for anything that doesn't terminate using
a newline. This means a key-values service definition can be followed
by another key-values service definition, a positional definition,
or an ipsec, hostname, or .include directive on the same line.
memset is no longer used explicitly to clear the servtab structure,
a function init_servtab() is used instead, which uses a C struct
initializer.
The servtab se_group field is its own allocation now, and not just
a pointer into the user:group string.
Refactored some stuff out of getconfigent to separate functions
for use by parse_v2.c. These functions in inetd.c are named with
the form parse_*()
parse_v2.c only has code for parsing a key-values service definition
into a provided servtab. It should not have anything that affects
global state other than line and line_number.
Some function prototypes, structures, and #defines have been moved
from inetd.c to inetd.h.
The function config_root replaces config as the function called on
a config file load/reload. The code removed from the end of
config(void) is now called in config_root, so it is not run on each
recursive config call.
setconfig(void) was removed and its code added into config_root
because that is the only place it is called, and redundant checks
for non-null globals were removed because they are always freed by
endconfig. The fseek code was also removed because the config files
are always closed by endconfig.
Rate limiting code was updated to add a per-service per-IP rate
limiting form. Some of that code was refactored out of other places
into functions with names in the form rl_*()
We have not added any of the license or version information to the
new files parse_v2.c, parse_v2.h, and inetd.h and we have not
updated the license or version info for inetd.c.
Security related:
The behavior when reading invalid IPsec strings has changed. Inetd
no longer exits, it quits reading the current config file instead.
Could this impact program security?
We have not checked for memory leaks. Solomon tried to use dmalloc
without success. getconfigent seemed to have a memory leak at each
"goto more". It seems like inetd has never free'd allocated strings
when throwing away erroneous service definitions during parsing
(i.e. when "goto more" is called when parsing fields). OpenBSD's
version calls freeconfig on "goto more"
(https://github.com/openbsd/src/blob/c5eae130d6c937080c3d30d124e8c8b86db7d625/usr.sbin/inetd/inetd.c#L1049)
but NetBSD only calls it when service definitions are no longer
needed. This has been fixed. freeconfig is called immediately before
any "goto more". There shouldn't be any time when a servtab is in
an invalid state where freeconfig would break.
2021-08-29 12:54:18 +03:00
|
|
|
#include <glob.h>
|
1997-03-13 20:22:23 +03:00
|
|
|
#include <grp.h>
|
Inetd enhancements by James Browning, Gabe Coffland, Alex Gavin, Solomon Ritzow
Described in:
https://www.mail-archive.com/tech-userlevel@netbsd.org/msg03114.html
And developed in:
https://github.com/ritzow/src/pull/1
From their notes:
All new functionality should be explained by the updated manpage.
The manpage has been refactored a bit: A new section "Directives"
has been added and the information about default hostnames and
IPsec directives has been moved there, and the new file include
directive information is also there.
getconfigent has the most major changes. A newline is no longer
read immediately, but is called only by a "goto more" (inside an
if(false) block). This allows multiple definitions or directives
to exist on a single line for anything that doesn't terminate using
a newline. This means a key-values service definition can be followed
by another key-values service definition, a positional definition,
or an ipsec, hostname, or .include directive on the same line.
memset is no longer used explicitly to clear the servtab structure,
a function init_servtab() is used instead, which uses a C struct
initializer.
The servtab se_group field is its own allocation now, and not just
a pointer into the user:group string.
Refactored some stuff out of getconfigent to separate functions
for use by parse_v2.c. These functions in inetd.c are named with
the form parse_*()
parse_v2.c only has code for parsing a key-values service definition
into a provided servtab. It should not have anything that affects
global state other than line and line_number.
Some function prototypes, structures, and #defines have been moved
from inetd.c to inetd.h.
The function config_root replaces config as the function called on
a config file load/reload. The code removed from the end of
config(void) is now called in config_root, so it is not run on each
recursive config call.
setconfig(void) was removed and its code added into config_root
because that is the only place it is called, and redundant checks
for non-null globals were removed because they are always freed by
endconfig. The fseek code was also removed because the config files
are always closed by endconfig.
Rate limiting code was updated to add a per-service per-IP rate
limiting form. Some of that code was refactored out of other places
into functions with names in the form rl_*()
We have not added any of the license or version information to the
new files parse_v2.c, parse_v2.h, and inetd.h and we have not
updated the license or version info for inetd.c.
Security related:
The behavior when reading invalid IPsec strings has changed. Inetd
no longer exits, it quits reading the current config file instead.
Could this impact program security?
We have not checked for memory leaks. Solomon tried to use dmalloc
without success. getconfigent seemed to have a memory leak at each
"goto more". It seems like inetd has never free'd allocated strings
when throwing away erroneous service definitions during parsing
(i.e. when "goto more" is called when parsing fields). OpenBSD's
version calls freeconfig on "goto more"
(https://github.com/openbsd/src/blob/c5eae130d6c937080c3d30d124e8c8b86db7d625/usr.sbin/inetd/inetd.c#L1049)
but NetBSD only calls it when service definitions are no longer
needed. This has been fixed. freeconfig is called immediately before
any "goto more". There shouldn't be any time when a servtab is in
an invalid state where freeconfig would break.
2021-08-29 12:54:18 +03:00
|
|
|
#include <libgen.h>
|
1993-03-21 12:45:37 +03:00
|
|
|
#include <pwd.h>
|
1997-03-13 20:22:23 +03:00
|
|
|
#include <signal.h>
|
1993-03-21 12:45:37 +03:00
|
|
|
#include <stdio.h>
|
1994-12-23 19:45:11 +03:00
|
|
|
#include <stdlib.h>
|
1993-03-21 12:45:37 +03:00
|
|
|
#include <string.h>
|
1997-03-13 20:22:23 +03:00
|
|
|
#include <syslog.h>
|
|
|
|
#include <unistd.h>
|
1999-06-06 05:50:23 +04:00
|
|
|
#include <util.h>
|
2002-06-05 14:03:31 +04:00
|
|
|
#include <ifaddrs.h>
|
1997-03-13 20:22:23 +03:00
|
|
|
|
Inetd enhancements by James Browning, Gabe Coffland, Alex Gavin, Solomon Ritzow
Described in:
https://www.mail-archive.com/tech-userlevel@netbsd.org/msg03114.html
And developed in:
https://github.com/ritzow/src/pull/1
From their notes:
All new functionality should be explained by the updated manpage.
The manpage has been refactored a bit: A new section "Directives"
has been added and the information about default hostnames and
IPsec directives has been moved there, and the new file include
directive information is also there.
getconfigent has the most major changes. A newline is no longer
read immediately, but is called only by a "goto more" (inside an
if(false) block). This allows multiple definitions or directives
to exist on a single line for anything that doesn't terminate using
a newline. This means a key-values service definition can be followed
by another key-values service definition, a positional definition,
or an ipsec, hostname, or .include directive on the same line.
memset is no longer used explicitly to clear the servtab structure,
a function init_servtab() is used instead, which uses a C struct
initializer.
The servtab se_group field is its own allocation now, and not just
a pointer into the user:group string.
Refactored some stuff out of getconfigent to separate functions
for use by parse_v2.c. These functions in inetd.c are named with
the form parse_*()
parse_v2.c only has code for parsing a key-values service definition
into a provided servtab. It should not have anything that affects
global state other than line and line_number.
Some function prototypes, structures, and #defines have been moved
from inetd.c to inetd.h.
The function config_root replaces config as the function called on
a config file load/reload. The code removed from the end of
config(void) is now called in config_root, so it is not run on each
recursive config call.
setconfig(void) was removed and its code added into config_root
because that is the only place it is called, and redundant checks
for non-null globals were removed because they are always freed by
endconfig. The fseek code was also removed because the config files
are always closed by endconfig.
Rate limiting code was updated to add a per-service per-IP rate
limiting form. Some of that code was refactored out of other places
into functions with names in the form rl_*()
We have not added any of the license or version information to the
new files parse_v2.c, parse_v2.h, and inetd.h and we have not
updated the license or version info for inetd.c.
Security related:
The behavior when reading invalid IPsec strings has changed. Inetd
no longer exits, it quits reading the current config file instead.
Could this impact program security?
We have not checked for memory leaks. Solomon tried to use dmalloc
without success. getconfigent seemed to have a memory leak at each
"goto more". It seems like inetd has never free'd allocated strings
when throwing away erroneous service definitions during parsing
(i.e. when "goto more" is called when parsing fields). OpenBSD's
version calls freeconfig on "goto more"
(https://github.com/openbsd/src/blob/c5eae130d6c937080c3d30d124e8c8b86db7d625/usr.sbin/inetd/inetd.c#L1049)
but NetBSD only calls it when service definitions are no longer
needed. This has been fixed. freeconfig is called immediately before
any "goto more". There shouldn't be any time when a servtab is in
an invalid state where freeconfig would break.
2021-08-29 12:54:18 +03:00
|
|
|
#include "inetd.h"
|
1999-07-02 08:48:19 +04:00
|
|
|
|
1996-11-26 20:23:34 +03:00
|
|
|
#ifdef LIBWRAP
|
|
|
|
# include <tcpd.h>
|
1996-12-04 16:37:18 +03:00
|
|
|
#ifndef LIBWRAP_ALLOW_FACILITY
|
1997-01-02 17:25:18 +03:00
|
|
|
# define LIBWRAP_ALLOW_FACILITY LOG_AUTH
|
1996-12-04 16:37:18 +03:00
|
|
|
#endif
|
|
|
|
#ifndef LIBWRAP_ALLOW_SEVERITY
|
|
|
|
# define LIBWRAP_ALLOW_SEVERITY LOG_INFO
|
|
|
|
#endif
|
|
|
|
#ifndef LIBWRAP_DENY_FACILITY
|
1997-01-02 17:25:18 +03:00
|
|
|
# define LIBWRAP_DENY_FACILITY LOG_AUTH
|
1996-12-04 16:37:18 +03:00
|
|
|
#endif
|
|
|
|
#ifndef LIBWRAP_DENY_SEVERITY
|
|
|
|
# define LIBWRAP_DENY_SEVERITY LOG_WARNING
|
|
|
|
#endif
|
|
|
|
int allow_severity = LIBWRAP_ALLOW_FACILITY|LIBWRAP_ALLOW_SEVERITY;
|
|
|
|
int deny_severity = LIBWRAP_DENY_FACILITY|LIBWRAP_DENY_SEVERITY;
|
1996-11-26 20:23:34 +03:00
|
|
|
#endif
|
|
|
|
|
2021-10-12 22:08:04 +03:00
|
|
|
static bool foreground;
|
1996-11-26 20:23:34 +03:00
|
|
|
int debug;
|
|
|
|
#ifdef LIBWRAP
|
|
|
|
int lflag;
|
|
|
|
#endif
|
2003-02-16 20:57:34 +03:00
|
|
|
int maxsock;
|
2003-02-12 11:52:03 +03:00
|
|
|
int kq;
|
1993-03-21 12:45:37 +03:00
|
|
|
int options;
|
|
|
|
int timingout;
|
2000-01-27 22:52:43 +03:00
|
|
|
const int niflags = NI_NUMERICHOST | NI_NUMERICSERV;
|
1993-10-13 14:22:48 +03:00
|
|
|
|
|
|
|
#ifndef OPEN_MAX
|
|
|
|
#define OPEN_MAX 64
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Reserve some descriptors, 3 stdio + at least: 1 log, 1 conf. file */
|
|
|
|
#define FD_MARGIN (8)
|
2000-07-24 02:54:51 +04:00
|
|
|
rlim_t rlim_ofile_cur = OPEN_MAX;
|
1993-10-13 14:22:48 +03:00
|
|
|
|
|
|
|
struct rlimit rlim_ofile;
|
1993-03-21 12:45:37 +03:00
|
|
|
|
2003-02-13 14:47:27 +03:00
|
|
|
struct kevent changebuf[64];
|
|
|
|
size_t changes;
|
|
|
|
|
Inetd enhancements by James Browning, Gabe Coffland, Alex Gavin, Solomon Ritzow
Described in:
https://www.mail-archive.com/tech-userlevel@netbsd.org/msg03114.html
And developed in:
https://github.com/ritzow/src/pull/1
From their notes:
All new functionality should be explained by the updated manpage.
The manpage has been refactored a bit: A new section "Directives"
has been added and the information about default hostnames and
IPsec directives has been moved there, and the new file include
directive information is also there.
getconfigent has the most major changes. A newline is no longer
read immediately, but is called only by a "goto more" (inside an
if(false) block). This allows multiple definitions or directives
to exist on a single line for anything that doesn't terminate using
a newline. This means a key-values service definition can be followed
by another key-values service definition, a positional definition,
or an ipsec, hostname, or .include directive on the same line.
memset is no longer used explicitly to clear the servtab structure,
a function init_servtab() is used instead, which uses a C struct
initializer.
The servtab se_group field is its own allocation now, and not just
a pointer into the user:group string.
Refactored some stuff out of getconfigent to separate functions
for use by parse_v2.c. These functions in inetd.c are named with
the form parse_*()
parse_v2.c only has code for parsing a key-values service definition
into a provided servtab. It should not have anything that affects
global state other than line and line_number.
Some function prototypes, structures, and #defines have been moved
from inetd.c to inetd.h.
The function config_root replaces config as the function called on
a config file load/reload. The code removed from the end of
config(void) is now called in config_root, so it is not run on each
recursive config call.
setconfig(void) was removed and its code added into config_root
because that is the only place it is called, and redundant checks
for non-null globals were removed because they are always freed by
endconfig. The fseek code was also removed because the config files
are always closed by endconfig.
Rate limiting code was updated to add a per-service per-IP rate
limiting form. Some of that code was refactored out of other places
into functions with names in the form rl_*()
We have not added any of the license or version information to the
new files parse_v2.c, parse_v2.h, and inetd.h and we have not
updated the license or version info for inetd.c.
Security related:
The behavior when reading invalid IPsec strings has changed. Inetd
no longer exits, it quits reading the current config file instead.
Could this impact program security?
We have not checked for memory leaks. Solomon tried to use dmalloc
without success. getconfigent seemed to have a memory leak at each
"goto more". It seems like inetd has never free'd allocated strings
when throwing away erroneous service definitions during parsing
(i.e. when "goto more" is called when parsing fields). OpenBSD's
version calls freeconfig on "goto more"
(https://github.com/openbsd/src/blob/c5eae130d6c937080c3d30d124e8c8b86db7d625/usr.sbin/inetd/inetd.c#L1049)
but NetBSD only calls it when service definitions are no longer
needed. This has been fixed. freeconfig is called immediately before
any "goto more". There shouldn't be any time when a servtab is in
an invalid state where freeconfig would break.
2021-08-29 12:54:18 +03:00
|
|
|
struct servtab *servtab;
|
1997-03-13 20:22:23 +03:00
|
|
|
|
2003-02-13 14:47:27 +03:00
|
|
|
static void chargen_dg(int, struct servtab *);
|
|
|
|
static void chargen_stream(int, struct servtab *);
|
|
|
|
static void daytime_dg(int, struct servtab *);
|
|
|
|
static void daytime_stream(int, struct servtab *);
|
|
|
|
static void discard_dg(int, struct servtab *);
|
|
|
|
static void discard_stream(int, struct servtab *);
|
|
|
|
static void echo_dg(int, struct servtab *);
|
|
|
|
static void echo_stream(int, struct servtab *);
|
2011-08-31 17:32:36 +04:00
|
|
|
__dead static void goaway(void);
|
2003-02-13 14:47:27 +03:00
|
|
|
static void machtime_dg(int, struct servtab *);
|
|
|
|
static void machtime_stream(int, struct servtab *);
|
|
|
|
static void reapchild(void);
|
|
|
|
static void retry(void);
|
2008-05-26 07:41:25 +04:00
|
|
|
static void run_service(int, struct servtab *, int);
|
2003-02-13 14:47:27 +03:00
|
|
|
static void tcpmux(int, struct servtab *);
|
2011-08-31 17:32:36 +04:00
|
|
|
__dead static void usage(void);
|
2003-02-13 14:47:27 +03:00
|
|
|
static void bump_nofile(void);
|
|
|
|
static void inetd_setproctitle(char *, int);
|
|
|
|
static void initring(void);
|
|
|
|
static uint32_t machtime(void);
|
|
|
|
static int port_good_dg(struct sockaddr *);
|
Inetd enhancements by James Browning, Gabe Coffland, Alex Gavin, Solomon Ritzow
Described in:
https://www.mail-archive.com/tech-userlevel@netbsd.org/msg03114.html
And developed in:
https://github.com/ritzow/src/pull/1
From their notes:
All new functionality should be explained by the updated manpage.
The manpage has been refactored a bit: A new section "Directives"
has been added and the information about default hostnames and
IPsec directives has been moved there, and the new file include
directive information is also there.
getconfigent has the most major changes. A newline is no longer
read immediately, but is called only by a "goto more" (inside an
if(false) block). This allows multiple definitions or directives
to exist on a single line for anything that doesn't terminate using
a newline. This means a key-values service definition can be followed
by another key-values service definition, a positional definition,
or an ipsec, hostname, or .include directive on the same line.
memset is no longer used explicitly to clear the servtab structure,
a function init_servtab() is used instead, which uses a C struct
initializer.
The servtab se_group field is its own allocation now, and not just
a pointer into the user:group string.
Refactored some stuff out of getconfigent to separate functions
for use by parse_v2.c. These functions in inetd.c are named with
the form parse_*()
parse_v2.c only has code for parsing a key-values service definition
into a provided servtab. It should not have anything that affects
global state other than line and line_number.
Some function prototypes, structures, and #defines have been moved
from inetd.c to inetd.h.
The function config_root replaces config as the function called on
a config file load/reload. The code removed from the end of
config(void) is now called in config_root, so it is not run on each
recursive config call.
setconfig(void) was removed and its code added into config_root
because that is the only place it is called, and redundant checks
for non-null globals were removed because they are always freed by
endconfig. The fseek code was also removed because the config files
are always closed by endconfig.
Rate limiting code was updated to add a per-service per-IP rate
limiting form. Some of that code was refactored out of other places
into functions with names in the form rl_*()
We have not added any of the license or version information to the
new files parse_v2.c, parse_v2.h, and inetd.h and we have not
updated the license or version info for inetd.c.
Security related:
The behavior when reading invalid IPsec strings has changed. Inetd
no longer exits, it quits reading the current config file instead.
Could this impact program security?
We have not checked for memory leaks. Solomon tried to use dmalloc
without success. getconfigent seemed to have a memory leak at each
"goto more". It seems like inetd has never free'd allocated strings
when throwing away erroneous service definitions during parsing
(i.e. when "goto more" is called when parsing fields). OpenBSD's
version calls freeconfig on "goto more"
(https://github.com/openbsd/src/blob/c5eae130d6c937080c3d30d124e8c8b86db7d625/usr.sbin/inetd/inetd.c#L1049)
but NetBSD only calls it when service definitions are no longer
needed. This has been fixed. freeconfig is called immediately before
any "goto more". There shouldn't be any time when a servtab is in
an invalid state where freeconfig would break.
2021-08-29 12:54:18 +03:00
|
|
|
static int dg_broadcast(struct in_addr *);
|
|
|
|
static int my_kevent(const struct kevent *, size_t, struct kevent *, size_t);
|
|
|
|
static struct kevent *allocchange(void);
|
2009-07-13 23:05:39 +04:00
|
|
|
static int get_line(int, char *, int);
|
2003-02-13 14:47:27 +03:00
|
|
|
static void spawn(struct servtab *, int);
|
1993-03-21 12:45:37 +03:00
|
|
|
|
|
|
|
struct biltin {
|
2009-01-09 00:37:20 +03:00
|
|
|
const char *bi_service; /* internally provided service name */
|
1993-03-21 12:45:37 +03:00
|
|
|
int bi_socktype; /* type of socket supported */
|
|
|
|
short bi_fork; /* 1 if should fork before call */
|
|
|
|
short bi_wait; /* 1 if should wait for child */
|
2003-02-12 13:03:47 +03:00
|
|
|
void (*bi_fn)(int, struct servtab *);
|
1997-10-05 20:40:24 +04:00
|
|
|
/* function which performs it */
|
1993-03-21 12:45:37 +03:00
|
|
|
} biltins[] = {
|
|
|
|
/* Echo received data */
|
2021-09-03 23:24:28 +03:00
|
|
|
{ "echo", SOCK_STREAM, true, false, echo_stream },
|
|
|
|
{ "echo", SOCK_DGRAM, false, false, echo_dg },
|
1993-03-21 12:45:37 +03:00
|
|
|
|
|
|
|
/* Internet /dev/null */
|
2021-09-03 23:24:28 +03:00
|
|
|
{ "discard", SOCK_STREAM, true, false, discard_stream },
|
|
|
|
{ "discard", SOCK_DGRAM, false, false, discard_dg },
|
1993-03-21 12:45:37 +03:00
|
|
|
|
1997-10-05 20:16:10 +04:00
|
|
|
/* Return 32 bit time since 1970 */
|
2021-09-03 23:24:28 +03:00
|
|
|
{ "time", SOCK_STREAM, false, false, machtime_stream },
|
|
|
|
{ "time", SOCK_DGRAM, false, false, machtime_dg },
|
1993-03-21 12:45:37 +03:00
|
|
|
|
|
|
|
/* Return human-readable time */
|
2021-09-03 23:24:28 +03:00
|
|
|
{ "daytime", SOCK_STREAM, false, false, daytime_stream },
|
|
|
|
{ "daytime", SOCK_DGRAM, false, false, daytime_dg },
|
1993-03-21 12:45:37 +03:00
|
|
|
|
|
|
|
/* Familiar character generator */
|
2021-09-03 23:24:28 +03:00
|
|
|
{ "chargen", SOCK_STREAM, true, false, chargen_stream },
|
|
|
|
{ "chargen", SOCK_DGRAM, false, false, chargen_dg },
|
1997-03-13 20:22:23 +03:00
|
|
|
|
2021-10-12 22:08:04 +03:00
|
|
|
{ "tcpmux", SOCK_STREAM, true, false, tcpmux }
|
1993-03-21 12:45:37 +03:00
|
|
|
};
|
|
|
|
|
1999-04-11 19:40:58 +04:00
|
|
|
/* list of "bad" ports. I.e. ports that are most obviously used for
|
|
|
|
* "cycling packets" denial of service attacks. See /etc/services.
|
|
|
|
* List must end with port number "0".
|
|
|
|
*/
|
|
|
|
|
2002-06-01 04:28:52 +04:00
|
|
|
u_int16_t bad_ports[] = { 7, 9, 13, 19, 37, 0 };
|
1999-04-11 19:40:58 +04:00
|
|
|
|
|
|
|
|
1993-03-21 12:45:37 +03:00
|
|
|
#define NUMINT (sizeof(intab) / sizeof(struct inent))
|
2009-01-09 00:37:20 +03:00
|
|
|
const char *CONFIG = _PATH_INETDCONF;
|
1993-10-13 14:22:48 +03:00
|
|
|
|
2003-02-16 20:57:34 +03:00
|
|
|
static int my_signals[] =
|
|
|
|
{ SIGALRM, SIGHUP, SIGCHLD, SIGTERM, SIGINT, SIGPIPE };
|
2003-02-13 14:47:27 +03:00
|
|
|
|
1997-10-05 20:40:24 +04:00
|
|
|
int
|
2003-02-13 14:47:27 +03:00
|
|
|
main(int argc, char *argv[])
|
1993-03-21 12:45:37 +03:00
|
|
|
{
|
2003-02-13 14:47:27 +03:00
|
|
|
int ch, n, reload = 1;
|
1993-03-21 12:45:37 +03:00
|
|
|
|
1996-11-26 20:23:34 +03:00
|
|
|
while ((ch = getopt(argc, argv,
|
|
|
|
#ifdef LIBWRAP
|
2021-10-12 22:08:04 +03:00
|
|
|
"dfl"
|
1996-11-26 20:23:34 +03:00
|
|
|
#else
|
2021-10-12 22:08:04 +03:00
|
|
|
"df"
|
1996-11-26 20:23:34 +03:00
|
|
|
#endif
|
1997-10-17 17:53:30 +04:00
|
|
|
)) != -1)
|
1993-03-21 12:45:37 +03:00
|
|
|
switch(ch) {
|
|
|
|
case 'd':
|
2021-10-12 22:08:04 +03:00
|
|
|
foreground = true;
|
2021-09-03 23:24:28 +03:00
|
|
|
debug = true;
|
1993-03-21 12:45:37 +03:00
|
|
|
options |= SO_DEBUG;
|
|
|
|
break;
|
2021-10-12 22:08:04 +03:00
|
|
|
case 'f':
|
|
|
|
foreground = true;
|
|
|
|
break;
|
1996-11-26 20:23:34 +03:00
|
|
|
#ifdef LIBWRAP
|
|
|
|
case 'l':
|
2021-09-03 23:24:28 +03:00
|
|
|
lflag = true;
|
1996-11-26 20:23:34 +03:00
|
|
|
break;
|
|
|
|
#endif
|
1993-03-21 12:45:37 +03:00
|
|
|
case '?':
|
|
|
|
default:
|
1997-03-13 20:22:23 +03:00
|
|
|
usage();
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
|
|
|
argc -= optind;
|
|
|
|
argv += optind;
|
|
|
|
|
|
|
|
if (argc > 0)
|
|
|
|
CONFIG = argv[0];
|
1993-10-13 14:22:48 +03:00
|
|
|
|
2021-10-12 22:08:04 +03:00
|
|
|
if (!foreground)
|
1993-03-21 12:45:37 +03:00
|
|
|
daemon(0, 0);
|
2001-01-11 04:34:28 +03:00
|
|
|
openlog("inetd", LOG_PID | LOG_NOWAIT, LOG_DAEMON);
|
1999-06-06 05:50:23 +04:00
|
|
|
pidfile(NULL);
|
1993-10-13 14:22:48 +03:00
|
|
|
|
2003-02-12 11:52:03 +03:00
|
|
|
kq = kqueue();
|
|
|
|
if (kq < 0) {
|
|
|
|
syslog(LOG_ERR, "kqueue: %m");
|
|
|
|
return (EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
|
1993-12-15 00:31:53 +03:00
|
|
|
if (getrlimit(RLIMIT_NOFILE, &rlim_ofile) < 0) {
|
1993-10-13 14:22:48 +03:00
|
|
|
syslog(LOG_ERR, "getrlimit: %m");
|
|
|
|
} else {
|
|
|
|
rlim_ofile_cur = rlim_ofile.rlim_cur;
|
1993-12-15 00:31:53 +03:00
|
|
|
if (rlim_ofile_cur == RLIM_INFINITY) /* ! */
|
|
|
|
rlim_ofile_cur = OPEN_MAX;
|
1993-10-13 14:22:48 +03:00
|
|
|
}
|
|
|
|
|
Inetd enhancements by James Browning, Gabe Coffland, Alex Gavin, Solomon Ritzow
Described in:
https://www.mail-archive.com/tech-userlevel@netbsd.org/msg03114.html
And developed in:
https://github.com/ritzow/src/pull/1
From their notes:
All new functionality should be explained by the updated manpage.
The manpage has been refactored a bit: A new section "Directives"
has been added and the information about default hostnames and
IPsec directives has been moved there, and the new file include
directive information is also there.
getconfigent has the most major changes. A newline is no longer
read immediately, but is called only by a "goto more" (inside an
if(false) block). This allows multiple definitions or directives
to exist on a single line for anything that doesn't terminate using
a newline. This means a key-values service definition can be followed
by another key-values service definition, a positional definition,
or an ipsec, hostname, or .include directive on the same line.
memset is no longer used explicitly to clear the servtab structure,
a function init_servtab() is used instead, which uses a C struct
initializer.
The servtab se_group field is its own allocation now, and not just
a pointer into the user:group string.
Refactored some stuff out of getconfigent to separate functions
for use by parse_v2.c. These functions in inetd.c are named with
the form parse_*()
parse_v2.c only has code for parsing a key-values service definition
into a provided servtab. It should not have anything that affects
global state other than line and line_number.
Some function prototypes, structures, and #defines have been moved
from inetd.c to inetd.h.
The function config_root replaces config as the function called on
a config file load/reload. The code removed from the end of
config(void) is now called in config_root, so it is not run on each
recursive config call.
setconfig(void) was removed and its code added into config_root
because that is the only place it is called, and redundant checks
for non-null globals were removed because they are always freed by
endconfig. The fseek code was also removed because the config files
are always closed by endconfig.
Rate limiting code was updated to add a per-service per-IP rate
limiting form. Some of that code was refactored out of other places
into functions with names in the form rl_*()
We have not added any of the license or version information to the
new files parse_v2.c, parse_v2.h, and inetd.h and we have not
updated the license or version info for inetd.c.
Security related:
The behavior when reading invalid IPsec strings has changed. Inetd
no longer exits, it quits reading the current config file instead.
Could this impact program security?
We have not checked for memory leaks. Solomon tried to use dmalloc
without success. getconfigent seemed to have a memory leak at each
"goto more". It seems like inetd has never free'd allocated strings
when throwing away erroneous service definitions during parsing
(i.e. when "goto more" is called when parsing fields). OpenBSD's
version calls freeconfig on "goto more"
(https://github.com/openbsd/src/blob/c5eae130d6c937080c3d30d124e8c8b86db7d625/usr.sbin/inetd/inetd.c#L1049)
but NetBSD only calls it when service definitions are no longer
needed. This has been fixed. freeconfig is called immediately before
any "goto more". There shouldn't be any time when a servtab is in
an invalid state where freeconfig would break.
2021-08-29 12:54:18 +03:00
|
|
|
for (n = 0; n < (int)__arraycount(my_signals); n++) {
|
2003-02-16 20:57:34 +03:00
|
|
|
int signum;
|
|
|
|
|
|
|
|
signum = my_signals[n];
|
2005-04-10 00:14:55 +04:00
|
|
|
if (signum != SIGCHLD)
|
|
|
|
(void) signal(signum, SIG_IGN);
|
2003-02-16 20:57:34 +03:00
|
|
|
|
|
|
|
if (signum != SIGPIPE) {
|
|
|
|
struct kevent *ev;
|
|
|
|
|
|
|
|
ev = allocchange();
|
|
|
|
EV_SET(ev, signum, EVFILT_SIGNAL, EV_ADD | EV_ENABLE,
|
2003-10-21 06:43:37 +04:00
|
|
|
0, 0, 0);
|
2003-02-16 20:57:34 +03:00
|
|
|
}
|
2003-02-13 14:47:27 +03:00
|
|
|
}
|
1993-03-21 12:45:37 +03:00
|
|
|
|
|
|
|
for (;;) {
|
2003-02-13 14:47:27 +03:00
|
|
|
int ctrl;
|
2003-02-16 20:57:34 +03:00
|
|
|
struct kevent eventbuf[64], *ev;
|
2003-02-13 14:47:27 +03:00
|
|
|
struct servtab *sep;
|
|
|
|
|
|
|
|
if (reload) {
|
2021-09-03 23:24:28 +03:00
|
|
|
reload = false;
|
Inetd enhancements by James Browning, Gabe Coffland, Alex Gavin, Solomon Ritzow
Described in:
https://www.mail-archive.com/tech-userlevel@netbsd.org/msg03114.html
And developed in:
https://github.com/ritzow/src/pull/1
From their notes:
All new functionality should be explained by the updated manpage.
The manpage has been refactored a bit: A new section "Directives"
has been added and the information about default hostnames and
IPsec directives has been moved there, and the new file include
directive information is also there.
getconfigent has the most major changes. A newline is no longer
read immediately, but is called only by a "goto more" (inside an
if(false) block). This allows multiple definitions or directives
to exist on a single line for anything that doesn't terminate using
a newline. This means a key-values service definition can be followed
by another key-values service definition, a positional definition,
or an ipsec, hostname, or .include directive on the same line.
memset is no longer used explicitly to clear the servtab structure,
a function init_servtab() is used instead, which uses a C struct
initializer.
The servtab se_group field is its own allocation now, and not just
a pointer into the user:group string.
Refactored some stuff out of getconfigent to separate functions
for use by parse_v2.c. These functions in inetd.c are named with
the form parse_*()
parse_v2.c only has code for parsing a key-values service definition
into a provided servtab. It should not have anything that affects
global state other than line and line_number.
Some function prototypes, structures, and #defines have been moved
from inetd.c to inetd.h.
The function config_root replaces config as the function called on
a config file load/reload. The code removed from the end of
config(void) is now called in config_root, so it is not run on each
recursive config call.
setconfig(void) was removed and its code added into config_root
because that is the only place it is called, and redundant checks
for non-null globals were removed because they are always freed by
endconfig. The fseek code was also removed because the config files
are always closed by endconfig.
Rate limiting code was updated to add a per-service per-IP rate
limiting form. Some of that code was refactored out of other places
into functions with names in the form rl_*()
We have not added any of the license or version information to the
new files parse_v2.c, parse_v2.h, and inetd.h and we have not
updated the license or version info for inetd.c.
Security related:
The behavior when reading invalid IPsec strings has changed. Inetd
no longer exits, it quits reading the current config file instead.
Could this impact program security?
We have not checked for memory leaks. Solomon tried to use dmalloc
without success. getconfigent seemed to have a memory leak at each
"goto more". It seems like inetd has never free'd allocated strings
when throwing away erroneous service definitions during parsing
(i.e. when "goto more" is called when parsing fields). OpenBSD's
version calls freeconfig on "goto more"
(https://github.com/openbsd/src/blob/c5eae130d6c937080c3d30d124e8c8b86db7d625/usr.sbin/inetd/inetd.c#L1049)
but NetBSD only calls it when service definitions are no longer
needed. This has been fixed. freeconfig is called immediately before
any "goto more". There shouldn't be any time when a servtab is in
an invalid state where freeconfig would break.
2021-08-29 12:54:18 +03:00
|
|
|
config_root();
|
2003-02-13 14:47:27 +03:00
|
|
|
}
|
2002-06-01 04:28:52 +04:00
|
|
|
|
Inetd enhancements by James Browning, Gabe Coffland, Alex Gavin, Solomon Ritzow
Described in:
https://www.mail-archive.com/tech-userlevel@netbsd.org/msg03114.html
And developed in:
https://github.com/ritzow/src/pull/1
From their notes:
All new functionality should be explained by the updated manpage.
The manpage has been refactored a bit: A new section "Directives"
has been added and the information about default hostnames and
IPsec directives has been moved there, and the new file include
directive information is also there.
getconfigent has the most major changes. A newline is no longer
read immediately, but is called only by a "goto more" (inside an
if(false) block). This allows multiple definitions or directives
to exist on a single line for anything that doesn't terminate using
a newline. This means a key-values service definition can be followed
by another key-values service definition, a positional definition,
or an ipsec, hostname, or .include directive on the same line.
memset is no longer used explicitly to clear the servtab structure,
a function init_servtab() is used instead, which uses a C struct
initializer.
The servtab se_group field is its own allocation now, and not just
a pointer into the user:group string.
Refactored some stuff out of getconfigent to separate functions
for use by parse_v2.c. These functions in inetd.c are named with
the form parse_*()
parse_v2.c only has code for parsing a key-values service definition
into a provided servtab. It should not have anything that affects
global state other than line and line_number.
Some function prototypes, structures, and #defines have been moved
from inetd.c to inetd.h.
The function config_root replaces config as the function called on
a config file load/reload. The code removed from the end of
config(void) is now called in config_root, so it is not run on each
recursive config call.
setconfig(void) was removed and its code added into config_root
because that is the only place it is called, and redundant checks
for non-null globals were removed because they are always freed by
endconfig. The fseek code was also removed because the config files
are always closed by endconfig.
Rate limiting code was updated to add a per-service per-IP rate
limiting form. Some of that code was refactored out of other places
into functions with names in the form rl_*()
We have not added any of the license or version information to the
new files parse_v2.c, parse_v2.h, and inetd.h and we have not
updated the license or version info for inetd.c.
Security related:
The behavior when reading invalid IPsec strings has changed. Inetd
no longer exits, it quits reading the current config file instead.
Could this impact program security?
We have not checked for memory leaks. Solomon tried to use dmalloc
without success. getconfigent seemed to have a memory leak at each
"goto more". It seems like inetd has never free'd allocated strings
when throwing away erroneous service definitions during parsing
(i.e. when "goto more" is called when parsing fields). OpenBSD's
version calls freeconfig on "goto more"
(https://github.com/openbsd/src/blob/c5eae130d6c937080c3d30d124e8c8b86db7d625/usr.sbin/inetd/inetd.c#L1049)
but NetBSD only calls it when service definitions are no longer
needed. This has been fixed. freeconfig is called immediately before
any "goto more". There shouldn't be any time when a servtab is in
an invalid state where freeconfig would break.
2021-08-29 12:54:18 +03:00
|
|
|
n = my_kevent(changebuf, changes, eventbuf, __arraycount(eventbuf));
|
2003-02-13 14:47:27 +03:00
|
|
|
changes = 0;
|
|
|
|
|
|
|
|
for (ev = eventbuf; n > 0; ev++, n--) {
|
|
|
|
if (ev->filter == EVFILT_SIGNAL) {
|
|
|
|
switch (ev->ident) {
|
|
|
|
case SIGALRM:
|
|
|
|
retry();
|
|
|
|
break;
|
|
|
|
case SIGCHLD:
|
|
|
|
reapchild();
|
|
|
|
break;
|
|
|
|
case SIGTERM:
|
|
|
|
case SIGINT:
|
|
|
|
goaway();
|
|
|
|
break;
|
|
|
|
case SIGHUP:
|
2021-09-03 23:24:28 +03:00
|
|
|
reload = true;
|
2003-02-13 14:47:27 +03:00
|
|
|
break;
|
|
|
|
}
|
2003-02-12 11:52:03 +03:00
|
|
|
continue;
|
2003-02-13 14:47:27 +03:00
|
|
|
}
|
|
|
|
if (ev->filter != EVFILT_READ)
|
|
|
|
continue;
|
|
|
|
sep = (struct servtab *)ev->udata;
|
2003-02-12 11:52:03 +03:00
|
|
|
/* Paranoia */
|
2007-01-02 19:00:46 +03:00
|
|
|
if ((int)ev->ident != sep->se_fd)
|
2002-06-01 04:28:52 +04:00
|
|
|
continue;
|
Inetd enhancements by James Browning, Gabe Coffland, Alex Gavin, Solomon Ritzow
Described in:
https://www.mail-archive.com/tech-userlevel@netbsd.org/msg03114.html
And developed in:
https://github.com/ritzow/src/pull/1
From their notes:
All new functionality should be explained by the updated manpage.
The manpage has been refactored a bit: A new section "Directives"
has been added and the information about default hostnames and
IPsec directives has been moved there, and the new file include
directive information is also there.
getconfigent has the most major changes. A newline is no longer
read immediately, but is called only by a "goto more" (inside an
if(false) block). This allows multiple definitions or directives
to exist on a single line for anything that doesn't terminate using
a newline. This means a key-values service definition can be followed
by another key-values service definition, a positional definition,
or an ipsec, hostname, or .include directive on the same line.
memset is no longer used explicitly to clear the servtab structure,
a function init_servtab() is used instead, which uses a C struct
initializer.
The servtab se_group field is its own allocation now, and not just
a pointer into the user:group string.
Refactored some stuff out of getconfigent to separate functions
for use by parse_v2.c. These functions in inetd.c are named with
the form parse_*()
parse_v2.c only has code for parsing a key-values service definition
into a provided servtab. It should not have anything that affects
global state other than line and line_number.
Some function prototypes, structures, and #defines have been moved
from inetd.c to inetd.h.
The function config_root replaces config as the function called on
a config file load/reload. The code removed from the end of
config(void) is now called in config_root, so it is not run on each
recursive config call.
setconfig(void) was removed and its code added into config_root
because that is the only place it is called, and redundant checks
for non-null globals were removed because they are always freed by
endconfig. The fseek code was also removed because the config files
are always closed by endconfig.
Rate limiting code was updated to add a per-service per-IP rate
limiting form. Some of that code was refactored out of other places
into functions with names in the form rl_*()
We have not added any of the license or version information to the
new files parse_v2.c, parse_v2.h, and inetd.h and we have not
updated the license or version info for inetd.c.
Security related:
The behavior when reading invalid IPsec strings has changed. Inetd
no longer exits, it quits reading the current config file instead.
Could this impact program security?
We have not checked for memory leaks. Solomon tried to use dmalloc
without success. getconfigent seemed to have a memory leak at each
"goto more". It seems like inetd has never free'd allocated strings
when throwing away erroneous service definitions during parsing
(i.e. when "goto more" is called when parsing fields). OpenBSD's
version calls freeconfig on "goto more"
(https://github.com/openbsd/src/blob/c5eae130d6c937080c3d30d124e8c8b86db7d625/usr.sbin/inetd/inetd.c#L1049)
but NetBSD only calls it when service definitions are no longer
needed. This has been fixed. freeconfig is called immediately before
any "goto more". There shouldn't be any time when a servtab is in
an invalid state where freeconfig would break.
2021-08-29 12:54:18 +03:00
|
|
|
DPRINTF(SERV_FMT ": service requested" , SERV_PARAMS(sep));
|
2021-09-03 23:24:28 +03:00
|
|
|
if (sep->se_wait == 0 && sep->se_socktype == SOCK_STREAM) {
|
2004-09-14 21:42:31 +04:00
|
|
|
/* XXX here do the libwrap check-before-accept*/
|
2003-02-12 11:52:03 +03:00
|
|
|
ctrl = accept(sep->se_fd, NULL, NULL);
|
2021-08-30 20:32:23 +03:00
|
|
|
DPRINTF(SERV_FMT ": accept, ctrl fd %d",
|
Inetd enhancements by James Browning, Gabe Coffland, Alex Gavin, Solomon Ritzow
Described in:
https://www.mail-archive.com/tech-userlevel@netbsd.org/msg03114.html
And developed in:
https://github.com/ritzow/src/pull/1
From their notes:
All new functionality should be explained by the updated manpage.
The manpage has been refactored a bit: A new section "Directives"
has been added and the information about default hostnames and
IPsec directives has been moved there, and the new file include
directive information is also there.
getconfigent has the most major changes. A newline is no longer
read immediately, but is called only by a "goto more" (inside an
if(false) block). This allows multiple definitions or directives
to exist on a single line for anything that doesn't terminate using
a newline. This means a key-values service definition can be followed
by another key-values service definition, a positional definition,
or an ipsec, hostname, or .include directive on the same line.
memset is no longer used explicitly to clear the servtab structure,
a function init_servtab() is used instead, which uses a C struct
initializer.
The servtab se_group field is its own allocation now, and not just
a pointer into the user:group string.
Refactored some stuff out of getconfigent to separate functions
for use by parse_v2.c. These functions in inetd.c are named with
the form parse_*()
parse_v2.c only has code for parsing a key-values service definition
into a provided servtab. It should not have anything that affects
global state other than line and line_number.
Some function prototypes, structures, and #defines have been moved
from inetd.c to inetd.h.
The function config_root replaces config as the function called on
a config file load/reload. The code removed from the end of
config(void) is now called in config_root, so it is not run on each
recursive config call.
setconfig(void) was removed and its code added into config_root
because that is the only place it is called, and redundant checks
for non-null globals were removed because they are always freed by
endconfig. The fseek code was also removed because the config files
are always closed by endconfig.
Rate limiting code was updated to add a per-service per-IP rate
limiting form. Some of that code was refactored out of other places
into functions with names in the form rl_*()
We have not added any of the license or version information to the
new files parse_v2.c, parse_v2.h, and inetd.h and we have not
updated the license or version info for inetd.c.
Security related:
The behavior when reading invalid IPsec strings has changed. Inetd
no longer exits, it quits reading the current config file instead.
Could this impact program security?
We have not checked for memory leaks. Solomon tried to use dmalloc
without success. getconfigent seemed to have a memory leak at each
"goto more". It seems like inetd has never free'd allocated strings
when throwing away erroneous service definitions during parsing
(i.e. when "goto more" is called when parsing fields). OpenBSD's
version calls freeconfig on "goto more"
(https://github.com/openbsd/src/blob/c5eae130d6c937080c3d30d124e8c8b86db7d625/usr.sbin/inetd/inetd.c#L1049)
but NetBSD only calls it when service definitions are no longer
needed. This has been fixed. freeconfig is called immediately before
any "goto more". There shouldn't be any time when a servtab is in
an invalid state where freeconfig would break.
2021-08-29 12:54:18 +03:00
|
|
|
SERV_PARAMS(sep), ctrl);
|
2002-06-01 04:28:52 +04:00
|
|
|
if (ctrl < 0) {
|
|
|
|
if (errno != EINTR)
|
|
|
|
syslog(LOG_WARNING,
|
Inetd enhancements by James Browning, Gabe Coffland, Alex Gavin, Solomon Ritzow
Described in:
https://www.mail-archive.com/tech-userlevel@netbsd.org/msg03114.html
And developed in:
https://github.com/ritzow/src/pull/1
From their notes:
All new functionality should be explained by the updated manpage.
The manpage has been refactored a bit: A new section "Directives"
has been added and the information about default hostnames and
IPsec directives has been moved there, and the new file include
directive information is also there.
getconfigent has the most major changes. A newline is no longer
read immediately, but is called only by a "goto more" (inside an
if(false) block). This allows multiple definitions or directives
to exist on a single line for anything that doesn't terminate using
a newline. This means a key-values service definition can be followed
by another key-values service definition, a positional definition,
or an ipsec, hostname, or .include directive on the same line.
memset is no longer used explicitly to clear the servtab structure,
a function init_servtab() is used instead, which uses a C struct
initializer.
The servtab se_group field is its own allocation now, and not just
a pointer into the user:group string.
Refactored some stuff out of getconfigent to separate functions
for use by parse_v2.c. These functions in inetd.c are named with
the form parse_*()
parse_v2.c only has code for parsing a key-values service definition
into a provided servtab. It should not have anything that affects
global state other than line and line_number.
Some function prototypes, structures, and #defines have been moved
from inetd.c to inetd.h.
The function config_root replaces config as the function called on
a config file load/reload. The code removed from the end of
config(void) is now called in config_root, so it is not run on each
recursive config call.
setconfig(void) was removed and its code added into config_root
because that is the only place it is called, and redundant checks
for non-null globals were removed because they are always freed by
endconfig. The fseek code was also removed because the config files
are always closed by endconfig.
Rate limiting code was updated to add a per-service per-IP rate
limiting form. Some of that code was refactored out of other places
into functions with names in the form rl_*()
We have not added any of the license or version information to the
new files parse_v2.c, parse_v2.h, and inetd.h and we have not
updated the license or version info for inetd.c.
Security related:
The behavior when reading invalid IPsec strings has changed. Inetd
no longer exits, it quits reading the current config file instead.
Could this impact program security?
We have not checked for memory leaks. Solomon tried to use dmalloc
without success. getconfigent seemed to have a memory leak at each
"goto more". It seems like inetd has never free'd allocated strings
when throwing away erroneous service definitions during parsing
(i.e. when "goto more" is called when parsing fields). OpenBSD's
version calls freeconfig on "goto more"
(https://github.com/openbsd/src/blob/c5eae130d6c937080c3d30d124e8c8b86db7d625/usr.sbin/inetd/inetd.c#L1049)
but NetBSD only calls it when service definitions are no longer
needed. This has been fixed. freeconfig is called immediately before
any "goto more". There shouldn't be any time when a servtab is in
an invalid state where freeconfig would break.
2021-08-29 12:54:18 +03:00
|
|
|
SERV_FMT ": accept: %m",
|
|
|
|
SERV_PARAMS(sep));
|
2002-06-01 04:28:52 +04:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
ctrl = sep->se_fd;
|
|
|
|
spawn(sep, ctrl);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-02-13 14:47:27 +03:00
|
|
|
static void
|
|
|
|
spawn(struct servtab *sep, int ctrl)
|
2002-06-01 04:28:52 +04:00
|
|
|
{
|
|
|
|
int dofork;
|
|
|
|
pid_t pid;
|
|
|
|
|
|
|
|
pid = 0;
|
1997-03-13 21:36:35 +03:00
|
|
|
#ifdef LIBWRAP_INTERNAL
|
2021-09-03 23:24:28 +03:00
|
|
|
dofork = true;
|
1997-03-13 21:08:19 +03:00
|
|
|
#else
|
2021-09-03 23:24:28 +03:00
|
|
|
dofork = (sep->se_bi == NULL || sep->se_bi->bi_fork);
|
1997-03-13 21:08:19 +03:00
|
|
|
#endif
|
2002-06-01 04:28:52 +04:00
|
|
|
if (dofork) {
|
Inetd enhancements by James Browning, Gabe Coffland, Alex Gavin, Solomon Ritzow
Described in:
https://www.mail-archive.com/tech-userlevel@netbsd.org/msg03114.html
And developed in:
https://github.com/ritzow/src/pull/1
From their notes:
All new functionality should be explained by the updated manpage.
The manpage has been refactored a bit: A new section "Directives"
has been added and the information about default hostnames and
IPsec directives has been moved there, and the new file include
directive information is also there.
getconfigent has the most major changes. A newline is no longer
read immediately, but is called only by a "goto more" (inside an
if(false) block). This allows multiple definitions or directives
to exist on a single line for anything that doesn't terminate using
a newline. This means a key-values service definition can be followed
by another key-values service definition, a positional definition,
or an ipsec, hostname, or .include directive on the same line.
memset is no longer used explicitly to clear the servtab structure,
a function init_servtab() is used instead, which uses a C struct
initializer.
The servtab se_group field is its own allocation now, and not just
a pointer into the user:group string.
Refactored some stuff out of getconfigent to separate functions
for use by parse_v2.c. These functions in inetd.c are named with
the form parse_*()
parse_v2.c only has code for parsing a key-values service definition
into a provided servtab. It should not have anything that affects
global state other than line and line_number.
Some function prototypes, structures, and #defines have been moved
from inetd.c to inetd.h.
The function config_root replaces config as the function called on
a config file load/reload. The code removed from the end of
config(void) is now called in config_root, so it is not run on each
recursive config call.
setconfig(void) was removed and its code added into config_root
because that is the only place it is called, and redundant checks
for non-null globals were removed because they are always freed by
endconfig. The fseek code was also removed because the config files
are always closed by endconfig.
Rate limiting code was updated to add a per-service per-IP rate
limiting form. Some of that code was refactored out of other places
into functions with names in the form rl_*()
We have not added any of the license or version information to the
new files parse_v2.c, parse_v2.h, and inetd.h and we have not
updated the license or version info for inetd.c.
Security related:
The behavior when reading invalid IPsec strings has changed. Inetd
no longer exits, it quits reading the current config file instead.
Could this impact program security?
We have not checked for memory leaks. Solomon tried to use dmalloc
without success. getconfigent seemed to have a memory leak at each
"goto more". It seems like inetd has never free'd allocated strings
when throwing away erroneous service definitions during parsing
(i.e. when "goto more" is called when parsing fields). OpenBSD's
version calls freeconfig on "goto more"
(https://github.com/openbsd/src/blob/c5eae130d6c937080c3d30d124e8c8b86db7d625/usr.sbin/inetd/inetd.c#L1049)
but NetBSD only calls it when service definitions are no longer
needed. This has been fixed. freeconfig is called immediately before
any "goto more". There shouldn't be any time when a servtab is in
an invalid state where freeconfig would break.
2021-08-29 12:54:18 +03:00
|
|
|
if (rl_process(sep, ctrl)) {
|
|
|
|
return;
|
1993-10-13 14:22:48 +03:00
|
|
|
}
|
2002-06-01 04:28:52 +04:00
|
|
|
pid = fork();
|
|
|
|
if (pid < 0) {
|
|
|
|
syslog(LOG_ERR, "fork: %m");
|
2021-09-03 23:24:28 +03:00
|
|
|
if (sep->se_wait == 0 && sep->se_socktype == SOCK_STREAM)
|
2002-06-01 04:28:52 +04:00
|
|
|
close(ctrl);
|
|
|
|
sleep(1);
|
|
|
|
return;
|
|
|
|
}
|
2021-09-03 23:24:28 +03:00
|
|
|
if (pid != 0 && sep->se_wait != 0) {
|
2003-02-13 14:47:27 +03:00
|
|
|
struct kevent *ev;
|
2003-02-12 11:52:03 +03:00
|
|
|
|
2002-06-01 04:28:52 +04:00
|
|
|
sep->se_wait = pid;
|
2003-02-13 14:47:27 +03:00
|
|
|
ev = allocchange();
|
|
|
|
EV_SET(ev, sep->se_fd, EVFILT_READ,
|
2003-02-12 11:52:03 +03:00
|
|
|
EV_DELETE, 0, 0, 0);
|
2002-06-01 04:28:52 +04:00
|
|
|
}
|
1993-10-13 14:22:48 +03:00
|
|
|
if (pid == 0) {
|
2007-01-02 19:00:46 +03:00
|
|
|
size_t n;
|
2003-02-16 20:57:34 +03:00
|
|
|
|
Inetd enhancements by James Browning, Gabe Coffland, Alex Gavin, Solomon Ritzow
Described in:
https://www.mail-archive.com/tech-userlevel@netbsd.org/msg03114.html
And developed in:
https://github.com/ritzow/src/pull/1
From their notes:
All new functionality should be explained by the updated manpage.
The manpage has been refactored a bit: A new section "Directives"
has been added and the information about default hostnames and
IPsec directives has been moved there, and the new file include
directive information is also there.
getconfigent has the most major changes. A newline is no longer
read immediately, but is called only by a "goto more" (inside an
if(false) block). This allows multiple definitions or directives
to exist on a single line for anything that doesn't terminate using
a newline. This means a key-values service definition can be followed
by another key-values service definition, a positional definition,
or an ipsec, hostname, or .include directive on the same line.
memset is no longer used explicitly to clear the servtab structure,
a function init_servtab() is used instead, which uses a C struct
initializer.
The servtab se_group field is its own allocation now, and not just
a pointer into the user:group string.
Refactored some stuff out of getconfigent to separate functions
for use by parse_v2.c. These functions in inetd.c are named with
the form parse_*()
parse_v2.c only has code for parsing a key-values service definition
into a provided servtab. It should not have anything that affects
global state other than line and line_number.
Some function prototypes, structures, and #defines have been moved
from inetd.c to inetd.h.
The function config_root replaces config as the function called on
a config file load/reload. The code removed from the end of
config(void) is now called in config_root, so it is not run on each
recursive config call.
setconfig(void) was removed and its code added into config_root
because that is the only place it is called, and redundant checks
for non-null globals were removed because they are always freed by
endconfig. The fseek code was also removed because the config files
are always closed by endconfig.
Rate limiting code was updated to add a per-service per-IP rate
limiting form. Some of that code was refactored out of other places
into functions with names in the form rl_*()
We have not added any of the license or version information to the
new files parse_v2.c, parse_v2.h, and inetd.h and we have not
updated the license or version info for inetd.c.
Security related:
The behavior when reading invalid IPsec strings has changed. Inetd
no longer exits, it quits reading the current config file instead.
Could this impact program security?
We have not checked for memory leaks. Solomon tried to use dmalloc
without success. getconfigent seemed to have a memory leak at each
"goto more". It seems like inetd has never free'd allocated strings
when throwing away erroneous service definitions during parsing
(i.e. when "goto more" is called when parsing fields). OpenBSD's
version calls freeconfig on "goto more"
(https://github.com/openbsd/src/blob/c5eae130d6c937080c3d30d124e8c8b86db7d625/usr.sbin/inetd/inetd.c#L1049)
but NetBSD only calls it when service definitions are no longer
needed. This has been fixed. freeconfig is called immediately before
any "goto more". There shouldn't be any time when a servtab is in
an invalid state where freeconfig would break.
2021-08-29 12:54:18 +03:00
|
|
|
for (n = 0; n < __arraycount(my_signals); n++)
|
2003-02-16 20:57:34 +03:00
|
|
|
(void) signal(my_signals[n], SIG_DFL);
|
2021-10-12 22:08:04 +03:00
|
|
|
/* Don't put services in terminal session */
|
|
|
|
if (foreground)
|
2002-06-01 04:28:52 +04:00
|
|
|
setsid();
|
1997-03-13 23:15:04 +03:00
|
|
|
}
|
|
|
|
}
|
2002-06-01 04:28:52 +04:00
|
|
|
if (pid == 0) {
|
2008-05-26 07:41:25 +04:00
|
|
|
run_service(ctrl, sep, dofork);
|
2002-06-01 04:28:52 +04:00
|
|
|
if (dofork)
|
2021-10-12 22:08:04 +03:00
|
|
|
exit(EXIT_SUCCESS);
|
2002-06-01 04:28:52 +04:00
|
|
|
}
|
2021-09-03 23:24:28 +03:00
|
|
|
if (sep->se_wait == 0 && sep->se_socktype == SOCK_STREAM)
|
2002-06-01 04:28:52 +04:00
|
|
|
close(ctrl);
|
1997-03-13 23:15:04 +03:00
|
|
|
}
|
|
|
|
|
2003-02-13 14:47:27 +03:00
|
|
|
static void
|
2008-05-26 07:41:25 +04:00
|
|
|
run_service(int ctrl, struct servtab *sep, int didfork)
|
1997-03-13 23:15:04 +03:00
|
|
|
{
|
|
|
|
struct passwd *pwd;
|
1997-10-05 20:40:24 +04:00
|
|
|
struct group *grp = NULL; /* XXX gcc */
|
2000-01-27 22:52:43 +03:00
|
|
|
char buf[NI_MAXSERV];
|
2008-05-26 07:41:25 +04:00
|
|
|
struct servtab *s;
|
1997-03-13 23:15:04 +03:00
|
|
|
#ifdef LIBWRAP
|
2009-01-08 21:29:43 +03:00
|
|
|
char abuf[BUFSIZ];
|
1997-03-13 23:15:04 +03:00
|
|
|
struct request_info req;
|
|
|
|
int denied;
|
1998-01-20 19:44:22 +03:00
|
|
|
char *service = NULL; /* XXX gcc */
|
1997-03-13 23:15:04 +03:00
|
|
|
#endif
|
|
|
|
|
1997-03-13 17:15:40 +03:00
|
|
|
#ifdef LIBWRAP
|
1997-03-13 21:36:35 +03:00
|
|
|
#ifndef LIBWRAP_INTERNAL
|
1997-03-13 23:15:04 +03:00
|
|
|
if (sep->se_bi == 0)
|
1997-03-13 21:36:35 +03:00
|
|
|
#endif
|
2021-09-03 23:24:28 +03:00
|
|
|
if (sep->se_wait == 0 && sep->se_socktype == SOCK_STREAM) {
|
|
|
|
request_init(&req, RQ_DAEMON, sep->se_argv[0] != NULL ?
|
1997-03-13 23:15:04 +03:00
|
|
|
sep->se_argv[0] : sep->se_service, RQ_FILE, ctrl, NULL);
|
|
|
|
fromhost(&req);
|
2021-09-03 23:24:28 +03:00
|
|
|
denied = hosts_access(&req) == 0;
|
1997-03-13 23:15:04 +03:00
|
|
|
if (denied || lflag) {
|
1999-07-28 14:58:31 +04:00
|
|
|
if (getnameinfo(&sep->se_ctrladdr,
|
2009-01-09 00:37:20 +03:00
|
|
|
(socklen_t)sep->se_ctrladdr.sa_len, NULL, 0,
|
|
|
|
buf, sizeof(buf), 0) != 0) {
|
1999-07-28 14:58:31 +04:00
|
|
|
/* shouldn't happen */
|
1997-03-13 23:15:04 +03:00
|
|
|
(void)snprintf(buf, sizeof buf, "%d",
|
|
|
|
ntohs(sep->se_ctrladdr_in.sin_port));
|
1999-07-28 14:58:31 +04:00
|
|
|
}
|
|
|
|
service = buf;
|
2021-09-03 23:24:28 +03:00
|
|
|
if (req.client->sin != NULL) {
|
2010-03-25 19:36:00 +03:00
|
|
|
sockaddr_snprintf(abuf, sizeof(abuf), "%a",
|
|
|
|
req.client->sin);
|
|
|
|
} else {
|
|
|
|
strcpy(abuf, "(null)");
|
|
|
|
}
|
1997-03-13 23:15:04 +03:00
|
|
|
}
|
|
|
|
if (denied) {
|
|
|
|
syslog(deny_severity,
|
2009-01-08 21:29:43 +03:00
|
|
|
"refused connection from %.500s(%s), service %s (%s)",
|
|
|
|
eval_client(&req), abuf, service, sep->se_proto);
|
1997-03-13 23:15:04 +03:00
|
|
|
goto reject;
|
|
|
|
}
|
|
|
|
if (lflag) {
|
|
|
|
syslog(allow_severity,
|
2009-01-08 21:29:43 +03:00
|
|
|
"connection from %.500s(%s), service %s (%s)",
|
|
|
|
eval_client(&req), abuf, service, sep->se_proto);
|
1997-03-13 23:15:04 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif /* LIBWRAP */
|
|
|
|
|
2021-09-03 23:24:28 +03:00
|
|
|
if (sep->se_bi != NULL) {
|
2008-05-26 07:41:25 +04:00
|
|
|
if (didfork) {
|
2021-09-03 23:24:28 +03:00
|
|
|
for (s = servtab; s != NULL; s = s->se_next)
|
2009-01-09 00:37:20 +03:00
|
|
|
if (s->se_fd != -1 && s->se_fd != ctrl) {
|
2008-05-26 07:41:25 +04:00
|
|
|
close(s->se_fd);
|
2009-01-09 00:37:20 +03:00
|
|
|
s->se_fd = -1;
|
|
|
|
}
|
2008-05-26 07:41:25 +04:00
|
|
|
}
|
1997-03-13 23:15:04 +03:00
|
|
|
(*sep->se_bi->bi_fn)(ctrl, sep);
|
|
|
|
} else {
|
|
|
|
if ((pwd = getpwnam(sep->se_user)) == NULL) {
|
|
|
|
syslog(LOG_ERR, "%s/%s: %s: No such user",
|
|
|
|
sep->se_service, sep->se_proto, sep->se_user);
|
|
|
|
goto reject;
|
|
|
|
}
|
2021-09-03 23:24:28 +03:00
|
|
|
if (sep->se_group != NULL &&
|
1997-03-13 23:15:04 +03:00
|
|
|
(grp = getgrnam(sep->se_group)) == NULL) {
|
|
|
|
syslog(LOG_ERR, "%s/%s: %s: No such group",
|
|
|
|
sep->se_service, sep->se_proto, sep->se_group);
|
|
|
|
goto reject;
|
|
|
|
}
|
2021-09-03 23:24:28 +03:00
|
|
|
if (pwd->pw_uid != 0) {
|
|
|
|
if (sep->se_group != NULL)
|
1997-03-13 23:15:04 +03:00
|
|
|
pwd->pw_gid = grp->gr_gid;
|
|
|
|
if (setgid(pwd->pw_gid) < 0) {
|
|
|
|
syslog(LOG_ERR,
|
|
|
|
"%s/%s: can't set gid %d: %m", sep->se_service,
|
|
|
|
sep->se_proto, pwd->pw_gid);
|
1997-03-13 17:57:34 +03:00
|
|
|
goto reject;
|
1997-03-13 17:15:40 +03:00
|
|
|
}
|
1997-03-13 23:15:04 +03:00
|
|
|
(void) initgroups(pwd->pw_name,
|
|
|
|
pwd->pw_gid);
|
|
|
|
if (setuid(pwd->pw_uid) < 0) {
|
|
|
|
syslog(LOG_ERR,
|
|
|
|
"%s/%s: can't set uid %d: %m", sep->se_service,
|
|
|
|
sep->se_proto, pwd->pw_uid);
|
|
|
|
goto reject;
|
1997-03-13 17:15:40 +03:00
|
|
|
}
|
2021-09-03 23:24:28 +03:00
|
|
|
} else if (sep->se_group != NULL) {
|
1997-03-13 23:15:04 +03:00
|
|
|
(void) setgid((gid_t)grp->gr_gid);
|
|
|
|
}
|
2021-08-30 20:32:23 +03:00
|
|
|
DPRINTF("%d execl %s",
|
Inetd enhancements by James Browning, Gabe Coffland, Alex Gavin, Solomon Ritzow
Described in:
https://www.mail-archive.com/tech-userlevel@netbsd.org/msg03114.html
And developed in:
https://github.com/ritzow/src/pull/1
From their notes:
All new functionality should be explained by the updated manpage.
The manpage has been refactored a bit: A new section "Directives"
has been added and the information about default hostnames and
IPsec directives has been moved there, and the new file include
directive information is also there.
getconfigent has the most major changes. A newline is no longer
read immediately, but is called only by a "goto more" (inside an
if(false) block). This allows multiple definitions or directives
to exist on a single line for anything that doesn't terminate using
a newline. This means a key-values service definition can be followed
by another key-values service definition, a positional definition,
or an ipsec, hostname, or .include directive on the same line.
memset is no longer used explicitly to clear the servtab structure,
a function init_servtab() is used instead, which uses a C struct
initializer.
The servtab se_group field is its own allocation now, and not just
a pointer into the user:group string.
Refactored some stuff out of getconfigent to separate functions
for use by parse_v2.c. These functions in inetd.c are named with
the form parse_*()
parse_v2.c only has code for parsing a key-values service definition
into a provided servtab. It should not have anything that affects
global state other than line and line_number.
Some function prototypes, structures, and #defines have been moved
from inetd.c to inetd.h.
The function config_root replaces config as the function called on
a config file load/reload. The code removed from the end of
config(void) is now called in config_root, so it is not run on each
recursive config call.
setconfig(void) was removed and its code added into config_root
because that is the only place it is called, and redundant checks
for non-null globals were removed because they are always freed by
endconfig. The fseek code was also removed because the config files
are always closed by endconfig.
Rate limiting code was updated to add a per-service per-IP rate
limiting form. Some of that code was refactored out of other places
into functions with names in the form rl_*()
We have not added any of the license or version information to the
new files parse_v2.c, parse_v2.h, and inetd.h and we have not
updated the license or version info for inetd.c.
Security related:
The behavior when reading invalid IPsec strings has changed. Inetd
no longer exits, it quits reading the current config file instead.
Could this impact program security?
We have not checked for memory leaks. Solomon tried to use dmalloc
without success. getconfigent seemed to have a memory leak at each
"goto more". It seems like inetd has never free'd allocated strings
when throwing away erroneous service definitions during parsing
(i.e. when "goto more" is called when parsing fields). OpenBSD's
version calls freeconfig on "goto more"
(https://github.com/openbsd/src/blob/c5eae130d6c937080c3d30d124e8c8b86db7d625/usr.sbin/inetd/inetd.c#L1049)
but NetBSD only calls it when service definitions are no longer
needed. This has been fixed. freeconfig is called immediately before
any "goto more". There shouldn't be any time when a servtab is in
an invalid state where freeconfig would break.
2021-08-29 12:54:18 +03:00
|
|
|
getpid(), sep->se_server);
|
1997-03-13 23:15:04 +03:00
|
|
|
/* Set our control descriptor to not close-on-exec... */
|
|
|
|
if (fcntl(ctrl, F_SETFD, 0) < 0)
|
2009-01-09 00:37:20 +03:00
|
|
|
syslog(LOG_ERR, "fcntl (%d, F_SETFD, 0): %m", ctrl);
|
1997-03-13 23:15:04 +03:00
|
|
|
/* ...and dup it to stdin, stdout, and stderr. */
|
|
|
|
if (ctrl != 0) {
|
|
|
|
dup2(ctrl, 0);
|
|
|
|
close(ctrl);
|
|
|
|
ctrl = 0;
|
|
|
|
}
|
|
|
|
dup2(0, 1);
|
|
|
|
dup2(0, 2);
|
|
|
|
if (rlim_ofile.rlim_cur != rlim_ofile_cur &&
|
|
|
|
setrlimit(RLIMIT_NOFILE, &rlim_ofile) < 0)
|
|
|
|
syslog(LOG_ERR, "setrlimit: %m");
|
|
|
|
execv(sep->se_server, sep->se_argv);
|
|
|
|
syslog(LOG_ERR, "cannot execute %s: %m", sep->se_server);
|
|
|
|
reject:
|
|
|
|
if (sep->se_socktype != SOCK_STREAM)
|
|
|
|
recv(ctrl, buf, sizeof (buf), 0);
|
Inetd enhancements by James Browning, Gabe Coffland, Alex Gavin, Solomon Ritzow
Described in:
https://www.mail-archive.com/tech-userlevel@netbsd.org/msg03114.html
And developed in:
https://github.com/ritzow/src/pull/1
From their notes:
All new functionality should be explained by the updated manpage.
The manpage has been refactored a bit: A new section "Directives"
has been added and the information about default hostnames and
IPsec directives has been moved there, and the new file include
directive information is also there.
getconfigent has the most major changes. A newline is no longer
read immediately, but is called only by a "goto more" (inside an
if(false) block). This allows multiple definitions or directives
to exist on a single line for anything that doesn't terminate using
a newline. This means a key-values service definition can be followed
by another key-values service definition, a positional definition,
or an ipsec, hostname, or .include directive on the same line.
memset is no longer used explicitly to clear the servtab structure,
a function init_servtab() is used instead, which uses a C struct
initializer.
The servtab se_group field is its own allocation now, and not just
a pointer into the user:group string.
Refactored some stuff out of getconfigent to separate functions
for use by parse_v2.c. These functions in inetd.c are named with
the form parse_*()
parse_v2.c only has code for parsing a key-values service definition
into a provided servtab. It should not have anything that affects
global state other than line and line_number.
Some function prototypes, structures, and #defines have been moved
from inetd.c to inetd.h.
The function config_root replaces config as the function called on
a config file load/reload. The code removed from the end of
config(void) is now called in config_root, so it is not run on each
recursive config call.
setconfig(void) was removed and its code added into config_root
because that is the only place it is called, and redundant checks
for non-null globals were removed because they are always freed by
endconfig. The fseek code was also removed because the config files
are always closed by endconfig.
Rate limiting code was updated to add a per-service per-IP rate
limiting form. Some of that code was refactored out of other places
into functions with names in the form rl_*()
We have not added any of the license or version information to the
new files parse_v2.c, parse_v2.h, and inetd.h and we have not
updated the license or version info for inetd.c.
Security related:
The behavior when reading invalid IPsec strings has changed. Inetd
no longer exits, it quits reading the current config file instead.
Could this impact program security?
We have not checked for memory leaks. Solomon tried to use dmalloc
without success. getconfigent seemed to have a memory leak at each
"goto more". It seems like inetd has never free'd allocated strings
when throwing away erroneous service definitions during parsing
(i.e. when "goto more" is called when parsing fields). OpenBSD's
version calls freeconfig on "goto more"
(https://github.com/openbsd/src/blob/c5eae130d6c937080c3d30d124e8c8b86db7d625/usr.sbin/inetd/inetd.c#L1049)
but NetBSD only calls it when service definitions are no longer
needed. This has been fixed. freeconfig is called immediately before
any "goto more". There shouldn't be any time when a servtab is in
an invalid state where freeconfig would break.
2021-08-29 12:54:18 +03:00
|
|
|
_exit(EXIT_FAILURE);
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-02-13 14:47:27 +03:00
|
|
|
static void
|
|
|
|
reapchild(void)
|
1993-03-21 12:45:37 +03:00
|
|
|
{
|
|
|
|
int status;
|
1997-03-13 20:22:23 +03:00
|
|
|
pid_t pid;
|
|
|
|
struct servtab *sep;
|
1993-03-21 12:45:37 +03:00
|
|
|
|
|
|
|
for (;;) {
|
2003-02-12 11:52:03 +03:00
|
|
|
pid = wait3(&status, WNOHANG, NULL);
|
1993-03-21 12:45:37 +03:00
|
|
|
if (pid <= 0)
|
|
|
|
break;
|
Inetd enhancements by James Browning, Gabe Coffland, Alex Gavin, Solomon Ritzow
Described in:
https://www.mail-archive.com/tech-userlevel@netbsd.org/msg03114.html
And developed in:
https://github.com/ritzow/src/pull/1
From their notes:
All new functionality should be explained by the updated manpage.
The manpage has been refactored a bit: A new section "Directives"
has been added and the information about default hostnames and
IPsec directives has been moved there, and the new file include
directive information is also there.
getconfigent has the most major changes. A newline is no longer
read immediately, but is called only by a "goto more" (inside an
if(false) block). This allows multiple definitions or directives
to exist on a single line for anything that doesn't terminate using
a newline. This means a key-values service definition can be followed
by another key-values service definition, a positional definition,
or an ipsec, hostname, or .include directive on the same line.
memset is no longer used explicitly to clear the servtab structure,
a function init_servtab() is used instead, which uses a C struct
initializer.
The servtab se_group field is its own allocation now, and not just
a pointer into the user:group string.
Refactored some stuff out of getconfigent to separate functions
for use by parse_v2.c. These functions in inetd.c are named with
the form parse_*()
parse_v2.c only has code for parsing a key-values service definition
into a provided servtab. It should not have anything that affects
global state other than line and line_number.
Some function prototypes, structures, and #defines have been moved
from inetd.c to inetd.h.
The function config_root replaces config as the function called on
a config file load/reload. The code removed from the end of
config(void) is now called in config_root, so it is not run on each
recursive config call.
setconfig(void) was removed and its code added into config_root
because that is the only place it is called, and redundant checks
for non-null globals were removed because they are always freed by
endconfig. The fseek code was also removed because the config files
are always closed by endconfig.
Rate limiting code was updated to add a per-service per-IP rate
limiting form. Some of that code was refactored out of other places
into functions with names in the form rl_*()
We have not added any of the license or version information to the
new files parse_v2.c, parse_v2.h, and inetd.h and we have not
updated the license or version info for inetd.c.
Security related:
The behavior when reading invalid IPsec strings has changed. Inetd
no longer exits, it quits reading the current config file instead.
Could this impact program security?
We have not checked for memory leaks. Solomon tried to use dmalloc
without success. getconfigent seemed to have a memory leak at each
"goto more". It seems like inetd has never free'd allocated strings
when throwing away erroneous service definitions during parsing
(i.e. when "goto more" is called when parsing fields). OpenBSD's
version calls freeconfig on "goto more"
(https://github.com/openbsd/src/blob/c5eae130d6c937080c3d30d124e8c8b86db7d625/usr.sbin/inetd/inetd.c#L1049)
but NetBSD only calls it when service definitions are no longer
needed. This has been fixed. freeconfig is called immediately before
any "goto more". There shouldn't be any time when a servtab is in
an invalid state where freeconfig would break.
2021-08-29 12:54:18 +03:00
|
|
|
DPRINTF("%d reaped, status %#x", pid, status);
|
2003-02-12 11:52:03 +03:00
|
|
|
for (sep = servtab; sep != NULL; sep = sep->se_next)
|
1993-03-21 12:45:37 +03:00
|
|
|
if (sep->se_wait == pid) {
|
2003-02-13 14:47:27 +03:00
|
|
|
struct kevent *ev;
|
2003-02-12 11:52:03 +03:00
|
|
|
|
1993-10-13 14:22:48 +03:00
|
|
|
if (WIFEXITED(status) && WEXITSTATUS(status))
|
1993-03-21 12:45:37 +03:00
|
|
|
syslog(LOG_WARNING,
|
2014-04-06 03:36:10 +04:00
|
|
|
"%s: exit status %u",
|
1993-10-13 14:22:48 +03:00
|
|
|
sep->se_server, WEXITSTATUS(status));
|
|
|
|
else if (WIFSIGNALED(status))
|
|
|
|
syslog(LOG_WARNING,
|
2014-04-06 03:36:10 +04:00
|
|
|
"%s: exit signal %u",
|
1993-10-13 14:22:48 +03:00
|
|
|
sep->se_server, WTERMSIG(status));
|
|
|
|
sep->se_wait = 1;
|
2003-02-13 14:47:27 +03:00
|
|
|
ev = allocchange();
|
|
|
|
EV_SET(ev, sep->se_fd, EVFILT_READ,
|
2003-02-12 11:52:03 +03:00
|
|
|
EV_ADD | EV_ENABLE, 0, 0, (intptr_t)sep);
|
Inetd enhancements by James Browning, Gabe Coffland, Alex Gavin, Solomon Ritzow
Described in:
https://www.mail-archive.com/tech-userlevel@netbsd.org/msg03114.html
And developed in:
https://github.com/ritzow/src/pull/1
From their notes:
All new functionality should be explained by the updated manpage.
The manpage has been refactored a bit: A new section "Directives"
has been added and the information about default hostnames and
IPsec directives has been moved there, and the new file include
directive information is also there.
getconfigent has the most major changes. A newline is no longer
read immediately, but is called only by a "goto more" (inside an
if(false) block). This allows multiple definitions or directives
to exist on a single line for anything that doesn't terminate using
a newline. This means a key-values service definition can be followed
by another key-values service definition, a positional definition,
or an ipsec, hostname, or .include directive on the same line.
memset is no longer used explicitly to clear the servtab structure,
a function init_servtab() is used instead, which uses a C struct
initializer.
The servtab se_group field is its own allocation now, and not just
a pointer into the user:group string.
Refactored some stuff out of getconfigent to separate functions
for use by parse_v2.c. These functions in inetd.c are named with
the form parse_*()
parse_v2.c only has code for parsing a key-values service definition
into a provided servtab. It should not have anything that affects
global state other than line and line_number.
Some function prototypes, structures, and #defines have been moved
from inetd.c to inetd.h.
The function config_root replaces config as the function called on
a config file load/reload. The code removed from the end of
config(void) is now called in config_root, so it is not run on each
recursive config call.
setconfig(void) was removed and its code added into config_root
because that is the only place it is called, and redundant checks
for non-null globals were removed because they are always freed by
endconfig. The fseek code was also removed because the config files
are always closed by endconfig.
Rate limiting code was updated to add a per-service per-IP rate
limiting form. Some of that code was refactored out of other places
into functions with names in the form rl_*()
We have not added any of the license or version information to the
new files parse_v2.c, parse_v2.h, and inetd.h and we have not
updated the license or version info for inetd.c.
Security related:
The behavior when reading invalid IPsec strings has changed. Inetd
no longer exits, it quits reading the current config file instead.
Could this impact program security?
We have not checked for memory leaks. Solomon tried to use dmalloc
without success. getconfigent seemed to have a memory leak at each
"goto more". It seems like inetd has never free'd allocated strings
when throwing away erroneous service definitions during parsing
(i.e. when "goto more" is called when parsing fields). OpenBSD's
version calls freeconfig on "goto more"
(https://github.com/openbsd/src/blob/c5eae130d6c937080c3d30d124e8c8b86db7d625/usr.sbin/inetd/inetd.c#L1049)
but NetBSD only calls it when service definitions are no longer
needed. This has been fixed. freeconfig is called immediately before
any "goto more". There shouldn't be any time when a servtab is in
an invalid state where freeconfig would break.
2021-08-29 12:54:18 +03:00
|
|
|
DPRINTF("restored %s, fd %d",
|
|
|
|
sep->se_service, sep->se_fd);
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-02-13 14:47:27 +03:00
|
|
|
static void
|
|
|
|
retry(void)
|
1993-06-11 04:36:31 +04:00
|
|
|
{
|
1997-03-13 20:22:23 +03:00
|
|
|
struct servtab *sep;
|
1993-06-11 04:36:31 +04:00
|
|
|
|
2021-09-03 23:24:28 +03:00
|
|
|
timingout = false;
|
2003-02-12 11:52:03 +03:00
|
|
|
for (sep = servtab; sep != NULL; sep = sep->se_next) {
|
1997-03-13 20:22:23 +03:00
|
|
|
if (sep->se_fd == -1 && !ISMUX(sep)) {
|
1993-10-13 14:22:48 +03:00
|
|
|
switch (sep->se_family) {
|
1998-07-18 09:04:35 +04:00
|
|
|
case AF_LOCAL:
|
1993-10-13 14:22:48 +03:00
|
|
|
case AF_INET:
|
2000-01-31 17:28:17 +03:00
|
|
|
#ifdef INET6
|
1999-07-02 08:48:19 +04:00
|
|
|
case AF_INET6:
|
2000-01-31 17:28:17 +03:00
|
|
|
#endif
|
1993-10-13 14:22:48 +03:00
|
|
|
setup(sep);
|
2009-01-09 00:37:20 +03:00
|
|
|
if (sep->se_fd >= 0 && isrpcservice(sep))
|
1993-10-13 14:22:48 +03:00
|
|
|
register_rpc(sep);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
1993-06-11 04:36:31 +04:00
|
|
|
}
|
|
|
|
|
2003-02-13 14:47:27 +03:00
|
|
|
static void
|
|
|
|
goaway(void)
|
1993-03-21 12:45:37 +03:00
|
|
|
{
|
1997-10-05 20:40:24 +04:00
|
|
|
struct servtab *sep;
|
1993-03-21 12:45:37 +03:00
|
|
|
|
2003-02-12 11:52:03 +03:00
|
|
|
for (sep = servtab; sep != NULL; sep = sep->se_next) {
|
1993-03-21 12:45:37 +03:00
|
|
|
if (sep->se_fd == -1)
|
1993-10-13 14:22:48 +03:00
|
|
|
continue;
|
2021-08-30 20:32:23 +03:00
|
|
|
|
1993-10-13 14:22:48 +03:00
|
|
|
switch (sep->se_family) {
|
1998-07-18 09:04:35 +04:00
|
|
|
case AF_LOCAL:
|
1993-10-13 14:22:48 +03:00
|
|
|
(void)unlink(sep->se_service);
|
|
|
|
break;
|
|
|
|
case AF_INET:
|
2000-01-31 17:28:17 +03:00
|
|
|
#ifdef INET6
|
1999-07-02 08:48:19 +04:00
|
|
|
case AF_INET6:
|
2000-01-31 17:28:17 +03:00
|
|
|
#endif
|
1993-10-13 14:22:48 +03:00
|
|
|
if (sep->se_wait == 1 && isrpcservice(sep))
|
|
|
|
unregister_rpc(sep);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
(void)close(sep->se_fd);
|
2009-01-09 00:37:20 +03:00
|
|
|
sep->se_fd = -1;
|
1993-10-13 14:22:48 +03:00
|
|
|
}
|
2021-10-12 22:08:04 +03:00
|
|
|
|
|
|
|
DPRINTF("Going away.");
|
|
|
|
|
|
|
|
exit(EXIT_SUCCESS);
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
|
|
|
|
2021-10-12 22:08:04 +03:00
|
|
|
void
|
2003-02-13 14:47:27 +03:00
|
|
|
setup(struct servtab *sep)
|
1993-03-21 12:45:37 +03:00
|
|
|
{
|
2004-10-20 15:37:42 +04:00
|
|
|
int on = 1;
|
|
|
|
#ifdef INET6
|
|
|
|
int off = 0;
|
|
|
|
#endif
|
2003-02-13 14:47:27 +03:00
|
|
|
struct kevent *ev;
|
1993-03-21 12:45:37 +03:00
|
|
|
|
1993-10-13 14:22:48 +03:00
|
|
|
if ((sep->se_fd = socket(sep->se_family, sep->se_socktype, 0)) < 0) {
|
2021-08-30 20:32:23 +03:00
|
|
|
DPRINTF("socket failed on " SERV_FMT ": %s",
|
Inetd enhancements by James Browning, Gabe Coffland, Alex Gavin, Solomon Ritzow
Described in:
https://www.mail-archive.com/tech-userlevel@netbsd.org/msg03114.html
And developed in:
https://github.com/ritzow/src/pull/1
From their notes:
All new functionality should be explained by the updated manpage.
The manpage has been refactored a bit: A new section "Directives"
has been added and the information about default hostnames and
IPsec directives has been moved there, and the new file include
directive information is also there.
getconfigent has the most major changes. A newline is no longer
read immediately, but is called only by a "goto more" (inside an
if(false) block). This allows multiple definitions or directives
to exist on a single line for anything that doesn't terminate using
a newline. This means a key-values service definition can be followed
by another key-values service definition, a positional definition,
or an ipsec, hostname, or .include directive on the same line.
memset is no longer used explicitly to clear the servtab structure,
a function init_servtab() is used instead, which uses a C struct
initializer.
The servtab se_group field is its own allocation now, and not just
a pointer into the user:group string.
Refactored some stuff out of getconfigent to separate functions
for use by parse_v2.c. These functions in inetd.c are named with
the form parse_*()
parse_v2.c only has code for parsing a key-values service definition
into a provided servtab. It should not have anything that affects
global state other than line and line_number.
Some function prototypes, structures, and #defines have been moved
from inetd.c to inetd.h.
The function config_root replaces config as the function called on
a config file load/reload. The code removed from the end of
config(void) is now called in config_root, so it is not run on each
recursive config call.
setconfig(void) was removed and its code added into config_root
because that is the only place it is called, and redundant checks
for non-null globals were removed because they are always freed by
endconfig. The fseek code was also removed because the config files
are always closed by endconfig.
Rate limiting code was updated to add a per-service per-IP rate
limiting form. Some of that code was refactored out of other places
into functions with names in the form rl_*()
We have not added any of the license or version information to the
new files parse_v2.c, parse_v2.h, and inetd.h and we have not
updated the license or version info for inetd.c.
Security related:
The behavior when reading invalid IPsec strings has changed. Inetd
no longer exits, it quits reading the current config file instead.
Could this impact program security?
We have not checked for memory leaks. Solomon tried to use dmalloc
without success. getconfigent seemed to have a memory leak at each
"goto more". It seems like inetd has never free'd allocated strings
when throwing away erroneous service definitions during parsing
(i.e. when "goto more" is called when parsing fields). OpenBSD's
version calls freeconfig on "goto more"
(https://github.com/openbsd/src/blob/c5eae130d6c937080c3d30d124e8c8b86db7d625/usr.sbin/inetd/inetd.c#L1049)
but NetBSD only calls it when service definitions are no longer
needed. This has been fixed. freeconfig is called immediately before
any "goto more". There shouldn't be any time when a servtab is in
an invalid state where freeconfig would break.
2021-08-29 12:54:18 +03:00
|
|
|
SERV_PARAMS(sep), strerror(errno));
|
1993-03-21 12:45:37 +03:00
|
|
|
syslog(LOG_ERR, "%s/%s: socket: %m",
|
|
|
|
sep->se_service, sep->se_proto);
|
|
|
|
return;
|
|
|
|
}
|
1999-01-20 12:24:06 +03:00
|
|
|
/* Set all listening sockets to close-on-exec. */
|
2002-09-20 01:59:03 +04:00
|
|
|
if (fcntl(sep->se_fd, F_SETFD, FD_CLOEXEC) < 0) {
|
Inetd enhancements by James Browning, Gabe Coffland, Alex Gavin, Solomon Ritzow
Described in:
https://www.mail-archive.com/tech-userlevel@netbsd.org/msg03114.html
And developed in:
https://github.com/ritzow/src/pull/1
From their notes:
All new functionality should be explained by the updated manpage.
The manpage has been refactored a bit: A new section "Directives"
has been added and the information about default hostnames and
IPsec directives has been moved there, and the new file include
directive information is also there.
getconfigent has the most major changes. A newline is no longer
read immediately, but is called only by a "goto more" (inside an
if(false) block). This allows multiple definitions or directives
to exist on a single line for anything that doesn't terminate using
a newline. This means a key-values service definition can be followed
by another key-values service definition, a positional definition,
or an ipsec, hostname, or .include directive on the same line.
memset is no longer used explicitly to clear the servtab structure,
a function init_servtab() is used instead, which uses a C struct
initializer.
The servtab se_group field is its own allocation now, and not just
a pointer into the user:group string.
Refactored some stuff out of getconfigent to separate functions
for use by parse_v2.c. These functions in inetd.c are named with
the form parse_*()
parse_v2.c only has code for parsing a key-values service definition
into a provided servtab. It should not have anything that affects
global state other than line and line_number.
Some function prototypes, structures, and #defines have been moved
from inetd.c to inetd.h.
The function config_root replaces config as the function called on
a config file load/reload. The code removed from the end of
config(void) is now called in config_root, so it is not run on each
recursive config call.
setconfig(void) was removed and its code added into config_root
because that is the only place it is called, and redundant checks
for non-null globals were removed because they are always freed by
endconfig. The fseek code was also removed because the config files
are always closed by endconfig.
Rate limiting code was updated to add a per-service per-IP rate
limiting form. Some of that code was refactored out of other places
into functions with names in the form rl_*()
We have not added any of the license or version information to the
new files parse_v2.c, parse_v2.h, and inetd.h and we have not
updated the license or version info for inetd.c.
Security related:
The behavior when reading invalid IPsec strings has changed. Inetd
no longer exits, it quits reading the current config file instead.
Could this impact program security?
We have not checked for memory leaks. Solomon tried to use dmalloc
without success. getconfigent seemed to have a memory leak at each
"goto more". It seems like inetd has never free'd allocated strings
when throwing away erroneous service definitions during parsing
(i.e. when "goto more" is called when parsing fields). OpenBSD's
version calls freeconfig on "goto more"
(https://github.com/openbsd/src/blob/c5eae130d6c937080c3d30d124e8c8b86db7d625/usr.sbin/inetd/inetd.c#L1049)
but NetBSD only calls it when service definitions are no longer
needed. This has been fixed. freeconfig is called immediately before
any "goto more". There shouldn't be any time when a servtab is in
an invalid state where freeconfig would break.
2021-08-29 12:54:18 +03:00
|
|
|
syslog(LOG_ERR, SERV_FMT ": fcntl(F_SETFD, FD_CLOEXEC): %m",
|
|
|
|
SERV_PARAMS(sep));
|
2002-09-20 01:59:03 +04:00
|
|
|
close(sep->se_fd);
|
2009-01-09 00:37:20 +03:00
|
|
|
sep->se_fd = -1;
|
2002-09-20 01:59:03 +04:00
|
|
|
return;
|
|
|
|
}
|
1998-05-01 05:57:26 +04:00
|
|
|
|
1993-03-21 12:45:37 +03:00
|
|
|
#define turnon(fd, opt) \
|
2009-01-09 00:37:20 +03:00
|
|
|
setsockopt(fd, SOL_SOCKET, opt, &on, (socklen_t)sizeof(on))
|
1993-03-21 12:45:37 +03:00
|
|
|
if (strcmp(sep->se_proto, "tcp") == 0 && (options & SO_DEBUG) &&
|
|
|
|
turnon(sep->se_fd, SO_DEBUG) < 0)
|
|
|
|
syslog(LOG_ERR, "setsockopt (SO_DEBUG): %m");
|
|
|
|
if (turnon(sep->se_fd, SO_REUSEADDR) < 0)
|
|
|
|
syslog(LOG_ERR, "setsockopt (SO_REUSEADDR): %m");
|
|
|
|
#undef turnon
|
1998-05-01 05:57:26 +04:00
|
|
|
|
|
|
|
/* Set the socket buffer sizes, if specified. */
|
|
|
|
if (sep->se_sndbuf != 0 && setsockopt(sep->se_fd, SOL_SOCKET,
|
2009-01-09 00:37:20 +03:00
|
|
|
SO_SNDBUF, &sep->se_sndbuf, (socklen_t)sizeof(sep->se_sndbuf)) < 0)
|
1998-05-01 05:57:26 +04:00
|
|
|
syslog(LOG_ERR, "setsockopt (SO_SNDBUF %d): %m",
|
|
|
|
sep->se_sndbuf);
|
|
|
|
if (sep->se_rcvbuf != 0 && setsockopt(sep->se_fd, SOL_SOCKET,
|
2009-01-09 00:37:20 +03:00
|
|
|
SO_RCVBUF, &sep->se_rcvbuf, (socklen_t)sizeof(sep->se_rcvbuf)) < 0)
|
1998-05-01 05:57:26 +04:00
|
|
|
syslog(LOG_ERR, "setsockopt (SO_RCVBUF %d): %m",
|
|
|
|
sep->se_rcvbuf);
|
2003-04-22 11:45:27 +04:00
|
|
|
#ifdef INET6
|
|
|
|
if (sep->se_family == AF_INET6) {
|
|
|
|
int *v;
|
|
|
|
v = (sep->se_type == FAITH_TYPE) ? &on : &off;
|
|
|
|
if (setsockopt(sep->se_fd, IPPROTO_IPV6, IPV6_FAITH,
|
2009-01-09 00:37:20 +03:00
|
|
|
v, (socklen_t)sizeof(*v)) < 0)
|
2003-04-22 11:45:27 +04:00
|
|
|
syslog(LOG_ERR, "setsockopt (IPV6_FAITH): %m");
|
|
|
|
}
|
|
|
|
#endif
|
1999-07-02 08:48:19 +04:00
|
|
|
#ifdef IPSEC
|
2017-10-17 10:13:19 +03:00
|
|
|
/* Avoid setting a policy if a policy specifier doesn't exist. */
|
|
|
|
if (sep->se_policy != NULL) {
|
|
|
|
int e = ipsecsetup(sep->se_family, sep->se_fd, sep->se_policy);
|
|
|
|
if (e < 0) {
|
Inetd enhancements by James Browning, Gabe Coffland, Alex Gavin, Solomon Ritzow
Described in:
https://www.mail-archive.com/tech-userlevel@netbsd.org/msg03114.html
And developed in:
https://github.com/ritzow/src/pull/1
From their notes:
All new functionality should be explained by the updated manpage.
The manpage has been refactored a bit: A new section "Directives"
has been added and the information about default hostnames and
IPsec directives has been moved there, and the new file include
directive information is also there.
getconfigent has the most major changes. A newline is no longer
read immediately, but is called only by a "goto more" (inside an
if(false) block). This allows multiple definitions or directives
to exist on a single line for anything that doesn't terminate using
a newline. This means a key-values service definition can be followed
by another key-values service definition, a positional definition,
or an ipsec, hostname, or .include directive on the same line.
memset is no longer used explicitly to clear the servtab structure,
a function init_servtab() is used instead, which uses a C struct
initializer.
The servtab se_group field is its own allocation now, and not just
a pointer into the user:group string.
Refactored some stuff out of getconfigent to separate functions
for use by parse_v2.c. These functions in inetd.c are named with
the form parse_*()
parse_v2.c only has code for parsing a key-values service definition
into a provided servtab. It should not have anything that affects
global state other than line and line_number.
Some function prototypes, structures, and #defines have been moved
from inetd.c to inetd.h.
The function config_root replaces config as the function called on
a config file load/reload. The code removed from the end of
config(void) is now called in config_root, so it is not run on each
recursive config call.
setconfig(void) was removed and its code added into config_root
because that is the only place it is called, and redundant checks
for non-null globals were removed because they are always freed by
endconfig. The fseek code was also removed because the config files
are always closed by endconfig.
Rate limiting code was updated to add a per-service per-IP rate
limiting form. Some of that code was refactored out of other places
into functions with names in the form rl_*()
We have not added any of the license or version information to the
new files parse_v2.c, parse_v2.h, and inetd.h and we have not
updated the license or version info for inetd.c.
Security related:
The behavior when reading invalid IPsec strings has changed. Inetd
no longer exits, it quits reading the current config file instead.
Could this impact program security?
We have not checked for memory leaks. Solomon tried to use dmalloc
without success. getconfigent seemed to have a memory leak at each
"goto more". It seems like inetd has never free'd allocated strings
when throwing away erroneous service definitions during parsing
(i.e. when "goto more" is called when parsing fields). OpenBSD's
version calls freeconfig on "goto more"
(https://github.com/openbsd/src/blob/c5eae130d6c937080c3d30d124e8c8b86db7d625/usr.sbin/inetd/inetd.c#L1049)
but NetBSD only calls it when service definitions are no longer
needed. This has been fixed. freeconfig is called immediately before
any "goto more". There shouldn't be any time when a servtab is in
an invalid state where freeconfig would break.
2021-08-29 12:54:18 +03:00
|
|
|
syslog(LOG_ERR, SERV_FMT ": ipsec setup failed",
|
|
|
|
SERV_PARAMS(sep));
|
2017-10-17 10:13:19 +03:00
|
|
|
(void)close(sep->se_fd);
|
|
|
|
sep->se_fd = -1;
|
|
|
|
return;
|
|
|
|
}
|
1999-07-04 04:31:57 +04:00
|
|
|
}
|
1999-07-02 08:48:19 +04:00
|
|
|
#endif
|
1998-05-01 05:57:26 +04:00
|
|
|
|
Inetd enhancements by James Browning, Gabe Coffland, Alex Gavin, Solomon Ritzow
Described in:
https://www.mail-archive.com/tech-userlevel@netbsd.org/msg03114.html
And developed in:
https://github.com/ritzow/src/pull/1
From their notes:
All new functionality should be explained by the updated manpage.
The manpage has been refactored a bit: A new section "Directives"
has been added and the information about default hostnames and
IPsec directives has been moved there, and the new file include
directive information is also there.
getconfigent has the most major changes. A newline is no longer
read immediately, but is called only by a "goto more" (inside an
if(false) block). This allows multiple definitions or directives
to exist on a single line for anything that doesn't terminate using
a newline. This means a key-values service definition can be followed
by another key-values service definition, a positional definition,
or an ipsec, hostname, or .include directive on the same line.
memset is no longer used explicitly to clear the servtab structure,
a function init_servtab() is used instead, which uses a C struct
initializer.
The servtab se_group field is its own allocation now, and not just
a pointer into the user:group string.
Refactored some stuff out of getconfigent to separate functions
for use by parse_v2.c. These functions in inetd.c are named with
the form parse_*()
parse_v2.c only has code for parsing a key-values service definition
into a provided servtab. It should not have anything that affects
global state other than line and line_number.
Some function prototypes, structures, and #defines have been moved
from inetd.c to inetd.h.
The function config_root replaces config as the function called on
a config file load/reload. The code removed from the end of
config(void) is now called in config_root, so it is not run on each
recursive config call.
setconfig(void) was removed and its code added into config_root
because that is the only place it is called, and redundant checks
for non-null globals were removed because they are always freed by
endconfig. The fseek code was also removed because the config files
are always closed by endconfig.
Rate limiting code was updated to add a per-service per-IP rate
limiting form. Some of that code was refactored out of other places
into functions with names in the form rl_*()
We have not added any of the license or version information to the
new files parse_v2.c, parse_v2.h, and inetd.h and we have not
updated the license or version info for inetd.c.
Security related:
The behavior when reading invalid IPsec strings has changed. Inetd
no longer exits, it quits reading the current config file instead.
Could this impact program security?
We have not checked for memory leaks. Solomon tried to use dmalloc
without success. getconfigent seemed to have a memory leak at each
"goto more". It seems like inetd has never free'd allocated strings
when throwing away erroneous service definitions during parsing
(i.e. when "goto more" is called when parsing fields). OpenBSD's
version calls freeconfig on "goto more"
(https://github.com/openbsd/src/blob/c5eae130d6c937080c3d30d124e8c8b86db7d625/usr.sbin/inetd/inetd.c#L1049)
but NetBSD only calls it when service definitions are no longer
needed. This has been fixed. freeconfig is called immediately before
any "goto more". There shouldn't be any time when a servtab is in
an invalid state where freeconfig would break.
2021-08-29 12:54:18 +03:00
|
|
|
if (bind(sep->se_fd, &sep->se_ctrladdr, sep->se_ctrladdr_size) < 0) {
|
|
|
|
DPRINTF(SERV_FMT ": bind failed: %s",
|
|
|
|
SERV_PARAMS(sep), strerror(errno));
|
|
|
|
syslog(LOG_ERR, SERV_FMT ": bind: %m",
|
|
|
|
SERV_PARAMS(sep));
|
1993-03-21 12:45:37 +03:00
|
|
|
(void) close(sep->se_fd);
|
|
|
|
sep->se_fd = -1;
|
|
|
|
if (!timingout) {
|
2021-09-03 23:24:28 +03:00
|
|
|
timingout = true;
|
1993-03-21 12:45:37 +03:00
|
|
|
alarm(RETRYTIME);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (sep->se_socktype == SOCK_STREAM)
|
|
|
|
listen(sep->se_fd, 10);
|
1993-10-13 14:22:48 +03:00
|
|
|
|
2008-08-04 07:55:47 +04:00
|
|
|
/* Set the accept filter, if specified. To be done after listen.*/
|
|
|
|
if (sep->se_accf.af_name[0] != 0 && setsockopt(sep->se_fd, SOL_SOCKET,
|
2009-01-09 00:37:20 +03:00
|
|
|
SO_ACCEPTFILTER, &sep->se_accf,
|
|
|
|
(socklen_t)sizeof(sep->se_accf)) < 0)
|
2008-08-04 07:55:47 +04:00
|
|
|
syslog(LOG_ERR, "setsockopt(SO_ACCEPTFILTER %s): %m",
|
|
|
|
sep->se_accf.af_name);
|
|
|
|
|
2003-02-13 14:47:27 +03:00
|
|
|
ev = allocchange();
|
|
|
|
EV_SET(ev, sep->se_fd, EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0,
|
2003-02-12 11:52:03 +03:00
|
|
|
(intptr_t)sep);
|
1993-10-13 14:22:48 +03:00
|
|
|
if (sep->se_fd > maxsock) {
|
1993-03-21 12:45:37 +03:00
|
|
|
maxsock = sep->se_fd;
|
2009-04-15 12:38:37 +04:00
|
|
|
if (maxsock > (int)(rlim_ofile_cur - FD_MARGIN))
|
1993-10-13 14:22:48 +03:00
|
|
|
bump_nofile();
|
|
|
|
}
|
Inetd enhancements by James Browning, Gabe Coffland, Alex Gavin, Solomon Ritzow
Described in:
https://www.mail-archive.com/tech-userlevel@netbsd.org/msg03114.html
And developed in:
https://github.com/ritzow/src/pull/1
From their notes:
All new functionality should be explained by the updated manpage.
The manpage has been refactored a bit: A new section "Directives"
has been added and the information about default hostnames and
IPsec directives has been moved there, and the new file include
directive information is also there.
getconfigent has the most major changes. A newline is no longer
read immediately, but is called only by a "goto more" (inside an
if(false) block). This allows multiple definitions or directives
to exist on a single line for anything that doesn't terminate using
a newline. This means a key-values service definition can be followed
by another key-values service definition, a positional definition,
or an ipsec, hostname, or .include directive on the same line.
memset is no longer used explicitly to clear the servtab structure,
a function init_servtab() is used instead, which uses a C struct
initializer.
The servtab se_group field is its own allocation now, and not just
a pointer into the user:group string.
Refactored some stuff out of getconfigent to separate functions
for use by parse_v2.c. These functions in inetd.c are named with
the form parse_*()
parse_v2.c only has code for parsing a key-values service definition
into a provided servtab. It should not have anything that affects
global state other than line and line_number.
Some function prototypes, structures, and #defines have been moved
from inetd.c to inetd.h.
The function config_root replaces config as the function called on
a config file load/reload. The code removed from the end of
config(void) is now called in config_root, so it is not run on each
recursive config call.
setconfig(void) was removed and its code added into config_root
because that is the only place it is called, and redundant checks
for non-null globals were removed because they are always freed by
endconfig. The fseek code was also removed because the config files
are always closed by endconfig.
Rate limiting code was updated to add a per-service per-IP rate
limiting form. Some of that code was refactored out of other places
into functions with names in the form rl_*()
We have not added any of the license or version information to the
new files parse_v2.c, parse_v2.h, and inetd.h and we have not
updated the license or version info for inetd.c.
Security related:
The behavior when reading invalid IPsec strings has changed. Inetd
no longer exits, it quits reading the current config file instead.
Could this impact program security?
We have not checked for memory leaks. Solomon tried to use dmalloc
without success. getconfigent seemed to have a memory leak at each
"goto more". It seems like inetd has never free'd allocated strings
when throwing away erroneous service definitions during parsing
(i.e. when "goto more" is called when parsing fields). OpenBSD's
version calls freeconfig on "goto more"
(https://github.com/openbsd/src/blob/c5eae130d6c937080c3d30d124e8c8b86db7d625/usr.sbin/inetd/inetd.c#L1049)
but NetBSD only calls it when service definitions are no longer
needed. This has been fixed. freeconfig is called immediately before
any "goto more". There shouldn't be any time when a servtab is in
an invalid state where freeconfig would break.
2021-08-29 12:54:18 +03:00
|
|
|
DPRINTF(SERV_FMT ": registered on fd %d", SERV_PARAMS(sep), sep->se_fd);
|
1997-03-13 20:22:23 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Finish with a service and its socket.
|
|
|
|
*/
|
2021-10-12 22:08:04 +03:00
|
|
|
void
|
2003-02-13 14:47:27 +03:00
|
|
|
close_sep(struct servtab *sep)
|
2021-08-30 20:32:23 +03:00
|
|
|
{
|
Inetd enhancements by James Browning, Gabe Coffland, Alex Gavin, Solomon Ritzow
Described in:
https://www.mail-archive.com/tech-userlevel@netbsd.org/msg03114.html
And developed in:
https://github.com/ritzow/src/pull/1
From their notes:
All new functionality should be explained by the updated manpage.
The manpage has been refactored a bit: A new section "Directives"
has been added and the information about default hostnames and
IPsec directives has been moved there, and the new file include
directive information is also there.
getconfigent has the most major changes. A newline is no longer
read immediately, but is called only by a "goto more" (inside an
if(false) block). This allows multiple definitions or directives
to exist on a single line for anything that doesn't terminate using
a newline. This means a key-values service definition can be followed
by another key-values service definition, a positional definition,
or an ipsec, hostname, or .include directive on the same line.
memset is no longer used explicitly to clear the servtab structure,
a function init_servtab() is used instead, which uses a C struct
initializer.
The servtab se_group field is its own allocation now, and not just
a pointer into the user:group string.
Refactored some stuff out of getconfigent to separate functions
for use by parse_v2.c. These functions in inetd.c are named with
the form parse_*()
parse_v2.c only has code for parsing a key-values service definition
into a provided servtab. It should not have anything that affects
global state other than line and line_number.
Some function prototypes, structures, and #defines have been moved
from inetd.c to inetd.h.
The function config_root replaces config as the function called on
a config file load/reload. The code removed from the end of
config(void) is now called in config_root, so it is not run on each
recursive config call.
setconfig(void) was removed and its code added into config_root
because that is the only place it is called, and redundant checks
for non-null globals were removed because they are always freed by
endconfig. The fseek code was also removed because the config files
are always closed by endconfig.
Rate limiting code was updated to add a per-service per-IP rate
limiting form. Some of that code was refactored out of other places
into functions with names in the form rl_*()
We have not added any of the license or version information to the
new files parse_v2.c, parse_v2.h, and inetd.h and we have not
updated the license or version info for inetd.c.
Security related:
The behavior when reading invalid IPsec strings has changed. Inetd
no longer exits, it quits reading the current config file instead.
Could this impact program security?
We have not checked for memory leaks. Solomon tried to use dmalloc
without success. getconfigent seemed to have a memory leak at each
"goto more". It seems like inetd has never free'd allocated strings
when throwing away erroneous service definitions during parsing
(i.e. when "goto more" is called when parsing fields). OpenBSD's
version calls freeconfig on "goto more"
(https://github.com/openbsd/src/blob/c5eae130d6c937080c3d30d124e8c8b86db7d625/usr.sbin/inetd/inetd.c#L1049)
but NetBSD only calls it when service definitions are no longer
needed. This has been fixed. freeconfig is called immediately before
any "goto more". There shouldn't be any time when a servtab is in
an invalid state where freeconfig would break.
2021-08-29 12:54:18 +03:00
|
|
|
|
1997-03-13 20:22:23 +03:00
|
|
|
if (sep->se_fd >= 0) {
|
|
|
|
(void) close(sep->se_fd);
|
|
|
|
sep->se_fd = -1;
|
|
|
|
}
|
|
|
|
sep->se_count = 0;
|
Inetd enhancements by James Browning, Gabe Coffland, Alex Gavin, Solomon Ritzow
Described in:
https://www.mail-archive.com/tech-userlevel@netbsd.org/msg03114.html
And developed in:
https://github.com/ritzow/src/pull/1
From their notes:
All new functionality should be explained by the updated manpage.
The manpage has been refactored a bit: A new section "Directives"
has been added and the information about default hostnames and
IPsec directives has been moved there, and the new file include
directive information is also there.
getconfigent has the most major changes. A newline is no longer
read immediately, but is called only by a "goto more" (inside an
if(false) block). This allows multiple definitions or directives
to exist on a single line for anything that doesn't terminate using
a newline. This means a key-values service definition can be followed
by another key-values service definition, a positional definition,
or an ipsec, hostname, or .include directive on the same line.
memset is no longer used explicitly to clear the servtab structure,
a function init_servtab() is used instead, which uses a C struct
initializer.
The servtab se_group field is its own allocation now, and not just
a pointer into the user:group string.
Refactored some stuff out of getconfigent to separate functions
for use by parse_v2.c. These functions in inetd.c are named with
the form parse_*()
parse_v2.c only has code for parsing a key-values service definition
into a provided servtab. It should not have anything that affects
global state other than line and line_number.
Some function prototypes, structures, and #defines have been moved
from inetd.c to inetd.h.
The function config_root replaces config as the function called on
a config file load/reload. The code removed from the end of
config(void) is now called in config_root, so it is not run on each
recursive config call.
setconfig(void) was removed and its code added into config_root
because that is the only place it is called, and redundant checks
for non-null globals were removed because they are always freed by
endconfig. The fseek code was also removed because the config files
are always closed by endconfig.
Rate limiting code was updated to add a per-service per-IP rate
limiting form. Some of that code was refactored out of other places
into functions with names in the form rl_*()
We have not added any of the license or version information to the
new files parse_v2.c, parse_v2.h, and inetd.h and we have not
updated the license or version info for inetd.c.
Security related:
The behavior when reading invalid IPsec strings has changed. Inetd
no longer exits, it quits reading the current config file instead.
Could this impact program security?
We have not checked for memory leaks. Solomon tried to use dmalloc
without success. getconfigent seemed to have a memory leak at each
"goto more". It seems like inetd has never free'd allocated strings
when throwing away erroneous service definitions during parsing
(i.e. when "goto more" is called when parsing fields). OpenBSD's
version calls freeconfig on "goto more"
(https://github.com/openbsd/src/blob/c5eae130d6c937080c3d30d124e8c8b86db7d625/usr.sbin/inetd/inetd.c#L1049)
but NetBSD only calls it when service definitions are no longer
needed. This has been fixed. freeconfig is called immediately before
any "goto more". There shouldn't be any time when a servtab is in
an invalid state where freeconfig would break.
2021-08-29 12:54:18 +03:00
|
|
|
if (sep->se_ip_max != SERVTAB_UNSPEC_SIZE_T) {
|
2021-10-12 22:08:04 +03:00
|
|
|
rl_clear_ip_list(sep);
|
Inetd enhancements by James Browning, Gabe Coffland, Alex Gavin, Solomon Ritzow
Described in:
https://www.mail-archive.com/tech-userlevel@netbsd.org/msg03114.html
And developed in:
https://github.com/ritzow/src/pull/1
From their notes:
All new functionality should be explained by the updated manpage.
The manpage has been refactored a bit: A new section "Directives"
has been added and the information about default hostnames and
IPsec directives has been moved there, and the new file include
directive information is also there.
getconfigent has the most major changes. A newline is no longer
read immediately, but is called only by a "goto more" (inside an
if(false) block). This allows multiple definitions or directives
to exist on a single line for anything that doesn't terminate using
a newline. This means a key-values service definition can be followed
by another key-values service definition, a positional definition,
or an ipsec, hostname, or .include directive on the same line.
memset is no longer used explicitly to clear the servtab structure,
a function init_servtab() is used instead, which uses a C struct
initializer.
The servtab se_group field is its own allocation now, and not just
a pointer into the user:group string.
Refactored some stuff out of getconfigent to separate functions
for use by parse_v2.c. These functions in inetd.c are named with
the form parse_*()
parse_v2.c only has code for parsing a key-values service definition
into a provided servtab. It should not have anything that affects
global state other than line and line_number.
Some function prototypes, structures, and #defines have been moved
from inetd.c to inetd.h.
The function config_root replaces config as the function called on
a config file load/reload. The code removed from the end of
config(void) is now called in config_root, so it is not run on each
recursive config call.
setconfig(void) was removed and its code added into config_root
because that is the only place it is called, and redundant checks
for non-null globals were removed because they are always freed by
endconfig. The fseek code was also removed because the config files
are always closed by endconfig.
Rate limiting code was updated to add a per-service per-IP rate
limiting form. Some of that code was refactored out of other places
into functions with names in the form rl_*()
We have not added any of the license or version information to the
new files parse_v2.c, parse_v2.h, and inetd.h and we have not
updated the license or version info for inetd.c.
Security related:
The behavior when reading invalid IPsec strings has changed. Inetd
no longer exits, it quits reading the current config file instead.
Could this impact program security?
We have not checked for memory leaks. Solomon tried to use dmalloc
without success. getconfigent seemed to have a memory leak at each
"goto more". It seems like inetd has never free'd allocated strings
when throwing away erroneous service definitions during parsing
(i.e. when "goto more" is called when parsing fields). OpenBSD's
version calls freeconfig on "goto more"
(https://github.com/openbsd/src/blob/c5eae130d6c937080c3d30d124e8c8b86db7d625/usr.sbin/inetd/inetd.c#L1049)
but NetBSD only calls it when service definitions are no longer
needed. This has been fixed. freeconfig is called immediately before
any "goto more". There shouldn't be any time when a servtab is in
an invalid state where freeconfig would break.
2021-08-29 12:54:18 +03:00
|
|
|
}
|
1993-10-13 14:22:48 +03:00
|
|
|
}
|
|
|
|
|
2021-10-12 22:08:04 +03:00
|
|
|
void
|
2003-02-13 14:47:27 +03:00
|
|
|
register_rpc(struct servtab *sep)
|
1993-10-13 14:22:48 +03:00
|
|
|
{
|
|
|
|
#ifdef RPC
|
2000-06-03 03:17:55 +04:00
|
|
|
struct netbuf nbuf;
|
1999-07-02 08:48:19 +04:00
|
|
|
struct sockaddr_storage ss;
|
2000-06-03 03:17:55 +04:00
|
|
|
struct netconfig *nconf;
|
2007-01-02 19:00:46 +03:00
|
|
|
socklen_t socklen;
|
|
|
|
int n;
|
1993-10-13 14:22:48 +03:00
|
|
|
|
2000-06-03 03:17:55 +04:00
|
|
|
if ((nconf = getnetconfigent(sep->se_proto+4)) == NULL) {
|
|
|
|
syslog(LOG_ERR, "%s: getnetconfigent failed",
|
1993-10-13 14:22:48 +03:00
|
|
|
sep->se_proto);
|
|
|
|
return;
|
|
|
|
}
|
2007-01-02 19:00:46 +03:00
|
|
|
socklen = sizeof ss;
|
2009-01-09 00:37:20 +03:00
|
|
|
if (getsockname(sep->se_fd, (struct sockaddr *)(void *)&ss, &socklen) < 0) {
|
Inetd enhancements by James Browning, Gabe Coffland, Alex Gavin, Solomon Ritzow
Described in:
https://www.mail-archive.com/tech-userlevel@netbsd.org/msg03114.html
And developed in:
https://github.com/ritzow/src/pull/1
From their notes:
All new functionality should be explained by the updated manpage.
The manpage has been refactored a bit: A new section "Directives"
has been added and the information about default hostnames and
IPsec directives has been moved there, and the new file include
directive information is also there.
getconfigent has the most major changes. A newline is no longer
read immediately, but is called only by a "goto more" (inside an
if(false) block). This allows multiple definitions or directives
to exist on a single line for anything that doesn't terminate using
a newline. This means a key-values service definition can be followed
by another key-values service definition, a positional definition,
or an ipsec, hostname, or .include directive on the same line.
memset is no longer used explicitly to clear the servtab structure,
a function init_servtab() is used instead, which uses a C struct
initializer.
The servtab se_group field is its own allocation now, and not just
a pointer into the user:group string.
Refactored some stuff out of getconfigent to separate functions
for use by parse_v2.c. These functions in inetd.c are named with
the form parse_*()
parse_v2.c only has code for parsing a key-values service definition
into a provided servtab. It should not have anything that affects
global state other than line and line_number.
Some function prototypes, structures, and #defines have been moved
from inetd.c to inetd.h.
The function config_root replaces config as the function called on
a config file load/reload. The code removed from the end of
config(void) is now called in config_root, so it is not run on each
recursive config call.
setconfig(void) was removed and its code added into config_root
because that is the only place it is called, and redundant checks
for non-null globals were removed because they are always freed by
endconfig. The fseek code was also removed because the config files
are always closed by endconfig.
Rate limiting code was updated to add a per-service per-IP rate
limiting form. Some of that code was refactored out of other places
into functions with names in the form rl_*()
We have not added any of the license or version information to the
new files parse_v2.c, parse_v2.h, and inetd.h and we have not
updated the license or version info for inetd.c.
Security related:
The behavior when reading invalid IPsec strings has changed. Inetd
no longer exits, it quits reading the current config file instead.
Could this impact program security?
We have not checked for memory leaks. Solomon tried to use dmalloc
without success. getconfigent seemed to have a memory leak at each
"goto more". It seems like inetd has never free'd allocated strings
when throwing away erroneous service definitions during parsing
(i.e. when "goto more" is called when parsing fields). OpenBSD's
version calls freeconfig on "goto more"
(https://github.com/openbsd/src/blob/c5eae130d6c937080c3d30d124e8c8b86db7d625/usr.sbin/inetd/inetd.c#L1049)
but NetBSD only calls it when service definitions are no longer
needed. This has been fixed. freeconfig is called immediately before
any "goto more". There shouldn't be any time when a servtab is in
an invalid state where freeconfig would break.
2021-08-29 12:54:18 +03:00
|
|
|
syslog(LOG_ERR, SERV_FMT ": getsockname: %m",
|
|
|
|
SERV_PARAMS(sep));
|
1993-10-13 14:22:48 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2000-06-03 03:17:55 +04:00
|
|
|
nbuf.buf = &ss;
|
|
|
|
nbuf.len = ss.ss_len;
|
|
|
|
nbuf.maxlen = sizeof (struct sockaddr_storage);
|
1993-10-13 14:22:48 +03:00
|
|
|
for (n = sep->se_rpcversl; n <= sep->se_rpcversh; n++) {
|
Inetd enhancements by James Browning, Gabe Coffland, Alex Gavin, Solomon Ritzow
Described in:
https://www.mail-archive.com/tech-userlevel@netbsd.org/msg03114.html
And developed in:
https://github.com/ritzow/src/pull/1
From their notes:
All new functionality should be explained by the updated manpage.
The manpage has been refactored a bit: A new section "Directives"
has been added and the information about default hostnames and
IPsec directives has been moved there, and the new file include
directive information is also there.
getconfigent has the most major changes. A newline is no longer
read immediately, but is called only by a "goto more" (inside an
if(false) block). This allows multiple definitions or directives
to exist on a single line for anything that doesn't terminate using
a newline. This means a key-values service definition can be followed
by another key-values service definition, a positional definition,
or an ipsec, hostname, or .include directive on the same line.
memset is no longer used explicitly to clear the servtab structure,
a function init_servtab() is used instead, which uses a C struct
initializer.
The servtab se_group field is its own allocation now, and not just
a pointer into the user:group string.
Refactored some stuff out of getconfigent to separate functions
for use by parse_v2.c. These functions in inetd.c are named with
the form parse_*()
parse_v2.c only has code for parsing a key-values service definition
into a provided servtab. It should not have anything that affects
global state other than line and line_number.
Some function prototypes, structures, and #defines have been moved
from inetd.c to inetd.h.
The function config_root replaces config as the function called on
a config file load/reload. The code removed from the end of
config(void) is now called in config_root, so it is not run on each
recursive config call.
setconfig(void) was removed and its code added into config_root
because that is the only place it is called, and redundant checks
for non-null globals were removed because they are always freed by
endconfig. The fseek code was also removed because the config files
are always closed by endconfig.
Rate limiting code was updated to add a per-service per-IP rate
limiting form. Some of that code was refactored out of other places
into functions with names in the form rl_*()
We have not added any of the license or version information to the
new files parse_v2.c, parse_v2.h, and inetd.h and we have not
updated the license or version info for inetd.c.
Security related:
The behavior when reading invalid IPsec strings has changed. Inetd
no longer exits, it quits reading the current config file instead.
Could this impact program security?
We have not checked for memory leaks. Solomon tried to use dmalloc
without success. getconfigent seemed to have a memory leak at each
"goto more". It seems like inetd has never free'd allocated strings
when throwing away erroneous service definitions during parsing
(i.e. when "goto more" is called when parsing fields). OpenBSD's
version calls freeconfig on "goto more"
(https://github.com/openbsd/src/blob/c5eae130d6c937080c3d30d124e8c8b86db7d625/usr.sbin/inetd/inetd.c#L1049)
but NetBSD only calls it when service definitions are no longer
needed. This has been fixed. freeconfig is called immediately before
any "goto more". There shouldn't be any time when a servtab is in
an invalid state where freeconfig would break.
2021-08-29 12:54:18 +03:00
|
|
|
DPRINTF("rpcb_set: %u %d %s %s",
|
|
|
|
sep->se_rpcprog, n, nconf->nc_netid,
|
|
|
|
taddr2uaddr(nconf, &nbuf));
|
2009-01-09 00:37:20 +03:00
|
|
|
(void)rpcb_unset((unsigned int)sep->se_rpcprog, (unsigned int)n, nconf);
|
2021-09-03 23:24:28 +03:00
|
|
|
if (rpcb_set((unsigned int)sep->se_rpcprog, (unsigned int)n, nconf, &nbuf) == 0)
|
2000-06-03 03:17:55 +04:00
|
|
|
syslog(LOG_ERR, "rpcb_set: %u %d %s %s%s",
|
|
|
|
sep->se_rpcprog, n, nconf->nc_netid,
|
|
|
|
taddr2uaddr(nconf, &nbuf), clnt_spcreateerror(""));
|
1993-10-13 14:22:48 +03:00
|
|
|
}
|
|
|
|
#endif /* RPC */
|
|
|
|
}
|
|
|
|
|
2021-10-12 22:08:04 +03:00
|
|
|
void
|
2003-02-13 14:47:27 +03:00
|
|
|
unregister_rpc(struct servtab *sep)
|
1993-10-13 14:22:48 +03:00
|
|
|
{
|
|
|
|
#ifdef RPC
|
|
|
|
int n;
|
2000-06-03 03:17:55 +04:00
|
|
|
struct netconfig *nconf;
|
|
|
|
|
|
|
|
if ((nconf = getnetconfigent(sep->se_proto+4)) == NULL) {
|
|
|
|
syslog(LOG_ERR, "%s: getnetconfigent failed",
|
|
|
|
sep->se_proto);
|
|
|
|
return;
|
|
|
|
}
|
1993-10-13 14:22:48 +03:00
|
|
|
|
|
|
|
for (n = sep->se_rpcversl; n <= sep->se_rpcversh; n++) {
|
Inetd enhancements by James Browning, Gabe Coffland, Alex Gavin, Solomon Ritzow
Described in:
https://www.mail-archive.com/tech-userlevel@netbsd.org/msg03114.html
And developed in:
https://github.com/ritzow/src/pull/1
From their notes:
All new functionality should be explained by the updated manpage.
The manpage has been refactored a bit: A new section "Directives"
has been added and the information about default hostnames and
IPsec directives has been moved there, and the new file include
directive information is also there.
getconfigent has the most major changes. A newline is no longer
read immediately, but is called only by a "goto more" (inside an
if(false) block). This allows multiple definitions or directives
to exist on a single line for anything that doesn't terminate using
a newline. This means a key-values service definition can be followed
by another key-values service definition, a positional definition,
or an ipsec, hostname, or .include directive on the same line.
memset is no longer used explicitly to clear the servtab structure,
a function init_servtab() is used instead, which uses a C struct
initializer.
The servtab se_group field is its own allocation now, and not just
a pointer into the user:group string.
Refactored some stuff out of getconfigent to separate functions
for use by parse_v2.c. These functions in inetd.c are named with
the form parse_*()
parse_v2.c only has code for parsing a key-values service definition
into a provided servtab. It should not have anything that affects
global state other than line and line_number.
Some function prototypes, structures, and #defines have been moved
from inetd.c to inetd.h.
The function config_root replaces config as the function called on
a config file load/reload. The code removed from the end of
config(void) is now called in config_root, so it is not run on each
recursive config call.
setconfig(void) was removed and its code added into config_root
because that is the only place it is called, and redundant checks
for non-null globals were removed because they are always freed by
endconfig. The fseek code was also removed because the config files
are always closed by endconfig.
Rate limiting code was updated to add a per-service per-IP rate
limiting form. Some of that code was refactored out of other places
into functions with names in the form rl_*()
We have not added any of the license or version information to the
new files parse_v2.c, parse_v2.h, and inetd.h and we have not
updated the license or version info for inetd.c.
Security related:
The behavior when reading invalid IPsec strings has changed. Inetd
no longer exits, it quits reading the current config file instead.
Could this impact program security?
We have not checked for memory leaks. Solomon tried to use dmalloc
without success. getconfigent seemed to have a memory leak at each
"goto more". It seems like inetd has never free'd allocated strings
when throwing away erroneous service definitions during parsing
(i.e. when "goto more" is called when parsing fields). OpenBSD's
version calls freeconfig on "goto more"
(https://github.com/openbsd/src/blob/c5eae130d6c937080c3d30d124e8c8b86db7d625/usr.sbin/inetd/inetd.c#L1049)
but NetBSD only calls it when service definitions are no longer
needed. This has been fixed. freeconfig is called immediately before
any "goto more". There shouldn't be any time when a servtab is in
an invalid state where freeconfig would break.
2021-08-29 12:54:18 +03:00
|
|
|
DPRINTF("rpcb_unset(%u, %d, %s)",
|
|
|
|
sep->se_rpcprog, n, nconf->nc_netid);
|
2021-09-03 23:24:28 +03:00
|
|
|
if (rpcb_unset((unsigned int)sep->se_rpcprog, (unsigned int)n, nconf) == 0)
|
2000-06-03 03:17:55 +04:00
|
|
|
syslog(LOG_ERR, "rpcb_unset(%u, %d, %s) failed\n",
|
|
|
|
sep->se_rpcprog, n, nconf->nc_netid);
|
1993-10-13 14:22:48 +03:00
|
|
|
}
|
|
|
|
#endif /* RPC */
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
|
|
|
|
2003-02-13 14:47:27 +03:00
|
|
|
static void
|
|
|
|
inetd_setproctitle(char *a, int s)
|
1993-03-21 12:45:37 +03:00
|
|
|
{
|
2002-05-31 18:28:20 +04:00
|
|
|
socklen_t size;
|
1999-07-02 08:48:19 +04:00
|
|
|
struct sockaddr_storage ss;
|
2009-01-09 00:37:20 +03:00
|
|
|
char hbuf[NI_MAXHOST];
|
|
|
|
const char *hp;
|
|
|
|
struct sockaddr *sa;
|
1993-03-21 12:45:37 +03:00
|
|
|
|
1999-07-02 08:48:19 +04:00
|
|
|
size = sizeof(ss);
|
2009-01-09 00:37:20 +03:00
|
|
|
sa = (struct sockaddr *)(void *)&ss;
|
|
|
|
if (getpeername(s, sa, &size) == 0) {
|
|
|
|
if (getnameinfo(sa, size, hbuf, (socklen_t)sizeof(hbuf), NULL,
|
|
|
|
0, niflags) != 0)
|
2004-11-28 08:40:47 +03:00
|
|
|
hp = "?";
|
2009-01-09 00:37:20 +03:00
|
|
|
else
|
|
|
|
hp = hbuf;
|
2004-11-28 08:40:47 +03:00
|
|
|
setproctitle("-%s [%s]", a, hp);
|
1999-07-02 08:48:19 +04:00
|
|
|
} else
|
2002-05-31 18:28:20 +04:00
|
|
|
setproctitle("-%s", a);
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
|
|
|
|
2003-02-13 14:47:27 +03:00
|
|
|
static void
|
|
|
|
bump_nofile(void)
|
1993-10-13 14:22:48 +03:00
|
|
|
{
|
|
|
|
#define FD_CHUNK 32
|
|
|
|
struct rlimit rl;
|
|
|
|
|
1993-12-15 00:31:53 +03:00
|
|
|
if (getrlimit(RLIMIT_NOFILE, &rl) < 0) {
|
1993-10-13 14:22:48 +03:00
|
|
|
syslog(LOG_ERR, "getrlimit: %m");
|
1997-10-05 20:40:24 +04:00
|
|
|
return;
|
1993-10-13 14:22:48 +03:00
|
|
|
}
|
|
|
|
rl.rlim_cur = MIN(rl.rlim_max, rl.rlim_cur + FD_CHUNK);
|
|
|
|
if (rl.rlim_cur <= rlim_ofile_cur) {
|
|
|
|
syslog(LOG_ERR,
|
1997-03-13 20:22:23 +03:00
|
|
|
"bump_nofile: cannot extend file limit, max = %d",
|
1997-10-05 20:40:24 +04:00
|
|
|
(int)rl.rlim_cur);
|
|
|
|
return;
|
1993-10-13 14:22:48 +03:00
|
|
|
}
|
|
|
|
|
1993-12-15 00:31:53 +03:00
|
|
|
if (setrlimit(RLIMIT_NOFILE, &rl) < 0) {
|
1993-10-13 14:22:48 +03:00
|
|
|
syslog(LOG_ERR, "setrlimit: %m");
|
1997-10-05 20:40:24 +04:00
|
|
|
return;
|
1993-10-13 14:22:48 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
rlim_ofile_cur = rl.rlim_cur;
|
1997-10-05 20:40:24 +04:00
|
|
|
return;
|
1993-10-13 14:22:48 +03:00
|
|
|
}
|
|
|
|
|
1993-03-21 12:45:37 +03:00
|
|
|
/*
|
|
|
|
* Internet services provided internally by inetd:
|
|
|
|
*/
|
1993-10-13 14:22:48 +03:00
|
|
|
#define BUFSIZE 4096
|
1993-03-21 12:45:37 +03:00
|
|
|
|
|
|
|
/* ARGSUSED */
|
2003-02-13 14:47:27 +03:00
|
|
|
static void
|
|
|
|
echo_stream(int s, struct servtab *sep) /* Echo service -- echo data back */
|
1993-03-21 12:45:37 +03:00
|
|
|
{
|
|
|
|
char buffer[BUFSIZE];
|
2009-01-09 00:37:20 +03:00
|
|
|
ssize_t i;
|
1993-03-21 12:45:37 +03:00
|
|
|
|
1994-12-23 19:45:11 +03:00
|
|
|
inetd_setproctitle(sep->se_service, s);
|
1993-03-21 12:45:37 +03:00
|
|
|
while ((i = read(s, buffer, sizeof(buffer))) > 0 &&
|
2009-01-09 00:37:20 +03:00
|
|
|
write(s, buffer, (size_t)i) > 0)
|
2021-10-12 22:08:04 +03:00
|
|
|
continue;
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ARGSUSED */
|
2003-02-13 14:47:27 +03:00
|
|
|
static void
|
|
|
|
echo_dg(int s, struct servtab *sep) /* Echo service -- echo data back */
|
1993-03-21 12:45:37 +03:00
|
|
|
{
|
|
|
|
char buffer[BUFSIZE];
|
2009-01-09 00:37:20 +03:00
|
|
|
ssize_t i;
|
2002-06-01 04:15:08 +04:00
|
|
|
socklen_t size;
|
1999-09-15 13:59:41 +04:00
|
|
|
struct sockaddr_storage ss;
|
|
|
|
struct sockaddr *sa;
|
1993-03-21 12:45:37 +03:00
|
|
|
|
2009-01-09 00:37:20 +03:00
|
|
|
sa = (struct sockaddr *)(void *)&ss;
|
1999-09-15 13:59:41 +04:00
|
|
|
size = sizeof(ss);
|
|
|
|
if ((i = recvfrom(s, buffer, sizeof(buffer), 0, sa, &size)) < 0)
|
1993-03-21 12:45:37 +03:00
|
|
|
return;
|
1999-09-15 13:59:41 +04:00
|
|
|
if (port_good_dg(sa))
|
2009-01-09 00:37:20 +03:00
|
|
|
(void) sendto(s, buffer, (size_t)i, 0, sa, size);
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ARGSUSED */
|
2003-02-13 14:47:27 +03:00
|
|
|
static void
|
|
|
|
discard_stream(int s, struct servtab *sep) /* Discard service -- ignore data */
|
1993-03-21 12:45:37 +03:00
|
|
|
{
|
|
|
|
char buffer[BUFSIZE];
|
|
|
|
|
1994-12-23 19:45:11 +03:00
|
|
|
inetd_setproctitle(sep->se_service, s);
|
1993-10-13 14:22:48 +03:00
|
|
|
while ((errno = 0, read(s, buffer, sizeof(buffer)) > 0) ||
|
|
|
|
errno == EINTR)
|
|
|
|
;
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ARGSUSED */
|
2003-02-13 14:47:27 +03:00
|
|
|
static void
|
|
|
|
discard_dg(int s, struct servtab *sep) /* Discard service -- ignore data */
|
2021-08-30 20:32:23 +03:00
|
|
|
|
1993-03-21 12:45:37 +03:00
|
|
|
{
|
|
|
|
char buffer[BUFSIZE];
|
|
|
|
|
|
|
|
(void) read(s, buffer, sizeof(buffer));
|
|
|
|
}
|
|
|
|
|
|
|
|
#define LINESIZ 72
|
|
|
|
char ring[128];
|
|
|
|
char *endring;
|
|
|
|
|
2003-02-13 14:47:27 +03:00
|
|
|
static void
|
|
|
|
initring(void)
|
1993-03-21 12:45:37 +03:00
|
|
|
{
|
1997-03-13 20:22:23 +03:00
|
|
|
int i;
|
1993-03-21 12:45:37 +03:00
|
|
|
|
|
|
|
endring = ring;
|
|
|
|
|
|
|
|
for (i = 0; i <= 128; ++i)
|
|
|
|
if (isprint(i))
|
2021-08-30 21:21:11 +03:00
|
|
|
*endring++ = (char)i;
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ARGSUSED */
|
2003-02-13 14:47:27 +03:00
|
|
|
static void
|
2021-08-30 21:21:11 +03:00
|
|
|
chargen_stream(int s, struct servtab *sep) /* Character generator */
|
1993-03-21 12:45:37 +03:00
|
|
|
{
|
2009-01-09 00:37:20 +03:00
|
|
|
size_t len;
|
1997-03-13 20:22:23 +03:00
|
|
|
char *rs, text[LINESIZ+2];
|
1993-03-21 12:45:37 +03:00
|
|
|
|
1994-12-23 19:45:11 +03:00
|
|
|
inetd_setproctitle(sep->se_service, s);
|
1993-03-21 12:45:37 +03:00
|
|
|
|
2021-09-03 23:24:28 +03:00
|
|
|
if (endring == NULL) {
|
1993-03-21 12:45:37 +03:00
|
|
|
initring();
|
|
|
|
rs = ring;
|
|
|
|
}
|
|
|
|
|
|
|
|
text[LINESIZ] = '\r';
|
|
|
|
text[LINESIZ + 1] = '\n';
|
|
|
|
for (rs = ring;;) {
|
2021-08-30 21:21:11 +03:00
|
|
|
if ((len = (size_t)(endring - rs)) >= LINESIZ)
|
1997-03-13 20:22:23 +03:00
|
|
|
memmove(text, rs, LINESIZ);
|
1993-03-21 12:45:37 +03:00
|
|
|
else {
|
1997-03-13 20:22:23 +03:00
|
|
|
memmove(text, rs, len);
|
|
|
|
memmove(text + len, ring, LINESIZ - len);
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
|
|
|
if (++rs == endring)
|
|
|
|
rs = ring;
|
|
|
|
if (write(s, text, sizeof(text)) != sizeof(text))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ARGSUSED */
|
2003-02-13 14:47:27 +03:00
|
|
|
static void
|
|
|
|
chargen_dg(int s, struct servtab *sep) /* Character generator */
|
1993-03-21 12:45:37 +03:00
|
|
|
{
|
1999-09-15 13:59:41 +04:00
|
|
|
struct sockaddr_storage ss;
|
|
|
|
struct sockaddr *sa;
|
1993-03-21 12:45:37 +03:00
|
|
|
static char *rs;
|
2009-01-09 00:37:20 +03:00
|
|
|
size_t len;
|
2002-06-01 04:15:08 +04:00
|
|
|
socklen_t size;
|
1993-03-21 12:45:37 +03:00
|
|
|
char text[LINESIZ+2];
|
|
|
|
|
|
|
|
if (endring == 0) {
|
|
|
|
initring();
|
|
|
|
rs = ring;
|
|
|
|
}
|
|
|
|
|
2009-01-09 00:37:20 +03:00
|
|
|
sa = (struct sockaddr *)(void *)&ss;
|
1999-09-15 13:59:41 +04:00
|
|
|
size = sizeof(ss);
|
|
|
|
if (recvfrom(s, text, sizeof(text), 0, sa, &size) < 0)
|
1993-03-21 12:45:37 +03:00
|
|
|
return;
|
|
|
|
|
1999-09-15 13:59:41 +04:00
|
|
|
if (!port_good_dg(sa))
|
1999-04-11 19:40:58 +04:00
|
|
|
return;
|
|
|
|
|
2021-08-30 21:21:11 +03:00
|
|
|
if ((len = (size_t)(endring - rs)) >= LINESIZ)
|
1997-03-13 20:22:23 +03:00
|
|
|
memmove(text, rs, LINESIZ);
|
1993-03-21 12:45:37 +03:00
|
|
|
else {
|
1997-03-13 20:22:23 +03:00
|
|
|
memmove(text, rs, len);
|
|
|
|
memmove(text + len, ring, LINESIZ - len);
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
|
|
|
if (++rs == endring)
|
|
|
|
rs = ring;
|
|
|
|
text[LINESIZ] = '\r';
|
|
|
|
text[LINESIZ + 1] = '\n';
|
1999-09-15 13:59:41 +04:00
|
|
|
(void) sendto(s, text, sizeof(text), 0, sa, size);
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Return a machine readable date and time, in the form of the
|
|
|
|
* number of seconds since midnight, Jan 1, 1900. Since gettimeofday
|
|
|
|
* returns the number of seconds since midnight, Jan 1, 1970,
|
|
|
|
* we must add 2208988800 seconds to this figure to make up for
|
|
|
|
* some seventy years Bell Labs was asleep.
|
|
|
|
*/
|
|
|
|
|
2003-02-13 14:47:27 +03:00
|
|
|
static uint32_t
|
|
|
|
machtime(void)
|
1993-03-21 12:45:37 +03:00
|
|
|
{
|
|
|
|
struct timeval tv;
|
|
|
|
|
2003-02-12 11:52:03 +03:00
|
|
|
if (gettimeofday(&tv, NULL) < 0) {
|
Inetd enhancements by James Browning, Gabe Coffland, Alex Gavin, Solomon Ritzow
Described in:
https://www.mail-archive.com/tech-userlevel@netbsd.org/msg03114.html
And developed in:
https://github.com/ritzow/src/pull/1
From their notes:
All new functionality should be explained by the updated manpage.
The manpage has been refactored a bit: A new section "Directives"
has been added and the information about default hostnames and
IPsec directives has been moved there, and the new file include
directive information is also there.
getconfigent has the most major changes. A newline is no longer
read immediately, but is called only by a "goto more" (inside an
if(false) block). This allows multiple definitions or directives
to exist on a single line for anything that doesn't terminate using
a newline. This means a key-values service definition can be followed
by another key-values service definition, a positional definition,
or an ipsec, hostname, or .include directive on the same line.
memset is no longer used explicitly to clear the servtab structure,
a function init_servtab() is used instead, which uses a C struct
initializer.
The servtab se_group field is its own allocation now, and not just
a pointer into the user:group string.
Refactored some stuff out of getconfigent to separate functions
for use by parse_v2.c. These functions in inetd.c are named with
the form parse_*()
parse_v2.c only has code for parsing a key-values service definition
into a provided servtab. It should not have anything that affects
global state other than line and line_number.
Some function prototypes, structures, and #defines have been moved
from inetd.c to inetd.h.
The function config_root replaces config as the function called on
a config file load/reload. The code removed from the end of
config(void) is now called in config_root, so it is not run on each
recursive config call.
setconfig(void) was removed and its code added into config_root
because that is the only place it is called, and redundant checks
for non-null globals were removed because they are always freed by
endconfig. The fseek code was also removed because the config files
are always closed by endconfig.
Rate limiting code was updated to add a per-service per-IP rate
limiting form. Some of that code was refactored out of other places
into functions with names in the form rl_*()
We have not added any of the license or version information to the
new files parse_v2.c, parse_v2.h, and inetd.h and we have not
updated the license or version info for inetd.c.
Security related:
The behavior when reading invalid IPsec strings has changed. Inetd
no longer exits, it quits reading the current config file instead.
Could this impact program security?
We have not checked for memory leaks. Solomon tried to use dmalloc
without success. getconfigent seemed to have a memory leak at each
"goto more". It seems like inetd has never free'd allocated strings
when throwing away erroneous service definitions during parsing
(i.e. when "goto more" is called when parsing fields). OpenBSD's
version calls freeconfig on "goto more"
(https://github.com/openbsd/src/blob/c5eae130d6c937080c3d30d124e8c8b86db7d625/usr.sbin/inetd/inetd.c#L1049)
but NetBSD only calls it when service definitions are no longer
needed. This has been fixed. freeconfig is called immediately before
any "goto more". There shouldn't be any time when a servtab is in
an invalid state where freeconfig would break.
2021-08-29 12:54:18 +03:00
|
|
|
DPRINTF("Unable to get time of day");
|
2001-12-26 20:01:39 +03:00
|
|
|
return (0);
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
2001-12-26 20:01:39 +03:00
|
|
|
#define OFFSET ((uint32_t)25567 * 24*60*60)
|
|
|
|
return (htonl((uint32_t)(tv.tv_sec + OFFSET)));
|
1997-03-13 20:22:23 +03:00
|
|
|
#undef OFFSET
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ARGSUSED */
|
2003-02-13 14:47:27 +03:00
|
|
|
static void
|
|
|
|
machtime_stream(int s, struct servtab *sep)
|
1993-03-21 12:45:37 +03:00
|
|
|
{
|
2001-12-26 20:01:39 +03:00
|
|
|
uint32_t result;
|
1993-03-21 12:45:37 +03:00
|
|
|
|
|
|
|
result = machtime();
|
2009-01-09 00:37:20 +03:00
|
|
|
(void) write(s, &result, sizeof(result));
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ARGSUSED */
|
1997-03-13 20:22:23 +03:00
|
|
|
void
|
2003-02-13 14:47:27 +03:00
|
|
|
machtime_dg(int s, struct servtab *sep)
|
1993-03-21 12:45:37 +03:00
|
|
|
{
|
2001-12-26 20:01:39 +03:00
|
|
|
uint32_t result;
|
1999-09-15 13:59:41 +04:00
|
|
|
struct sockaddr_storage ss;
|
|
|
|
struct sockaddr *sa;
|
2002-06-01 04:15:08 +04:00
|
|
|
socklen_t size;
|
1993-03-21 12:45:37 +03:00
|
|
|
|
2009-01-09 00:37:20 +03:00
|
|
|
sa = (struct sockaddr *)(void *)&ss;
|
1999-09-15 13:59:41 +04:00
|
|
|
size = sizeof(ss);
|
2009-01-09 00:37:20 +03:00
|
|
|
if (recvfrom(s, &result, sizeof(result), 0, sa, &size) < 0)
|
1993-03-21 12:45:37 +03:00
|
|
|
return;
|
1999-09-15 13:59:41 +04:00
|
|
|
if (!port_good_dg(sa))
|
1999-04-11 19:40:58 +04:00
|
|
|
return;
|
1993-03-21 12:45:37 +03:00
|
|
|
result = machtime();
|
2009-01-09 00:37:20 +03:00
|
|
|
(void)sendto(s, &result, sizeof(result), 0, sa, size);
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ARGSUSED */
|
2003-02-13 14:47:27 +03:00
|
|
|
static void
|
|
|
|
daytime_stream(int s,struct servtab *sep)
|
|
|
|
/* Return human-readable time of day */
|
1993-03-21 12:45:37 +03:00
|
|
|
{
|
|
|
|
char buffer[256];
|
2009-01-09 00:37:20 +03:00
|
|
|
time_t clk;
|
1996-11-26 20:23:34 +03:00
|
|
|
int len;
|
1993-03-21 12:45:37 +03:00
|
|
|
|
2009-01-09 00:37:20 +03:00
|
|
|
clk = time((time_t *) 0);
|
1993-03-21 12:45:37 +03:00
|
|
|
|
2009-01-09 00:37:20 +03:00
|
|
|
len = snprintf(buffer, sizeof buffer, "%.24s\r\n", ctime(&clk));
|
2021-08-30 21:21:11 +03:00
|
|
|
(void) write(s, buffer, (size_t)len);
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ARGSUSED */
|
1997-03-13 20:22:23 +03:00
|
|
|
void
|
2003-02-13 14:47:27 +03:00
|
|
|
daytime_dg(int s, struct servtab *sep)
|
|
|
|
/* Return human-readable time of day */
|
1993-03-21 12:45:37 +03:00
|
|
|
{
|
|
|
|
char buffer[256];
|
2009-01-09 00:37:20 +03:00
|
|
|
time_t clk;
|
1999-09-15 13:59:41 +04:00
|
|
|
struct sockaddr_storage ss;
|
|
|
|
struct sockaddr *sa;
|
2002-06-01 04:15:08 +04:00
|
|
|
socklen_t size;
|
|
|
|
int len;
|
1993-03-21 12:45:37 +03:00
|
|
|
|
2009-01-09 00:37:20 +03:00
|
|
|
clk = time((time_t *) 0);
|
1993-03-21 12:45:37 +03:00
|
|
|
|
2009-01-09 00:37:20 +03:00
|
|
|
sa = (struct sockaddr *)(void *)&ss;
|
1999-09-15 13:59:41 +04:00
|
|
|
size = sizeof(ss);
|
|
|
|
if (recvfrom(s, buffer, sizeof(buffer), 0, sa, &size) < 0)
|
1993-03-21 12:45:37 +03:00
|
|
|
return;
|
1999-09-15 13:59:41 +04:00
|
|
|
if (!port_good_dg(sa))
|
1999-04-11 19:40:58 +04:00
|
|
|
return;
|
2009-01-09 00:37:20 +03:00
|
|
|
len = snprintf(buffer, sizeof buffer, "%.24s\r\n", ctime(&clk));
|
2021-08-30 21:21:11 +03:00
|
|
|
(void) sendto(s, buffer, (size_t)len, 0, sa, size);
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
|
|
|
|
2003-02-13 14:47:27 +03:00
|
|
|
static void
|
|
|
|
usage(void)
|
1997-03-13 20:22:23 +03:00
|
|
|
{
|
|
|
|
#ifdef LIBWRAP
|
2001-02-20 02:22:40 +03:00
|
|
|
(void)fprintf(stderr, "usage: %s [-dl] [conf]\n", getprogname());
|
1997-03-13 20:22:23 +03:00
|
|
|
#else
|
2001-02-20 02:22:40 +03:00
|
|
|
(void)fprintf(stderr, "usage: %s [-d] [conf]\n", getprogname());
|
1997-03-13 20:22:23 +03:00
|
|
|
#endif
|
Inetd enhancements by James Browning, Gabe Coffland, Alex Gavin, Solomon Ritzow
Described in:
https://www.mail-archive.com/tech-userlevel@netbsd.org/msg03114.html
And developed in:
https://github.com/ritzow/src/pull/1
From their notes:
All new functionality should be explained by the updated manpage.
The manpage has been refactored a bit: A new section "Directives"
has been added and the information about default hostnames and
IPsec directives has been moved there, and the new file include
directive information is also there.
getconfigent has the most major changes. A newline is no longer
read immediately, but is called only by a "goto more" (inside an
if(false) block). This allows multiple definitions or directives
to exist on a single line for anything that doesn't terminate using
a newline. This means a key-values service definition can be followed
by another key-values service definition, a positional definition,
or an ipsec, hostname, or .include directive on the same line.
memset is no longer used explicitly to clear the servtab structure,
a function init_servtab() is used instead, which uses a C struct
initializer.
The servtab se_group field is its own allocation now, and not just
a pointer into the user:group string.
Refactored some stuff out of getconfigent to separate functions
for use by parse_v2.c. These functions in inetd.c are named with
the form parse_*()
parse_v2.c only has code for parsing a key-values service definition
into a provided servtab. It should not have anything that affects
global state other than line and line_number.
Some function prototypes, structures, and #defines have been moved
from inetd.c to inetd.h.
The function config_root replaces config as the function called on
a config file load/reload. The code removed from the end of
config(void) is now called in config_root, so it is not run on each
recursive config call.
setconfig(void) was removed and its code added into config_root
because that is the only place it is called, and redundant checks
for non-null globals were removed because they are always freed by
endconfig. The fseek code was also removed because the config files
are always closed by endconfig.
Rate limiting code was updated to add a per-service per-IP rate
limiting form. Some of that code was refactored out of other places
into functions with names in the form rl_*()
We have not added any of the license or version information to the
new files parse_v2.c, parse_v2.h, and inetd.h and we have not
updated the license or version info for inetd.c.
Security related:
The behavior when reading invalid IPsec strings has changed. Inetd
no longer exits, it quits reading the current config file instead.
Could this impact program security?
We have not checked for memory leaks. Solomon tried to use dmalloc
without success. getconfigent seemed to have a memory leak at each
"goto more". It seems like inetd has never free'd allocated strings
when throwing away erroneous service definitions during parsing
(i.e. when "goto more" is called when parsing fields). OpenBSD's
version calls freeconfig on "goto more"
(https://github.com/openbsd/src/blob/c5eae130d6c937080c3d30d124e8c8b86db7d625/usr.sbin/inetd/inetd.c#L1049)
but NetBSD only calls it when service definitions are no longer
needed. This has been fixed. freeconfig is called immediately before
any "goto more". There shouldn't be any time when a servtab is in
an invalid state where freeconfig would break.
2021-08-29 12:54:18 +03:00
|
|
|
exit(EXIT_FAILURE);
|
1997-03-13 20:22:23 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Based on TCPMUX.C by Mark K. Lottor November 1988
|
|
|
|
* sri-nic::ps:<mkl>tcpmux.c
|
|
|
|
*/
|
|
|
|
|
|
|
|
static int /* # of characters upto \r,\n or \0 */
|
2009-07-13 23:05:39 +04:00
|
|
|
get_line(int fd, char *buf, int len)
|
1997-03-13 20:22:23 +03:00
|
|
|
{
|
2009-01-09 00:37:20 +03:00
|
|
|
int count = 0;
|
|
|
|
ssize_t n;
|
1997-03-13 20:22:23 +03:00
|
|
|
|
|
|
|
do {
|
2021-08-30 21:21:11 +03:00
|
|
|
n = read(fd, buf, (size_t)(len - count));
|
1997-03-13 20:22:23 +03:00
|
|
|
if (n == 0)
|
|
|
|
return (count);
|
|
|
|
if (n < 0)
|
|
|
|
return (-1);
|
|
|
|
while (--n >= 0) {
|
|
|
|
if (*buf == '\r' || *buf == '\n' || *buf == '\0')
|
|
|
|
return (count);
|
|
|
|
count++;
|
|
|
|
buf++;
|
|
|
|
}
|
|
|
|
} while (count < len);
|
|
|
|
return (count);
|
|
|
|
}
|
|
|
|
|
|
|
|
#define MAX_SERV_LEN (256+2) /* 2 bytes for \r\n */
|
|
|
|
|
|
|
|
#define strwrite(fd, buf) (void) write(fd, buf, sizeof(buf)-1)
|
|
|
|
|
2003-02-13 14:47:27 +03:00
|
|
|
static void
|
|
|
|
tcpmux(int ctrl, struct servtab *sep)
|
1997-03-13 23:15:04 +03:00
|
|
|
{
|
1997-03-13 20:22:23 +03:00
|
|
|
char service[MAX_SERV_LEN+1];
|
|
|
|
int len;
|
|
|
|
|
|
|
|
/* Get requested service name */
|
2009-07-13 23:05:39 +04:00
|
|
|
if ((len = get_line(ctrl, service, MAX_SERV_LEN)) < 0) {
|
1997-03-13 23:15:04 +03:00
|
|
|
strwrite(ctrl, "-Error reading service name\r\n");
|
|
|
|
goto reject;
|
1997-03-13 20:22:23 +03:00
|
|
|
}
|
|
|
|
service[len] = '\0';
|
|
|
|
|
Inetd enhancements by James Browning, Gabe Coffland, Alex Gavin, Solomon Ritzow
Described in:
https://www.mail-archive.com/tech-userlevel@netbsd.org/msg03114.html
And developed in:
https://github.com/ritzow/src/pull/1
From their notes:
All new functionality should be explained by the updated manpage.
The manpage has been refactored a bit: A new section "Directives"
has been added and the information about default hostnames and
IPsec directives has been moved there, and the new file include
directive information is also there.
getconfigent has the most major changes. A newline is no longer
read immediately, but is called only by a "goto more" (inside an
if(false) block). This allows multiple definitions or directives
to exist on a single line for anything that doesn't terminate using
a newline. This means a key-values service definition can be followed
by another key-values service definition, a positional definition,
or an ipsec, hostname, or .include directive on the same line.
memset is no longer used explicitly to clear the servtab structure,
a function init_servtab() is used instead, which uses a C struct
initializer.
The servtab se_group field is its own allocation now, and not just
a pointer into the user:group string.
Refactored some stuff out of getconfigent to separate functions
for use by parse_v2.c. These functions in inetd.c are named with
the form parse_*()
parse_v2.c only has code for parsing a key-values service definition
into a provided servtab. It should not have anything that affects
global state other than line and line_number.
Some function prototypes, structures, and #defines have been moved
from inetd.c to inetd.h.
The function config_root replaces config as the function called on
a config file load/reload. The code removed from the end of
config(void) is now called in config_root, so it is not run on each
recursive config call.
setconfig(void) was removed and its code added into config_root
because that is the only place it is called, and redundant checks
for non-null globals were removed because they are always freed by
endconfig. The fseek code was also removed because the config files
are always closed by endconfig.
Rate limiting code was updated to add a per-service per-IP rate
limiting form. Some of that code was refactored out of other places
into functions with names in the form rl_*()
We have not added any of the license or version information to the
new files parse_v2.c, parse_v2.h, and inetd.h and we have not
updated the license or version info for inetd.c.
Security related:
The behavior when reading invalid IPsec strings has changed. Inetd
no longer exits, it quits reading the current config file instead.
Could this impact program security?
We have not checked for memory leaks. Solomon tried to use dmalloc
without success. getconfigent seemed to have a memory leak at each
"goto more". It seems like inetd has never free'd allocated strings
when throwing away erroneous service definitions during parsing
(i.e. when "goto more" is called when parsing fields). OpenBSD's
version calls freeconfig on "goto more"
(https://github.com/openbsd/src/blob/c5eae130d6c937080c3d30d124e8c8b86db7d625/usr.sbin/inetd/inetd.c#L1049)
but NetBSD only calls it when service definitions are no longer
needed. This has been fixed. freeconfig is called immediately before
any "goto more". There shouldn't be any time when a servtab is in
an invalid state where freeconfig would break.
2021-08-29 12:54:18 +03:00
|
|
|
DPRINTF("tcpmux: %s: service requested", service);
|
1997-03-13 20:22:23 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Help is a required command, and lists available services,
|
|
|
|
* one per line.
|
|
|
|
*/
|
2021-09-03 23:24:28 +03:00
|
|
|
if (strcasecmp(service, "help") == 0) {
|
1997-03-14 06:18:25 +03:00
|
|
|
strwrite(ctrl, "+Available services:\r\n");
|
|
|
|
strwrite(ctrl, "help\r\n");
|
2003-02-12 11:52:03 +03:00
|
|
|
for (sep = servtab; sep != NULL; sep = sep->se_next) {
|
1997-03-13 20:22:23 +03:00
|
|
|
if (!ISMUX(sep))
|
|
|
|
continue;
|
1997-03-13 23:15:04 +03:00
|
|
|
(void)write(ctrl, sep->se_service,
|
|
|
|
strlen(sep->se_service));
|
|
|
|
strwrite(ctrl, "\r\n");
|
1997-03-13 20:22:23 +03:00
|
|
|
}
|
1997-03-13 23:15:04 +03:00
|
|
|
goto reject;
|
1997-03-13 20:22:23 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Try matching a service in inetd.conf with the request */
|
2003-02-12 11:52:03 +03:00
|
|
|
for (sep = servtab; sep != NULL; sep = sep->se_next) {
|
1997-03-13 20:22:23 +03:00
|
|
|
if (!ISMUX(sep))
|
|
|
|
continue;
|
2021-09-03 23:24:28 +03:00
|
|
|
if (strcasecmp(service, sep->se_service) == 0) {
|
1997-03-13 23:15:04 +03:00
|
|
|
if (ISMUXPLUS(sep))
|
|
|
|
strwrite(ctrl, "+Go\r\n");
|
2021-09-03 23:24:28 +03:00
|
|
|
run_service(ctrl, sep, true /* forked */);
|
1997-03-13 23:15:04 +03:00
|
|
|
return;
|
1997-03-13 20:22:23 +03:00
|
|
|
}
|
|
|
|
}
|
1997-03-13 23:15:04 +03:00
|
|
|
strwrite(ctrl, "-Service not available\r\n");
|
|
|
|
reject:
|
Inetd enhancements by James Browning, Gabe Coffland, Alex Gavin, Solomon Ritzow
Described in:
https://www.mail-archive.com/tech-userlevel@netbsd.org/msg03114.html
And developed in:
https://github.com/ritzow/src/pull/1
From their notes:
All new functionality should be explained by the updated manpage.
The manpage has been refactored a bit: A new section "Directives"
has been added and the information about default hostnames and
IPsec directives has been moved there, and the new file include
directive information is also there.
getconfigent has the most major changes. A newline is no longer
read immediately, but is called only by a "goto more" (inside an
if(false) block). This allows multiple definitions or directives
to exist on a single line for anything that doesn't terminate using
a newline. This means a key-values service definition can be followed
by another key-values service definition, a positional definition,
or an ipsec, hostname, or .include directive on the same line.
memset is no longer used explicitly to clear the servtab structure,
a function init_servtab() is used instead, which uses a C struct
initializer.
The servtab se_group field is its own allocation now, and not just
a pointer into the user:group string.
Refactored some stuff out of getconfigent to separate functions
for use by parse_v2.c. These functions in inetd.c are named with
the form parse_*()
parse_v2.c only has code for parsing a key-values service definition
into a provided servtab. It should not have anything that affects
global state other than line and line_number.
Some function prototypes, structures, and #defines have been moved
from inetd.c to inetd.h.
The function config_root replaces config as the function called on
a config file load/reload. The code removed from the end of
config(void) is now called in config_root, so it is not run on each
recursive config call.
setconfig(void) was removed and its code added into config_root
because that is the only place it is called, and redundant checks
for non-null globals were removed because they are always freed by
endconfig. The fseek code was also removed because the config files
are always closed by endconfig.
Rate limiting code was updated to add a per-service per-IP rate
limiting form. Some of that code was refactored out of other places
into functions with names in the form rl_*()
We have not added any of the license or version information to the
new files parse_v2.c, parse_v2.h, and inetd.h and we have not
updated the license or version info for inetd.c.
Security related:
The behavior when reading invalid IPsec strings has changed. Inetd
no longer exits, it quits reading the current config file instead.
Could this impact program security?
We have not checked for memory leaks. Solomon tried to use dmalloc
without success. getconfigent seemed to have a memory leak at each
"goto more". It seems like inetd has never free'd allocated strings
when throwing away erroneous service definitions during parsing
(i.e. when "goto more" is called when parsing fields). OpenBSD's
version calls freeconfig on "goto more"
(https://github.com/openbsd/src/blob/c5eae130d6c937080c3d30d124e8c8b86db7d625/usr.sbin/inetd/inetd.c#L1049)
but NetBSD only calls it when service definitions are no longer
needed. This has been fixed. freeconfig is called immediately before
any "goto more". There shouldn't be any time when a servtab is in
an invalid state where freeconfig would break.
2021-08-29 12:54:18 +03:00
|
|
|
_exit(EXIT_FAILURE);
|
1997-03-13 20:22:23 +03:00
|
|
|
}
|
|
|
|
|
1999-04-11 19:40:58 +04:00
|
|
|
/*
|
2000-08-01 22:42:08 +04:00
|
|
|
* check if the address/port where send data to is one of the obvious ports
|
1999-04-11 19:40:58 +04:00
|
|
|
* that are used for denial of service attacks like two echo ports
|
|
|
|
* just echoing data between them
|
|
|
|
*/
|
2003-02-13 14:47:27 +03:00
|
|
|
static int
|
|
|
|
port_good_dg(struct sockaddr *sa)
|
1999-04-11 19:40:58 +04:00
|
|
|
{
|
2000-08-01 22:42:08 +04:00
|
|
|
struct in_addr in;
|
2009-01-09 00:37:20 +03:00
|
|
|
struct sockaddr_in *sin;
|
2000-08-01 22:42:08 +04:00
|
|
|
#ifdef INET6
|
|
|
|
struct in6_addr *in6;
|
2009-01-09 00:37:20 +03:00
|
|
|
struct sockaddr_in6 *sin6;
|
2000-08-01 22:42:08 +04:00
|
|
|
#endif
|
1999-04-11 19:40:58 +04:00
|
|
|
u_int16_t port;
|
2009-01-09 00:37:20 +03:00
|
|
|
int i;
|
2000-01-27 22:52:43 +03:00
|
|
|
char hbuf[NI_MAXHOST];
|
1999-04-11 19:40:58 +04:00
|
|
|
|
1999-09-15 13:59:41 +04:00
|
|
|
switch (sa->sa_family) {
|
|
|
|
case AF_INET:
|
2009-01-09 00:37:20 +03:00
|
|
|
sin = (struct sockaddr_in *)(void *)sa;
|
|
|
|
in.s_addr = ntohl(sin->sin_addr.s_addr);
|
|
|
|
port = ntohs(sin->sin_port);
|
2004-10-20 15:37:42 +04:00
|
|
|
#ifdef INET6
|
2000-08-01 22:42:08 +04:00
|
|
|
v4chk:
|
2004-10-20 15:37:42 +04:00
|
|
|
#endif
|
2000-08-01 22:42:08 +04:00
|
|
|
if (IN_MULTICAST(in.s_addr))
|
|
|
|
goto bad;
|
|
|
|
switch ((in.s_addr & 0xff000000) >> 24) {
|
|
|
|
case 0: case 127: case 255:
|
|
|
|
goto bad;
|
|
|
|
}
|
2002-06-05 14:03:31 +04:00
|
|
|
if (dg_broadcast(&in))
|
|
|
|
goto bad;
|
1999-09-15 13:59:41 +04:00
|
|
|
break;
|
2000-01-31 17:28:17 +03:00
|
|
|
#ifdef INET6
|
1999-09-15 13:59:41 +04:00
|
|
|
case AF_INET6:
|
2009-01-09 00:37:20 +03:00
|
|
|
sin6 = (struct sockaddr_in6 *)(void *)sa;
|
|
|
|
in6 = &sin6->sin6_addr;
|
|
|
|
port = ntohs(sin6->sin6_port);
|
2000-08-01 22:42:08 +04:00
|
|
|
if (IN6_IS_ADDR_MULTICAST(in6) || IN6_IS_ADDR_UNSPECIFIED(in6))
|
|
|
|
goto bad;
|
|
|
|
if (IN6_IS_ADDR_V4MAPPED(in6) || IN6_IS_ADDR_V4COMPAT(in6)) {
|
|
|
|
memcpy(&in, &in6->s6_addr[12], sizeof(in));
|
|
|
|
in.s_addr = ntohl(in.s_addr);
|
|
|
|
goto v4chk;
|
|
|
|
}
|
1999-09-15 13:59:41 +04:00
|
|
|
break;
|
2000-01-31 17:28:17 +03:00
|
|
|
#endif
|
1999-09-15 13:59:41 +04:00
|
|
|
default:
|
|
|
|
/* XXX unsupported af, is it safe to assume it to be safe? */
|
2021-09-03 23:24:28 +03:00
|
|
|
return true;
|
1999-09-15 13:59:41 +04:00
|
|
|
}
|
1999-04-11 19:40:58 +04:00
|
|
|
|
2000-08-01 22:42:08 +04:00
|
|
|
for (i = 0; bad_ports[i] != 0; i++) {
|
|
|
|
if (port == bad_ports[i])
|
|
|
|
goto bad;
|
|
|
|
}
|
1999-04-11 19:40:58 +04:00
|
|
|
|
2021-09-03 23:24:28 +03:00
|
|
|
return true;
|
1999-04-11 19:40:58 +04:00
|
|
|
|
2000-08-01 22:42:08 +04:00
|
|
|
bad:
|
2009-01-09 00:37:20 +03:00
|
|
|
if (getnameinfo(sa, sa->sa_len, hbuf, (socklen_t)sizeof(hbuf), NULL, 0,
|
2002-06-01 04:32:41 +04:00
|
|
|
niflags) != 0)
|
2003-07-13 17:54:02 +04:00
|
|
|
strlcpy(hbuf, "?", sizeof(hbuf));
|
2000-08-01 22:42:08 +04:00
|
|
|
syslog(LOG_WARNING,"Possible DoS attack from %s, Port %d",
|
|
|
|
hbuf, port);
|
2021-09-03 23:24:28 +03:00
|
|
|
return false;
|
2000-08-01 22:42:08 +04:00
|
|
|
}
|
2002-06-05 14:03:31 +04:00
|
|
|
|
|
|
|
/* XXX need optimization */
|
2003-02-13 14:47:27 +03:00
|
|
|
static int
|
|
|
|
dg_broadcast(struct in_addr *in)
|
2002-06-05 14:03:31 +04:00
|
|
|
{
|
|
|
|
struct ifaddrs *ifa, *ifap;
|
|
|
|
struct sockaddr_in *sin;
|
|
|
|
|
|
|
|
if (getifaddrs(&ifap) < 0)
|
2021-09-03 23:24:28 +03:00
|
|
|
return false;
|
|
|
|
for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
|
2002-06-05 14:03:31 +04:00
|
|
|
if (ifa->ifa_addr->sa_family != AF_INET ||
|
|
|
|
(ifa->ifa_flags & IFF_BROADCAST) == 0)
|
|
|
|
continue;
|
2009-01-09 00:37:20 +03:00
|
|
|
sin = (struct sockaddr_in *)(void *)ifa->ifa_broadaddr;
|
2002-06-05 14:03:31 +04:00
|
|
|
if (sin->sin_addr.s_addr == in->s_addr) {
|
|
|
|
freeifaddrs(ifap);
|
2021-09-03 23:24:28 +03:00
|
|
|
return true;
|
2002-06-05 14:03:31 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
freeifaddrs(ifap);
|
2021-09-03 23:24:28 +03:00
|
|
|
return false;
|
2002-06-05 14:03:31 +04:00
|
|
|
}
|
2003-02-12 11:52:03 +03:00
|
|
|
|
|
|
|
static int
|
|
|
|
my_kevent(const struct kevent *changelist, size_t nchanges,
|
|
|
|
struct kevent *eventlist, size_t nevents)
|
|
|
|
{
|
|
|
|
int result;
|
|
|
|
|
|
|
|
while ((result = kevent(kq, changelist, nchanges, eventlist, nevents,
|
|
|
|
NULL)) < 0)
|
|
|
|
if (errno != EINTR) {
|
|
|
|
syslog(LOG_ERR, "kevent: %m");
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
|
|
|
|
return (result);
|
|
|
|
}
|
2003-02-13 14:47:27 +03:00
|
|
|
|
|
|
|
static struct kevent *
|
|
|
|
allocchange(void)
|
|
|
|
{
|
Inetd enhancements by James Browning, Gabe Coffland, Alex Gavin, Solomon Ritzow
Described in:
https://www.mail-archive.com/tech-userlevel@netbsd.org/msg03114.html
And developed in:
https://github.com/ritzow/src/pull/1
From their notes:
All new functionality should be explained by the updated manpage.
The manpage has been refactored a bit: A new section "Directives"
has been added and the information about default hostnames and
IPsec directives has been moved there, and the new file include
directive information is also there.
getconfigent has the most major changes. A newline is no longer
read immediately, but is called only by a "goto more" (inside an
if(false) block). This allows multiple definitions or directives
to exist on a single line for anything that doesn't terminate using
a newline. This means a key-values service definition can be followed
by another key-values service definition, a positional definition,
or an ipsec, hostname, or .include directive on the same line.
memset is no longer used explicitly to clear the servtab structure,
a function init_servtab() is used instead, which uses a C struct
initializer.
The servtab se_group field is its own allocation now, and not just
a pointer into the user:group string.
Refactored some stuff out of getconfigent to separate functions
for use by parse_v2.c. These functions in inetd.c are named with
the form parse_*()
parse_v2.c only has code for parsing a key-values service definition
into a provided servtab. It should not have anything that affects
global state other than line and line_number.
Some function prototypes, structures, and #defines have been moved
from inetd.c to inetd.h.
The function config_root replaces config as the function called on
a config file load/reload. The code removed from the end of
config(void) is now called in config_root, so it is not run on each
recursive config call.
setconfig(void) was removed and its code added into config_root
because that is the only place it is called, and redundant checks
for non-null globals were removed because they are always freed by
endconfig. The fseek code was also removed because the config files
are always closed by endconfig.
Rate limiting code was updated to add a per-service per-IP rate
limiting form. Some of that code was refactored out of other places
into functions with names in the form rl_*()
We have not added any of the license or version information to the
new files parse_v2.c, parse_v2.h, and inetd.h and we have not
updated the license or version info for inetd.c.
Security related:
The behavior when reading invalid IPsec strings has changed. Inetd
no longer exits, it quits reading the current config file instead.
Could this impact program security?
We have not checked for memory leaks. Solomon tried to use dmalloc
without success. getconfigent seemed to have a memory leak at each
"goto more". It seems like inetd has never free'd allocated strings
when throwing away erroneous service definitions during parsing
(i.e. when "goto more" is called when parsing fields). OpenBSD's
version calls freeconfig on "goto more"
(https://github.com/openbsd/src/blob/c5eae130d6c937080c3d30d124e8c8b86db7d625/usr.sbin/inetd/inetd.c#L1049)
but NetBSD only calls it when service definitions are no longer
needed. This has been fixed. freeconfig is called immediately before
any "goto more". There shouldn't be any time when a servtab is in
an invalid state where freeconfig would break.
2021-08-29 12:54:18 +03:00
|
|
|
if (changes == __arraycount(changebuf)) {
|
|
|
|
(void) my_kevent(changebuf, __arraycount(changebuf), NULL, 0);
|
2003-02-13 14:47:27 +03:00
|
|
|
changes = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (&changebuf[changes++]);
|
|
|
|
}
|
Inetd enhancements by James Browning, Gabe Coffland, Alex Gavin, Solomon Ritzow
Described in:
https://www.mail-archive.com/tech-userlevel@netbsd.org/msg03114.html
And developed in:
https://github.com/ritzow/src/pull/1
From their notes:
All new functionality should be explained by the updated manpage.
The manpage has been refactored a bit: A new section "Directives"
has been added and the information about default hostnames and
IPsec directives has been moved there, and the new file include
directive information is also there.
getconfigent has the most major changes. A newline is no longer
read immediately, but is called only by a "goto more" (inside an
if(false) block). This allows multiple definitions or directives
to exist on a single line for anything that doesn't terminate using
a newline. This means a key-values service definition can be followed
by another key-values service definition, a positional definition,
or an ipsec, hostname, or .include directive on the same line.
memset is no longer used explicitly to clear the servtab structure,
a function init_servtab() is used instead, which uses a C struct
initializer.
The servtab se_group field is its own allocation now, and not just
a pointer into the user:group string.
Refactored some stuff out of getconfigent to separate functions
for use by parse_v2.c. These functions in inetd.c are named with
the form parse_*()
parse_v2.c only has code for parsing a key-values service definition
into a provided servtab. It should not have anything that affects
global state other than line and line_number.
Some function prototypes, structures, and #defines have been moved
from inetd.c to inetd.h.
The function config_root replaces config as the function called on
a config file load/reload. The code removed from the end of
config(void) is now called in config_root, so it is not run on each
recursive config call.
setconfig(void) was removed and its code added into config_root
because that is the only place it is called, and redundant checks
for non-null globals were removed because they are always freed by
endconfig. The fseek code was also removed because the config files
are always closed by endconfig.
Rate limiting code was updated to add a per-service per-IP rate
limiting form. Some of that code was refactored out of other places
into functions with names in the form rl_*()
We have not added any of the license or version information to the
new files parse_v2.c, parse_v2.h, and inetd.h and we have not
updated the license or version info for inetd.c.
Security related:
The behavior when reading invalid IPsec strings has changed. Inetd
no longer exits, it quits reading the current config file instead.
Could this impact program security?
We have not checked for memory leaks. Solomon tried to use dmalloc
without success. getconfigent seemed to have a memory leak at each
"goto more". It seems like inetd has never free'd allocated strings
when throwing away erroneous service definitions during parsing
(i.e. when "goto more" is called when parsing fields). OpenBSD's
version calls freeconfig on "goto more"
(https://github.com/openbsd/src/blob/c5eae130d6c937080c3d30d124e8c8b86db7d625/usr.sbin/inetd/inetd.c#L1049)
but NetBSD only calls it when service definitions are no longer
needed. This has been fixed. freeconfig is called immediately before
any "goto more". There shouldn't be any time when a servtab is in
an invalid state where freeconfig would break.
2021-08-29 12:54:18 +03:00
|
|
|
|
2021-10-12 22:08:04 +03:00
|
|
|
bool
|
|
|
|
try_biltin(struct servtab *sep)
|
Inetd enhancements by James Browning, Gabe Coffland, Alex Gavin, Solomon Ritzow
Described in:
https://www.mail-archive.com/tech-userlevel@netbsd.org/msg03114.html
And developed in:
https://github.com/ritzow/src/pull/1
From their notes:
All new functionality should be explained by the updated manpage.
The manpage has been refactored a bit: A new section "Directives"
has been added and the information about default hostnames and
IPsec directives has been moved there, and the new file include
directive information is also there.
getconfigent has the most major changes. A newline is no longer
read immediately, but is called only by a "goto more" (inside an
if(false) block). This allows multiple definitions or directives
to exist on a single line for anything that doesn't terminate using
a newline. This means a key-values service definition can be followed
by another key-values service definition, a positional definition,
or an ipsec, hostname, or .include directive on the same line.
memset is no longer used explicitly to clear the servtab structure,
a function init_servtab() is used instead, which uses a C struct
initializer.
The servtab se_group field is its own allocation now, and not just
a pointer into the user:group string.
Refactored some stuff out of getconfigent to separate functions
for use by parse_v2.c. These functions in inetd.c are named with
the form parse_*()
parse_v2.c only has code for parsing a key-values service definition
into a provided servtab. It should not have anything that affects
global state other than line and line_number.
Some function prototypes, structures, and #defines have been moved
from inetd.c to inetd.h.
The function config_root replaces config as the function called on
a config file load/reload. The code removed from the end of
config(void) is now called in config_root, so it is not run on each
recursive config call.
setconfig(void) was removed and its code added into config_root
because that is the only place it is called, and redundant checks
for non-null globals were removed because they are always freed by
endconfig. The fseek code was also removed because the config files
are always closed by endconfig.
Rate limiting code was updated to add a per-service per-IP rate
limiting form. Some of that code was refactored out of other places
into functions with names in the form rl_*()
We have not added any of the license or version information to the
new files parse_v2.c, parse_v2.h, and inetd.h and we have not
updated the license or version info for inetd.c.
Security related:
The behavior when reading invalid IPsec strings has changed. Inetd
no longer exits, it quits reading the current config file instead.
Could this impact program security?
We have not checked for memory leaks. Solomon tried to use dmalloc
without success. getconfigent seemed to have a memory leak at each
"goto more". It seems like inetd has never free'd allocated strings
when throwing away erroneous service definitions during parsing
(i.e. when "goto more" is called when parsing fields). OpenBSD's
version calls freeconfig on "goto more"
(https://github.com/openbsd/src/blob/c5eae130d6c937080c3d30d124e8c8b86db7d625/usr.sbin/inetd/inetd.c#L1049)
but NetBSD only calls it when service definitions are no longer
needed. This has been fixed. freeconfig is called immediately before
any "goto more". There shouldn't be any time when a servtab is in
an invalid state where freeconfig would break.
2021-08-29 12:54:18 +03:00
|
|
|
{
|
2021-10-12 22:08:04 +03:00
|
|
|
for(size_t i = 0; i < __arraycount(biltins); i++) {
|
|
|
|
if (biltins[i].bi_socktype == sep->se_socktype &&
|
|
|
|
strcmp(biltins[i].bi_service, sep->se_service) == 0) {
|
|
|
|
sep->se_bi = &biltins[i];
|
|
|
|
sep->se_wait = biltins[i].bi_wait;
|
|
|
|
return true;
|
Inetd enhancements by James Browning, Gabe Coffland, Alex Gavin, Solomon Ritzow
Described in:
https://www.mail-archive.com/tech-userlevel@netbsd.org/msg03114.html
And developed in:
https://github.com/ritzow/src/pull/1
From their notes:
All new functionality should be explained by the updated manpage.
The manpage has been refactored a bit: A new section "Directives"
has been added and the information about default hostnames and
IPsec directives has been moved there, and the new file include
directive information is also there.
getconfigent has the most major changes. A newline is no longer
read immediately, but is called only by a "goto more" (inside an
if(false) block). This allows multiple definitions or directives
to exist on a single line for anything that doesn't terminate using
a newline. This means a key-values service definition can be followed
by another key-values service definition, a positional definition,
or an ipsec, hostname, or .include directive on the same line.
memset is no longer used explicitly to clear the servtab structure,
a function init_servtab() is used instead, which uses a C struct
initializer.
The servtab se_group field is its own allocation now, and not just
a pointer into the user:group string.
Refactored some stuff out of getconfigent to separate functions
for use by parse_v2.c. These functions in inetd.c are named with
the form parse_*()
parse_v2.c only has code for parsing a key-values service definition
into a provided servtab. It should not have anything that affects
global state other than line and line_number.
Some function prototypes, structures, and #defines have been moved
from inetd.c to inetd.h.
The function config_root replaces config as the function called on
a config file load/reload. The code removed from the end of
config(void) is now called in config_root, so it is not run on each
recursive config call.
setconfig(void) was removed and its code added into config_root
because that is the only place it is called, and redundant checks
for non-null globals were removed because they are always freed by
endconfig. The fseek code was also removed because the config files
are always closed by endconfig.
Rate limiting code was updated to add a per-service per-IP rate
limiting form. Some of that code was refactored out of other places
into functions with names in the form rl_*()
We have not added any of the license or version information to the
new files parse_v2.c, parse_v2.h, and inetd.h and we have not
updated the license or version info for inetd.c.
Security related:
The behavior when reading invalid IPsec strings has changed. Inetd
no longer exits, it quits reading the current config file instead.
Could this impact program security?
We have not checked for memory leaks. Solomon tried to use dmalloc
without success. getconfigent seemed to have a memory leak at each
"goto more". It seems like inetd has never free'd allocated strings
when throwing away erroneous service definitions during parsing
(i.e. when "goto more" is called when parsing fields). OpenBSD's
version calls freeconfig on "goto more"
(https://github.com/openbsd/src/blob/c5eae130d6c937080c3d30d124e8c8b86db7d625/usr.sbin/inetd/inetd.c#L1049)
but NetBSD only calls it when service definitions are no longer
needed. This has been fixed. freeconfig is called immediately before
any "goto more". There shouldn't be any time when a servtab is in
an invalid state where freeconfig would break.
2021-08-29 12:54:18 +03:00
|
|
|
}
|
|
|
|
}
|
2021-10-12 22:08:04 +03:00
|
|
|
return false;
|
Inetd enhancements by James Browning, Gabe Coffland, Alex Gavin, Solomon Ritzow
Described in:
https://www.mail-archive.com/tech-userlevel@netbsd.org/msg03114.html
And developed in:
https://github.com/ritzow/src/pull/1
From their notes:
All new functionality should be explained by the updated manpage.
The manpage has been refactored a bit: A new section "Directives"
has been added and the information about default hostnames and
IPsec directives has been moved there, and the new file include
directive information is also there.
getconfigent has the most major changes. A newline is no longer
read immediately, but is called only by a "goto more" (inside an
if(false) block). This allows multiple definitions or directives
to exist on a single line for anything that doesn't terminate using
a newline. This means a key-values service definition can be followed
by another key-values service definition, a positional definition,
or an ipsec, hostname, or .include directive on the same line.
memset is no longer used explicitly to clear the servtab structure,
a function init_servtab() is used instead, which uses a C struct
initializer.
The servtab se_group field is its own allocation now, and not just
a pointer into the user:group string.
Refactored some stuff out of getconfigent to separate functions
for use by parse_v2.c. These functions in inetd.c are named with
the form parse_*()
parse_v2.c only has code for parsing a key-values service definition
into a provided servtab. It should not have anything that affects
global state other than line and line_number.
Some function prototypes, structures, and #defines have been moved
from inetd.c to inetd.h.
The function config_root replaces config as the function called on
a config file load/reload. The code removed from the end of
config(void) is now called in config_root, so it is not run on each
recursive config call.
setconfig(void) was removed and its code added into config_root
because that is the only place it is called, and redundant checks
for non-null globals were removed because they are always freed by
endconfig. The fseek code was also removed because the config files
are always closed by endconfig.
Rate limiting code was updated to add a per-service per-IP rate
limiting form. Some of that code was refactored out of other places
into functions with names in the form rl_*()
We have not added any of the license or version information to the
new files parse_v2.c, parse_v2.h, and inetd.h and we have not
updated the license or version info for inetd.c.
Security related:
The behavior when reading invalid IPsec strings has changed. Inetd
no longer exits, it quits reading the current config file instead.
Could this impact program security?
We have not checked for memory leaks. Solomon tried to use dmalloc
without success. getconfigent seemed to have a memory leak at each
"goto more". It seems like inetd has never free'd allocated strings
when throwing away erroneous service definitions during parsing
(i.e. when "goto more" is called when parsing fields). OpenBSD's
version calls freeconfig on "goto more"
(https://github.com/openbsd/src/blob/c5eae130d6c937080c3d30d124e8c8b86db7d625/usr.sbin/inetd/inetd.c#L1049)
but NetBSD only calls it when service definitions are no longer
needed. This has been fixed. freeconfig is called immediately before
any "goto more". There shouldn't be any time when a servtab is in
an invalid state where freeconfig would break.
2021-08-29 12:54:18 +03:00
|
|
|
}
|