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().
This commit is contained 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.
|
||||
|
@@ -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.
|
||||
|
@@ -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.
|
||||
|
@@ -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)
|
||||
{
|
||||
|
@@ -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);
|
||||
|
@@ -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)
|
||||
@@ -806,6 +848,23 @@ cb_syslog_maxlen(struct logsrvd_config *config, const char *str, size_t offset)
|
||||
debug_return_bool(true);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -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);
|
||||
}
|
||||
@@ -1127,6 +1185,21 @@ logsrvd_open_eventlog(struct logsrvd_config *config)
|
||||
debug_return_ptr(fp);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -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:
|
||||
|
Reference in New Issue
Block a user