Clear the write bit on the timing file for completed logs.

This allows us to tell whether or not a log can be restarted.
This commit is contained in:
Todd C. Miller
2019-10-24 20:04:33 -06:00
parent dbf78d0716
commit 955fa11b53
6 changed files with 65 additions and 17 deletions

View File

@@ -16,7 +16,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
.TH "SUDO_LOGSRVD" "@mansectsu@" "October 3, 2019" "Sudo @PACKAGE_VERSION@" "System Manager's Manual"
.TH "SUDO_LOGSRVD" "@mansectsu@" "October 16, 2019" "Sudo @PACKAGE_VERSION@" "System Manager's Manual"
.nh
.if n .ad l
.SH "NAME"
@@ -46,6 +46,16 @@ utility in the same way as logs generated directly by the
\fBsudoers\fR
plugin.
.PP
The server also supports restarting interrupted log transfers.
To distinguish completed I/O logs from incomplete ones, the
I/O log timing file is set to be read-only when the log is complete.
.PP
Configuration parameters for
\fBsudo_logsrvd\fR
may be specified in the
sudo_logsrvd.conf(@mansectform@)
file.
.PP
The options are as follows:
.TP 12n
\fB\-f\fR, \fB\--file\fR
@@ -60,7 +70,7 @@ Display a short help message to the standard output and exit.
\fB\-n\fR, \fB\--no-fork\fR
Run
\fBsudo_logsrvd\fR
in the the foreground instead of detaching from the terminal and becoming
in the foreground instead of detaching from the terminal and becoming
a daemon.
.TP 12n
\fB\-R\fR, \fB\--random-drop\fR
@@ -74,12 +84,6 @@ client to restart a connection.
Print the
\fBsudo_logsrvd\fR
version and exit.
.PP
Configuration parameters for
\fBsudo_logsrvd\fR
may be set in the
sudo_logsrvd.conf(@mansectform@)
file.
.SS "Debugging sudo_logsrvd"
\fBsudo_logsrvd\fR
supports a flexible debugging framework that is configured via
@@ -98,8 +102,12 @@ Sudo front end configuration
.TP 26n
\fI@sysconfdir@/sudo_logsrvd.conf\fR
Sudo log server configuration file
.TP 26n
\fI@iolog_dir@\fR
Default I/O log file location
.SH "SEE ALSO"
sudo.conf(@mansectform@),
sudo_logsrvd.conf(@mansectform@),
sudoers(@mansectform@),
sudo(@mansectsu@),
sudo_sendlog(@mansectsu@),

View File

@@ -15,7 +15,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
.Dd October 3, 2019
.Dd October 16, 2019
.Dt SUDO_LOGSRVD @mansectsu@
.Os Sudo @PACKAGE_VERSION@
.Sh NAME
@@ -44,6 +44,16 @@ utility in the same way as logs generated directly by the
.Nm sudoers
plugin.
.Pp
The server also supports restarting interrupted log transfers.
To distinguish completed I/O logs from incomplete ones, the
I/O log timing file is set to be read-only when the log is complete.
.Pp
Configuration parameters for
.Nm
may be specified in the
.Xr sudo_logsrvd.conf @mansectform@
file.
.Pp
The options are as follows:
.Bl -tag -width Fl
.It Fl f , -file
@@ -69,12 +79,6 @@ Print the
.Nm
version and exit.
.El
.Pp
Configuration parameters for
.Nm
may be set in the
.Xr sudo_logsrvd.conf @mansectform@
file.
.Ss Debugging sudo_logsrvd
.Nm
supports a flexible debugging framework that is configured via
@@ -92,9 +96,12 @@ please refer to its manual.
Sudo front end configuration
.It Pa @sysconfdir@/sudo_logsrvd.conf
Sudo log server configuration file
.It Pa @iolog_dir@
Default I/O log file location
.El
.Sh SEE ALSO
.Xr sudo.conf @mansectform@ ,
.Xr sudo_logsrvd.conf @mansectform@ ,
.Xr sudoers @mansectform@ ,
.Xr sudo @mansectsu@ ,
.Xr sudo_sendlog @mansectsu@ ,

View File

