Enable sudo_logsrvd.conf settings.
This commit is contained in:
@@ -49,7 +49,7 @@ sudoers_gid = @SUDOERS_GID@
|
|||||||
sudoers_mode = @SUDOERS_MODE@
|
sudoers_mode = @SUDOERS_MODE@
|
||||||
shlib_mode = @SHLIB_MODE@
|
shlib_mode = @SHLIB_MODE@
|
||||||
|
|
||||||
SUBDIRS = lib/util lib/iolog @ZLIB_SRC@ logsrvd plugins/group_file \
|
SUBDIRS = lib/util @ZLIB_SRC@ lib/iolog logsrvd plugins/group_file \
|
||||||
plugins/sudoers plugins/system_group src include doc examples
|
plugins/sudoers plugins/system_group src include doc examples
|
||||||
|
|
||||||
SAMPLES = plugins/sample
|
SAMPLES = plugins/sample
|
||||||
|
@@ -98,11 +98,11 @@ struct iolog_file {
|
|||||||
|
|
||||||
struct iolog_path_escape {
|
struct iolog_path_escape {
|
||||||
const char *name;
|
const char *name;
|
||||||
size_t (*copy_fn)(char *, size_t, char *);
|
size_t (*copy_fn)(char *, size_t, char *, void *);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* iolog_path.c */
|
/* iolog_path.c */
|
||||||
char *expand_iolog_path(const char *prefix, const char *dir, const char *file, char **slashp, const struct iolog_path_escape *escapes);
|
char *expand_iolog_path(const char *prefix, const char *dir, const char *file, char **slashp, const struct iolog_path_escape *escapes, void *closure);
|
||||||
|
|
||||||
/* iolog_util.c */
|
/* iolog_util.c */
|
||||||
bool parse_timing(const char *line, struct timing_closure *timing);
|
bool parse_timing(const char *line, struct timing_closure *timing);
|
||||||
|
@@ -59,7 +59,7 @@
|
|||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
expand_iolog_path(const char *prefix, const char *dir, const char *file,
|
expand_iolog_path(const char *prefix, const char *dir, const char *file,
|
||||||
char **slashp, const struct iolog_path_escape *escapes)
|
char **slashp, const struct iolog_path_escape *escapes, void *closure)
|
||||||
{
|
{
|
||||||
size_t len, prelen = 0;
|
size_t len, prelen = 0;
|
||||||
char *dst, *dst0, *path, *pathend, tmpbuf[PATH_MAX];
|
char *dst, *dst0, *path, *pathend, tmpbuf[PATH_MAX];
|
||||||
@@ -128,7 +128,7 @@ expand_iolog_path(const char *prefix, const char *dir, const char *file,
|
|||||||
}
|
}
|
||||||
if (esc->name != NULL) {
|
if (esc->name != NULL) {
|
||||||
len = esc->copy_fn(dst, (size_t)(pathend - dst),
|
len = esc->copy_fn(dst, (size_t)(pathend - dst),
|
||||||
path + prelen);
|
path + prelen, closure);
|
||||||
if (len >= (size_t)(pathend - dst))
|
if (len >= (size_t)(pathend - dst))
|
||||||
goto bad;
|
goto bad;
|
||||||
dst += len;
|
dst += len;
|
||||||
|
@@ -69,7 +69,7 @@ reset_escape_data(struct iolog_escape_data *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
fill_seq(char *str, size_t strsize, char *logdir)
|
fill_seq(char *str, size_t strsize, char *logdir, void *closure)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
@@ -83,37 +83,37 @@ fill_seq(char *str, size_t strsize, char *logdir)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
fill_user(char *str, size_t strsize, char *unused)
|
fill_user(char *str, size_t strsize, char *unused, void *closure)
|
||||||
{
|
{
|
||||||
return strlcpy(str, escape_data.user, strsize);
|
return strlcpy(str, escape_data.user, strsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
fill_group(char *str, size_t strsize, char *unused)
|
fill_group(char *str, size_t strsize, char *unused, void *closure)
|
||||||
{
|
{
|
||||||
return strlcpy(str, escape_data.group, strsize);
|
return strlcpy(str, escape_data.group, strsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
fill_runas_user(char *str, size_t strsize, char *unused)
|
fill_runas_user(char *str, size_t strsize, char *unused, void *closure)
|
||||||
{
|
{
|
||||||
return strlcpy(str, escape_data.runas_user, strsize);
|
return strlcpy(str, escape_data.runas_user, strsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
fill_runas_group(char *str, size_t strsize, char *unused)
|
fill_runas_group(char *str, size_t strsize, char *unused, void *closure)
|
||||||
{
|
{
|
||||||
return strlcpy(str, escape_data.runas_group, strsize);
|
return strlcpy(str, escape_data.runas_group, strsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
fill_hostname(char *str, size_t strsize, char *unused)
|
fill_hostname(char *str, size_t strsize, char *unused, void *closure)
|
||||||
{
|
{
|
||||||
return strlcpy(str, escape_data.host, strsize);
|
return strlcpy(str, escape_data.host, strsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
fill_command(char *str, size_t strsize, char *unused)
|
fill_command(char *str, size_t strsize, char *unused, void *closure)
|
||||||
{
|
{
|
||||||
return strlcpy(str, escape_data.command, strsize);
|
return strlcpy(str, escape_data.command, strsize);
|
||||||
}
|
}
|
||||||
@@ -150,7 +150,7 @@ do_check(char *dir_in, char *file_in, char *tdir_out, char *tfile_out)
|
|||||||
strftime(dir_out, sizeof(dir_out), tdir_out, timeptr);
|
strftime(dir_out, sizeof(dir_out), tdir_out, timeptr);
|
||||||
strftime(file_out, sizeof(file_out), tfile_out, timeptr);
|
strftime(file_out, sizeof(file_out), tfile_out, timeptr);
|
||||||
|
|
||||||
path = expand_iolog_path(NULL, dir_in, file_in, &slash, path_escapes);
|
path = expand_iolog_path(NULL, dir_in, file_in, &slash, path_escapes, NULL);
|
||||||
if (path == NULL)
|
if (path == NULL)
|
||||||
sudo_fatalx("unable to expand I/O log path");
|
sudo_fatalx("unable to expand I/O log path");
|
||||||
*slash = '\0';
|
*slash = '\0';
|
||||||
|
@@ -82,6 +82,7 @@ iolog_details_fill(struct iolog_details *details, ExecMessage *msg)
|
|||||||
/* Default values */
|
/* Default values */
|
||||||
details->lines = 24;
|
details->lines = 24;
|
||||||
details->columns = 80;
|
details->columns = 80;
|
||||||
|
details->submitgroup = "unknown";
|
||||||
|
|
||||||
/* Pull out values by key from info array. */
|
/* Pull out values by key from info array. */
|
||||||
for (idx = 0; idx < msg->n_info_msgs; idx++) {
|
for (idx = 0; idx < msg->n_info_msgs; idx++) {
|
||||||
@@ -174,6 +175,15 @@ iolog_details_fill(struct iolog_details *details, ExecMessage *msg)
|
|||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (strcmp(key, "submitgroup") == 0) {
|
||||||
|
if (has_strval(info)) {
|
||||||
|
details->submitgroup = info->strval;
|
||||||
|
} else {
|
||||||
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
|
"submitgroup specified but not a string");
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (strcmp(key, "submituser") == 0) {
|
if (strcmp(key, "submituser") == 0) {
|
||||||
if (has_strval(info)) {
|
if (has_strval(info)) {
|
||||||
details->submituser = info->strval;
|
details->submituser = info->strval;
|
||||||
@@ -218,62 +228,161 @@ iolog_details_fill(struct iolog_details *details, ExecMessage *msg)
|
|||||||
debug_return_bool(ret);
|
debug_return_bool(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static size_t
|
||||||
|
fill_seq(char *str, size_t strsize, char *logdir, void *closure)
|
||||||
|
{
|
||||||
|
struct iolog_details *details = closure;
|
||||||
|
char *sessid = details->sessid;
|
||||||
|
int len;
|
||||||
|
debug_decl(fill_seq, SUDO_DEBUG_UTIL)
|
||||||
|
|
||||||
|
if (sessid[0] == '\0') {
|
||||||
|
if (!iolog_nextid(logdir, sessid))
|
||||||
|
debug_return_size_t((size_t)-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Path is of the form /var/log/sudo-io/00/00/01. */
|
||||||
|
len = snprintf(str, strsize, "%c%c/%c%c/%c%c", sessid[0],
|
||||||
|
sessid[1], sessid[2], sessid[3], sessid[4], sessid[5]);
|
||||||
|
if (len < 0 || len >= (ssize_t)strsize) {
|
||||||
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
|
"unable to format session id");
|
||||||
|
debug_return_size_t(strsize); /* handle non-standard snprintf() */
|
||||||
|
}
|
||||||
|
debug_return_size_t(len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t
|
||||||
|
fill_user(char *str, size_t strsize, char *unused, void *closure)
|
||||||
|
{
|
||||||
|
const struct iolog_details *details = closure;
|
||||||
|
debug_decl(fill_user, SUDO_DEBUG_UTIL)
|
||||||
|
|
||||||
|
if (details->submituser == NULL) {
|
||||||
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
|
"submituser not set");
|
||||||
|
debug_return_size_t(strsize);
|
||||||
|
}
|
||||||
|
debug_return_size_t(strlcpy(str, details->submituser, strsize));
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t
|
||||||
|
fill_group(char *str, size_t strsize, char *unused, void *closure)
|
||||||
|
{
|
||||||
|
const struct iolog_details *details = closure;
|
||||||
|
debug_decl(fill_group, SUDO_DEBUG_UTIL)
|
||||||
|
|
||||||
|
if (details->submitgroup == NULL) {
|
||||||
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
|
"submitgroup not set");
|
||||||
|
debug_return_size_t(strsize);
|
||||||
|
}
|
||||||
|
debug_return_size_t(strlcpy(str, details->submitgroup, strsize));
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t
|
||||||
|
fill_runas_user(char *str, size_t strsize, char *unused, void *closure)
|
||||||
|
{
|
||||||
|
const struct iolog_details *details = closure;
|
||||||
|
debug_decl(fill_runas_user, SUDO_DEBUG_UTIL)
|
||||||
|
|
||||||
|
if (details->runuser == NULL) {
|
||||||
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
|
"runuser not set");
|
||||||
|
debug_return_size_t(strsize);
|
||||||
|
}
|
||||||
|
debug_return_size_t(strlcpy(str, details->runuser, strsize));
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t
|
||||||
|
fill_runas_group(char *str, size_t strsize, char *unused, void *closure)
|
||||||
|
{
|
||||||
|
const struct iolog_details *details = closure;
|
||||||
|
debug_decl(fill_runas_group, SUDO_DEBUG_UTIL)
|
||||||
|
|
||||||
|
/* FIXME: rungroup not guaranteed to be set */
|
||||||
|
if (details->rungroup == NULL) {
|
||||||
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
|
"rungroup not set");
|
||||||
|
debug_return_size_t(strsize);
|
||||||
|
}
|
||||||
|
debug_return_size_t(strlcpy(str, details->rungroup, strsize));
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t
|
||||||
|
fill_hostname(char *str, size_t strsize, char *unused, void *closure)
|
||||||
|
{
|
||||||
|
const struct iolog_details *details = closure;
|
||||||
|
debug_decl(fill_hostname, SUDO_DEBUG_UTIL)
|
||||||
|
|
||||||
|
if (details->submithost == NULL) {
|
||||||
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
|
"submithost not set");
|
||||||
|
debug_return_size_t(strsize);
|
||||||
|
}
|
||||||
|
debug_return_size_t(strlcpy(str, details->submithost, strsize));
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t
|
||||||
|
fill_command(char *str, size_t strsize, char *unused, void *closure)
|
||||||
|
{
|
||||||
|
const struct iolog_details *details = closure;
|
||||||
|
debug_decl(fill_command, SUDO_DEBUG_UTIL)
|
||||||
|
|
||||||
|
if (details->command == NULL) {
|
||||||
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
|
"command not set");
|
||||||
|
debug_return_size_t(strsize);
|
||||||
|
}
|
||||||
|
debug_return_size_t(strlcpy(str, details->command, strsize));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Note: "seq" must be first in the list. */
|
||||||
|
static const struct iolog_path_escape path_escapes[] = {
|
||||||
|
{ "seq", fill_seq },
|
||||||
|
{ "user", fill_user },
|
||||||
|
{ "group", fill_group },
|
||||||
|
{ "runas_user", fill_runas_user },
|
||||||
|
{ "runas_group", fill_runas_group },
|
||||||
|
{ "hostname", fill_hostname },
|
||||||
|
{ "command", fill_command },
|
||||||
|
{ NULL, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create I/O log path
|
* Create I/O log path
|
||||||
* Sets iolog_dir and iolog_dir_fd in the closure
|
* Sets iolog_dir and iolog_dir_fd in the closure (XXX - not iolog_dir_fd)
|
||||||
* XXX - use iolog_dir and iolog_file code from sudoers/iolog.c
|
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
create_iolog_dir(struct iolog_details *details, struct connection_closure *closure)
|
create_iolog_dir(struct iolog_details *details, struct connection_closure *closure)
|
||||||
{
|
{
|
||||||
char path[PATH_MAX];
|
char pathbuf[PATH_MAX];
|
||||||
int len;
|
size_t len;
|
||||||
debug_decl(create_iolog_dir, SUDO_DEBUG_UTIL)
|
debug_decl(create_iolog_dir, SUDO_DEBUG_UTIL)
|
||||||
|
|
||||||
/* Create IOLOG_DIR/host/user/XXXXXX directory */
|
/* XXX - awkward api */
|
||||||
if (mkdir(IOLOG_DIR, 0755) == -1 && errno != EEXIST) {
|
closure->iolog_dir = expand_iolog_path(NULL, logsrvd_conf_iolog_dir(),
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
|
logsrvd_conf_iolog_file(), NULL, &path_escapes[0], details);
|
||||||
"mkdir %s", path);
|
if (closure->iolog_dir == NULL) {
|
||||||
goto bad;
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
}
|
"unable to expand iolog path %s/%s",
|
||||||
len = snprintf(path, sizeof(path), "%s/%s", IOLOG_DIR,
|
logsrvd_conf_iolog_dir(), logsrvd_conf_iolog_file());
|
||||||
details->submithost);
|
|
||||||
if (len < 0 || len >= ssizeof(path)) {
|
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
|
|
||||||
"failed to snprintf I/O log path");
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
if (mkdir(path, 0755) == -1 && errno != EEXIST) {
|
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
|
|
||||||
"mkdir %s", path);
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
len = snprintf(path, sizeof(path), "%s/%s/%s", IOLOG_DIR,
|
|
||||||
details->submithost, details->submituser);
|
|
||||||
if (len < 0 || len >= ssizeof(path)) {
|
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
|
|
||||||
"failed to snprintf I/O log path");
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
if (mkdir(path, 0755) == -1 && errno != EEXIST) {
|
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
|
|
||||||
"mkdir %s", path);
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
len = snprintf(path, sizeof(path), "%s/%s/%s/XXXXXX", IOLOG_DIR,
|
|
||||||
details->submithost, details->submituser);
|
|
||||||
if (len < 0 || len >= ssizeof(path)) {
|
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
|
|
||||||
"failed to snprintf I/O log path");
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
if (mkdtemp(path) == NULL) {
|
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
|
|
||||||
"mkdtemp %s", path);
|
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((closure->iolog_dir = strdup(path)) == NULL) {
|
/*
|
||||||
|
* Make local copy of I/O log path and create it, along with any
|
||||||
|
* intermediate subdirs. Calls mkdtemp() if iolog_path ends in XXXXXX.
|
||||||
|
*/
|
||||||
|
len = mkdir_iopath(closure->iolog_dir, pathbuf, sizeof(pathbuf));
|
||||||
|
if (len >= sizeof(pathbuf)) {
|
||||||
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
|
||||||
|
"unable to mkdir iolog path %s", closure->iolog_dir);
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
free(closure->iolog_dir);
|
||||||
|
if ((closure->iolog_dir = strdup(pathbuf)) == NULL) {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
|
||||||
"strdup");
|
"strdup");
|
||||||
goto bad;
|
goto bad;
|
||||||
@@ -306,7 +415,14 @@ iolog_details_write(struct iolog_details *details, struct connection_closure *cl
|
|||||||
int error;
|
int error;
|
||||||
debug_decl(iolog_details_write, SUDO_DEBUG_UTIL)
|
debug_decl(iolog_details_write, SUDO_DEBUG_UTIL)
|
||||||
|
|
||||||
|
#if 0
|
||||||
fd = openat(closure->iolog_dir_fd, "log", O_CREAT|O_EXCL|O_WRONLY, 0600);
|
fd = openat(closure->iolog_dir_fd, "log", O_CREAT|O_EXCL|O_WRONLY, 0600);
|
||||||
|
#else
|
||||||
|
/* XXX */
|
||||||
|
char path[PATH_MAX]; // XXX
|
||||||
|
snprintf(path, sizeof(path), "%s/log", closure->iolog_dir);
|
||||||
|
fd = open(path, O_CREAT|O_EXCL|O_WRONLY, 0600);
|
||||||
|
#endif
|
||||||
if (fd == -1 || (fp = fdopen(fd, "w")) == NULL) {
|
if (fd == -1 || (fp = fdopen(fd, "w")) == NULL) {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
|
||||||
"unable to open %s", closure->iolog_dir);
|
"unable to open %s", closure->iolog_dir);
|
||||||
@@ -379,6 +495,10 @@ iolog_close_all(struct connection_closure *closure)
|
|||||||
"error closing iofd %d: %s", i, errstr);
|
"error closing iofd %d: %s", i, errstr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
|
if (closure->iolog_dir_fd != -1)
|
||||||
|
close(closure->iolog_dir_fd);
|
||||||
|
#endif
|
||||||
|
|
||||||
debug_return;
|
debug_return;
|
||||||
}
|
}
|
||||||
|
@@ -32,7 +32,7 @@
|
|||||||
#define SHUTDOWN_TIMEO 10
|
#define SHUTDOWN_TIMEO 10
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* I/O log details from the ExecMessage
|
* I/O log details from the ExecMessage + iolog path and sessid.
|
||||||
*/
|
*/
|
||||||
struct iolog_details {
|
struct iolog_details {
|
||||||
char *command;
|
char *command;
|
||||||
@@ -42,12 +42,14 @@ struct iolog_details {
|
|||||||
char *runuser;
|
char *runuser;
|
||||||
char *submithost;
|
char *submithost;
|
||||||
char *submituser;
|
char *submituser;
|
||||||
|
char *submitgroup;
|
||||||
char *ttyname;
|
char *ttyname;
|
||||||
char **argv;
|
char **argv;
|
||||||
time_t start_time;
|
time_t start_time;
|
||||||
int argc;
|
int argc;
|
||||||
int lines;
|
int lines;
|
||||||
int columns;
|
int columns;
|
||||||
|
char sessid[7];
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -85,7 +87,9 @@ struct connection_closure {
|
|||||||
struct sudo_event *write_ev;
|
struct sudo_event *write_ev;
|
||||||
char *iolog_dir;
|
char *iolog_dir;
|
||||||
struct iolog_file iolog_files[IOFD_MAX];
|
struct iolog_file iolog_files[IOFD_MAX];
|
||||||
|
#if 0
|
||||||
int iolog_dir_fd;
|
int iolog_dir_fd;
|
||||||
|
#endif
|
||||||
int sock;
|
int sock;
|
||||||
enum connection_status state;
|
enum connection_status state;
|
||||||
};
|
};
|
||||||
@@ -99,14 +103,8 @@ int store_winsize(ChangeWindowSize *msg, struct connection_closure *closure);
|
|||||||
void iolog_close_all(struct connection_closure *closure);
|
void iolog_close_all(struct connection_closure *closure);
|
||||||
|
|
||||||
/* logsrvd_conf.c */
|
/* logsrvd_conf.c */
|
||||||
bool logsrvd_conf_iolog_compress(void);
|
void logsrvd_conf_read(const char *path);
|
||||||
bool logsrvd_conf_iolog_flush(void);
|
|
||||||
const char *logsrvd_conf_iolog_dir(void);
|
const char *logsrvd_conf_iolog_dir(void);
|
||||||
const char *logsrvd_conf_iolog_file(void);
|
const char *logsrvd_conf_iolog_file(void);
|
||||||
const char *logsrvd_conf_iolog_group(void);
|
|
||||||
const char *logsrvd_conf_iolog_user(void);
|
|
||||||
mode_t logsrvd_conf_iolog_mode(void);
|
|
||||||
unsigned int logsrvd_conf_maxseq(void);
|
|
||||||
void logsrvd_conf_read(const char *path);
|
|
||||||
|
|
||||||
#endif /* SUDO_LOGSRVD_H */
|
#endif /* SUDO_LOGSRVD_H */
|
||||||
|
@@ -32,6 +32,8 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <grp.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
|
||||||
#include "log_server.pb-c.h"
|
#include "log_server.pb-c.h"
|
||||||
#include "sudo_gettext.h" /* must be included before sudo_compat.h */
|
#include "sudo_gettext.h" /* must be included before sudo_compat.h */
|
||||||
@@ -43,97 +45,133 @@
|
|||||||
#include "pathnames.h"
|
#include "pathnames.h"
|
||||||
#include "logsrvd.h"
|
#include "logsrvd.h"
|
||||||
|
|
||||||
enum config_type {
|
typedef bool (*logsrvd_conf_cb_t)(const char *);
|
||||||
CONF_BOOL,
|
|
||||||
CONF_INT,
|
|
||||||
CONF_UINT,
|
|
||||||
CONF_MODE,
|
|
||||||
CONF_STR
|
|
||||||
};
|
|
||||||
|
|
||||||
union config_value {
|
|
||||||
char *strval;
|
|
||||||
int intval;
|
|
||||||
unsigned int uintval;
|
|
||||||
mode_t modeval;
|
|
||||||
bool boolval;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct logsrvd_config_table {
|
struct logsrvd_config_table {
|
||||||
char *conf_str;
|
char *conf_str;
|
||||||
enum config_type conf_type;
|
logsrvd_conf_cb_t setter;
|
||||||
union config_value conf_val;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Indexes into conf_table */
|
static char *logsrvd_iolog_dir;
|
||||||
#define LOGSRVD_CONF_IOLOG_DIR 0
|
|
||||||
#define LOGSRVD_CONF_IOLOG_FILE 1
|
|
||||||
#define LOGSRVD_CONF_IOLOG_FLUSH 2
|
|
||||||
#define LOGSRVD_CONF_IOLOG_COMPRESS 3
|
|
||||||
#define LOGSRVD_CONF_IOLOG_USER 4
|
|
||||||
#define LOGSRVD_CONF_IOLOG_GROUP 5
|
|
||||||
#define LOGSRVD_CONF_IOLOG_MODE 6
|
|
||||||
#define LOGSRVD_CONF_MAXSEQ 7
|
|
||||||
|
|
||||||
/* XXX - use callbacks into iolog.c instead */
|
const char *
|
||||||
static struct logsrvd_config_table conf_table[] = {
|
logsrvd_conf_iolog_dir(void)
|
||||||
{ "iolog_dir", CONF_STR, { .strval = _PATH_SUDO_IO_LOGDIR } },
|
{
|
||||||
{ "iolog_file", CONF_STR, { .strval = "%{seq}" } },
|
return logsrvd_iolog_dir;
|
||||||
{ "iolog_flush", CONF_BOOL, { .boolval = true } },
|
}
|
||||||
{ "iolog_compress", CONF_BOOL, { .boolval = false } },
|
|
||||||
{ "iolog_user", CONF_STR, { .strval = NULL } },
|
static char *logsrvd_iolog_file;
|
||||||
{ "iolog_group", CONF_STR, { .strval = NULL } },
|
|
||||||
{ "iolog_mode", CONF_MODE, { .intval = S_IRUSR|S_IWUSR } },
|
const char *
|
||||||
{ "maxseq", CONF_UINT, { .intval = SESSID_MAX } },
|
logsrvd_conf_iolog_file(void)
|
||||||
{ NULL }
|
{
|
||||||
};
|
return logsrvd_iolog_file;
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
parse_value(struct logsrvd_config_table *ct, const char *val)
|
cb_iolog_dir(const char *path)
|
||||||
{
|
{
|
||||||
int ival;
|
debug_decl(cb_iolog_dir, SUDO_DEBUG_UTIL)
|
||||||
unsigned int uval;
|
|
||||||
mode_t mode;
|
|
||||||
const char *errstr;
|
|
||||||
debug_decl(parse_value, SUDO_DEBUG_UTIL)
|
|
||||||
|
|
||||||
switch (ct->conf_type) {
|
free(logsrvd_iolog_dir);
|
||||||
case CONF_BOOL:
|
if ((logsrvd_iolog_dir = strdup(path)) == NULL) {
|
||||||
ival = sudo_strtobool(val);
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
|
||||||
if (ival == -1)
|
"strdup");
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
ct->conf_val.boolval = ival;
|
}
|
||||||
break;
|
debug_return_bool(true);
|
||||||
case CONF_INT:
|
}
|
||||||
ival = sudo_strtonum(val, INT_MIN, INT_MAX, &errstr);
|
|
||||||
if (errstr != NULL)
|
static bool
|
||||||
debug_return_bool(false);
|
cb_iolog_file(const char *path)
|
||||||
ct->conf_val.intval = ival;
|
{
|
||||||
break;
|
debug_decl(cb_iolog_file, SUDO_DEBUG_UTIL)
|
||||||
case CONF_UINT:
|
|
||||||
uval = sudo_strtonum(val, 0, UINT_MAX, &errstr);
|
free(logsrvd_iolog_file);
|
||||||
if (errstr != NULL)
|
if ((logsrvd_iolog_file = strdup(path)) == NULL) {
|
||||||
debug_return_bool(false);
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
|
||||||
ct->conf_val.uintval = uval;
|
"strdup");
|
||||||
break;
|
debug_return_bool(false);
|
||||||
case CONF_MODE:
|
}
|
||||||
mode = sudo_strtomode(val, &errstr);
|
debug_return_bool(true);
|
||||||
if (errstr != NULL)
|
}
|
||||||
debug_return_bool(false);
|
|
||||||
ct->conf_val.modeval = mode;
|
static bool
|
||||||
break;
|
cb_iolog_compress(const char *str)
|
||||||
case CONF_STR:
|
{
|
||||||
ct->conf_val.strval = strdup(val);
|
return iolog_set_compress(str);
|
||||||
if (ct->conf_val.strval == NULL)
|
}
|
||||||
debug_return_bool(false);
|
|
||||||
break;
|
static bool
|
||||||
default:
|
cb_iolog_flush(const char *str)
|
||||||
|
{
|
||||||
|
return iolog_set_flush(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
cb_iolog_user(const char *user)
|
||||||
|
{
|
||||||
|
struct passwd *pw;
|
||||||
|
debug_decl(cb_iolog_user, SUDO_DEBUG_UTIL)
|
||||||
|
|
||||||
|
if ((pw = getpwnam(user)) == NULL) {
|
||||||
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
|
"unknown user %s", user);
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
debug_return_bool(true);
|
debug_return_bool(iolog_set_user(pw));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
cb_iolog_group(const char *group)
|
||||||
|
{
|
||||||
|
struct group *gr;
|
||||||
|
debug_decl(cb_iolog_group, SUDO_DEBUG_UTIL)
|
||||||
|
|
||||||
|
if ((gr = getgrnam(group)) == NULL) {
|
||||||
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
|
"unknown group %s", group);
|
||||||
|
debug_return_bool(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
debug_return_bool(iolog_set_group(gr));
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
cb_iolog_mode(const char *str)
|
||||||
|
{
|
||||||
|
const char *errstr;
|
||||||
|
mode_t mode;
|
||||||
|
debug_decl(cb_iolog_mode, SUDO_DEBUG_UTIL)
|
||||||
|
|
||||||
|
mode = sudo_strtomode(str, &errstr);
|
||||||
|
if (errstr != NULL) {
|
||||||
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
|
"unable to parse iolog mode %s", str);
|
||||||
|
debug_return_bool(false);
|
||||||
|
}
|
||||||
|
debug_return_bool(iolog_set_mode(mode));
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
cb_maxseq(const char *str)
|
||||||
|
{
|
||||||
|
return iolog_set_maxseq(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct logsrvd_config_table conf_table[] = {
|
||||||
|
{ "iolog_dir", cb_iolog_dir },
|
||||||
|
{ "iolog_file", cb_iolog_file },
|
||||||
|
{ "iolog_flush", cb_iolog_flush },
|
||||||
|
{ "iolog_compress", cb_iolog_compress },
|
||||||
|
{ "iolog_user", cb_iolog_user },
|
||||||
|
{ "iolog_group", cb_iolog_group },
|
||||||
|
{ "iolog_mode", cb_iolog_mode },
|
||||||
|
{ "maxseq", cb_maxseq },
|
||||||
|
{ NULL }
|
||||||
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
logsrvd_conf_read(const char *path)
|
logsrvd_conf_read(const char *path)
|
||||||
{
|
{
|
||||||
@@ -153,9 +191,14 @@ logsrvd_conf_read(const char *path)
|
|||||||
struct logsrvd_config_table *ct;
|
struct logsrvd_config_table *ct;
|
||||||
char *ep, *val;
|
char *ep, *val;
|
||||||
|
|
||||||
// XXX - warn about bogus lines
|
/* Skip blank, comment or invalid lines. */
|
||||||
if ((ep = strchr(line, '=')) == NULL)
|
if (*line == '\0')
|
||||||
continue;
|
continue;
|
||||||
|
if ((ep = strchr(line, '=')) == NULL) {
|
||||||
|
sudo_warnx("%s:%d invalid setting %s", path, lineno, line);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
val = ep + 1;
|
val = ep + 1;
|
||||||
while (isspace((unsigned char)*val))
|
while (isspace((unsigned char)*val))
|
||||||
val++;
|
val++;
|
||||||
@@ -164,72 +207,18 @@ logsrvd_conf_read(const char *path)
|
|||||||
*ep = '\0';
|
*ep = '\0';
|
||||||
for (ct = conf_table; ct->conf_str != NULL; ct++) {
|
for (ct = conf_table; ct->conf_str != NULL; ct++) {
|
||||||
if (strcmp(line, ct->conf_str) == 0) {
|
if (strcmp(line, ct->conf_str) == 0) {
|
||||||
if (!parse_value(ct, val))
|
if (!ct->setter(val))
|
||||||
sudo_warnx("invalid value for %s: %s", ct->conf_str, val);
|
sudo_warnx("invalid value for %s: %s", ct->conf_str, val);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
/* All the others have default values. */
|
||||||
/*
|
if (logsrvd_iolog_dir == NULL)
|
||||||
* TODO: iolog_dir, iolog_file, iolog_flush, iolog_compress
|
logsrvd_iolog_dir = strdup(_PATH_SUDO_IO_LOGDIR);
|
||||||
*/
|
if (logsrvd_iolog_file == NULL)
|
||||||
iolog_set_user(conf_table[LOGSRVD_CONF_IOLOG_USER].conf_val.strval);
|
logsrvd_iolog_file = strdup("%{seq}");
|
||||||
iolog_set_group(conf_table[LOGSRVD_CONF_IOLOG_GROUP].conf_val.strval);
|
|
||||||
iolog_set_mode(conf_table[LOGSRVD_CONF_IOLOG_MODE].conf_val.modeval);
|
|
||||||
/* XXX - expects a string */
|
|
||||||
iolog_set_max_sessid(conf_table[LOGSRVD_CONF_MAXSEQ].conf_val.uintval);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
debug_return;
|
debug_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX - use callbacks instead */
|
|
||||||
const char *
|
|
||||||
logsrvd_conf_iolog_dir(void)
|
|
||||||
{
|
|
||||||
return conf_table[LOGSRVD_CONF_IOLOG_DIR].conf_val.strval;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *
|
|
||||||
logsrvd_conf_iolog_file(void)
|
|
||||||
{
|
|
||||||
return conf_table[LOGSRVD_CONF_IOLOG_FILE].conf_val.strval;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *
|
|
||||||
logsrvd_conf_iolog_user(void)
|
|
||||||
{
|
|
||||||
return conf_table[LOGSRVD_CONF_IOLOG_USER].conf_val.strval;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *
|
|
||||||
logsrvd_conf_iolog_group(void)
|
|
||||||
{
|
|
||||||
return conf_table[LOGSRVD_CONF_IOLOG_GROUP].conf_val.strval;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
logsrvd_conf_iolog_flush(void)
|
|
||||||
{
|
|
||||||
return conf_table[LOGSRVD_CONF_IOLOG_FLUSH].conf_val.boolval;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
logsrvd_conf_iolog_compress(void)
|
|
||||||
{
|
|
||||||
return conf_table[LOGSRVD_CONF_IOLOG_COMPRESS].conf_val.boolval;
|
|
||||||
}
|
|
||||||
|
|
||||||
mode_t
|
|
||||||
logsrvd_conf_iolog_mode(void)
|
|
||||||
{
|
|
||||||
return conf_table[LOGSRVD_CONF_IOLOG_MODE].conf_val.modeval;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int
|
|
||||||
logsrvd_conf_maxseq(void)
|
|
||||||
{
|
|
||||||
return conf_table[LOGSRVD_CONF_MAXSEQ].conf_val.uintval;
|
|
||||||
}
|
|
||||||
|
@@ -42,7 +42,7 @@
|
|||||||
#include "sudo_iolog.h"
|
#include "sudo_iolog.h"
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
fill_seq(char *str, size_t strsize, char *logdir)
|
fill_seq(char *str, size_t strsize, char *logdir, void *closure)
|
||||||
{
|
{
|
||||||
#ifdef SUDOERS_NO_SEQ
|
#ifdef SUDOERS_NO_SEQ
|
||||||
debug_decl(fill_seq, SUDO_DEBUG_UTIL)
|
debug_decl(fill_seq, SUDO_DEBUG_UTIL)
|
||||||
@@ -67,14 +67,14 @@ fill_seq(char *str, size_t strsize, char *logdir)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
fill_user(char *str, size_t strsize, char *unused)
|
fill_user(char *str, size_t strsize, char *unused, void *closure)
|
||||||
{
|
{
|
||||||
debug_decl(fill_user, SUDO_DEBUG_UTIL)
|
debug_decl(fill_user, SUDO_DEBUG_UTIL)
|
||||||
debug_return_size_t(strlcpy(str, user_name, strsize));
|
debug_return_size_t(strlcpy(str, user_name, strsize));
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
fill_group(char *str, size_t strsize, char *unused)
|
fill_group(char *str, size_t strsize, char *unused, void *closure)
|
||||||
{
|
{
|
||||||
struct group *grp;
|
struct group *grp;
|
||||||
size_t len;
|
size_t len;
|
||||||
@@ -92,14 +92,14 @@ fill_group(char *str, size_t strsize, char *unused)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
fill_runas_user(char *str, size_t strsize, char *unused)
|
fill_runas_user(char *str, size_t strsize, char *unused, void *closure)
|
||||||
{
|
{
|
||||||
debug_decl(fill_runas_user, SUDO_DEBUG_UTIL)
|
debug_decl(fill_runas_user, SUDO_DEBUG_UTIL)
|
||||||
debug_return_size_t(strlcpy(str, runas_pw->pw_name, strsize));
|
debug_return_size_t(strlcpy(str, runas_pw->pw_name, strsize));
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
fill_runas_group(char *str, size_t strsize, char *unused)
|
fill_runas_group(char *str, size_t strsize, char *unused, void *closure)
|
||||||
{
|
{
|
||||||
struct group *grp;
|
struct group *grp;
|
||||||
size_t len;
|
size_t len;
|
||||||
@@ -121,14 +121,14 @@ fill_runas_group(char *str, size_t strsize, char *unused)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
fill_hostname(char *str, size_t strsize, char *unused)
|
fill_hostname(char *str, size_t strsize, char *unused, void *closure)
|
||||||
{
|
{
|
||||||
debug_decl(fill_hostname, SUDO_DEBUG_UTIL)
|
debug_decl(fill_hostname, SUDO_DEBUG_UTIL)
|
||||||
debug_return_size_t(strlcpy(str, user_shost, strsize));
|
debug_return_size_t(strlcpy(str, user_shost, strsize));
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
fill_command(char *str, size_t strsize, char *unused)
|
fill_command(char *str, size_t strsize, char *unused, void *closure)
|
||||||
{
|
{
|
||||||
debug_decl(fill_command, SUDO_DEBUG_UTIL)
|
debug_decl(fill_command, SUDO_DEBUG_UTIL)
|
||||||
debug_return_size_t(strlcpy(str, user_base, strsize));
|
debug_return_size_t(strlcpy(str, user_base, strsize));
|
||||||
|
@@ -477,7 +477,7 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
|
|||||||
sudoers_setlocale(SUDOERS_LOCALE_SUDOERS, &oldlocale);
|
sudoers_setlocale(SUDOERS_LOCALE_SUDOERS, &oldlocale);
|
||||||
iolog_path = expand_iolog_path(prefix, def_iolog_dir,
|
iolog_path = expand_iolog_path(prefix, def_iolog_dir,
|
||||||
def_iolog_file, &sudo_user.iolog_file,
|
def_iolog_file, &sudo_user.iolog_file,
|
||||||
sudoers_iolog_path_escapes);
|
sudoers_iolog_path_escapes, NULL);
|
||||||
sudoers_setlocale(oldlocale, NULL);
|
sudoers_setlocale(oldlocale, NULL);
|
||||||
if (iolog_path == NULL) {
|
if (iolog_path == NULL) {
|
||||||
if (!def_ignore_iolog_errors)
|
if (!def_ignore_iolog_errors)
|
||||||
|
Reference in New Issue
Block a user