mirror of
https://github.com/sudo-project/sudo.git
synced 2025-08-28 21:07:55 +00:00
iolog_parse_loginfo() now opens the log file itself.
This commit is contained in:
parent
9ab8efa8f4
commit
a644c1d1d2
@ -109,7 +109,7 @@ bool expand_iolog_path(const char *inpath, char *path, size_t pathlen, const str
|
|||||||
bool iolog_parse_timing(const char *line, struct timing_closure *timing);
|
bool iolog_parse_timing(const char *line, struct timing_closure *timing);
|
||||||
char *iolog_parse_delay(const char *cp, struct timespec *delay, const char *decimal_point);
|
char *iolog_parse_delay(const char *cp, struct timespec *delay, const char *decimal_point);
|
||||||
int iolog_read_timing_record(struct iolog_file *iol, struct timing_closure *timing);
|
int iolog_read_timing_record(struct iolog_file *iol, struct timing_closure *timing);
|
||||||
struct iolog_info *iolog_parse_loginfo(FILE *fp, const char *iolog_dir);
|
struct iolog_info *iolog_parse_loginfo(int dfd, const char *iolog_dir);
|
||||||
void iolog_adjust_delay(struct timespec *delay, struct timespec *max_delay, double scale_factor);
|
void iolog_adjust_delay(struct timespec *delay, struct timespec *max_delay, double scale_factor);
|
||||||
void iolog_free_loginfo(struct iolog_info *li);
|
void iolog_free_loginfo(struct iolog_info *li);
|
||||||
|
|
||||||
|
@ -61,14 +61,32 @@
|
|||||||
static int timing_event_adj;
|
static int timing_event_adj;
|
||||||
|
|
||||||
struct iolog_info *
|
struct iolog_info *
|
||||||
iolog_parse_loginfo(FILE *fp, const char *logfile)
|
iolog_parse_loginfo(int dfd, const char *iolog_dir)
|
||||||
{
|
{
|
||||||
char *buf = NULL, *cp, *ep;
|
char *buf = NULL, *cp, *ep;
|
||||||
const char *errstr;
|
const char *errstr;
|
||||||
size_t bufsize = 0, cwdsize = 0, cmdsize = 0;
|
size_t bufsize = 0, cwdsize = 0, cmdsize = 0;
|
||||||
struct iolog_info *li = NULL;
|
struct iolog_info *li = NULL;
|
||||||
|
FILE *fp = NULL;
|
||||||
|
int fd = -1;
|
||||||
debug_decl(iolog_parse_loginfo, SUDO_DEBUG_UTIL);
|
debug_decl(iolog_parse_loginfo, SUDO_DEBUG_UTIL);
|
||||||
|
|
||||||
|
if (dfd == -1) {
|
||||||
|
if ((dfd = open(iolog_dir, O_RDONLY)) == -1) {
|
||||||
|
sudo_warn("%s", iolog_dir);
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
fd = openat(dfd, "log", O_RDONLY, 0);
|
||||||
|
close(dfd);
|
||||||
|
} else {
|
||||||
|
fd = openat(dfd, "log", O_RDONLY, 0);
|
||||||
|
}
|
||||||
|
if (fd == -1 || (fp = fdopen(fd, "r")) == NULL) {
|
||||||
|
sudo_warn("%s/log", iolog_dir);
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
fd = -1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Info file has three lines:
|
* Info file has three lines:
|
||||||
* 1) a log info line
|
* 1) a log info line
|
||||||
@ -80,9 +98,11 @@ iolog_parse_loginfo(FILE *fp, const char *logfile)
|
|||||||
if (getdelim(&buf, &bufsize, '\n', fp) == -1 ||
|
if (getdelim(&buf, &bufsize, '\n', fp) == -1 ||
|
||||||
getdelim(&li->cwd, &cwdsize, '\n', fp) == -1 ||
|
getdelim(&li->cwd, &cwdsize, '\n', fp) == -1 ||
|
||||||
getdelim(&li->cmd, &cmdsize, '\n', fp) == -1) {
|
getdelim(&li->cmd, &cmdsize, '\n', fp) == -1) {
|
||||||
sudo_warn(U_("%s: invalid log file"), logfile);
|
sudo_warn(U_("%s: invalid log file"), iolog_dir);
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
fclose(fp);
|
||||||
|
fp = NULL;
|
||||||
|
|
||||||
/* Strip the newline from the cwd and command. */
|
/* Strip the newline from the cwd and command. */
|
||||||
li->cwd[strcspn(li->cwd, "\n")] = '\0';
|
li->cwd[strcspn(li->cwd, "\n")] = '\0';
|
||||||
@ -98,20 +118,20 @@ iolog_parse_loginfo(FILE *fp, const char *logfile)
|
|||||||
|
|
||||||
/* timestamp */
|
/* timestamp */
|
||||||
if ((ep = strchr(cp, ':')) == NULL) {
|
if ((ep = strchr(cp, ':')) == NULL) {
|
||||||
sudo_warn(U_("%s: time stamp field is missing"), logfile);
|
sudo_warn(U_("%s: time stamp field is missing"), iolog_dir);
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
*ep = '\0';
|
*ep = '\0';
|
||||||
li->tstamp = sudo_strtonum(cp, 0, TIME_T_MAX, &errstr);
|
li->tstamp = sudo_strtonum(cp, 0, TIME_T_MAX, &errstr);
|
||||||
if (errstr != NULL) {
|
if (errstr != NULL) {
|
||||||
sudo_warn(U_("%s: time stamp %s: %s"), logfile, cp, errstr);
|
sudo_warn(U_("%s: time stamp %s: %s"), iolog_dir, cp, errstr);
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* submit user */
|
/* submit user */
|
||||||
cp = ep + 1;
|
cp = ep + 1;
|
||||||
if ((ep = strchr(cp, ':')) == NULL) {
|
if ((ep = strchr(cp, ':')) == NULL) {
|
||||||
sudo_warn(U_("%s: user field is missing"), logfile);
|
sudo_warn(U_("%s: user field is missing"), iolog_dir);
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
if ((li->user = strndup(cp, (size_t)(ep - cp))) == NULL)
|
if ((li->user = strndup(cp, (size_t)(ep - cp))) == NULL)
|
||||||
@ -120,7 +140,7 @@ iolog_parse_loginfo(FILE *fp, const char *logfile)
|
|||||||
/* runas user */
|
/* runas user */
|
||||||
cp = ep + 1;
|
cp = ep + 1;
|
||||||
if ((ep = strchr(cp, ':')) == NULL) {
|
if ((ep = strchr(cp, ':')) == NULL) {
|
||||||
sudo_warn(U_("%s: runas user field is missing"), logfile);
|
sudo_warn(U_("%s: runas user field is missing"), iolog_dir);
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
if ((li->runas_user = strndup(cp, (size_t)(ep - cp))) == NULL)
|
if ((li->runas_user = strndup(cp, (size_t)(ep - cp))) == NULL)
|
||||||
@ -129,7 +149,7 @@ iolog_parse_loginfo(FILE *fp, const char *logfile)
|
|||||||
/* runas group */
|
/* runas group */
|
||||||
cp = ep + 1;
|
cp = ep + 1;
|
||||||
if ((ep = strchr(cp, ':')) == NULL) {
|
if ((ep = strchr(cp, ':')) == NULL) {
|
||||||
sudo_warn(U_("%s: runas group field is missing"), logfile);
|
sudo_warn(U_("%s: runas group field is missing"), iolog_dir);
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
if (cp != ep) {
|
if (cp != ep) {
|
||||||
@ -156,14 +176,14 @@ iolog_parse_loginfo(FILE *fp, const char *logfile)
|
|||||||
li->lines = sudo_strtonum(cp, 1, INT_MAX, &errstr);
|
li->lines = sudo_strtonum(cp, 1, INT_MAX, &errstr);
|
||||||
if (errstr != NULL) {
|
if (errstr != NULL) {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
"%s: tty lines %s: %s", logfile, cp, errstr);
|
"%s: tty lines %s: %s", iolog_dir, cp, errstr);
|
||||||
}
|
}
|
||||||
if (ep != NULL) {
|
if (ep != NULL) {
|
||||||
cp = ep + 1;
|
cp = ep + 1;
|
||||||
li->cols = sudo_strtonum(cp, 1, INT_MAX, &errstr);
|
li->cols = sudo_strtonum(cp, 1, INT_MAX, &errstr);
|
||||||
if (errstr != NULL) {
|
if (errstr != NULL) {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
"%s: tty cols %s: %s", logfile, cp, errstr);
|
"%s: tty cols %s: %s", iolog_dir, cp, errstr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -171,6 +191,10 @@ iolog_parse_loginfo(FILE *fp, const char *logfile)
|
|||||||
debug_return_ptr(li);
|
debug_return_ptr(li);
|
||||||
|
|
||||||
bad:
|
bad:
|
||||||
|
if (fd != -1)
|
||||||
|
close(fd);
|
||||||
|
if (fp != NULL)
|
||||||
|
fclose(fp);
|
||||||
free(buf);
|
free(buf);
|
||||||
iolog_free_loginfo(li);
|
iolog_free_loginfo(li);
|
||||||
debug_return_ptr(NULL);
|
debug_return_ptr(NULL);
|
||||||
|
@ -1487,8 +1487,7 @@ main(int argc, char *argv[])
|
|||||||
struct timespec elapsed = { 0, 0 };
|
struct timespec elapsed = { 0, 0 };
|
||||||
const char *iolog_id = NULL;
|
const char *iolog_id = NULL;
|
||||||
const char *open_mode = "r";
|
const char *open_mode = "r";
|
||||||
int ch, sock, iolog_dir_fd, fd;
|
int ch, sock, iolog_dir_fd;
|
||||||
FILE *fp;
|
|
||||||
debug_decl_vars(main, SUDO_DEBUG_MAIN);
|
debug_decl_vars(main, SUDO_DEBUG_MAIN);
|
||||||
|
|
||||||
#if defined(SUDO_DEVEL) && defined(__OpenBSD__)
|
#if defined(SUDO_DEVEL) && defined(__OpenBSD__)
|
||||||
@ -1582,12 +1581,7 @@ main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Parse I/O log info file. */
|
/* Parse I/O log info file. */
|
||||||
fd = openat(iolog_dir_fd, "log", O_RDONLY, 0);
|
if ((log_info = iolog_parse_loginfo(iolog_dir_fd, iolog_dir)) == NULL)
|
||||||
if (fd == -1 || (fp = fdopen(fd, "r")) == NULL) {
|
|
||||||
sudo_warn("%s/log", iolog_dir);
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
if ((log_info = iolog_parse_loginfo(fp, iolog_dir)) == NULL)
|
|
||||||
goto bad;
|
goto bad;
|
||||||
|
|
||||||
if ((evbase = sudo_ev_base_alloc()) == NULL)
|
if ((evbase = sudo_ev_base_alloc()) == NULL)
|
||||||
|
@ -82,22 +82,15 @@ sudo_printf_int(int msg_type, const char *fmt, ...)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
validate_iolog_info(const char *logfile)
|
validate_iolog_info(const char *log_dir)
|
||||||
{
|
{
|
||||||
struct iolog_info *info;
|
struct iolog_info *info;
|
||||||
time_t now;
|
time_t now;
|
||||||
FILE *fp;
|
|
||||||
|
|
||||||
time(&now);
|
time(&now);
|
||||||
|
|
||||||
/* Parse log file. */
|
/* Parse log file. */
|
||||||
if ((fp = fopen(logfile, "r")) == NULL) {
|
if ((info = iolog_parse_loginfo(-1, log_dir)) == NULL)
|
||||||
sudo_warn("%s", logfile);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
info = iolog_parse_loginfo(fp, logfile);
|
|
||||||
fclose(fp);
|
|
||||||
if (info == NULL)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (strcmp(info->cwd, "/") != 0) {
|
if (strcmp(info->cwd, "/") != 0) {
|
||||||
@ -262,8 +255,7 @@ test_endpoints(int *ntests, int *nerrors, const char *iolog_dir, char *envp[])
|
|||||||
|
|
||||||
/* Validate I/O log info file. */
|
/* Validate I/O log info file. */
|
||||||
(*ntests)++;
|
(*ntests)++;
|
||||||
snprintf(iolog_path, sizeof(iolog_path), "%s/log", iolog_dir);
|
if (!validate_iolog_info(iolog_dir))
|
||||||
if (!validate_iolog_info(iolog_path))
|
|
||||||
(*nerrors)++;
|
(*nerrors)++;
|
||||||
|
|
||||||
/* Test log_ttyout endpoint. */
|
/* Test log_ttyout endpoint. */
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-License-Identifier: ISC
|
* SPDX-License-Identifier: ISC
|
||||||
*
|
*
|
||||||
* Copyright (c) 2009-2019 Todd C. Miller <Todd.Miller@sudo.ws>
|
* Copyright (c) 2009-2020 Todd C. Miller <Todd.Miller@sudo.ws>
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
@ -207,7 +207,7 @@ __dso_public int main(int argc, char *argv[]);
|
|||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int ch, fd, i, iolog_dir_fd, len, exitcode = EXIT_FAILURE;
|
int ch, i, iolog_dir_fd, len, exitcode = EXIT_FAILURE;
|
||||||
bool def_filter = true, listonly = false;
|
bool def_filter = true, listonly = false;
|
||||||
bool interactive = true, suspend_wait = false, resize = true;
|
bool interactive = true, suspend_wait = false, resize = true;
|
||||||
const char *decimal, *id, *user = NULL, *pattern = NULL, *tty = NULL;
|
const char *decimal, *id, *user = NULL, *pattern = NULL, *tty = NULL;
|
||||||
@ -215,7 +215,6 @@ main(int argc, char *argv[])
|
|||||||
struct iolog_info *li;
|
struct iolog_info *li;
|
||||||
struct timespec max_delay_storage, *max_delay = NULL;
|
struct timespec max_delay_storage, *max_delay = NULL;
|
||||||
double dval;
|
double dval;
|
||||||
FILE *fp;
|
|
||||||
debug_decl(main, SUDO_DEBUG_MAIN);
|
debug_decl(main, SUDO_DEBUG_MAIN);
|
||||||
|
|
||||||
#if defined(SUDO_DEVEL) && defined(__OpenBSD__)
|
#if defined(SUDO_DEVEL) && defined(__OpenBSD__)
|
||||||
@ -363,12 +362,8 @@ main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Parse log file. */
|
/* Parse log file. */
|
||||||
fd = openat(iolog_dir_fd, "log", O_RDONLY, 0);
|
if ((li = iolog_parse_loginfo(iolog_dir_fd, iolog_dir)) == NULL)
|
||||||
if (fd == -1 || (fp = fdopen(fd, "r")) == NULL)
|
|
||||||
sudo_fatal(U_("unable to open %s/%s"), iolog_dir, "log");
|
|
||||||
if ((li = iolog_parse_loginfo(fp, iolog_dir)) == NULL)
|
|
||||||
goto done;
|
goto done;
|
||||||
fclose(fp);
|
|
||||||
printf(_("Replaying sudo session: %s"), li->cmd);
|
printf(_("Replaying sudo session: %s"), li->cmd);
|
||||||
|
|
||||||
/* Setup terminal if appropriate. */
|
/* Setup terminal if appropriate. */
|
||||||
@ -1306,28 +1301,23 @@ match_expr(struct search_node_list *head, struct iolog_info *log, bool last_matc
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
list_session(char *logfile, regex_t *re, const char *user, const char *tty)
|
list_session(char *log_dir, regex_t *re, const char *user, const char *tty)
|
||||||
{
|
{
|
||||||
char idbuf[7], *idstr, *cp;
|
char idbuf[7], *idstr, *cp;
|
||||||
struct iolog_info *li = NULL;
|
struct iolog_info *li = NULL;
|
||||||
const char *timestr;
|
const char *timestr;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
FILE *fp;
|
|
||||||
debug_decl(list_session, SUDO_DEBUG_UTIL);
|
debug_decl(list_session, SUDO_DEBUG_UTIL);
|
||||||
|
|
||||||
if ((fp = fopen(logfile, "r")) == NULL) {
|
if ((li = iolog_parse_loginfo(-1, log_dir)) == NULL)
|
||||||
sudo_warn("%s", logfile);
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
if ((li = iolog_parse_loginfo(fp, logfile)) == NULL)
|
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
/* Match on search expression if there is one. */
|
/* Match on search expression if there is one. */
|
||||||
if (!STAILQ_EMPTY(&search_expr) && !match_expr(&search_expr, li, true))
|
if (!STAILQ_EMPTY(&search_expr) && !match_expr(&search_expr, li, true))
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
/* Convert from /var/log/sudo-sessions/00/00/01/log to 000001 */
|
/* Convert from /var/log/sudo-sessions/00/00/01 to 000001 */
|
||||||
cp = logfile + strlen(session_dir) + 1;
|
cp = log_dir + strlen(session_dir) + 1;
|
||||||
if (IS_IDLOG(cp)) {
|
if (IS_IDLOG(cp)) {
|
||||||
idbuf[0] = cp[0];
|
idbuf[0] = cp[0];
|
||||||
idbuf[1] = cp[1];
|
idbuf[1] = cp[1];
|
||||||
@ -1338,8 +1328,7 @@ list_session(char *logfile, regex_t *re, const char *user, const char *tty)
|
|||||||
idbuf[6] = '\0';
|
idbuf[6] = '\0';
|
||||||
idstr = idbuf;
|
idstr = idbuf;
|
||||||
} else {
|
} else {
|
||||||
/* Not an id, just use the iolog_file portion. */
|
/* Not an id, use as-is. */
|
||||||
cp[strlen(cp) - 4] = '\0';
|
|
||||||
idstr = cp;
|
idstr = cp;
|
||||||
}
|
}
|
||||||
/* XXX - print lines + cols? */
|
/* XXX - print lines + cols? */
|
||||||
@ -1354,8 +1343,6 @@ list_session(char *logfile, regex_t *re, const char *user, const char *tty)
|
|||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
done:
|
done:
|
||||||
if (fp != NULL)
|
|
||||||
fclose(fp);
|
|
||||||
iolog_free_loginfo(li);
|
iolog_free_loginfo(li);
|
||||||
debug_return_int(ret);
|
debug_return_int(ret);
|
||||||
}
|
}
|
||||||
@ -1445,9 +1432,10 @@ find_sessions(const char *dir, regex_t *re, const char *user, const char *tty)
|
|||||||
|
|
||||||
/* Check for dir with a log file. */
|
/* Check for dir with a log file. */
|
||||||
if (lstat(pathbuf, &sb) == 0 && S_ISREG(sb.st_mode)) {
|
if (lstat(pathbuf, &sb) == 0 && S_ISREG(sb.st_mode)) {
|
||||||
|
pathbuf[sdlen + len - 4] = '\0';
|
||||||
list_session(pathbuf, re, user, tty);
|
list_session(pathbuf, re, user, tty);
|
||||||
} else {
|
} else {
|
||||||
/* Strip off "/log" and recurse if a dir. */
|
/* Strip off "/log" and recurse if a non-log dir. */
|
||||||
pathbuf[sdlen + len - 4] = '\0';
|
pathbuf[sdlen + len - 4] = '\0';
|
||||||
if (checked_type ||
|
if (checked_type ||
|
||||||
(lstat(pathbuf, &sb) == 0 && S_ISDIR(sb.st_mode)))
|
(lstat(pathbuf, &sb) == 0 && S_ISDIR(sb.st_mode)))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user