@@ -37,6 +37,7 @@
#include <unistd.h>
#include "log_server.pb-c.h"
#include "sudo_gettext.h" /* must be included before sudo_compat.h */
#include "sudo_compat.h"
#include "sudo_queue.h"
#include "sudo_debug.h"
@@ -809,6 +810,7 @@ bool
iolog_restart(RestartMessage *msg, struct connection_closure *closure)
{
struct timespec target;
struct stat sb;
int iofd;
debug_decl(iolog_restart, SUDO_DEBUG_UTIL)
@@ -830,6 +832,19 @@ iolog_restart(RestartMessage *msg, struct connection_closure *closure)
goto bad;
}
/* If the timing file write bit is clear, log is already complete. */
if (fstatat(closure->iolog_dir_fd, "timing", &sb, 0) == -1) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
"unable to stat %s/timing", closure->details.iolog_path);
goto bad;
}
if (!ISSET(sb.st_mode, S_IWUSR)) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
"%s already complete", closure->details.iolog_path);
closure->errstr = _("log is already complete, cannot be restarted");
goto bad;
}
/* Open existing I/O log files. */
if (!iolog_open_all(closure->iolog_dir_fd, closure->details.iolog_path,
closure->iolog_files, "r+"))
@@ -856,6 +871,8 @@ iolog_restart(RestartMessage *msg, struct connection_closure *closure)
/* Ready to log I/O buffers. */
debug_return_bool(true);
bad:
if (closure->errstr == NULL)
closure->errstr = _("unable to restart log");
debug_return_bool(false);
}

View File

@@ -236,7 +236,7 @@ handle_accept(AcceptMessage *msg, struct connection_closure *closure)
debug_return_bool(true);
}
/* Send log ID to client for restarting connectoins. */
/* Send log ID to client for restarting connections. */
if (!fmt_log_id_message(closure->details.iolog_path, &closure->write_buf))
debug_return_bool(false);
if (sudo_ev_add(NULL, closure->write_ev, NULL, false) == -1) {
@@ -297,6 +297,7 @@ static bool
handle_exit(ExitMessage *msg, struct connection_closure *closure)
{
struct timespec tv = { 0, 0 };
mode_t mode;
debug_decl(handle_exit, SUDO_DEBUG_UTIL)
if (closure->state != RUNNING) {
@@ -325,6 +326,14 @@ handle_exit(ExitMessage *msg, struct connection_closure *closure)
__func__, (long long)closure->elapsed_time.tv_sec,
closure->elapsed_time.tv_nsec);
/* Clear write bits from I/O timing file to indicate completion. */
mode = logsrvd_conf_iolog_mode();
CLR(mode, S_IWUSR|S_IWGRP|S_IWOTH);
if (fchmodat(closure->iolog_dir_fd, "timing", mode, 0) == -1) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
"unable to fchmodat timing file");
}
/* Schedule the final commit point event immediately. */
if (sudo_ev_add(NULL, closure->commit_ev, &tv, false) == -1) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
@@ -352,7 +361,7 @@ handle_restart(RestartMessage *msg, struct connection_closure *closure)
if (!iolog_restart(msg, closure)) {
sudo_debug_printf(SUDO_DEBUG_WARN, "%s: unable to restart I/O log", __func__);
/* XXX - structured error message so client can send from beginning */
if (!fmt_error_message("unable to restart log", &closure->write_buf))
if (!fmt_error_message(closure->errstr, &closure->write_buf))
debug_return_bool(false);
sudo_ev_del(NULL, closure->read_ev);
if (sudo_ev_add(NULL, closure->write_ev, NULL, false) == -1) {

View File

@@ -145,6 +145,7 @@ int logsrvd_conf_syslog_facility(void);
int logsrvd_conf_syslog_acceptpri(void);
int logsrvd_conf_syslog_rejectpri(void);
int logsrvd_conf_syslog_alertpri(void);
mode_t logsrvd_conf_iolog_mode(void);
const char *logsrvd_conf_logfile_path(void);
const char *logsrvd_conf_logfile_time_format(void);

View File

@@ -98,6 +98,12 @@ static struct logsrvd_config {
} *logsrvd_config;
/* iolog getters */
mode_t
logsrvd_conf_iolog_mode(void)
{
return logsrvd_config->iolog.mode;
}
const char *
logsrvd_conf_iolog_dir(void)
{