From 6f5b353e871133a9cf2166ee351a47028dea3e55 Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Fri, 23 Apr 2021 16:54:15 -0600 Subject: [PATCH] Add configuration for sudo_logsrvd store-and-forward mode. Adds "relay_dir" and "store_first" settings to sudo_logsrvd.conf in the [relay] section. Also adds a --with-relaydir configure argument to change the default value (usually /var/log/logsrvd-relay. --- INSTALL | 6 +++++ configure | 40 ++++++++++++++++++++++++++++ configure.ac | 10 +++++++ doc/sudo_logsrvd.conf.man.in | 20 +++++++++++++- doc/sudo_logsrvd.conf.mdoc.in | 20 ++++++++++++-- doc/sudo_logsrvd.mdoc.in | 2 +- logsrvd/logsrvd.h | 2 ++ logsrvd/logsrvd_conf.c | 49 +++++++++++++++++++++++++++++++++++ m4/sudo.m4 | 24 +++++++++++++++++ pathnames.h.in | 9 +++++++ 10 files changed, 178 insertions(+), 4 deletions(-) diff --git a/INSTALL b/INSTALL index 1fa98c02a..211b67c92 100644 --- a/INSTALL +++ b/INSTALL @@ -149,6 +149,12 @@ Directory and file names: /var/db/sudo, /var/lib/sudo, /var/adm/sudo, /usr/adm/sudo This directory should *not* be cleared when the system boots. + --with-relaydir=DIR + The directory to be used for sudo_logsrvd relay temporary files. + When sudo_logsrvd is configured as a store-and-forward relay, + the journaled data is written to this directory before it is + forwarded to a relay server. + --with-tzdir=DIR The directory to the system's time zone data files. This is only used when sanitizing the TZ environment variable diff --git a/configure b/configure index 5ad31f30d..661f7c890 100755 --- a/configure +++ b/configure @@ -759,6 +759,7 @@ password_timeout timeout vardir rundir +relay_dir logpath log_dir iolog_dir @@ -954,6 +955,7 @@ with_timedir with_rundir with_vardir with_iologdir +with_relaydir with_tzdir with_sendmail with_sudoers_mode @@ -1814,6 +1816,8 @@ Optional Packages: system reboot, e.g. `/var/db/sudo' or `/var/lib/sudo' --with-iologdir=DIR directory to store sudo I/O log files in + --with-relaydir=DIR directory to store sudo_logsrvd relay temporary + files in --with-tzdir=DIR path to the time zone data directory --with-sendmail set path to sendmail --without-sendmail do not send mail at all @@ -3544,6 +3548,7 @@ printf "%s\n" "$as_me: Configuring Sudo version $PACKAGE_VERSION" >&6;} iolog_dir=/var/log/sudo-io log_dir=/var/log logpath=/var/log/sudo.log +relay_dir=/var/log/logsrvd-relay rundir=/var/run/sudo vardir=/var/adm/sudo timeout=5 @@ -5869,6 +5874,18 @@ fi +# Check whether --with-relaydir was given. +if test ${with_relaydir+y} +then : + withval=$with_relaydir; case $with_relaydir in + yes) ;; + no) as_fn_error $? "\"--without-relaydir not supported.\"" "$LINENO" 5 + ;; +esac +fi + + + # Check whether --with-tzdir was given. if test ${with_tzdir+y} then : @@ -27863,6 +27880,29 @@ printf "%s\n" "$logpath" >&6; } EOF + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sudo_logsrvd relay dir location" >&5 +printf %s "checking for sudo_logsrvd relay dir location... " >&6; } + if test "${with_relaydir-yes}" != "yes"; then + relay_dir="$with_relaydir" + else + # Default value of relay_dir set in configure.ac + for d in /var/log /var/adm /usr/adm; do + if test -d "$d"; then + relay_dir="$d/logsrvd-relay" + break + fi + done + fi + if test "${with_relaydir}" != "no"; then + cat >>confdefs.h <&5 +printf "%s\n" "$relay_dir" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sudo run dir location" >&5 printf %s "checking for sudo run dir location... " >&6; } if test -n "$with_rundir"; then diff --git a/configure.ac b/configure.ac index 9b173a5ec..750ca0dc8 100644 --- a/configure.ac +++ b/configure.ac @@ -132,6 +132,7 @@ dnl AC_SUBST([iolog_dir])dnl real initial value from SUDO_IO_LOGDIR AC_SUBST([log_dir])dnl real initial value from SUDO_LOGDIR AC_SUBST([logpath])dnl real initial value from SUDO_LOGFILE +AC_SUBST([relay_dir])dnl real initial value from SUDO_RELAY_DIR AC_SUBST([rundir])dnl real initial value from SUDO_RUNDIR AC_SUBST([vardir])dnl real initial value from SUDO_VARDIR AC_SUBST([timeout]) @@ -177,6 +178,7 @@ AC_SUBST([plugindir]) iolog_dir=/var/log/sudo-io log_dir=/var/log logpath=/var/log/sudo.log +relay_dir=/var/log/logsrvd-relay rundir=/var/run/sudo vardir=/var/adm/sudo timeout=5 @@ -910,6 +912,13 @@ AC_ARG_WITH(iologdir, [AS_HELP_STRING([--with-iologdir=DIR], [directory to store ;; esac]) +AC_ARG_WITH(relaydir, [AS_HELP_STRING([--with-relaydir=DIR], [directory to store sudo_logsrvd relay temporary files in])], +[case $with_relaydir in + yes) ;; + no) AC_MSG_ERROR(["--without-relaydir not supported."]) + ;; +esac]) + AC_ARG_WITH(tzdir, [AS_HELP_STRING([--with-tzdir=DIR], [path to the time zone data directory])], [case $with_tzdir in yes) AC_MSG_ERROR(["must give --with-tzdir an argument."]) @@ -4424,6 +4433,7 @@ if test "$utmp_style" = "LEGACY"; then fi SUDO_LOGDIR SUDO_LOGFILE +SUDO_RELAY_DIR SUDO_RUNDIR SUDO_VARDIR SUDO_IO_LOGDIR diff --git a/doc/sudo_logsrvd.conf.man.in b/doc/sudo_logsrvd.conf.man.in index fc877e9c9..3a716950b 100644 --- a/doc/sudo_logsrvd.conf.man.in +++ b/doc/sudo_logsrvd.conf.man.in @@ -16,7 +16,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.TH "SUDO_LOGSRVD.CONF" "@mansectform@" "April 9, 2021" "Sudo @PACKAGE_VERSION@" "File Formats Manual" +.TH "SUDO_LOGSRVD.CONF" "@mansectform@" "April 14, 2021" "Sudo @PACKAGE_VERSION@" "File Formats Manual" .nh .if n .ad l .SH "NAME" @@ -285,6 +285,14 @@ will wait for the relay to respond. A value of 0 will disable the timeout. The default value is 30. .TP 10n +relay_dir = path +The directory in which log messages are temporarily stored before they +are sent to the relay host. +Messages are stored in the wire format used by +sudo_logsrv.proto(@mansectform@) +The default value is +\fI@relay_dir@\fR. +.TP 10n relay_host = host[:port][(tls)] The relay host name or IP address, optional port to connect to and an optional Transport Layer Security (TLS) flag in parentheses. @@ -310,6 +318,16 @@ If multiple \fIrelay_host\fR lines are specified, the first available relay host will be used. .TP 10n +store_first = boolean +If true, +\fBsudo_logsrvd\fR +will store logs locally before relaying them. +Once the log is complete, a connection to the relay host is opened +and the log is relayed. +If the network connection is interrupted before the log can be fully +transfered, it will be retransmitted later. +The default is to relay logs in real-time. +.TP 10n tcp_keepalive = boolean If true, \fBsudo_logsrvd\fR diff --git a/doc/sudo_logsrvd.conf.mdoc.in b/doc/sudo_logsrvd.conf.mdoc.in index 119396850..7714e30b7 100644 --- a/doc/sudo_logsrvd.conf.mdoc.in +++ b/doc/sudo_logsrvd.conf.mdoc.in @@ -15,7 +15,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd April 9, 2021 +.Dd April 14, 2021 .Dt SUDO_LOGSRVD.CONF @mansectform@ .Os Sudo @PACKAGE_VERSION@ .Sh NAME @@ -247,6 +247,13 @@ setting controls the amount of time will wait for the relay to respond. A value of 0 will disable the timeout. The default value is 30. +.It relay_dir = path +The directory in which log messages are temporarily stored before they +are sent to the relay host. +Messages are stored in the wire format used by +.Xr sudo_logsrv.proto @mansectform@ +The default value is +.Pa @relay_dir@ . .It relay_host = host Ns Oo : Ns port Oc Ns Op (tls) The relay host name or IP address, optional port to connect to and an optional Transport Layer Security (TLS) flag in parentheses. @@ -265,12 +272,21 @@ The could be running an instance of .Nm sudo_logsrvd or another server that supports the -.Xr sudo_logsrv.proto 5 +.Xr sudo_logsrv.proto @mansectform@ protocol. .Pp If multiple .Em relay_host lines are specified, the first available relay host will be used. +.It store_first = boolean +If true, +.Nm sudo_logsrvd +will store logs locally before relaying them. +Once the log is complete, a connection to the relay host is opened +and the log is relayed. +If the network connection is interrupted before the log can be fully +transfered, it will be retransmitted later. +The default is to relay logs in real-time. .It tcp_keepalive = boolean If true, .Nm sudo_logsrvd diff --git a/doc/sudo_logsrvd.mdoc.in b/doc/sudo_logsrvd.mdoc.in index 3675c7bb1..02fc0f4ac 100644 --- a/doc/sudo_logsrvd.mdoc.in +++ b/doc/sudo_logsrvd.mdoc.in @@ -38,7 +38,7 @@ By default, .Nm stores the logs locally but it can also be configured to relay them to another server that supports the -.Xr sudo_logsrv.proto 5 +.Xr sudo_logsrv.proto @mansectform@ protocol. .Pp When not relaying, event log entries may be logged either via diff --git a/logsrvd/logsrvd.h b/logsrvd/logsrvd.h index 0a946967c..35f820788 100644 --- a/logsrvd/logsrvd.h +++ b/logsrvd/logsrvd.h @@ -167,6 +167,8 @@ const char *logsrvd_conf_iolog_dir(void); const char *logsrvd_conf_iolog_file(void); struct server_address_list *logsrvd_conf_server_listen_address(void); struct server_address_list *logsrvd_conf_relay_address(void); +const char *logsrvd_conf_relay_dir(void); +bool logsrvd_conf_relay_store_first(void); bool logsrvd_conf_relay_tcp_keepalive(void); bool logsrvd_conf_server_tcp_keepalive(void); const char *logsrvd_conf_pid_file(void); diff --git a/logsrvd/logsrvd_conf.c b/logsrvd/logsrvd_conf.c index 04c394612..dd692d73e 100644 --- a/logsrvd/logsrvd_conf.c +++ b/logsrvd/logsrvd_conf.c @@ -119,7 +119,9 @@ static struct logsrvd_config { struct address_list_container relays; struct timespec connect_timeout; struct timespec timeout; + char *relay_dir; bool tcp_keepalive; + bool store_first; #if defined(HAVE_OPENSSL) char *tls_key_path; char *tls_cert_path; @@ -230,6 +232,18 @@ logsrvd_conf_relay_address(void) return &logsrvd_config->relay.relays.addrs; } +const char * +logsrvd_conf_relay_dir(void) +{ + return logsrvd_config->relay.relay_dir; +} + +bool +logsrvd_conf_relay_store_first(void) +{ + return logsrvd_config->relay.store_first; +} + bool logsrvd_conf_relay_tcp_keepalive(void) { @@ -692,6 +706,36 @@ cb_relay_connect_timeout(struct logsrvd_config *config, const char *str, size_t debug_return_bool(true); } +static bool +cb_relay_dir(struct logsrvd_config *config, const char *str, size_t offset) +{ + char *copy = NULL; + debug_decl(cb_relay_dir, SUDO_DEBUG_UTIL); + + if ((copy = strdup(str)) == NULL) { + sudo_warn(NULL); + debug_return_bool(false); + } + + free(config->relay.relay_dir); + config->relay.relay_dir = copy; + + debug_return_bool(true); +} + +static bool +cb_relay_store_first(struct logsrvd_config *config, const char *str, size_t offset) +{ + int val; + debug_decl(cb_relay_store_first, SUDO_DEBUG_UTIL); + + if ((val = sudo_strtobool(str)) == -1) + debug_return_bool(false); + + config->relay.store_first = val; + debug_return_bool(true); +} + static bool cb_relay_keepalive(struct logsrvd_config *config, const char *str, size_t offset) { @@ -906,6 +950,8 @@ static struct logsrvd_config_entry relay_conf_entries[] = { { "relay_host", cb_relay_host }, { "timeout", cb_relay_timeout }, { "connect_timeout", cb_relay_connect_timeout }, + { "relay_dir", cb_relay_dir }, + { "store_first", cb_relay_store_first }, { "tcp_keepalive", cb_relay_keepalive }, #if defined(HAVE_OPENSSL) { "tls_key", cb_tls_key, offsetof(struct logsrvd_config, relay.tls_key_path) }, @@ -1133,6 +1179,7 @@ logsrvd_conf_free(struct logsrvd_config *config) /* struct logsrvd_config_relay */ address_list_delref(&config->relay.relays.addrs); + free(config->relay.relay_dir); #if defined(HAVE_OPENSSL) free(config->relay.tls_key_path); free(config->relay.tls_cert_path); @@ -1178,6 +1225,8 @@ logsrvd_conf_alloc(void) config->relay.timeout.tv_sec = DEFAULT_SOCKET_TIMEOUT_SEC; config->relay.connect_timeout.tv_sec = DEFAULT_SOCKET_TIMEOUT_SEC; config->relay.tcp_keepalive = true; + if (!cb_relay_dir(config, _PATH_SUDO_RELAY_DIR, 0)) + goto bad; #if defined(HAVE_OPENSSL) config->relay.tls_verify = -1; config->relay.tls_check_peer = -1; diff --git a/m4/sudo.m4 b/m4/sudo.m4 index 90fb25472..4e5061afe 100644 --- a/m4/sudo.m4 +++ b/m4/sudo.m4 @@ -153,6 +153,30 @@ AC_MSG_RESULT([$vardir]) SUDO_DEFINE_UNQUOTED(_PATH_SUDO_LECTURE_DIR, "$vardir/lectured") ])dnl +dnl +dnl Where the sudo_logsrvd relay temporary log files go, use +dnl /var/log/logsrvd-relay if /var/log exists, else +dnl /{var,usr}/adm/logsrvd-relay +dnl +AC_DEFUN([SUDO_RELAY_DIR], [ + AC_MSG_CHECKING(for sudo_logsrvd relay dir location) + if test "${with_relaydir-yes}" != "yes"; then + relay_dir="$with_relaydir" + else + # Default value of relay_dir set in configure.ac + for d in /var/log /var/adm /usr/adm; do + if test -d "$d"; then + relay_dir="$d/logsrvd-relay" + break + fi + done + fi + if test "${with_relaydir}" != "no"; then + SUDO_DEFINE_UNQUOTED(_PATH_SUDO_RELAY_DIR, "$relay_dir") + fi + AC_MSG_RESULT($relay_dir) +])dnl + dnl dnl Where the I/O log files go, use /var/log/sudo-io if dnl /var/log exists, else /{var,usr}/adm/sudo-io diff --git a/pathnames.h.in b/pathnames.h.in index 003a80b26..b0d3a9939 100644 --- a/pathnames.h.in +++ b/pathnames.h.in @@ -133,6 +133,15 @@ # undef _PATH_SUDO_LOGDIR #endif /* _PATH_SUDO_LOGDIR */ +/* + * Where to store sudo_logsrvd relay temporary files. Defaults to + * /var/log/logsrvd-relay, /var/adm/logsrvd-relay or /usr/adm/logsrvd-relay + * depending on what exists. + */ +#ifndef _PATH_SUDO_RELAY_DIR +# undef _PATH_SUDO_RELAY_DIR +#endif /* _PATH_SUDO_RELAY_DIR */ + /* * Where to put the sudo log file when logging to a file. Defaults to * /var/log/sudo.log if /var/log exists, else /var/adm/sudo.log.