Add basic support for event logging using a sudo-style log format.
This commit is contained in:
3
MANIFEST
3
MANIFEST
@@ -120,6 +120,8 @@ lib/util/isblank.c
|
|||||||
lib/util/key_val.c
|
lib/util/key_val.c
|
||||||
lib/util/lbuf.c
|
lib/util/lbuf.c
|
||||||
lib/util/locking.c
|
lib/util/locking.c
|
||||||
|
lib/util/logfac.c
|
||||||
|
lib/util/logpri.c
|
||||||
lib/util/memrchr.c
|
lib/util/memrchr.c
|
||||||
lib/util/memset_s.c
|
lib/util/memset_s.c
|
||||||
lib/util/mkdir_parents.c
|
lib/util/mkdir_parents.c
|
||||||
@@ -243,6 +245,7 @@ logsrvd/Makefile.in
|
|||||||
logsrvd/log_server.pb-c.c
|
logsrvd/log_server.pb-c.c
|
||||||
logsrvd/log_server.pb-c.h
|
logsrvd/log_server.pb-c.h
|
||||||
logsrvd/log_server.proto
|
logsrvd/log_server.proto
|
||||||
|
logsrvd/eventlog.c
|
||||||
logsrvd/iolog_writer.c
|
logsrvd/iolog_writer.c
|
||||||
logsrvd/logsrvd.c
|
logsrvd/logsrvd.c
|
||||||
logsrvd/logsrvd.h
|
logsrvd/logsrvd.h
|
||||||
|
@@ -6,12 +6,12 @@
|
|||||||
# The host name or IP address and port to listen on. If no port is
|
# The host name or IP address and port to listen on. If no port is
|
||||||
# specified, port 30344 will be used.
|
# specified, port 30344 will be used.
|
||||||
# The following forms are accepted:
|
# The following forms are accepted:
|
||||||
# listent_address = hostname
|
# listen_address = hostname
|
||||||
# listent_address = hostname:port
|
# listen_address = hostname:port
|
||||||
# listent_address = IPv4_address
|
# listen_address = IPv4_address
|
||||||
# listent_address = IPv4_address:port
|
# listen_address = IPv4_address:port
|
||||||
# listent_address = [IPv6_address]
|
# listen_address = [IPv6_address]
|
||||||
# listent_address = [IPv6_address]:port
|
# listen_address = [IPv6_address]:port
|
||||||
#
|
#
|
||||||
# Multiple listen_address settings may be specified.
|
# Multiple listen_address settings may be specified.
|
||||||
# The default is to listen on all addresses.
|
# The default is to listen on all addresses.
|
||||||
@@ -20,21 +20,21 @@
|
|||||||
[iolog]
|
[iolog]
|
||||||
# The top-level directory to use when constructing the path name for the
|
# The top-level directory to use when constructing the path name for the
|
||||||
# I/O log directory. The session sequence number, if any, is stored here.
|
# I/O log directory. The session sequence number, if any, is stored here.
|
||||||
iolog_dir = /var/log/sudo-io
|
#iolog_dir = /var/log/sudo-io
|
||||||
|
|
||||||
# The path name, relative to iolog_dir, in which to store I/O logs.
|
# The path name, relative to iolog_dir, in which to store I/O logs.
|
||||||
# Note that iolog_file may contain directory components.
|
# Note that iolog_file may contain directory components.
|
||||||
iolog_file = %{seq}
|
#iolog_file = %{seq}
|
||||||
|
|
||||||
# If set, I/O log data is flushed to disk after each write instead of
|
# If set, I/O log data is flushed to disk after each write instead of
|
||||||
# buffering it. This makes it possible to view the logs in real-time
|
# buffering it. This makes it possible to view the logs in real-time
|
||||||
# as the program is executing but may significantly reduce the effectiveness
|
# as the program is executing but may significantly reduce the effectiveness
|
||||||
# of I/O log compression.
|
# of I/O log compression.
|
||||||
iolog_flush = true
|
#iolog_flush = true
|
||||||
|
|
||||||
# If set, I/O logs will be compressed using zlib. Enabling compression can
|
# If set, I/O logs will be compressed using zlib. Enabling compression can
|
||||||
# make it harder to view the logs in real-time as the program is executing.
|
# make it harder to view the logs in real-time as the program is executing.
|
||||||
iolog_compress = false
|
#iolog_compress = false
|
||||||
|
|
||||||
# The group name to look up when setting the group-ID on new I/O log files
|
# The group name to look up when setting the group-ID on new I/O log files
|
||||||
# and directories. If iolog_group is not set, the primary group-ID of the
|
# and directories. If iolog_group is not set, the primary group-ID of the
|
||||||
@@ -54,7 +54,7 @@ iolog_compress = false
|
|||||||
# write bits, even if they are not present in the specified mode. When
|
# write bits, even if they are not present in the specified mode. When
|
||||||
# creating I/O log directories, search (execute) bits are added to match
|
# creating I/O log directories, search (execute) bits are added to match
|
||||||
# the read and write bits specified by iolog_mode.
|
# the read and write bits specified by iolog_mode.
|
||||||
iolog_mode = 0600
|
#iolog_mode = 0600
|
||||||
|
|
||||||
# The maximum sequence number that will be substituted for the %{seq}
|
# The maximum sequence number that will be substituted for the %{seq}
|
||||||
# escape in the I/O log file (see the iolog_dir description below for
|
# escape in the I/O log file (see the iolog_dir description below for
|
||||||
@@ -62,4 +62,52 @@ iolog_mode = 0600
|
|||||||
# base 36, maxseq itself should be expressed in decimal. Values larger
|
# base 36, maxseq itself should be expressed in decimal. Values larger
|
||||||
# than 2176782336 (which corresponds to the base 36 sequence number
|
# than 2176782336 (which corresponds to the base 36 sequence number
|
||||||
# ZZZZZZ) will be silently truncated to 2176782336.
|
# ZZZZZZ) will be silently truncated to 2176782336.
|
||||||
maxseq = 2176782336
|
#maxseq = 2176782336
|
||||||
|
|
||||||
|
[eventlog]
|
||||||
|
# Where to log accept, reject and alert events.
|
||||||
|
# Accepted values are syslog, logfile, or none.
|
||||||
|
# Defaults to syslog
|
||||||
|
#log_type = syslog
|
||||||
|
|
||||||
|
# Event log format.
|
||||||
|
# Currently only supports sudo-style event logs.
|
||||||
|
#log_format = sudo
|
||||||
|
|
||||||
|
[syslog]
|
||||||
|
# The maximum length of a syslog payload.
|
||||||
|
# On many systems, syslog(3) has a relatively small log buffer.
|
||||||
|
# IETF RFC 5424 states that syslog servers must support messages
|
||||||
|
# of at least 480 bytes and should support messages up to 2048 bytes.
|
||||||
|
# Messages larger than this value will be split into multiple messages.
|
||||||
|
#maxlen = 960
|
||||||
|
|
||||||
|
# The syslog facility to use for event log messages.
|
||||||
|
# The following syslog facilities are supported: authpriv (if your OS
|
||||||
|
# supports it), auth, daemon, user, local0, local1, local2, local3, local4,
|
||||||
|
# local5, local6, and local7.
|
||||||
|
#facility = authpriv
|
||||||
|
|
||||||
|
# The syslog priority to use for event log accept messages, when
|
||||||
|
# the command is allowed by the security policy. The following syslog
|
||||||
|
# priorities are supported: alert, crit, debug, emerg, err, info,
|
||||||
|
# notice, warning, and none.
|
||||||
|
#accept_priority = notice
|
||||||
|
|
||||||
|
# The syslog priority to use for event log reject messages, when the
|
||||||
|
# command is not allowed by the security policy.
|
||||||
|
#reject_priority = alert
|
||||||
|
|
||||||
|
# The syslog priority to use for event log alert messages reported
|
||||||
|
# by the security policy.
|
||||||
|
#alert_priority = alert
|
||||||
|
|
||||||
|
[logfile]
|
||||||
|
# The format string used when formatting the date and time for
|
||||||
|
# file-based event logs. Formatting is performed via strftime(3) so
|
||||||
|
# any format string supported by that function is allowed.
|
||||||
|
#time_format = %h %e %T
|
||||||
|
|
||||||
|
# The path to the file-based event log.
|
||||||
|
# This path must be fully-qualified and start with a '/' character.
|
||||||
|
#path = /var/log/sudo
|
||||||
|
@@ -220,6 +220,18 @@ __dso_public bool sudo_lock_file_v1(int fd, int action);
|
|||||||
__dso_public bool sudo_lock_region_v1(int fd, int action, off_t len);
|
__dso_public bool sudo_lock_region_v1(int fd, int action, off_t len);
|
||||||
#define sudo_lock_region(_a, _b, _c) sudo_lock_region_v1((_a), (_b), (_c))
|
#define sudo_lock_region(_a, _b, _c) sudo_lock_region_v1((_a), (_b), (_c))
|
||||||
|
|
||||||
|
/* logfac.c */
|
||||||
|
__dso_public bool sudo_str2logfac_v1(const char *str, int *logfac);
|
||||||
|
#define sudo_str2logfac(_a, _b) sudo_str2logfac_v1((_a), (_b))
|
||||||
|
__dso_public const char *sudo_logfac2str_v1(int num);
|
||||||
|
#define sudo_logfac2str(_a) sudo_logfac2str_v1((_a))
|
||||||
|
|
||||||
|
/* logpri.c */
|
||||||
|
__dso_public bool sudo_str2logpri_v1(const char *str, int *logpri);
|
||||||
|
#define sudo_str2logpri(_a, _b) sudo_str2logpri_v1((_a), (_b))
|
||||||
|
__dso_public const char *sudo_logpri2str_v1(int num);
|
||||||
|
#define sudo_logpri2str(_a) sudo_logpri2str_v1((_a))
|
||||||
|
|
||||||
/* mkdir_parents.c */
|
/* mkdir_parents.c */
|
||||||
__dso_public bool sudo_mkdir_parents_v1(char *path, uid_t uid, gid_t gid, mode_t mode, bool quiet);
|
__dso_public bool sudo_mkdir_parents_v1(char *path, uid_t uid, gid_t gid, mode_t mode, bool quiet);
|
||||||
#define sudo_mkdir_parents(_a, _b, _c, _d, _e) sudo_mkdir_parents_v1((_a), (_b), (_c), (_d), (_e))
|
#define sudo_mkdir_parents(_a, _b, _c, _d, _e) sudo_mkdir_parents_v1((_a), (_b), (_c), (_d), (_e))
|
||||||
|
@@ -117,10 +117,11 @@ SHELL = @SHELL@
|
|||||||
|
|
||||||
LTOBJS = @DIGEST@ event.lo fatal.lo key_val.lo gethostname.lo \
|
LTOBJS = @DIGEST@ event.lo fatal.lo key_val.lo gethostname.lo \
|
||||||
gettime.lo getgrouplist.lo gidlist.lo lbuf.lo locking.lo \
|
gettime.lo getgrouplist.lo gidlist.lo lbuf.lo locking.lo \
|
||||||
mkdir_parents.lo parseln.lo progname.lo secure_path.lo \
|
logfac.lo logpri.lo mkdir_parents.lo parseln.lo progname.lo \
|
||||||
setgroups.lo strsplit.lo strtobool.lo strtoid.lo strtomode.lo \
|
secure_path.lo setgroups.lo strsplit.lo strtobool.lo \
|
||||||
strtonum.lo sudo_conf.lo sudo_debug.lo sudo_dso.lo term.lo \
|
strtoid.lo strtomode.lo strtonum.lo sudo_conf.lo \
|
||||||
ttyname_dev.lo ttysize.lo @COMMON_OBJS@ @LTLIBOBJS@
|
sudo_debug.lo sudo_dso.lo term.lo ttyname_dev.lo \
|
||||||
|
ttysize.lo @COMMON_OBJS@ @LTLIBOBJS@
|
||||||
|
|
||||||
IOBJS = $(LTOBJS:.lo=.i)
|
IOBJS = $(LTOBJS:.lo=.i)
|
||||||
|
|
||||||
@@ -771,6 +772,26 @@ locking.i: $(srcdir)/locking.c $(incdir)/compat/stdbool.h \
|
|||||||
$(CC) -E -o $@ $(CPPFLAGS) $<
|
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||||
locking.plog: locking.i
|
locking.plog: locking.i
|
||||||
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/locking.c --i-file $< --output-file $@
|
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/locking.c --i-file $< --output-file $@
|
||||||
|
logfac.lo: $(srcdir)/logfac.c $(incdir)/compat/stdbool.h \
|
||||||
|
$(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
|
||||||
|
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(top_builddir)/config.h
|
||||||
|
$(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/logfac.c
|
||||||
|
logfac.i: $(srcdir)/logfac.c $(incdir)/compat/stdbool.h \
|
||||||
|
$(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
|
||||||
|
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(top_builddir)/config.h
|
||||||
|
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||||
|
logfac.plog: logfac.i
|
||||||
|
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/logfac.c --i-file $< --output-file $@
|
||||||
|
logpri.lo: $(srcdir)/logpri.c $(incdir)/compat/stdbool.h \
|
||||||
|
$(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
|
||||||
|
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(top_builddir)/config.h
|
||||||
|
$(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/logpri.c
|
||||||
|
logpri.i: $(srcdir)/logpri.c $(incdir)/compat/stdbool.h \
|
||||||
|
$(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
|
||||||
|
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(top_builddir)/config.h
|
||||||
|
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||||
|
logpri.plog: logpri.i
|
||||||
|
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/logpri.c --i-file $< --output-file $@
|
||||||
memrchr.lo: $(srcdir)/memrchr.c $(incdir)/sudo_compat.h $(top_builddir)/config.h
|
memrchr.lo: $(srcdir)/memrchr.c $(incdir)/sudo_compat.h $(top_builddir)/config.h
|
||||||
$(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/memrchr.c
|
$(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/memrchr.c
|
||||||
memrchr.i: $(srcdir)/memrchr.c $(incdir)/sudo_compat.h $(top_builddir)/config.h
|
memrchr.i: $(srcdir)/memrchr.c $(incdir)/sudo_compat.h $(top_builddir)/config.h
|
||||||
|
93
lib/util/logfac.c
Normal file
93
lib/util/logfac.c
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-License-Identifier: ISC
|
||||||
|
*
|
||||||
|
* Copyright (c) 1999-2005, 2007-2019
|
||||||
|
* Todd C. Miller <Todd.Miller@sudo.ws>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*
|
||||||
|
* Sponsored in part by the Defense Advanced Research Projects
|
||||||
|
* Agency (DARPA) and Air Force Research Laboratory, Air Force
|
||||||
|
* Materiel Command, USAF, under agreement number F39502-99-1-0512.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is an open source non-commercial project. Dear PVS-Studio, please check it.
|
||||||
|
* PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
|
||||||
|
#include "sudo_compat.h"
|
||||||
|
#include "sudo_debug.h"
|
||||||
|
#include "sudo_util.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For converting between syslog numbers and strings.
|
||||||
|
*/
|
||||||
|
struct strmap {
|
||||||
|
char *name;
|
||||||
|
int num;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct strmap facilities[] = {
|
||||||
|
#ifdef LOG_AUTHPRIV
|
||||||
|
{ "authpriv", LOG_AUTHPRIV },
|
||||||
|
#endif
|
||||||
|
{ "auth", LOG_AUTH },
|
||||||
|
{ "daemon", LOG_DAEMON },
|
||||||
|
{ "user", LOG_USER },
|
||||||
|
{ "local0", LOG_LOCAL0 },
|
||||||
|
{ "local1", LOG_LOCAL1 },
|
||||||
|
{ "local2", LOG_LOCAL2 },
|
||||||
|
{ "local3", LOG_LOCAL3 },
|
||||||
|
{ "local4", LOG_LOCAL4 },
|
||||||
|
{ "local5", LOG_LOCAL5 },
|
||||||
|
{ "local6", LOG_LOCAL6 },
|
||||||
|
{ "local7", LOG_LOCAL7 },
|
||||||
|
{ NULL, -1 }
|
||||||
|
};
|
||||||
|
|
||||||
|
bool
|
||||||
|
sudo_str2logfac_v1(const char *str, int *logfac)
|
||||||
|
{
|
||||||
|
const struct strmap *fac;
|
||||||
|
debug_decl(sudo_str2logfac, SUDO_DEBUG_UTIL)
|
||||||
|
|
||||||
|
for (fac = facilities; fac->name != NULL; fac++) {
|
||||||
|
if (strcmp(str, fac->name) == 0) {
|
||||||
|
*logfac = fac->num;
|
||||||
|
debug_return_bool(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
debug_return_bool(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
sudo_logfac2str_v1(int num)
|
||||||
|
{
|
||||||
|
const struct strmap *fac;
|
||||||
|
debug_decl(sudo_logfac2str, SUDO_DEBUG_UTIL)
|
||||||
|
|
||||||
|
for (fac = facilities; fac->name != NULL; fac++) {
|
||||||
|
if (fac->num == num)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
debug_return_const_str(fac->name);
|
||||||
|
}
|
88
lib/util/logpri.c
Normal file
88
lib/util/logpri.c
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-License-Identifier: ISC
|
||||||
|
*
|
||||||
|
* Copyright (c) 1999-2005, 2007-2019
|
||||||
|
* Todd C. Miller <Todd.Miller@sudo.ws>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*
|
||||||
|
* Sponsored in part by the Defense Advanced Research Projects
|
||||||
|
* Agency (DARPA) and Air Force Research Laboratory, Air Force
|
||||||
|
* Materiel Command, USAF, under agreement number F39502-99-1-0512.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is an open source non-commercial project. Dear PVS-Studio, please check it.
|
||||||
|
* PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
|
||||||
|
#include "sudo_compat.h"
|
||||||
|
#include "sudo_debug.h"
|
||||||
|
#include "sudo_util.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For converting between syslog numbers and strings.
|
||||||
|
*/
|
||||||
|
struct strmap {
|
||||||
|
char *name;
|
||||||
|
int num;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct strmap priorities[] = {
|
||||||
|
{ "alert", LOG_ALERT },
|
||||||
|
{ "crit", LOG_CRIT },
|
||||||
|
{ "debug", LOG_DEBUG },
|
||||||
|
{ "emerg", LOG_EMERG },
|
||||||
|
{ "err", LOG_ERR },
|
||||||
|
{ "info", LOG_INFO },
|
||||||
|
{ "notice", LOG_NOTICE },
|
||||||
|
{ "warning", LOG_WARNING },
|
||||||
|
{ "none", -1 },
|
||||||
|
{ NULL, -1 }
|
||||||
|
};
|
||||||
|
|
||||||
|
bool
|
||||||
|
sudo_str2logpri_v1(const char *str, int *logpri)
|
||||||
|
{
|
||||||
|
const struct strmap *pri;
|
||||||
|
debug_decl(sudo_str2logpri, SUDO_DEBUG_UTIL)
|
||||||
|
|
||||||
|
for (pri = priorities; pri->name != NULL; pri++) {
|
||||||
|
if (strcmp(str, pri->name) == 0) {
|
||||||
|
*logpri = pri->num;
|
||||||
|
debug_return_bool(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
debug_return_bool(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
sudo_logpri2str_v1(int num)
|
||||||
|
{
|
||||||
|
const struct strmap *pri;
|
||||||
|
debug_decl(sudo_logpri2str, SUDO_DEBUG_UTIL)
|
||||||
|
|
||||||
|
for (pri = priorities; pri->name != NULL; pri++) {
|
||||||
|
if (pri->num == num)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
debug_return_const_str(pri->name);
|
||||||
|
}
|
@@ -88,6 +88,8 @@ sudo_lbuf_init_v1
|
|||||||
sudo_lbuf_print_v1
|
sudo_lbuf_print_v1
|
||||||
sudo_lock_file_v1
|
sudo_lock_file_v1
|
||||||
sudo_lock_region_v1
|
sudo_lock_region_v1
|
||||||
|
sudo_logfac2str_v1
|
||||||
|
sudo_logpri2str_v1
|
||||||
sudo_mkdir_parents_v1
|
sudo_mkdir_parents_v1
|
||||||
sudo_new_key_val_v1
|
sudo_new_key_val_v1
|
||||||
sudo_parse_gids_v1
|
sudo_parse_gids_v1
|
||||||
@@ -96,6 +98,8 @@ sudo_parseln_v2
|
|||||||
sudo_secure_dir_v1
|
sudo_secure_dir_v1
|
||||||
sudo_secure_file_v1
|
sudo_secure_file_v1
|
||||||
sudo_setgroups_v1
|
sudo_setgroups_v1
|
||||||
|
sudo_str2logfac_v1
|
||||||
|
sudo_str2logpri_v1
|
||||||
sudo_strsplit_v1
|
sudo_strsplit_v1
|
||||||
sudo_strtobool_v1
|
sudo_strtobool_v1
|
||||||
sudo_strtoid_v1
|
sudo_strtoid_v1
|
||||||
|
@@ -107,7 +107,7 @@ SHELL = @SHELL@
|
|||||||
|
|
||||||
PROGS = sudo_logsrvd sudo_sendlog
|
PROGS = sudo_logsrvd sudo_sendlog
|
||||||
|
|
||||||
LOGSRVD_OBJS = iolog_writer.o logsrvd.o \
|
LOGSRVD_OBJS = eventlog.o iolog_writer.o logsrvd.o \
|
||||||
logsrvd_conf.o log_server.pb-c.o protobuf-c.o
|
logsrvd_conf.o log_server.pb-c.o protobuf-c.o
|
||||||
|
|
||||||
SENDLOG_OBJS = sendlog.o log_server.pb-c.o protobuf-c.o
|
SENDLOG_OBJS = sendlog.o log_server.pb-c.o protobuf-c.o
|
||||||
@@ -211,6 +211,22 @@ realclean: distclean
|
|||||||
cleandir: realclean
|
cleandir: realclean
|
||||||
|
|
||||||
# Autogenerated dependencies, do not modify
|
# Autogenerated dependencies, do not modify
|
||||||
|
eventlog.o: $(srcdir)/eventlog.c $(devdir)/log_server.pb-c.h \
|
||||||
|
$(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
|
||||||
|
$(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
|
||||||
|
$(incdir)/sudo_gettext.h $(incdir)/sudo_iolog.h \
|
||||||
|
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/logsrvd.h \
|
||||||
|
$(srcdir)/protobuf-c/protobuf-c.h $(top_builddir)/config.h
|
||||||
|
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/eventlog.c
|
||||||
|
eventlog.i: $(srcdir)/eventlog.c $(devdir)/log_server.pb-c.h \
|
||||||
|
$(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
|
||||||
|
$(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
|
||||||
|
$(incdir)/sudo_gettext.h $(incdir)/sudo_iolog.h \
|
||||||
|
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/logsrvd.h \
|
||||||
|
$(srcdir)/protobuf-c/protobuf-c.h $(top_builddir)/config.h
|
||||||
|
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||||
|
eventlog.plog: eventlog.i
|
||||||
|
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/eventlog.c --i-file $< --output-file $@
|
||||||
iolog_writer.o: $(srcdir)/iolog_writer.c $(devdir)/log_server.pb-c.h \
|
iolog_writer.o: $(srcdir)/iolog_writer.c $(devdir)/log_server.pb-c.h \
|
||||||
$(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
|
$(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
|
||||||
$(incdir)/sudo_debug.h $(incdir)/sudo_iolog.h \
|
$(incdir)/sudo_debug.h $(incdir)/sudo_iolog.h \
|
||||||
|
459
logsrvd/eventlog.c
Normal file
459
logsrvd/eventlog.c
Normal file
@@ -0,0 +1,459 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-License-Identifier: ISC
|
||||||
|
*
|
||||||
|
* Copyright (c) 1994-1996, 1998-2019 Todd C. Miller <Todd.Miller@sudo.ws>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*
|
||||||
|
* Sponsored in part by the Defense Advanced Research Projects
|
||||||
|
* Agency (DARPA) and Air Force Research Laboratory, Air Force
|
||||||
|
* Materiel Command, USAF, under agreement number F39502-99-1-0512.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is an open source non-commercial project. Dear PVS-Studio, please check it.
|
||||||
|
* PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <grp.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "log_server.pb-c.h"
|
||||||
|
#include "sudo_gettext.h" /* must be included before sudo_compat.h */
|
||||||
|
#include "sudo_compat.h"
|
||||||
|
#include "sudo_fatal.h"
|
||||||
|
#include "sudo_queue.h"
|
||||||
|
#include "sudo_debug.h"
|
||||||
|
#include "sudo_util.h"
|
||||||
|
#include "sudo_iolog.h"
|
||||||
|
#include "logsrvd.h"
|
||||||
|
|
||||||
|
#define LL_HOST_STR "HOST="
|
||||||
|
#define LL_TTY_STR "TTY="
|
||||||
|
#define LL_CWD_STR "PWD="
|
||||||
|
#define LL_USER_STR "USER="
|
||||||
|
#define LL_GROUP_STR "GROUP="
|
||||||
|
#define LL_ENV_STR "ENV="
|
||||||
|
#define LL_CMND_STR "COMMAND="
|
||||||
|
#define LL_TSID_STR "TSID="
|
||||||
|
|
||||||
|
#define IS_SESSID(s) ( \
|
||||||
|
isalnum((unsigned char)(s)[0]) && isalnum((unsigned char)(s)[1]) && \
|
||||||
|
(s)[2] == '/' && \
|
||||||
|
isalnum((unsigned char)(s)[3]) && isalnum((unsigned char)(s)[4]) && \
|
||||||
|
(s)[5] == '/' && \
|
||||||
|
isalnum((unsigned char)(s)[6]) && isalnum((unsigned char)(s)[7]) && \
|
||||||
|
(s)[8] == '\0')
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allocate and fill in a new logline.
|
||||||
|
*/
|
||||||
|
static char *
|
||||||
|
new_logline(const char *message, const char *errstr,
|
||||||
|
const struct iolog_details *details)
|
||||||
|
{
|
||||||
|
char *line = NULL, *evstr = NULL;
|
||||||
|
const char *iolog_file = details->iolog_file;
|
||||||
|
char sessid[7];
|
||||||
|
const char *tsid = NULL;
|
||||||
|
size_t len = 0;
|
||||||
|
int i;
|
||||||
|
debug_decl(new_logline, SUDO_DEBUG_UTIL)
|
||||||
|
|
||||||
|
/* A TSID may be a sudoers-style session ID or a free-form string. */
|
||||||
|
if (iolog_file != NULL) {
|
||||||
|
if (IS_SESSID(iolog_file)) {
|
||||||
|
sessid[0] = iolog_file[0];
|
||||||
|
sessid[1] = iolog_file[1];
|
||||||
|
sessid[2] = iolog_file[3];
|
||||||
|
sessid[3] = iolog_file[4];
|
||||||
|
sessid[4] = iolog_file[6];
|
||||||
|
sessid[5] = iolog_file[7];
|
||||||
|
sessid[6] = '\0';
|
||||||
|
tsid = sessid;
|
||||||
|
} else {
|
||||||
|
tsid = iolog_file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compute line length
|
||||||
|
*/
|
||||||
|
if (message != NULL)
|
||||||
|
len += strlen(message) + 3;
|
||||||
|
if (errstr != NULL)
|
||||||
|
len += strlen(errstr) + 3;
|
||||||
|
len += sizeof(LL_HOST_STR) + 2 + strlen(details->submithost);
|
||||||
|
len += sizeof(LL_TTY_STR) + 2 + strlen(details->ttyname);
|
||||||
|
len += sizeof(LL_CWD_STR) + 2 + strlen(details->cwd);
|
||||||
|
if (details->runuser != NULL)
|
||||||
|
len += sizeof(LL_USER_STR) + 2 + strlen(details->runuser);
|
||||||
|
if (details->rungroup != NULL)
|
||||||
|
len += sizeof(LL_GROUP_STR) + 2 + strlen(details->rungroup);
|
||||||
|
if (tsid != NULL)
|
||||||
|
len += sizeof(LL_TSID_STR) + 2 + strlen(tsid);
|
||||||
|
if (details->env_add != NULL) {
|
||||||
|
size_t evlen = 0;
|
||||||
|
char * const *ep;
|
||||||
|
|
||||||
|
for (ep = details->env_add; *ep != NULL; ep++)
|
||||||
|
evlen += strlen(*ep) + 1;
|
||||||
|
if (evlen != 0) {
|
||||||
|
if ((evstr = malloc(evlen)) == NULL)
|
||||||
|
goto oom;
|
||||||
|
ep = details->env_add;
|
||||||
|
if (strlcpy(evstr, *ep, evlen) >= evlen)
|
||||||
|
goto toobig;
|
||||||
|
while (*++ep != NULL) {
|
||||||
|
if (strlcat(evstr, " ", evlen) >= evlen ||
|
||||||
|
strlcat(evstr, *ep, evlen) >= evlen)
|
||||||
|
goto toobig;
|
||||||
|
}
|
||||||
|
len += sizeof(LL_ENV_STR) + 2 + evlen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (details->command != NULL) {
|
||||||
|
len += sizeof(LL_CMND_STR) - 1 + strlen(details->command);
|
||||||
|
if (details->argc > 1) {
|
||||||
|
for (i = 1; i < details->argc; i++)
|
||||||
|
len += strlen(details->argv[i]) + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allocate and build up the line.
|
||||||
|
*/
|
||||||
|
if ((line = malloc(++len)) == NULL)
|
||||||
|
goto oom;
|
||||||
|
line[0] = '\0';
|
||||||
|
|
||||||
|
if (message != NULL) {
|
||||||
|
if (strlcat(line, message, len) >= len ||
|
||||||
|
strlcat(line, errstr ? " : " : " ; ", len) >= len)
|
||||||
|
goto toobig;
|
||||||
|
}
|
||||||
|
if (errstr != NULL) {
|
||||||
|
if (strlcat(line, errstr, len) >= len ||
|
||||||
|
strlcat(line, " ; ", len) >= len)
|
||||||
|
goto toobig;
|
||||||
|
}
|
||||||
|
if (strlcat(line, LL_HOST_STR, len) >= len ||
|
||||||
|
strlcat(line, details->submithost, len) >= len ||
|
||||||
|
strlcat(line, " ; ", len) >= len)
|
||||||
|
goto toobig;
|
||||||
|
if (strlcat(line, LL_TTY_STR, len) >= len ||
|
||||||
|
strlcat(line, details->ttyname, len) >= len ||
|
||||||
|
strlcat(line, " ; ", len) >= len)
|
||||||
|
goto toobig;
|
||||||
|
if (strlcat(line, LL_CWD_STR, len) >= len ||
|
||||||
|
strlcat(line, details->cwd, len) >= len ||
|
||||||
|
strlcat(line, " ; ", len) >= len)
|
||||||
|
goto toobig;
|
||||||
|
if (details->runuser != NULL) {
|
||||||
|
if (strlcat(line, LL_USER_STR, len) >= len ||
|
||||||
|
strlcat(line, details->runuser, len) >= len ||
|
||||||
|
strlcat(line, " ; ", len) >= len)
|
||||||
|
goto toobig;
|
||||||
|
}
|
||||||
|
if (details->rungroup != NULL) {
|
||||||
|
if (strlcat(line, LL_GROUP_STR, len) >= len ||
|
||||||
|
strlcat(line, details->rungroup, len) >= len ||
|
||||||
|
strlcat(line, " ; ", len) >= len)
|
||||||
|
goto toobig;
|
||||||
|
}
|
||||||
|
if (tsid != NULL) {
|
||||||
|
if (strlcat(line, LL_TSID_STR, len) >= len ||
|
||||||
|
strlcat(line, tsid, len) >= len ||
|
||||||
|
strlcat(line, " ; ", len) >= len)
|
||||||
|
goto toobig;
|
||||||
|
}
|
||||||
|
if (evstr != NULL) {
|
||||||
|
if (strlcat(line, LL_ENV_STR, len) >= len ||
|
||||||
|
strlcat(line, evstr, len) >= len ||
|
||||||
|
strlcat(line, " ; ", len) >= len)
|
||||||
|
goto toobig;
|
||||||
|
free(evstr);
|
||||||
|
evstr = NULL;
|
||||||
|
}
|
||||||
|
if (details->command != NULL) {
|
||||||
|
if (strlcat(line, LL_CMND_STR, len) >= len)
|
||||||
|
goto toobig;
|
||||||
|
if (strlcat(line, details->command, len) >= len)
|
||||||
|
goto toobig;
|
||||||
|
if (details->argc > 1) {
|
||||||
|
for (i = 1; i < details->argc; i++) {
|
||||||
|
if (strlcat(line, " ", len) >= len ||
|
||||||
|
strlcat(line, details->argv[i], len) >= len)
|
||||||
|
goto toobig;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
debug_return_str(line);
|
||||||
|
oom:
|
||||||
|
free(evstr);
|
||||||
|
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
||||||
|
debug_return_str(NULL);
|
||||||
|
toobig:
|
||||||
|
free(evstr);
|
||||||
|
free(line);
|
||||||
|
sudo_warnx(U_("internal error, %s overflow"), __func__);
|
||||||
|
debug_return_str(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We do an openlog(3)/closelog(3) for each message because some
|
||||||
|
* authentication methods (notably PAM) use syslog(3) for their
|
||||||
|
* own nefarious purposes and may call openlog(3) and closelog(3).
|
||||||
|
* XXX - no longer need openlog/closelog dance, move openlog call
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
mysyslog(int pri, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
debug_decl(mysyslog, SUDO_DEBUG_UTIL)
|
||||||
|
|
||||||
|
openlog("sudo", 0, logsrvd_conf_syslog_facility());
|
||||||
|
va_start(ap, fmt);
|
||||||
|
vsyslog(pri, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
closelog();
|
||||||
|
debug_return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Log a message to syslog, pre-pending the username and splitting the
|
||||||
|
* message into parts if it is longer than syslog_maxlen.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
do_syslog(int pri, const struct iolog_details *details, char *msg)
|
||||||
|
{
|
||||||
|
size_t len, maxlen;
|
||||||
|
char *p, *tmp, save;
|
||||||
|
const char *fmt;
|
||||||
|
debug_decl(do_syslog, SUDO_DEBUG_UTIL)
|
||||||
|
|
||||||
|
/* A priority of -1 corresponds to "none". */
|
||||||
|
if (pri == -1)
|
||||||
|
debug_return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Log the full line, breaking into multiple syslog(3) calls if necessary
|
||||||
|
*/
|
||||||
|
fmt = _("%8s : %s");
|
||||||
|
maxlen = logsrvd_conf_syslog_maxlen() -
|
||||||
|
(strlen(fmt) - 5 + strlen(details->submituser));
|
||||||
|
for (p = msg; *p != '\0'; ) {
|
||||||
|
len = strlen(p);
|
||||||
|
if (len > maxlen) {
|
||||||
|
/*
|
||||||
|
* Break up the line into what will fit on one syslog(3) line
|
||||||
|
* Try to avoid breaking words into several lines if possible.
|
||||||
|
*/
|
||||||
|
tmp = memrchr(p, ' ', maxlen);
|
||||||
|
if (tmp == NULL)
|
||||||
|
tmp = p + maxlen;
|
||||||
|
|
||||||
|
/* NULL terminate line, but save the char to restore later */
|
||||||
|
save = *tmp;
|
||||||
|
*tmp = '\0';
|
||||||
|
|
||||||
|
mysyslog(pri, fmt, details->submituser, p);
|
||||||
|
|
||||||
|
*tmp = save; /* restore saved character */
|
||||||
|
|
||||||
|
/* Advance p and eliminate leading whitespace */
|
||||||
|
for (p = tmp; *p == ' '; p++)
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
mysyslog(pri, fmt, details->submituser, p);
|
||||||
|
p += len;
|
||||||
|
}
|
||||||
|
fmt = _("%8s : (command continued) %s");
|
||||||
|
maxlen = logsrvd_conf_syslog_maxlen() -
|
||||||
|
(strlen(fmt) - 5 + strlen(details->submituser));
|
||||||
|
}
|
||||||
|
|
||||||
|
debug_return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
do_logfile(const char *logfile, const struct iolog_details *details,
|
||||||
|
const char *msg)
|
||||||
|
{
|
||||||
|
const char *timefmt = logsrvd_conf_logfile_time_format();
|
||||||
|
char timebuf[8192], *timestr = NULL;
|
||||||
|
struct tm *timeptr;
|
||||||
|
bool ret = false;
|
||||||
|
mode_t oldmask;
|
||||||
|
FILE *fp;
|
||||||
|
debug_decl(do_logfile, SUDO_DEBUG_UTIL)
|
||||||
|
|
||||||
|
oldmask = umask(S_IRWXG|S_IRWXO);
|
||||||
|
fp = fopen(logfile, "a");
|
||||||
|
(void) umask(oldmask);
|
||||||
|
if (fp == NULL) {
|
||||||
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
|
||||||
|
"unable to open log file %s", logfile);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if (!sudo_lock_file(fileno(fp), SUDO_LOCK)) {
|
||||||
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
|
||||||
|
"unable to lock log file %s", logfile);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((timeptr = localtime(&details->submit_time)) != NULL) {
|
||||||
|
/* strftime() does not guarantee to NUL-terminate so we must check. */
|
||||||
|
timebuf[sizeof(timebuf) - 1] = '\0';
|
||||||
|
if (strftime(timebuf, sizeof(timebuf), timefmt, timeptr) != 0 &&
|
||||||
|
timebuf[sizeof(timebuf) - 1] == '\0') {
|
||||||
|
timestr = timebuf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(void)fprintf(fp, "%s : %s : %s", timestr ? timestr : "invalid date",
|
||||||
|
details->submituser, msg);
|
||||||
|
(void)fflush(fp);
|
||||||
|
if (ferror(fp)) {
|
||||||
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
|
||||||
|
"unable to write log file %s", logfile);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
ret = true;
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (fp != NULL)
|
||||||
|
(void) fclose(fp);
|
||||||
|
debug_return_bool(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
log_accept(const struct iolog_details *details)
|
||||||
|
{
|
||||||
|
const enum logsrvd_eventlog_type log_type = logsrvd_conf_eventlog_type();
|
||||||
|
char *logline;
|
||||||
|
bool ret = true;
|
||||||
|
int pri;
|
||||||
|
debug_decl(log_accept, SUDO_DEBUG_UTIL)
|
||||||
|
|
||||||
|
if (log_type == EVLOG_NONE)
|
||||||
|
debug_return_bool(true);
|
||||||
|
|
||||||
|
if ((logline = new_logline(NULL, NULL, details)) == NULL)
|
||||||
|
debug_return_bool(false);
|
||||||
|
|
||||||
|
switch (log_type) {
|
||||||
|
case EVLOG_SYSLOG:
|
||||||
|
pri = logsrvd_conf_syslog_acceptpri();
|
||||||
|
if (pri != -1)
|
||||||
|
do_syslog(pri, details, logline);
|
||||||
|
break;
|
||||||
|
case EVLOG_FILE:
|
||||||
|
ret = do_logfile(logsrvd_conf_logfile_path(), details, logline);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
|
"unexpected eventlog type %d", log_type);
|
||||||
|
ret = false;
|
||||||
|
}
|
||||||
|
free(logline);
|
||||||
|
|
||||||
|
debug_return_bool(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
log_reject(const struct iolog_details *details, const char *reason)
|
||||||
|
{
|
||||||
|
const enum logsrvd_eventlog_type log_type = logsrvd_conf_eventlog_type();
|
||||||
|
char *logline;
|
||||||
|
bool ret = true;
|
||||||
|
int pri;
|
||||||
|
debug_decl(log_reject, SUDO_DEBUG_UTIL)
|
||||||
|
|
||||||
|
if (log_type == EVLOG_NONE)
|
||||||
|
debug_return_bool(true);
|
||||||
|
|
||||||
|
if ((logline = new_logline(reason, NULL, details)) == NULL)
|
||||||
|
debug_return_bool(false);
|
||||||
|
|
||||||
|
switch (log_type) {
|
||||||
|
case EVLOG_SYSLOG:
|
||||||
|
pri = logsrvd_conf_syslog_rejectpri();
|
||||||
|
if (pri != -1)
|
||||||
|
do_syslog(pri, details, logline);
|
||||||
|
break;
|
||||||
|
case EVLOG_FILE:
|
||||||
|
ret = do_logfile(logsrvd_conf_logfile_path(), details, logline);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
|
"unexpected eventlog type %d", log_type);
|
||||||
|
ret = false;
|
||||||
|
}
|
||||||
|
free(logline);
|
||||||
|
|
||||||
|
debug_return_bool(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
log_alert(const struct iolog_details *details, TimeSpec *alert_time,
|
||||||
|
const char *reason)
|
||||||
|
{
|
||||||
|
const enum logsrvd_eventlog_type log_type = logsrvd_conf_eventlog_type();
|
||||||
|
char *logline;
|
||||||
|
bool ret = true;
|
||||||
|
int pri;
|
||||||
|
debug_decl(log_alert, SUDO_DEBUG_UTIL)
|
||||||
|
|
||||||
|
if (log_type == EVLOG_NONE)
|
||||||
|
debug_return_bool(true);
|
||||||
|
|
||||||
|
if ((logline = new_logline(reason, NULL, details)) == NULL)
|
||||||
|
debug_return_bool(false);
|
||||||
|
|
||||||
|
/* TODO: log alert_time */
|
||||||
|
switch (log_type) {
|
||||||
|
case EVLOG_SYSLOG:
|
||||||
|
pri = logsrvd_conf_syslog_alertpri();
|
||||||
|
if (pri != -1)
|
||||||
|
do_syslog(pri, details, logline);
|
||||||
|
break;
|
||||||
|
case EVLOG_FILE:
|
||||||
|
ret = do_logfile(logsrvd_conf_logfile_path(), details, logline);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
|
"unexpected eventlog type %d", log_type);
|
||||||
|
ret = false;
|
||||||
|
}
|
||||||
|
free(logline);
|
||||||
|
|
||||||
|
debug_return_bool(ret);
|
||||||
|
}
|
@@ -63,29 +63,94 @@ has_strlistval(InfoMessage *info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Fill in I/O log details from an AcceptMessage
|
* Copy the specified string list.
|
||||||
* Only makes a shallow copy of strings and string lists.
|
* The input string list need not be NULL-terminated.
|
||||||
|
* Returns a NULL-terminated string vector.
|
||||||
*/
|
*/
|
||||||
static bool
|
static char **
|
||||||
iolog_details_fill(struct iolog_details *details, AcceptMessage *msg)
|
strlist_copy(InfoMessage__StringList *strlist)
|
||||||
|
{
|
||||||
|
char **dst, **src = strlist->strings;
|
||||||
|
size_t i, len = strlist->n_strings;
|
||||||
|
debug_decl(strlist_copy, SUDO_DEBUG_UTIL)
|
||||||
|
|
||||||
|
dst = reallocarray(NULL, len + 1, sizeof(char *));
|
||||||
|
if (dst == NULL) {
|
||||||
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
|
||||||
|
"reallocarray(NULL, %zu, %zu)", len + 1, sizeof(char *));
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
if ((dst[i] = strdup(src[i])) == NULL) {
|
||||||
|
sudo_debug_printf(
|
||||||
|
SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO, "strdup");
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst[i] = NULL;
|
||||||
|
debug_return_ptr(dst);
|
||||||
|
|
||||||
|
bad:
|
||||||
|
if (dst != NULL) {
|
||||||
|
while (i--)
|
||||||
|
free(dst[i]);
|
||||||
|
free(dst);
|
||||||
|
}
|
||||||
|
debug_return_ptr(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Free the strings in a struct iolog_details.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
iolog_details_free(struct iolog_details *details)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
debug_decl(iolog_details_free, SUDO_DEBUG_UTIL)
|
||||||
|
|
||||||
|
if (details != NULL) {
|
||||||
|
free(details->iolog_path);
|
||||||
|
free(details->command);
|
||||||
|
free(details->cwd);
|
||||||
|
free(details->rungroup);
|
||||||
|
free(details->runuser);
|
||||||
|
free(details->submithost);
|
||||||
|
free(details->submituser);
|
||||||
|
free(details->submitgroup);
|
||||||
|
free(details->ttyname);
|
||||||
|
for (i = 0; i < details->argc; i++)
|
||||||
|
free(details->argv[i]);
|
||||||
|
free(details->argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
debug_return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fill in I/O log details from an AcceptMessage
|
||||||
|
* Caller is responsible for freeing strings in struct iolog_details.
|
||||||
|
* Returns true on success and false on failure.
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
iolog_details_fill(struct iolog_details *details, TimeSpec *submit_time,
|
||||||
|
InfoMessage **info_msgs, size_t infolen)
|
||||||
{
|
{
|
||||||
size_t idx;
|
size_t idx;
|
||||||
bool ret = true;
|
bool ret = false;
|
||||||
debug_decl(iolog_details_fill, SUDO_DEBUG_UTIL)
|
debug_decl(iolog_details_fill, SUDO_DEBUG_UTIL)
|
||||||
|
|
||||||
memset(details, 0, sizeof(*details));
|
memset(details, 0, sizeof(*details));
|
||||||
|
|
||||||
/* Submit time. */
|
/* Submit time. */
|
||||||
details->submit_time = msg->submit_time->tv_sec;
|
details->submit_time = submit_time->tv_sec;
|
||||||
|
|
||||||
/* Default values */
|
/* Default values */
|
||||||
details->lines = 24;
|
details->lines = 24;
|
||||||
details->columns = 80;
|
details->columns = 80;
|
||||||
details->submitgroup = "unknown";
|
|
||||||
|
|
||||||
/* Pull out values by key from info array. */
|
/* Pull out values by key from info array. */
|
||||||
for (idx = 0; idx < msg->n_info_msgs; idx++) {
|
for (idx = 0; idx < infolen; idx++) {
|
||||||
InfoMessage *info = msg->info_msgs[idx];
|
InfoMessage *info = info_msgs[idx];
|
||||||
const char *key = info->key;
|
const char *key = info->key;
|
||||||
switch (key[0]) {
|
switch (key[0]) {
|
||||||
case 'c':
|
case 'c':
|
||||||
@@ -103,7 +168,12 @@ iolog_details_fill(struct iolog_details *details, AcceptMessage *msg)
|
|||||||
}
|
}
|
||||||
if (strcmp(key, "command") == 0) {
|
if (strcmp(key, "command") == 0) {
|
||||||
if (has_strval(info)) {
|
if (has_strval(info)) {
|
||||||
details->command = info->strval;
|
if ((details->command = strdup(info->strval)) == NULL) {
|
||||||
|
sudo_debug_printf(
|
||||||
|
SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
|
||||||
|
"strdup");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
"command specified but not a string");
|
"command specified but not a string");
|
||||||
@@ -112,7 +182,12 @@ iolog_details_fill(struct iolog_details *details, AcceptMessage *msg)
|
|||||||
}
|
}
|
||||||
if (strcmp(key, "cwd") == 0) {
|
if (strcmp(key, "cwd") == 0) {
|
||||||
if (has_strval(info)) {
|
if (has_strval(info)) {
|
||||||
details->cwd = info->strval;
|
if ((details->cwd = strdup(info->strval)) == NULL) {
|
||||||
|
sudo_debug_printf(
|
||||||
|
SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
|
||||||
|
"strdup");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
"cwd specified but not a string");
|
"cwd specified but not a string");
|
||||||
@@ -137,7 +212,9 @@ iolog_details_fill(struct iolog_details *details, AcceptMessage *msg)
|
|||||||
case 'r':
|
case 'r':
|
||||||
if (strcmp(key, "runargv") == 0) {
|
if (strcmp(key, "runargv") == 0) {
|
||||||
if (has_strlistval(info)) {
|
if (has_strlistval(info)) {
|
||||||
details->argv = info->strlistval->strings;
|
details->argv = strlist_copy(info->strlistval);
|
||||||
|
if (details->argv == NULL)
|
||||||
|
goto done;
|
||||||
details->argc = info->strlistval->n_strings;
|
details->argc = info->strlistval->n_strings;
|
||||||
} else {
|
} else {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
@@ -147,7 +224,12 @@ iolog_details_fill(struct iolog_details *details, AcceptMessage *msg)
|
|||||||
}
|
}
|
||||||
if (strcmp(key, "rungroup") == 0) {
|
if (strcmp(key, "rungroup") == 0) {
|
||||||
if (has_strval(info)) {
|
if (has_strval(info)) {
|
||||||
details->rungroup = info->strval;
|
if ((details->rungroup = strdup(info->strval)) == NULL) {
|
||||||
|
sudo_debug_printf(
|
||||||
|
SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
|
||||||
|
"strdup");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
"rungroup specified but not a string");
|
"rungroup specified but not a string");
|
||||||
@@ -156,7 +238,12 @@ iolog_details_fill(struct iolog_details *details, AcceptMessage *msg)
|
|||||||
}
|
}
|
||||||
if (strcmp(key, "runuser") == 0) {
|
if (strcmp(key, "runuser") == 0) {
|
||||||
if (has_strval(info)) {
|
if (has_strval(info)) {
|
||||||
details->runuser = info->strval;
|
if ((details->runuser = strdup(info->strval)) == NULL) {
|
||||||
|
sudo_debug_printf(
|
||||||
|
SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
|
||||||
|
"strdup");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
"runuser specified but not a string");
|
"runuser specified but not a string");
|
||||||
@@ -167,7 +254,12 @@ iolog_details_fill(struct iolog_details *details, AcceptMessage *msg)
|
|||||||
case 's':
|
case 's':
|
||||||
if (strcmp(key, "submithost") == 0) {
|
if (strcmp(key, "submithost") == 0) {
|
||||||
if (has_strval(info)) {
|
if (has_strval(info)) {
|
||||||
details->submithost = info->strval;
|
if ((details->submithost = strdup(info->strval)) == NULL) {
|
||||||
|
sudo_debug_printf(
|
||||||
|
SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
|
||||||
|
"strdup");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
"submithost specified but not a string");
|
"submithost specified but not a string");
|
||||||
@@ -176,7 +268,12 @@ iolog_details_fill(struct iolog_details *details, AcceptMessage *msg)
|
|||||||
}
|
}
|
||||||
if (strcmp(key, "submitgroup") == 0) {
|
if (strcmp(key, "submitgroup") == 0) {
|
||||||
if (has_strval(info)) {
|
if (has_strval(info)) {
|
||||||
details->submitgroup = info->strval;
|
if ((details->submitgroup = strdup(info->strval)) == NULL) {
|
||||||
|
sudo_debug_printf(
|
||||||
|
SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
|
||||||
|
"strdup");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
"submitgroup specified but not a string");
|
"submitgroup specified but not a string");
|
||||||
@@ -185,7 +282,12 @@ iolog_details_fill(struct iolog_details *details, AcceptMessage *msg)
|
|||||||
}
|
}
|
||||||
if (strcmp(key, "submituser") == 0) {
|
if (strcmp(key, "submituser") == 0) {
|
||||||
if (has_strval(info)) {
|
if (has_strval(info)) {
|
||||||
details->submituser = info->strval;
|
if ((details->submituser = strdup(info->strval)) == NULL) {
|
||||||
|
sudo_debug_printf(
|
||||||
|
SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
|
||||||
|
"strdup");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
"submituser specified but not a string");
|
"submituser specified but not a string");
|
||||||
@@ -196,7 +298,12 @@ iolog_details_fill(struct iolog_details *details, AcceptMessage *msg)
|
|||||||
case 't':
|
case 't':
|
||||||
if (strcmp(key, "ttyname") == 0) {
|
if (strcmp(key, "ttyname") == 0) {
|
||||||
if (has_strval(info)) {
|
if (has_strval(info)) {
|
||||||
details->ttyname = info->strval;
|
if ((details->ttyname = strdup(info->strval)) == NULL) {
|
||||||
|
sudo_debug_printf(
|
||||||
|
SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
|
||||||
|
"strdup");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
"ttyname specified but not a string");
|
"ttyname specified but not a string");
|
||||||
@@ -207,23 +314,38 @@ iolog_details_fill(struct iolog_details *details, AcceptMessage *msg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO: make submitgroup required */
|
||||||
|
if (details->submitgroup == NULL) {
|
||||||
|
if ((details->submitgroup = strdup("unknown")) == NULL) {
|
||||||
|
sudo_debug_printf(
|
||||||
|
SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
|
||||||
|
"strdup");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Check for required settings */
|
/* Check for required settings */
|
||||||
if (details->submituser == NULL) {
|
if (details->submituser == NULL) {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
"missing user in AcceptMessage");
|
"missing user in AcceptMessage");
|
||||||
ret = false;
|
goto done;
|
||||||
}
|
}
|
||||||
if (details->submithost == NULL) {
|
if (details->submithost == NULL) {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
"missing host in AcceptMessage");
|
"missing host in AcceptMessage");
|
||||||
ret = false;
|
goto done;
|
||||||
}
|
}
|
||||||
if (details->command == NULL) {
|
if (details->command == NULL) {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
"missing command in AcceptMessage");
|
"missing command in AcceptMessage");
|
||||||
ret = false;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = true;
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (!ret)
|
||||||
|
iolog_details_free(details);
|
||||||
debug_return_bool(ret);
|
debug_return_bool(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -351,54 +473,58 @@ static const struct iolog_path_escape path_escapes[] = {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Create I/O log path
|
* Create I/O log path
|
||||||
* Sets iolog_dir and iolog_dir_fd in the closure
|
* Sets iolog_path, iolog_file and iolog_dir_fd in the closure
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
create_iolog_dir(struct iolog_details *details, struct connection_closure *closure)
|
create_iolog_path(struct connection_closure *closure)
|
||||||
{
|
{
|
||||||
|
struct iolog_details *details = &closure->details;
|
||||||
char pathbuf[PATH_MAX];
|
char pathbuf[PATH_MAX];
|
||||||
size_t len;
|
size_t len, pathlen;
|
||||||
debug_decl(create_iolog_dir, SUDO_DEBUG_UTIL)
|
debug_decl(create_iolog_path, SUDO_DEBUG_UTIL)
|
||||||
|
|
||||||
/* XXX - awkward api */
|
details->iolog_path = expand_iolog_path(NULL, logsrvd_conf_iolog_dir(),
|
||||||
closure->iolog_dir = expand_iolog_path(NULL, logsrvd_conf_iolog_dir(),
|
logsrvd_conf_iolog_file(), &details->iolog_file, &path_escapes[0],
|
||||||
logsrvd_conf_iolog_file(), NULL, &path_escapes[0], details);
|
details);
|
||||||
if (closure->iolog_dir == NULL) {
|
if (details->iolog_path == NULL) {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
"unable to expand iolog path %s/%s",
|
"unable to expand iolog path %s/%s",
|
||||||
logsrvd_conf_iolog_dir(), logsrvd_conf_iolog_file());
|
logsrvd_conf_iolog_dir(), logsrvd_conf_iolog_file());
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
pathlen = details->iolog_file - details->iolog_path;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make local copy of I/O log path and create it, along with any
|
* Make local copy of I/O log path and create it, along with any
|
||||||
* intermediate subdirs. Calls mkdtemp() if iolog_path ends in XXXXXX.
|
* intermediate subdirs. Calls mkdtemp() if iolog_path ends in XXXXXX.
|
||||||
*/
|
*/
|
||||||
len = mkdir_iopath(closure->iolog_dir, pathbuf, sizeof(pathbuf));
|
len = mkdir_iopath(details->iolog_path, pathbuf, sizeof(pathbuf));
|
||||||
if (len >= sizeof(pathbuf)) {
|
if (len >= sizeof(pathbuf)) {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
|
||||||
"unable to mkdir iolog path %s", closure->iolog_dir);
|
"unable to mkdir iolog path %s", details->iolog_path);
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
free(closure->iolog_dir);
|
free(details->iolog_path);
|
||||||
if ((closure->iolog_dir = strdup(pathbuf)) == NULL) {
|
if ((details->iolog_path = strdup(pathbuf)) == NULL) {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
|
||||||
"strdup");
|
"strdup");
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
details->iolog_file = details->iolog_path + pathlen + 1;
|
||||||
|
|
||||||
/* We use iolog_dir_fd in calls to openat(2) */
|
/* We use iolog_dir_fd in calls to openat(2) */
|
||||||
closure->iolog_dir_fd =
|
closure->iolog_dir_fd =
|
||||||
iolog_openat(AT_FDCWD, closure->iolog_dir, O_RDONLY);
|
iolog_openat(AT_FDCWD, details->iolog_path, O_RDONLY);
|
||||||
if (closure->iolog_dir_fd == -1) {
|
if (closure->iolog_dir_fd == -1) {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
|
||||||
"%s", closure->iolog_dir);
|
"%s", details->iolog_path);
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
debug_return_bool(true);
|
debug_return_bool(true);
|
||||||
bad:
|
bad:
|
||||||
free(closure->iolog_dir);
|
free(details->iolog_path);
|
||||||
|
details->iolog_path = NULL;
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -424,7 +550,7 @@ iolog_details_write(struct iolog_details *details,
|
|||||||
log_info.cols = details->columns;
|
log_info.cols = details->columns;
|
||||||
|
|
||||||
debug_return_bool(iolog_write_info_file(closure->iolog_dir_fd,
|
debug_return_bool(iolog_write_info_file(closure->iolog_dir_fd,
|
||||||
closure->iolog_dir, &log_info, details->argv));
|
details->iolog_path, &log_info, details->argv));
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
@@ -467,19 +593,14 @@ iolog_close_all(struct connection_closure *closure)
|
|||||||
bool
|
bool
|
||||||
iolog_init(AcceptMessage *msg, struct connection_closure *closure)
|
iolog_init(AcceptMessage *msg, struct connection_closure *closure)
|
||||||
{
|
{
|
||||||
struct iolog_details details;
|
|
||||||
debug_decl(iolog_init, SUDO_DEBUG_UTIL)
|
debug_decl(iolog_init, SUDO_DEBUG_UTIL)
|
||||||
|
|
||||||
/* Fill in iolog_details */
|
/* Create I/O log path */
|
||||||
if (!iolog_details_fill(&details, msg))
|
if (!create_iolog_path(closure))
|
||||||
debug_return_bool(false);
|
|
||||||
|
|
||||||
/* Create I/O log dir */
|
|
||||||
if (!create_iolog_dir(&details, closure))
|
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
|
|
||||||
/* Write sudo I/O log info file */
|
/* Write sudo I/O log info file */
|
||||||
if (!iolog_details_write(&details, closure))
|
if (!iolog_details_write(&closure->details, closure))
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -541,7 +662,7 @@ iolog_restart(RestartMessage *msg, struct connection_closure *closure)
|
|||||||
target.tv_sec = msg->resume_point->tv_sec;
|
target.tv_sec = msg->resume_point->tv_sec;
|
||||||
target.tv_nsec = msg->resume_point->tv_nsec;
|
target.tv_nsec = msg->resume_point->tv_nsec;
|
||||||
|
|
||||||
if ((closure->iolog_dir = strdup(msg->log_id)) == NULL) {
|
if ((closure->details.iolog_path = strdup(msg->log_id)) == NULL) {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
|
||||||
"strdup");
|
"strdup");
|
||||||
goto bad;
|
goto bad;
|
||||||
@@ -555,7 +676,7 @@ iolog_restart(RestartMessage *msg, struct connection_closure *closure)
|
|||||||
if (errno != ENOENT) {
|
if (errno != ENOENT) {
|
||||||
sudo_debug_printf(
|
sudo_debug_printf(
|
||||||
SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
|
SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
|
||||||
"unable to open %s/%s", closure->iolog_dir,
|
"unable to open %s/%s", closure->details.iolog_path,
|
||||||
iolog_fd_to_name(iofd));
|
iolog_fd_to_name(iofd));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
@@ -563,7 +684,7 @@ iolog_restart(RestartMessage *msg, struct connection_closure *closure)
|
|||||||
}
|
}
|
||||||
if (!closure->iolog_files[IOFD_TIMING].enabled) {
|
if (!closure->iolog_files[IOFD_TIMING].enabled) {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
"missing timing file in %s", closure->iolog_dir);
|
"missing timing file in %s", closure->details.iolog_path);
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -666,7 +787,7 @@ store_iobuf(int iofd, IoBuffer *msg, struct connection_closure *closure)
|
|||||||
if (!iolog_write(&closure->iolog_files[iofd], msg->data.data,
|
if (!iolog_write(&closure->iolog_files[iofd], msg->data.data,
|
||||||
msg->data.len, &errstr)) {
|
msg->data.len, &errstr)) {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
"unable to write to %s/%s: %s", closure->iolog_dir,
|
"unable to write to %s/%s: %s", closure->details.iolog_path,
|
||||||
iolog_fd_to_name(iofd), errstr);
|
iolog_fd_to_name(iofd), errstr);
|
||||||
debug_return_int(-1);
|
debug_return_int(-1);
|
||||||
}
|
}
|
||||||
@@ -675,7 +796,7 @@ store_iobuf(int iofd, IoBuffer *msg, struct connection_closure *closure)
|
|||||||
if (!iolog_write(&closure->iolog_files[IOFD_TIMING], tbuf,
|
if (!iolog_write(&closure->iolog_files[IOFD_TIMING], tbuf,
|
||||||
len, &errstr)) {
|
len, &errstr)) {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
"unable to write to %s/%s: %s", closure->iolog_dir,
|
"unable to write to %s/%s: %s", closure->details.iolog_path,
|
||||||
iolog_fd_to_name(IOFD_TIMING), errstr);
|
iolog_fd_to_name(IOFD_TIMING), errstr);
|
||||||
debug_return_int(-1);
|
debug_return_int(-1);
|
||||||
}
|
}
|
||||||
@@ -707,7 +828,7 @@ store_suspend(CommandSuspend *msg, struct connection_closure *closure)
|
|||||||
if (!iolog_write(&closure->iolog_files[IOFD_TIMING], tbuf,
|
if (!iolog_write(&closure->iolog_files[IOFD_TIMING], tbuf,
|
||||||
len, &errstr)) {
|
len, &errstr)) {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
"unable to write to %s/%s: %s", closure->iolog_dir,
|
"unable to write to %s/%s: %s", closure->details.iolog_path,
|
||||||
iolog_fd_to_name(IOFD_TIMING), errstr);
|
iolog_fd_to_name(IOFD_TIMING), errstr);
|
||||||
debug_return_int(-1);
|
debug_return_int(-1);
|
||||||
}
|
}
|
||||||
@@ -739,7 +860,7 @@ store_winsize(ChangeWindowSize *msg, struct connection_closure *closure)
|
|||||||
if (!iolog_write(&closure->iolog_files[IOFD_TIMING], tbuf,
|
if (!iolog_write(&closure->iolog_files[IOFD_TIMING], tbuf,
|
||||||
len, &errstr)) {
|
len, &errstr)) {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
"unable to write to %s/%s: %s", closure->iolog_dir,
|
"unable to write to %s/%s: %s", closure->details.iolog_path,
|
||||||
iolog_fd_to_name(IOFD_TIMING), errstr);
|
iolog_fd_to_name(IOFD_TIMING), errstr);
|
||||||
debug_return_int(-1);
|
debug_return_int(-1);
|
||||||
}
|
}
|
||||||
|
@@ -87,9 +87,9 @@ connection_closure_free(struct connection_closure *closure)
|
|||||||
sudo_ev_free(closure->commit_ev);
|
sudo_ev_free(closure->commit_ev);
|
||||||
sudo_ev_free(closure->read_ev);
|
sudo_ev_free(closure->read_ev);
|
||||||
sudo_ev_free(closure->write_ev);
|
sudo_ev_free(closure->write_ev);
|
||||||
|
iolog_details_free(&closure->details);
|
||||||
free(closure->read_buf.data);
|
free(closure->read_buf.data);
|
||||||
free(closure->write_buf.data);
|
free(closure->write_buf.data);
|
||||||
free(closure->iolog_dir);
|
|
||||||
free(closure);
|
free(closure);
|
||||||
|
|
||||||
if (shutting_down && TAILQ_EMPTY(&connections))
|
if (shutting_down && TAILQ_EMPTY(&connections))
|
||||||
@@ -206,20 +206,32 @@ handle_accept(AcceptMessage *msg, struct connection_closure *closure)
|
|||||||
closure->submit_time.tv_sec = msg->submit_time->tv_sec;
|
closure->submit_time.tv_sec = msg->submit_time->tv_sec;
|
||||||
closure->submit_time.tv_nsec = msg->submit_time->tv_nsec;
|
closure->submit_time.tv_nsec = msg->submit_time->tv_nsec;
|
||||||
|
|
||||||
/* TODO: handle event logging via syslog */
|
if (!iolog_details_fill(&closure->details, msg->submit_time, msg->info_msgs,
|
||||||
|
msg->n_info_msgs)) {
|
||||||
|
closure->errstr = _("error parsing AcceptMessage");
|
||||||
|
debug_return_bool(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create I/O log info file and parent directories. */
|
||||||
|
if (msg->expect_iobufs) {
|
||||||
|
if (!iolog_init(msg, closure)) {
|
||||||
|
closure->errstr = _("error creating I/O log");
|
||||||
|
debug_return_bool(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!log_accept(&closure->details)) {
|
||||||
|
closure->errstr = _("error logging accept event");
|
||||||
|
debug_return_bool(false);
|
||||||
|
}
|
||||||
|
|
||||||
if (!msg->expect_iobufs) {
|
if (!msg->expect_iobufs) {
|
||||||
closure->state = FLUSHED;
|
closure->state = FLUSHED;
|
||||||
debug_return_bool(true);
|
debug_return_bool(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create I/O log info file and parent directories. */
|
|
||||||
if (!iolog_init(msg, closure)) {
|
|
||||||
closure->errstr = _("error creating I/O log");
|
|
||||||
debug_return_bool(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Send log ID to client for restarting connectoins. */
|
/* Send log ID to client for restarting connectoins. */
|
||||||
if (!fmt_log_id_message(closure->iolog_dir, &closure->write_buf))
|
if (!fmt_log_id_message(closure->details.iolog_path, &closure->write_buf))
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
if (sudo_ev_add(NULL, closure->write_ev, NULL, false) == -1) {
|
if (sudo_ev_add(NULL, closure->write_ev, NULL, false) == -1) {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
@@ -260,7 +272,16 @@ handle_reject(RejectMessage *msg, struct connection_closure *closure)
|
|||||||
closure->submit_time.tv_sec = msg->submit_time->tv_sec;
|
closure->submit_time.tv_sec = msg->submit_time->tv_sec;
|
||||||
closure->submit_time.tv_nsec = msg->submit_time->tv_nsec;
|
closure->submit_time.tv_nsec = msg->submit_time->tv_nsec;
|
||||||
|
|
||||||
/* TODO: handle event logging via syslog */
|
if (!iolog_details_fill(&closure->details, msg->submit_time, msg->info_msgs,
|
||||||
|
msg->n_info_msgs)) {
|
||||||
|
closure->errstr = _("error parsing RejectMessage");
|
||||||
|
debug_return_bool(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!log_reject(&closure->details, msg->reason)) {
|
||||||
|
closure->errstr = _("error logging reject event");
|
||||||
|
debug_return_bool(false);
|
||||||
|
}
|
||||||
|
|
||||||
closure->state = FLUSHED;
|
closure->state = FLUSHED;
|
||||||
debug_return_bool(true);
|
debug_return_bool(true);
|
||||||
@@ -346,8 +367,12 @@ handle_alert(AlertMessage *msg, struct connection_closure *closure)
|
|||||||
{
|
{
|
||||||
debug_decl(handle_alert, SUDO_DEBUG_UTIL)
|
debug_decl(handle_alert, SUDO_DEBUG_UTIL)
|
||||||
|
|
||||||
/* TODO */
|
if (!log_alert(&closure->details, msg->alert_time, msg->reason)) {
|
||||||
debug_return_bool(false);
|
closure->errstr = _("error logging alert event");
|
||||||
|
debug_return_bool(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
debug_return_bool(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
@@ -35,9 +35,10 @@
|
|||||||
* I/O log details from the AcceptMessage + iolog path and sessid.
|
* I/O log details from the AcceptMessage + iolog path and sessid.
|
||||||
*/
|
*/
|
||||||
struct iolog_details {
|
struct iolog_details {
|
||||||
|
char *iolog_path;
|
||||||
|
char *iolog_file; /* substring of iolog_path, do not free */
|
||||||
char *command;
|
char *command;
|
||||||
char *cwd;
|
char *cwd;
|
||||||
char *iolog_dir;
|
|
||||||
char *rungroup;
|
char *rungroup;
|
||||||
char *runuser;
|
char *runuser;
|
||||||
char *submithost;
|
char *submithost;
|
||||||
@@ -45,6 +46,7 @@ struct iolog_details {
|
|||||||
char *submitgroup;
|
char *submitgroup;
|
||||||
char *ttyname;
|
char *ttyname;
|
||||||
char **argv;
|
char **argv;
|
||||||
|
char **env_add;
|
||||||
time_t submit_time;
|
time_t submit_time;
|
||||||
int argc;
|
int argc;
|
||||||
int lines;
|
int lines;
|
||||||
@@ -78,6 +80,7 @@ struct connection_buffer {
|
|||||||
*/
|
*/
|
||||||
struct connection_closure {
|
struct connection_closure {
|
||||||
TAILQ_ENTRY(connection_closure) entries;
|
TAILQ_ENTRY(connection_closure) entries;
|
||||||
|
struct iolog_details details;
|
||||||
struct timespec submit_time;
|
struct timespec submit_time;
|
||||||
struct timespec elapsed_time;
|
struct timespec elapsed_time;
|
||||||
struct connection_buffer read_buf;
|
struct connection_buffer read_buf;
|
||||||
@@ -85,7 +88,6 @@ struct connection_closure {
|
|||||||
struct sudo_event *commit_ev;
|
struct sudo_event *commit_ev;
|
||||||
struct sudo_event *read_ev;
|
struct sudo_event *read_ev;
|
||||||
struct sudo_event *write_ev;
|
struct sudo_event *write_ev;
|
||||||
char *iolog_dir;
|
|
||||||
const char *errstr;
|
const char *errstr;
|
||||||
struct iolog_file iolog_files[IOFD_MAX];
|
struct iolog_file iolog_files[IOFD_MAX];
|
||||||
int iolog_dir_fd;
|
int iolog_dir_fd;
|
||||||
@@ -111,18 +113,46 @@ struct listen_address {
|
|||||||
};
|
};
|
||||||
TAILQ_HEAD(listen_address_list, listen_address);
|
TAILQ_HEAD(listen_address_list, listen_address);
|
||||||
|
|
||||||
|
/* Supported eventlog types */
|
||||||
|
enum logsrvd_eventlog_type {
|
||||||
|
EVLOG_NONE,
|
||||||
|
EVLOG_SYSLOG,
|
||||||
|
EVLOG_FILE,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Supported eventlog formats (currently just sudo) */
|
||||||
|
enum logsrvd_eventlog_format {
|
||||||
|
EVLOG_SUDO
|
||||||
|
};
|
||||||
|
|
||||||
|
/* eventlog.c */
|
||||||
|
bool log_accept(const struct iolog_details *details);
|
||||||
|
bool log_reject(const struct iolog_details *details, const char *reason);
|
||||||
|
bool log_alert(const struct iolog_details *details, TimeSpec *alert_time, const char *reason);
|
||||||
|
|
||||||
/* iolog_writer.c */
|
/* iolog_writer.c */
|
||||||
|
bool iolog_details_fill(struct iolog_details *details, TimeSpec *submit_time, InfoMessage **info_msgs, size_t infolen);
|
||||||
bool iolog_init(AcceptMessage *msg, struct connection_closure *closure);
|
bool iolog_init(AcceptMessage *msg, struct connection_closure *closure);
|
||||||
bool iolog_restart(RestartMessage *msg, struct connection_closure *closure);
|
bool iolog_restart(RestartMessage *msg, struct connection_closure *closure);
|
||||||
int store_iobuf(int iofd, IoBuffer *msg, struct connection_closure *closure);
|
int store_iobuf(int iofd, IoBuffer *msg, struct connection_closure *closure);
|
||||||
int store_suspend(CommandSuspend *msg, struct connection_closure *closure);
|
int store_suspend(CommandSuspend *msg, struct connection_closure *closure);
|
||||||
int store_winsize(ChangeWindowSize *msg, struct connection_closure *closure);
|
int store_winsize(ChangeWindowSize *msg, struct connection_closure *closure);
|
||||||
void iolog_close_all(struct connection_closure *closure);
|
void iolog_close_all(struct connection_closure *closure);
|
||||||
|
void iolog_details_free(struct iolog_details *details);
|
||||||
|
|
||||||
/* logsrvd_conf.c */
|
/* logsrvd_conf.c */
|
||||||
bool logsrvd_conf_read(const char *path);
|
bool logsrvd_conf_read(const char *path);
|
||||||
const char *logsrvd_conf_iolog_dir(void);
|
const char *logsrvd_conf_iolog_dir(void);
|
||||||
const char *logsrvd_conf_iolog_file(void);
|
const char *logsrvd_conf_iolog_file(void);
|
||||||
struct listen_address_list *logsrvd_conf_listen_address(void);
|
struct listen_address_list *logsrvd_conf_listen_address(void);
|
||||||
|
enum logsrvd_eventlog_type logsrvd_conf_eventlog_type(void);
|
||||||
|
enum logsrvd_eventlog_format logsrvd_conf_eventlog_format(void);
|
||||||
|
unsigned int logsrvd_conf_syslog_maxlen(void);
|
||||||
|
int logsrvd_conf_syslog_facility(void);
|
||||||
|
int logsrvd_conf_syslog_acceptpri(void);
|
||||||
|
int logsrvd_conf_syslog_rejectpri(void);
|
||||||
|
int logsrvd_conf_syslog_alertpri(void);
|
||||||
|
const char *logsrvd_conf_logfile_path(void);
|
||||||
|
const char *logsrvd_conf_logfile_time_format(void);
|
||||||
|
|
||||||
#endif /* SUDO_LOGSRVD_H */
|
#endif /* SUDO_LOGSRVD_H */
|
||||||
|
@@ -64,30 +64,114 @@ struct logsrvd_config_section {
|
|||||||
struct logsrvd_config_entry *entries;
|
struct logsrvd_config_entry *entries;
|
||||||
};
|
};
|
||||||
|
|
||||||
static char *logsrvd_iolog_dir;
|
static struct logsrvd_config {
|
||||||
|
struct logsrvd_config_server {
|
||||||
|
struct listen_address_list addresses;
|
||||||
|
} server;
|
||||||
|
struct logsrvd_config_iolog {
|
||||||
|
/* XXX - others private to iolog */
|
||||||
|
char *iolog_dir;
|
||||||
|
char *iolog_file;
|
||||||
|
} iolog;
|
||||||
|
struct logsrvd_config_eventlog {
|
||||||
|
enum logsrvd_eventlog_type log_type;
|
||||||
|
enum logsrvd_eventlog_format log_format;
|
||||||
|
} eventlog;
|
||||||
|
struct logsrvd_config_syslog {
|
||||||
|
unsigned int maxlen;
|
||||||
|
int facility;
|
||||||
|
int acceptpri;
|
||||||
|
int rejectpri;
|
||||||
|
int alertpri;
|
||||||
|
} syslog;
|
||||||
|
struct logsrvd_config_logfile {
|
||||||
|
char *path;
|
||||||
|
char *time_format;
|
||||||
|
} logfile;
|
||||||
|
} logsrvd_config = {
|
||||||
|
{ TAILQ_HEAD_INITIALIZER(logsrvd_config.server.addresses) }
|
||||||
|
};
|
||||||
|
|
||||||
|
/* iolog getters */
|
||||||
const char *
|
const char *
|
||||||
logsrvd_conf_iolog_dir(void)
|
logsrvd_conf_iolog_dir(void)
|
||||||
{
|
{
|
||||||
return logsrvd_iolog_dir;
|
return logsrvd_config.iolog.iolog_dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *logsrvd_iolog_file;
|
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
logsrvd_conf_iolog_file(void)
|
logsrvd_conf_iolog_file(void)
|
||||||
{
|
{
|
||||||
return logsrvd_iolog_file;
|
return logsrvd_config.iolog.iolog_file;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct listen_address_list addresses = TAILQ_HEAD_INITIALIZER(addresses);
|
/* server getters */
|
||||||
|
|
||||||
struct listen_address_list *
|
struct listen_address_list *
|
||||||
logsrvd_conf_listen_address(void)
|
logsrvd_conf_listen_address(void)
|
||||||
{
|
{
|
||||||
return &addresses;
|
return &logsrvd_config.server.addresses;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* eventlog getters */
|
||||||
|
enum logsrvd_eventlog_type
|
||||||
|
logsrvd_conf_eventlog_type(void)
|
||||||
|
{
|
||||||
|
return logsrvd_config.eventlog.log_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum logsrvd_eventlog_format
|
||||||
|
logsrvd_conf_eventlog_format(void)
|
||||||
|
{
|
||||||
|
return logsrvd_config.eventlog.log_format;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* syslog getters */
|
||||||
|
unsigned int
|
||||||
|
logsrvd_conf_syslog_maxlen(void)
|
||||||
|
{
|
||||||
|
return logsrvd_config.syslog.maxlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
logsrvd_conf_syslog_facility(void)
|
||||||
|
{
|
||||||
|
return logsrvd_config.syslog.facility;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
logsrvd_conf_syslog_acceptpri(void)
|
||||||
|
{
|
||||||
|
return logsrvd_config.syslog.acceptpri;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
logsrvd_conf_syslog_rejectpri(void)
|
||||||
|
{
|
||||||
|
return logsrvd_config.syslog.rejectpri;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
logsrvd_conf_syslog_alertpri(void)
|
||||||
|
{
|
||||||
|
return logsrvd_config.syslog.alertpri;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* logfile getters */
|
||||||
|
const char *
|
||||||
|
logsrvd_conf_logfile_path(void)
|
||||||
|
{
|
||||||
|
return logsrvd_config.logfile.path;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
logsrvd_conf_logfile_time_format(void)
|
||||||
|
{
|
||||||
|
return logsrvd_config.logfile.time_format;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reset logsrvd_config to default values and reset I/O log values.
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
logsrvd_conf_reset(void)
|
logsrvd_conf_reset(void)
|
||||||
{
|
{
|
||||||
@@ -95,26 +179,30 @@ logsrvd_conf_reset(void)
|
|||||||
debug_decl(logsrvd_conf_reset, SUDO_DEBUG_UTIL)
|
debug_decl(logsrvd_conf_reset, SUDO_DEBUG_UTIL)
|
||||||
|
|
||||||
iolog_set_defaults();
|
iolog_set_defaults();
|
||||||
free(logsrvd_iolog_dir);
|
free(logsrvd_config.iolog.iolog_dir);
|
||||||
logsrvd_iolog_dir = NULL;
|
logsrvd_config.iolog.iolog_dir = NULL;
|
||||||
free(logsrvd_iolog_file);
|
free(logsrvd_config.iolog.iolog_file);
|
||||||
logsrvd_iolog_file = NULL;
|
logsrvd_config.iolog.iolog_file = NULL;
|
||||||
|
|
||||||
while ((addr = TAILQ_FIRST(&addresses))) {
|
while ((addr = TAILQ_FIRST(&logsrvd_config.server.addresses))) {
|
||||||
TAILQ_REMOVE(&addresses, addr, entries);
|
TAILQ_REMOVE(&logsrvd_config.server.addresses, addr, entries);
|
||||||
free(addr);
|
free(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(logsrvd_config.logfile.path);
|
||||||
|
free(logsrvd_config.logfile.time_format);
|
||||||
|
|
||||||
debug_return;
|
debug_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* I/O log callbacks */
|
||||||
static bool
|
static bool
|
||||||
cb_iolog_dir(const char *path)
|
cb_iolog_dir(const char *path)
|
||||||
{
|
{
|
||||||
debug_decl(cb_iolog_dir, SUDO_DEBUG_UTIL)
|
debug_decl(cb_iolog_dir, SUDO_DEBUG_UTIL)
|
||||||
|
|
||||||
free(logsrvd_iolog_dir);
|
free(logsrvd_config.iolog.iolog_dir);
|
||||||
if ((logsrvd_iolog_dir = strdup(path)) == NULL) {
|
if ((logsrvd_config.iolog.iolog_dir = strdup(path)) == NULL) {
|
||||||
sudo_warn(NULL);
|
sudo_warn(NULL);
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
}
|
}
|
||||||
@@ -126,8 +214,8 @@ cb_iolog_file(const char *path)
|
|||||||
{
|
{
|
||||||
debug_decl(cb_iolog_file, SUDO_DEBUG_UTIL)
|
debug_decl(cb_iolog_file, SUDO_DEBUG_UTIL)
|
||||||
|
|
||||||
free(logsrvd_iolog_file);
|
free(logsrvd_config.iolog.iolog_file);
|
||||||
if ((logsrvd_iolog_file = strdup(path)) == NULL) {
|
if ((logsrvd_config.iolog.iolog_file = strdup(path)) == NULL) {
|
||||||
sudo_warn(NULL);
|
sudo_warn(NULL);
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
}
|
}
|
||||||
@@ -192,6 +280,13 @@ cb_iolog_mode(const char *str)
|
|||||||
debug_return_bool(iolog_set_mode(mode));
|
debug_return_bool(iolog_set_mode(mode));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
cb_iolog_maxseq(const char *str)
|
||||||
|
{
|
||||||
|
return iolog_set_maxseq(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Server callbacks */
|
||||||
/* TODO: unit test */
|
/* TODO: unit test */
|
||||||
static bool
|
static bool
|
||||||
cb_listen_address(const char *str)
|
cb_listen_address(const char *str)
|
||||||
@@ -256,7 +351,7 @@ cb_listen_address(const char *str)
|
|||||||
}
|
}
|
||||||
memcpy(&addr->sa_un, res->ai_addr, res->ai_addrlen);
|
memcpy(&addr->sa_un, res->ai_addr, res->ai_addrlen);
|
||||||
addr->sa_len = res->ai_addrlen;
|
addr->sa_len = res->ai_addrlen;
|
||||||
TAILQ_INSERT_TAIL(&addresses, addr, entries);
|
TAILQ_INSERT_TAIL(&logsrvd_config.server.addresses, addr, entries);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = true;
|
ret = true;
|
||||||
@@ -267,10 +362,157 @@ done:
|
|||||||
debug_return_bool(ret);
|
debug_return_bool(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* eventlog callbacks */
|
||||||
static bool
|
static bool
|
||||||
cb_maxseq(const char *str)
|
cb_eventlog_type(const char *str)
|
||||||
{
|
{
|
||||||
return iolog_set_maxseq(str);
|
debug_decl(cb_eventlog_type, SUDO_DEBUG_UTIL)
|
||||||
|
|
||||||
|
if (strcmp(str, "none") == 0)
|
||||||
|
logsrvd_config.eventlog.log_type = EVLOG_NONE;
|
||||||
|
else if (strcmp(str, "syslog") == 0)
|
||||||
|
logsrvd_config.eventlog.log_type = EVLOG_SYSLOG;
|
||||||
|
else if (strcmp(str, "logfile") == 0)
|
||||||
|
logsrvd_config.eventlog.log_type = EVLOG_FILE;
|
||||||
|
else
|
||||||
|
debug_return_bool(false);
|
||||||
|
|
||||||
|
debug_return_bool(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
cb_eventlog_format(const char *str)
|
||||||
|
{
|
||||||
|
debug_decl(cb_eventlog_format, SUDO_DEBUG_UTIL)
|
||||||
|
|
||||||
|
if (strcmp(str, "sudo") == 0)
|
||||||
|
logsrvd_config.eventlog.log_format = EVLOG_SUDO;
|
||||||
|
else
|
||||||
|
debug_return_bool(false);
|
||||||
|
|
||||||
|
debug_return_bool(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* syslog callbacks */
|
||||||
|
static bool
|
||||||
|
cb_syslog_maxlen(const char *str)
|
||||||
|
{
|
||||||
|
unsigned int maxlen;
|
||||||
|
const char *errstr;
|
||||||
|
debug_decl(cb_syslog_maxlen, SUDO_DEBUG_UTIL)
|
||||||
|
|
||||||
|
maxlen = sudo_strtonum(str, 1, UINT_MAX, &errstr);
|
||||||
|
if (errstr != NULL)
|
||||||
|
debug_return_bool(false);
|
||||||
|
|
||||||
|
logsrvd_config.syslog.maxlen = maxlen;
|
||||||
|
|
||||||
|
debug_return_bool(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
cb_syslog_facility(const char *str)
|
||||||
|
{
|
||||||
|
int logfac;
|
||||||
|
debug_decl(cb_syslog_facility, SUDO_DEBUG_UTIL)
|
||||||
|
|
||||||
|
if (!sudo_str2logfac(str, &logfac)) {
|
||||||
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
|
"invalid syslog priority %s", str);
|
||||||
|
debug_return_bool(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
logsrvd_config.syslog.facility = logfac;
|
||||||
|
|
||||||
|
debug_return_bool(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
cb_syslog_acceptpri(const char *str)
|
||||||
|
{
|
||||||
|
int logpri;
|
||||||
|
debug_decl(cb_syslog_acceptpri, SUDO_DEBUG_UTIL)
|
||||||
|
|
||||||
|
if (!sudo_str2logpri(str, &logpri)) {
|
||||||
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
|
"invalid syslog priority %s", str);
|
||||||
|
debug_return_bool(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
logsrvd_config.syslog.acceptpri = logpri;
|
||||||
|
|
||||||
|
debug_return_bool(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
cb_syslog_rejectpri(const char *str)
|
||||||
|
{
|
||||||
|
int logpri;
|
||||||
|
debug_decl(cb_syslog_rejectpri, SUDO_DEBUG_UTIL)
|
||||||
|
|
||||||
|
if (!sudo_str2logpri(str, &logpri))
|
||||||
|
debug_return_bool(false);
|
||||||
|
|
||||||
|
logsrvd_config.syslog.rejectpri = logpri;
|
||||||
|
|
||||||
|
debug_return_bool(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
cb_syslog_alertpri(const char *str)
|
||||||
|
{
|
||||||
|
int logpri;
|
||||||
|
debug_decl(cb_syslog_alertpri, SUDO_DEBUG_UTIL)
|
||||||
|
|
||||||
|
if (!sudo_str2logpri(str, &logpri)) {
|
||||||
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
|
"invalid syslog priority %s", str);
|
||||||
|
debug_return_bool(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
logsrvd_config.syslog.alertpri = logpri;
|
||||||
|
|
||||||
|
debug_return_bool(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* logfile callbacks */
|
||||||
|
static bool
|
||||||
|
cb_logfile_path(const char *str)
|
||||||
|
{
|
||||||
|
char *copy = NULL;
|
||||||
|
debug_decl(cb_logfile_path, SUDO_DEBUG_UTIL)
|
||||||
|
|
||||||
|
if (*str != '/') {
|
||||||
|
debug_return_bool(false);
|
||||||
|
sudo_warnx(U_("%s: not a fully qualified path"), str);
|
||||||
|
debug_return_bool(false);
|
||||||
|
}
|
||||||
|
if ((copy = strdup(str)) == NULL) {
|
||||||
|
sudo_warn(NULL);
|
||||||
|
debug_return_bool(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(logsrvd_config.logfile.path);
|
||||||
|
logsrvd_config.logfile.path = copy;
|
||||||
|
|
||||||
|
debug_return_bool(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
cb_logfile_time_format(const char *str)
|
||||||
|
{
|
||||||
|
char *copy = NULL;
|
||||||
|
debug_decl(cb_logfile_time_format, SUDO_DEBUG_UTIL)
|
||||||
|
|
||||||
|
if ((copy = strdup(str)) == NULL) {
|
||||||
|
sudo_warn(NULL);
|
||||||
|
debug_return_bool(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(logsrvd_config.logfile.time_format);
|
||||||
|
logsrvd_config.logfile.time_format = copy;
|
||||||
|
|
||||||
|
debug_return_bool(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct logsrvd_config_entry server_conf_entries[] = {
|
static struct logsrvd_config_entry server_conf_entries[] = {
|
||||||
@@ -286,13 +528,37 @@ static struct logsrvd_config_entry iolog_conf_entries[] = {
|
|||||||
{ "iolog_user", cb_iolog_user },
|
{ "iolog_user", cb_iolog_user },
|
||||||
{ "iolog_group", cb_iolog_group },
|
{ "iolog_group", cb_iolog_group },
|
||||||
{ "iolog_mode", cb_iolog_mode },
|
{ "iolog_mode", cb_iolog_mode },
|
||||||
{ "maxseq", cb_maxseq },
|
{ "maxseq", cb_iolog_maxseq },
|
||||||
|
{ NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct logsrvd_config_entry eventlog_conf_entries[] = {
|
||||||
|
{ "log_type", cb_eventlog_type },
|
||||||
|
{ "log_format", cb_eventlog_format },
|
||||||
|
{ NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct logsrvd_config_entry syslog_conf_entries[] = {
|
||||||
|
{ "maxlen", cb_syslog_maxlen },
|
||||||
|
{ "facility", cb_syslog_facility },
|
||||||
|
{ "reject_priority", cb_syslog_rejectpri },
|
||||||
|
{ "accept_priority", cb_syslog_acceptpri },
|
||||||
|
{ "alert_priority", cb_syslog_alertpri },
|
||||||
|
{ NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct logsrvd_config_entry logfile_conf_entries[] = {
|
||||||
|
{ "path", cb_logfile_path },
|
||||||
|
{ "time_format", cb_logfile_time_format },
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct logsrvd_config_section logsrvd_config_sections[] = {
|
static struct logsrvd_config_section logsrvd_config_sections[] = {
|
||||||
{ "server", server_conf_entries },
|
{ "server", server_conf_entries },
|
||||||
{ "iolog", iolog_conf_entries },
|
{ "iolog", iolog_conf_entries },
|
||||||
|
{ "eventlog", eventlog_conf_entries },
|
||||||
|
{ "syslog", syslog_conf_entries },
|
||||||
|
{ "logfile", logfile_conf_entries },
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -300,7 +566,7 @@ static struct logsrvd_config_section logsrvd_config_sections[] = {
|
|||||||
* Read .ini style logsrvd.conf file.
|
* Read .ini style logsrvd.conf file.
|
||||||
* Note that we use '#' not ';' for the comment character.
|
* Note that we use '#' not ';' for the comment character.
|
||||||
*/
|
*/
|
||||||
/* XXX - on reload we should preserve old config if there is an error */
|
/* XXX - split into read and apply so we don't overwrite good config with bad */
|
||||||
bool
|
bool
|
||||||
logsrvd_conf_read(const char *path)
|
logsrvd_conf_read(const char *path)
|
||||||
{
|
{
|
||||||
@@ -318,7 +584,27 @@ logsrvd_conf_read(const char *path)
|
|||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Initialize default values for settings that take int values. */
|
||||||
logsrvd_conf_reset();
|
logsrvd_conf_reset();
|
||||||
|
logsrvd_config.eventlog.log_type = EVLOG_SYSLOG;
|
||||||
|
logsrvd_config.eventlog.log_format = EVLOG_SUDO;
|
||||||
|
logsrvd_config.syslog.maxlen = 960;
|
||||||
|
if (!cb_syslog_facility(LOGFAC)) {
|
||||||
|
sudo_warnx(U_("unknown syslog facility %s"), LOGFAC);
|
||||||
|
debug_return_bool(false);
|
||||||
|
}
|
||||||
|
if (!cb_syslog_acceptpri(PRI_SUCCESS)) {
|
||||||
|
sudo_warnx(U_("unknown syslog priority %s"), PRI_SUCCESS);
|
||||||
|
debug_return_bool(false);
|
||||||
|
}
|
||||||
|
if (!cb_syslog_rejectpri(PRI_FAILURE)) {
|
||||||
|
sudo_warnx(U_("unknown syslog priority %s"), PRI_FAILURE);
|
||||||
|
debug_return_bool(false);
|
||||||
|
}
|
||||||
|
if (!cb_syslog_alertpri(PRI_FAILURE)) {
|
||||||
|
sudo_warnx(U_("unknown syslog priority %s"), PRI_FAILURE);
|
||||||
|
debug_return_bool(false);
|
||||||
|
}
|
||||||
|
|
||||||
while (sudo_parseln(&line, &linesize, &lineno, fp, 0) != -1) {
|
while (sudo_parseln(&line, &linesize, &lineno, fp, 0) != -1) {
|
||||||
struct logsrvd_config_entry *entry;
|
struct logsrvd_config_entry *entry;
|
||||||
@@ -386,23 +672,27 @@ logsrvd_conf_read(const char *path)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* All the others have default values. */
|
/* For settings with pointer values we can tell what is unset. */
|
||||||
if (logsrvd_iolog_dir == NULL) {
|
if (logsrvd_config.iolog.iolog_dir == NULL) {
|
||||||
if ((logsrvd_iolog_dir = strdup(_PATH_SUDO_IO_LOGDIR)) == NULL) {
|
if (!cb_iolog_dir(_PATH_SUDO_IO_LOGDIR))
|
||||||
sudo_warn(NULL);
|
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (logsrvd_iolog_file == NULL) {
|
if (logsrvd_config.iolog.iolog_file == NULL) {
|
||||||
if ((logsrvd_iolog_file = strdup("%{seq}")) == NULL) {
|
if (!cb_iolog_file("%{seq}"))
|
||||||
sudo_warn(NULL);
|
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (TAILQ_EMPTY(&addresses)) {
|
if (TAILQ_EMPTY(&logsrvd_config.server.addresses)) {
|
||||||
if (!cb_listen_address("*:30344"))
|
if (!cb_listen_address("*:30344"))
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
}
|
}
|
||||||
|
if (logsrvd_config.logfile.time_format == NULL) {
|
||||||
|
if (!cb_logfile_time_format("%h %e %T"))
|
||||||
|
debug_return_bool(false);
|
||||||
|
}
|
||||||
|
if (logsrvd_config.logfile.path == NULL) {
|
||||||
|
if (!cb_logfile_path(_PATH_SUDO_LOGFILE))
|
||||||
|
debug_return_bool(false);
|
||||||
|
}
|
||||||
|
|
||||||
debug_return_bool(true);
|
debug_return_bool(true);
|
||||||
}
|
}
|
||||||
|
@@ -46,45 +46,6 @@
|
|||||||
#include "sudoers.h"
|
#include "sudoers.h"
|
||||||
#include <gram.h>
|
#include <gram.h>
|
||||||
|
|
||||||
/*
|
|
||||||
* For converting between syslog numbers and strings.
|
|
||||||
*/
|
|
||||||
struct strmap {
|
|
||||||
char *name;
|
|
||||||
int num;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct strmap facilities[] = {
|
|
||||||
#ifdef LOG_AUTHPRIV
|
|
||||||
{ "authpriv", LOG_AUTHPRIV },
|
|
||||||
#endif
|
|
||||||
{ "auth", LOG_AUTH },
|
|
||||||
{ "daemon", LOG_DAEMON },
|
|
||||||
{ "user", LOG_USER },
|
|
||||||
{ "local0", LOG_LOCAL0 },
|
|
||||||
{ "local1", LOG_LOCAL1 },
|
|
||||||
{ "local2", LOG_LOCAL2 },
|
|
||||||
{ "local3", LOG_LOCAL3 },
|
|
||||||
{ "local4", LOG_LOCAL4 },
|
|
||||||
{ "local5", LOG_LOCAL5 },
|
|
||||||
{ "local6", LOG_LOCAL6 },
|
|
||||||
{ "local7", LOG_LOCAL7 },
|
|
||||||
{ NULL, -1 }
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct strmap priorities[] = {
|
|
||||||
{ "alert", LOG_ALERT },
|
|
||||||
{ "crit", LOG_CRIT },
|
|
||||||
{ "debug", LOG_DEBUG },
|
|
||||||
{ "emerg", LOG_EMERG },
|
|
||||||
{ "err", LOG_ERR },
|
|
||||||
{ "info", LOG_INFO },
|
|
||||||
{ "notice", LOG_NOTICE },
|
|
||||||
{ "warning", LOG_WARNING },
|
|
||||||
{ "none", -1 },
|
|
||||||
{ NULL, -1 }
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct early_default early_defaults[] = {
|
static struct early_default early_defaults[] = {
|
||||||
{ I_IGNORE_UNKNOWN_DEFAULTS },
|
{ I_IGNORE_UNKNOWN_DEFAULTS },
|
||||||
#ifdef FQDN
|
#ifdef FQDN
|
||||||
@@ -113,8 +74,6 @@ static bool store_tuple(const char *str, union sudo_defs_val *sd_un, struct def_
|
|||||||
static bool store_uint(const char *str, union sudo_defs_val *sd_un);
|
static bool store_uint(const char *str, union sudo_defs_val *sd_un);
|
||||||
static bool store_timespec(const char *str, union sudo_defs_val *sd_un);
|
static bool store_timespec(const char *str, union sudo_defs_val *sd_un);
|
||||||
static bool list_op(const char *str, size_t, union sudo_defs_val *sd_un, enum list_ops op);
|
static bool list_op(const char *str, size_t, union sudo_defs_val *sd_un, enum list_ops op);
|
||||||
static const char *logfac2str(int);
|
|
||||||
static const char *logpri2str(int);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Table describing compile-time and run-time options.
|
* Table describing compile-time and run-time options.
|
||||||
@@ -150,14 +109,14 @@ dump_defaults(void)
|
|||||||
case T_LOGFAC:
|
case T_LOGFAC:
|
||||||
if (cur->sd_un.ival) {
|
if (cur->sd_un.ival) {
|
||||||
sudo_printf(SUDO_CONV_INFO_MSG, desc,
|
sudo_printf(SUDO_CONV_INFO_MSG, desc,
|
||||||
logfac2str(cur->sd_un.ival));
|
sudo_logfac2str(cur->sd_un.ival));
|
||||||
sudo_printf(SUDO_CONV_INFO_MSG, "\n");
|
sudo_printf(SUDO_CONV_INFO_MSG, "\n");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case T_LOGPRI:
|
case T_LOGPRI:
|
||||||
if (cur->sd_un.ival) {
|
if (cur->sd_un.ival) {
|
||||||
sudo_printf(SUDO_CONV_INFO_MSG, desc,
|
sudo_printf(SUDO_CONV_INFO_MSG, desc,
|
||||||
logpri2str(cur->sd_un.ival));
|
sudo_logpri2str(cur->sd_un.ival));
|
||||||
sudo_printf(SUDO_CONV_INFO_MSG, "\n");
|
sudo_printf(SUDO_CONV_INFO_MSG, "\n");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -990,63 +949,25 @@ store_list(const char *str, union sudo_defs_val *sd_un, int op)
|
|||||||
static bool
|
static bool
|
||||||
store_syslogfac(const char *str, union sudo_defs_val *sd_un)
|
store_syslogfac(const char *str, union sudo_defs_val *sd_un)
|
||||||
{
|
{
|
||||||
struct strmap *fac;
|
|
||||||
debug_decl(store_syslogfac, SUDOERS_DEBUG_DEFAULTS)
|
debug_decl(store_syslogfac, SUDOERS_DEBUG_DEFAULTS)
|
||||||
|
|
||||||
if (str == NULL) {
|
if (str == NULL) {
|
||||||
sd_un->ival = false;
|
sd_un->ival = false;
|
||||||
debug_return_bool(true);
|
debug_return_bool(true);
|
||||||
}
|
}
|
||||||
for (fac = facilities; fac->name != NULL; fac++) {
|
debug_return_bool(sudo_str2logfac(str, &sd_un->ival));
|
||||||
if (strcmp(str, fac->name) == 0) {
|
|
||||||
sd_un->ival = fac->num;
|
|
||||||
debug_return_bool(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
debug_return_bool(false); /* not found */
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char *
|
|
||||||
logfac2str(int n)
|
|
||||||
{
|
|
||||||
struct strmap *fac;
|
|
||||||
debug_decl(logfac2str, SUDOERS_DEBUG_DEFAULTS)
|
|
||||||
|
|
||||||
for (fac = facilities; fac->name && fac->num != n; fac++)
|
|
||||||
continue;
|
|
||||||
debug_return_const_str(fac->name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
store_syslogpri(const char *str, union sudo_defs_val *sd_un)
|
store_syslogpri(const char *str, union sudo_defs_val *sd_un)
|
||||||
{
|
{
|
||||||
struct strmap *pri;
|
|
||||||
debug_decl(store_syslogpri, SUDOERS_DEBUG_DEFAULTS)
|
debug_decl(store_syslogpri, SUDOERS_DEBUG_DEFAULTS)
|
||||||
|
|
||||||
if (str == NULL) {
|
if (str == NULL) {
|
||||||
sd_un->ival = -1;
|
sd_un->ival = -1;
|
||||||
debug_return_bool(true);
|
debug_return_bool(true);
|
||||||
}
|
}
|
||||||
for (pri = priorities; pri->name != NULL; pri++) {
|
debug_return_bool(sudo_str2logpri(str, &sd_un->ival));
|
||||||
if (strcmp(str, pri->name) == 0) {
|
|
||||||
sd_un->ival = pri->num;
|
|
||||||
debug_return_bool(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
debug_return_bool(false); /* not found */
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char *
|
|
||||||
logpri2str(int n)
|
|
||||||
{
|
|
||||||
struct strmap *pri;
|
|
||||||
debug_decl(logpri2str, SUDOERS_DEBUG_DEFAULTS)
|
|
||||||
|
|
||||||
for (pri = priorities; pri->name != NULL; pri++) {
|
|
||||||
if (pri->num == n)
|
|
||||||
debug_return_const_str(pri->name);
|
|
||||||
}
|
|
||||||
debug_return_const_str("unknown");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
Reference in New Issue
Block a user