mirror of
https://github.com/sudo-project/sudo.git
synced 2025-08-22 09:57:41 +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);
|
||||
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);
|
||||
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_free_loginfo(struct iolog_info *li);
|
||||
|
||||
|
@ -61,14 +61,32 @@
|
||||
static int timing_event_adj;
|
||||
|
||||
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;
|
||||
const char *errstr;
|
||||
size_t bufsize = 0, cwdsize = 0, cmdsize = 0;
|
||||
struct iolog_info *li = NULL;
|
||||
FILE *fp = NULL;
|
||||
int fd = -1;
|
||||
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:
|
||||
* 1) a log info line
|
||||
@ -80,9 +98,11 @@ iolog_parse_loginfo(FILE *fp, const char *logfile)
|
||||
if (getdelim(&buf, &bufsize, '\n', fp) == -1 ||
|
||||
getdelim(&li->cwd, &cwdsize, '\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;
|
||||
}
|
||||
fclose(fp);
|
||||
fp = NULL;
|
||||
|
||||
/* Strip the newline from the cwd and command. */
|
||||
li->cwd[strcspn(li->cwd, "\n")] = '\0';
|
||||
@ -98,20 +118,20 @@ iolog_parse_loginfo(FILE *fp, const char *logfile)
|
||||
|
||||
/* timestamp */
|
||||
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;
|
||||
}
|
||||
*ep = '\0';
|
||||
li->tstamp = sudo_strtonum(cp, 0, TIME_T_MAX, &errstr);
|
||||
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;
|
||||
}
|
||||
|
||||
/* submit user */
|
||||
cp = ep + 1;
|
||||
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;
|
||||
}
|
||||
if ((li->user = strndup(cp, (size_t)(ep - cp))) == NULL)
|
||||
@ -120,7 +140,7 @@ iolog_parse_loginfo(FILE *fp, const char *logfile)
|
||||
/* runas user */
|
||||
cp = ep + 1;
|
||||
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;
|
||||
}
|
||||
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 */
|
||||
cp = ep + 1;
|
||||
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;
|
||||
}
|
||||
if (cp != ep) {
|
||||
@ -156,14 +176,14 @@ iolog_parse_loginfo(FILE *fp, const char *logfile)
|
||||
li->lines = sudo_strtonum(cp, 1, INT_MAX, &errstr);
|
||||
if (errstr != NULL) {
|
||||
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) {
|
||||
cp = ep + 1;
|
||||
li->cols = sudo_strtonum(cp, 1, INT_MAX, &errstr);
|
||||
if (errstr != NULL) {
|
||||
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);
|
||||
|
||||
bad:
|
||||
if (fd != -1)
|
||||
close(fd);
|
||||
if (fp != NULL)
|
||||
fclose(fp);
|
||||
free(buf);
|
||||
iolog_free_loginfo(li);
|
||||
debug_return_ptr(NULL);
|
||||
|
@ -1487,8 +1487,7 @@ main(int argc, char *argv[])
|
||||
struct timespec elapsed = { 0, 0 };
|
||||
const char *iolog_id = NULL;
|
||||
const char *open_mode = "r";
|
||||
int ch, sock, iolog_dir_fd, fd;
|
||||
FILE *fp;
|
||||
int ch, sock, iolog_dir_fd;
|
||||
debug_decl_vars(main, SUDO_DEBUG_MAIN);
|
||||
|
||||
#if defined(SUDO_DEVEL) && defined(__OpenBSD__)
|
||||
@ -1582,12 +1581,7 @@ main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
/* Parse I/O log info file. */
|
||||
fd = openat(iolog_dir_fd, "log", O_RDONLY, 0);
|
||||
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)
|
||||
if ((log_info = iolog_parse_loginfo(iolog_dir_fd, iolog_dir)) == NULL)
|
||||
goto bad;
|
||||
|
||||
if ((evbase = sudo_ev_base_alloc()) == NULL)
|
||||
|
@ -82,22 +82,15 @@ sudo_printf_int(int msg_type, const char *fmt, ...)
|
||||
}
|
||||
|
||||
bool
|
||||
validate_iolog_info(const char *logfile)
|
||||
validate_iolog_info(const char *log_dir)
|
||||
{
|
||||
struct iolog_info *info;
|
||||
time_t now;
|
||||
FILE *fp;
|
||||
|
||||
time(&now);
|
||||
|
||||
/* Parse log file. */
|
||||
if ((fp = fopen(logfile, "r")) == NULL) {
|
||||
sudo_warn("%s", logfile);
|
||||
return false;
|
||||
}
|
||||
info = iolog_parse_loginfo(fp, logfile);
|
||||
fclose(fp);
|
||||
if (info == NULL)
|
||||
if ((info = iolog_parse_loginfo(-1, log_dir)) == NULL)
|
||||
return false;
|
||||
|
||||
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. */
|
||||
(*ntests)++;
|
||||
snprintf(iolog_path, sizeof(iolog_path), "%s/log", iolog_dir);
|
||||
if (!validate_iolog_info(iolog_path))
|
||||
if (!validate_iolog_info(iolog_dir))
|
||||
(*nerrors)++;
|
||||
|
||||
/* Test log_ttyout endpoint. */
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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
|
||||
* 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
|
||||
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 interactive = true, suspend_wait = false, resize = true;
|
||||
const char *decimal, *id, *user = NULL, *pattern = NULL, *tty = NULL;
|
||||
@ -215,7 +215,6 @@ main(int argc, char *argv[])
|
||||
struct iolog_info *li;
|
||||
struct timespec max_delay_storage, *max_delay = NULL;
|
||||
double dval;
|
||||
FILE *fp;
|
||||
debug_decl(main, SUDO_DEBUG_MAIN);
|
||||
|
||||
#if defined(SUDO_DEVEL) && defined(__OpenBSD__)
|
||||
@ -363,12 +362,8 @@ main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
/* Parse log file. */
|
||||
fd = openat(iolog_dir_fd, "log", O_RDONLY, 0);
|
||||
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)
|
||||
if ((li = iolog_parse_loginfo(iolog_dir_fd, iolog_dir)) == NULL)
|
||||
goto done;
|
||||
fclose(fp);
|
||||
printf(_("Replaying sudo session: %s"), li->cmd);
|
||||
|
||||
/* Setup terminal if appropriate. */
|
||||
@ -1306,28 +1301,23 @@ match_expr(struct search_node_list *head, struct iolog_info *log, bool last_matc
|
||||
}
|
||||
|
||||
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;
|
||||
struct iolog_info *li = NULL;
|
||||
const char *timestr;
|
||||
int ret = -1;
|
||||
FILE *fp;
|
||||
debug_decl(list_session, SUDO_DEBUG_UTIL);
|
||||
|
||||
if ((fp = fopen(logfile, "r")) == NULL) {
|
||||
sudo_warn("%s", logfile);
|
||||
goto done;
|
||||
}
|
||||
if ((li = iolog_parse_loginfo(fp, logfile)) == NULL)
|
||||
if ((li = iolog_parse_loginfo(-1, log_dir)) == NULL)
|
||||
goto done;
|
||||
|
||||
/* Match on search expression if there is one. */
|
||||
if (!STAILQ_EMPTY(&search_expr) && !match_expr(&search_expr, li, true))
|
||||
goto done;
|
||||
|
||||
/* Convert from /var/log/sudo-sessions/00/00/01/log to 000001 */
|
||||
cp = logfile + strlen(session_dir) + 1;
|
||||
/* Convert from /var/log/sudo-sessions/00/00/01 to 000001 */
|
||||
cp = log_dir + strlen(session_dir) + 1;
|
||||
if (IS_IDLOG(cp)) {
|
||||
idbuf[0] = cp[0];
|
||||
idbuf[1] = cp[1];
|
||||
@ -1338,8 +1328,7 @@ list_session(char *logfile, regex_t *re, const char *user, const char *tty)
|
||||
idbuf[6] = '\0';
|
||||
idstr = idbuf;
|
||||
} else {
|
||||
/* Not an id, just use the iolog_file portion. */
|
||||
cp[strlen(cp) - 4] = '\0';
|
||||
/* Not an id, use as-is. */
|
||||
idstr = cp;
|
||||
}
|
||||
/* XXX - print lines + cols? */
|
||||
@ -1354,8 +1343,6 @@ list_session(char *logfile, regex_t *re, const char *user, const char *tty)
|
||||
ret = 0;
|
||||
|
||||
done:
|
||||
if (fp != NULL)
|
||||
fclose(fp);
|
||||
iolog_free_loginfo(li);
|
||||
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. */
|
||||
if (lstat(pathbuf, &sb) == 0 && S_ISREG(sb.st_mode)) {
|
||||
pathbuf[sdlen + len - 4] = '\0';
|
||||
list_session(pathbuf, re, user, tty);
|
||||
} else {
|
||||
/* Strip off "/log" and recurse if a dir. */
|
||||
/* Strip off "/log" and recurse if a non-log dir. */
|
||||
pathbuf[sdlen + len - 4] = '\0';
|
||||
if (checked_type ||
|
||||
(lstat(pathbuf, &sb) == 0 && S_ISDIR(sb.st_mode)))
|
||||
|
Loading…
x
Reference in New Issue
Block a user