summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd C. Miller <Todd.Miller@sudo.ws>2021-06-13 18:27:36 -0600
committerTodd C. Miller <Todd.Miller@sudo.ws>2021-06-13 18:27:36 -0600
commit344e9d691e7b29f2b104bce868d86439f74d6bbf (patch)
treeb866a5f3e54b381dcb17df63aeb6d712770a9c6e
parent2f3f3774a5269644b90effe3a36ec13c2ae7c150 (diff)
downloadsudo-344e9d691e7b29f2b104bce868d86439f74d6bbf.tar.gz
Add support for logging server warning/error messages.
We can use sudo_warn_set_conversation() to set a conversation function that either writes to a log file or calls syslog().
-rw-r--r--doc/sudo_logsrvd.conf.man.in32
-rw-r--r--doc/sudo_logsrvd.conf.mdoc.in30
-rw-r--r--examples/sudo_logsrvd.conf7
-rw-r--r--logsrvd/logsrvd.c39
-rw-r--r--logsrvd/logsrvd.h1
-rw-r--r--logsrvd/logsrvd_conf.c294
6 files changed, 381 insertions, 22 deletions
diff --git a/doc/sudo_logsrvd.conf.man.in b/doc/sudo_logsrvd.conf.man.in
index ea21f10af..fcd4aa7f3 100644
--- a/doc/sudo_logsrvd.conf.man.in
+++ b/doc/sudo_logsrvd.conf.man.in
@@ -16,7 +16,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.TH "SUDO_LOGSRVD.CONF" "@mansectform@" "May 1, 2021" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
+.TH "SUDO_LOGSRVD.CONF" "@mansectform@" "June 13, 2021" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
.nh
.if n .ad l
.SH "NAME"
@@ -128,6 +128,23 @@ Multiple
lines may be specified to listen on more than one port or interface.
.RE
.TP 10n
+server_log = string
+Where to log server warning and error messages.
+Supported values are
+\fInone\fR,
+\fIstderr\fR,
+\fIsyslog\fR,
+or a path name beginning with the
+\(oq/\(cq
+character.
+Note that a value of
+\fIstderr\fR
+is only effective when used in conjunction with the
+\fB\-n\fR
+option.
+The default value is
+\fIsyslog\fR.
+.TP 10n
pid_file = path
The path to the file containing the process ID of the running
\fBsudo_logsrvd\fR.
@@ -704,6 +721,12 @@ When a message is split, additional parts will include the string
after the user name and before the continued command line arguments.
JSON-format log entries are never split and are not affected by
\fImaxlen\fR.
+.TP 6n
+server_facility = string
+Syslog facility if syslog is being used for server warning messages.
+See above for a list of supported facilities.
+Defaults to
+\fRdaemon\fR
.SS "logfile"
The
\fIlogfile\fR
@@ -761,6 +784,9 @@ Sudo log server configuration file
# The file containing the ID of the running sudo_logsrvd process.
#pid_file = @rundir@/sudo_logsrvd.pid
+# Where to log server warnings: none, stderr, syslog, or a path name.
+#server_log = syslog
+
# If true, enable the SO_KEEPALIVE socket option on client connections.
#tcp_keepalive = true
@@ -955,6 +981,10 @@ Sudo log server configuration file
# client.
#alert_priority = alert
+# The syslog facility to use for server warning messages.
+# Defaults to daemon.
+#server_facility = daemon
+
[logfile]
# The path to the file-based event log.
# This path must be fully-qualified and start with a '/' character.
diff --git a/doc/sudo_logsrvd.conf.mdoc.in b/doc/sudo_logsrvd.conf.mdoc.in
index b8f1f6911..c8254ac1d 100644
--- a/doc/sudo_logsrvd.conf.mdoc.in
+++ b/doc/sudo_logsrvd.conf.mdoc.in
@@ -15,7 +15,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd May 1, 2021
+.Dd June 13, 2021
.Dt SUDO_LOGSRVD.CONF @mansectform@
.Os Sudo @PACKAGE_VERSION@
.Sh NAME
@@ -114,6 +114,22 @@ plaintext and TLS connections.
Multiple
.Em listen_address
lines may be specified to listen on more than one port or interface.
+.It server_log = string
+Where to log server warning and error messages.
+Supported values are
+.Em none ,
+.Em stderr ,
+.Em syslog ,
+or a path name beginning with the
+.Ql /
+character.
+Note that a value of
+.Em stderr
+is only effective when used in conjunction with the
+.Fl n
+option.
+The default value is
+.Em syslog .
.It pid_file = path
The path to the file containing the process ID of the running
.Nm sudo_logsrvd .
@@ -634,6 +650,11 @@ When a message is split, additional parts will include the string
after the user name and before the continued command line arguments.
JSON-format log entries are never split and are not affected by
.Em maxlen .
+.It server_facility = string
+Syslog facility if syslog is being used for server warning messages.
+See above for a list of supported facilities.
+Defaults to
+.Li daemon
.El
.Ss logfile
The
@@ -692,6 +713,9 @@ Sudo log server configuration file
# The file containing the ID of the running sudo_logsrvd process.
#pid_file = @rundir@/sudo_logsrvd.pid
+# Where to log server warnings: none, stderr, syslog, or a path name.
+#server_log = syslog
+
# If true, enable the SO_KEEPALIVE socket option on client connections.
#tcp_keepalive = true
@@ -886,6 +910,10 @@ Sudo log server configuration file
# client.
#alert_priority = alert
+# The syslog facility to use for server warning messages.
+# Defaults to daemon.
+#server_facility = daemon
+
[logfile]
# The path to the file-based event log.
# This path must be fully-qualified and start with a '/' character.
diff --git a/examples/sudo_logsrvd.conf b/examples/sudo_logsrvd.conf
index e73cd9998..2d42a6ab9 100644
--- a/examples/sudo_logsrvd.conf
+++ b/examples/sudo_logsrvd.conf
@@ -24,6 +24,9 @@
# The file containing the ID of the running sudo_logsrvd process.
#pid_file = /var/run/sudo/sudo_logsrvd.pid
+# Where to log server warnings: none, stderr, syslog, or a path name.
+#server_log = syslog
+
# If true, enable the SO_KEEPALIVE socket option on client connections.
#tcp_keepalive = true
@@ -219,6 +222,10 @@
# client.
#alert_priority = alert
+# The syslog facility to use for server warning messages.
+# Defaults to daemon.
+#server_facility = daemon
+
[logfile]
# The path to the file-based event log.
# This path must be fully-qualified and start with a '/' character.
diff --git a/logsrvd/logsrvd.c b/logsrvd/logsrvd.c
index a5d16730a..d019836e4 100644
--- a/logsrvd/logsrvd.c
+++ b/logsrvd/logsrvd.c
@@ -87,6 +87,7 @@ static struct connection_list connections = TAILQ_HEAD_INITIALIZER(connections);
static struct listener_list listeners = TAILQ_HEAD_INITIALIZER(listeners);
static const char server_id[] = "Sudo Audit Server " PACKAGE_VERSION;
static const char *conf_file = _PATH_SUDO_LOGSRVD_CONF;
+static bool is_early = true;
/* Event loop callbacks. */
static void client_msg_cb(int fd, int what, void *v);
@@ -1819,6 +1820,9 @@ daemonize(bool nofork)
int fd;
debug_decl(daemonize, SUDO_DEBUG_UTIL);
+ if (chdir("/") == -1)
+ sudo_warn("chdir(\"/\")");
+
if (!nofork) {
switch (sudo_debug_fork()) {
case -1:
@@ -1835,21 +1839,38 @@ daemonize(bool nofork)
if (setsid() == -1)
sudo_fatal("setsid");
write_pidfile();
- }
- if (chdir("/") == -1)
- sudo_warn("chdir(\"/\")");
- if ((fd = open(_PATH_DEVNULL, O_RDWR)) != -1) {
- (void) dup2(fd, STDIN_FILENO);
- (void) dup2(fd, STDOUT_FILENO);
- (void) dup2(fd, STDERR_FILENO);
- if (fd > STDERR_FILENO)
- (void) close(fd);
+ if ((fd = open(_PATH_DEVNULL, O_RDWR)) != -1) {
+ (void) dup2(fd, STDIN_FILENO);
+ (void) dup2(fd, STDOUT_FILENO);
+ (void) dup2(fd, STDERR_FILENO);
+ if (fd > STDERR_FILENO)
+ (void) close(fd);
+ }
+ } else {
+ if ((fd = open(_PATH_DEVNULL, O_RDWR)) != -1) {
+ /* Preserve stdout/stderr in nofork mode (if open). */
+ (void) dup2(fd, STDIN_FILENO);
+ if (fcntl(STDOUT_FILENO, F_GETFL) == -1)
+ (void) dup2(fd, STDOUT_FILENO);
+ if (fcntl(STDERR_FILENO, F_GETFL) == -1)
+ (void) dup2(fd, STDERR_FILENO);
+ if (fd > STDERR_FILENO)
+ (void) close(fd);
+ }
}
+ is_early = false;
debug_return;
}
+/* The early flag is used to decide whether sudo_warn() goes to stderr too. */
+bool
+logsrvd_is_early(void)
+{
+ return is_early;
+}
+
static void
usage(bool fatal)
{
diff --git a/logsrvd/logsrvd.h b/logsrvd/logsrvd.h
index 69bae730e..3d4575f4e 100644
--- a/logsrvd/logsrvd.h
+++ b/logsrvd/logsrvd.h
@@ -197,6 +197,7 @@ bool fmt_log_id_message(const char *id, struct connection_closure *closure);
bool schedule_error_message(const char *errstr, struct connection_closure *closure);
struct connection_buffer *get_free_buf(size_t, struct connection_closure *closure);
struct connection_closure *connection_closure_alloc(int fd, bool tls, bool relay_only, struct sudo_event_base *base);
+bool logsrvd_is_early(void);
/* logsrvd_conf.c */
bool logsrvd_conf_read(const char *path);
diff --git a/logsrvd/logsrvd_conf.c b/logsrvd/logsrvd_conf.c
index e380cd7ac..18d46b11f 100644
--- a/logsrvd/logsrvd_conf.c
+++ b/logsrvd/logsrvd_conf.c
@@ -78,6 +78,13 @@
((_c)->relay._f != -1 ? (_c)->relay._f : (_c)->server._f)
#endif
+enum server_log_type {
+ SERVER_LOG_NONE,
+ SERVER_LOG_STDERR,
+ SERVER_LOG_SYSLOG,
+ SERVER_LOG_FILE
+};
+
struct logsrvd_config;
typedef bool (*logsrvd_conf_cb_t)(struct logsrvd_config *, const char *, size_t);
@@ -102,6 +109,9 @@ static struct logsrvd_config {
struct address_list_container addresses;
struct timespec timeout;
bool tcp_keepalive;
+ enum server_log_type log_type;
+ FILE *log_stream;
+ char *log_file;
char *pid_file;
#if defined(HAVE_OPENSSL)
char *tls_key_path;
@@ -152,6 +162,7 @@ static struct logsrvd_config {
} eventlog;
struct logsrvd_config_syslog {
unsigned int maxlen;
+ int server_facility;
int facility;
int acceptpri;
int rejectpri;
@@ -560,6 +571,37 @@ cb_server_pid_file(struct logsrvd_config *config, const char *str, size_t offset
debug_return_bool(true);
}
+static bool
+cb_server_log(struct logsrvd_config *config, const char *str, size_t offset)
+{
+ char *copy = NULL;
+ enum server_log_type log_type = SERVER_LOG_NONE;
+ debug_decl(cb_server_log, SUDO_DEBUG_UTIL);
+
+ /* An empty value means to disable the server log. */
+ if (*str != '\0') {
+ if (*str != '/') {
+ log_type = SERVER_LOG_FILE;
+ if ((copy = strdup(str)) == NULL) {
+ sudo_warn(NULL);
+ debug_return_bool(false);
+ }
+ } else if (strcmp(str, "stderr") == 0) {
+ log_type = SERVER_LOG_STDERR;
+ } else if (strcmp(str, "syslog") == 0) {
+ log_type = SERVER_LOG_SYSLOG;
+ } else {
+ debug_return_bool(false);
+ }
+ }
+
+ free(config->server.log_file);
+ config->server.log_file = copy;
+ config->server.log_type = log_type;
+
+ debug_return_bool(true);
+}
+
#if defined(HAVE_OPENSSL)
static bool
cb_tls_key(struct logsrvd_config *config, const char *path, size_t offset)
@@ -807,6 +849,23 @@ cb_syslog_maxlen(struct logsrvd_config *config, const char *str, size_t offset)
}
static bool
+cb_syslog_server_facility(struct logsrvd_config *config, const char *str, size_t offset)
+{
+ int logfac;
+ debug_decl(cb_syslog_server_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);
+ }
+
+ config->syslog.server_facility = logfac;
+
+ debug_return_bool(true);
+}
+
+static bool
cb_syslog_facility(struct logsrvd_config *config, const char *str, size_t offset)
{
int logfac;
@@ -940,6 +999,7 @@ static struct logsrvd_config_entry server_conf_entries[] = {
{ "timeout", cb_server_timeout },
{ "tcp_keepalive", cb_server_keepalive },
{ "pid_file", cb_server_pid_file },
+ { "server_log", cb_server_log },
#if defined(HAVE_OPENSSL)
{ "tls_key", cb_tls_key, offsetof(struct logsrvd_config, server.tls_key_path) },
{ "tls_cacert", cb_tls_cacert, offsetof(struct logsrvd_config, server.tls_cacert_path) },
@@ -993,6 +1053,7 @@ static struct logsrvd_config_entry eventlog_conf_entries[] = {
static struct logsrvd_config_entry syslog_conf_entries[] = {
{ "maxlen", cb_syslog_maxlen },
+ { "server_facility", cb_syslog_server_facility },
{ "facility", cb_syslog_facility },
{ "reject_priority", cb_syslog_rejectpri },
{ "accept_priority", cb_syslog_acceptpri },
@@ -1098,28 +1159,25 @@ done:
}
static FILE *
-logsrvd_open_eventlog(struct logsrvd_config *config)
+logsrvd_open_log_file(const char *path, int flags)
{
mode_t oldmask;
FILE *fp = NULL;
const char *omode;
- int fd, flags;
- debug_decl(logsrvd_open_eventlog, SUDO_DEBUG_UTIL);
+ int fd;
+ debug_decl(logsrvd_open_log_file, SUDO_DEBUG_UTIL);
- /* Cannot append to a JSON file. */
- if (config->eventlog.log_format == EVLOG_JSON) {
- flags = O_RDWR|O_CREAT;
- omode = "w";
- } else {
- flags = O_WRONLY|O_APPEND|O_CREAT;
+ if (ISSET(flags, O_APPEND)) {
omode = "a";
+ } else {
+ omode = "w";
}
oldmask = umask(S_IRWXG|S_IRWXO);
- fd = open(config->logfile.path, flags, S_IRUSR|S_IWUSR);
+ fd = open(path, flags, S_IRUSR|S_IWUSR);
(void)umask(oldmask);
if (fd == -1 || (fp = fdopen(fd, omode)) == NULL) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
- "unable to open log file %s", config->logfile.path);
+ "unable to open log file %s", path);
if (fd != -1)
close(fd);
}
@@ -1128,6 +1186,21 @@ logsrvd_open_eventlog(struct logsrvd_config *config)
}
static FILE *
+logsrvd_open_eventlog(struct logsrvd_config *config)
+{
+ int flags;
+ debug_decl(logsrvd_open_eventlog, SUDO_DEBUG_UTIL);
+
+ /* Cannot append to a JSON file. */
+ if (config->eventlog.log_format == EVLOG_JSON) {
+ flags = O_RDWR|O_CREAT;
+ } else {
+ flags = O_WRONLY|O_APPEND|O_CREAT;
+ }
+ debug_return_ptr(logsrvd_open_log_file(config->logfile.path, flags));
+}
+
+static FILE *
logsrvd_stub_open_log(int type, const char *logfile)
{
/* Actual open already done by logsrvd_open_eventlog() */
@@ -1160,6 +1233,175 @@ logsrvd_conf_eventlog_setconf(struct logsrvd_config *config)
debug_return;
}
+/*
+ * Conversation function for use by sudo_warn/sudo_fatal.
+ * Logs to stdout/stderr.
+ */
+static int
+logsrvd_conv_stderr(int num_msgs, const struct sudo_conv_message msgs[],
+ struct sudo_conv_reply replies[], struct sudo_conv_callback *callback)
+{
+ int i;
+ debug_decl(logsrvd_conv_stderr, SUDO_DEBUG_UTIL);
+
+ for (i = 0; i < num_msgs; i++) {
+ if (fputs(msgs[i].msg, stderr) == EOF)
+ debug_return_int(-1);
+ }
+
+ debug_return_int(0);
+}
+
+/*
+ * Conversation function for use by sudo_warn/sudo_fatal.
+ * Acts as a no-op log sink.
+ */
+static int
+logsrvd_conv_none(int num_msgs, const struct sudo_conv_message msgs[],
+ struct sudo_conv_reply replies[], struct sudo_conv_callback *callback)
+{
+ /* Also write to stderr if still in the foreground. */
+ if (logsrvd_is_early()) {
+ (void)logsrvd_conv_stderr(num_msgs, msgs, replies, callback);
+ }
+
+ return 0;
+}
+
+/*
+ * Conversation function for use by sudo_warn/sudo_fatal.
+ * Logs to syslog.
+ */
+static int
+logsrvd_conv_syslog(int num_msgs, const struct sudo_conv_message msgs[],
+ struct sudo_conv_reply replies[], struct sudo_conv_callback *callback)
+{
+ char *buf = NULL, *cp = NULL;
+ const char *progname;
+ size_t proglen, bufsize = 0;
+ int i;
+ debug_decl(logsrvd_conv_syslog, SUDO_DEBUG_UTIL);
+
+ /* Also write to stderr if still in the foreground. */
+ if (logsrvd_is_early()) {
+ (void)logsrvd_conv_stderr(num_msgs, msgs, replies, callback);
+ }
+
+ /*
+ * Concat messages into a flag string that we can syslog.
+ */
+ progname = getprogname();
+ proglen = strlen(progname);
+ for (i = 0; i < num_msgs; i++) {
+ const char *msg = msgs[i].msg;
+ size_t len = strlen(msg);
+ size_t used = (size_t)(cp - buf);
+
+ /* Strip leading "sudo_logsrvd: " prefix. */
+ if (strncmp(msg, progname, proglen) == 0) {
+ msg += proglen;
+ len -= proglen;
+ if (len == 0) {
+ /* Skip over ": " string that follows program name. */
+ if (i + 1 < num_msgs && strcmp(msgs[i + 1].msg, ": ") == 0) {
+ i++;
+ continue;
+ }
+ } else if (msg[0] == ':' && msg[1] == ' ') {
+ /* Handle "progname: " */
+ msg += 2;
+ len -= 2;
+ }
+ }
+
+ /* Strip off trailing newlines. */
+ while (len > 1 && msgs[i].msg[len - 1] == '\n')
+ len--;
+ if (len == 0)
+ continue;
+
+ if (len >= bufsize - used) {
+ bufsize += 1024;
+ char *tmp = realloc(buf, bufsize);
+ if (tmp == NULL) {
+ free(buf);
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "unable to allocate memory");
+ debug_return_int(-1);
+ }
+ buf = tmp;
+ cp = tmp + used;
+ }
+ memcpy(cp, msgs[i].msg, len);
+ cp[len] = '\0';
+ cp += len;
+ }
+ if (buf != NULL) {
+ openlog(progname, 0, logsrvd_config->syslog.server_facility);
+ syslog(LOG_ERR, "%s", buf);
+ free(buf);
+
+ /* Restore old syslog settings. */
+ if (logsrvd_config->eventlog.log_type == EVLOG_SYSLOG)
+ openlog("sudo", 0, logsrvd_config->syslog.facility);
+ }
+
+ debug_return_int(0);
+}
+
+/*
+ * Conversation function for use by sudo_warn/sudo_fatal.
+ * Logs to an already-open log file.
+ */
+static int
+logsrvd_conv_logfile(int num_msgs, const struct sudo_conv_message msgs[],
+ struct sudo_conv_reply replies[], struct sudo_conv_callback *callback)
+{
+ const char *progname;
+ size_t proglen;
+ int i;
+ debug_decl(logsrvd_conv_logfile, SUDO_DEBUG_UTIL);
+
+ /* Also write to stderr if still in the foreground. */
+ if (logsrvd_is_early()) {
+ (void)logsrvd_conv_stderr(num_msgs, msgs, replies, callback);
+ }
+
+ if (logsrvd_config->server.log_stream == NULL) {
+ errno = EBADF;
+ debug_return_int(-1);
+ }
+
+ progname = getprogname();
+ proglen = strlen(progname);
+ for (i = 0; i < num_msgs; i++) {
+ const char *msg = msgs[i].msg;
+ size_t len = strlen(msg);
+
+ /* Strip leading "sudo_logsrvd: " prefix. */
+ if (strncmp(msg, progname, proglen) == 0) {
+ msg += proglen;
+ len -= proglen;
+ if (len == 0) {
+ /* Skip over ": " string that follows program name. */
+ if (i + 1 < num_msgs && strcmp(msgs[i + 1].msg, ": ") == 0) {
+ i++;
+ continue;
+ }
+ } else if (msg[0] == ':' && msg[1] == ' ') {
+ /* Handle "progname: " */
+ msg += 2;
+ len -= 2;
+ }
+ }
+
+ if (fwrite(msgs[i].msg, len, 1, logsrvd_config->server.log_stream) != 1)
+ debug_return_int(-1);
+ }
+
+ debug_return_int(0);
+}
+
/* Free the specified struct logsrvd_config and its contents. */
static void
logsrvd_conf_free(struct logsrvd_config *config)
@@ -1172,6 +1414,9 @@ logsrvd_conf_free(struct logsrvd_config *config)
/* struct logsrvd_config_server */
address_list_delref(&config->server.addresses.addrs);
free(config->server.pid_file);
+ free(config->server.log_file);
+ if (config->server.log_stream != NULL)
+ fclose(config->server.log_stream);
#if defined(HAVE_OPENSSL)
free(config->server.tls_key_path);
free(config->server.tls_cert_path);
@@ -1245,6 +1490,7 @@ logsrvd_conf_alloc(void)
config->server.addresses.refcnt = 1;
config->server.timeout.tv_sec = DEFAULT_SOCKET_TIMEOUT_SEC;
config->server.tcp_keepalive = true;
+ config->server.log_type = SERVER_LOG_SYSLOG;
config->server.pid_file = strdup(_PATH_SUDO_LOGSRVD_PID);
if (config->server.pid_file == NULL) {
sudo_warn(NULL);
@@ -1298,6 +1544,7 @@ logsrvd_conf_alloc(void)
/* Syslog defaults */
config->syslog.maxlen = 960;
+ config->syslog.server_facility = LOG_DAEMON;
if (!cb_syslog_facility(config, LOGFAC, 0)) {
sudo_warnx(U_("unknown syslog facility %s"), LOGFAC);
goto bad;
@@ -1411,6 +1658,31 @@ logsrvd_conf_apply(struct logsrvd_config *config)
if (TAILQ_EMPTY(&config->relay.relays.addrs))
config->relay.store_first = false;
+ /* Open server log if specified. */
+ switch (config->server.log_type) {
+ case SERVER_LOG_SYSLOG:
+ sudo_warn_set_conversation(logsrvd_conv_syslog);
+ break;
+ case SERVER_LOG_FILE:
+ config->server.log_stream =
+ logsrvd_open_log_file(config->server.log_file, O_WRONLY|O_APPEND|O_CREAT);
+ if (config->server.log_stream == NULL)
+ debug_return_bool(false);
+ sudo_warn_set_conversation(logsrvd_conv_logfile);
+ break;
+ case SERVER_LOG_NONE:
+ sudo_warn_set_conversation(logsrvd_conv_none);
+ break;
+ case SERVER_LOG_STDERR:
+ /* Default is stderr. */
+ sudo_warn_set_conversation(NULL);
+ break;
+ default:
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "cannot open unknown log type %d", config->eventlog.log_type);
+ break;
+ }
+
/* Open event log if specified. */
switch (config->eventlog.log_type) {
case EVLOG_SYSLOG: