Add support for logging to the log server
This commit is contained in:
2
MANIFEST
2
MANIFEST
@@ -359,7 +359,9 @@ plugins/sudoers/insults.h
|
|||||||
plugins/sudoers/interfaces.c
|
plugins/sudoers/interfaces.c
|
||||||
plugins/sudoers/interfaces.h
|
plugins/sudoers/interfaces.h
|
||||||
plugins/sudoers/iolog.c
|
plugins/sudoers/iolog.c
|
||||||
|
plugins/sudoers/iolog_client.c
|
||||||
plugins/sudoers/iolog_path_escapes.c
|
plugins/sudoers/iolog_path_escapes.c
|
||||||
|
plugins/sudoers/iolog_plugin.h
|
||||||
plugins/sudoers/ldap.c
|
plugins/sudoers/ldap.c
|
||||||
plugins/sudoers/ldap_conf.c
|
plugins/sudoers/ldap_conf.c
|
||||||
plugins/sudoers/ldap_util.c
|
plugins/sudoers/ldap_util.c
|
||||||
|
@@ -54,9 +54,10 @@ INSTALL_BACKUP = @INSTALL_BACKUP@
|
|||||||
# Libraries
|
# Libraries
|
||||||
LIBUTIL = $(top_builddir)/lib/util/libsudo_util.la
|
LIBUTIL = $(top_builddir)/lib/util/libsudo_util.la
|
||||||
LIBIOLOG = $(top_builddir)/lib/iolog/libsudo_iolog.la
|
LIBIOLOG = $(top_builddir)/lib/iolog/libsudo_iolog.la
|
||||||
|
LIBLOGSRV = $(top_builddir)/lib/logsrv/liblogsrv.la
|
||||||
LIBS = $(LIBUTIL)
|
LIBS = $(LIBUTIL)
|
||||||
NET_LIBS = @NET_LIBS@
|
NET_LIBS = @NET_LIBS@
|
||||||
SUDOERS_LIBS = @SUDOERS_LIBS@ @AFS_LIBS@ @GETGROUPS_LIB@ $(NET_LIBS) $(LIBIOLOG)
|
SUDOERS_LIBS = @SUDOERS_LIBS@ @AFS_LIBS@ @GETGROUPS_LIB@ $(NET_LIBS) $(LIBIOLOG) $(LIBLOGSRV)
|
||||||
REPLAY_LIBS = @REPLAY_LIBS@ $(LIBIOLOG)
|
REPLAY_LIBS = @REPLAY_LIBS@ $(LIBIOLOG)
|
||||||
VISUDO_LIBS = $(NET_LIBS)
|
VISUDO_LIBS = $(NET_LIBS)
|
||||||
CVTSUDOERS_LIBS = $(NET_LIBS)
|
CVTSUDOERS_LIBS = $(NET_LIBS)
|
||||||
@@ -158,17 +159,17 @@ LIBPARSESUDOERS_OBJS = alias.lo audit.lo base64.lo defaults.lo digestname.lo \
|
|||||||
filedigest.lo gentime.lo gmtoff.lo gram.lo hexchar.lo \
|
filedigest.lo gentime.lo gmtoff.lo gram.lo hexchar.lo \
|
||||||
match.lo match_addr.lo match_command.lo match_digest.lo \
|
match.lo match_addr.lo match_command.lo match_digest.lo \
|
||||||
pwutil.lo pwutil_impl.lo rcstr.lo redblack.lo \
|
pwutil.lo pwutil_impl.lo rcstr.lo redblack.lo \
|
||||||
sudoers_debug.lo timeout.lo timestr.lo toke.lo \
|
strlist.lo sudoers_debug.lo timeout.lo timestr.lo \
|
||||||
toke_util.lo
|
toke.lo toke_util.lo
|
||||||
|
|
||||||
LIBPARSESUDOERS_IOBJS = $(LIBPARSESUDOERS_OBJS:.lo=.i) passwd.i
|
LIBPARSESUDOERS_IOBJS = $(LIBPARSESUDOERS_OBJS:.lo=.i) passwd.i
|
||||||
|
|
||||||
SUDOERS_OBJS = $(AUTH_OBJS) boottime.lo check.lo editor.lo env.lo \
|
SUDOERS_OBJS = $(AUTH_OBJS) boottime.lo check.lo editor.lo env.lo \
|
||||||
env_pattern.lo file.lo find_path.lo fmtsudoers.lo gc.lo \
|
env_pattern.lo file.lo find_path.lo fmtsudoers.lo gc.lo \
|
||||||
goodpath.lo group_plugin.lo interfaces.lo iolog.lo \
|
goodpath.lo group_plugin.lo interfaces.lo iolog.lo \
|
||||||
iolog_path_escapes.lo locale.lo logging.lo logwrap.lo \
|
iolog_path_escapes.lo locale.lo iolog_client.lo logging.lo \
|
||||||
parse.lo policy.lo prompt.lo set_perms.lo starttime.lo \
|
logwrap.lo parse.lo policy.lo prompt.lo set_perms.lo \
|
||||||
sudo_nss.lo sudoers.lo timestamp.lo @SUDOERS_OBJS@
|
starttime.lo sudo_nss.lo sudoers.lo timestamp.lo @SUDOERS_OBJS@
|
||||||
|
|
||||||
SUDOERS_IOBJS = $(SUDOERS_OBJS:.lo=.i)
|
SUDOERS_IOBJS = $(SUDOERS_OBJS:.lo=.i)
|
||||||
|
|
||||||
@@ -179,17 +180,17 @@ VISUDO_IOBJS = sudo_printf.i visudo.i
|
|||||||
|
|
||||||
CVTSUDOERS_OBJS = cvtsudoers.o cvtsudoers_json.o cvtsudoers_ldif.o \
|
CVTSUDOERS_OBJS = cvtsudoers.o cvtsudoers_json.o cvtsudoers_ldif.o \
|
||||||
cvtsudoers_pwutil.o fmtsudoers.lo locale.lo parse_ldif.o \
|
cvtsudoers_pwutil.o fmtsudoers.lo locale.lo parse_ldif.o \
|
||||||
strlist.o stubs.o sudo_printf.o ldap_util.lo
|
stubs.o sudo_printf.o ldap_util.lo
|
||||||
|
|
||||||
CVTSUDOERS_IOBJS = cvtsudoers.i cvtsudoers_json.i cvtsudoers_ldif.i \
|
CVTSUDOERS_IOBJS = cvtsudoers.i cvtsudoers_json.i cvtsudoers_ldif.i \
|
||||||
cvtsudoers_pwutil.i strlist.i
|
cvtsudoers_pwutil.i
|
||||||
|
|
||||||
REPLAY_OBJS = getdate.o sudoreplay.o
|
REPLAY_OBJS = getdate.o sudoreplay.o
|
||||||
|
|
||||||
REPLAY_IOBJS = $(REPLAY_OBJS:.o=.i)
|
REPLAY_IOBJS = $(REPLAY_OBJS:.o=.i)
|
||||||
|
|
||||||
TEST_OBJS = fmtsudoers.lo group_plugin.lo interfaces.lo ldap_util.lo \
|
TEST_OBJS = fmtsudoers.lo group_plugin.lo interfaces.lo ldap_util.lo \
|
||||||
locale.lo net_ifs.o parse_ldif.o strlist.o sudo_printf.o \
|
locale.lo net_ifs.o parse_ldif.o sudo_printf.o \
|
||||||
testsudoers.o tsgetgrpw.o
|
testsudoers.o tsgetgrpw.o
|
||||||
|
|
||||||
IOBJS = $(LIBPARSESUDOERS_IOBJS) $(SUDOERS_IOBJS) $(VISUDO_IOBJS) \
|
IOBJS = $(LIBPARSESUDOERS_IOBJS) $(SUDOERS_IOBJS) $(VISUDO_IOBJS) \
|
||||||
@@ -214,8 +215,9 @@ CHECK_GENTIME_OBJS = check_gentime.o gentime.lo gmtoff.lo sudoers_debug.lo
|
|||||||
|
|
||||||
CHECK_HEXCHAR_OBJS = check_hexchar.o hexchar.lo sudoers_debug.lo
|
CHECK_HEXCHAR_OBJS = check_hexchar.o hexchar.lo sudoers_debug.lo
|
||||||
|
|
||||||
CHECK_IOLOG_PLUGIN_OBJS = check_iolog_plugin.o iolog.lo locale.lo pwutil.lo \
|
CHECK_IOLOG_PLUGIN_OBJS = check_iolog_plugin.o iolog.lo iolog_client.lo \
|
||||||
pwutil_impl.lo redblack.lo sudoers_debug.lo
|
locale.lo pwutil.lo pwutil_impl.lo redblack.lo \
|
||||||
|
strlist.lo sudoers_debug.lo
|
||||||
|
|
||||||
CHECK_SYMBOLS_OBJS = check_symbols.o
|
CHECK_SYMBOLS_OBJS = check_symbols.o
|
||||||
|
|
||||||
@@ -266,7 +268,7 @@ Makefile: $(srcdir)/Makefile.in
|
|||||||
libparsesudoers.la: $(LIBPARSESUDOERS_OBJS)
|
libparsesudoers.la: $(LIBPARSESUDOERS_OBJS)
|
||||||
$(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(LIBPARSESUDOERS_OBJS) -no-install
|
$(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(LIBPARSESUDOERS_OBJS) -no-install
|
||||||
|
|
||||||
sudoers.la: $(SUDOERS_OBJS) $(LIBUTIL) $(LIBIOLOG) libparsesudoers.la @LT_LDDEP@
|
sudoers.la: $(SUDOERS_OBJS) $(LIBUTIL) $(LIBIOLOG) $(LIBLOGSRV) libparsesudoers.la @LT_LDDEP@
|
||||||
case "$(LT_LDFLAGS)" in \
|
case "$(LT_LDFLAGS)" in \
|
||||||
*-no-install*) \
|
*-no-install*) \
|
||||||
$(LIBTOOL) $(LTFLAGS) @LT_STATIC@ --mode=link $(CC) $(LDFLAGS) $(LT_LDFLAGS) -o $@ $(SUDOERS_OBJS) libparsesudoers.la $(SUDOERS_LIBS) -module;; \
|
$(LIBTOOL) $(LTFLAGS) @LT_STATIC@ --mode=link $(CC) $(LDFLAGS) $(LT_LDFLAGS) -o $@ $(SUDOERS_OBJS) libparsesudoers.la $(SUDOERS_LIBS) -module;; \
|
||||||
@@ -310,8 +312,8 @@ check_gentime: $(CHECK_GENTIME_OBJS) $(LIBUTIL)
|
|||||||
check_hexchar: $(CHECK_HEXCHAR_OBJS) $(LIBUTIL)
|
check_hexchar: $(CHECK_HEXCHAR_OBJS) $(LIBUTIL)
|
||||||
$(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(CHECK_HEXCHAR_OBJS) $(LDFLAGS) $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(LIBS)
|
$(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)
|
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)
|
$(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(CHECK_IOLOG_PLUGIN_OBJS) $(LDFLAGS) $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(LIBIOLOG) $(LIBLOGSRV)
|
||||||
|
|
||||||
check_starttime: $(CHECK_STARTTIME_OBJS) $(LIBUTIL)
|
check_starttime: $(CHECK_STARTTIME_OBJS) $(LIBUTIL)
|
||||||
$(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(CHECK_STARTTIME_OBJS) $(LDFLAGS) $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(LIBS)
|
$(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(CHECK_STARTTIME_OBJS) $(LDFLAGS) $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(LIBS)
|
||||||
@@ -1494,25 +1496,57 @@ interfaces.i: $(srcdir)/interfaces.c $(devdir)/def_data.h \
|
|||||||
interfaces.plog: interfaces.i
|
interfaces.plog: interfaces.i
|
||||||
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/interfaces.c --i-file $< --output-file $@
|
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/interfaces.c --i-file $< --output-file $@
|
||||||
iolog.lo: $(srcdir)/iolog.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
|
iolog.lo: $(srcdir)/iolog.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
|
||||||
|
$(incdir)/log_server.pb-c.h $(incdir)/protobuf-c/protobuf-c.h \
|
||||||
$(incdir)/sudo_compat.h $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
|
$(incdir)/sudo_compat.h $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
|
||||||
$(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
|
$(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
|
||||||
$(incdir)/sudo_iolog.h $(incdir)/sudo_plugin.h \
|
$(incdir)/sudo_iolog.h $(incdir)/sudo_plugin.h \
|
||||||
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/defaults.h \
|
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/defaults.h \
|
||||||
$(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
|
$(srcdir)/iolog_plugin.h $(srcdir)/logging.h $(srcdir)/parse.h \
|
||||||
$(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
|
$(srcdir)/strlist.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
|
||||||
$(top_builddir)/config.h $(top_builddir)/pathnames.h
|
$(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
|
||||||
|
$(top_builddir)/pathnames.h
|
||||||
$(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/iolog.c
|
$(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/iolog.c
|
||||||
iolog.i: $(srcdir)/iolog.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
|
iolog.i: $(srcdir)/iolog.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
|
||||||
|
$(incdir)/log_server.pb-c.h $(incdir)/protobuf-c/protobuf-c.h \
|
||||||
$(incdir)/sudo_compat.h $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
|
$(incdir)/sudo_compat.h $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
|
||||||
$(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
|
$(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
|
||||||
$(incdir)/sudo_iolog.h $(incdir)/sudo_plugin.h \
|
$(incdir)/sudo_iolog.h $(incdir)/sudo_plugin.h \
|
||||||
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/defaults.h \
|
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/defaults.h \
|
||||||
$(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
|
$(srcdir)/iolog_plugin.h $(srcdir)/logging.h $(srcdir)/parse.h \
|
||||||
$(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
|
$(srcdir)/strlist.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
|
||||||
$(top_builddir)/config.h $(top_builddir)/pathnames.h
|
$(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
|
||||||
|
$(top_builddir)/pathnames.h
|
||||||
$(CC) -E -o $@ $(CPPFLAGS) $<
|
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||||
iolog.plog: iolog.i
|
iolog.plog: iolog.i
|
||||||
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/iolog.c --i-file $< --output-file $@
|
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/iolog.c --i-file $< --output-file $@
|
||||||
|
iolog_client.lo: $(srcdir)/iolog_client.c $(devdir)/def_data.h \
|
||||||
|
$(incdir)/compat/getaddrinfo.h $(incdir)/compat/stdbool.h \
|
||||||
|
$(incdir)/log_server.pb-c.h $(incdir)/protobuf-c/protobuf-c.h \
|
||||||
|
$(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
|
||||||
|
$(incdir)/sudo_debug.h $(incdir)/sudo_event.h \
|
||||||
|
$(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
|
||||||
|
$(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
|
||||||
|
$(incdir)/sudo_util.h $(srcdir)/defaults.h \
|
||||||
|
$(srcdir)/iolog_plugin.h $(srcdir)/logging.h \
|
||||||
|
$(srcdir)/parse.h $(srcdir)/strlist.h $(srcdir)/sudo_nss.h \
|
||||||
|
$(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
|
||||||
|
$(top_builddir)/config.h $(top_builddir)/pathnames.h
|
||||||
|
$(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/iolog_client.c
|
||||||
|
iolog_client.i: $(srcdir)/iolog_client.c $(devdir)/def_data.h \
|
||||||
|
$(incdir)/compat/getaddrinfo.h $(incdir)/compat/stdbool.h \
|
||||||
|
$(incdir)/log_server.pb-c.h $(incdir)/protobuf-c/protobuf-c.h \
|
||||||
|
$(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
|
||||||
|
$(incdir)/sudo_debug.h $(incdir)/sudo_event.h \
|
||||||
|
$(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
|
||||||
|
$(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
|
||||||
|
$(incdir)/sudo_util.h $(srcdir)/defaults.h \
|
||||||
|
$(srcdir)/iolog_plugin.h $(srcdir)/logging.h \
|
||||||
|
$(srcdir)/parse.h $(srcdir)/strlist.h $(srcdir)/sudo_nss.h \
|
||||||
|
$(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
|
||||||
|
$(top_builddir)/config.h $(top_builddir)/pathnames.h
|
||||||
|
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||||
|
iolog_client.plog: iolog_client.i
|
||||||
|
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/iolog_client.c --i-file $< --output-file $@
|
||||||
iolog_path_escapes.lo: $(srcdir)/iolog_path_escapes.c $(devdir)/def_data.h \
|
iolog_path_escapes.lo: $(srcdir)/iolog_path_escapes.c $(devdir)/def_data.h \
|
||||||
$(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
|
$(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
|
||||||
$(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
|
$(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
|
||||||
@@ -2201,11 +2235,11 @@ starttime.i: $(srcdir)/starttime.c $(devdir)/def_data.h \
|
|||||||
$(CC) -E -o $@ $(CPPFLAGS) $<
|
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||||
starttime.plog: starttime.i
|
starttime.plog: starttime.i
|
||||||
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/starttime.c --i-file $< --output-file $@
|
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/starttime.c --i-file $< --output-file $@
|
||||||
strlist.o: $(srcdir)/strlist.c $(incdir)/compat/stdbool.h \
|
strlist.lo: $(srcdir)/strlist.c $(incdir)/compat/stdbool.h \
|
||||||
$(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
|
$(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
|
||||||
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/strlist.h \
|
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/strlist.h \
|
||||||
$(srcdir)/sudoers_debug.h $(top_builddir)/config.h
|
$(srcdir)/sudoers_debug.h $(top_builddir)/config.h
|
||||||
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/strlist.c
|
$(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/strlist.c
|
||||||
strlist.i: $(srcdir)/strlist.c $(incdir)/compat/stdbool.h \
|
strlist.i: $(srcdir)/strlist.c $(incdir)/compat/stdbool.h \
|
||||||
$(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
|
$(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
|
||||||
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/strlist.h \
|
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/strlist.h \
|
||||||
|
@@ -505,6 +505,14 @@ struct sudo_defs_types sudo_defs_table[] = {
|
|||||||
"log_denied", T_FLAG,
|
"log_denied", T_FLAG,
|
||||||
N_("Log when a command is denied by sudoers"),
|
N_("Log when a command is denied by sudoers"),
|
||||||
NULL,
|
NULL,
|
||||||
|
}, {
|
||||||
|
"log_server", T_LIST|T_BOOL,
|
||||||
|
N_("Sudo log server(s) to connect to with optional port"),
|
||||||
|
NULL,
|
||||||
|
}, {
|
||||||
|
"log_server_timeout", T_TIMEOUT|T_BOOL,
|
||||||
|
N_("Sudo log server timeout in seconds: %u"),
|
||||||
|
NULL,
|
||||||
}, {
|
}, {
|
||||||
NULL, 0, NULL
|
NULL, 0, NULL
|
||||||
}
|
}
|
||||||
|
@@ -232,6 +232,10 @@
|
|||||||
#define def_log_allowed (sudo_defs_table[I_LOG_ALLOWED].sd_un.flag)
|
#define def_log_allowed (sudo_defs_table[I_LOG_ALLOWED].sd_un.flag)
|
||||||
#define I_LOG_DENIED 116
|
#define I_LOG_DENIED 116
|
||||||
#define def_log_denied (sudo_defs_table[I_LOG_DENIED].sd_un.flag)
|
#define def_log_denied (sudo_defs_table[I_LOG_DENIED].sd_un.flag)
|
||||||
|
#define I_LOG_SERVER 117
|
||||||
|
#define def_log_server (sudo_defs_table[I_LOG_SERVER].sd_un.list)
|
||||||
|
#define I_LOG_SERVER_TIMEOUT 118
|
||||||
|
#define def_log_server_timeout (sudo_defs_table[I_LOG_SERVER_TIMEOUT].sd_un.ival)
|
||||||
|
|
||||||
enum def_tuple {
|
enum def_tuple {
|
||||||
never,
|
never,
|
||||||
|
@@ -366,3 +366,9 @@ log_allowed
|
|||||||
log_denied
|
log_denied
|
||||||
T_FLAG
|
T_FLAG
|
||||||
"Log when a command is denied by sudoers"
|
"Log when a command is denied by sudoers"
|
||||||
|
log_server
|
||||||
|
T_LIST|T_BOOL
|
||||||
|
"Sudo log server(s) to connect to with optional port"
|
||||||
|
log_server_timeout
|
||||||
|
T_TIMEOUT|T_BOOL
|
||||||
|
"Sudo log server timeout in seconds: %u"
|
||||||
|
@@ -562,6 +562,7 @@ init_defaults(void)
|
|||||||
#ifdef HAVE_ZLIB_H
|
#ifdef HAVE_ZLIB_H
|
||||||
def_compress_io = true;
|
def_compress_io = true;
|
||||||
#endif
|
#endif
|
||||||
|
def_log_server_timeout = 30;
|
||||||
def_ignore_audit_errors = true;
|
def_ignore_audit_errors = true;
|
||||||
def_ignore_iolog_errors = false;
|
def_ignore_iolog_errors = false;
|
||||||
def_ignore_logfile_errors = true;
|
def_ignore_logfile_errors = true;
|
||||||
|
@@ -43,23 +43,7 @@
|
|||||||
|
|
||||||
#include "sudoers.h"
|
#include "sudoers.h"
|
||||||
#include "sudo_iolog.h"
|
#include "sudo_iolog.h"
|
||||||
|
#include "iolog_plugin.h"
|
||||||
/* XXX - separate sudoers.h and iolog.h? */
|
|
||||||
#undef runas_pw
|
|
||||||
#undef runas_gr
|
|
||||||
|
|
||||||
struct iolog_details {
|
|
||||||
const char *cwd;
|
|
||||||
const char *tty;
|
|
||||||
const char *user;
|
|
||||||
const char *command;
|
|
||||||
const char *iolog_path;
|
|
||||||
struct passwd *runas_pw;
|
|
||||||
struct group *runas_gr;
|
|
||||||
int lines;
|
|
||||||
int cols;
|
|
||||||
bool ignore_iolog_errors;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct iolog_file iolog_files[] = {
|
static struct iolog_file iolog_files[] = {
|
||||||
{ false }, /* IOFD_STDIN */
|
{ false }, /* IOFD_STDIN */
|
||||||
@@ -70,6 +54,7 @@ static struct iolog_file iolog_files[] = {
|
|||||||
{ true, }, /* IOFD_TIMING */
|
{ true, }, /* IOFD_TIMING */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct client_closure client_closure = CLIENT_CLOSURE_INITIALIZER(client_closure);
|
||||||
static struct iolog_details iolog_details;
|
static struct iolog_details iolog_details;
|
||||||
static bool warned = false;
|
static bool warned = false;
|
||||||
static struct timespec last_time;
|
static struct timespec last_time;
|
||||||
@@ -77,6 +62,8 @@ static struct timespec last_time;
|
|||||||
/* sudoers_io is declared at the end of this file. */
|
/* sudoers_io is declared at the end of this file. */
|
||||||
extern __dso_public struct io_plugin sudoers_io;
|
extern __dso_public struct io_plugin sudoers_io;
|
||||||
|
|
||||||
|
#define iolog_remote (client_closure.sock != -1)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sudoers callback for maxseq Defaults setting.
|
* Sudoers callback for maxseq Defaults setting.
|
||||||
*/
|
*/
|
||||||
@@ -162,10 +149,47 @@ cb_iolog_mode(const union sudo_defs_val *sd_un)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Pull out I/O log related data from user_info and command_info arrays.
|
* Convert a comma-separated list to a string list.
|
||||||
* Returns true if I/O logging is enabled, else false.
|
|
||||||
*/
|
*/
|
||||||
static bool
|
static struct sudoers_str_list *
|
||||||
|
deserialize_stringlist(const char *s)
|
||||||
|
{
|
||||||
|
struct sudoers_str_list *strlist;
|
||||||
|
struct sudoers_string *str;
|
||||||
|
const char *s_end = s + strlen(s);
|
||||||
|
const char *cp, *ep;
|
||||||
|
debug_decl(deserialize_stringlist, SUDOERS_DEBUG_UTIL)
|
||||||
|
|
||||||
|
if ((strlist = str_list_alloc()) == NULL)
|
||||||
|
debug_return_ptr(NULL);
|
||||||
|
|
||||||
|
for (cp = sudo_strsplit(s, s_end, ",", &ep); cp != NULL;
|
||||||
|
cp = sudo_strsplit(NULL, s_end, ",", &ep)) {
|
||||||
|
if (cp == ep)
|
||||||
|
continue;
|
||||||
|
if ((str = malloc(sizeof(*str))) == NULL)
|
||||||
|
goto bad;
|
||||||
|
if ((str->str = strndup(cp, (ep - cp))) == NULL) {
|
||||||
|
free(str);
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
STAILQ_INSERT_TAIL(strlist, str, entries);
|
||||||
|
}
|
||||||
|
if (STAILQ_EMPTY(strlist))
|
||||||
|
goto bad;
|
||||||
|
|
||||||
|
debug_return_ptr(strlist);
|
||||||
|
|
||||||
|
bad:
|
||||||
|
str_list_free(strlist);
|
||||||
|
debug_return_ptr(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Pull out I/O log related data from user_info and command_info arrays.
|
||||||
|
* Returns true if I/O logging is enabled, false if not and -1 on error.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
iolog_deserialize_info(struct iolog_details *details, char * const user_info[],
|
iolog_deserialize_info(struct iolog_details *details, char * const user_info[],
|
||||||
char * const command_info[])
|
char * const command_info[])
|
||||||
{
|
{
|
||||||
@@ -197,6 +221,12 @@ iolog_deserialize_info(struct iolog_details *details, char * const user_info[],
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'h':
|
||||||
|
if (strncmp(*cur, "host=", sizeof("host=") - 1) == 0) {
|
||||||
|
details->host = *cur + sizeof("host=") - 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 'l':
|
case 'l':
|
||||||
if (strncmp(*cur, "lines=", sizeof("lines=") - 1) == 0) {
|
if (strncmp(*cur, "lines=", sizeof("lines=") - 1) == 0) {
|
||||||
int n = sudo_strtonum(*cur + sizeof("lines=") - 1, 1, INT_MAX,
|
int n = sudo_strtonum(*cur + sizeof("lines=") - 1, 1, INT_MAX,
|
||||||
@@ -319,6 +349,21 @@ iolog_deserialize_info(struct iolog_details *details, char * const user_info[],
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'l':
|
||||||
|
if (strncmp(*cur, "log_servers=", sizeof("log_servers=") - 1) == 0) {
|
||||||
|
details->log_servers =
|
||||||
|
deserialize_stringlist(*cur + sizeof("log_servers=") - 1);
|
||||||
|
if (!details->log_servers)
|
||||||
|
goto oom;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (strncmp(*cur, "log_server_timeout=", sizeof("log_server_timeout=") - 1) == 0) {
|
||||||
|
details->server_timeout.tv_sec =
|
||||||
|
sudo_strtonum(*cur + sizeof("log_server_timeout=") - 1, 1,
|
||||||
|
TIME_T_MAX, NULL);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 'm':
|
case 'm':
|
||||||
if (strncmp(*cur, "maxseq=", sizeof("maxseq=") - 1) == 0) {
|
if (strncmp(*cur, "maxseq=", sizeof("maxseq=") - 1) == 0) {
|
||||||
union sudo_defs_val sd_un;
|
union sudo_defs_val sd_un;
|
||||||
@@ -385,10 +430,14 @@ iolog_deserialize_info(struct iolog_details *details, char * const user_info[],
|
|||||||
details->runas_gr = sudo_fakegrnam(idbuf);
|
details->runas_gr = sudo_fakegrnam(idbuf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
debug_return_bool(
|
debug_return_int(
|
||||||
iolog_files[IOFD_STDIN].enabled || iolog_files[IOFD_STDOUT].enabled ||
|
iolog_files[IOFD_STDIN].enabled || iolog_files[IOFD_STDOUT].enabled ||
|
||||||
iolog_files[IOFD_STDERR].enabled || iolog_files[IOFD_TTYIN].enabled ||
|
iolog_files[IOFD_STDERR].enabled || iolog_files[IOFD_TTYIN].enabled ||
|
||||||
iolog_files[IOFD_TTYOUT].enabled);
|
iolog_files[IOFD_TTYOUT].enabled);
|
||||||
|
oom:
|
||||||
|
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
||||||
|
str_list_free(details->log_servers);
|
||||||
|
debug_return_int(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -396,8 +445,7 @@ iolog_deserialize_info(struct iolog_details *details, char * const user_info[],
|
|||||||
* This file is not compressed.
|
* This file is not compressed.
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
write_info_log(int dfd, char *iolog_dir, struct iolog_details *details,
|
write_info_log(int dfd, char *iolog_dir, struct iolog_details *details)
|
||||||
char * const argv[])
|
|
||||||
{
|
{
|
||||||
struct iolog_info iolog_info;
|
struct iolog_info iolog_info;
|
||||||
debug_decl(write_info_log, SUDOERS_DEBUG_UTIL)
|
debug_decl(write_info_log, SUDOERS_DEBUG_UTIL)
|
||||||
@@ -414,7 +462,7 @@ write_info_log(int dfd, char *iolog_dir, struct iolog_details *details,
|
|||||||
iolog_info.lines = details->lines;
|
iolog_info.lines = details->lines;
|
||||||
iolog_info.cols = details->cols;
|
iolog_info.cols = details->cols;
|
||||||
|
|
||||||
if (!iolog_write_info_file(dfd, iolog_dir, &iolog_info, argv)) {
|
if (!iolog_write_info_file(dfd, iolog_dir, &iolog_info, details->argv)) {
|
||||||
log_warning(SLOG_SEND_MAIL,
|
log_warning(SLOG_SEND_MAIL,
|
||||||
N_("unable to write to I/O log file: %s"), strerror(errno));
|
N_("unable to write to I/O log file: %s"), strerror(errno));
|
||||||
warned = true;
|
warned = true;
|
||||||
@@ -424,55 +472,13 @@ write_info_log(int dfd, char *iolog_dir, struct iolog_details *details,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
sudoers_io_open(unsigned int version, sudo_conv_t conversation,
|
sudoers_io_open_local(void)
|
||||||
sudo_printf_t plugin_printf, char * const settings[],
|
|
||||||
char * const user_info[], char * const command_info[],
|
|
||||||
int argc, char * const argv[], char * const user_env[], char * const args[])
|
|
||||||
{
|
{
|
||||||
struct sudo_conf_debug_file_list debug_files = TAILQ_HEAD_INITIALIZER(debug_files);
|
|
||||||
char iolog_path[PATH_MAX], sessid[7];
|
char iolog_path[PATH_MAX], sessid[7];
|
||||||
char * const *cur;
|
|
||||||
const char *cp, *plugin_path = NULL;
|
|
||||||
size_t len;
|
size_t len;
|
||||||
int i, ret = -1;
|
|
||||||
int iolog_dir_fd = -1;
|
int iolog_dir_fd = -1;
|
||||||
debug_decl(sudoers_io_open, SUDOERS_DEBUG_PLUGIN)
|
int i, ret = -1;
|
||||||
|
debug_decl(sudoers_io_open_local, SUDOERS_DEBUG_PLUGIN)
|
||||||
sudo_conv = conversation;
|
|
||||||
sudo_printf = plugin_printf;
|
|
||||||
|
|
||||||
/* If we have no command (because -V was specified) just return. */
|
|
||||||
if (argc == 0)
|
|
||||||
debug_return_int(true);
|
|
||||||
|
|
||||||
bindtextdomain("sudoers", LOCALEDIR);
|
|
||||||
|
|
||||||
/* Initialize the debug subsystem. */
|
|
||||||
for (cur = settings; (cp = *cur) != NULL; cur++) {
|
|
||||||
if (strncmp(cp, "debug_flags=", sizeof("debug_flags=") - 1) == 0) {
|
|
||||||
cp += sizeof("debug_flags=") - 1;
|
|
||||||
if (!sudoers_debug_parse_flags(&debug_files, cp))
|
|
||||||
debug_return_int(-1);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (strncmp(cp, "plugin_path=", sizeof("plugin_path=") - 1) == 0) {
|
|
||||||
plugin_path = cp + sizeof("plugin_path=") - 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!sudoers_debug_register(plugin_path, &debug_files)) {
|
|
||||||
ret = -1;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Pull iolog settings out of command_info.
|
|
||||||
*/
|
|
||||||
if (!iolog_deserialize_info(&iolog_details, user_info, command_info)) {
|
|
||||||
ret = false;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If no I/O log path defined we need to figure it out ourselves. */
|
/* If no I/O log path defined we need to figure it out ourselves. */
|
||||||
if (iolog_details.iolog_path == NULL) {
|
if (iolog_details.iolog_path == NULL) {
|
||||||
@@ -517,7 +523,7 @@ sudoers_io_open(unsigned int version, sudo_conv_t conversation,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Write log file with user and command details. */
|
/* Write log file with user and command details. */
|
||||||
if (!write_info_log(iolog_dir_fd, iolog_path, &iolog_details, argv))
|
if (!write_info_log(iolog_dir_fd, iolog_path, &iolog_details))
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
/* Create the timing and I/O log files. */
|
/* Create the timing and I/O log files. */
|
||||||
@@ -529,6 +535,107 @@ sudoers_io_open(unsigned int version, sudo_conv_t conversation,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = true;
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (iolog_dir_fd != -1)
|
||||||
|
close(iolog_dir_fd);
|
||||||
|
|
||||||
|
debug_return_int(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
sudoers_io_open_remote(void)
|
||||||
|
{
|
||||||
|
int sock, ret = -1;
|
||||||
|
debug_decl(sudoers_io_open_remote, SUDOERS_DEBUG_PLUGIN)
|
||||||
|
|
||||||
|
/* Connect to log server. */
|
||||||
|
sock = log_server_connect(iolog_details.log_servers,
|
||||||
|
&iolog_details.server_timeout);
|
||||||
|
if (sock == -1) {
|
||||||
|
/* TODO: support offline logs if server unreachable */
|
||||||
|
sudo_warnx(U_("unable to connect to log server"));
|
||||||
|
ret = -1;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!client_closure_fill(&client_closure, sock, &iolog_details, &sudoers_io)) {
|
||||||
|
close(sock);
|
||||||
|
ret = -1;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enable reader for server hello */
|
||||||
|
ret = client_closure.read_ev->add(client_closure.read_ev,
|
||||||
|
&iolog_details.server_timeout);
|
||||||
|
if (ret == -1)
|
||||||
|
sudo_warn(U_("unable to add event to queue"));
|
||||||
|
|
||||||
|
done:
|
||||||
|
debug_return_int(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
sudoers_io_open(unsigned int version, sudo_conv_t conversation,
|
||||||
|
sudo_printf_t plugin_printf, char * const settings[],
|
||||||
|
char * const user_info[], char * const command_info[],
|
||||||
|
int argc, char * const argv[], char * const user_env[], char * const args[])
|
||||||
|
{
|
||||||
|
struct sudo_conf_debug_file_list debug_files = TAILQ_HEAD_INITIALIZER(debug_files);
|
||||||
|
char * const *cur;
|
||||||
|
const char *cp, *plugin_path = NULL;
|
||||||
|
int ret = -1;
|
||||||
|
debug_decl(sudoers_io_open, SUDOERS_DEBUG_PLUGIN)
|
||||||
|
|
||||||
|
sudo_conv = conversation;
|
||||||
|
sudo_printf = plugin_printf;
|
||||||
|
|
||||||
|
/* If we have no command (because -V was specified) just return. */
|
||||||
|
if (argc == 0)
|
||||||
|
debug_return_int(true);
|
||||||
|
|
||||||
|
bindtextdomain("sudoers", LOCALEDIR);
|
||||||
|
|
||||||
|
/* Initialize the debug subsystem. */
|
||||||
|
for (cur = settings; (cp = *cur) != NULL; cur++) {
|
||||||
|
if (strncmp(cp, "debug_flags=", sizeof("debug_flags=") - 1) == 0) {
|
||||||
|
cp += sizeof("debug_flags=") - 1;
|
||||||
|
if (!sudoers_debug_parse_flags(&debug_files, cp))
|
||||||
|
debug_return_int(-1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (strncmp(cp, "plugin_path=", sizeof("plugin_path=") - 1) == 0) {
|
||||||
|
plugin_path = cp + sizeof("plugin_path=") - 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sudoers_debug_register(plugin_path, &debug_files)) {
|
||||||
|
ret = -1;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Pull iolog settings out of command_info.
|
||||||
|
*/
|
||||||
|
ret = iolog_deserialize_info(&iolog_details, user_info, command_info);
|
||||||
|
if (ret != true)
|
||||||
|
goto done;
|
||||||
|
iolog_details.user_env = user_env;
|
||||||
|
iolog_details.argv = argv;
|
||||||
|
iolog_details.argc = argc;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create local I/O log file or connect to remote log server.
|
||||||
|
*/
|
||||||
|
if (sudoers_io.event_alloc != NULL && iolog_details.log_servers != NULL)
|
||||||
|
ret = sudoers_io_open_remote();
|
||||||
|
else
|
||||||
|
ret = sudoers_io_open_local();
|
||||||
|
if (ret != true)
|
||||||
|
goto done;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Clear I/O log function pointers for disabled log functions.
|
* Clear I/O log function pointers for disabled log functions.
|
||||||
*/
|
*/
|
||||||
@@ -548,18 +655,19 @@ sudoers_io_open(unsigned int version, sudo_conv_t conversation,
|
|||||||
"%s: unable to get time of day", __func__);
|
"%s: unable to get time of day", __func__);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
if (iolog_remote)
|
||||||
ret = true;
|
client_closure.start_time = last_time;
|
||||||
|
|
||||||
done:
|
done:
|
||||||
if (iolog_dir_fd != -1)
|
if (ret != true) {
|
||||||
close(iolog_dir_fd);
|
client_closure_free(&client_closure);
|
||||||
if (iolog_details.runas_pw)
|
if (iolog_details.runas_pw)
|
||||||
sudo_pw_delref(iolog_details.runas_pw);
|
sudo_pw_delref(iolog_details.runas_pw);
|
||||||
if (iolog_details.runas_gr)
|
if (iolog_details.runas_gr)
|
||||||
sudo_gr_delref(iolog_details.runas_gr);
|
sudo_gr_delref(iolog_details.runas_gr);
|
||||||
sudo_freepwcache();
|
sudo_freepwcache();
|
||||||
sudo_freegrcache();
|
sudo_freegrcache();
|
||||||
|
}
|
||||||
|
|
||||||
/* Ignore errors if they occur if the policy says so. */
|
/* Ignore errors if they occur if the policy says so. */
|
||||||
if (ret == -1 && iolog_details.ignore_iolog_errors)
|
if (ret == -1 && iolog_details.ignore_iolog_errors)
|
||||||
@@ -575,11 +683,35 @@ sudoers_io_close(int exit_status, int error)
|
|||||||
int i;
|
int i;
|
||||||
debug_decl(sudoers_io_close, SUDOERS_DEBUG_PLUGIN)
|
debug_decl(sudoers_io_close, SUDOERS_DEBUG_PLUGIN)
|
||||||
|
|
||||||
|
if (iolog_remote) {
|
||||||
|
if (client_closure.disabled)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
if (!fmt_exit_message(&client_closure, exit_status, error))
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Main sudo event loop exited, use our own mini event loop
|
||||||
|
* to flush the write queue and read the final commit messages.
|
||||||
|
*/
|
||||||
|
if (!client_loop(&client_closure))
|
||||||
|
goto done;
|
||||||
|
} else {
|
||||||
for (i = 0; i < IOFD_MAX; i++) {
|
for (i = 0; i < IOFD_MAX; i++) {
|
||||||
if (iolog_files[i].fd.v == NULL)
|
if (iolog_files[i].fd.v == NULL)
|
||||||
continue;
|
continue;
|
||||||
iolog_close(&iolog_files[i], &errstr);
|
iolog_close(&iolog_files[i], &errstr);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
client_closure_free(&client_closure);
|
||||||
|
if (iolog_details.runas_pw)
|
||||||
|
sudo_pw_delref(iolog_details.runas_pw);
|
||||||
|
if (iolog_details.runas_gr)
|
||||||
|
sudo_gr_delref(iolog_details.runas_gr);
|
||||||
|
sudo_freepwcache();
|
||||||
|
sudo_freegrcache();
|
||||||
|
|
||||||
if (errstr != NULL && !warned) {
|
if (errstr != NULL && !warned) {
|
||||||
/* Only warn about I/O log file errors once. */
|
/* Only warn about I/O log file errors once. */
|
||||||
@@ -605,52 +737,128 @@ sudoers_io_version(int verbose)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generic I/O logging function. Called by the I/O logging entry points.
|
* Write an I/O log entry to the local file system.
|
||||||
* Returns 1 on success and -1 on error.
|
* Returns 1 on success and -1 on error.
|
||||||
|
* Fills in errstr on error.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
sudoers_io_log(struct iolog_file *iol, const char *buf, unsigned int len,
|
sudoers_io_log_local(int event, const char *buf, unsigned int len,
|
||||||
int event)
|
struct timespec *delay, const char **errstr)
|
||||||
{
|
{
|
||||||
struct timespec now, delay;
|
struct iolog_file *iol;
|
||||||
char tbuf[1024];
|
char tbuf[1024];
|
||||||
const char *errstr = NULL;
|
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
debug_decl(sudoers_io_log, SUDOERS_DEBUG_PLUGIN)
|
debug_decl(sudoers_io_log_local, SUDOERS_DEBUG_PLUGIN)
|
||||||
|
|
||||||
|
if (event < 0 || event >= IOFD_MAX) {
|
||||||
|
*errstr = NULL;
|
||||||
|
sudo_warnx(U_("unexpected I/O event %d"), event);
|
||||||
|
debug_return_int(-1);
|
||||||
|
}
|
||||||
|
iol = &iolog_files[event];
|
||||||
if (!iol->enabled) {
|
if (!iol->enabled) {
|
||||||
|
*errstr = NULL;
|
||||||
sudo_warnx(U_("%s: internal error, I/O log file for event %d not open"),
|
sudo_warnx(U_("%s: internal error, I/O log file for event %d not open"),
|
||||||
__func__, event);
|
__func__, event);
|
||||||
debug_return_int(-1);
|
debug_return_int(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Write I/O log file entry. */
|
||||||
|
if (iolog_write(iol, buf, len, errstr) == -1)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
/* Write timing file entry. */
|
||||||
|
len = (unsigned int)snprintf(tbuf, sizeof(tbuf), "%d %lld.%09ld %u\n",
|
||||||
|
event, (long long)delay->tv_sec, delay->tv_nsec, len);
|
||||||
|
if (len >= sizeof(tbuf)) {
|
||||||
|
/* Not actually possible due to the size of tbuf[]. */
|
||||||
|
*errstr = strerror(EOVERFLOW);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if (iolog_write(&iolog_files[IOFD_TIMING], tbuf, len, errstr) == -1)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
/* Success. */
|
||||||
|
ret = 1;
|
||||||
|
|
||||||
|
done:
|
||||||
|
debug_return_int(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Schedule an I/O log entry to be written to the log server.
|
||||||
|
* Returns 1 on success and -1 on error.
|
||||||
|
* Fills in errstr on error.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
sudoers_io_log_remote(int event, const char *buf, unsigned int len,
|
||||||
|
struct timespec *delay, const char **errstr)
|
||||||
|
{
|
||||||
|
int type, ret = -1;
|
||||||
|
debug_decl(sudoers_io_log_remote, SUDOERS_DEBUG_PLUGIN)
|
||||||
|
|
||||||
|
if (client_closure.disabled)
|
||||||
|
debug_return_int(1);
|
||||||
|
|
||||||
|
/* Track elapsed time for comparison with commit points. */
|
||||||
|
sudo_timespecadd(delay, &client_closure.elapsed, &client_closure.elapsed);
|
||||||
|
|
||||||
|
switch (event) {
|
||||||
|
case IO_EVENT_STDIN:
|
||||||
|
type = CLIENT_MESSAGE__TYPE_STDIN_BUF;
|
||||||
|
break;
|
||||||
|
case IO_EVENT_STDOUT:
|
||||||
|
type = CLIENT_MESSAGE__TYPE_STDOUT_BUF;
|
||||||
|
break;
|
||||||
|
case IO_EVENT_STDERR:
|
||||||
|
type = CLIENT_MESSAGE__TYPE_STDERR_BUF;
|
||||||
|
break;
|
||||||
|
case IO_EVENT_TTYIN:
|
||||||
|
type = CLIENT_MESSAGE__TYPE_TTYIN_BUF;
|
||||||
|
break;
|
||||||
|
case IO_EVENT_TTYOUT:
|
||||||
|
type = CLIENT_MESSAGE__TYPE_TTYOUT_BUF;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
sudo_warnx(U_("unexpected I/O event %d"), event);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if (fmt_io_buf(&client_closure, type, buf, len, delay)) {
|
||||||
|
ret = client_closure.write_ev->add(client_closure.write_ev,
|
||||||
|
&iolog_details.server_timeout);
|
||||||
|
if (ret == -1)
|
||||||
|
sudo_warn(U_("unable to add event to queue"));
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
debug_return_int(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generic I/O logging function. Called by the I/O logging entry points.
|
||||||
|
* Returns 1 on success and -1 on error.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
sudoers_io_log(const char *buf, unsigned int len, int event)
|
||||||
|
{
|
||||||
|
struct timespec now, delay;
|
||||||
|
const char *errstr = NULL;
|
||||||
|
int ret = -1;
|
||||||
|
debug_decl(sudoers_io_log, SUDOERS_DEBUG_PLUGIN)
|
||||||
|
|
||||||
if (sudo_gettime_awake(&now) == -1) {
|
if (sudo_gettime_awake(&now) == -1) {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
|
||||||
"%s: unable to get time of day", __func__);
|
"%s: unable to get time of day", __func__);
|
||||||
errstr = strerror(errno);
|
errstr = strerror(errno);
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write I/O log file entry. */
|
|
||||||
if (iolog_write(iol, buf, len, &errstr) == -1)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
/* Write timing file entry. */
|
|
||||||
sudo_timespecsub(&now, &last_time, &delay);
|
sudo_timespecsub(&now, &last_time, &delay);
|
||||||
len = (unsigned int)snprintf(tbuf, sizeof(tbuf), "%d %lld.%09ld %u\n",
|
|
||||||
event, (long long)delay.tv_sec, delay.tv_nsec, len);
|
|
||||||
if (len >= sizeof(tbuf)) {
|
|
||||||
/* Not actually possible due to the size of tbuf[]. */
|
|
||||||
errstr = strerror(EOVERFLOW);
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
if (iolog_write(&iolog_files[IOFD_TIMING], tbuf, len, &errstr) == -1)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
/* Success. */
|
if (iolog_remote)
|
||||||
ret = 1;
|
ret = sudoers_io_log_remote(event, buf, len, &delay, &errstr);
|
||||||
|
else
|
||||||
|
ret = sudoers_io_log_local(event, buf, len, &delay, &errstr);
|
||||||
|
|
||||||
done:
|
|
||||||
last_time.tv_sec = now.tv_sec;
|
last_time.tv_sec = now.tv_sec;
|
||||||
last_time.tv_nsec = now.tv_nsec;
|
last_time.tv_nsec = now.tv_nsec;
|
||||||
|
|
||||||
@@ -674,39 +882,87 @@ bad:
|
|||||||
static int
|
static int
|
||||||
sudoers_io_log_stdin(const char *buf, unsigned int len)
|
sudoers_io_log_stdin(const char *buf, unsigned int len)
|
||||||
{
|
{
|
||||||
return sudoers_io_log(&iolog_files[IOFD_STDIN], buf, len, IO_EVENT_STDIN);
|
return sudoers_io_log(buf, len, IO_EVENT_STDIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
sudoers_io_log_stdout(const char *buf, unsigned int len)
|
sudoers_io_log_stdout(const char *buf, unsigned int len)
|
||||||
{
|
{
|
||||||
return sudoers_io_log(&iolog_files[IOFD_STDOUT], buf, len, IO_EVENT_STDOUT);
|
return sudoers_io_log(buf, len, IO_EVENT_STDOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
sudoers_io_log_stderr(const char *buf, unsigned int len)
|
sudoers_io_log_stderr(const char *buf, unsigned int len)
|
||||||
{
|
{
|
||||||
return sudoers_io_log(&iolog_files[IOFD_STDERR], buf, len, IO_EVENT_STDERR);
|
return sudoers_io_log(buf, len, IO_EVENT_STDERR);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
sudoers_io_log_ttyin(const char *buf, unsigned int len)
|
sudoers_io_log_ttyin(const char *buf, unsigned int len)
|
||||||
{
|
{
|
||||||
return sudoers_io_log(&iolog_files[IOFD_TTYIN], buf, len, IO_EVENT_TTYIN);
|
return sudoers_io_log(buf, len, IO_EVENT_TTYIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
sudoers_io_log_ttyout(const char *buf, unsigned int len)
|
sudoers_io_log_ttyout(const char *buf, unsigned int len)
|
||||||
{
|
{
|
||||||
return sudoers_io_log(&iolog_files[IOFD_TTYOUT], buf, len, IO_EVENT_TTYOUT);
|
return sudoers_io_log(buf, len, IO_EVENT_TTYOUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
sudoers_io_change_winsize_local(unsigned int lines, unsigned int cols,
|
||||||
|
struct timespec *delay, const char **errstr)
|
||||||
|
{
|
||||||
|
char tbuf[1024];
|
||||||
|
int len, ret = -1;
|
||||||
|
debug_decl(sudoers_io_change_winsize_local, SUDOERS_DEBUG_PLUGIN)
|
||||||
|
|
||||||
|
/* Write window change event to the timing file. */
|
||||||
|
len = snprintf(tbuf, sizeof(tbuf), "%d %lld.%09ld %u %u\n",
|
||||||
|
IO_EVENT_WINSIZE, (long long)delay->tv_sec, delay->tv_nsec,
|
||||||
|
lines, cols);
|
||||||
|
if (len < 0 || len >= ssizeof(tbuf)) {
|
||||||
|
/* Not actually possible due to the size of tbuf[]. */
|
||||||
|
*errstr = strerror(EOVERFLOW);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if (iolog_write(&iolog_files[IOFD_TIMING], tbuf, len, errstr) == -1)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
/* Success. */
|
||||||
|
ret = 1;
|
||||||
|
|
||||||
|
done:
|
||||||
|
debug_return_int(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
sudoers_io_change_winsize_remote(unsigned int lines, unsigned int cols,
|
||||||
|
struct timespec *delay, const char **errstr)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
debug_decl(sudoers_io_change_winsize_remote, SUDOERS_DEBUG_PLUGIN)
|
||||||
|
|
||||||
|
if (client_closure.disabled)
|
||||||
|
debug_return_int(1);
|
||||||
|
|
||||||
|
/* Track elapsed time for comparison with commit points. */
|
||||||
|
sudo_timespecadd(delay, &client_closure.elapsed, &client_closure.elapsed);
|
||||||
|
|
||||||
|
if (fmt_winsize(&client_closure, lines, cols, delay)) {
|
||||||
|
ret = client_closure.write_ev->add(client_closure.write_ev,
|
||||||
|
&iolog_details.server_timeout);
|
||||||
|
if (ret == -1)
|
||||||
|
sudo_warn(U_("unable to add event to queue"));
|
||||||
|
}
|
||||||
|
|
||||||
|
debug_return_int(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
sudoers_io_change_winsize(unsigned int lines, unsigned int cols)
|
sudoers_io_change_winsize(unsigned int lines, unsigned int cols)
|
||||||
{
|
{
|
||||||
struct timespec now, delay;
|
struct timespec now, delay;
|
||||||
unsigned int len;
|
|
||||||
char tbuf[1024];
|
|
||||||
const char *errstr = NULL;
|
const char *errstr = NULL;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
debug_decl(sudoers_io_change_winsize, SUDOERS_DEBUG_PLUGIN)
|
debug_decl(sudoers_io_change_winsize, SUDOERS_DEBUG_PLUGIN)
|
||||||
@@ -717,23 +973,13 @@ sudoers_io_change_winsize(unsigned int lines, unsigned int cols)
|
|||||||
errstr = strerror(errno);
|
errstr = strerror(errno);
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write window change event to the timing file. */
|
|
||||||
sudo_timespecsub(&now, &last_time, &delay);
|
sudo_timespecsub(&now, &last_time, &delay);
|
||||||
len = (unsigned int)snprintf(tbuf, sizeof(tbuf), "%d %lld.%09ld %u %u\n",
|
|
||||||
IO_EVENT_WINSIZE, (long long)delay.tv_sec, delay.tv_nsec, lines, cols);
|
|
||||||
if (len >= sizeof(tbuf)) {
|
|
||||||
/* Not actually possible due to the size of tbuf[]. */
|
|
||||||
errstr = strerror(EOVERFLOW);
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
if (iolog_write(&iolog_files[IOFD_TIMING], tbuf, len, &errstr) == -1)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
/* Success. */
|
if (iolog_remote)
|
||||||
ret = 1;
|
ret = sudoers_io_change_winsize_remote(lines, cols, &delay, &errstr);
|
||||||
|
else
|
||||||
|
ret = sudoers_io_change_winsize_local(lines, cols, &delay, &errstr);
|
||||||
|
|
||||||
done:
|
|
||||||
last_time.tv_sec = now.tv_sec;
|
last_time.tv_sec = now.tv_sec;
|
||||||
last_time.tv_nsec = now.tv_nsec;
|
last_time.tv_nsec = now.tv_nsec;
|
||||||
|
|
||||||
@@ -754,13 +1000,61 @@ bad:
|
|||||||
debug_return_int(ret);
|
debug_return_int(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
sudoers_io_suspend_local(const char *signame, struct timespec *delay,
|
||||||
|
const char **errstr)
|
||||||
|
{
|
||||||
|
unsigned int len;
|
||||||
|
char tbuf[1024];
|
||||||
|
int ret = -1;
|
||||||
|
debug_decl(sudoers_io_suspend_local, SUDOERS_DEBUG_PLUGIN)
|
||||||
|
|
||||||
|
/* Write suspend event to the timing file. */
|
||||||
|
len = (unsigned int)snprintf(tbuf, sizeof(tbuf), "%d %lld.%09ld %s\n",
|
||||||
|
IO_EVENT_SUSPEND, (long long)delay->tv_sec, delay->tv_nsec, signame);
|
||||||
|
if (len >= sizeof(tbuf)) {
|
||||||
|
/* Not actually possible due to the size of tbuf[]. */
|
||||||
|
*errstr = strerror(EOVERFLOW);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if (iolog_write(&iolog_files[IOFD_TIMING], tbuf, len, errstr) == -1)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
/* Success. */
|
||||||
|
ret = 1;
|
||||||
|
|
||||||
|
done:
|
||||||
|
debug_return_int(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
sudoers_io_suspend_remote(const char *signame, struct timespec *delay,
|
||||||
|
const char **errstr)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
debug_decl(sudoers_io_suspend_remote, SUDOERS_DEBUG_PLUGIN)
|
||||||
|
|
||||||
|
if (client_closure.disabled)
|
||||||
|
debug_return_int(1);
|
||||||
|
|
||||||
|
/* Track elapsed time for comparison with commit points. */
|
||||||
|
sudo_timespecadd(delay, &client_closure.elapsed, &client_closure.elapsed);
|
||||||
|
|
||||||
|
if (fmt_suspend(&client_closure, signame, delay)) {
|
||||||
|
ret = client_closure.write_ev->add(client_closure.write_ev,
|
||||||
|
&iolog_details.server_timeout);
|
||||||
|
if (ret == -1)
|
||||||
|
sudo_warn(U_("unable to add event to queue"));
|
||||||
|
}
|
||||||
|
|
||||||
|
debug_return_int(ret);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
sudoers_io_suspend(int signo)
|
sudoers_io_suspend(int signo)
|
||||||
{
|
{
|
||||||
struct timespec now, delay;
|
struct timespec now, delay;
|
||||||
unsigned int len;
|
|
||||||
char signame[SIG2STR_MAX];
|
char signame[SIG2STR_MAX];
|
||||||
char tbuf[1024];
|
|
||||||
const char *errstr = NULL;
|
const char *errstr = NULL;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
debug_decl(sudoers_io_suspend, SUDOERS_DEBUG_PLUGIN)
|
debug_decl(sudoers_io_suspend, SUDOERS_DEBUG_PLUGIN)
|
||||||
@@ -777,23 +1071,14 @@ sudoers_io_suspend(int signo)
|
|||||||
errstr = strerror(errno);
|
errstr = strerror(errno);
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
sudo_timespecsub(&now, &last_time, &delay);
|
||||||
|
|
||||||
/* Write suspend event to the timing file. */
|
/* Write suspend event to the timing file. */
|
||||||
sudo_timespecsub(&now, &last_time, &delay);
|
if (iolog_remote)
|
||||||
len = (unsigned int)snprintf(tbuf, sizeof(tbuf), "%d %lld.%09ld %s\n",
|
ret = sudoers_io_suspend_remote(signame, &delay, &errstr);
|
||||||
IO_EVENT_SUSPEND, (long long)delay.tv_sec, delay.tv_nsec, signame);
|
else
|
||||||
if (len >= sizeof(tbuf)) {
|
ret = sudoers_io_suspend_local(signame, &delay, &errstr);
|
||||||
/* Not actually possible due to the size of tbuf[]. */
|
|
||||||
errstr = strerror(EOVERFLOW);
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
if (iolog_write(&iolog_files[IOFD_TIMING], tbuf, len, &errstr) == -1)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
/* Success. */
|
|
||||||
ret = 1;
|
|
||||||
|
|
||||||
done:
|
|
||||||
last_time.tv_sec = now.tv_sec;
|
last_time.tv_sec = now.tv_sec;
|
||||||
last_time.tv_nsec = now.tv_nsec;
|
last_time.tv_nsec = now.tv_nsec;
|
||||||
|
|
||||||
|
1159
plugins/sudoers/iolog_client.c
Normal file
1159
plugins/sudoers/iolog_client.c
Normal file
File diff suppressed because it is too large
Load Diff
115
plugins/sudoers/iolog_plugin.h
Normal file
115
plugins/sudoers/iolog_plugin.h
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SUDOERS_IOLOG_CLIENT_H
|
||||||
|
#define SUDOERS_IOLOG_CLIENT_H
|
||||||
|
|
||||||
|
#include "log_server.pb-c.h"
|
||||||
|
#include "strlist.h"
|
||||||
|
|
||||||
|
#if PROTOBUF_C_VERSION_NUMBER < 1003000
|
||||||
|
# error protobuf-c version 1.30 or higher required
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Default port to listen on */
|
||||||
|
#define DEFAULT_PORT_STR "30344"
|
||||||
|
|
||||||
|
/* Maximum message size (2Mb) */
|
||||||
|
#define MESSAGE_SIZE_MAX (2 * 1024 * 1024)
|
||||||
|
|
||||||
|
/* TODO - share with logsrvd/sendlog */
|
||||||
|
struct connection_buffer {
|
||||||
|
TAILQ_ENTRY(connection_buffer) entries;
|
||||||
|
uint8_t *data;
|
||||||
|
unsigned int size;
|
||||||
|
unsigned int len;
|
||||||
|
unsigned int off;
|
||||||
|
};
|
||||||
|
TAILQ_HEAD(connection_buffer_list, connection_buffer);
|
||||||
|
|
||||||
|
/* XXX - remove dependency on sudoers.h? */
|
||||||
|
#undef runas_pw
|
||||||
|
#undef runas_gr
|
||||||
|
|
||||||
|
struct iolog_details {
|
||||||
|
const char *cwd;
|
||||||
|
const char *host;
|
||||||
|
const char *tty;
|
||||||
|
const char *user;
|
||||||
|
const char *command;
|
||||||
|
const char *iolog_path;
|
||||||
|
struct passwd *runas_pw;
|
||||||
|
struct group *runas_gr;
|
||||||
|
char * const *argv;
|
||||||
|
char * const *user_env;
|
||||||
|
struct sudoers_str_list *log_servers;
|
||||||
|
struct timespec server_timeout;
|
||||||
|
int argc;
|
||||||
|
int lines;
|
||||||
|
int cols;
|
||||||
|
bool ignore_iolog_errors;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum client_state {
|
||||||
|
ERROR,
|
||||||
|
RECV_HELLO,
|
||||||
|
SEND_RESTART, /* TODO: currently unimplemented */
|
||||||
|
SEND_ACCEPT,
|
||||||
|
SEND_IO,
|
||||||
|
SEND_EXIT,
|
||||||
|
CLOSING,
|
||||||
|
FINISHED
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Remote connection closure, non-zero fields must come first. */
|
||||||
|
struct client_closure {
|
||||||
|
int sock;
|
||||||
|
enum client_state state;
|
||||||
|
bool disabled;
|
||||||
|
struct connection_buffer_list write_bufs;
|
||||||
|
struct connection_buffer_list free_bufs;
|
||||||
|
struct connection_buffer read_buf;
|
||||||
|
struct sudo_plugin_event *read_ev;
|
||||||
|
struct sudo_plugin_event *write_ev;
|
||||||
|
struct iolog_details *log_details;
|
||||||
|
struct timespec start_time;
|
||||||
|
struct timespec elapsed;
|
||||||
|
struct timespec committed;
|
||||||
|
char *iolog_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define CLIENT_CLOSURE_INITIALIZER(_c) \
|
||||||
|
{ \
|
||||||
|
-1, \
|
||||||
|
ERROR, \
|
||||||
|
false, \
|
||||||
|
TAILQ_HEAD_INITIALIZER((_c).write_bufs), \
|
||||||
|
TAILQ_HEAD_INITIALIZER((_c).free_bufs) \
|
||||||
|
}
|
||||||
|
|
||||||
|
/* iolog_client.c */
|
||||||
|
bool client_closure_fill(struct client_closure *closure, int sock, struct iolog_details *details, struct io_plugin *sudoers_io);
|
||||||
|
bool client_loop(struct client_closure *closure);
|
||||||
|
bool fmt_accept_message(struct client_closure *closure);
|
||||||
|
bool fmt_client_message(struct client_closure *closure, ClientMessage *msg);
|
||||||
|
bool fmt_exit_message(struct client_closure *closure, int exit_status, int error);
|
||||||
|
bool fmt_io_buf(struct client_closure *closure, int type, const char *buf, unsigned int len, struct timespec *delay);
|
||||||
|
bool fmt_suspend(struct client_closure *closure, const char *signame, struct timespec *delay);
|
||||||
|
bool fmt_winsize(struct client_closure *closure, unsigned int lines, unsigned int cols, struct timespec *delay);
|
||||||
|
int log_server_connect(struct sudoers_str_list *servers, struct timespec *timo);
|
||||||
|
void client_closure_free(struct client_closure *closure);
|
||||||
|
|
||||||
|
#endif /* SUDOERS_IOLOG_CLIENT_H */
|
@@ -506,6 +506,45 @@ bad:
|
|||||||
debug_return_int(MODE_ERROR);
|
debug_return_int(MODE_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert struct list_members to a comma-separated string with
|
||||||
|
* the given variable name.
|
||||||
|
*/
|
||||||
|
static char *
|
||||||
|
serialize_list(const char *varname, struct list_members *members)
|
||||||
|
{
|
||||||
|
struct list_member *lm, *next;
|
||||||
|
size_t len, result_size;
|
||||||
|
char *result;
|
||||||
|
debug_decl(serialize_list, SUDOERS_DEBUG_PLUGIN)
|
||||||
|
|
||||||
|
result_size = strlen(varname) + 1;
|
||||||
|
SLIST_FOREACH(lm, members, entries) {
|
||||||
|
result_size += strlen(lm->value) + 1;
|
||||||
|
}
|
||||||
|
if ((result = malloc(result_size)) == NULL)
|
||||||
|
goto bad;
|
||||||
|
/* No need to check len for overflow here. */
|
||||||
|
len = strlcpy(result, varname, result_size);
|
||||||
|
result[len++] = '=';
|
||||||
|
result[len] = '\0';
|
||||||
|
SLIST_FOREACH_SAFE(lm, members, entries, next) {
|
||||||
|
len = strlcat(result, lm->value, result_size);
|
||||||
|
if (len + (next != NULL) >= result_size) {
|
||||||
|
sudo_warnx(U_("internal error, %s overflow"), __func__);
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
if (next != NULL) {
|
||||||
|
result[len++] = ',';
|
||||||
|
result[len] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
debug_return_str(result);
|
||||||
|
bad:
|
||||||
|
free(result);
|
||||||
|
debug_return_str(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Setup the execution environment.
|
* Setup the execution environment.
|
||||||
* Builds up the command_info list and sets argv and envp.
|
* Builds up the command_info list and sets argv and envp.
|
||||||
@@ -686,6 +725,15 @@ sudoers_policy_exec_setup(char *argv[], char *envp[], mode_t cmnd_umask,
|
|||||||
if ((command_info[info_len++] = sudo_new_key_val("iolog_group", def_iolog_group)) == NULL)
|
if ((command_info[info_len++] = sudo_new_key_val("iolog_group", def_iolog_group)) == NULL)
|
||||||
goto oom;
|
goto oom;
|
||||||
}
|
}
|
||||||
|
if (!SLIST_EMPTY(&def_log_server)) {
|
||||||
|
char *log_servers = serialize_list("log_servers", &def_log_server);
|
||||||
|
if (log_servers == NULL)
|
||||||
|
goto oom;
|
||||||
|
command_info[info_len++] = log_servers;
|
||||||
|
|
||||||
|
if (asprintf(&command_info[info_len++], "log_server_timeout=%u", def_log_server_timeout) == -1)
|
||||||
|
goto oom;
|
||||||
|
}
|
||||||
if (def_command_timeout > 0 || user_timeout > 0) {
|
if (def_command_timeout > 0 || user_timeout > 0) {
|
||||||
int timeout = user_timeout;
|
int timeout = user_timeout;
|
||||||
if (timeout == 0 || def_command_timeout < timeout)
|
if (timeout == 0 || def_command_timeout < timeout)
|
||||||
|
@@ -438,6 +438,7 @@ exec_nopty(struct command_details *details, struct command_status *cstat)
|
|||||||
sudo_debug_printf(SUDO_DEBUG_ERROR, "event loop exited prematurely");
|
sudo_debug_printf(SUDO_DEBUG_ERROR, "event loop exited prematurely");
|
||||||
/* kill command */
|
/* kill command */
|
||||||
terminate_command(ec.cmnd_pid, true);
|
terminate_command(ec.cmnd_pid, true);
|
||||||
|
ec.cmnd_pid = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_SELINUX
|
#ifdef HAVE_SELINUX
|
||||||
|
@@ -1581,7 +1581,12 @@ exec_pty(struct command_details *details, struct command_status *cstat)
|
|||||||
if (sudo_ev_got_break(ec.evbase)) {
|
if (sudo_ev_got_break(ec.evbase)) {
|
||||||
/* error from callback or monitor died */
|
/* error from callback or monitor died */
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR, "event loop exited prematurely");
|
sudo_debug_printf(SUDO_DEBUG_ERROR, "event loop exited prematurely");
|
||||||
/* XXX - may need to terminate command if cmnd_pid != -1 */
|
/* kill command */
|
||||||
|
terminate_command(ec.cmnd_pid, true);
|
||||||
|
ec.cmnd_pid = -1;
|
||||||
|
/* TODO: need way to pass an error to the sudo front end */
|
||||||
|
cstat->type = CMD_WSTATUS;
|
||||||
|
cstat->val = W_EXITCODE(1, SIGKILL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Flush any remaining output, free I/O bufs and events, do logout. */
|
/* Flush any remaining output, free I/O bufs and events, do logout. */
|
||||||
|
@@ -1479,6 +1479,7 @@ sudo_plugin_event_alloc(void)
|
|||||||
ev_int->public.fd = plugin_event_fd;
|
ev_int->public.fd = plugin_event_fd;
|
||||||
ev_int->public.timeleft = plugin_event_timeleft;
|
ev_int->public.timeleft = plugin_event_timeleft;
|
||||||
ev_int->public.setbase = plugin_event_setbase;
|
ev_int->public.setbase = plugin_event_setbase;
|
||||||
|
ev_int->public.loopbreak = plugin_event_loopbreak;
|
||||||
ev_int->public.free = plugin_event_free;
|
ev_int->public.free = plugin_event_free;
|
||||||
|
|
||||||
/* Clear private portion in case caller tries to use us uninitialized. */
|
/* Clear private portion in case caller tries to use us uninitialized. */
|
||||||
|
Reference in New Issue
Block a user