syslogd: Allow use of non-standard ports.

This commit is contained in:
Mats Erik Andersson
2012-02-08 00:15:45 +01:00
parent 71281f6d10
commit 860baccb1e
5 changed files with 164 additions and 33 deletions

View File

@@ -1,3 +1,32 @@
2012-02-08 Mats Erik Andersson <gnu@gisladisker.se>
* src/syslogd.c: Implement presetable inet port, defaulting to the
standard port `syslog/udp'. Fall back to `514' if `syslog' fails.
(find_inet_port): New function.
(BindPort): New variable.
[IPPORT_SYSLOG] (portstr): New variable.
(LogPortText): Initialize to NULL.
(LogForwardPort): New variable.
(argp_options, parse_opt): New option `-B/--bind-port'.
(main): New call to `find_inet_port'.
(create_inet_socket): Check that LOGPORTTEXT is non-null,
otherwise inet sockets are left disabled.
[AI_ADDRCONFIG] (fprintflog, cfline): Only AF_UNSPEC invokes
AI_ADDRCONFIG. Replace LOGPORTTEXT by LOGFORWARDPORT in calls
to getaddrinfo.
* tests/syslogd.sh: Adapt to `syslogd' allowing non-standard ports.
(PORT): Make presetable from command line.
(locate_port): New function.
<non-root && privileged port>: Use a pseudo-random port.
<port in use>: Take a pseudo-random step to an even higher port, only
to disable inet sockets if even that action fails.
[do_inet_socket]: Add `-B$PORT' to IU_OPTIONS and append `:$PORT'
to option `-h' in calls to logger.
* tests/ftp-localhost.sh, tests/tftp.sh (NSSWITCH): Override
with value `/etc/services' when running OpenBSD.
2012-02-06 Mats Erik Andersson <gnu@gisladisker.se>
* doc/inetutils.texi (logger invocation): Describe option `-u/--unix'.

View File

@@ -251,6 +251,7 @@ int decode (const char *, CODE *);
void die (int);
void doexit (int);
void domark (int);
void find_inet_port (const char *);
void fprintlog (struct filed *, const char *, int, const char *);
void init (int);
void logerror (const char *);
@@ -272,6 +273,11 @@ char *LocalHostName; /* Our hostname. */
char *LocalDomain; /* Our local domain name. */
char *BindAddress = NULL; /* Binding address for INET listeners.
* The default is a wildcard address. */
char *BindPort = NULL; /* Optional non-standard port, instead
* of the usual 514/udp. */
#ifdef IPPORT_SYSLOG
char portstr[8]; /* Fallback port number. */
#endif
char addrstr[INET6_ADDRSTRLEN]; /* Common address presentation. */
char addrname[NI_MAXHOST]; /* Common name lookup. */
int usefamily = AF_INET; /* Address family for INET services.
@@ -281,7 +287,8 @@ int finet[2] = {-1, -1}; /* Internet datagram socket fd. */
#define IU_FD_IP4 0 /* Indices for the address families. */
#define IU_FD_IP6 1
int fklog = -1; /* Kernel log device fd. */
char *LogPortText = "syslog"; /* Service/port for INET connections. */
char *LogPortText = NULL; /* Service/port for INET connections. */
char *LogForwardPort = NULL; /* Target port for message forwarding. */
int Initialized; /* True when we are initialized. */
int MarkInterval = 20 * 60; /* Interval between marks in seconds. */
int MarkSeq; /* Mark sequence number. */
@@ -328,6 +335,7 @@ static struct argp_option argp_options[] = {
{"ipv6", '6', NULL, 0, "restrict to IPv6 transport", GRP+1},
{"ipany", OPT_IPANY, NULL, 0, "allow transport with IPv4 and IPv6", GRP+1},
{"bind", 'b', "ADDR", 0, "bind listener to this address/name", GRP+1},
{"bind-port", 'B', "PORT", 0, "bind listener to this port", GRP+1},
{"mark", 'm', "INTVL", 0, "specify timestamp interval in logs (0 for no "
"timestamps)", GRP+1},
{"no-detach", 'n', NULL, 0, "do not enter daemon mode", GRP+1},
@@ -400,6 +408,10 @@ parse_opt (int key, char *arg, struct argp_state *state)
BindAddress = arg;
break;
case 'B':
BindPort = arg;
break;
case 'm':
v = strtol (arg, &endptr, 10);
if (*endptr)
@@ -464,13 +476,16 @@ main (int argc, char *argv[])
set_program_name (argv[0]);
/* Initiliaze PATH_LOG as the first element of the unix sockets array. */
/* Initialize PATH_LOG as the first element of the unix sockets array. */
add_funix (PATH_LOG);
/* Parse command line */
iu_argp_init ("syslogd", default_program_authors);
argp_parse (&argp, argc, argv, 0, NULL, NULL);
/* Check desired port, if in demand at all. */
find_inet_port (BindPort);
/* Daemonise, if not, set the buffering for line buffer. */
if (!NoDetach)
{
@@ -849,6 +864,12 @@ create_inet_socket (int af, int fd46[2])
/* Invalidate old descriptors. */
fd46[IU_FD_IP4] = fd46[IU_FD_IP6] = -1;
if (!LogPortText)
{
dbg_printf ("No listen port has been accepted.\n");
return;
}
memset (&hints, 0, sizeof (hints));
hints.ai_family = af;
hints.ai_socktype = SOCK_DGRAM;
@@ -1300,9 +1321,11 @@ fprintlog (struct filed *f, const char *from, int flags, const char *msg)
memset (&hints, 0, sizeof (hints));
hints.ai_family = usefamily;
#ifdef AI_ADDRCONFIG
hints.ai_flags = AI_ADDRCONFIG;
if (usefamily == AF_UNSPEC)
hints.ai_flags |= AI_ADDRCONFIG;
#endif
err = getaddrinfo (f->f_un.f_forw.f_hname, LogPortText, &hints, &rp);
err = getaddrinfo (f->f_un.f_forw.f_hname, LogForwardPort,
&hints, &rp);
if (err)
{
dbg_printf ("Failure: %s\n", gai_strerror (err));
@@ -1360,7 +1383,7 @@ fprintlog (struct filed *f, const char *from, int flags, const char *msg)
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_PASSIVE;
err = getaddrinfo (NULL, LogPortText, &hints, &rp);
err = getaddrinfo (NULL, LogForwardPort, &hints, &rp);
if (err)
{
dbg_printf ("Not forwarding due to lookup failure: %s.\n",
@@ -2067,13 +2090,14 @@ cfline (const char *line, struct filed *f)
hints.ai_family = usefamily;
hints.ai_socktype = SOCK_DGRAM;
#ifdef AI_ADDRCONFIG
hints.ai_flags = AI_ADDRCONFIG;
if (usefamily == AF_UNSPEC)
hints.ai_flags |= AI_ADDRCONFIG;
#endif
f->f_un.f_forw.f_addrlen = 0; /* Invalidate address. */
memset (&f->f_un.f_forw.f_addr, 0, sizeof (f->f_un.f_forw.f_addr));
err = getaddrinfo (p, LogPortText, &hints, &rp);
err = getaddrinfo (p, LogForwardPort, &hints, &rp);
if (err)
{
switch (err)
@@ -2225,3 +2249,59 @@ trigger_restart (int signo _GL_UNUSED_PARAMETER)
{
restart = 1;
}
/* Override default port with a non-NULL argument.
* Otherwise identify the default syslog/udp with
* proper fallback to avoid resolve issues. */
void
find_inet_port (const char *port)
{
int err;
struct addrinfo hints, *ai;
/* Fall back to numerical description. */
#ifdef IPPORT_SYSLOG
snprintf (portstr, sizeof (portstr), "%u", IPPORT_SYSLOG);
LogForwardPort = portstr;
#else
LogForwardPort = "514";
#endif
memset (&hints, 0, sizeof (hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_PASSIVE;
err = getaddrinfo (NULL, "syslog", &hints, &ai);
if (err == 0)
{
LogForwardPort = "syslog"; /* Symbolic name is usable. */
freeaddrinfo (ai);
}
LogPortText = (char *) port;
if (!LogPortText)
{
LogPortText = LogForwardPort;
return;
}
/* Is the port specified on command line really usable? */
memset (&hints, 0, sizeof (hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_PASSIVE;
err = getaddrinfo (NULL, LogPortText, &hints, &ai);
if (err != 0)
{
/* Not usable, disable listener.
* It is too early to report failure at this time. */
LogPortText = NULL;
}
else
freeaddrinfo (ai);
return;
}

View File

@@ -32,6 +32,8 @@
#
# * Accessed by launched Inetd:
# /etc/nsswitch.conf, /etc/passwd, /etc/protocols.
#
# OpenBSD uses /etc/services directly, not via /etc/nsswitch.conf.
# FIXME: Better test coverage!
#
@@ -93,6 +95,9 @@ NSSWITCH=/etc/nsswitch.conf
PASSWD=/etc/passwd
PROTOCOLS=/etc/protocols
# Overrides based on systems.
test `uname -s` = OpenBSD && NSSWITCH=/etc/services
if test ! -r $NSSWITCH || test ! -r $PASSWD \
|| test ! -r $PROTOCOLS; then
cat <<-EOT >&2

View File

@@ -176,7 +176,19 @@ trap clean_testdir EXIT HUP INT QUIT TERM
# Test at this port.
# Standard is syslog at 514/udp.
PROTO=udp
PORT=514
PORT=${PORT:-514}
# locate_port proto port
#
locate_port () {
if [ "`uname -s`" = "SunOS" ]; then
netstat -na -finet -finet6 -P$1 |
grep "\.$2[^0-9]" >/dev/null 2>&1
else
netstat -na |
grep "^$1\(4\|6\|46\)\{0,1\}.*[^0-9]$2[^0-9]" >/dev/null 2>&1
fi
}
# Receivers for INET sockets.
: ${TARGET:=127.0.0.1}
@@ -253,31 +265,31 @@ TAG="syslogd-test"
# Remove old files in use by daemon.
rm -f "$OUT" "$PID" "$CONF"
# Full testing needs a superuser. Report this.
if [ `id -u` -ne 0 ]; then
# Full testing at the standard port needs a superuser.
# Randomise if necessary.
if test `id -u` -ne 0 && test $PORT -le 1023; then
cat <<-EOT >&2
WARNING!! Disabling INET server tests since you seem
to be underprivileged.
WARNING!! The preset port $PORT/$PROTO is not usable,
since you are underprivileged. Now attempting
a randomised higher port.
EOT
PORT=`expr $PORT + 3917 + ${RANDOM:-$$} % 2711`
fi
# Is the INET port already in use? If so,
# randomise somewhat.
if locate_port $PROTO $PORT; then
echo "Port $PORT/$PROTO is in use. Randomising port somewhat." >&2
PORT=`expr $PORT + 2711 + ${RANDOM:-$$} % 917`
fi
# Test a final time.
if locate_port $PROTO $PORT; then
cat <<-EOT >&2
The INET port $PORT/$PROTO is already in use.
Skipping test of INET socket this time.
EOT
do_inet_socket=false
else
# Is the INET port already in use? If so,
# skip the test in its entirety.
if [ "`uname -s`" = "SunOS" ]; then
netstat -na -finet -finet6 -P$PROTO |
grep "\.$PORT[^0-9]" >/dev/null 2>&1
else
netstat -na |
grep "^$PROTO\(4\|6\|46\)\{0,1\}.*[^0-9]$PORT[^0-9]" \
>/dev/null 2>&1
fi
if [ $? -eq 0 ]; then
cat <<-EOT >&2
The INET port $PORT/$PROTO is already in use.
No reliable test of INET socket is possible.
EOT
do_inet_socket=false
fi
fi
# A minimal, catch-all configuration.
@@ -319,7 +331,7 @@ fi
## Enable INET service when possible.
if $do_inet_socket; then
IU_OPTIONS="$IU_OPTIONS --ipany --inet --hop"
IU_OPTIONS="$IU_OPTIONS --ipany --inet -B$PORT --hop"
fi
## Bring in additional options from command line.
## Disable kernel messages otherwise.
@@ -381,9 +393,9 @@ fi
if $do_inet_socket; then
TESTCASES=`expr $TESTCASES + 2`
$LOGGER -4 -h "$TARGET" -p user.info -t "$TAG" \
$LOGGER -4 -h "$TARGET:$PORT" -p user.info -t "$TAG" \
"Sending IPv4 message. (pid $$)"
$LOGGER -6 -h "$TARGET6" -p user.info -t "$TAG" \
$LOGGER -6 -h "$TARGET6:$PORT" -p user.info -t "$TAG" \
"Sending IPv6 message. (pid $$)"
fi

View File

@@ -30,6 +30,8 @@
#
# * Accessed by launched Inetd:
# /etc/nsswitch.conf, /etc/passwd, /etc/protocols.
#
# OpenBSD uses /etc/services directly, not via /etc/nsswitch.conf.
# Need job control when spawning Inetd.
set -m
@@ -82,6 +84,9 @@ NSSWITCH=/etc/nsswitch.conf
PASSWD=/etc/passwd
PROTOCOLS=/etc/protocols
# Overrides based on systems.
test `uname -s` = OpenBSD && NSSWITCH=/etc/services
if test ! -r $NSSWITCH || test ! -r $PASSWD \
|| test ! -r $PROTOCOLS; then
cat <<-EOT >&2