Compare commits
No commits in common. "c8" and "c9-beta" have entirely different histories.
@ -1,79 +0,0 @@
|
|||||||
From ecaa9cd08d25870ec89fec82cf17c6cdaa4c7912 Mon Sep 17 00:00:00 2001
|
|
||||||
From: "Todd C. Miller" <Todd.Miller@sudo.ws>
|
|
||||||
Date: Sat, 6 Feb 2021 08:36:01 -0700
|
|
||||||
Subject: [PATCH] Add libsudo_eventlog.la as a dependency of libsudo_iolog.la
|
|
||||||
No longer need to link against libsudo_eventlog.la in sudoers.
|
|
||||||
|
|
||||||
---
|
|
||||||
lib/iolog/Makefile.in | 7 ++++---
|
|
||||||
plugins/sudoers/Makefile.in | 8 ++++----
|
|
||||||
2 files changed, 8 insertions(+), 7 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/lib/iolog/Makefile.in b/lib/iolog/Makefile.in
|
|
||||||
index 2ae9c1b42..8fbc76c98 100644
|
|
||||||
--- a/lib/iolog/Makefile.in
|
|
||||||
+++ b/lib/iolog/Makefile.in
|
|
||||||
@@ -1,7 +1,7 @@
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: ISC
|
|
||||||
#
|
|
||||||
-# Copyright (c) 2011-2020 Todd C. Miller <Todd.Miller@sudo.ws>
|
|
||||||
+# Copyright (c) 2011-2021 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
|
|
||||||
@@ -36,7 +36,8 @@ CC = @CC@
|
|
||||||
LIBTOOL = @LIBTOOL@
|
|
||||||
|
|
||||||
# Libraries
|
|
||||||
-LT_LIBS = $(top_builddir)/lib/util/libsudo_util.la
|
|
||||||
+LT_LIBS = $(top_builddir)/lib/eventlog/libsudo_eventlog.la \
|
|
||||||
+ $(top_builddir)/lib/util/libsudo_util.la
|
|
||||||
LIBS = @LIBS@ @ZLIB@ $(LT_LIBS)
|
|
||||||
|
|
||||||
# C preprocessor flags
|
|
||||||
@@ -76,7 +77,7 @@ PVS_LOG_OPTS = -a 'GA:1,2' -e -t errorfile -d $(PVS_IGNORE)
|
|
||||||
|
|
||||||
# Regression tests
|
|
||||||
TEST_PROGS = check_iolog_json check_iolog_mkpath check_iolog_path check_iolog_util host_port_test
|
|
||||||
-TEST_LIBS = @LIBS@ $(top_builddir)/lib/eventlog/libsudo_eventlog.la
|
|
||||||
+TEST_LIBS = @LIBS@
|
|
||||||
TEST_LDFLAGS = @LDFLAGS@
|
|
||||||
|
|
||||||
# Set to non-empty for development mode
|
|
||||||
diff --git a/plugins/sudoers/Makefile.in b/plugins/sudoers/Makefile.in
|
|
||||||
index 77d54553b..8eadf479d 100644
|
|
||||||
--- a/plugins/sudoers/Makefile.in
|
|
||||||
+++ b/plugins/sudoers/Makefile.in
|
|
||||||
@@ -1,7 +1,7 @@
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: ISC
|
|
||||||
#
|
|
||||||
-# Copyright (c) 1996, 1998-2005, 2007-2020
|
|
||||||
+# Copyright (c) 1996, 1998-2005, 2007-2021
|
|
||||||
# Todd C. Miller <Todd.Miller@sudo.ws>
|
|
||||||
#
|
|
||||||
# Permission to use, copy, modify, and distribute this software for any
|
|
||||||
@@ -61,8 +61,8 @@ LIBLOGSRV = @LIBLOGSRV@
|
|
||||||
LIBUTIL = $(top_builddir)/lib/util/libsudo_util.la
|
|
||||||
LIBS = $(LIBUTIL)
|
|
||||||
NET_LIBS = @NET_LIBS@
|
|
||||||
-SUDOERS_LIBS = @SUDOERS_LIBS@ @AFS_LIBS@ @GETGROUPS_LIB@ @LIBTLS@ $(NET_LIBS) $(LIBIOLOG) $(LIBEVENTLOG) $(LIBLOGSRV)
|
|
||||||
-REPLAY_LIBS = @REPLAY_LIBS@ $(LIBEVENTLOG) $(LIBIOLOG)
|
|
||||||
+SUDOERS_LIBS = @SUDOERS_LIBS@ @AFS_LIBS@ @GETGROUPS_LIB@ @LIBTLS@ $(NET_LIBS) $(LIBIOLOG) $(LIBLOGSRV)
|
|
||||||
+REPLAY_LIBS = @REPLAY_LIBS@ $(LIBIOLOG)
|
|
||||||
VISUDO_LIBS = $(NET_LIBS)
|
|
||||||
CVTSUDOERS_LIBS = $(NET_LIBS)
|
|
||||||
TESTSUDOERS_LIBS = $(NET_LIBS)
|
|
||||||
@@ -323,7 +323,7 @@ check_hexchar: $(CHECK_HEXCHAR_OBJS) $(LIBUTIL)
|
|
||||||
$(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(CHECK_HEXCHAR_OBJS) $(LDFLAGS) $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(LIBS)
|
|
||||||
|
|
||||||
check_iolog_plugin: $(CHECK_IOLOG_PLUGIN_OBJS) $(LIBUTIL) $(LIBIOLOG) $(LIBLOGSRV)
|
|
||||||
- $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(CHECK_IOLOG_PLUGIN_OBJS) $(LDFLAGS) $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(LIBIOLOG) $(LIBEVENTLOG) $(LIBLOGSRV) @LIBTLS@
|
|
||||||
+ $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(CHECK_IOLOG_PLUGIN_OBJS) $(LDFLAGS) $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(LIBIOLOG) $(LIBLOGSRV) @LIBTLS@
|
|
||||||
|
|
||||||
check_starttime: $(CHECK_STARTTIME_OBJS) $(LIBUTIL)
|
|
||||||
$(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(CHECK_STARTTIME_OBJS) $(LDFLAGS) $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(LIBS)
|
|
||||||
--
|
|
||||||
2.43.0
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
|||||||
From e5c1778e7dd32ff3ed8cf969540404c9c0e6d5a1 Mon Sep 17 00:00:00 2001
|
|
||||||
From: "Todd C. Miller" <Todd.Miller@sudo.ws>
|
|
||||||
Date: Thu, 18 Feb 2021 08:32:13 -0700
|
|
||||||
Subject: [PATCH] When logging JSON to syslog, wrap the contents in a "sudo"
|
|
||||||
object. This makes it easier for log parsers to identify what is a sudo log
|
|
||||||
entry.
|
|
||||||
|
|
||||||
---
|
|
||||||
lib/eventlog/eventlog.c | 4 ++--
|
|
||||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/lib/eventlog/eventlog.c b/lib/eventlog/eventlog.c
|
|
||||||
index 1f0183b1b..e6f744da5 100644
|
|
||||||
--- a/lib/eventlog/eventlog.c
|
|
||||||
+++ b/lib/eventlog/eventlog.c
|
|
||||||
@@ -950,10 +950,10 @@ do_syslog_json(int pri, int event_type, const char *reason,
|
|
||||||
if (json_str == NULL)
|
|
||||||
debug_return_bool(false);
|
|
||||||
|
|
||||||
- /* Syslog it with a @cee: prefix */
|
|
||||||
+ /* Syslog it in a sudo object with a @cee: prefix. */
|
|
||||||
/* TODO: use evl_conf.syslog_maxlen to break up long messages. */
|
|
||||||
evl_conf.open_log(EVLOG_SYSLOG, NULL);
|
|
||||||
- syslog(pri, "@cee:{%s}", json_str);
|
|
||||||
+ syslog(pri, "@cee:{\"sudo\":{%s}}", json_str);
|
|
||||||
evl_conf.close_log(EVLOG_SYSLOG, NULL);
|
|
||||||
free(json_str);
|
|
||||||
debug_return_bool(true);
|
|
||||||
--
|
|
||||||
2.43.0
|
|
||||||
|
|
@ -1,187 +0,0 @@
|
|||||||
From f399c449ad6fc7412588998aa92b52323ef63ee5 Mon Sep 17 00:00:00 2001
|
|
||||||
From: "Todd C. Miller" <Todd.Miller@sudo.ws>
|
|
||||||
Date: Wed, 24 Feb 2021 13:59:17 -0700
|
|
||||||
Subject: [PATCH] Move eventlog_free() into its own file.
|
|
||||||
|
|
||||||
---
|
|
||||||
MANIFEST | 1 +
|
|
||||||
lib/eventlog/Makefile.in | 14 ++++++-
|
|
||||||
lib/eventlog/eventlog.c | 37 ------------------
|
|
||||||
lib/eventlog/eventlog_free.c | 73 ++++++++++++++++++++++++++++++++++++
|
|
||||||
4 files changed, 87 insertions(+), 38 deletions(-)
|
|
||||||
create mode 100644 lib/eventlog/eventlog_free.c
|
|
||||||
|
|
||||||
diff --git a/MANIFEST b/MANIFEST
|
|
||||||
index 8c5a57ae8..a2bed131d 100644
|
|
||||||
--- a/MANIFEST
|
|
||||||
+++ b/MANIFEST
|
|
||||||
@@ -104,6 +104,7 @@ include/sudo_util.h
|
|
||||||
install-sh
|
|
||||||
lib/eventlog/Makefile.in
|
|
||||||
lib/eventlog/eventlog.c
|
|
||||||
+lib/eventlog/eventlog_free.c
|
|
||||||
lib/eventlog/logwrap.c
|
|
||||||
lib/eventlog/regress/logwrap/check_wrap.c
|
|
||||||
lib/eventlog/regress/logwrap/check_wrap.in
|
|
||||||
diff --git a/lib/eventlog/Makefile.in b/lib/eventlog/Makefile.in
|
|
||||||
index 8790ac1ae..24c2dbce9 100644
|
|
||||||
--- a/lib/eventlog/Makefile.in
|
|
||||||
+++ b/lib/eventlog/Makefile.in
|
|
||||||
@@ -82,7 +82,7 @@ SHELL = @SHELL@
|
|
||||||
|
|
||||||
TEST_PROGS = check_wrap
|
|
||||||
|
|
||||||
-LIBEVENTLOG_OBJS = eventlog.lo logwrap.lo
|
|
||||||
+LIBEVENTLOG_OBJS = eventlog.lo eventlog_free.lo logwrap.lo
|
|
||||||
|
|
||||||
IOBJS = $(LIBEVENTLOG_OBJS:.lo=.i)
|
|
||||||
|
|
||||||
@@ -213,6 +213,18 @@ eventlog.i: $(srcdir)/eventlog.c $(incdir)/compat/stdbool.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 $@
|
|
||||||
+eventlog_free.lo: $(srcdir)/eventlog_free.c $(incdir)/compat/stdbool.h \
|
|
||||||
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
|
|
||||||
+ $(incdir)/sudo_eventlog.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)/eventlog_free.c
|
|
||||||
+eventlog_free.i: $(srcdir)/eventlog_free.c $(incdir)/compat/stdbool.h \
|
|
||||||
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
|
|
||||||
+ $(incdir)/sudo_eventlog.h $(incdir)/sudo_queue.h \
|
|
||||||
+ $(incdir)/sudo_util.h $(top_builddir)/config.h
|
|
||||||
+ $(CC) -E -o $@ $(CPPFLAGS) $<
|
|
||||||
+eventlog_free.plog: eventlog_free.i
|
|
||||||
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/eventlog_free.c --i-file $< --output-file $@
|
|
||||||
logwrap.lo: $(srcdir)/logwrap.c $(incdir)/compat/stdbool.h \
|
|
||||||
$(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
|
|
||||||
$(incdir)/sudo_eventlog.h $(incdir)/sudo_queue.h \
|
|
||||||
diff --git a/lib/eventlog/eventlog.c b/lib/eventlog/eventlog.c
|
|
||||||
index e6f744da5..c8c9b7ba5 100644
|
|
||||||
--- a/lib/eventlog/eventlog.c
|
|
||||||
+++ b/lib/eventlog/eventlog.c
|
|
||||||
@@ -1256,43 +1256,6 @@ eventlog_alert(const struct eventlog *evlog, int flags,
|
|
||||||
debug_return_bool(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
-/*
|
|
||||||
- * Free the strings in a struct eventlog.
|
|
||||||
- */
|
|
||||||
-void
|
|
||||||
-eventlog_free(struct eventlog *evlog)
|
|
||||||
-{
|
|
||||||
- int i;
|
|
||||||
- debug_decl(eventlog_free, SUDO_DEBUG_UTIL);
|
|
||||||
-
|
|
||||||
- if (evlog != NULL) {
|
|
||||||
- free(evlog->iolog_path);
|
|
||||||
- free(evlog->command);
|
|
||||||
- free(evlog->cwd);
|
|
||||||
- free(evlog->runchroot);
|
|
||||||
- free(evlog->runcwd);
|
|
||||||
- free(evlog->rungroup);
|
|
||||||
- free(evlog->runuser);
|
|
||||||
- free(evlog->submithost);
|
|
||||||
- free(evlog->submituser);
|
|
||||||
- free(evlog->submitgroup);
|
|
||||||
- free(evlog->ttyname);
|
|
||||||
- if (evlog->argv != NULL) {
|
|
||||||
- for (i = 0; evlog->argv[i] != NULL; i++)
|
|
||||||
- free(evlog->argv[i]);
|
|
||||||
- free(evlog->argv);
|
|
||||||
- }
|
|
||||||
- if (evlog->envp != NULL) {
|
|
||||||
- for (i = 0; evlog->envp[i] != NULL; i++)
|
|
||||||
- free(evlog->envp[i]);
|
|
||||||
- free(evlog->envp);
|
|
||||||
- }
|
|
||||||
- free(evlog);
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- debug_return;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
static FILE *
|
|
||||||
eventlog_stub_open_log(int type, const char *logfile)
|
|
||||||
{
|
|
||||||
diff --git a/lib/eventlog/eventlog_free.c b/lib/eventlog/eventlog_free.c
|
|
||||||
new file mode 100644
|
|
||||||
index 000000000..49583b61c
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/lib/eventlog/eventlog_free.c
|
|
||||||
@@ -0,0 +1,73 @@
|
|
||||||
+/*
|
|
||||||
+ * SPDX-License-Identifier: ISC
|
|
||||||
+ *
|
|
||||||
+ * Copyright (c) 2020 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 <stdio.h>
|
|
||||||
+#include <stdlib.h>
|
|
||||||
+
|
|
||||||
+#include "sudo_compat.h"
|
|
||||||
+#include "sudo_debug.h"
|
|
||||||
+#include "sudo_eventlog.h"
|
|
||||||
+#include "sudo_util.h"
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * Free the strings in a struct eventlog.
|
|
||||||
+ */
|
|
||||||
+void
|
|
||||||
+eventlog_free(struct eventlog *evlog)
|
|
||||||
+{
|
|
||||||
+ int i;
|
|
||||||
+ debug_decl(eventlog_free, SUDO_DEBUG_UTIL);
|
|
||||||
+
|
|
||||||
+ if (evlog != NULL) {
|
|
||||||
+ free(evlog->iolog_path);
|
|
||||||
+ free(evlog->command);
|
|
||||||
+ free(evlog->cwd);
|
|
||||||
+ free(evlog->runchroot);
|
|
||||||
+ free(evlog->runcwd);
|
|
||||||
+ free(evlog->rungroup);
|
|
||||||
+ free(evlog->runuser);
|
|
||||||
+ free(evlog->submithost);
|
|
||||||
+ free(evlog->submituser);
|
|
||||||
+ free(evlog->submitgroup);
|
|
||||||
+ free(evlog->ttyname);
|
|
||||||
+ if (evlog->argv != NULL) {
|
|
||||||
+ for (i = 0; evlog->argv[i] != NULL; i++)
|
|
||||||
+ free(evlog->argv[i]);
|
|
||||||
+ free(evlog->argv);
|
|
||||||
+ }
|
|
||||||
+ if (evlog->envp != NULL) {
|
|
||||||
+ for (i = 0; evlog->envp[i] != NULL; i++)
|
|
||||||
+ free(evlog->envp[i]);
|
|
||||||
+ free(evlog->envp);
|
|
||||||
+ }
|
|
||||||
+ free(evlog);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ debug_return;
|
|
||||||
+}
|
|
||||||
--
|
|
||||||
2.43.0
|
|
||||||
|
|
@ -1,884 +0,0 @@
|
|||||||
From 412858272365f0e6d6f8873e794f64374da8fa06 Mon Sep 17 00:00:00 2001
|
|
||||||
From: "Todd C. Miller" <Todd.Miller@sudo.ws>
|
|
||||||
Date: Wed, 24 Feb 2021 14:25:39 -0700
|
|
||||||
Subject: [PATCH] Move eventlog config code into eventlog_conf.c
|
|
||||||
|
|
||||||
---
|
|
||||||
MANIFEST | 1 +
|
|
||||||
include/sudo_eventlog.h | 3 +-
|
|
||||||
lib/eventlog/Makefile.in | 20 ++-
|
|
||||||
lib/eventlog/eventlog.c | 292 +++++++----------------------------
|
|
||||||
lib/eventlog/eventlog_conf.c | 226 +++++++++++++++++++++++++++
|
|
||||||
5 files changed, 303 insertions(+), 239 deletions(-)
|
|
||||||
create mode 100644 lib/eventlog/eventlog_conf.c
|
|
||||||
|
|
||||||
diff --git a/MANIFEST b/MANIFEST
|
|
||||||
index a2bed131d..c960e3e8b 100644
|
|
||||||
--- a/MANIFEST
|
|
||||||
+++ b/MANIFEST
|
|
||||||
@@ -104,6 +104,7 @@ include/sudo_util.h
|
|
||||||
install-sh
|
|
||||||
lib/eventlog/Makefile.in
|
|
||||||
lib/eventlog/eventlog.c
|
|
||||||
+lib/eventlog/eventlog_conf.c
|
|
||||||
lib/eventlog/eventlog_free.c
|
|
||||||
lib/eventlog/logwrap.c
|
|
||||||
lib/eventlog/regress/logwrap/check_wrap.c
|
|
||||||
diff --git a/include/sudo_eventlog.h b/include/sudo_eventlog.h
|
|
||||||
index 127ee5dd8..e40622a51 100644
|
|
||||||
--- a/include/sudo_eventlog.h
|
|
||||||
+++ b/include/sudo_eventlog.h
|
|
||||||
@@ -66,7 +66,7 @@ enum eventlog_format {
|
|
||||||
#define EVENTLOG_INDENT " "
|
|
||||||
|
|
||||||
/*
|
|
||||||
- * Event log config, used with eventlog_setconf()
|
|
||||||
+ * Event log config, used with eventlog_getconf()
|
|
||||||
*/
|
|
||||||
struct eventlog_config {
|
|
||||||
int type;
|
|
||||||
@@ -144,5 +144,6 @@ void eventlog_set_mailto(const char *to_addr);
|
|
||||||
void eventlog_set_mailsub(const char *subject);
|
|
||||||
void eventlog_set_open_log(FILE *(*fn)(int type, const char *));
|
|
||||||
void eventlog_set_close_log(void (*fn)(int type, FILE *));
|
|
||||||
+const struct eventlog_config *eventlog_getconf(void);
|
|
||||||
|
|
||||||
#endif /* SUDO_EVENTLOG_H */
|
|
||||||
diff --git a/lib/eventlog/Makefile.in b/lib/eventlog/Makefile.in
|
|
||||||
index 24c2dbce9..02236f70b 100644
|
|
||||||
--- a/lib/eventlog/Makefile.in
|
|
||||||
+++ b/lib/eventlog/Makefile.in
|
|
||||||
@@ -82,7 +82,7 @@ SHELL = @SHELL@
|
|
||||||
|
|
||||||
TEST_PROGS = check_wrap
|
|
||||||
|
|
||||||
-LIBEVENTLOG_OBJS = eventlog.lo eventlog_free.lo logwrap.lo
|
|
||||||
+LIBEVENTLOG_OBJS = eventlog.lo eventlog_conf.lo eventlog_free.lo logwrap.lo
|
|
||||||
|
|
||||||
IOBJS = $(LIBEVENTLOG_OBJS:.lo=.i)
|
|
||||||
|
|
||||||
@@ -213,6 +213,24 @@ eventlog.i: $(srcdir)/eventlog.c $(incdir)/compat/stdbool.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 $@
|
|
||||||
+eventlog_conf.lo: $(srcdir)/eventlog_conf.c $(incdir)/compat/stdbool.h \
|
|
||||||
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
|
|
||||||
+ $(incdir)/sudo_eventlog.h $(incdir)/sudo_fatal.h \
|
|
||||||
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_json.h \
|
|
||||||
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
|
|
||||||
+ $(incdir)/sudo_util.h $(top_builddir)/config.h \
|
|
||||||
+ $(top_builddir)/pathnames.h
|
|
||||||
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/eventlog_conf.c
|
|
||||||
+eventlog_conf.i: $(srcdir)/eventlog_conf.c $(incdir)/compat/stdbool.h \
|
|
||||||
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
|
|
||||||
+ $(incdir)/sudo_eventlog.h $(incdir)/sudo_fatal.h \
|
|
||||||
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_json.h \
|
|
||||||
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
|
|
||||||
+ $(incdir)/sudo_util.h $(top_builddir)/config.h \
|
|
||||||
+ $(top_builddir)/pathnames.h
|
|
||||||
+ $(CC) -E -o $@ $(CPPFLAGS) $<
|
|
||||||
+eventlog_conf.plog: eventlog_conf.i
|
|
||||||
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/eventlog_conf.c --i-file $< --output-file $@
|
|
||||||
eventlog_free.lo: $(srcdir)/eventlog_free.c $(incdir)/compat/stdbool.h \
|
|
||||||
$(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
|
|
||||||
$(incdir)/sudo_eventlog.h $(incdir)/sudo_queue.h \
|
|
||||||
diff --git a/lib/eventlog/eventlog.c b/lib/eventlog/eventlog.c
|
|
||||||
index c8c9b7ba5..e7505d9d9 100644
|
|
||||||
--- a/lib/eventlog/eventlog.c
|
|
||||||
+++ b/lib/eventlog/eventlog.c
|
|
||||||
@@ -75,35 +75,6 @@
|
|
||||||
isalnum((unsigned char)(s)[6]) && isalnum((unsigned char)(s)[7]) && \
|
|
||||||
(s)[8] == '\0')
|
|
||||||
|
|
||||||
-static FILE *eventlog_stub_open_log(int type, const char *logfile);
|
|
||||||
-static void eventlog_stub_close_log(int type, FILE *fp);
|
|
||||||
-
|
|
||||||
-/* Eventlog config settings (default values). */
|
|
||||||
-static struct eventlog_config evl_conf = {
|
|
||||||
- EVLOG_NONE, /* type */
|
|
||||||
- EVLOG_SUDO, /* format */
|
|
||||||
- LOG_NOTICE, /* syslog_acceptpri */
|
|
||||||
- LOG_ALERT, /* syslog_rejectpri */
|
|
||||||
- LOG_ALERT, /* syslog_alertpri */
|
|
||||||
- MAXSYSLOGLEN, /* syslog_maxlen */
|
|
||||||
- 0, /* file_maxlen */
|
|
||||||
- ROOT_UID, /* mailuid */
|
|
||||||
- false, /* omit_hostname */
|
|
||||||
- _PATH_SUDO_LOGFILE, /* logpath */
|
|
||||||
- "%h %e %T", /* time_fmt */
|
|
||||||
-#ifdef _PATH_SUDO_SENDMAIL
|
|
||||||
- _PATH_SUDO_SENDMAIL, /* mailerpath */
|
|
||||||
-#else
|
|
||||||
- NULL, /* mailerpath (disabled) */
|
|
||||||
-#endif
|
|
||||||
- "-t", /* mailerflags */
|
|
||||||
- NULL, /* mailfrom */
|
|
||||||
- MAILTO, /* mailto */
|
|
||||||
- N_(MAILSUBJECT), /* mailsub */
|
|
||||||
- eventlog_stub_open_log, /* open_log */
|
|
||||||
- eventlog_stub_close_log /* close_log */
|
|
||||||
-};
|
|
||||||
-
|
|
||||||
/*
|
|
||||||
* Allocate and fill in a new logline.
|
|
||||||
*/
|
|
||||||
@@ -111,6 +82,7 @@ static char *
|
|
||||||
new_logline(int flags, const char *message, const char *errstr,
|
|
||||||
const struct eventlog *evlog)
|
|
||||||
{
|
|
||||||
+ const struct eventlog_config *evl_conf = eventlog_getconf();
|
|
||||||
char *line = NULL, *evstr = NULL;
|
|
||||||
const char *iolog_file = evlog->iolog_file;
|
|
||||||
const char *tty, *tsid = NULL;
|
|
||||||
@@ -159,7 +131,7 @@ new_logline(int flags, const char *message, const char *errstr,
|
|
||||||
len += strlen(message) + 3;
|
|
||||||
if (errstr != NULL)
|
|
||||||
len += strlen(errstr) + 3;
|
|
||||||
- if (evlog->submithost != NULL && !evl_conf.omit_hostname)
|
|
||||||
+ if (evlog->submithost != NULL && !evl_conf->omit_hostname)
|
|
||||||
len += sizeof(LL_HOST_STR) + 2 + strlen(evlog->submithost);
|
|
||||||
if (tty != NULL)
|
|
||||||
len += sizeof(LL_TTY_STR) + 2 + strlen(tty);
|
|
||||||
@@ -218,7 +190,7 @@ new_logline(int flags, const char *message, const char *errstr,
|
|
||||||
strlcat(line, " ; ", len) >= len)
|
|
||||||
goto toobig;
|
|
||||||
}
|
|
||||||
- if (evlog->submithost != NULL && !evl_conf.omit_hostname) {
|
|
||||||
+ if (evlog->submithost != NULL && !evl_conf->omit_hostname) {
|
|
||||||
if (strlcat(line, LL_HOST_STR, len) >= len ||
|
|
||||||
strlcat(line, evlog->submithost, len) >= len ||
|
|
||||||
strlcat(line, " ; ", len) >= len)
|
|
||||||
@@ -331,8 +303,9 @@ closefrom_nodebug(int lowfd)
|
|
||||||
static void __attribute__((__noreturn__))
|
|
||||||
exec_mailer(int pipein)
|
|
||||||
{
|
|
||||||
+ const struct eventlog_config *evl_conf = eventlog_getconf();
|
|
||||||
char *last, *mflags, *p, *argv[MAX_MAILFLAGS + 1];
|
|
||||||
- const char *mpath = evl_conf.mailerpath;
|
|
||||||
+ const char *mpath = evl_conf->mailerpath;
|
|
||||||
int i;
|
|
||||||
char * const root_envp[] = {
|
|
||||||
"HOME=/",
|
|
||||||
@@ -356,7 +329,7 @@ exec_mailer(int pipein)
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Build up an argv based on the mailer path and flags */
|
|
||||||
- if ((mflags = strdup(evl_conf.mailerflags)) == NULL) {
|
|
||||||
+ if ((mflags = strdup(evl_conf->mailerflags)) == NULL) {
|
|
||||||
syslog(LOG_ERR, _("unable to allocate memory")); // -V618
|
|
||||||
sudo_debug_exit(__func__, __FILE__, __LINE__, sudo_debug_subsys);
|
|
||||||
_exit(127);
|
|
||||||
@@ -379,14 +352,14 @@ exec_mailer(int pipein)
|
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR, "unable to change uid to %u",
|
|
||||||
ROOT_UID);
|
|
||||||
}
|
|
||||||
- if (evl_conf.mailuid != ROOT_UID) {
|
|
||||||
- if (setuid(evl_conf.mailuid) != 0) {
|
|
||||||
+ if (evl_conf->mailuid != ROOT_UID) {
|
|
||||||
+ if (setuid(evl_conf->mailuid) != 0) {
|
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR, "unable to change uid to %u",
|
|
||||||
- (unsigned int)evl_conf.mailuid);
|
|
||||||
+ (unsigned int)evl_conf->mailuid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sudo_debug_exit(__func__, __FILE__, __LINE__, sudo_debug_subsys);
|
|
||||||
- if (evl_conf.mailuid == ROOT_UID)
|
|
||||||
+ if (evl_conf->mailuid == ROOT_UID)
|
|
||||||
execve(mpath, argv, root_envp);
|
|
||||||
else
|
|
||||||
execv(mpath, argv);
|
|
||||||
@@ -400,7 +373,8 @@ exec_mailer(int pipein)
|
|
||||||
static bool
|
|
||||||
send_mail(const struct eventlog *evlog, const char *fmt, ...)
|
|
||||||
{
|
|
||||||
- const char *cp, *timefmt = evl_conf.time_fmt;
|
|
||||||
+ const struct eventlog_config *evl_conf = eventlog_getconf();
|
|
||||||
+ const char *cp, *timefmt = evl_conf->time_fmt;
|
|
||||||
char timebuf[1024];
|
|
||||||
struct tm *tm;
|
|
||||||
time_t now;
|
|
||||||
@@ -415,11 +389,11 @@ send_mail(const struct eventlog *evlog, const char *fmt, ...)
|
|
||||||
debug_decl(send_mail, SUDO_DEBUG_UTIL);
|
|
||||||
|
|
||||||
/* If mailer is disabled just return. */
|
|
||||||
- if (evl_conf.mailerpath == NULL || evl_conf.mailto == NULL)
|
|
||||||
+ if (evl_conf->mailerpath == NULL || evl_conf->mailto == NULL)
|
|
||||||
debug_return_bool(true);
|
|
||||||
|
|
||||||
/* Make sure the mailer exists and is a regular file. */
|
|
||||||
- if (stat(evl_conf.mailerpath, &sb) != 0 || !S_ISREG(sb.st_mode))
|
|
||||||
+ if (stat(evl_conf->mailerpath, &sb) != 0 || !S_ISREG(sb.st_mode))
|
|
||||||
debug_return_bool(false);
|
|
||||||
|
|
||||||
time(&now);
|
|
||||||
@@ -516,11 +490,11 @@ send_mail(const struct eventlog *evlog, const char *fmt, ...)
|
|
||||||
|
|
||||||
/* Pipes are all setup, send message. */
|
|
||||||
(void) fprintf(mail, "To: %s\nFrom: %s\nAuto-Submitted: %s\nSubject: ",
|
|
||||||
- evl_conf.mailto,
|
|
||||||
- evl_conf.mailfrom ? evl_conf.mailfrom :
|
|
||||||
+ evl_conf->mailto,
|
|
||||||
+ evl_conf->mailfrom ? evl_conf->mailfrom :
|
|
||||||
(evlog ? evlog->submituser : "root"),
|
|
||||||
"auto-generated");
|
|
||||||
- for (cp = _(evl_conf.mailsub); *cp; cp++) {
|
|
||||||
+ for (cp = _(evl_conf->mailsub); *cp; cp++) {
|
|
||||||
/* Expand escapes in the subject */
|
|
||||||
if (*cp == '%' && *(cp+1) != '%') {
|
|
||||||
switch (*(++cp)) {
|
|
||||||
@@ -576,7 +550,8 @@ static bool
|
|
||||||
json_add_timestamp(struct json_container *json, const char *name,
|
|
||||||
const struct timespec *ts)
|
|
||||||
{
|
|
||||||
- const char *timefmt = evl_conf.time_fmt;
|
|
||||||
+ const struct eventlog_config *evl_conf = eventlog_getconf();
|
|
||||||
+ const char *timefmt = evl_conf->time_fmt;
|
|
||||||
struct json_value json_value;
|
|
||||||
time_t secs = ts->tv_sec;
|
|
||||||
char timebuf[1024];
|
|
||||||
@@ -880,12 +855,13 @@ bad:
|
|
||||||
static bool
|
|
||||||
do_syslog_sudo(int pri, char *logline, const struct eventlog *evlog)
|
|
||||||
{
|
|
||||||
+ const struct eventlog_config *evl_conf = eventlog_getconf();
|
|
||||||
size_t len, maxlen;
|
|
||||||
char *p, *tmp, save;
|
|
||||||
const char *fmt;
|
|
||||||
debug_decl(do_syslog_sudo, SUDO_DEBUG_UTIL);
|
|
||||||
|
|
||||||
- evl_conf.open_log(EVLOG_SYSLOG, NULL);
|
|
||||||
+ evl_conf->open_log(EVLOG_SYSLOG, NULL);
|
|
||||||
|
|
||||||
if (evlog == NULL) {
|
|
||||||
/* Not a command, just log it as-is. */
|
|
||||||
@@ -897,7 +873,7 @@ do_syslog_sudo(int pri, char *logline, const struct eventlog *evlog)
|
|
||||||
* Log the full line, breaking into multiple syslog(3) calls if necessary
|
|
||||||
*/
|
|
||||||
fmt = _("%8s : %s");
|
|
||||||
- maxlen = evl_conf.syslog_maxlen -
|
|
||||||
+ maxlen = evl_conf->syslog_maxlen -
|
|
||||||
(strlen(fmt) - 5 + strlen(evlog->submituser));
|
|
||||||
for (p = logline; *p != '\0'; ) {
|
|
||||||
len = strlen(p);
|
|
||||||
@@ -926,11 +902,11 @@ do_syslog_sudo(int pri, char *logline, const struct eventlog *evlog)
|
|
||||||
p += len;
|
|
||||||
}
|
|
||||||
fmt = _("%8s : (command continued) %s");
|
|
||||||
- maxlen = evl_conf.syslog_maxlen -
|
|
||||||
+ maxlen = evl_conf->syslog_maxlen -
|
|
||||||
(strlen(fmt) - 5 + strlen(evlog->submituser));
|
|
||||||
}
|
|
||||||
done:
|
|
||||||
- evl_conf.close_log(EVLOG_SYSLOG, NULL);
|
|
||||||
+ evl_conf->close_log(EVLOG_SYSLOG, NULL);
|
|
||||||
|
|
||||||
debug_return_bool(true);
|
|
||||||
}
|
|
||||||
@@ -941,6 +917,7 @@ do_syslog_json(int pri, int event_type, const char *reason,
|
|
||||||
const struct timespec *event_time,
|
|
||||||
eventlog_json_callback_t info_cb, void *info)
|
|
||||||
{
|
|
||||||
+ const struct eventlog_config *evl_conf = eventlog_getconf();
|
|
||||||
char *json_str;
|
|
||||||
debug_decl(do_syslog_json, SUDO_DEBUG_UTIL);
|
|
||||||
|
|
||||||
@@ -951,10 +928,10 @@ do_syslog_json(int pri, int event_type, const char *reason,
|
|
||||||
debug_return_bool(false);
|
|
||||||
|
|
||||||
/* Syslog it in a sudo object with a @cee: prefix. */
|
|
||||||
- /* TODO: use evl_conf.syslog_maxlen to break up long messages. */
|
|
||||||
- evl_conf.open_log(EVLOG_SYSLOG, NULL);
|
|
||||||
+ /* TODO: use evl_conf->syslog_maxlen to break up long messages. */
|
|
||||||
+ evl_conf->open_log(EVLOG_SYSLOG, NULL);
|
|
||||||
syslog(pri, "@cee:{\"sudo\":{%s}}", json_str);
|
|
||||||
- evl_conf.close_log(EVLOG_SYSLOG, NULL);
|
|
||||||
+ evl_conf->close_log(EVLOG_SYSLOG, NULL);
|
|
||||||
free(json_str);
|
|
||||||
debug_return_bool(true);
|
|
||||||
}
|
|
||||||
@@ -967,13 +944,14 @@ do_syslog(int event_type, int flags, const char *reason, const char *errstr,
|
|
||||||
const struct eventlog *evlog, const struct timespec *event_time,
|
|
||||||
eventlog_json_callback_t info_cb, void *info)
|
|
||||||
{
|
|
||||||
+ const struct eventlog_config *evl_conf = eventlog_getconf();
|
|
||||||
char *logline = NULL;
|
|
||||||
bool ret = false;
|
|
||||||
int pri;
|
|
||||||
debug_decl(do_syslog, SUDO_DEBUG_UTIL);
|
|
||||||
|
|
||||||
/* Sudo format logs and mailed logs use the same log line format. */
|
|
||||||
- if (evl_conf.format == EVLOG_SUDO || ISSET(flags, EVLOG_MAIL)) {
|
|
||||||
+ if (evl_conf->format == EVLOG_SUDO || ISSET(flags, EVLOG_MAIL)) {
|
|
||||||
logline = new_logline(flags, reason, errstr, evlog);
|
|
||||||
if (logline == NULL)
|
|
||||||
debug_return_bool(false);
|
|
||||||
@@ -992,13 +970,13 @@ do_syslog(int event_type, int flags, const char *reason, const char *errstr,
|
|
||||||
|
|
||||||
switch (event_type) {
|
|
||||||
case EVLOG_ACCEPT:
|
|
||||||
- pri = evl_conf.syslog_acceptpri;
|
|
||||||
+ pri = evl_conf->syslog_acceptpri;
|
|
||||||
break;
|
|
||||||
case EVLOG_REJECT:
|
|
||||||
- pri = evl_conf.syslog_rejectpri;
|
|
||||||
+ pri = evl_conf->syslog_rejectpri;
|
|
||||||
break;
|
|
||||||
case EVLOG_ALERT:
|
|
||||||
- pri = evl_conf.syslog_alertpri;
|
|
||||||
+ pri = evl_conf->syslog_alertpri;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
|
||||||
@@ -1012,7 +990,7 @@ do_syslog(int event_type, int flags, const char *reason, const char *errstr,
|
|
||||||
debug_return_bool(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
- switch (evl_conf.format) {
|
|
||||||
+ switch (evl_conf->format) {
|
|
||||||
case EVLOG_SUDO:
|
|
||||||
ret = do_syslog_sudo(pri, logline, evlog);
|
|
||||||
break;
|
|
||||||
@@ -1022,7 +1000,7 @@ do_syslog(int event_type, int flags, const char *reason, const char *errstr,
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
|
||||||
- "unexpected eventlog format %d", evl_conf.format);
|
|
||||||
+ "unexpected eventlog format %d", evl_conf->format);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
free(logline);
|
|
||||||
@@ -1034,9 +1012,10 @@ static bool
|
|
||||||
do_logfile_sudo(const char *logline, const struct eventlog *evlog,
|
|
||||||
const struct timespec *event_time)
|
|
||||||
{
|
|
||||||
+ const struct eventlog_config *evl_conf = eventlog_getconf();
|
|
||||||
char *full_line, timebuf[8192], *timestr = NULL;
|
|
||||||
- const char *timefmt = evl_conf.time_fmt;
|
|
||||||
- const char *logfile = evl_conf.logpath;
|
|
||||||
+ const char *timefmt = evl_conf->time_fmt;
|
|
||||||
+ const char *logfile = evl_conf->logpath;
|
|
||||||
time_t tv_sec = event_time->tv_sec;
|
|
||||||
struct tm *timeptr;
|
|
||||||
bool ret = false;
|
|
||||||
@@ -1044,7 +1023,7 @@ do_logfile_sudo(const char *logline, const struct eventlog *evlog,
|
|
||||||
int len;
|
|
||||||
debug_decl(do_logfile_sudo, SUDO_DEBUG_UTIL);
|
|
||||||
|
|
||||||
- if ((fp = evl_conf.open_log(EVLOG_FILE, logfile)) == NULL)
|
|
||||||
+ if ((fp = evl_conf->open_log(EVLOG_FILE, logfile)) == NULL)
|
|
||||||
debug_return_bool(false);
|
|
||||||
|
|
||||||
if (!sudo_lock_file(fileno(fp), SUDO_LOCK)) {
|
|
||||||
@@ -1067,7 +1046,7 @@ do_logfile_sudo(const char *logline, const struct eventlog *evlog,
|
|
||||||
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
- eventlog_writeln(fp, full_line, len, evl_conf.file_maxlen);
|
|
||||||
+ eventlog_writeln(fp, full_line, len, evl_conf->file_maxlen);
|
|
||||||
(void)fflush(fp);
|
|
||||||
if (ferror(fp)) {
|
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
|
|
||||||
@@ -1078,7 +1057,7 @@ do_logfile_sudo(const char *logline, const struct eventlog *evlog,
|
|
||||||
|
|
||||||
done:
|
|
||||||
(void)sudo_lock_file(fileno(fp), SUDO_UNLOCK);
|
|
||||||
- evl_conf.close_log(EVLOG_FILE, fp);
|
|
||||||
+ evl_conf->close_log(EVLOG_FILE, fp);
|
|
||||||
debug_return_bool(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1087,14 +1066,15 @@ do_logfile_json(int event_type, const char *reason, const char *errstr,
|
|
||||||
const struct eventlog *evlog, const struct timespec *event_time,
|
|
||||||
eventlog_json_callback_t info_cb, void *info)
|
|
||||||
{
|
|
||||||
- const char *logfile = evl_conf.logpath;
|
|
||||||
+ const struct eventlog_config *evl_conf = eventlog_getconf();
|
|
||||||
+ const char *logfile = evl_conf->logpath;
|
|
||||||
struct stat sb;
|
|
||||||
char *json_str;
|
|
||||||
int ret = false;
|
|
||||||
FILE *fp;
|
|
||||||
debug_decl(do_logfile_json, SUDO_DEBUG_UTIL);
|
|
||||||
|
|
||||||
- if ((fp = evl_conf.open_log(EVLOG_FILE, logfile)) == NULL)
|
|
||||||
+ if ((fp = evl_conf->open_log(EVLOG_FILE, logfile)) == NULL)
|
|
||||||
debug_return_bool(false);
|
|
||||||
|
|
||||||
json_str = format_json(event_type, reason, errstr, evlog, event_time,
|
|
||||||
@@ -1135,7 +1115,7 @@ do_logfile_json(int event_type, const char *reason, const char *errstr,
|
|
||||||
done:
|
|
||||||
free(json_str);
|
|
||||||
(void)sudo_lock_file(fileno(fp), SUDO_UNLOCK);
|
|
||||||
- evl_conf.close_log(EVLOG_FILE, fp);
|
|
||||||
+ evl_conf->close_log(EVLOG_FILE, fp);
|
|
||||||
debug_return_bool(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1144,12 +1124,13 @@ do_logfile(int event_type, int flags, const char *reason, const char *errstr,
|
|
||||||
const struct eventlog *evlog, const struct timespec *event_time,
|
|
||||||
eventlog_json_callback_t info_cb, void *info)
|
|
||||||
{
|
|
||||||
+ const struct eventlog_config *evl_conf = eventlog_getconf();
|
|
||||||
bool ret = false;
|
|
||||||
char *logline = NULL;
|
|
||||||
debug_decl(do_logfile, SUDO_DEBUG_UTIL);
|
|
||||||
|
|
||||||
/* Sudo format logs and mailed logs use the same log line format. */
|
|
||||||
- if (evl_conf.format == EVLOG_SUDO || ISSET(flags, EVLOG_MAIL)) {
|
|
||||||
+ if (evl_conf->format == EVLOG_SUDO || ISSET(flags, EVLOG_MAIL)) {
|
|
||||||
logline = new_logline(flags, reason, errstr, evlog);
|
|
||||||
if (logline == NULL)
|
|
||||||
debug_return_bool(false);
|
|
||||||
@@ -1166,7 +1147,7 @@ do_logfile(int event_type, int flags, const char *reason, const char *errstr,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- switch (evl_conf.format) {
|
|
||||||
+ switch (evl_conf->format) {
|
|
||||||
case EVLOG_SUDO:
|
|
||||||
ret = do_logfile_sudo(logline ? logline : reason, evlog, event_time);
|
|
||||||
break;
|
|
||||||
@@ -1176,7 +1157,7 @@ do_logfile(int event_type, int flags, const char *reason, const char *errstr,
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
|
||||||
- "unexpected eventlog format %d", evl_conf.format);
|
|
||||||
+ "unexpected eventlog format %d", evl_conf->format);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
free(logline);
|
|
||||||
@@ -1188,7 +1169,8 @@ bool
|
|
||||||
eventlog_accept(const struct eventlog *evlog, int flags,
|
|
||||||
eventlog_json_callback_t info_cb, void *info)
|
|
||||||
{
|
|
||||||
- const int log_type = evl_conf.type;
|
|
||||||
+ const struct eventlog_config *evl_conf = eventlog_getconf();
|
|
||||||
+ const int log_type = evl_conf->type;
|
|
||||||
bool ret = true;
|
|
||||||
debug_decl(log_accept, SUDO_DEBUG_UTIL);
|
|
||||||
|
|
||||||
@@ -1214,7 +1196,8 @@ bool
|
|
||||||
eventlog_reject(const struct eventlog *evlog, int flags, const char *reason,
|
|
||||||
eventlog_json_callback_t info_cb, void *info)
|
|
||||||
{
|
|
||||||
- const int log_type = evl_conf.type;
|
|
||||||
+ const struct eventlog_config *evl_conf = eventlog_getconf();
|
|
||||||
+ const int log_type = evl_conf->type;
|
|
||||||
bool ret = true;
|
|
||||||
debug_decl(log_reject, SUDO_DEBUG_UTIL);
|
|
||||||
|
|
||||||
@@ -1237,7 +1220,8 @@ bool
|
|
||||||
eventlog_alert(const struct eventlog *evlog, int flags,
|
|
||||||
struct timespec *alert_time, const char *reason, const char *errstr)
|
|
||||||
{
|
|
||||||
- const int log_type = evl_conf.type;
|
|
||||||
+ const struct eventlog_config *evl_conf = eventlog_getconf();
|
|
||||||
+ const int log_type = evl_conf->type;
|
|
||||||
bool ret = true;
|
|
||||||
debug_decl(log_alert, SUDO_DEBUG_UTIL);
|
|
||||||
|
|
||||||
@@ -1255,169 +1239,3 @@ eventlog_alert(const struct eventlog *evlog, int flags,
|
|
||||||
|
|
||||||
debug_return_bool(ret);
|
|
||||||
}
|
|
||||||
-
|
|
||||||
-static FILE *
|
|
||||||
-eventlog_stub_open_log(int type, const char *logfile)
|
|
||||||
-{
|
|
||||||
- debug_decl(eventlog_stub_open_log, SUDO_DEBUG_UTIL);
|
|
||||||
- sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO,
|
|
||||||
- "open_log not set, using stub");
|
|
||||||
- debug_return_ptr(NULL);
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static void
|
|
||||||
-eventlog_stub_close_log(int type, FILE *fp)
|
|
||||||
-{
|
|
||||||
- debug_decl(eventlog_stub_close_log, SUDO_DEBUG_UTIL);
|
|
||||||
- sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO,
|
|
||||||
- "close_log not set, using stub");
|
|
||||||
- debug_return;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-/*
|
|
||||||
- * Set eventlog config settings.
|
|
||||||
- */
|
|
||||||
-
|
|
||||||
-void
|
|
||||||
-eventlog_set_type(int type)
|
|
||||||
-{
|
|
||||||
- evl_conf.type = type;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-void
|
|
||||||
-eventlog_set_format(enum eventlog_format format)
|
|
||||||
-{
|
|
||||||
- evl_conf.format = format;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-void
|
|
||||||
-eventlog_set_syslog_acceptpri(int pri)
|
|
||||||
-{
|
|
||||||
- evl_conf.syslog_acceptpri = pri;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-void
|
|
||||||
-eventlog_set_syslog_rejectpri(int pri)
|
|
||||||
-{
|
|
||||||
- evl_conf.syslog_rejectpri = pri;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-void
|
|
||||||
-eventlog_set_syslog_alertpri(int pri)
|
|
||||||
-{
|
|
||||||
- evl_conf.syslog_alertpri = pri;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-void
|
|
||||||
-eventlog_set_syslog_maxlen(int len)
|
|
||||||
-{
|
|
||||||
- evl_conf.syslog_maxlen = len;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-void
|
|
||||||
-eventlog_set_file_maxlen(int len)
|
|
||||||
-{
|
|
||||||
- evl_conf.file_maxlen = len;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-void
|
|
||||||
-eventlog_set_mailuid(uid_t uid)
|
|
||||||
-{
|
|
||||||
- evl_conf.mailuid = uid;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-void
|
|
||||||
-eventlog_set_omit_hostname(bool omit_hostname)
|
|
||||||
-{
|
|
||||||
- evl_conf.omit_hostname = omit_hostname;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-void
|
|
||||||
-eventlog_set_logpath(const char *path)
|
|
||||||
-{
|
|
||||||
- evl_conf.logpath = path;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-void
|
|
||||||
-eventlog_set_time_fmt(const char *fmt)
|
|
||||||
-{
|
|
||||||
- evl_conf.time_fmt = fmt;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-void
|
|
||||||
-eventlog_set_mailerpath(const char *path)
|
|
||||||
-{
|
|
||||||
- evl_conf.mailerpath = path;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-void
|
|
||||||
-eventlog_set_mailerflags(const char *mflags)
|
|
||||||
-{
|
|
||||||
- evl_conf.mailerflags = mflags;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-void
|
|
||||||
-eventlog_set_mailfrom(const char *from_addr)
|
|
||||||
-{
|
|
||||||
- evl_conf.mailfrom = from_addr;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-void
|
|
||||||
-eventlog_set_mailto(const char *to_addr)
|
|
||||||
-{
|
|
||||||
- evl_conf.mailto = to_addr;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-void
|
|
||||||
-eventlog_set_mailsub(const char *subject)
|
|
||||||
-{
|
|
||||||
- evl_conf.mailsub = subject;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-void
|
|
||||||
-eventlog_set_open_log(FILE *(*fn)(int type, const char *))
|
|
||||||
-{
|
|
||||||
- evl_conf.open_log = fn;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-void
|
|
||||||
-eventlog_set_close_log(void (*fn)(int type, FILE *))
|
|
||||||
-{
|
|
||||||
- evl_conf.close_log = fn;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-bool
|
|
||||||
-eventlog_setconf(struct eventlog_config *conf)
|
|
||||||
-{
|
|
||||||
- debug_decl(eventlog_setconf, SUDO_DEBUG_UTIL);
|
|
||||||
-
|
|
||||||
- if (conf != NULL) {
|
|
||||||
- memcpy(&evl_conf, conf, sizeof(evl_conf));
|
|
||||||
- } else {
|
|
||||||
- memset(&evl_conf, 0, sizeof(evl_conf));
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- /* Apply default values where possible. */
|
|
||||||
- if (evl_conf.syslog_maxlen == 0)
|
|
||||||
- evl_conf.syslog_maxlen = MAXSYSLOGLEN;
|
|
||||||
- if (evl_conf.logpath == NULL)
|
|
||||||
- evl_conf.logpath = _PATH_SUDO_LOGFILE;
|
|
||||||
- if (evl_conf.time_fmt == NULL)
|
|
||||||
- evl_conf.time_fmt = "%h %e %T";
|
|
||||||
-#ifdef _PATH_SUDO_SENDMAIL
|
|
||||||
- if (evl_conf.mailerpath == NULL)
|
|
||||||
- evl_conf.mailerpath = _PATH_SUDO_SENDMAIL;
|
|
||||||
-#endif
|
|
||||||
- if (evl_conf.mailerflags == NULL)
|
|
||||||
- evl_conf.mailerflags = "-t";
|
|
||||||
- if (evl_conf.mailto == NULL)
|
|
||||||
- evl_conf.mailto = MAILTO;
|
|
||||||
- if (evl_conf.mailsub == NULL)
|
|
||||||
- evl_conf.mailsub = N_(MAILSUBJECT);
|
|
||||||
- if (evl_conf.open_log == NULL)
|
|
||||||
- evl_conf.open_log = eventlog_stub_open_log;
|
|
||||||
- if (evl_conf.close_log == NULL)
|
|
||||||
- evl_conf.close_log = eventlog_stub_close_log;
|
|
||||||
-
|
|
||||||
- debug_return_bool(true);
|
|
||||||
-}
|
|
||||||
diff --git a/lib/eventlog/eventlog_conf.c b/lib/eventlog/eventlog_conf.c
|
|
||||||
new file mode 100644
|
|
||||||
index 000000000..8ad03851f
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/lib/eventlog/eventlog_conf.c
|
|
||||||
@@ -0,0 +1,226 @@
|
|
||||||
+/*
|
|
||||||
+ * SPDX-License-Identifier: ISC
|
|
||||||
+ *
|
|
||||||
+ * Copyright (c) 1994-1996, 1998-2020 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 <sys/wait.h>
|
|
||||||
+#include <netinet/in.h>
|
|
||||||
+
|
|
||||||
+#include <ctype.h>
|
|
||||||
+#include <errno.h>
|
|
||||||
+#include <fcntl.h>
|
|
||||||
+#include <grp.h>
|
|
||||||
+#include <locale.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 "pathnames.h"
|
|
||||||
+#include "sudo_compat.h"
|
|
||||||
+#include "sudo_debug.h"
|
|
||||||
+#include "sudo_eventlog.h"
|
|
||||||
+#include "sudo_fatal.h"
|
|
||||||
+#include "sudo_gettext.h"
|
|
||||||
+#include "sudo_json.h"
|
|
||||||
+#include "sudo_queue.h"
|
|
||||||
+#include "sudo_util.h"
|
|
||||||
+
|
|
||||||
+static FILE *eventlog_stub_open_log(int type, const char *logfile);
|
|
||||||
+static void eventlog_stub_close_log(int type, FILE *fp);
|
|
||||||
+
|
|
||||||
+/* Eventlog config settings (default values). */
|
|
||||||
+static struct eventlog_config evl_conf = {
|
|
||||||
+ EVLOG_NONE, /* type */
|
|
||||||
+ EVLOG_SUDO, /* format */
|
|
||||||
+ LOG_NOTICE, /* syslog_acceptpri */
|
|
||||||
+ LOG_ALERT, /* syslog_rejectpri */
|
|
||||||
+ LOG_ALERT, /* syslog_alertpri */
|
|
||||||
+ MAXSYSLOGLEN, /* syslog_maxlen */
|
|
||||||
+ 0, /* file_maxlen */
|
|
||||||
+ ROOT_UID, /* mailuid */
|
|
||||||
+ false, /* omit_hostname */
|
|
||||||
+ _PATH_SUDO_LOGFILE, /* logpath */
|
|
||||||
+ "%h %e %T", /* time_fmt */
|
|
||||||
+#ifdef _PATH_SUDO_SENDMAIL
|
|
||||||
+ _PATH_SUDO_SENDMAIL, /* mailerpath */
|
|
||||||
+#else
|
|
||||||
+ NULL, /* mailerpath (disabled) */
|
|
||||||
+#endif
|
|
||||||
+ "-t", /* mailerflags */
|
|
||||||
+ NULL, /* mailfrom */
|
|
||||||
+ MAILTO, /* mailto */
|
|
||||||
+ N_(MAILSUBJECT), /* mailsub */
|
|
||||||
+ eventlog_stub_open_log, /* open_log */
|
|
||||||
+ eventlog_stub_close_log /* close_log */
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static FILE *
|
|
||||||
+eventlog_stub_open_log(int type, const char *logfile)
|
|
||||||
+{
|
|
||||||
+ debug_decl(eventlog_stub_open_log, SUDO_DEBUG_UTIL);
|
|
||||||
+ sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO,
|
|
||||||
+ "open_log not set, using stub");
|
|
||||||
+ debug_return_ptr(NULL);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void
|
|
||||||
+eventlog_stub_close_log(int type, FILE *fp)
|
|
||||||
+{
|
|
||||||
+ debug_decl(eventlog_stub_close_log, SUDO_DEBUG_UTIL);
|
|
||||||
+ sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO,
|
|
||||||
+ "close_log not set, using stub");
|
|
||||||
+ debug_return;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * eventlog config setters.
|
|
||||||
+ */
|
|
||||||
+
|
|
||||||
+void
|
|
||||||
+eventlog_set_type(int type)
|
|
||||||
+{
|
|
||||||
+ evl_conf.type = type;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+void
|
|
||||||
+eventlog_set_format(enum eventlog_format format)
|
|
||||||
+{
|
|
||||||
+ evl_conf.format = format;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+void
|
|
||||||
+eventlog_set_syslog_acceptpri(int pri)
|
|
||||||
+{
|
|
||||||
+ evl_conf.syslog_acceptpri = pri;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+void
|
|
||||||
+eventlog_set_syslog_rejectpri(int pri)
|
|
||||||
+{
|
|
||||||
+ evl_conf.syslog_rejectpri = pri;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+void
|
|
||||||
+eventlog_set_syslog_alertpri(int pri)
|
|
||||||
+{
|
|
||||||
+ evl_conf.syslog_alertpri = pri;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+void
|
|
||||||
+eventlog_set_syslog_maxlen(int len)
|
|
||||||
+{
|
|
||||||
+ evl_conf.syslog_maxlen = len;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+void
|
|
||||||
+eventlog_set_file_maxlen(int len)
|
|
||||||
+{
|
|
||||||
+ evl_conf.file_maxlen = len;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+void
|
|
||||||
+eventlog_set_mailuid(uid_t uid)
|
|
||||||
+{
|
|
||||||
+ evl_conf.mailuid = uid;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+void
|
|
||||||
+eventlog_set_omit_hostname(bool omit_hostname)
|
|
||||||
+{
|
|
||||||
+ evl_conf.omit_hostname = omit_hostname;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+void
|
|
||||||
+eventlog_set_logpath(const char *path)
|
|
||||||
+{
|
|
||||||
+ evl_conf.logpath = path;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+void
|
|
||||||
+eventlog_set_time_fmt(const char *fmt)
|
|
||||||
+{
|
|
||||||
+ evl_conf.time_fmt = fmt;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+void
|
|
||||||
+eventlog_set_mailerpath(const char *path)
|
|
||||||
+{
|
|
||||||
+ evl_conf.mailerpath = path;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+void
|
|
||||||
+eventlog_set_mailerflags(const char *mflags)
|
|
||||||
+{
|
|
||||||
+ evl_conf.mailerflags = mflags;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+void
|
|
||||||
+eventlog_set_mailfrom(const char *from_addr)
|
|
||||||
+{
|
|
||||||
+ evl_conf.mailfrom = from_addr;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+void
|
|
||||||
+eventlog_set_mailto(const char *to_addr)
|
|
||||||
+{
|
|
||||||
+ evl_conf.mailto = to_addr;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+void
|
|
||||||
+eventlog_set_mailsub(const char *subject)
|
|
||||||
+{
|
|
||||||
+ evl_conf.mailsub = subject;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+void
|
|
||||||
+eventlog_set_open_log(FILE *(*fn)(int type, const char *))
|
|
||||||
+{
|
|
||||||
+ evl_conf.open_log = fn;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+void
|
|
||||||
+eventlog_set_close_log(void (*fn)(int type, FILE *))
|
|
||||||
+{
|
|
||||||
+ evl_conf.close_log = fn;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * get eventlog config.
|
|
||||||
+ */
|
|
||||||
+const struct eventlog_config *
|
|
||||||
+eventlog_getconf(void)
|
|
||||||
+{
|
|
||||||
+ return &evl_conf;
|
|
||||||
+}
|
|
||||||
--
|
|
||||||
2.43.0
|
|
||||||
|
|
@ -1,66 +0,0 @@
|
|||||||
From d452678787683da6498668cd1f1cbb8000d63178 Mon Sep 17 00:00:00 2001
|
|
||||||
From: "Todd C. Miller" <Todd.Miller@sudo.ws>
|
|
||||||
Date: Tue, 2 Mar 2021 18:37:35 -0700
|
|
||||||
Subject: [PATCH] Log peer address in sudo_logsrvd JSON-format logs. The peer
|
|
||||||
that connected to us might not be the same host where the log entry
|
|
||||||
originated.
|
|
||||||
|
|
||||||
---
|
|
||||||
include/sudo_eventlog.h | 3 ++-
|
|
||||||
lib/eventlog/eventlog.c | 9 ++++++++-
|
|
||||||
logsrvd/iolog_writer.c | 8 ++++++--
|
|
||||||
logsrvd/logsrvd.c | 9 +++++----
|
|
||||||
logsrvd/logsrvd.h | 4 ++--
|
|
||||||
5 files changed, 23 insertions(+), 10 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/include/sudo_eventlog.h b/include/sudo_eventlog.h
|
|
||||||
index e40622a51..49153e173 100644
|
|
||||||
--- a/include/sudo_eventlog.h
|
|
||||||
+++ b/include/sudo_eventlog.h
|
|
||||||
@@ -1,7 +1,7 @@
|
|
||||||
/*
|
|
||||||
* SPDX-License-Identifier: ISC
|
|
||||||
*
|
|
||||||
- * Copyright (c) 2020 Todd C. Miller <Todd.Miller@sudo.ws>
|
|
||||||
+ * Copyright (c) 2020-2021 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
|
|
||||||
@@ -101,6 +101,7 @@ struct eventlog {
|
|
||||||
char *runcwd;
|
|
||||||
char *rungroup;
|
|
||||||
char *runuser;
|
|
||||||
+ char *peeraddr;
|
|
||||||
char *submithost;
|
|
||||||
char *submituser;
|
|
||||||
char *submitgroup;
|
|
||||||
diff --git a/lib/eventlog/eventlog.c b/lib/eventlog/eventlog.c
|
|
||||||
index e7505d9d9..0c1e74e38 100644
|
|
||||||
--- a/lib/eventlog/eventlog.c
|
|
||||||
+++ b/lib/eventlog/eventlog.c
|
|
||||||
@@ -1,7 +1,7 @@
|
|
||||||
/*
|
|
||||||
* SPDX-License-Identifier: ISC
|
|
||||||
*
|
|
||||||
- * Copyright (c) 1994-1996, 1998-2020 Todd C. Miller <Todd.Miller@sudo.ws>
|
|
||||||
+ * Copyright (c) 1994-1996, 1998-2021 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
|
|
||||||
@@ -825,6 +825,13 @@ format_json(int event_type, const char *reason, const char *errstr,
|
|
||||||
|
|
||||||
/* Event log info may be missing for alert messages. */
|
|
||||||
if (evlog != NULL) {
|
|
||||||
+ if (evlog->peeraddr != NULL) {
|
|
||||||
+ json_value.type = JSON_STRING;
|
|
||||||
+ json_value.u.string = evlog->peeraddr;
|
|
||||||
+ if (!sudo_json_add_value(&json, "peeraddr", &json_value))
|
|
||||||
+ goto bad;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
if (evlog->iolog_path != NULL) {
|
|
||||||
json_value.type = JSON_STRING;
|
|
||||||
json_value.u.string = evlog->iolog_path;
|
|
||||||
--
|
|
||||||
2.43.0
|
|
||||||
|
|
@ -1,559 +0,0 @@
|
|||||||
From b54a16e1749fc53e4ed047da72f97b8f99bf4d6a Mon Sep 17 00:00:00 2001
|
|
||||||
From: "Todd C. Miller" <Todd.Miller@sudo.ws>
|
|
||||||
Date: Fri, 9 Jul 2021 11:08:44 -0600
|
|
||||||
Subject: [PATCH] Add support for logging exit status events. For
|
|
||||||
sudo-formatted logs, this is a record with "EXIT=number" and potentially
|
|
||||||
"SIGNAL=name" after the command. For JSON-format logs, a new "exit" record
|
|
||||||
is logged which contains an "exit_value" and potentially "signal" and
|
|
||||||
"core_dumped". JSON-format logs now incude a UUID to associate the "exit"
|
|
||||||
record with the "accept" record.
|
|
||||||
|
|
||||||
---
|
|
||||||
include/sudo_eventlog.h | 2 +
|
|
||||||
lib/eventlog/eventlog.c | 255 +++++++++++++++++++++++++++-------------
|
|
||||||
2 files changed, 175 insertions(+), 82 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/include/sudo_eventlog.h b/include/sudo_eventlog.h
|
|
||||||
index 49153e173..07ef9dcbe 100644
|
|
||||||
--- a/include/sudo_eventlog.h
|
|
||||||
+++ b/include/sudo_eventlog.h
|
|
||||||
@@ -31,6 +31,7 @@
|
|
||||||
enum event_type {
|
|
||||||
EVLOG_ACCEPT,
|
|
||||||
EVLOG_REJECT,
|
|
||||||
+ EVLOG_EXIT,
|
|
||||||
EVLOG_ALERT
|
|
||||||
};
|
|
||||||
|
|
||||||
@@ -122,6 +123,7 @@ struct json_container;
|
|
||||||
typedef bool (*eventlog_json_callback_t)(struct json_container *, void *);
|
|
||||||
|
|
||||||
bool eventlog_accept(const struct eventlog *evlog, int flags, eventlog_json_callback_t info_cb, void *info);
|
|
||||||
+bool eventlog_exit(const struct eventlog *evlog, int flags, struct timespec *run_time, int exit_value, const char *signal_name, bool core_dumped, eventlog_json_callback_t info_cb, void *info);
|
|
||||||
bool eventlog_alert(const struct eventlog *evlog, int flags, struct timespec *alert_time, const char *reason, const char *errstr);
|
|
||||||
bool eventlog_reject(const struct eventlog *evlog, int flags, const char *reason, eventlog_json_callback_t info_cb, void *info);
|
|
||||||
bool eventlog_store_json(struct json_container *json, const struct eventlog *evlog);
|
|
||||||
diff --git a/lib/eventlog/eventlog.c b/lib/eventlog/eventlog.c
|
|
||||||
index 0c1e74e38..efcd6859d 100644
|
|
||||||
--- a/lib/eventlog/eventlog.c
|
|
||||||
+++ b/lib/eventlog/eventlog.c
|
|
||||||
@@ -66,6 +66,8 @@
|
|
||||||
#define LL_ENV_STR "ENV="
|
|
||||||
#define LL_CMND_STR "COMMAND="
|
|
||||||
#define LL_TSID_STR "TSID="
|
|
||||||
+#define LL_EXIT_STR "EXIT="
|
|
||||||
+#define LL_SIGNAL_STR "SIGNAL="
|
|
||||||
|
|
||||||
#define IS_SESSID(s) ( \
|
|
||||||
isalnum((unsigned char)(s)[0]) && isalnum((unsigned char)(s)[1]) && \
|
|
||||||
@@ -75,28 +77,40 @@
|
|
||||||
isalnum((unsigned char)(s)[6]) && isalnum((unsigned char)(s)[7]) && \
|
|
||||||
(s)[8] == '\0')
|
|
||||||
|
|
||||||
+struct eventlog_args {
|
|
||||||
+ const char *reason;
|
|
||||||
+ const char *errstr;
|
|
||||||
+ const char *signal_name;
|
|
||||||
+ const struct timespec *event_time;
|
|
||||||
+ int exit_value;
|
|
||||||
+ bool core_dumped;
|
|
||||||
+ eventlog_json_callback_t json_info_cb;
|
|
||||||
+ void *json_info;
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
/*
|
|
||||||
* Allocate and fill in a new logline.
|
|
||||||
*/
|
|
||||||
static char *
|
|
||||||
-new_logline(int flags, const char *message, const char *errstr,
|
|
||||||
+new_logline(int event_type, int flags, struct eventlog_args *args,
|
|
||||||
const struct eventlog *evlog)
|
|
||||||
{
|
|
||||||
const struct eventlog_config *evl_conf = eventlog_getconf();
|
|
||||||
char *line = NULL, *evstr = NULL;
|
|
||||||
const char *iolog_file = evlog->iolog_file;
|
|
||||||
const char *tty, *tsid = NULL;
|
|
||||||
+ char exit_str[(((sizeof(int) * 8) + 2) / 3) + 2];
|
|
||||||
char sessid[7];
|
|
||||||
size_t len = 0;
|
|
||||||
int i;
|
|
||||||
debug_decl(new_logline, SUDO_DEBUG_UTIL);
|
|
||||||
|
|
||||||
if (ISSET(flags, EVLOG_RAW)) {
|
|
||||||
- if (errstr != NULL) {
|
|
||||||
- if (asprintf(&line, "%s: %s", message, errstr) == -1)
|
|
||||||
+ if (args->errstr != NULL) {
|
|
||||||
+ if (asprintf(&line, "%s: %s", args->reason, args->errstr) == -1)
|
|
||||||
goto oom;
|
|
||||||
} else {
|
|
||||||
- if ((line = strdup(message)) == NULL)
|
|
||||||
+ if ((line = strdup(args->reason)) == NULL)
|
|
||||||
goto oom;
|
|
||||||
}
|
|
||||||
debug_return_str(line);
|
|
||||||
@@ -127,10 +141,10 @@ new_logline(int flags, const char *message, const char *errstr,
|
|
||||||
/*
|
|
||||||
* Compute line length
|
|
||||||
*/
|
|
||||||
- if (message != NULL)
|
|
||||||
- len += strlen(message) + 3;
|
|
||||||
- if (errstr != NULL)
|
|
||||||
- len += strlen(errstr) + 3;
|
|
||||||
+ if (args->reason != NULL)
|
|
||||||
+ len += strlen(args->reason) + 3;
|
|
||||||
+ if (args->errstr != NULL)
|
|
||||||
+ len += strlen(args->errstr) + 3;
|
|
||||||
if (evlog->submithost != NULL && !evl_conf->omit_hostname)
|
|
||||||
len += sizeof(LL_HOST_STR) + 2 + strlen(evlog->submithost);
|
|
||||||
if (tty != NULL)
|
|
||||||
@@ -171,6 +185,12 @@ new_logline(int flags, const char *message, const char *errstr,
|
|
||||||
for (i = 1; evlog->argv[i] != NULL; i++)
|
|
||||||
len += strlen(evlog->argv[i]) + 1;
|
|
||||||
}
|
|
||||||
+ if (event_type == EVLOG_EXIT) {
|
|
||||||
+ if (args->signal_name != NULL)
|
|
||||||
+ len += sizeof(LL_SIGNAL_STR) + 2 + strlen(args->signal_name);
|
|
||||||
+ (void)snprintf(exit_str, sizeof(exit_str), "%d", args->exit_value);
|
|
||||||
+ len += sizeof(LL_EXIT_STR) + 2 + strlen(exit_str);
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
@@ -180,13 +200,13 @@ new_logline(int flags, const char *message, const char *errstr,
|
|
||||||
goto oom;
|
|
||||||
line[0] = '\0';
|
|
||||||
|
|
||||||
- if (message != NULL) {
|
|
||||||
- if (strlcat(line, message, len) >= len ||
|
|
||||||
- strlcat(line, errstr ? " : " : " ; ", len) >= len)
|
|
||||||
+ if (args->reason != NULL) {
|
|
||||||
+ if (strlcat(line, args->reason, len) >= len ||
|
|
||||||
+ strlcat(line, args->errstr ? " : " : " ; ", len) >= len)
|
|
||||||
goto toobig;
|
|
||||||
}
|
|
||||||
- if (errstr != NULL) {
|
|
||||||
- if (strlcat(line, errstr, len) >= len ||
|
|
||||||
+ if (args->errstr != NULL) {
|
|
||||||
+ if (strlcat(line, args->errstr, len) >= len ||
|
|
||||||
strlcat(line, " ; ", len) >= len)
|
|
||||||
goto toobig;
|
|
||||||
}
|
|
||||||
@@ -252,6 +272,18 @@ new_logline(int flags, const char *message, const char *errstr,
|
|
||||||
goto toobig;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+ if (event_type == EVLOG_EXIT) {
|
|
||||||
+ if (args->signal_name != NULL) {
|
|
||||||
+ if (strlcat(line, " ; ", len) >= len ||
|
|
||||||
+ strlcat(line, LL_SIGNAL_STR, len) >= len ||
|
|
||||||
+ strlcat(line, args->signal_name, len) >= len)
|
|
||||||
+ goto toobig;
|
|
||||||
+ }
|
|
||||||
+ if (strlcat(line, " ; ", len) >= len ||
|
|
||||||
+ strlcat(line, LL_EXIT_STR, len) >= len ||
|
|
||||||
+ strlcat(line, exit_str, len) >= len)
|
|
||||||
+ goto toobig;
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
|
|
||||||
debug_return_str(line);
|
|
||||||
@@ -369,7 +401,7 @@ exec_mailer(int pipein)
|
|
||||||
_exit(127);
|
|
||||||
}
|
|
||||||
|
|
||||||
-/* Send a message to MAILTO user */
|
|
||||||
+/* Send a message to the mailto user */
|
|
||||||
static bool
|
|
||||||
send_mail(const struct eventlog *evlog, const char *fmt, ...)
|
|
||||||
{
|
|
||||||
@@ -548,19 +580,11 @@ send_mail(const struct eventlog *evlog, const char *fmt, ...)
|
|
||||||
|
|
||||||
static bool
|
|
||||||
json_add_timestamp(struct json_container *json, const char *name,
|
|
||||||
- const struct timespec *ts)
|
|
||||||
+ const struct timespec *ts, bool format_timestamp)
|
|
||||||
{
|
|
||||||
- const struct eventlog_config *evl_conf = eventlog_getconf();
|
|
||||||
- const char *timefmt = evl_conf->time_fmt;
|
|
||||||
struct json_value json_value;
|
|
||||||
- time_t secs = ts->tv_sec;
|
|
||||||
- char timebuf[1024];
|
|
||||||
- struct tm *tm;
|
|
||||||
debug_decl(json_add_timestamp, SUDO_DEBUG_PLUGIN);
|
|
||||||
|
|
||||||
- if ((tm = gmtime(&secs)) == NULL)
|
|
||||||
- debug_return_bool(false);
|
|
||||||
-
|
|
||||||
if (!sudo_json_open_object(json, name))
|
|
||||||
goto oom;
|
|
||||||
|
|
||||||
@@ -574,17 +598,27 @@ json_add_timestamp(struct json_container *json, const char *name,
|
|
||||||
if (!sudo_json_add_value(json, "nanoseconds", &json_value))
|
|
||||||
goto oom;
|
|
||||||
|
|
||||||
- strftime(timebuf, sizeof(timebuf), "%Y%m%d%H%M%SZ", tm);
|
|
||||||
- json_value.type = JSON_STRING;
|
|
||||||
- json_value.u.string = timebuf;
|
|
||||||
- if (!sudo_json_add_value(json, "iso8601", &json_value))
|
|
||||||
- goto oom;
|
|
||||||
+ if (format_timestamp) {
|
|
||||||
+ const struct eventlog_config *evl_conf = eventlog_getconf();
|
|
||||||
+ const char *timefmt = evl_conf->time_fmt;
|
|
||||||
+ time_t secs = ts->tv_sec;
|
|
||||||
+ char timebuf[1024];
|
|
||||||
+ struct tm *tm;
|
|
||||||
|
|
||||||
- strftime(timebuf, sizeof(timebuf), timefmt, tm);
|
|
||||||
- json_value.type = JSON_STRING;
|
|
||||||
- json_value.u.string = timebuf;
|
|
||||||
- if (!sudo_json_add_value(json, "localtime", &json_value))
|
|
||||||
- goto oom;
|
|
||||||
+ if ((tm = gmtime(&secs)) != NULL) {
|
|
||||||
+ strftime(timebuf, sizeof(timebuf), "%Y%m%d%H%M%SZ", tm);
|
|
||||||
+ json_value.type = JSON_STRING;
|
|
||||||
+ json_value.u.string = timebuf;
|
|
||||||
+ if (!sudo_json_add_value(json, "iso8601", &json_value))
|
|
||||||
+ goto oom;
|
|
||||||
+
|
|
||||||
+ strftime(timebuf, sizeof(timebuf), timefmt, tm);
|
|
||||||
+ json_value.type = JSON_STRING;
|
|
||||||
+ json_value.u.string = timebuf;
|
|
||||||
+ if (!sudo_json_add_value(json, "localtime", &json_value))
|
|
||||||
+ goto oom;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
|
|
||||||
if (!sudo_json_close_object(json))
|
|
||||||
goto oom;
|
|
||||||
@@ -741,14 +775,15 @@ default_json_cb(struct json_container *json, void *v)
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *
|
|
||||||
-format_json(int event_type, const char *reason, const char *errstr,
|
|
||||||
- const struct eventlog *evlog, const struct timespec *event_time,
|
|
||||||
- eventlog_json_callback_t info_cb, void *info, bool compact)
|
|
||||||
+format_json(int event_type, struct eventlog_args *args,
|
|
||||||
+ const struct eventlog *evlog, bool compact)
|
|
||||||
{
|
|
||||||
- const char *type_str;
|
|
||||||
- const char *time_str;
|
|
||||||
+ eventlog_json_callback_t info_cb = args->json_info_cb;
|
|
||||||
+ void *info = args->json_info;
|
|
||||||
struct json_container json = { 0 };
|
|
||||||
struct json_value json_value;
|
|
||||||
+ const char *time_str, *type_str;
|
|
||||||
+ bool format_timestamp = true;
|
|
||||||
struct timespec now;
|
|
||||||
debug_decl(format_json, SUDO_DEBUG_UTIL);
|
|
||||||
|
|
||||||
@@ -776,6 +811,11 @@ format_json(int event_type, const char *reason, const char *errstr,
|
|
||||||
type_str = "alert";
|
|
||||||
time_str = "alert_time";
|
|
||||||
break;
|
|
||||||
+ case EVLOG_EXIT:
|
|
||||||
+ type_str = "exit";
|
|
||||||
+ time_str = "run_time";
|
|
||||||
+ format_timestamp = false;
|
|
||||||
+ break;
|
|
||||||
default:
|
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
|
||||||
"unexpected event type %d", event_type);
|
|
||||||
@@ -788,18 +828,20 @@ format_json(int event_type, const char *reason, const char *errstr,
|
|
||||||
goto bad;
|
|
||||||
|
|
||||||
/* Reject and Alert events include a reason and optional error string. */
|
|
||||||
- if (reason != NULL) {
|
|
||||||
+ if (args->reason != NULL) {
|
|
||||||
char *ereason = NULL;
|
|
||||||
|
|
||||||
- if (errstr != NULL) {
|
|
||||||
- if (asprintf(&ereason, _("%s: %s"), reason, errstr) == -1) {
|
|
||||||
+ if (args->errstr != NULL) {
|
|
||||||
+ const int len = asprintf(&ereason, _("%s: %s"), args->reason,
|
|
||||||
+ args->errstr);
|
|
||||||
+ if (len == -1) {
|
|
||||||
sudo_warnx(U_("%s: %s"), __func__,
|
|
||||||
U_("unable to allocate memory"));
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
json_value.type = JSON_STRING;
|
|
||||||
- json_value.u.string = ereason ? ereason : reason;
|
|
||||||
+ json_value.u.string = ereason ? ereason : args->reason;
|
|
||||||
if (!sudo_json_add_value(&json, "reason", &json_value)) {
|
|
||||||
free(ereason);
|
|
||||||
goto bad;
|
|
||||||
@@ -810,19 +852,37 @@ format_json(int event_type, const char *reason, const char *errstr,
|
|
||||||
/* XXX - create and log uuid? */
|
|
||||||
|
|
||||||
/* Log event time on server (set earlier) */
|
|
||||||
- if (!json_add_timestamp(&json, "server_time", &now)) {
|
|
||||||
+ if (!json_add_timestamp(&json, "server_time", &now, true)) {
|
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO|SUDO_DEBUG_LINENO,
|
|
||||||
"unable format timestamp");
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Log event time from client */
|
|
||||||
- if (!json_add_timestamp(&json, time_str, event_time)) {
|
|
||||||
+ if (!json_add_timestamp(&json, time_str, args->event_time, format_timestamp)) {
|
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO|SUDO_DEBUG_LINENO,
|
|
||||||
"unable format timestamp");
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ if (event_type == EVLOG_EXIT) {
|
|
||||||
+ if (args->signal_name != NULL) {
|
|
||||||
+ json_value.type = JSON_STRING;
|
|
||||||
+ json_value.u.string = args->signal_name;
|
|
||||||
+ if (!sudo_json_add_value(&json, "signal", &json_value))
|
|
||||||
+ goto bad;
|
|
||||||
+
|
|
||||||
+ json_value.type = JSON_BOOL;
|
|
||||||
+ json_value.u.boolean = args->signal_name;
|
|
||||||
+ if (!sudo_json_add_value(&json, "dumped_core", &json_value))
|
|
||||||
+ goto bad;
|
|
||||||
+ }
|
|
||||||
+ json_value.type = JSON_NUMBER;
|
|
||||||
+ json_value.u.number = args->exit_value;
|
|
||||||
+ if (!sudo_json_add_value(&json, "exit_value", &json_value))
|
|
||||||
+ goto bad;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
/* Event log info may be missing for alert messages. */
|
|
||||||
if (evlog != NULL) {
|
|
||||||
if (evlog->peeraddr != NULL) {
|
|
||||||
@@ -919,18 +979,15 @@ done:
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
|
||||||
-do_syslog_json(int pri, int event_type, const char *reason,
|
|
||||||
- const char *errstr, const struct eventlog *evlog,
|
|
||||||
- const struct timespec *event_time,
|
|
||||||
- eventlog_json_callback_t info_cb, void *info)
|
|
||||||
+do_syslog_json(int pri, int event_type, struct eventlog_args *args,
|
|
||||||
+ const struct eventlog *evlog)
|
|
||||||
{
|
|
||||||
const struct eventlog_config *evl_conf = eventlog_getconf();
|
|
||||||
char *json_str;
|
|
||||||
debug_decl(do_syslog_json, SUDO_DEBUG_UTIL);
|
|
||||||
|
|
||||||
/* Format as a compact JSON message (no newlines) */
|
|
||||||
- json_str = format_json(event_type, reason, errstr, evlog, event_time,
|
|
||||||
- info_cb, info, true);
|
|
||||||
+ json_str = format_json(event_type, args, evlog, true);
|
|
||||||
if (json_str == NULL)
|
|
||||||
debug_return_bool(false);
|
|
||||||
|
|
||||||
@@ -947,9 +1004,8 @@ do_syslog_json(int pri, int event_type, const char *reason,
|
|
||||||
* Log a message to syslog in either sudo or JSON format.
|
|
||||||
*/
|
|
||||||
static bool
|
|
||||||
-do_syslog(int event_type, int flags, const char *reason, const char *errstr,
|
|
||||||
- const struct eventlog *evlog, const struct timespec *event_time,
|
|
||||||
- eventlog_json_callback_t info_cb, void *info)
|
|
||||||
+do_syslog(int event_type, int flags, struct eventlog_args *args,
|
|
||||||
+ const struct eventlog *evlog)
|
|
||||||
{
|
|
||||||
const struct eventlog_config *evl_conf = eventlog_getconf();
|
|
||||||
char *logline = NULL;
|
|
||||||
@@ -959,7 +1015,7 @@ do_syslog(int event_type, int flags, const char *reason, const char *errstr,
|
|
||||||
|
|
||||||
/* Sudo format logs and mailed logs use the same log line format. */
|
|
||||||
if (evl_conf->format == EVLOG_SUDO || ISSET(flags, EVLOG_MAIL)) {
|
|
||||||
- logline = new_logline(flags, reason, errstr, evlog);
|
|
||||||
+ logline = new_logline(event_type, flags, args, evlog);
|
|
||||||
if (logline == NULL)
|
|
||||||
debug_return_bool(false);
|
|
||||||
|
|
||||||
@@ -977,6 +1033,7 @@ do_syslog(int event_type, int flags, const char *reason, const char *errstr,
|
|
||||||
|
|
||||||
switch (event_type) {
|
|
||||||
case EVLOG_ACCEPT:
|
|
||||||
+ case EVLOG_EXIT:
|
|
||||||
pri = evl_conf->syslog_acceptpri;
|
|
||||||
break;
|
|
||||||
case EVLOG_REJECT:
|
|
||||||
@@ -1002,8 +1059,7 @@ do_syslog(int event_type, int flags, const char *reason, const char *errstr,
|
|
||||||
ret = do_syslog_sudo(pri, logline, evlog);
|
|
||||||
break;
|
|
||||||
case EVLOG_JSON:
|
|
||||||
- ret = do_syslog_json(pri, event_type, reason, errstr, evlog,
|
|
||||||
- event_time, info_cb, info);
|
|
||||||
+ ret = do_syslog_json(pri, event_type, args, evlog);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
|
||||||
@@ -1069,9 +1125,8 @@ done:
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
|
||||||
-do_logfile_json(int event_type, const char *reason, const char *errstr,
|
|
||||||
- const struct eventlog *evlog, const struct timespec *event_time,
|
|
||||||
- eventlog_json_callback_t info_cb, void *info)
|
|
||||||
+do_logfile_json(int event_type, struct eventlog_args *args,
|
|
||||||
+ const struct eventlog *evlog)
|
|
||||||
{
|
|
||||||
const struct eventlog_config *evl_conf = eventlog_getconf();
|
|
||||||
const char *logfile = evl_conf->logpath;
|
|
||||||
@@ -1084,8 +1139,7 @@ do_logfile_json(int event_type, const char *reason, const char *errstr,
|
|
||||||
if ((fp = evl_conf->open_log(EVLOG_FILE, logfile)) == NULL)
|
|
||||||
debug_return_bool(false);
|
|
||||||
|
|
||||||
- json_str = format_json(event_type, reason, errstr, evlog, event_time,
|
|
||||||
- info_cb, info, false);
|
|
||||||
+ json_str = format_json(event_type, args, evlog, false);
|
|
||||||
if (json_str == NULL)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
@@ -1127,9 +1181,8 @@ done:
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
|
||||||
-do_logfile(int event_type, int flags, const char *reason, const char *errstr,
|
|
||||||
- const struct eventlog *evlog, const struct timespec *event_time,
|
|
||||||
- eventlog_json_callback_t info_cb, void *info)
|
|
||||||
+do_logfile(int event_type, int flags, struct eventlog_args *args,
|
|
||||||
+ const struct eventlog *evlog)
|
|
||||||
{
|
|
||||||
const struct eventlog_config *evl_conf = eventlog_getconf();
|
|
||||||
bool ret = false;
|
|
||||||
@@ -1138,7 +1191,7 @@ do_logfile(int event_type, int flags, const char *reason, const char *errstr,
|
|
||||||
|
|
||||||
/* Sudo format logs and mailed logs use the same log line format. */
|
|
||||||
if (evl_conf->format == EVLOG_SUDO || ISSET(flags, EVLOG_MAIL)) {
|
|
||||||
- logline = new_logline(flags, reason, errstr, evlog);
|
|
||||||
+ logline = new_logline(event_type, flags, args, evlog);
|
|
||||||
if (logline == NULL)
|
|
||||||
debug_return_bool(false);
|
|
||||||
|
|
||||||
@@ -1156,11 +1209,11 @@ do_logfile(int event_type, int flags, const char *reason, const char *errstr,
|
|
||||||
|
|
||||||
switch (evl_conf->format) {
|
|
||||||
case EVLOG_SUDO:
|
|
||||||
- ret = do_logfile_sudo(logline ? logline : reason, evlog, event_time);
|
|
||||||
+ ret = do_logfile_sudo(logline ? logline : args->reason, evlog,
|
|
||||||
+ args->event_time);
|
|
||||||
break;
|
|
||||||
case EVLOG_JSON:
|
|
||||||
- ret = do_logfile_json(event_type, reason, errstr, evlog,
|
|
||||||
- event_time, info_cb, info);
|
|
||||||
+ ret = do_logfile_json(event_type, args, evlog);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
|
||||||
@@ -1178,21 +1231,21 @@ eventlog_accept(const struct eventlog *evlog, int flags,
|
|
||||||
{
|
|
||||||
const struct eventlog_config *evl_conf = eventlog_getconf();
|
|
||||||
const int log_type = evl_conf->type;
|
|
||||||
+ struct eventlog_args args = { NULL };
|
|
||||||
bool ret = true;
|
|
||||||
debug_decl(log_accept, SUDO_DEBUG_UTIL);
|
|
||||||
|
|
||||||
- if (log_type == EVLOG_NONE)
|
|
||||||
- debug_return_bool(true);
|
|
||||||
+ args.event_time = &evlog->submit_time;
|
|
||||||
+ args.json_info_cb = info_cb;
|
|
||||||
+ args.json_info = info;
|
|
||||||
|
|
||||||
if (ISSET(log_type, EVLOG_SYSLOG)) {
|
|
||||||
- if (!do_syslog(EVLOG_ACCEPT, flags, NULL, NULL, evlog,
|
|
||||||
- &evlog->submit_time, info_cb, info))
|
|
||||||
+ if (!do_syslog(EVLOG_ACCEPT, flags, &args, evlog))
|
|
||||||
ret = false;
|
|
||||||
CLR(flags, EVLOG_MAIL);
|
|
||||||
}
|
|
||||||
if (ISSET(log_type, EVLOG_FILE)) {
|
|
||||||
- if (!do_logfile(EVLOG_ACCEPT, flags, NULL, NULL, evlog,
|
|
||||||
- &evlog->submit_time, info_cb, info))
|
|
||||||
+ if (!do_logfile(EVLOG_ACCEPT, flags, &args, evlog))
|
|
||||||
ret = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1205,18 +1258,22 @@ eventlog_reject(const struct eventlog *evlog, int flags, const char *reason,
|
|
||||||
{
|
|
||||||
const struct eventlog_config *evl_conf = eventlog_getconf();
|
|
||||||
const int log_type = evl_conf->type;
|
|
||||||
+ struct eventlog_args args = { NULL };
|
|
||||||
bool ret = true;
|
|
||||||
debug_decl(log_reject, SUDO_DEBUG_UTIL);
|
|
||||||
|
|
||||||
+ args.reason = reason;
|
|
||||||
+ args.event_time = &evlog->submit_time;
|
|
||||||
+ args.json_info_cb = info_cb;
|
|
||||||
+ args.json_info = info;
|
|
||||||
+
|
|
||||||
if (ISSET(log_type, EVLOG_SYSLOG)) {
|
|
||||||
- if (!do_syslog(EVLOG_REJECT, flags, reason, NULL, evlog,
|
|
||||||
- &evlog->submit_time, info_cb, info))
|
|
||||||
+ if (!do_syslog(EVLOG_REJECT, flags, &args, evlog))
|
|
||||||
ret = false;
|
|
||||||
CLR(flags, EVLOG_MAIL);
|
|
||||||
}
|
|
||||||
if (ISSET(log_type, EVLOG_FILE)) {
|
|
||||||
- if (!do_logfile(EVLOG_REJECT, flags, reason, NULL, evlog,
|
|
||||||
- &evlog->submit_time, info_cb, info))
|
|
||||||
+ if (!do_logfile(EVLOG_REJECT, flags, &args, evlog))
|
|
||||||
ret = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1229,18 +1286,52 @@ eventlog_alert(const struct eventlog *evlog, int flags,
|
|
||||||
{
|
|
||||||
const struct eventlog_config *evl_conf = eventlog_getconf();
|
|
||||||
const int log_type = evl_conf->type;
|
|
||||||
+ struct eventlog_args args = { NULL };
|
|
||||||
bool ret = true;
|
|
||||||
debug_decl(log_alert, SUDO_DEBUG_UTIL);
|
|
||||||
|
|
||||||
+ args.reason = reason;
|
|
||||||
+ args.errstr = errstr;
|
|
||||||
+ args.event_time = alert_time;
|
|
||||||
+
|
|
||||||
+ if (ISSET(log_type, EVLOG_SYSLOG)) {
|
|
||||||
+ if (!do_syslog(EVLOG_ALERT, flags, &args, evlog))
|
|
||||||
+ ret = false;
|
|
||||||
+ CLR(flags, EVLOG_MAIL);
|
|
||||||
+ }
|
|
||||||
+ if (ISSET(log_type, EVLOG_FILE)) {
|
|
||||||
+ if (!do_logfile(EVLOG_ALERT, flags, &args, evlog))
|
|
||||||
+ ret = false;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ debug_return_bool(ret);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+bool
|
|
||||||
+eventlog_exit(const struct eventlog *evlog, int flags,
|
|
||||||
+ struct timespec *run_time, int exit_value, const char *signal_name,
|
|
||||||
+ bool core_dumped, eventlog_json_callback_t info_cb, void *info)
|
|
||||||
+{
|
|
||||||
+ const struct eventlog_config *evl_conf = eventlog_getconf();
|
|
||||||
+ const int log_type = evl_conf->type;
|
|
||||||
+ struct eventlog_args args = { NULL };
|
|
||||||
+ bool ret = true;
|
|
||||||
+ debug_decl(eventlog_exit, SUDO_DEBUG_UTIL);
|
|
||||||
+
|
|
||||||
+ args.signal_name = signal_name;
|
|
||||||
+ args.core_dumped = core_dumped;
|
|
||||||
+ args.exit_value = exit_value;
|
|
||||||
+ args.event_time = run_time;
|
|
||||||
+ args.json_info_cb = info_cb;
|
|
||||||
+ args.json_info = info;
|
|
||||||
+
|
|
||||||
if (ISSET(log_type, EVLOG_SYSLOG)) {
|
|
||||||
- if (!do_syslog(EVLOG_ALERT, flags, reason, errstr, evlog, alert_time,
|
|
||||||
- NULL, NULL))
|
|
||||||
+ if (!do_syslog(EVLOG_EXIT, flags, &args, evlog))
|
|
||||||
ret = false;
|
|
||||||
CLR(flags, EVLOG_MAIL);
|
|
||||||
}
|
|
||||||
if (ISSET(log_type, EVLOG_FILE)) {
|
|
||||||
- if (!do_logfile(EVLOG_ALERT, flags, reason, errstr, evlog, alert_time,
|
|
||||||
- NULL, NULL))
|
|
||||||
+ if (!do_logfile(EVLOG_EXIT, flags, &args, evlog))
|
|
||||||
ret = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
--
|
|
||||||
2.43.0
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
|||||||
From d109cd61d9ff01053f1d43b7d4fc0e5e657c8da3 Mon Sep 17 00:00:00 2001
|
|
||||||
From: "Todd C. Miller" <Todd.Miller@sudo.ws>
|
|
||||||
Date: Tue, 27 Jul 2021 12:19:53 -0600
|
|
||||||
Subject: [PATCH] In new_logline check for NULL args->reason for EVLOG_RAW.
|
|
||||||
This can't happen in practice since we never set EVLOG_RAW without passing in
|
|
||||||
a reason. Coverity CID 237142 237143
|
|
||||||
|
|
||||||
---
|
|
||||||
lib/eventlog/eventlog.c | 14 ++++++++------
|
|
||||||
1 file changed, 8 insertions(+), 6 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/lib/eventlog/eventlog.c b/lib/eventlog/eventlog.c
|
|
||||||
index 280be7fcf..26c5f6dc7 100644
|
|
||||||
--- a/lib/eventlog/eventlog.c
|
|
||||||
+++ b/lib/eventlog/eventlog.c
|
|
||||||
@@ -106,12 +106,14 @@ new_logline(int event_type, int flags, struct eventlog_args *args,
|
|
||||||
debug_decl(new_logline, SUDO_DEBUG_UTIL);
|
|
||||||
|
|
||||||
if (ISSET(flags, EVLOG_RAW)) {
|
|
||||||
- if (args->errstr != NULL) {
|
|
||||||
- if (asprintf(&line, "%s: %s", args->reason, args->errstr) == -1)
|
|
||||||
- goto oom;
|
|
||||||
- } else {
|
|
||||||
- if ((line = strdup(args->reason)) == NULL)
|
|
||||||
- goto oom;
|
|
||||||
+ if (args->reason != NULL) {
|
|
||||||
+ if (args->errstr != NULL) {
|
|
||||||
+ if (asprintf(&line, "%s: %s", args->reason, args->errstr) == -1)
|
|
||||||
+ goto oom;
|
|
||||||
+ } else {
|
|
||||||
+ if ((line = strdup(args->reason)) == NULL)
|
|
||||||
+ goto oom;
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
debug_return_str(line);
|
|
||||||
}
|
|
||||||
--
|
|
||||||
2.43.0
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
|||||||
From babb498c6ebe09723a751127b104f43ab643ee91 Mon Sep 17 00:00:00 2001
|
|
||||||
From: "Todd C. Miller" <Todd.Miller@sudo.ws>
|
|
||||||
Date: Sat, 14 Aug 2021 09:24:39 -0600
|
|
||||||
Subject: [PATCH] new_logline: handle case where evlog is NULL
|
|
||||||
|
|
||||||
---
|
|
||||||
lib/eventlog/eventlog.c | 5 +++--
|
|
||||||
1 file changed, 3 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/lib/eventlog/eventlog.c b/lib/eventlog/eventlog.c
|
|
||||||
index 255ef1bbf..7f55859b6 100644
|
|
||||||
--- a/lib/eventlog/eventlog.c
|
|
||||||
+++ b/lib/eventlog/eventlog.c
|
|
||||||
@@ -97,7 +97,7 @@ new_logline(int event_type, int flags, struct eventlog_args *args,
|
|
||||||
{
|
|
||||||
const struct eventlog_config *evl_conf = eventlog_getconf();
|
|
||||||
char *line = NULL, *evstr = NULL;
|
|
||||||
- const char *iolog_file = evlog->iolog_file;
|
|
||||||
+ const char *iolog_file;
|
|
||||||
const char *tty, *tsid = NULL;
|
|
||||||
char exit_str[(((sizeof(int) * 8) + 2) / 3) + 2];
|
|
||||||
char sessid[7];
|
|
||||||
@@ -105,7 +105,7 @@ new_logline(int event_type, int flags, struct eventlog_args *args,
|
|
||||||
int i;
|
|
||||||
debug_decl(new_logline, SUDO_DEBUG_UTIL);
|
|
||||||
|
|
||||||
- if (ISSET(flags, EVLOG_RAW)) {
|
|
||||||
+ if (ISSET(flags, EVLOG_RAW) || evlog == NULL) {
|
|
||||||
if (args->reason != NULL) {
|
|
||||||
if (args->errstr != NULL) {
|
|
||||||
if (asprintf(&line, "%s: %s", args->reason, args->errstr) == -1)
|
|
||||||
@@ -119,6 +119,7 @@ new_logline(int event_type, int flags, struct eventlog_args *args,
|
|
||||||
}
|
|
||||||
|
|
||||||
/* A TSID may be a sudoers-style session ID or a free-form string. */
|
|
||||||
+ iolog_file = evlog->iolog_file;
|
|
||||||
if (iolog_file != NULL) {
|
|
||||||
if (IS_SESSID(iolog_file)) {
|
|
||||||
sessid[0] = iolog_file[0];
|
|
||||||
--
|
|
||||||
2.43.0
|
|
||||||
|
|
@ -1,56 +0,0 @@
|
|||||||
From 4e4b506f22006c485c7ce557c9905dae16c5c12e Mon Sep 17 00:00:00 2001
|
|
||||||
From: "Todd C. Miller" <Todd.Miller@sudo.ws>
|
|
||||||
Date: Fri, 1 Oct 2021 10:33:55 -0600
|
|
||||||
Subject: [PATCH] Sync "sudo -l" output with normal sudo log format. It now
|
|
||||||
prints runchroot and runcwd (falling back on cwd). As a result, submithost is
|
|
||||||
now printed first, matching sudo. Also avoid printing NULL pointers and skip
|
|
||||||
entries that don't have at least command, submituser and runuser set.
|
|
||||||
|
|
||||||
---
|
|
||||||
plugins/sudoers/sudoreplay.c | 22 ++++++++++++++++------
|
|
||||||
1 file changed, 16 insertions(+), 6 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/plugins/sudoers/sudoreplay.c b/plugins/sudoers/sudoreplay.c
|
|
||||||
index f32d44eb5..786aae30d 100644
|
|
||||||
--- a/plugins/sudoers/sudoreplay.c
|
|
||||||
+++ b/plugins/sudoers/sudoreplay.c
|
|
||||||
@@ -1388,6 +1388,11 @@ list_session(char *log_dir, regex_t *re, const char *user, const char *tty)
|
|
||||||
if ((evlog = iolog_parse_loginfo(-1, log_dir)) == NULL)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
+ if (evlog->command == NULL || evlog->submituser == NULL ||
|
|
||||||
+ evlog->runuser == NULL) {
|
|
||||||
+ goto done;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
/* Match on search expression if there is one. */
|
|
||||||
if (!STAILQ_EMPTY(&search_expr) && !match_expr(&search_expr, evlog, true))
|
|
||||||
goto done;
|
|
||||||
@@ -1409,13 +1414,18 @@ list_session(char *log_dir, regex_t *re, const char *user, const char *tty)
|
|
||||||
}
|
|
||||||
/* XXX - print lines + cols? */
|
|
||||||
timestr = get_timestr(evlog->submit_time.tv_sec, 1);
|
|
||||||
- printf("%s : %s : TTY=%s ; CWD=%s ; USER=%s ; ",
|
|
||||||
- timestr ? timestr : "invalid date",
|
|
||||||
- evlog->submituser, evlog->ttyname, evlog->cwd, evlog->runuser);
|
|
||||||
- if (evlog->rungroup)
|
|
||||||
- printf("GROUP=%s ; ", evlog->rungroup);
|
|
||||||
- if (evlog->submithost)
|
|
||||||
+ printf("%s : %s : ", timestr ? timestr : "invalid date", evlog->submituser);
|
|
||||||
+ if (evlog->submithost != NULL)
|
|
||||||
printf("HOST=%s ; ", evlog->submithost);
|
|
||||||
+ if (evlog->ttyname != NULL)
|
|
||||||
+ printf("TTY=%s ; ", evlog->ttyname);
|
|
||||||
+ if (evlog->runchroot != NULL)
|
|
||||||
+ printf("CHROOT=%s ; ", evlog->runchroot);
|
|
||||||
+ if (evlog->runcwd != NULL || evlog->cwd != NULL)
|
|
||||||
+ printf("CWD=%s ; ", evlog->runcwd ? evlog->runcwd : evlog->cwd);
|
|
||||||
+ printf("USER=%s ; ", evlog->runuser);
|
|
||||||
+ if (evlog->rungroup != NULL)
|
|
||||||
+ printf("GROUP=%s ; ", evlog->rungroup);
|
|
||||||
printf("TSID=%s ; COMMAND=%s\n", idstr, evlog->command);
|
|
||||||
|
|
||||||
ret = 0;
|
|
||||||
--
|
|
||||||
2.43.0
|
|
||||||
|
|
@ -1,910 +0,0 @@
|
|||||||
diff -up ./doc/sudoers.man.in.cve ./doc/sudoers.man.in
|
|
||||||
--- ./doc/sudoers.man.in.cve 2021-01-09 21:12:16.000000000 +0100
|
|
||||||
+++ ./doc/sudoers.man.in 2023-12-04 16:52:54.499061280 +0100
|
|
||||||
@@ -4978,14 +4978,31 @@ can log events via
|
|
||||||
syslog(3),
|
|
||||||
to a local log file, or both.
|
|
||||||
The log format is almost identical in both cases.
|
|
||||||
+Any control characters present in the log data are formatted in octal
|
|
||||||
+with a leading
|
|
||||||
+\(oq#\(cq
|
|
||||||
+character.
|
|
||||||
+For example, a horizontal tab is stored as
|
|
||||||
+\(oq#011\(cq
|
|
||||||
+and an embedded carriage return is stored as
|
|
||||||
+\(oq#015\(cq.
|
|
||||||
+In addition, space characters in the command path are stored as
|
|
||||||
+\(oq#040\(cq.
|
|
||||||
+Command line arguments that contain spaces are enclosed in single quotes
|
|
||||||
+('').
|
|
||||||
+This makes it possible to distinguish multiple command line arguments
|
|
||||||
+from a single argument that contains spaces.
|
|
||||||
+Literal single quotes and backslash characters
|
|
||||||
+(\(oq\e\(cq)
|
|
||||||
+in command line arguments are escaped with a backslash.
|
|
||||||
.SS "Accepted command log entries"
|
|
||||||
Commands that sudo runs are logged using the following format (split
|
|
||||||
into multiple lines for readability):
|
|
||||||
.nf
|
|
||||||
.sp
|
|
||||||
.RS 4n
|
|
||||||
-date hostname progname: username : TTY=ttyname ; PWD=cwd ; \e
|
|
||||||
- USER=runasuser ; GROUP=runasgroup ; TSID=logid ; \e
|
|
||||||
+date hostname progname: username : TTY=ttyname ; CHROOT=chroot ; \e
|
|
||||||
+ PWD=cwd ; USER=runasuser ; GROUP=runasgroup ; TSID=logid ; \e
|
|
||||||
ENV=env_vars COMMAND=command
|
|
||||||
.RE
|
|
||||||
.fi
|
|
||||||
@@ -5034,6 +5051,9 @@ was run on, or
|
|
||||||
\(lqunknown\(rq
|
|
||||||
if there was no terminal present.
|
|
||||||
.TP 14n
|
|
||||||
+chroot
|
|
||||||
+The root directory that the command was run in, if one was specified.
|
|
||||||
+.TP 14n
|
|
||||||
cwd
|
|
||||||
The current working directory that
|
|
||||||
\fBsudo\fR
|
|
||||||
@@ -5058,7 +5078,7 @@ A list of environment variables specifie
|
|
||||||
if specified.
|
|
||||||
.TP 14n
|
|
||||||
command
|
|
||||||
-The actual command that was executed.
|
|
||||||
+The actual command that was executed, including any command line arguments.
|
|
||||||
.PP
|
|
||||||
Messages are logged using the locale specified by
|
|
||||||
\fIsudoers_locale\fR,
|
|
||||||
@@ -5294,17 +5314,21 @@ with a few important differences:
|
|
||||||
1.\&
|
|
||||||
The
|
|
||||||
\fIprogname\fR
|
|
||||||
-and
|
|
||||||
-\fIhostname\fR
|
|
||||||
-fields are not present.
|
|
||||||
+field is not present.
|
|
||||||
.TP 5n
|
|
||||||
2.\&
|
|
||||||
-If the
|
|
||||||
-\fIlog_year\fR
|
|
||||||
-option is enabled,
|
|
||||||
-the date will also include the year.
|
|
||||||
+The
|
|
||||||
+\fIhostname\fR
|
|
||||||
+is only logged if the
|
|
||||||
+\fIlog_host\fR
|
|
||||||
+option is enabled.
|
|
||||||
.TP 5n
|
|
||||||
3.\&
|
|
||||||
+The date does not include the year unless the
|
|
||||||
+\fIlog_year\fR
|
|
||||||
+option is enabled.
|
|
||||||
+.TP 5n
|
|
||||||
+4.\&
|
|
||||||
Lines that are longer than
|
|
||||||
\fIloglinelen\fR
|
|
||||||
characters (80 by default) are word-wrapped and continued on the
|
|
||||||
diff -up ./doc/sudoers.mdoc.in.cve ./doc/sudoers.mdoc.in
|
|
||||||
--- ./doc/sudoers.mdoc.in.cve 2021-01-09 21:12:16.000000000 +0100
|
|
||||||
+++ ./doc/sudoers.mdoc.in 2023-12-04 16:52:54.500061266 +0100
|
|
||||||
@@ -4649,12 +4649,29 @@ can log events via
|
|
||||||
.Xr syslog 3 ,
|
|
||||||
to a local log file, or both.
|
|
||||||
The log format is almost identical in both cases.
|
|
||||||
+Any control characters present in the log data are formatted in octal
|
|
||||||
+with a leading
|
|
||||||
+.Ql #
|
|
||||||
+character.
|
|
||||||
+For example, a horizontal tab is stored as
|
|
||||||
+.Ql #011
|
|
||||||
+and an embedded carriage return is stored as
|
|
||||||
+.Ql #015 .
|
|
||||||
+In addition, space characters in the command path are stored as
|
|
||||||
+.Ql #040 .
|
|
||||||
+Command line arguments that contain spaces are enclosed in single quotes
|
|
||||||
+.Pq '' .
|
|
||||||
+This makes it possible to distinguish multiple command line arguments
|
|
||||||
+from a single argument that contains spaces.
|
|
||||||
+Literal single quotes and backslash characters
|
|
||||||
+.Pq Ql \e
|
|
||||||
+in command line arguments are escaped with a backslash.
|
|
||||||
.Ss Accepted command log entries
|
|
||||||
Commands that sudo runs are logged using the following format (split
|
|
||||||
into multiple lines for readability):
|
|
||||||
.Bd -literal -offset 4n
|
|
||||||
-date hostname progname: username : TTY=ttyname ; PWD=cwd ; \e
|
|
||||||
- USER=runasuser ; GROUP=runasgroup ; TSID=logid ; \e
|
|
||||||
+date hostname progname: username : TTY=ttyname ; CHROOT=chroot ; \e
|
|
||||||
+ PWD=cwd ; USER=runasuser ; GROUP=runasgroup ; TSID=logid ; \e
|
|
||||||
ENV=env_vars COMMAND=command
|
|
||||||
.Ed
|
|
||||||
.Pp
|
|
||||||
@@ -4697,6 +4714,8 @@ or
|
|
||||||
was run on, or
|
|
||||||
.Dq unknown
|
|
||||||
if there was no terminal present.
|
|
||||||
+.It chroot
|
|
||||||
+The root directory that the command was run in, if one was specified.
|
|
||||||
.It cwd
|
|
||||||
The current working directory that
|
|
||||||
.Nm sudo
|
|
||||||
@@ -4716,7 +4735,7 @@ option is enabled.
|
|
||||||
A list of environment variables specified on the command line,
|
|
||||||
if specified.
|
|
||||||
.It command
|
|
||||||
-The actual command that was executed.
|
|
||||||
+The actual command that was executed, including any command line arguments.
|
|
||||||
.El
|
|
||||||
.Pp
|
|
||||||
Messages are logged using the locale specified by
|
|
||||||
@@ -4938,14 +4957,17 @@ with a few important differences:
|
|
||||||
.It
|
|
||||||
The
|
|
||||||
.Em progname
|
|
||||||
-and
|
|
||||||
+field is not present.
|
|
||||||
+.It
|
|
||||||
+The
|
|
||||||
.Em hostname
|
|
||||||
-fields are not present.
|
|
||||||
+is only logged if the
|
|
||||||
+.Em log_host
|
|
||||||
+option is enabled.
|
|
||||||
.It
|
|
||||||
-If the
|
|
||||||
+The date does not include the year unless the
|
|
||||||
.Em log_year
|
|
||||||
-option is enabled,
|
|
||||||
-the date will also include the year.
|
|
||||||
+option is enabled.
|
|
||||||
.It
|
|
||||||
Lines that are longer than
|
|
||||||
.Em loglinelen
|
|
||||||
diff -up ./doc/sudoreplay.man.in.cve ./doc/sudoreplay.man.in
|
|
||||||
--- ./doc/sudoreplay.man.in.cve 2020-12-17 02:33:43.000000000 +0100
|
|
||||||
+++ ./doc/sudoreplay.man.in 2023-12-04 16:52:54.500061266 +0100
|
|
||||||
@@ -164,6 +164,15 @@ In this mode,
|
|
||||||
will list available sessions in a format similar to the
|
|
||||||
\fBsudo\fR
|
|
||||||
log file format, sorted by file name (or sequence number).
|
|
||||||
+Any control characters present in the log data are formated in octal
|
|
||||||
+with a leading
|
|
||||||
+\(oq#\(cq
|
|
||||||
+character.
|
|
||||||
+For example, a horizontal tab is displayed as
|
|
||||||
+\(oq#011\(cq
|
|
||||||
+and an embedded carriage return is displayed as
|
|
||||||
+\(oq#015\(cq.
|
|
||||||
+.sp
|
|
||||||
If a
|
|
||||||
\fIsearch expression\fR
|
|
||||||
is specified, it will be used to restrict the IDs that are displayed.
|
|
||||||
diff -up ./doc/sudoreplay.mdoc.in.cve ./doc/sudoreplay.mdoc.in
|
|
||||||
--- ./doc/sudoreplay.mdoc.in.cve 2020-12-17 02:33:43.000000000 +0100
|
|
||||||
+++ ./doc/sudoreplay.mdoc.in 2023-12-04 16:52:54.500061266 +0100
|
|
||||||
@@ -156,6 +156,16 @@ In this mode,
|
|
||||||
will list available sessions in a format similar to the
|
|
||||||
.Nm sudo
|
|
||||||
log file format, sorted by file name (or sequence number).
|
|
||||||
+Any control characters present in the log data are formatted in octal
|
|
||||||
+with a leading
|
|
||||||
+.Ql #
|
|
||||||
+character.
|
|
||||||
+For example, a horizontal tab is displayed as
|
|
||||||
+.Ql #011
|
|
||||||
+and an embedded carriage return is displayed as
|
|
||||||
+.Ql #015 .
|
|
||||||
+Space characters in the command name and arguments are also formatted in octal.
|
|
||||||
+.Pp
|
|
||||||
If a
|
|
||||||
.Ar search expression
|
|
||||||
is specified, it will be used to restrict the IDs that are displayed.
|
|
||||||
diff -up ./include/sudo_lbuf.h.cve ./include/sudo_lbuf.h
|
|
||||||
--- ./include/sudo_lbuf.h.cve 2020-12-17 02:33:43.000000000 +0100
|
|
||||||
+++ ./include/sudo_lbuf.h 2023-12-04 16:52:54.500061266 +0100
|
|
||||||
@@ -36,9 +36,15 @@ struct sudo_lbuf {
|
|
||||||
|
|
||||||
typedef int (*sudo_lbuf_output_t)(const char *);
|
|
||||||
|
|
||||||
+/* Flags for sudo_lbuf_append_esc() */
|
|
||||||
+#define LBUF_ESC_CNTRL 0x01
|
|
||||||
+#define LBUF_ESC_BLANK 0x02
|
|
||||||
+#define LBUF_ESC_QUOTE 0x04
|
|
||||||
+
|
|
||||||
sudo_dso_public void sudo_lbuf_init_v1(struct sudo_lbuf *lbuf, sudo_lbuf_output_t output, int indent, const char *continuation, int cols);
|
|
||||||
sudo_dso_public void sudo_lbuf_destroy_v1(struct sudo_lbuf *lbuf);
|
|
||||||
sudo_dso_public bool sudo_lbuf_append_v1(struct sudo_lbuf *lbuf, const char *fmt, ...) __printflike(2, 3);
|
|
||||||
+sudo_dso_public bool sudo_lbuf_append_esc_v1(struct sudo_lbuf *lbuf, int flags, const char *fmt, ...) __printflike(3, 4);
|
|
||||||
sudo_dso_public bool sudo_lbuf_append_quoted_v1(struct sudo_lbuf *lbuf, const char *set, const char *fmt, ...) __printflike(3, 4);
|
|
||||||
sudo_dso_public void sudo_lbuf_print_v1(struct sudo_lbuf *lbuf);
|
|
||||||
sudo_dso_public bool sudo_lbuf_error_v1(struct sudo_lbuf *lbuf);
|
|
||||||
@@ -47,6 +53,7 @@ sudo_dso_public void sudo_lbuf_clearerr_
|
|
||||||
#define sudo_lbuf_init(_a, _b, _c, _d, _e) sudo_lbuf_init_v1((_a), (_b), (_c), (_d), (_e))
|
|
||||||
#define sudo_lbuf_destroy(_a) sudo_lbuf_destroy_v1((_a))
|
|
||||||
#define sudo_lbuf_append sudo_lbuf_append_v1
|
|
||||||
+#define sudo_lbuf_append_esc sudo_lbuf_append_esc_v1
|
|
||||||
#define sudo_lbuf_append_quoted sudo_lbuf_append_quoted_v1
|
|
||||||
#define sudo_lbuf_print(_a) sudo_lbuf_print_v1((_a))
|
|
||||||
#define sudo_lbuf_error(_a) sudo_lbuf_error_v1((_a))
|
|
||||||
diff -up ./lib/eventlog/eventlog.c.cve ./lib/eventlog/eventlog.c
|
|
||||||
--- ./lib/eventlog/eventlog.c.cve 2023-12-04 16:52:54.497061306 +0100
|
|
||||||
+++ ./lib/eventlog/eventlog.c 2023-12-04 16:54:09.820048779 +0100
|
|
||||||
@@ -51,24 +51,13 @@
|
|
||||||
#include "sudo_compat.h"
|
|
||||||
#include "sudo_debug.h"
|
|
||||||
#include "sudo_eventlog.h"
|
|
||||||
+#include "sudo_lbuf.h"
|
|
||||||
#include "sudo_fatal.h"
|
|
||||||
#include "sudo_gettext.h"
|
|
||||||
#include "sudo_json.h"
|
|
||||||
#include "sudo_queue.h"
|
|
||||||
#include "sudo_util.h"
|
|
||||||
|
|
||||||
-#define LL_HOST_STR "HOST="
|
|
||||||
-#define LL_TTY_STR "TTY="
|
|
||||||
-#define LL_CHROOT_STR "CHROOT="
|
|
||||||
-#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 LL_EXIT_STR "EXIT="
|
|
||||||
-#define LL_SIGNAL_STR "SIGNAL="
|
|
||||||
-
|
|
||||||
#define IS_SESSID(s) ( \
|
|
||||||
isalnum((unsigned char)(s)[0]) && isalnum((unsigned char)(s)[1]) && \
|
|
||||||
(s)[2] == '/' && \
|
|
||||||
@@ -96,26 +85,28 @@ new_logline(int event_type, int flags, s
|
|
||||||
const struct eventlog *evlog)
|
|
||||||
{
|
|
||||||
const struct eventlog_config *evl_conf = eventlog_getconf();
|
|
||||||
- char *line = NULL, *evstr = NULL;
|
|
||||||
const char *iolog_file;
|
|
||||||
const char *tty, *tsid = NULL;
|
|
||||||
char exit_str[(((sizeof(int) * 8) + 2) / 3) + 2];
|
|
||||||
char sessid[7];
|
|
||||||
- size_t len = 0;
|
|
||||||
+ struct sudo_lbuf lbuf;
|
|
||||||
int i;
|
|
||||||
debug_decl(new_logline, SUDO_DEBUG_UTIL);
|
|
||||||
|
|
||||||
+ sudo_lbuf_init(&lbuf, NULL, 0, NULL, 0);
|
|
||||||
+
|
|
||||||
if (ISSET(flags, EVLOG_RAW) || evlog == NULL) {
|
|
||||||
if (args->reason != NULL) {
|
|
||||||
if (args->errstr != NULL) {
|
|
||||||
- if (asprintf(&line, "%s: %s", args->reason, args->errstr) == -1)
|
|
||||||
- goto oom;
|
|
||||||
+ sudo_lbuf_append_esc(&lbuf, LBUF_ESC_CNTRL, "%s: %s",
|
|
||||||
+ args->reason, args->errstr);
|
|
||||||
} else {
|
|
||||||
- if ((line = strdup(args->reason)) == NULL)
|
|
||||||
- goto oom;
|
|
||||||
+ sudo_lbuf_append_esc(&lbuf, LBUF_ESC_CNTRL, "%s", args->reason);
|
|
||||||
}
|
|
||||||
+ if (sudo_lbuf_error(&lbuf))
|
|
||||||
+ goto oom;
|
|
||||||
}
|
|
||||||
- debug_return_str(line);
|
|
||||||
+ debug_return_str(lbuf.buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* A TSID may be a sudoers-style session ID or a free-form string. */
|
|
||||||
@@ -142,163 +133,92 @@ new_logline(int event_type, int flags, s
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
- * Compute line length
|
|
||||||
+ * Format the log line as an lbuf, escaping control characters is
|
|
||||||
+ * octal form (#0nn). Error checking (ENOMEM) is done at the end
|
|
||||||
*/
|
|
||||||
- if (args->reason != NULL)
|
|
||||||
- len += strlen(args->reason) + 3;
|
|
||||||
- if (args->errstr != NULL)
|
|
||||||
- len += strlen(args->errstr) + 3;
|
|
||||||
- if (evlog->submithost != NULL && !evl_conf->omit_hostname)
|
|
||||||
- len += sizeof(LL_HOST_STR) + 2 + strlen(evlog->submithost);
|
|
||||||
- if (tty != NULL)
|
|
||||||
- len += sizeof(LL_TTY_STR) + 2 + strlen(tty);
|
|
||||||
- if (evlog->runchroot != NULL)
|
|
||||||
- len += sizeof(LL_CHROOT_STR) + 2 + strlen(evlog->runchroot);
|
|
||||||
- if (evlog->runcwd != NULL)
|
|
||||||
- len += sizeof(LL_CWD_STR) + 2 + strlen(evlog->runcwd);
|
|
||||||
- if (evlog->runuser != NULL)
|
|
||||||
- len += sizeof(LL_USER_STR) + 2 + strlen(evlog->runuser);
|
|
||||||
- if (evlog->rungroup != NULL)
|
|
||||||
- len += sizeof(LL_GROUP_STR) + 2 + strlen(evlog->rungroup);
|
|
||||||
- if (tsid != NULL)
|
|
||||||
- len += sizeof(LL_TSID_STR) + 2 + strlen(tsid);
|
|
||||||
- if (evlog->env_add != NULL) {
|
|
||||||
- size_t evlen = 0;
|
|
||||||
- char * const *ep;
|
|
||||||
-
|
|
||||||
- for (ep = evlog->env_add; *ep != NULL; ep++)
|
|
||||||
- evlen += strlen(*ep) + 1;
|
|
||||||
- if (evlen != 0) {
|
|
||||||
- if ((evstr = malloc(evlen)) == NULL)
|
|
||||||
- goto oom;
|
|
||||||
- ep = evlog->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 (evlog->command != NULL) {
|
|
||||||
- len += sizeof(LL_CMND_STR) - 1 + strlen(evlog->command);
|
|
||||||
- if (evlog->argv != NULL) {
|
|
||||||
- for (i = 1; evlog->argv[i] != NULL; i++)
|
|
||||||
- len += strlen(evlog->argv[i]) + 1;
|
|
||||||
- }
|
|
||||||
- if (event_type == EVLOG_EXIT) {
|
|
||||||
- if (args->signal_name != NULL)
|
|
||||||
- len += sizeof(LL_SIGNAL_STR) + 2 + strlen(args->signal_name);
|
|
||||||
- (void)snprintf(exit_str, sizeof(exit_str), "%d", args->exit_value);
|
|
||||||
- len += sizeof(LL_EXIT_STR) + 2 + strlen(exit_str);
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- /*
|
|
||||||
- * Allocate and build up the line.
|
|
||||||
- */
|
|
||||||
- if ((line = malloc(++len)) == NULL)
|
|
||||||
- goto oom;
|
|
||||||
- line[0] = '\0';
|
|
||||||
-
|
|
||||||
if (args->reason != NULL) {
|
|
||||||
- if (strlcat(line, args->reason, len) >= len ||
|
|
||||||
- strlcat(line, args->errstr ? " : " : " ; ", len) >= len)
|
|
||||||
- goto toobig;
|
|
||||||
+ sudo_lbuf_append_esc(&lbuf, LBUF_ESC_CNTRL, "%s%s", args->reason,
|
|
||||||
+ args->errstr ? " : " : " ; ");
|
|
||||||
}
|
|
||||||
if (args->errstr != NULL) {
|
|
||||||
- if (strlcat(line, args->errstr, len) >= len ||
|
|
||||||
- strlcat(line, " ; ", len) >= len)
|
|
||||||
- goto toobig;
|
|
||||||
+ sudo_lbuf_append_esc(&lbuf, LBUF_ESC_CNTRL, "%s ; ", args->errstr);
|
|
||||||
}
|
|
||||||
if (evlog->submithost != NULL && !evl_conf->omit_hostname) {
|
|
||||||
- if (strlcat(line, LL_HOST_STR, len) >= len ||
|
|
||||||
- strlcat(line, evlog->submithost, len) >= len ||
|
|
||||||
- strlcat(line, " ; ", len) >= len)
|
|
||||||
- goto toobig;
|
|
||||||
+ sudo_lbuf_append_esc(&lbuf, LBUF_ESC_CNTRL, "HOST=%s ; ",
|
|
||||||
+ evlog->submithost);
|
|
||||||
}
|
|
||||||
if (tty != NULL) {
|
|
||||||
- if (strlcat(line, LL_TTY_STR, len) >= len ||
|
|
||||||
- strlcat(line, tty, len) >= len ||
|
|
||||||
- strlcat(line, " ; ", len) >= len)
|
|
||||||
- goto toobig;
|
|
||||||
+ sudo_lbuf_append_esc(&lbuf, LBUF_ESC_CNTRL, "TTY=%s ; ", tty);
|
|
||||||
}
|
|
||||||
if (evlog->runchroot != NULL) {
|
|
||||||
- if (strlcat(line, LL_CHROOT_STR, len) >= len ||
|
|
||||||
- strlcat(line, evlog->runchroot, len) >= len ||
|
|
||||||
- strlcat(line, " ; ", len) >= len)
|
|
||||||
- goto toobig;
|
|
||||||
+ sudo_lbuf_append_esc(&lbuf, LBUF_ESC_CNTRL, "CHROOT=%s ; ",
|
|
||||||
+ evlog->runchroot);
|
|
||||||
}
|
|
||||||
if (evlog->runcwd != NULL) {
|
|
||||||
- if (strlcat(line, LL_CWD_STR, len) >= len ||
|
|
||||||
- strlcat(line, evlog->runcwd, len) >= len ||
|
|
||||||
- strlcat(line, " ; ", len) >= len)
|
|
||||||
- goto toobig;
|
|
||||||
+ sudo_lbuf_append_esc(&lbuf, LBUF_ESC_CNTRL, "PWD=%s ; ",
|
|
||||||
+ evlog->runcwd);
|
|
||||||
}
|
|
||||||
if (evlog->runuser != NULL) {
|
|
||||||
- if (strlcat(line, LL_USER_STR, len) >= len ||
|
|
||||||
- strlcat(line, evlog->runuser, len) >= len ||
|
|
||||||
- strlcat(line, " ; ", len) >= len)
|
|
||||||
- goto toobig;
|
|
||||||
+ sudo_lbuf_append_esc(&lbuf, LBUF_ESC_CNTRL, "USER=%s ; ",
|
|
||||||
+ evlog->runuser);
|
|
||||||
}
|
|
||||||
if (evlog->rungroup != NULL) {
|
|
||||||
- if (strlcat(line, LL_GROUP_STR, len) >= len ||
|
|
||||||
- strlcat(line, evlog->rungroup, len) >= len ||
|
|
||||||
- strlcat(line, " ; ", len) >= len)
|
|
||||||
- goto toobig;
|
|
||||||
- }
|
|
||||||
+ sudo_lbuf_append_esc(&lbuf, LBUF_ESC_CNTRL, "GROUP=%s ; ",
|
|
||||||
+ evlog->rungroup);
|
|
||||||
+ }
|
|
||||||
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;
|
|
||||||
+ sudo_lbuf_append_esc(&lbuf, LBUF_ESC_CNTRL, "TSID=%s ; ", tsid);
|
|
||||||
+ }
|
|
||||||
+ if (evlog->env_add != NULL && evlog->env_add[0] != NULL) {
|
|
||||||
+ sudo_lbuf_append_esc(&lbuf, LBUF_ESC_CNTRL, "ENV=%s",
|
|
||||||
+ evlog->env_add[0]);
|
|
||||||
+ for (i = 1; evlog->env_add[i] != NULL; i++) {
|
|
||||||
+ sudo_lbuf_append_esc(&lbuf, LBUF_ESC_CNTRL, " %s",
|
|
||||||
+ evlog->env_add[i]);
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
if (evlog->command != NULL) {
|
|
||||||
- if (strlcat(line, LL_CMND_STR, len) >= len)
|
|
||||||
- goto toobig;
|
|
||||||
- if (strlcat(line, evlog->command, len) >= len)
|
|
||||||
- goto toobig;
|
|
||||||
- if (evlog->argv != NULL) {
|
|
||||||
+ sudo_lbuf_append_esc(&lbuf, LBUF_ESC_CNTRL|LBUF_ESC_BLANK,
|
|
||||||
+ "COMMAND=%s", evlog->command);
|
|
||||||
+ if (evlog->argv != NULL && evlog->argv[0] != NULL) {
|
|
||||||
for (i = 1; evlog->argv[i] != NULL; i++) {
|
|
||||||
- if (strlcat(line, " ", len) >= len ||
|
|
||||||
- strlcat(line, evlog->argv[i], len) >= len)
|
|
||||||
- goto toobig;
|
|
||||||
+ sudo_lbuf_append(&lbuf, " ");
|
|
||||||
+ if (strchr(evlog->argv[i], ' ') != NULL) {
|
|
||||||
+ /* Wrap args containing spaces in single quotes. */
|
|
||||||
+ sudo_lbuf_append(&lbuf, "'");
|
|
||||||
+ sudo_lbuf_append_esc(&lbuf, LBUF_ESC_CNTRL|LBUF_ESC_QUOTE,
|
|
||||||
+ "%s", evlog->argv[i]);
|
|
||||||
+ sudo_lbuf_append(&lbuf, "'");
|
|
||||||
+ } else {
|
|
||||||
+ /* Escape quotes here too for consistency. */
|
|
||||||
+ sudo_lbuf_append_esc(&lbuf,
|
|
||||||
+ LBUF_ESC_CNTRL|LBUF_ESC_BLANK|LBUF_ESC_QUOTE,
|
|
||||||
+ "%s", evlog->argv[i]);
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+/*
|
|
||||||
if (event_type == EVLOG_EXIT) {
|
|
||||||
if (args->signal_name != NULL) {
|
|
||||||
- if (strlcat(line, " ; ", len) >= len ||
|
|
||||||
- strlcat(line, LL_SIGNAL_STR, len) >= len ||
|
|
||||||
- strlcat(line, args->signal_name, len) >= len)
|
|
||||||
- goto toobig;
|
|
||||||
+ sudo_lbuf_append_esc(&lbuf, LBUF_ESC_CNTRL, " ; SIGNAL=%s",
|
|
||||||
+ evlog->signal_name);
|
|
||||||
}
|
|
||||||
- if (strlcat(line, " ; ", len) >= len ||
|
|
||||||
- strlcat(line, LL_EXIT_STR, len) >= len ||
|
|
||||||
- strlcat(line, exit_str, len) >= len)
|
|
||||||
- goto toobig;
|
|
||||||
+ if (evlog->exit_value != -1) {
|
|
||||||
+ (void)snprintf(exit_str, sizeof(exit_str), "%d",
|
|
||||||
+ evlog->exit_value);
|
|
||||||
+ sudo_lbuf_append_esc(&lbuf, LBUF_ESC_CNTRL, " ; EXIT=%s",
|
|
||||||
+ exit_str);
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
+*/
|
|
||||||
}
|
|
||||||
|
|
||||||
- debug_return_str(line);
|
|
||||||
+ if (!sudo_lbuf_error(&lbuf))
|
|
||||||
+ debug_return_str(lbuf.buf);
|
|
||||||
oom:
|
|
||||||
- free(evstr);
|
|
||||||
+ sudo_lbuf_destroy(&lbuf);
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
diff -up ./lib/iolog/iolog_json.c.cve ./lib/iolog/iolog_json.c
|
|
||||||
--- ./lib/iolog/iolog_json.c.cve 2020-12-17 02:33:43.000000000 +0100
|
|
||||||
+++ ./lib/iolog/iolog_json.c 2023-12-04 16:52:54.500061266 +0100
|
|
||||||
@@ -443,35 +443,6 @@ iolog_parse_json_object(struct json_obje
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- /* Merge cmd and argv as sudoreplay expects. */
|
|
||||||
- if (evlog->command != NULL && evlog->argv != NULL) {
|
|
||||||
- size_t len = strlen(evlog->command) + 1;
|
|
||||||
- char *newcmd;
|
|
||||||
- int ac;
|
|
||||||
-
|
|
||||||
- /* Skip argv[0], we use evlog->command instead. */
|
|
||||||
- for (ac = 1; evlog->argv[ac] != NULL; ac++)
|
|
||||||
- len += strlen(evlog->argv[ac]) + 1;
|
|
||||||
-
|
|
||||||
- if ((newcmd = malloc(len)) == NULL) {
|
|
||||||
- sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
|
||||||
- goto done;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- /* TODO: optimize this. */
|
|
||||||
- if (strlcpy(newcmd, evlog->command, len) >= len)
|
|
||||||
- sudo_fatalx(U_("internal error, %s overflow"), __func__);
|
|
||||||
- for (ac = 1; evlog->argv[ac] != NULL; ac++) {
|
|
||||||
- if (strlcat(newcmd, " ", len) >= len)
|
|
||||||
- sudo_fatalx(U_("internal error, %s overflow"), __func__);
|
|
||||||
- if (strlcat(newcmd, evlog->argv[ac], len) >= len)
|
|
||||||
- sudo_fatalx(U_("internal error, %s overflow"), __func__);
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- free(evlog->command);
|
|
||||||
- evlog->command = newcmd;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
ret = true;
|
|
||||||
|
|
||||||
done:
|
|
||||||
diff -up ./lib/util/lbuf.c.cve ./lib/util/lbuf.c
|
|
||||||
--- ./lib/util/lbuf.c.cve 2020-12-17 02:33:43.000000000 +0100
|
|
||||||
+++ ./lib/util/lbuf.c 2023-12-04 16:52:54.501061253 +0100
|
|
||||||
@@ -85,6 +85,112 @@ sudo_lbuf_expand(struct sudo_lbuf *lbuf,
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
+ * Escape a character in octal form (#0n) and store it as a string
|
|
||||||
+ * in buf, which must have at least 6 bytes available.
|
|
||||||
+ * Returns the length of buf, not counting the terminating NUL byte.
|
|
||||||
+ */
|
|
||||||
+static int
|
|
||||||
+escape(unsigned char ch, char *buf)
|
|
||||||
+{
|
|
||||||
+ const int len = ch < 0100 ? (ch < 010 ? 3 : 4) : 5;
|
|
||||||
+
|
|
||||||
+ /* Work backwards from the least significant digit to most significant. */
|
|
||||||
+ switch (len) {
|
|
||||||
+ case 5:
|
|
||||||
+ buf[4] = (ch & 7) + '0';
|
|
||||||
+ ch >>= 3;
|
|
||||||
+ FALLTHROUGH;
|
|
||||||
+ case 4:
|
|
||||||
+ buf[3] = (ch & 7) + '0';
|
|
||||||
+ ch >>= 3;
|
|
||||||
+ FALLTHROUGH;
|
|
||||||
+ case 3:
|
|
||||||
+ buf[2] = (ch & 7) + '0';
|
|
||||||
+ buf[1] = '0';
|
|
||||||
+ buf[0] = '#';
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+ buf[len] = '\0';
|
|
||||||
+
|
|
||||||
+ return len;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * Parse the format and append strings, only %s and %% escapes are supported.
|
|
||||||
+ * Any non-printable characters are escaped in octal as #0nn.
|
|
||||||
+ */
|
|
||||||
+bool
|
|
||||||
+sudo_lbuf_append_esc_v1(struct sudo_lbuf *lbuf, int flags, const char *fmt, ...)
|
|
||||||
+{
|
|
||||||
+ unsigned int saved_len = lbuf->len;
|
|
||||||
+ bool ret = false;
|
|
||||||
+ const char *s;
|
|
||||||
+ va_list ap;
|
|
||||||
+ debug_decl(sudo_lbuf_append_esc, SUDO_DEBUG_UTIL);
|
|
||||||
+
|
|
||||||
+ if (sudo_lbuf_error(lbuf))
|
|
||||||
+ debug_return_bool(false);
|
|
||||||
+
|
|
||||||
+#define should_escape(ch) \
|
|
||||||
+ ((ISSET(flags, LBUF_ESC_CNTRL) && iscntrl((unsigned char)ch)) || \
|
|
||||||
+ (ISSET(flags, LBUF_ESC_BLANK) && isblank((unsigned char)ch)))
|
|
||||||
+#define should_quote(ch) \
|
|
||||||
+ (ISSET(flags, LBUF_ESC_QUOTE) && (ch == '\'' || ch == '\\'))
|
|
||||||
+
|
|
||||||
+ va_start(ap, fmt);
|
|
||||||
+ while (*fmt != '\0') {
|
|
||||||
+ if (fmt[0] == '%' && fmt[1] == 's') {
|
|
||||||
+ if ((s = va_arg(ap, char *)) == NULL)
|
|
||||||
+ s = "(NULL)";
|
|
||||||
+ while (*s != '\0') {
|
|
||||||
+ if (should_escape(*s)) {
|
|
||||||
+ if (!sudo_lbuf_expand(lbuf, sizeof("#0177") - 1))
|
|
||||||
+ goto done;
|
|
||||||
+ lbuf->len += escape(*s++, lbuf->buf + lbuf->len);
|
|
||||||
+ continue;
|
|
||||||
+ }
|
|
||||||
+ if (should_quote(*s)) {
|
|
||||||
+ if (!sudo_lbuf_expand(lbuf, 2))
|
|
||||||
+ goto done;
|
|
||||||
+ lbuf->buf[lbuf->len++] = '\\';
|
|
||||||
+ lbuf->buf[lbuf->len++] = *s++;
|
|
||||||
+ continue;
|
|
||||||
+ }
|
|
||||||
+ if (!sudo_lbuf_expand(lbuf, 1))
|
|
||||||
+ goto done;
|
|
||||||
+ lbuf->buf[lbuf->len++] = *s++;
|
|
||||||
+ }
|
|
||||||
+ fmt += 2;
|
|
||||||
+ continue;
|
|
||||||
+ }
|
|
||||||
+ if (should_escape(*fmt)) {
|
|
||||||
+ if (!sudo_lbuf_expand(lbuf, sizeof("#0177") - 1))
|
|
||||||
+ goto done;
|
|
||||||
+ if (*fmt == '\'') {
|
|
||||||
+ lbuf->buf[lbuf->len++] = '\\';
|
|
||||||
+ lbuf->buf[lbuf->len++] = *fmt++;
|
|
||||||
+ } else {
|
|
||||||
+ lbuf->len += escape(*fmt++, lbuf->buf + lbuf->len);
|
|
||||||
+ }
|
|
||||||
+ continue;
|
|
||||||
+ }
|
|
||||||
+ if (!sudo_lbuf_expand(lbuf, 1))
|
|
||||||
+ goto done;
|
|
||||||
+ lbuf->buf[lbuf->len++] = *fmt++;
|
|
||||||
+ }
|
|
||||||
+ ret = true;
|
|
||||||
+
|
|
||||||
+done:
|
|
||||||
+ if (!ret)
|
|
||||||
+ lbuf->len = saved_len;
|
|
||||||
+ if (lbuf->size != 0)
|
|
||||||
+ lbuf->buf[lbuf->len] = '\0';
|
|
||||||
+ va_end(ap);
|
|
||||||
+
|
|
||||||
+ debug_return_bool(ret);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
* Parse the format and append strings, only %s and %% escapes are supported.
|
|
||||||
* Any characters in set are quoted with a backslash.
|
|
||||||
*/
|
|
||||||
diff -up ./lib/util/util.exp.in.cve ./lib/util/util.exp.in
|
|
||||||
--- ./lib/util/util.exp.in.cve 2021-01-09 21:12:16.000000000 +0100
|
|
||||||
+++ ./lib/util/util.exp.in 2023-12-04 16:52:54.501061253 +0100
|
|
||||||
@@ -95,6 +95,7 @@ sudo_json_get_len_v1
|
|
||||||
sudo_json_init_v1
|
|
||||||
sudo_json_open_array_v1
|
|
||||||
sudo_json_open_object_v1
|
|
||||||
+sudo_lbuf_append_esc_v1
|
|
||||||
sudo_lbuf_append_quoted_v1
|
|
||||||
sudo_lbuf_append_v1
|
|
||||||
sudo_lbuf_clearerr_v1
|
|
||||||
diff -up ./plugins/sudoers/sudoreplay.c.cve ./plugins/sudoers/sudoreplay.c
|
|
||||||
--- ./plugins/sudoers/sudoreplay.c.cve 2023-12-04 16:52:54.498061293 +0100
|
|
||||||
+++ ./plugins/sudoers/sudoreplay.c 2023-12-04 16:52:54.501061253 +0100
|
|
||||||
@@ -62,6 +62,7 @@
|
|
||||||
#include "sudo_debug.h"
|
|
||||||
#include "sudo_event.h"
|
|
||||||
#include "sudo_eventlog.h"
|
|
||||||
+#include "sudo_lbuf.h"
|
|
||||||
#include "sudo_fatal.h"
|
|
||||||
#include "sudo_gettext.h"
|
|
||||||
#include "sudo_iolog.h"
|
|
||||||
@@ -363,6 +364,10 @@ main(int argc, char *argv[])
|
|
||||||
if ((evlog = iolog_parse_loginfo(iolog_dir_fd, iolog_dir)) == NULL)
|
|
||||||
goto done;
|
|
||||||
printf(_("Replaying sudo session: %s"), evlog->command);
|
|
||||||
+ if (evlog->argv != NULL && evlog->argv[0] != NULL) {
|
|
||||||
+ for (i = 1; evlog->argv[i] != NULL; i++)
|
|
||||||
+ printf(" %s", evlog->argv[i]);
|
|
||||||
+ }
|
|
||||||
|
|
||||||
/* Setup terminal if appropriate. */
|
|
||||||
if (!isatty(STDIN_FILENO) || !isatty(STDOUT_FILENO))
|
|
||||||
@@ -1291,11 +1296,57 @@ parse_expr(struct search_node_list *head
|
|
||||||
debug_return_int(av - argv);
|
|
||||||
}
|
|
||||||
|
|
||||||
+static char *
|
|
||||||
+expand_command(struct eventlog *evlog, char **newbuf)
|
|
||||||
+{
|
|
||||||
+ size_t len, bufsize = strlen(evlog->command) + 1;
|
|
||||||
+ char *cp, *buf;
|
|
||||||
+ int ac;
|
|
||||||
+ debug_decl(expand_command, SUDO_DEBUG_UTIL);
|
|
||||||
+
|
|
||||||
+ if (evlog->argv == NULL || evlog->argv[0] == NULL || evlog->argv[1] == NULL) {
|
|
||||||
+ /* No arguments, we can use the command as-is. */
|
|
||||||
+ *newbuf = NULL;
|
|
||||||
+ debug_return_str(evlog->command);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /* Skip argv[0], we use evlog->command instead. */
|
|
||||||
+ for (ac = 1; evlog->argv[ac] != NULL; ac++)
|
|
||||||
+ bufsize += strlen(evlog->argv[ac]) + 1;
|
|
||||||
+
|
|
||||||
+ if ((buf = malloc(bufsize)) == NULL)
|
|
||||||
+ sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
|
||||||
+ cp = buf;
|
|
||||||
+
|
|
||||||
+ len = strlcpy(cp, evlog->command, bufsize);
|
|
||||||
+ if (len >= bufsize)
|
|
||||||
+ sudo_fatalx(U_("internal error, %s overflow"), __func__);
|
|
||||||
+ cp += len;
|
|
||||||
+ bufsize -= len;
|
|
||||||
+
|
|
||||||
+ for (ac = 1; evlog->argv[ac] != NULL; ac++) {
|
|
||||||
+ if (bufsize < 2)
|
|
||||||
+ sudo_fatalx(U_("internal error, %s overflow"), __func__);
|
|
||||||
+ *cp++ = ' ';
|
|
||||||
+ bufsize--;
|
|
||||||
+
|
|
||||||
+ len = strlcpy(cp, evlog->argv[ac], bufsize);
|
|
||||||
+ if (len >= bufsize)
|
|
||||||
+ sudo_fatalx(U_("internal error, %s overflow"), __func__);
|
|
||||||
+ cp += len;
|
|
||||||
+ bufsize -= len;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ *newbuf = buf;
|
|
||||||
+ debug_return_str(buf);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static bool
|
|
||||||
match_expr(struct search_node_list *head, struct eventlog *evlog, bool last_match)
|
|
||||||
{
|
|
||||||
struct search_node *sn;
|
|
||||||
bool res = false, matched = last_match;
|
|
||||||
+ char *tofree;
|
|
||||||
int rc;
|
|
||||||
debug_decl(match_expr, SUDO_DEBUG_UTIL);
|
|
||||||
|
|
||||||
@@ -1329,13 +1380,15 @@ match_expr(struct search_node_list *head
|
|
||||||
res = strcmp(sn->u.user, evlog->submituser) == 0;
|
|
||||||
break;
|
|
||||||
case ST_PATTERN:
|
|
||||||
- rc = regexec(&sn->u.cmdre, evlog->command, 0, NULL, 0);
|
|
||||||
+ rc = regexec(&sn->u.cmdre, expand_command(evlog, &tofree),
|
|
||||||
+ 0, NULL, 0);
|
|
||||||
if (rc && rc != REG_NOMATCH) {
|
|
||||||
char buf[BUFSIZ];
|
|
||||||
regerror(rc, &sn->u.cmdre, buf, sizeof(buf));
|
|
||||||
sudo_fatalx("%s", buf);
|
|
||||||
}
|
|
||||||
res = rc == REG_NOMATCH ? 0 : 1;
|
|
||||||
+ free(tofree);
|
|
||||||
break;
|
|
||||||
case ST_FROMDATE:
|
|
||||||
res = sudo_timespeccmp(&evlog->submit_time, &sn->u.tstamp, >=);
|
|
||||||
@@ -1356,12 +1409,13 @@ match_expr(struct search_node_list *head
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
-list_session(char *log_dir, regex_t *re, const char *user, const char *tty)
|
|
||||||
+list_session(struct sudo_lbuf *lbuf, char *log_dir, regex_t *re,
|
|
||||||
+ const char *user, const char *tty)
|
|
||||||
{
|
|
||||||
char idbuf[7], *idstr, *cp;
|
|
||||||
struct eventlog *evlog = NULL;
|
|
||||||
const char *timestr;
|
|
||||||
- int ret = -1;
|
|
||||||
+ int i, ret = -1;
|
|
||||||
debug_decl(list_session, SUDO_DEBUG_UTIL);
|
|
||||||
|
|
||||||
if ((evlog = iolog_parse_loginfo(-1, log_dir)) == NULL)
|
|
||||||
@@ -1393,23 +1447,71 @@ list_session(char *log_dir, regex_t *re,
|
|
||||||
}
|
|
||||||
/* XXX - print lines + cols? */
|
|
||||||
timestr = get_timestr(evlog->submit_time.tv_sec, 1);
|
|
||||||
- printf("%s : %s : ", timestr ? timestr : "invalid date", evlog->submituser);
|
|
||||||
- if (evlog->submithost != NULL)
|
|
||||||
- printf("HOST=%s ; ", evlog->submithost);
|
|
||||||
- if (evlog->ttyname != NULL)
|
|
||||||
- printf("TTY=%s ; ", evlog->ttyname);
|
|
||||||
- if (evlog->runchroot != NULL)
|
|
||||||
- printf("CHROOT=%s ; ", evlog->runchroot);
|
|
||||||
- if (evlog->runcwd != NULL || evlog->cwd != NULL)
|
|
||||||
- printf("CWD=%s ; ", evlog->runcwd ? evlog->runcwd : evlog->cwd);
|
|
||||||
- printf("USER=%s ; ", evlog->runuser);
|
|
||||||
- if (evlog->rungroup != NULL)
|
|
||||||
- printf("GROUP=%s ; ", evlog->rungroup);
|
|
||||||
- printf("TSID=%s ; COMMAND=%s\n", idstr, evlog->command);
|
|
||||||
+ sudo_lbuf_append_esc(lbuf, LBUF_ESC_CNTRL, "%s : %s : ",
|
|
||||||
+ timestr ? timestr : "invalid date", evlog->submituser);
|
|
||||||
+ if (evlog->submithost != NULL) {
|
|
||||||
+ sudo_lbuf_append_esc(lbuf, LBUF_ESC_CNTRL, "HOST=%s ; ",
|
|
||||||
+ evlog->submithost);
|
|
||||||
+ }
|
|
||||||
+ if (evlog->ttyname != NULL) {
|
|
||||||
+ sudo_lbuf_append_esc(lbuf, LBUF_ESC_CNTRL, "TTY=%s ; ",
|
|
||||||
+ evlog->ttyname);
|
|
||||||
+ }
|
|
||||||
+ if (evlog->runchroot != NULL) {
|
|
||||||
+ sudo_lbuf_append_esc(lbuf, LBUF_ESC_CNTRL, "CHROOT=%s ; ",
|
|
||||||
+ evlog->runchroot);
|
|
||||||
+ }
|
|
||||||
+ if (evlog->runcwd != NULL || evlog->cwd != NULL) {
|
|
||||||
+ sudo_lbuf_append_esc(lbuf, LBUF_ESC_CNTRL, "CWD=%s ; ",
|
|
||||||
+ evlog->runcwd ? evlog->runcwd : evlog->cwd);
|
|
||||||
+ }
|
|
||||||
+ sudo_lbuf_append_esc(lbuf, LBUF_ESC_CNTRL, "USER=%s ; ", evlog->runuser);
|
|
||||||
+ if (evlog->rungroup != NULL) {
|
|
||||||
+ sudo_lbuf_append_esc(lbuf, LBUF_ESC_CNTRL, "GROUP=%s ; ",
|
|
||||||
+ evlog->rungroup);
|
|
||||||
+ }
|
|
||||||
+ sudo_lbuf_append_esc(lbuf, LBUF_ESC_CNTRL, "TSID=%s ; ", idstr);
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * If we have both command and argv from info.json we can escape
|
|
||||||
+ * blanks in the the command and arguments. If all we have is a
|
|
||||||
+ * single string containing both the command and arguments we cannot.
|
|
||||||
+ */
|
|
||||||
+ if (evlog->argv != NULL) {
|
|
||||||
+ /* Command plus argv from the info.json file. */
|
|
||||||
+ sudo_lbuf_append_esc(lbuf, LBUF_ESC_CNTRL|LBUF_ESC_BLANK,
|
|
||||||
+ "COMMAND=%s", evlog->command);
|
|
||||||
+ if (evlog->argv[0] != NULL) {
|
|
||||||
+ for (i = 1; evlog->argv[i] != NULL; i++) {
|
|
||||||
+ sudo_lbuf_append(lbuf, " ");
|
|
||||||
+ if (strchr(evlog->argv[i], ' ') != NULL) {
|
|
||||||
+ /* Wrap args containing spaces in single quotes. */
|
|
||||||
+ sudo_lbuf_append(lbuf, "'");
|
|
||||||
+ sudo_lbuf_append_esc(lbuf, LBUF_ESC_CNTRL|LBUF_ESC_QUOTE,
|
|
||||||
+ "%s", evlog->argv[i]);
|
|
||||||
+ sudo_lbuf_append(lbuf, "'");
|
|
||||||
+ } else {
|
|
||||||
+ /* Escape quotes here too for consistency. */
|
|
||||||
+ sudo_lbuf_append_esc(lbuf,
|
|
||||||
+ LBUF_ESC_CNTRL|LBUF_ESC_BLANK|LBUF_ESC_QUOTE,
|
|
||||||
+ "%s", evlog->argv[i]);
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ } else {
|
|
||||||
+ /* Single string from the legacy info file. */
|
|
||||||
+ sudo_lbuf_append_esc(lbuf, LBUF_ESC_CNTRL, "COMMAND=%s",
|
|
||||||
+ evlog->command);
|
|
||||||
+ }
|
|
||||||
|
|
||||||
- ret = 0;
|
|
||||||
+ if (!sudo_lbuf_error(lbuf)) {
|
|
||||||
+ puts(lbuf->buf);
|
|
||||||
+ ret = 0;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
done:
|
|
||||||
+ lbuf->error = 0;
|
|
||||||
+ lbuf->len = 0;
|
|
||||||
eventlog_free(evlog);
|
|
||||||
debug_return_int(ret);
|
|
||||||
}
|
|
||||||
@@ -1429,6 +1531,7 @@ find_sessions(const char *dir, regex_t *
|
|
||||||
DIR *d;
|
|
||||||
struct dirent *dp;
|
|
||||||
struct stat sb;
|
|
||||||
+ struct sudo_lbuf lbuf;
|
|
||||||
size_t sdlen, sessions_len = 0, sessions_size = 0;
|
|
||||||
unsigned int i;
|
|
||||||
int len;
|
|
||||||
@@ -1440,6 +1543,8 @@ find_sessions(const char *dir, regex_t *
|
|
||||||
#endif
|
|
||||||
debug_decl(find_sessions, SUDO_DEBUG_UTIL);
|
|
||||||
|
|
||||||
+ sudo_lbuf_init(&lbuf, NULL, 0, NULL, 0);
|
|
||||||
+
|
|
||||||
d = opendir(dir);
|
|
||||||
if (d == NULL)
|
|
||||||
sudo_fatal(U_("unable to open %s"), dir);
|
|
||||||
@@ -1500,7 +1605,7 @@ find_sessions(const char *dir, regex_t *
|
|
||||||
/* Check for dir with a log file. */
|
|
||||||
if (lstat(pathbuf, &sb) == 0 && S_ISREG(sb.st_mode)) {
|
|
||||||
pathbuf[sdlen + len - 4] = '\0';
|
|
||||||
- list_session(pathbuf, re, user, tty);
|
|
||||||
+ list_session(&lbuf, pathbuf, re, user, tty);
|
|
||||||
} else {
|
|
||||||
/* Strip off "/log" and recurse if a non-log dir. */
|
|
||||||
pathbuf[sdlen + len - 4] = '\0';
|
|
||||||
@@ -1511,6 +1616,7 @@ find_sessions(const char *dir, regex_t *
|
|
||||||
}
|
|
||||||
free(sessions);
|
|
||||||
}
|
|
||||||
+ sudo_lbuf_destroy(&lbuf);
|
|
||||||
|
|
||||||
debug_return_int(0);
|
|
||||||
}
|
|
@ -1,598 +0,0 @@
|
|||||||
diff -up ./plugins/sudoers/auth/passwd.c.rowhammer ./plugins/sudoers/auth/passwd.c
|
|
||||||
--- ./plugins/sudoers/auth/passwd.c.rowhammer 2020-12-17 02:33:44.000000000 +0100
|
|
||||||
+++ ./plugins/sudoers/auth/passwd.c 2024-01-22 16:01:16.331874669 +0100
|
|
||||||
@@ -62,7 +62,7 @@ sudo_passwd_verify(struct passwd *pw, ch
|
|
||||||
char sav, *epass;
|
|
||||||
char *pw_epasswd = auth->data;
|
|
||||||
size_t pw_len;
|
|
||||||
- int matched = 0;
|
|
||||||
+ int ret;
|
|
||||||
debug_decl(sudo_passwd_verify, SUDOERS_DEBUG_AUTH);
|
|
||||||
|
|
||||||
/* An empty plain-text password must match an empty encrypted password. */
|
|
||||||
@@ -85,27 +85,37 @@ sudo_passwd_verify(struct passwd *pw, ch
|
|
||||||
*/
|
|
||||||
epass = (char *) crypt(pass, pw_epasswd);
|
|
||||||
pass[8] = sav;
|
|
||||||
+ ret = AUTH_FAILURE;
|
|
||||||
if (epass != NULL) {
|
|
||||||
- if (HAS_AGEINFO(pw_epasswd, pw_len) && strlen(epass) == DESLEN)
|
|
||||||
- matched = !strncmp(pw_epasswd, epass, DESLEN);
|
|
||||||
- else
|
|
||||||
- matched = !strcmp(pw_epasswd, epass);
|
|
||||||
+ if (HAS_AGEINFO(pw_epasswd, pw_len) && strlen(epass) == DESLEN) {
|
|
||||||
+ if (strncmp(pw_epasswd, epass, DESLEN) == 0)
|
|
||||||
+ ret = AUTH_SUCCESS;
|
|
||||||
+ } else {
|
|
||||||
+ if (strcmp(pw_epasswd, epass) == 0)
|
|
||||||
+ ret = AUTH_SUCCESS;
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
|
|
||||||
- debug_return_int(matched ? AUTH_SUCCESS : AUTH_FAILURE);
|
|
||||||
+ explicit_bzero(des_pass, sizeof(des_pass));
|
|
||||||
+
|
|
||||||
+ debug_return_int(ret);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
int
|
|
||||||
sudo_passwd_verify(struct passwd *pw, char *pass, sudo_auth *auth, struct sudo_conv_callback *callback)
|
|
||||||
{
|
|
||||||
char *pw_passwd = auth->data;
|
|
||||||
- int matched;
|
|
||||||
+ int ret;
|
|
||||||
debug_decl(sudo_passwd_verify, SUDOERS_DEBUG_AUTH);
|
|
||||||
|
|
||||||
/* Simple string compare for systems without crypt(). */
|
|
||||||
matched = !strcmp(pass, pw_passwd);
|
|
||||||
+ if (strcmp(pass, pw_passwd) == 0)
|
|
||||||
+ ret = AUTH_SUCCESS;
|
|
||||||
+ else
|
|
||||||
+ ret = AUTH_FAILURE;
|
|
||||||
|
|
||||||
- debug_return_int(matched ? AUTH_SUCCESS : AUTH_FAILURE);
|
|
||||||
+ debug_return_int(ret);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
diff -up ./plugins/sudoers/auth/sudo_auth.c.rowhammer ./plugins/sudoers/auth/sudo_auth.c
|
|
||||||
--- ./plugins/sudoers/auth/sudo_auth.c.rowhammer 2020-12-17 02:33:43.000000000 +0100
|
|
||||||
+++ ./plugins/sudoers/auth/sudo_auth.c 2024-01-22 16:01:16.331874669 +0100
|
|
||||||
@@ -112,10 +112,16 @@ sudo_auth_init(struct passwd *pw)
|
|
||||||
if (auth->init && !IS_DISABLED(auth)) {
|
|
||||||
/* Disable if it failed to init unless there was a fatal error. */
|
|
||||||
status = (auth->init)(pw, auth);
|
|
||||||
- if (status == AUTH_FAILURE)
|
|
||||||
- SET(auth->flags, FLAG_DISABLED);
|
|
||||||
- else if (status == AUTH_FATAL)
|
|
||||||
- break; /* assume error msg already printed */
|
|
||||||
+ switch (status) {
|
|
||||||
+ case AUTH_SUCCESS:
|
|
||||||
+ break;
|
|
||||||
+ case AUTH_FAILURE:
|
|
||||||
+ SET(auth->flags, FLAG_DISABLED);
|
|
||||||
+ break;
|
|
||||||
+ default:
|
|
||||||
+ /* Assume error msg already printed. */
|
|
||||||
+ debug_return_int(-1);
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -161,7 +167,7 @@ sudo_auth_init(struct passwd *pw)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- debug_return_int(status == AUTH_FATAL ? -1 : 0);
|
|
||||||
+ debug_return_int(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
@@ -202,7 +208,7 @@ sudo_auth_cleanup(struct passwd *pw, boo
|
|
||||||
for (auth = auth_switch; auth->name; auth++) {
|
|
||||||
if (auth->cleanup && !IS_DISABLED(auth)) {
|
|
||||||
int status = (auth->cleanup)(pw, auth, force);
|
|
||||||
- if (status == AUTH_FATAL) {
|
|
||||||
+ if (status != AUTH_SUCCESS) {
|
|
||||||
/* Assume error msg already printed. */
|
|
||||||
debug_return_int(-1);
|
|
||||||
}
|
|
||||||
@@ -297,7 +303,7 @@ verify_user(struct passwd *pw, char *pro
|
|
||||||
status = (auth->setup)(pw, &prompt, auth);
|
|
||||||
if (status == AUTH_FAILURE)
|
|
||||||
SET(auth->flags, FLAG_DISABLED);
|
|
||||||
- else if (status == AUTH_FATAL || user_interrupted())
|
|
||||||
+ else if (status != AUTH_SUCCESS || user_interrupted())
|
|
||||||
goto done; /* assume error msg already printed */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -348,7 +354,6 @@ done:
|
|
||||||
log_auth_failure(validated, ntries);
|
|
||||||
ret = false;
|
|
||||||
break;
|
|
||||||
- case AUTH_FATAL:
|
|
||||||
default:
|
|
||||||
log_auth_failure(validated, 0);
|
|
||||||
ret = -1;
|
|
||||||
@@ -360,24 +365,32 @@ done:
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Call authentication method begin session hooks.
|
|
||||||
- * Returns 1 on success and -1 on error.
|
|
||||||
+ * Returns true on success, false on failure and -1 on error.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
sudo_auth_begin_session(struct passwd *pw, char **user_env[])
|
|
||||||
{
|
|
||||||
sudo_auth *auth;
|
|
||||||
+ int ret = true;
|
|
||||||
debug_decl(sudo_auth_begin_session, SUDOERS_DEBUG_AUTH);
|
|
||||||
|
|
||||||
for (auth = auth_switch; auth->name; auth++) {
|
|
||||||
if (auth->begin_session && !IS_DISABLED(auth)) {
|
|
||||||
int status = (auth->begin_session)(pw, user_env, auth);
|
|
||||||
- if (status != AUTH_SUCCESS) {
|
|
||||||
- /* Assume error msg already printed. */
|
|
||||||
- debug_return_int(-1);
|
|
||||||
+ switch (status) {
|
|
||||||
+ case AUTH_SUCCESS:
|
|
||||||
+ break;
|
|
||||||
+ case AUTH_FAILURE:
|
|
||||||
+ ret = false;
|
|
||||||
+ break;
|
|
||||||
+ default:
|
|
||||||
+ /* Assume error msg already printed. */
|
|
||||||
+ ret = -1;
|
|
||||||
+ break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
- debug_return_int(1);
|
|
||||||
+ debug_return_int(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
@@ -398,25 +411,33 @@ sudo_auth_needs_end_session(void)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Call authentication method end session hooks.
|
|
||||||
- * Returns 1 on success and -1 on error.
|
|
||||||
+ * Returns true on success, false on failure and -1 on error.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
sudo_auth_end_session(struct passwd *pw)
|
|
||||||
{
|
|
||||||
sudo_auth *auth;
|
|
||||||
+ int ret = true;
|
|
||||||
int status;
|
|
||||||
debug_decl(sudo_auth_end_session, SUDOERS_DEBUG_AUTH);
|
|
||||||
|
|
||||||
for (auth = auth_switch; auth->name; auth++) {
|
|
||||||
if (auth->end_session && !IS_DISABLED(auth)) {
|
|
||||||
status = (auth->end_session)(pw, auth);
|
|
||||||
- if (status == AUTH_FATAL) {
|
|
||||||
- /* Assume error msg already printed. */
|
|
||||||
- debug_return_int(-1);
|
|
||||||
- }
|
|
||||||
+ switch (status) {
|
|
||||||
+ case AUTH_SUCCESS:
|
|
||||||
+ break;
|
|
||||||
+ case AUTH_FAILURE:
|
|
||||||
+ ret = false;
|
|
||||||
+ break;
|
|
||||||
+ default:
|
|
||||||
+ /* Assume error msg already printed. */
|
|
||||||
+ ret = -1;
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
- debug_return_int(1);
|
|
||||||
+ debug_return_int(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
diff -up ./plugins/sudoers/auth/sudo_auth.h.rowhammer ./plugins/sudoers/auth/sudo_auth.h
|
|
||||||
--- ./plugins/sudoers/auth/sudo_auth.h.rowhammer 2020-12-17 02:33:43.000000000 +0100
|
|
||||||
+++ ./plugins/sudoers/auth/sudo_auth.h 2024-01-22 16:01:16.332874679 +0100
|
|
||||||
@@ -19,11 +19,11 @@
|
|
||||||
#ifndef SUDO_AUTH_H
|
|
||||||
#define SUDO_AUTH_H
|
|
||||||
|
|
||||||
-/* Auth function return values. */
|
|
||||||
-#define AUTH_SUCCESS 0
|
|
||||||
-#define AUTH_FAILURE 1
|
|
||||||
-#define AUTH_INTR 2
|
|
||||||
-#define AUTH_FATAL 3
|
|
||||||
+/* Auth function return values (rowhammer resistent). */
|
|
||||||
+#define AUTH_SUCCESS 0x52a2925 /* 0101001010100010100100100101 */
|
|
||||||
+#define AUTH_FAILURE 0xad5d6da /* 1010110101011101011011011010 */
|
|
||||||
+#define AUTH_INTR 0x69d61fc8 /* 1101001110101100001111111001000 */
|
|
||||||
+#define AUTH_FATAL 0x1629e037 /* 0010110001010011110000000110111 */
|
|
||||||
|
|
||||||
typedef struct sudo_auth {
|
|
||||||
int flags; /* various flags, see below */
|
|
||||||
diff -up ./plugins/sudoers/cvtsudoers.c.rowhammer ./plugins/sudoers/cvtsudoers.c
|
|
||||||
--- ./plugins/sudoers/cvtsudoers.c.rowhammer 2024-01-22 18:30:09.585081693 +0100
|
|
||||||
+++ ./plugins/sudoers/cvtsudoers.c 2024-01-22 18:32:35.238519869 +0100
|
|
||||||
@@ -685,7 +685,7 @@ userlist_matches_filter(struct sudoers_p
|
|
||||||
pw.pw_uid = (uid_t)-1;
|
|
||||||
pw.pw_gid = (gid_t)-1;
|
|
||||||
|
|
||||||
- if (user_matches(parse_tree, &pw, m) == true)
|
|
||||||
+ if (user_matches(parse_tree, &pw, m) == ALLOW)
|
|
||||||
matched = true;
|
|
||||||
} else {
|
|
||||||
STAILQ_FOREACH(s, &filters->users, entries) {
|
|
||||||
@@ -711,7 +711,7 @@ userlist_matches_filter(struct sudoers_p
|
|
||||||
if (pw == NULL)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
- if (user_matches(parse_tree, pw, m) == true)
|
|
||||||
+ if (user_matches(parse_tree, pw, m) == ALLOW)
|
|
||||||
matched = true;
|
|
||||||
sudo_pw_delref(pw);
|
|
||||||
|
|
||||||
@@ -787,7 +787,7 @@ hostlist_matches_filter(struct sudoers_p
|
|
||||||
|
|
||||||
/* Only need one host in the filter to match. */
|
|
||||||
/* XXX - can't use netgroup_tuple with NULL pw */
|
|
||||||
- if (host_matches(parse_tree, NULL, lhost, shost, m) == true) {
|
|
||||||
+ if (host_matches(parse_tree, NULL, lhost, shost, m) == ALLOW) {
|
|
||||||
matched = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
diff -up ./plugins/sudoers/match.c.rowhammer ./plugins/sudoers/match.c
|
|
||||||
--- ./plugins/sudoers/match.c.rowhammer 2020-12-17 02:33:44.000000000 +0100
|
|
||||||
+++ ./plugins/sudoers/match.c 2024-01-22 16:01:16.332874679 +0100
|
|
||||||
@@ -26,6 +26,7 @@
|
|
||||||
* PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
|
||||||
*/
|
|
||||||
|
|
||||||
+#include "parse.h"
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
#include <sys/stat.h>
|
|
||||||
@@ -70,37 +71,42 @@ user_matches(struct sudoers_parse_tree *
|
|
||||||
{
|
|
||||||
const char *lhost = parse_tree->lhost ? parse_tree->lhost : user_runhost;
|
|
||||||
const char *shost = parse_tree->shost ? parse_tree->shost : user_srunhost;
|
|
||||||
- int matched = UNSPEC;
|
|
||||||
+ int rc, matched = UNSPEC;
|
|
||||||
struct alias *a;
|
|
||||||
debug_decl(user_matches, SUDOERS_DEBUG_MATCH);
|
|
||||||
|
|
||||||
switch (m->type) {
|
|
||||||
case ALL:
|
|
||||||
- matched = !m->negated;
|
|
||||||
+ matched = m->negated ? DENY : ALLOW;
|
|
||||||
break;
|
|
||||||
case NETGROUP:
|
|
||||||
if (netgr_matches(m->name,
|
|
||||||
def_netgroup_tuple ? lhost : NULL,
|
|
||||||
def_netgroup_tuple ? shost : NULL, pw->pw_name))
|
|
||||||
- matched = !m->negated;
|
|
||||||
+ matched = m->negated ? DENY : ALLOW;
|
|
||||||
break;
|
|
||||||
case USERGROUP:
|
|
||||||
if (usergr_matches(m->name, pw->pw_name, pw))
|
|
||||||
- matched = !m->negated;
|
|
||||||
+ matched = m->negated ? DENY : ALLOW;
|
|
||||||
break;
|
|
||||||
case ALIAS:
|
|
||||||
if ((a = alias_get(parse_tree, m->name, USERALIAS)) != NULL) {
|
|
||||||
/* XXX */
|
|
||||||
- int rc = userlist_matches(parse_tree, pw, &a->members);
|
|
||||||
- if (rc != UNSPEC)
|
|
||||||
- matched = m->negated ? !rc : rc;
|
|
||||||
+ rc = userlist_matches(parse_tree, pw, &a->members);
|
|
||||||
+ if (SPECIFIED(rc)) {
|
|
||||||
+ if (m->negated) {
|
|
||||||
+ matched = rc == ALLOW ? DENY : ALLOW;
|
|
||||||
+ } else {
|
|
||||||
+ matched = rc;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
alias_put(a);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
FALLTHROUGH;
|
|
||||||
case WORD:
|
|
||||||
if (userpw_matches(m->name, pw->pw_name, pw))
|
|
||||||
- matched = !m->negated;
|
|
||||||
+ matched = m->negated ? DENY : ALLOW;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
debug_return_int(matched);
|
|
||||||
@@ -119,7 +125,8 @@ userlist_matches(struct sudoers_parse_tr
|
|
||||||
debug_decl(userlist_matches, SUDOERS_DEBUG_MATCH);
|
|
||||||
|
|
||||||
TAILQ_FOREACH_REVERSE(m, list, member_list, entries) {
|
|
||||||
- if ((matched = user_matches(parse_tree, pw, m)) != UNSPEC)
|
|
||||||
+ matched = user_matches(parse_tree, pw, m);
|
|
||||||
+ if (SPECIFIED(matched))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
debug_return_int(matched);
|
|
||||||
@@ -164,48 +171,53 @@ runaslist_matches(struct sudoers_parse_t
|
|
||||||
/* If no runas user or runas group listed in sudoers, use default. */
|
|
||||||
if (user_list == NULL && group_list == NULL) {
|
|
||||||
debug_return_int(userpw_matches(def_runas_default,
|
|
||||||
- runas_pw->pw_name, runas_pw));
|
|
||||||
+ runas_pw->pw_name, runas_pw) ? ALLOW : DENY);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (user_list != NULL) {
|
|
||||||
TAILQ_FOREACH_REVERSE(m, user_list, member_list, entries) {
|
|
||||||
switch (m->type) {
|
|
||||||
case ALL:
|
|
||||||
- user_matched = !m->negated;
|
|
||||||
+ user_matched = m->negated ? DENY : ALLOW;
|
|
||||||
break;
|
|
||||||
case NETGROUP:
|
|
||||||
if (netgr_matches(m->name,
|
|
||||||
def_netgroup_tuple ? lhost : NULL,
|
|
||||||
def_netgroup_tuple ? shost : NULL,
|
|
||||||
runas_pw->pw_name))
|
|
||||||
- user_matched = !m->negated;
|
|
||||||
+ user_matched = m->negated ? DENY : ALLOW;
|
|
||||||
break;
|
|
||||||
case USERGROUP:
|
|
||||||
if (usergr_matches(m->name, runas_pw->pw_name, runas_pw))
|
|
||||||
- user_matched = !m->negated;
|
|
||||||
+ user_matched = m->negated ? DENY : ALLOW;
|
|
||||||
break;
|
|
||||||
case ALIAS:
|
|
||||||
a = alias_get(parse_tree, m->name, RUNASALIAS);
|
|
||||||
if (a != NULL) {
|
|
||||||
rc = runaslist_matches(parse_tree, &a->members,
|
|
||||||
&empty, matching_user, NULL);
|
|
||||||
- if (rc != UNSPEC)
|
|
||||||
- user_matched = m->negated ? !rc : rc;
|
|
||||||
+ if (SPECIFIED(rc)) {
|
|
||||||
+ if (m->negated) {
|
|
||||||
+ user_matched = rc == ALLOW ? DENY : ALLOW;
|
|
||||||
+ } else {
|
|
||||||
+ user_matched = rc;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
alias_put(a);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
FALLTHROUGH;
|
|
||||||
case WORD:
|
|
||||||
if (userpw_matches(m->name, runas_pw->pw_name, runas_pw))
|
|
||||||
- user_matched = !m->negated;
|
|
||||||
+ user_matched = m->negated ? DENY : ALLOW;
|
|
||||||
break;
|
|
||||||
case MYSELF:
|
|
||||||
if (!ISSET(sudo_user.flags, RUNAS_USER_SPECIFIED) ||
|
|
||||||
strcmp(user_name, runas_pw->pw_name) == 0)
|
|
||||||
- user_matched = !m->negated;
|
|
||||||
+ user_matched = m->negated ? DENY : ALLOW;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
- if (user_matched != UNSPEC) {
|
|
||||||
+ if (SPECIFIED(user_matched)) {
|
|
||||||
if (matching_user != NULL && m->type != ALIAS)
|
|
||||||
*matching_user = m;
|
|
||||||
break;
|
|
||||||
@@ -226,34 +238,40 @@ runaslist_matches(struct sudoers_parse_t
|
|
||||||
TAILQ_FOREACH_REVERSE(m, group_list, member_list, entries) {
|
|
||||||
switch (m->type) {
|
|
||||||
case ALL:
|
|
||||||
- group_matched = !m->negated;
|
|
||||||
+ group_matched = m->negated ? DENY : ALLOW;
|
|
||||||
break;
|
|
||||||
case ALIAS:
|
|
||||||
a = alias_get(parse_tree, m->name, RUNASALIAS);
|
|
||||||
if (a != NULL) {
|
|
||||||
rc = runaslist_matches(parse_tree, &empty,
|
|
||||||
&a->members, NULL, matching_group);
|
|
||||||
- if (rc != UNSPEC)
|
|
||||||
- group_matched = m->negated ? !rc : rc;
|
|
||||||
+ if (SPECIFIED(rc)) {
|
|
||||||
+ if (m->negated) {
|
|
||||||
+ group_matched = rc == ALLOW ? DENY : ALLOW;
|
|
||||||
+ } else {
|
|
||||||
+ group_matched = rc;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
alias_put(a);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
FALLTHROUGH;
|
|
||||||
case WORD:
|
|
||||||
if (group_matches(m->name, runas_gr))
|
|
||||||
- group_matched = !m->negated;
|
|
||||||
+ group_matched = m->negated ? DENY : ALLOW;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
- if (group_matched != UNSPEC) {
|
|
||||||
+ if (SPECIFIED(group_matched)) {
|
|
||||||
if (matching_group != NULL && m->type != ALIAS)
|
|
||||||
*matching_group = m;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
- if (group_matched == UNSPEC) {
|
|
||||||
+ if (!SPECIFIED(group_matched)) {
|
|
||||||
struct gid_list *runas_groups;
|
|
||||||
/*
|
|
||||||
+ *
|
|
||||||
* The runas group was not explicitly allowed by sudoers.
|
|
||||||
* Check whether it is one of the target user's groups.
|
|
||||||
*/
|
|
||||||
@@ -295,7 +313,7 @@ hostlist_matches_int(struct sudoers_pars
|
|
||||||
|
|
||||||
TAILQ_FOREACH_REVERSE(m, list, member_list, entries) {
|
|
||||||
matched = host_matches(parse_tree, pw, lhost, shost, m);
|
|
||||||
- if (matched != UNSPEC)
|
|
||||||
+ if (SPECIFIED(matched))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
debug_return_int(matched);
|
|
||||||
@@ -324,37 +342,42 @@ host_matches(struct sudoers_parse_tree *
|
|
||||||
const char *lhost, const char *shost, const struct member *m)
|
|
||||||
{
|
|
||||||
struct alias *a;
|
|
||||||
- int matched = UNSPEC;
|
|
||||||
+ int rc, matched = UNSPEC;
|
|
||||||
debug_decl(host_matches, SUDOERS_DEBUG_MATCH);
|
|
||||||
|
|
||||||
switch (m->type) {
|
|
||||||
case ALL:
|
|
||||||
- matched = !m->negated;
|
|
||||||
+ matched = m->negated ? DENY : ALLOW;
|
|
||||||
break;
|
|
||||||
case NETGROUP:
|
|
||||||
if (netgr_matches(m->name, lhost, shost,
|
|
||||||
def_netgroup_tuple ? pw->pw_name : NULL))
|
|
||||||
- matched = !m->negated;
|
|
||||||
+ matched = m->negated ? DENY : ALLOW;
|
|
||||||
break;
|
|
||||||
case NTWKADDR:
|
|
||||||
if (addr_matches(m->name))
|
|
||||||
- matched = !m->negated;
|
|
||||||
+ matched = m->negated ? DENY : ALLOW;
|
|
||||||
break;
|
|
||||||
case ALIAS:
|
|
||||||
a = alias_get(parse_tree, m->name, HOSTALIAS);
|
|
||||||
if (a != NULL) {
|
|
||||||
/* XXX */
|
|
||||||
- int rc = hostlist_matches_int(parse_tree, pw, lhost, shost,
|
|
||||||
+ rc = hostlist_matches_int(parse_tree, pw, lhost, shost,
|
|
||||||
&a->members);
|
|
||||||
- if (rc != UNSPEC)
|
|
||||||
- matched = m->negated ? !rc : rc;
|
|
||||||
+ if (SPECIFIED(rc)) {
|
|
||||||
+ if (m->negated) {
|
|
||||||
+ matched = rc == ALLOW ? DENY : ALLOW;
|
|
||||||
+ } else {
|
|
||||||
+ matched = rc;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
alias_put(a);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
FALLTHROUGH;
|
|
||||||
case WORD:
|
|
||||||
if (hostname_matches(shost, lhost, m->name))
|
|
||||||
- matched = !m->negated;
|
|
||||||
+ matched = m->negated ? DENY : ALLOW;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
debug_return_int(matched);
|
|
||||||
@@ -375,7 +398,7 @@ cmndlist_matches(struct sudoers_parse_tr
|
|
||||||
|
|
||||||
TAILQ_FOREACH_REVERSE(m, list, member_list, entries) {
|
|
||||||
matched = cmnd_matches(parse_tree, m, runchroot, info);
|
|
||||||
- if (matched != UNSPEC)
|
|
||||||
+ if (SPECIFIED(matched))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
debug_return_int(matched);
|
|
||||||
@@ -397,21 +420,26 @@ cmnd_matches(struct sudoers_parse_tree *
|
|
||||||
switch (m->type) {
|
|
||||||
case ALL:
|
|
||||||
if (m->name == NULL) {
|
|
||||||
- matched = !m->negated;
|
|
||||||
+ matched = m->negated ? DENY : ALLOW;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
FALLTHROUGH;
|
|
||||||
case COMMAND:
|
|
||||||
c = (struct sudo_command *)m->name;
|
|
||||||
if (command_matches(c->cmnd, c->args, runchroot, info, &c->digests))
|
|
||||||
- matched = !m->negated;
|
|
||||||
+ matched = m->negated ? DENY : ALLOW;
|
|
||||||
break;
|
|
||||||
case ALIAS:
|
|
||||||
a = alias_get(parse_tree, m->name, CMNDALIAS);
|
|
||||||
if (a != NULL) {
|
|
||||||
rc = cmndlist_matches(parse_tree, &a->members, runchroot, info);
|
|
||||||
- if (rc != UNSPEC)
|
|
||||||
- matched = m->negated ? !rc : rc;
|
|
||||||
+ if (SPECIFIED(rc)) {
|
|
||||||
+ if (m->negated) {
|
|
||||||
+ matched = rc == ALLOW ? DENY : ALLOW;
|
|
||||||
+ } else {
|
|
||||||
+ matched = rc;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
alias_put(a);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
diff -up ./plugins/sudoers/parse.c.rowhammer ./plugins/sudoers/parse.c
|
|
||||||
--- ./plugins/sudoers/parse.c.rowhammer 2020-12-17 02:33:43.000000000 +0100
|
|
||||||
+++ ./plugins/sudoers/parse.c 2024-01-22 16:01:16.333874689 +0100
|
|
||||||
@@ -151,7 +151,7 @@ sudoers_lookup_check(struct sudo_nss *ns
|
|
||||||
if (runas_match == ALLOW) {
|
|
||||||
cmnd_match = cmnd_matches(nss->parse_tree, cs->cmnd,
|
|
||||||
cs->runchroot, info);
|
|
||||||
- if (cmnd_match != UNSPEC) {
|
|
||||||
+ if (SPECIFIED(cmnd_match)) {
|
|
||||||
/*
|
|
||||||
* If user is running command as himself,
|
|
||||||
* set runas_pw = sudo_user.pw.
|
|
||||||
@@ -365,7 +365,7 @@ sudoers_lookup(struct sudo_nss_list *snl
|
|
||||||
}
|
|
||||||
|
|
||||||
m = sudoers_lookup_check(nss, pw, &validated, &info, &cs, &defs, now);
|
|
||||||
- if (m != UNSPEC) {
|
|
||||||
+ if (SPECIFIED(m)) {
|
|
||||||
match = m;
|
|
||||||
parse_tree = nss->parse_tree;
|
|
||||||
}
|
|
||||||
@@ -373,7 +373,7 @@ sudoers_lookup(struct sudo_nss_list *snl
|
|
||||||
if (!sudo_nss_can_continue(nss, m))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
- if (match != UNSPEC) {
|
|
||||||
+ if (SPECIFIED(match)) {
|
|
||||||
if (info.cmnd_path != NULL) {
|
|
||||||
/* Update user_cmnd, user_stat, cmnd_status from matching entry. */
|
|
||||||
free(user_cmnd);
|
|
||||||
diff -up ./plugins/sudoers/parse.h.rowhammer ./plugins/sudoers/parse.h
|
|
||||||
--- ./plugins/sudoers/parse.h.rowhammer 2021-01-09 21:12:16.000000000 +0100
|
|
||||||
+++ ./plugins/sudoers/parse.h 2024-01-22 16:01:16.333874689 +0100
|
|
||||||
@@ -20,6 +20,9 @@
|
|
||||||
#ifndef SUDOERS_PARSE_H
|
|
||||||
#define SUDOERS_PARSE_H
|
|
||||||
|
|
||||||
+#include <stdbool.h>
|
|
||||||
+#include <stddef.h>
|
|
||||||
+#include <stdio.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include "sudo_queue.h"
|
|
||||||
|
|
||||||
@@ -31,13 +34,26 @@
|
|
||||||
|
|
||||||
#undef UNSPEC
|
|
||||||
#define UNSPEC -1
|
|
||||||
+
|
|
||||||
+/* Denied by policy (rowhammer resistent). */
|
|
||||||
#undef DENY
|
|
||||||
-#define DENY 0
|
|
||||||
+#define DENY 0xad5d6da /* 1010110101011101011011011010 */
|
|
||||||
+
|
|
||||||
+/* Allowed by policy (rowhammer resistent). */
|
|
||||||
#undef ALLOW
|
|
||||||
-#define ALLOW 1
|
|
||||||
+#define ALLOW 0x52a2925 /* 0101001010100010100100100101 */
|
|
||||||
+
|
|
||||||
#undef IMPLIED
|
|
||||||
#define IMPLIED 2
|
|
||||||
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * We must explicitly check against ALLOW and DENY instead testing
|
|
||||||
+ * that the value is not UNSPEC to avoid potential ROWHAMMER issues.
|
|
||||||
+ */
|
|
||||||
+#define SPECIFIED(_v) ((_v) == ALLOW || (_v) == DENY)
|
|
||||||
+
|
|
||||||
+
|
|
||||||
/*
|
|
||||||
* Initialize all tags to UNSPEC.
|
|
||||||
*/
|
|
25
SOURCES/sudo-conf.patch
Normal file
25
SOURCES/sudo-conf.patch
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
diff -up ./examples/sudo.conf.in.fix ./examples/sudo.conf.in
|
||||||
|
--- ./examples/sudo.conf.in.fix 2021-07-09 16:29:45.854347994 +0200
|
||||||
|
+++ ./examples/sudo.conf.in 2021-07-09 16:31:01.144410540 +0200
|
||||||
|
@@ -11,9 +11,9 @@
|
||||||
|
# The plugin_options are optional.
|
||||||
|
#
|
||||||
|
# The sudoers plugin is used by default if no Plugin lines are present.
|
||||||
|
-#Plugin sudoers_policy sudoers.so
|
||||||
|
-#Plugin sudoers_io sudoers.so
|
||||||
|
-#Plugin sudoers_audit sudoers.so
|
||||||
|
+Plugin sudoers_policy sudoers.so
|
||||||
|
+Plugin sudoers_io sudoers.so
|
||||||
|
+Plugin sudoers_audit sudoers.so
|
||||||
|
|
||||||
|
#
|
||||||
|
# Sudo askpass:
|
||||||
|
@@ -78,7 +78,7 @@
|
||||||
|
# To aid in debugging sudo problems, you may wish to enable core
|
||||||
|
# dumps by setting "disable_coredump" to false.
|
||||||
|
#
|
||||||
|
-#Set disable_coredump false
|
||||||
|
+Set disable_coredump false
|
||||||
|
|
||||||
|
#
|
||||||
|
# User groups:
|
@ -1,57 +0,0 @@
|
|||||||
#
|
|
||||||
# Default /etc/sudo.conf file
|
|
||||||
#
|
|
||||||
# Format:
|
|
||||||
# Plugin plugin_name plugin_path plugin_options ...
|
|
||||||
# Path askpass /path/to/askpass
|
|
||||||
# Path noexec /path/to/sudo_noexec.so
|
|
||||||
# Debug sudo /var/log/sudo_debug all@warn
|
|
||||||
# Set disable_coredump true
|
|
||||||
#
|
|
||||||
# Sudo plugins:
|
|
||||||
#
|
|
||||||
# The plugin_path is relative to ${prefix}/libexec unless fully qualified.
|
|
||||||
# The plugin_name corresponds to a global symbol in the plugin
|
|
||||||
# that contains the plugin interface structure.
|
|
||||||
# The plugin_options are optional.
|
|
||||||
#
|
|
||||||
# The sudoers plugin is used by default if no Plugin lines are present.
|
|
||||||
Plugin sudoers_policy sudoers.so
|
|
||||||
Plugin sudoers_io sudoers.so
|
|
||||||
|
|
||||||
#
|
|
||||||
# Sudo askpass:
|
|
||||||
#
|
|
||||||
# An askpass helper program may be specified to provide a graphical
|
|
||||||
# password prompt for "sudo -A" support. Sudo does not ship with its
|
|
||||||
# own passpass program but can use the OpenSSH askpass.
|
|
||||||
#
|
|
||||||
# Use the OpenSSH askpass
|
|
||||||
#Path askpass /usr/X11R6/bin/ssh-askpass
|
|
||||||
#
|
|
||||||
# Use the Gnome OpenSSH askpass
|
|
||||||
#Path askpass /usr/libexec/openssh/gnome-ssh-askpass
|
|
||||||
|
|
||||||
#
|
|
||||||
# Sudo noexec:
|
|
||||||
#
|
|
||||||
# Path to a shared library containing dummy versions of the execv(),
|
|
||||||
# execve() and fexecve() library functions that just return an error.
|
|
||||||
# This is used to implement the "noexec" functionality on systems that
|
|
||||||
# support C<LD_PRELOAD> or its equivalent.
|
|
||||||
# The compiled-in value is usually sufficient and should only be changed
|
|
||||||
# if you rename or move the sudo_noexec.so file.
|
|
||||||
#
|
|
||||||
#Path noexec /usr/libexec/sudo_noexec.so
|
|
||||||
|
|
||||||
#
|
|
||||||
# Core dumps:
|
|
||||||
#
|
|
||||||
# By default, sudo disables core dumps while it is executing (they
|
|
||||||
# are re-enabled for the command that is run).
|
|
||||||
# To aid in debugging sudo problems, you may wish to enable core
|
|
||||||
# dumps by setting "disable_coredump" to false.
|
|
||||||
#
|
|
||||||
# Set to false here so as not to interfere with /proc/sys/fs/suid_dumpable
|
|
||||||
#
|
|
||||||
Set disable_coredump false
|
|
363
SPECS/sudo.spec
363
SPECS/sudo.spec
@ -1,36 +1,31 @@
|
|||||||
Summary: Allows restricted root access for specified users
|
Summary: Allows restricted root access for specified users
|
||||||
Name: sudo
|
Name: sudo
|
||||||
Version: 1.9.5p2
|
Version: 1.9.5p2
|
||||||
Release: 1%{?dist}
|
Release: 9%{?dist}
|
||||||
License: ISC
|
License: ISC
|
||||||
Group: Applications/System
|
URL: https://www.sudo.ws
|
||||||
URL: https://www.sudo.ws/
|
|
||||||
|
|
||||||
Source0: https://www.sudo.ws/dist/%{name}-%{version}.tar.gz
|
Source0: %{url}/dist/%{name}-%{version}.tar.gz
|
||||||
Source1: sudoers
|
Source1: sudoers
|
||||||
Source2: sudo-ldap.conf
|
Source2: sudo-ldap.conf
|
||||||
Source3: sudo.conf
|
|
||||||
|
|
||||||
Requires: /etc/pam.d/system-auth
|
Requires: pam
|
||||||
Requires: /usr/bin/vi
|
Requires(post): coreutils
|
||||||
Requires(post): /bin/chmod
|
|
||||||
|
|
||||||
BuildRequires: /usr/sbin/sendmail
|
BuildRequires: make
|
||||||
BuildRequires: autoconf
|
|
||||||
BuildRequires: automake
|
|
||||||
BuildRequires: bison
|
|
||||||
BuildRequires: flex
|
|
||||||
BuildRequires: gettext
|
|
||||||
BuildRequires: groff
|
|
||||||
BuildRequires: libtool
|
|
||||||
BuildRequires: audit-libs-devel
|
|
||||||
BuildRequires: libcap-devel
|
|
||||||
BuildRequires: libgcrypt-devel
|
|
||||||
BuildRequires: libselinux-devel
|
|
||||||
BuildRequires: openldap-devel
|
|
||||||
BuildRequires: pam-devel
|
BuildRequires: pam-devel
|
||||||
|
BuildRequires: groff
|
||||||
|
BuildRequires: openldap-devel
|
||||||
|
BuildRequires: flex
|
||||||
|
BuildRequires: bison
|
||||||
|
BuildRequires: automake autoconf libtool
|
||||||
|
BuildRequires: audit-libs-devel libcap-devel
|
||||||
|
BuildRequires: libselinux-devel
|
||||||
|
BuildRequires: sendmail
|
||||||
|
BuildRequires: gettext
|
||||||
BuildRequires: zlib-devel
|
BuildRequires: zlib-devel
|
||||||
|
|
||||||
|
Patch1: sudo-conf.patch
|
||||||
Patch2: sudo-1.9.5-undefined-symbol.patch
|
Patch2: sudo-1.9.5-undefined-symbol.patch
|
||||||
Patch3: sudo-1.9.5-selinux-t.patch
|
Patch3: sudo-1.9.5-selinux-t.patch
|
||||||
Patch4: sudo-1.9.5-sesh-bad-condition.patch
|
Patch4: sudo-1.9.5-sesh-bad-condition.patch
|
||||||
@ -39,20 +34,6 @@ Patch6: covscan.patch
|
|||||||
Patch7: sha-digest-calc.patch
|
Patch7: sha-digest-calc.patch
|
||||||
Patch8: sudo-1.9.12-CVE-2023-22809.patch
|
Patch8: sudo-1.9.12-CVE-2023-22809.patch
|
||||||
|
|
||||||
Patch9: sudo-1.9.13-CVE-2023-28486-7-1.patch
|
|
||||||
Patch10: sudo-1.9.13-CVE-2023-28486-7-2.patch
|
|
||||||
Patch11: sudo-1.9.13-CVE-2023-28486-7-3.patch
|
|
||||||
Patch12: sudo-1.9.13-CVE-2023-28486-7-4.patch
|
|
||||||
Patch13: sudo-1.9.13-CVE-2023-28486-7-5.patch
|
|
||||||
Patch14: sudo-1.9.13-CVE-2023-28486-7-6.patch
|
|
||||||
Patch15: sudo-1.9.13-CVE-2023-28486-7-7.patch
|
|
||||||
Patch16: sudo-1.9.13-CVE-2023-28486-7-8.patch
|
|
||||||
Patch17: sudo-1.9.13-CVE-2023-28486-7-9.patch
|
|
||||||
|
|
||||||
Patch18: linker.patch
|
|
||||||
|
|
||||||
Patch19: sudo-1.9.15-CVE-2023-42465.patch
|
|
||||||
|
|
||||||
%description
|
%description
|
||||||
Sudo (superuser do) allows a system administrator to give certain
|
Sudo (superuser do) allows a system administrator to give certain
|
||||||
users (or groups of users) the ability to run some (or all) commands
|
users (or groups of users) the ability to run some (or all) commands
|
||||||
@ -66,37 +47,32 @@ on many different machines.
|
|||||||
|
|
||||||
%package devel
|
%package devel
|
||||||
Summary: Development files for %{name}
|
Summary: Development files for %{name}
|
||||||
Group: Development/Libraries
|
|
||||||
Requires: %{name} = %{version}-%{release}
|
Requires: %{name} = %{version}-%{release}
|
||||||
|
|
||||||
%description devel
|
%description devel
|
||||||
The %{name}-devel package contains header files developing sudo
|
The %{name}-devel package contains header files developing sudo
|
||||||
plugins that use %{name}.
|
plugins that use %{name}.
|
||||||
|
|
||||||
|
%package python-plugin
|
||||||
|
Summary: Python plugin for %{name}
|
||||||
|
Requires: %{name} = %{version}-%{release}
|
||||||
|
BuildRequires: python3-devel
|
||||||
|
|
||||||
|
|
||||||
|
%description python-plugin
|
||||||
|
%{name}-python-plugin allows using sudo plugins written in Python.
|
||||||
|
|
||||||
%prep
|
%prep
|
||||||
%setup -q
|
%setup -q
|
||||||
|
|
||||||
%patch -P 2 -p1 -b .undefined
|
%patch1 -p1 -b .sudo-conf
|
||||||
%patch -P 3 -p1 -b .selinux-t
|
%patch2 -p1 -b .undefined
|
||||||
%patch -P 4 -p1 -b .bad-cond
|
%patch3 -p1 -b .selinux-t
|
||||||
%patch -P 5 -p1 -b .utmp-leak
|
%patch4 -p1 -b .bad-cond
|
||||||
%patch -P 6 -p1 -b .covscan
|
%patch5 -p1 -b .utmp-leak
|
||||||
%patch -P 7 -p1 -b .sha-digest
|
%patch6 -p1 -b .covscan
|
||||||
%patch -P 8 -p1 -b .cve-fix
|
%patch7 -p1 -b .sha-digest
|
||||||
|
%patch8 -p1 -b .cve-fix
|
||||||
%patch -P 9 -p1 -b .cve-escape-1
|
|
||||||
%patch -P 10 -p1 -b .cve-escape-2
|
|
||||||
%patch -P 11 -p1 -b .cve-escape-3
|
|
||||||
%patch -P 12 -p1 -b .cve-escape-4
|
|
||||||
%patch -P 13 -p1 -b .cve-escape-5
|
|
||||||
%patch -P 14 -p1 -b .cve-escape-6
|
|
||||||
%patch -P 15 -p1 -b .cve-escape-7
|
|
||||||
%patch -P 16 -p1 -b .cve-escape-8
|
|
||||||
%patch -P 17 -p1 -b .cve-escape-9
|
|
||||||
|
|
||||||
%patch -P 18 -p1 -b .linker
|
|
||||||
|
|
||||||
%patch -P 19 -p1 -b .rowhammer
|
|
||||||
|
|
||||||
%build
|
%build
|
||||||
# Remove bundled copy of zlib
|
# Remove bundled copy of zlib
|
||||||
@ -132,8 +108,8 @@ export CFLAGS="$RPM_OPT_FLAGS $F_PIE" LDFLAGS="-pie -Wl,-z,relro -Wl,-z,now"
|
|||||||
--with-ldap-conf-file="%{_sysconfdir}/sudo-ldap.conf" \
|
--with-ldap-conf-file="%{_sysconfdir}/sudo-ldap.conf" \
|
||||||
--with-selinux \
|
--with-selinux \
|
||||||
--with-passprompt="[sudo] password for %p: " \
|
--with-passprompt="[sudo] password for %p: " \
|
||||||
|
--enable-python \
|
||||||
--with-linux-audit \
|
--with-linux-audit \
|
||||||
--disable-python \
|
|
||||||
--with-sssd
|
--with-sssd
|
||||||
# --without-kerb5 \
|
# --without-kerb5 \
|
||||||
# --without-kerb4
|
# --without-kerb4
|
||||||
@ -149,14 +125,13 @@ rm -rf $RPM_BUILD_ROOT
|
|||||||
sed -i 's|/etc/ldap\.conf|%{_sysconfdir}/sudo-ldap.conf|g' README.LDAP
|
sed -i 's|/etc/ldap\.conf|%{_sysconfdir}/sudo-ldap.conf|g' README.LDAP
|
||||||
|
|
||||||
make install DESTDIR="$RPM_BUILD_ROOT" install_uid=`id -u` install_gid=`id -g` sudoers_uid=`id -u` sudoers_gid=`id -g`
|
make install DESTDIR="$RPM_BUILD_ROOT" install_uid=`id -u` install_gid=`id -g` sudoers_uid=`id -u` sudoers_gid=`id -g`
|
||||||
|
|
||||||
chmod 755 $RPM_BUILD_ROOT%{_bindir}/* $RPM_BUILD_ROOT%{_sbindir}/*
|
chmod 755 $RPM_BUILD_ROOT%{_bindir}/* $RPM_BUILD_ROOT%{_sbindir}/*
|
||||||
install -p -d -m 700 $RPM_BUILD_ROOT/var/db/sudo
|
install -p -d -m 700 $RPM_BUILD_ROOT/var/db/sudo
|
||||||
install -p -d -m 700 $RPM_BUILD_ROOT/var/db/sudo/lectured
|
install -p -d -m 700 $RPM_BUILD_ROOT/var/db/sudo/lectured
|
||||||
install -p -d -m 750 $RPM_BUILD_ROOT/etc/sudoers.d
|
install -p -d -m 750 $RPM_BUILD_ROOT/etc/sudoers.d
|
||||||
install -p -c -m 0440 %{SOURCE1} $RPM_BUILD_ROOT/etc/sudoers
|
install -p -c -m 0440 %{SOURCE1} $RPM_BUILD_ROOT/etc/sudoers
|
||||||
install -p -c -m 0640 %{SOURCE2} $RPM_BUILD_ROOT/%{_sysconfdir}/sudo-ldap.conf
|
install -p -c -m 0640 %{SOURCE2} $RPM_BUILD_ROOT/%{_sysconfdir}/sudo-ldap.conf
|
||||||
install -p -c -m 0640 %{SOURCE3} $RPM_BUILD_ROOT/%{_sysconfdir}/sudo.conf
|
|
||||||
|
|
||||||
|
|
||||||
# create sudo-ldap.conf man
|
# create sudo-ldap.conf man
|
||||||
echo ".so man5/sudoers.ldap.5" > sudo-ldap.conf.5
|
echo ".so man5/sudoers.ldap.5" > sudo-ldap.conf.5
|
||||||
@ -167,7 +142,7 @@ rm -f sudo-ldap.conf.5.gz
|
|||||||
# we are not building sendlog so we don't need this
|
# we are not building sendlog so we don't need this
|
||||||
rm -rf $RPM_BUILD_ROOT/%{_mandir}/man8/sudo_sendlog.8
|
rm -rf $RPM_BUILD_ROOT/%{_mandir}/man8/sudo_sendlog.8
|
||||||
|
|
||||||
# Add sudo to protected packages
|
# add sudo to protected packages
|
||||||
install -p -d -m 755 $RPM_BUILD_ROOT/etc/dnf/protected.d/
|
install -p -d -m 755 $RPM_BUILD_ROOT/etc/dnf/protected.d/
|
||||||
touch sudo.conf
|
touch sudo.conf
|
||||||
echo sudo > sudo.conf
|
echo sudo > sudo.conf
|
||||||
@ -182,7 +157,7 @@ rm -rf $RPM_BUILD_ROOT%{_pkgdocdir}/LICENSE
|
|||||||
# Remove examples; Examples can be found in man pages too.
|
# Remove examples; Examples can be found in man pages too.
|
||||||
rm -rf $RPM_BUILD_ROOT%{_datadir}/examples/sudo
|
rm -rf $RPM_BUILD_ROOT%{_datadir}/examples/sudo
|
||||||
|
|
||||||
# Remove all .la files
|
#Remove all .la files
|
||||||
find $RPM_BUILD_ROOT -name '*.la' -exec rm -f {} ';'
|
find $RPM_BUILD_ROOT -name '*.la' -exec rm -f {} ';'
|
||||||
|
|
||||||
# Remove sudoers.dist
|
# Remove sudoers.dist
|
||||||
@ -195,6 +170,7 @@ cat sudo.lang sudoers.lang > sudo_all.lang
|
|||||||
rm sudo.lang sudoers.lang
|
rm sudo.lang sudoers.lang
|
||||||
|
|
||||||
mkdir -p $RPM_BUILD_ROOT/etc/pam.d
|
mkdir -p $RPM_BUILD_ROOT/etc/pam.d
|
||||||
|
|
||||||
cat > $RPM_BUILD_ROOT/etc/pam.d/sudo << EOF
|
cat > $RPM_BUILD_ROOT/etc/pam.d/sudo << EOF
|
||||||
#%%PAM-1.0
|
#%%PAM-1.0
|
||||||
auth include system-auth
|
auth include system-auth
|
||||||
@ -212,10 +188,6 @@ session optional pam_keyinit.so force revoke
|
|||||||
session include sudo
|
session include sudo
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
|
||||||
%clean
|
|
||||||
rm -rf $RPM_BUILD_ROOT
|
|
||||||
|
|
||||||
%files -f sudo_all.lang
|
%files -f sudo_all.lang
|
||||||
%defattr(-,root,root)
|
%defattr(-,root,root)
|
||||||
%attr(0440,root,root) %config(noreplace) /etc/sudoers
|
%attr(0440,root,root) %config(noreplace) /etc/sudoers
|
||||||
@ -225,7 +197,7 @@ rm -rf $RPM_BUILD_ROOT
|
|||||||
%config(noreplace) /etc/pam.d/sudo
|
%config(noreplace) /etc/pam.d/sudo
|
||||||
%config(noreplace) /etc/pam.d/sudo-i
|
%config(noreplace) /etc/pam.d/sudo-i
|
||||||
%attr(0644,root,root) %{_tmpfilesdir}/sudo.conf
|
%attr(0644,root,root) %{_tmpfilesdir}/sudo.conf
|
||||||
%attr(0644,root,root) /etc/dnf/protected.d/sudo.conf
|
%attr(0644,root,root) %config(noreplace) /etc/dnf/protected.d/sudo.conf
|
||||||
%dir /var/db/sudo
|
%dir /var/db/sudo
|
||||||
%dir /var/db/sudo/lectured
|
%dir /var/db/sudo/lectured
|
||||||
%attr(4111,root,root) %{_bindir}/sudo
|
%attr(4111,root,root) %{_bindir}/sudo
|
||||||
@ -260,136 +232,195 @@ rm -rf $RPM_BUILD_ROOT
|
|||||||
%license doc/LICENSE
|
%license doc/LICENSE
|
||||||
%exclude %{_pkgdocdir}/ChangeLog
|
%exclude %{_pkgdocdir}/ChangeLog
|
||||||
|
|
||||||
|
|
||||||
# Make sure permissions are ok even if we're updating
|
# Make sure permissions are ok even if we're updating
|
||||||
%post
|
%post
|
||||||
/bin/chmod 0440 /etc/sudoers || :
|
/bin/chmod 0440 /etc/sudoers || :
|
||||||
|
|
||||||
|
|
||||||
%files devel
|
%files devel
|
||||||
%defattr(-,root,root,-)
|
|
||||||
%doc plugins/sample/sample_plugin.c
|
%doc plugins/sample/sample_plugin.c
|
||||||
%{_includedir}/sudo_plugin.h
|
%{_includedir}/sudo_plugin.h
|
||||||
%{_mandir}/man8/sudo_plugin.8*
|
%{_mandir}/man8/sudo_plugin.8*
|
||||||
|
|
||||||
|
%files python-plugin
|
||||||
|
%{_mandir}/man8/sudo_plugin_python.8.gz
|
||||||
|
%attr(0644,root,root) %{_libexecdir}/sudo/python_plugin.so
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
* Mon Jan 22 2024 Radovan Sroka <rsroka@redhat.com> - 1.9.5p2-1
|
* Thu Jan 19 2023 Radovan Sroka <rsroka@redhat.com> - 1.9.5p2-9
|
||||||
RHEL 8.9.0.Z ERRATUM
|
RHEL 9.2.0 ERRATUM
|
||||||
- Rebase to 1.9.5p2
|
|
||||||
- CVE-2023-28486 sudo: Sudo does not escape control characters in log messages
|
|
||||||
Resolves: RHEL-21825
|
|
||||||
- CVE-2023-28487 sudo: Sudo does not escape control characters in sudoreplay output
|
|
||||||
Resolves: RHEL-21831
|
|
||||||
- CVE-2023-42465 sudo: Targeted Corruption of Register and Stack Variables
|
|
||||||
Resolves: RHEL-21820
|
|
||||||
|
|
||||||
* Wed Jan 11 2023 Radovan Sroka <rsroka@redhat.com> - 1.8.29.9
|
|
||||||
RHEL 8.8.0 ERRATUM
|
|
||||||
- CVE-2023-22809 sudo: arbitrary file write with privileges of the RunAs user
|
- CVE-2023-22809 sudo: arbitrary file write with privileges of the RunAs user
|
||||||
Resolves: rhbz#2161221
|
Resolves: rhbz#2161225
|
||||||
|
|
||||||
|
* Wed Jan 11 2023 Radovan Sroka <rsroka@redhat.com> - 1.9.5p2-8
|
||||||
|
RHEL 9.2.0 ERRATUM
|
||||||
- sudo digest check fails incorrectly for certain file sizes (SHA512/SHA384)
|
- sudo digest check fails incorrectly for certain file sizes (SHA512/SHA384)
|
||||||
Resolves: rhbz#2114576
|
Resolves: rhbz#2115789
|
||||||
|
|
||||||
* Mon Dec 06 2021 Radovan Sroka <rsroka@redhat.com> - 1.8.29-8
|
* Fri Aug 20 2021 Radovan Sroka <rsroka@redhat.com> - 1.9.5p2-7
|
||||||
RHEL 8.6.0 ERRATUM
|
|
||||||
- sudoedit does not work with selinux args
|
|
||||||
Resolves: rhbz#2029551
|
|
||||||
- Make sure SIGCHLD is not ignored when sudo is executed
|
|
||||||
Resolves: rhbz#1999751
|
|
||||||
- [RFE] pass KRB5CCNAME to pam_authenticate environment if available
|
|
||||||
Resolves: rhbz#1917379
|
|
||||||
- utmp resource leak in sudo
|
- utmp resource leak in sudo
|
||||||
Resolves: rhbz#1986572
|
Resolves: rhbz#1986579
|
||||||
|
- sudo does not list /etc/dnf/protected.d/sudo.conf in the rpm config files listing
|
||||||
|
Resolves: rhbz#1997030
|
||||||
|
- sudo uses Recommends for sudo-python-plugin(x86-64) = 1.9.5p2-2.el9 and vim-minimal
|
||||||
|
Resolves: rhbz#1947908
|
||||||
|
- review of important potential issues detected by static analyzers in sudo-1.9.5p2-2.el9
|
||||||
|
Resolves: rhbz#1938879
|
||||||
|
|
||||||
* Tue Feb 02 2021 Radovan Sroka <rsroka@redhat.com> - 1.8.29-7
|
* Tue Aug 10 2021 Mohan Boddu <mboddu@redhat.com> - 1.9.5p2-6
|
||||||
- RHEL 8.4 ERRATUM
|
- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
|
||||||
- CVE-2021-3156
|
Related: rhbz#1991688
|
||||||
Resolves: rhbz#1917734
|
|
||||||
- CVE-2021-23239 sudo: possible directory existence test due to race condition in sudoedit
|
|
||||||
Resolves: rhzb#1916434
|
|
||||||
- CVE-2021-23240 sudo: symbolic link attack in SELinux-enabled sudoedit
|
|
||||||
Resolves: rhbz#1917038
|
|
||||||
- updated upstream url
|
|
||||||
Resolves: rhbz#1923825
|
|
||||||
|
|
||||||
* Tue Apr 28 2020 Radovan Sroka <rsroka@redhat.com> - 1.8.29-6
|
* Fri Jul 09 2021 Radovan Sroka <rsroka@redhat.com> - 1.9.5p2-5
|
||||||
- RHEL 8.3 ERRATUM
|
RHEL 9 BETA
|
||||||
- sudo allows privilege escalation with expire password
|
- sync with rhel8 spec
|
||||||
Resolves: rhbz#1815164
|
Resolves: rhbz#1908882
|
||||||
|
Resolves: rhbz#1942383
|
||||||
|
Resolves: rhbz#1946707
|
||||||
|
Resolves: rhbz#1946709
|
||||||
|
Resolves: rhbz#1981278
|
||||||
|
|
||||||
* Wed Feb 05 2020 Radovan Sroka <rsroka@redhat.com> - 1.8.29-5
|
* Wed Jun 16 2021 Mohan Boddu <mboddu@redhat.com> - 1.9.5p2-4
|
||||||
- RHEL 8.2 ERRATUM
|
- Rebuilt for RHEL 9 BETA for openssl 3.0
|
||||||
- CVE-2019-18634
|
Related: rhbz#1971065
|
||||||
Resolves: rhbz#1798093
|
|
||||||
|
|
||||||
* Tue Jan 14 2020 Radovan Sroka <rsroka@redhat.com> - 1.8.29-4
|
* Fri Apr 16 2021 Mohan Boddu <mboddu@redhat.com> - 1.9.5p2-3
|
||||||
- RHEL 8.2 ERRATUM
|
- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937
|
||||||
- CVE-2019-19232
|
|
||||||
Resolves: rhbz#1786987
|
|
||||||
Resolves: rhbz#1796518
|
|
||||||
|
|
||||||
* Wed Oct 30 2019 Radovan Sroka <rsroka@redhat.com> - 1.8.29-2
|
* Tue Feb 09 2021 Zoltan Fridrich <zfridric@redhat.com> - 1.9.5p2-2
|
||||||
- RHEL 8.2 ERRATUM
|
- change ldap.conf to sudo-ldap.conf
|
||||||
|
Resolves: rhbz#1908882
|
||||||
|
- remove /usr/local/* from secure_path
|
||||||
|
Resolves: rhbz#1908923
|
||||||
|
- fixed CVE-2021-23239 sudo: possible directory existence test due to race condition in sudoedit
|
||||||
|
Resolves: rhbz#1916655
|
||||||
|
- fixed CVE-2021-23240 sudo: symbolic link attack in SELinux-enabled sudoedit
|
||||||
|
Resolves: rhbz#1917039
|
||||||
|
- fixed CVE-2021-3156 sudo: Heap buffer overflow in argument parsing
|
||||||
|
Resolves: rhbz#1917735
|
||||||
|
|
||||||
|
* Tue Jan 26 2021 Matthew Miller <mattdm@fedoraproject.org> - 1.9.5p2-1
|
||||||
|
- rebase to 1.9.5p2
|
||||||
|
Resolves: rhbz#1920611
|
||||||
|
- fixed CVE-2021-3156 sudo: Heap buffer overflow in argument parsing
|
||||||
|
Resolves: rhbz#1920618
|
||||||
|
|
||||||
|
* Mon Jan 18 2021 Radovan Sroka <rsroka@redhat.com> - 1.9.5p1-1
|
||||||
|
- rebase to 1.9.5p1
|
||||||
|
Resolves: rhbz#1902758
|
||||||
|
- fixed double free in sss_to_sudoers
|
||||||
|
Resolves: rhbz#1885874
|
||||||
|
- fixed CVE-2021-23239 sudo: possible directory existence test due to race condition in sudoedit
|
||||||
|
Resolves: rhbz#1915055
|
||||||
|
- fixed CVE-2021-23240 sudo: symbolic link attack in SELinux-enabled sudoedit
|
||||||
|
Resolves: rhbz#1915054
|
||||||
|
|
||||||
|
* Wed Jan 13 2021 Jonathan Lebon <jonathan@jlebon.com> - 1.9.3p1-2
|
||||||
|
- split out Python modules into separate subpackage
|
||||||
|
Resolves: rhbz#1909299
|
||||||
|
|
||||||
|
* Mon Oct 05 2020 Radovan Sroka <rsroka@redhat.com> - 1.9.3p1-1
|
||||||
|
- rebase to 1.9.3p1
|
||||||
|
- enable python modules
|
||||||
|
Resolves: rhbz#1881112
|
||||||
|
|
||||||
|
* Tue Sep 15 2020 Radovan Sroka <rsroka@redhat.com> - 1.9.2-1
|
||||||
|
- rebase to 1.9.2
|
||||||
|
Resolves: rhbz#1859577
|
||||||
|
- added logsrvd subpackage
|
||||||
|
- added openssl-devel buildrequires
|
||||||
|
Resolves: rhbz#1860653
|
||||||
|
- fixed sudo runstatedir path
|
||||||
|
- it was generated as /sudo instead of /run/sudo
|
||||||
|
Resolves: rhbz#1868215
|
||||||
|
- added /var/lib/snapd/snap/bin to secure_path variable
|
||||||
|
Resolves: rhbz#1691996
|
||||||
|
|
||||||
|
* Sat Aug 01 2020 Fedora Release Engineering <releng@fedoraproject.org> - 1.9.1-3
|
||||||
|
- Second attempt - Rebuilt for
|
||||||
|
https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
|
||||||
|
|
||||||
|
* Wed Jul 29 2020 Fedora Release Engineering <releng@fedoraproject.org> - 1.9.1-2
|
||||||
|
- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
|
||||||
|
|
||||||
|
* Wed Jul 08 2020 Attila Lakatos <alakatos@redhat.com> - 1.9.1-1
|
||||||
|
- rebase to 1.9.1
|
||||||
|
Resolves: rhbz#1848788
|
||||||
|
- fix rpmlint errors
|
||||||
|
Resolves: rhbz#1817139
|
||||||
|
|
||||||
|
* Wed Mar 25 2020 Attila Lakatos <alakatos@redhat.com> - 1.9.0-0.1.b4
|
||||||
|
- update to latest development version 1.9.0b4
|
||||||
|
Resolves: rhbz#1816593
|
||||||
|
- setrlimit(RLIMIT_CORE): Operation not permitted warning message fix
|
||||||
|
Resolves: rhbz#1773148
|
||||||
|
|
||||||
|
* Mon Feb 24 2020 Attila Lakatos <alakatos@redhat.com> - 1.9.0-0.1.b1
|
||||||
|
- update to latest development version 1.9.0b1
|
||||||
|
- added sudo_logsrvd and sudo_sendlog to files and their appropriate man pages
|
||||||
|
Resolves: rhbz#1787823
|
||||||
|
- Stack based buffer overflow in when pwfeedback is enabled
|
||||||
|
Resolves: rhbz#1796945
|
||||||
|
- fixes: CVE-2019-18634
|
||||||
|
- By using ! character in the shadow file instead of a password hash can access to a run as all sudoer account
|
||||||
|
Resolves: rhbz#1786709
|
||||||
|
- fixes CVE-2019-19234
|
||||||
|
- attacker with access to a Runas ALL sudoer account can impersonate a nonexistent user
|
||||||
|
Resolves: rhbz#1786705
|
||||||
|
- fixes CVE-2019-19232
|
||||||
|
|
||||||
|
* Fri Jan 31 2020 Fedora Release Engineering <releng@fedoraproject.org> - 1.8.29-2
|
||||||
|
- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
|
||||||
|
|
||||||
|
* Mon Nov 11 2019 Radovan Sroka <rsroka@redhat.com> - 1.8.29-1
|
||||||
- rebase to 1.8.29
|
- rebase to 1.8.29
|
||||||
Resolves: rhbz#1733961
|
Resolves: rhbz#1766233
|
||||||
Resolves: rhbz#1651662
|
|
||||||
|
|
||||||
* Fri Oct 25 2019 Radovan Sroka <rsroka@redhat.com> - 1.8.28p1-1
|
* Tue Oct 22 2019 Radovan Sroka <rsroka@redhat.com> - 1.8.28p1-1
|
||||||
- RHEL 8.2 ERRATUM
|
|
||||||
- rebase to 1.8.28p1
|
- rebase to 1.8.28p1
|
||||||
Resolves: rhbz#1733961
|
Resolves: rhbz#1762350
|
||||||
- fixed man page for always_set_home
|
|
||||||
Resolves: rhbz#1576880
|
|
||||||
- sudo does not work with notbefore/after
|
|
||||||
Resolves: rhbz#1679508
|
|
||||||
- NOTBEFORE showing value of sudoNotAfter Ldap attribute
|
|
||||||
Resolves: rhbz#1715516
|
|
||||||
- CVE-2019-14287 sudo
|
|
||||||
- Privilege escalation via 'Runas' specification with 'ALL' keyword
|
|
||||||
Resolves: rhbz#1760697
|
|
||||||
|
|
||||||
* Fri Aug 16 2019 Radovan Sroka <rsroka@redhat.com> - 1.8.25-7
|
* Tue Oct 15 2019 Radovan Sroka <rsroka@redhat.com> - 1.8.28-1
|
||||||
- RHEL 8.1 ERRATUM
|
- rebase to 1.8.28
|
||||||
- sudo ipa_hostname not honored
|
Resolves: rhbz#1761533
|
||||||
Resolves: rhbz#1738662
|
- set always_set_home by default
|
||||||
|
Resolves: rhbz#1728687
|
||||||
|
- Sync sudoers options from rhel8 to fedora
|
||||||
|
Resolves: rhbz#1761781
|
||||||
|
- CVE-2019-14287
|
||||||
|
Resolves: rhbz#1761584
|
||||||
|
|
||||||
* Mon Aug 12 2019 Radovan Sroka <rsroka@redhat.com> - 1.8.25-6
|
* Sat Jul 27 2019 Fedora Release Engineering <releng@fedoraproject.org> - 1.8.27-3
|
||||||
- RHEL 8.1 ERRATUM
|
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
|
||||||
- Fixed The LDAP backend which is not properly parsing sudoOptions,
|
|
||||||
resulting in selinux roles not being applied
|
|
||||||
Resolves: rhbz#1738326
|
|
||||||
|
|
||||||
* Tue May 28 2019 Radovan Sroka <rsroka@redhat.com> - 1.8.25-5
|
* Sun Mar 31 2019 Marek Tamaskovic <mtamasko@redhat.com> 1.8.27-2
|
||||||
- RHEL 8.1 ERRATUM
|
- resolves rhbz#1676925
|
||||||
- Fixed problem with sudo-1.8.23 and 'who am i'
|
- Removed PS1, PS2 from sudoers
|
||||||
Resolves: rhbz#1673886
|
|
||||||
- Backporting sudo bug with expired passwords
|
|
||||||
Resolves: rhbz#1676819
|
|
||||||
|
|
||||||
* Tue Dec 11 2018 Radovan Sroka <rsroka@redhat.com> - 1.8.25-4
|
* Mon Mar 11 2019 Radovan Sroka <rsroka@redhat.com> 1.8.27-1
|
||||||
- Fix most of the man page scans problems
|
- rebase sudo to 1.8.27
|
||||||
- Resolves: rhbz#1613327
|
|
||||||
|
|
||||||
* Fri Oct 12 2018 Daniel Kopecek <dkopecek@redhat.com> - 1.8.25-3
|
* Sun Feb 03 2019 Fedora Release Engineering <releng@fedoraproject.org> - 1.8.25p1-2
|
||||||
- bump release for new build
|
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
|
||||||
Resolves: rhbz#1625683
|
|
||||||
|
|
||||||
* Thu Oct 11 2018 Daniel Kopecek <dkopecek@redhat.com> - 1.8.25-2
|
* Mon Oct 01 2018 Radovan Sroka <rsroka@redhat.com> 1.8.25p1-1
|
||||||
- Depend explicitly on /usr/sbin/sendmail instead of sendmail (rhel-7 sync)
|
- rebase sudo to 1.8.25p1
|
||||||
- Simplified pam configuration file by removing duplicate pam stack entries
|
|
||||||
Resolves: rhbz#1633144
|
|
||||||
|
|
||||||
* Wed Sep 26 2018 Radovan Sroka <rsroka@redhat.com> - 1.8.25-1
|
* Mon Sep 10 2018 Radovan Sroka <rsroka@redhat.com> 1.8.25-1
|
||||||
- rebase to the new upstream version 1.8.25p1
|
- rebase sudo to latest stawble version
|
||||||
- sync patches with rhel-7.6
|
- install /etc/dnf/protected.d/sudo instead of /etc/yum/protected.d/sudo (1626968)
|
||||||
- sync sudoers with rhel-7.6
|
|
||||||
resolves: rhbz#1633144
|
|
||||||
|
|
||||||
* Mon Sep 10 2018 Radovan Sroka <rsroka@redhat.com> - 1.8.23-2
|
* Sat Jul 14 2018 Fedora Release Engineering <releng@fedoraproject.org> - 1.8.23-3
|
||||||
- install /etc/dnf/protected.d/sudo instead of /etc/yum/protected.d/sudo
|
- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
|
||||||
resolves: rhbz#1626972
|
|
||||||
|
|
||||||
* Thu May 17 2018 Daniel Kopecek <dkopecek@redhat.com> - 1.8.23-1
|
* Tue Jul 03 2018 Matthew Miller <mattdm@fedoraproject.org> - 1.8.23-2
|
||||||
- Packaging update for RHEL 8.0 (sync with latest RHEL 7 state)
|
- remove defattr, as default is now sane
|
||||||
|
|
||||||
|
* Wed May 09 2018 Daniel Kopecek <dkopecek@redhat.com> - 1.8.23-1
|
||||||
|
- update to 1.8.23
|
||||||
|
|
||||||
|
* Wed Apr 18 2018 Daniel Kopecek <dkopecek@redhat.com> - 1.8.23-0.1.b3
|
||||||
|
- update to 1.8.23b3
|
||||||
|
|
||||||
* Fri Feb 09 2018 Fedora Release Engineering <releng@fedoraproject.org> - 1.8.22-0.2.b1
|
* Fri Feb 09 2018 Fedora Release Engineering <releng@fedoraproject.org> - 1.8.22-0.2.b1
|
||||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
|
- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
|
||||||
|
Loading…
Reference in New Issue
Block a user