Make the log_children option only log and not check policy.
This commit is contained in:
188
src/exec.c
188
src/exec.c
@@ -480,7 +480,15 @@ terminate_command(pid_t pid, bool use_pgrp)
|
|||||||
debug_return;
|
debug_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Must match start of exec_closure_nopty and monitor_closure. */
|
||||||
|
struct intercept_fd_closure {
|
||||||
|
struct command_details *details;
|
||||||
|
struct sudo_event_base *evbase;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Closure for intercept_cb() */
|
||||||
struct intercept_closure {
|
struct intercept_closure {
|
||||||
|
struct command_details *details;
|
||||||
struct sudo_event ev;
|
struct sudo_event ev;
|
||||||
const char *errstr;
|
const char *errstr;
|
||||||
char *command; /* dynamically allocated */
|
char *command; /* dynamically allocated */
|
||||||
@@ -548,14 +556,14 @@ intercept_check_policy(PolicyCheckRequest *req,
|
|||||||
{
|
{
|
||||||
char **command_info = NULL;
|
char **command_info = NULL;
|
||||||
char **user_env_out = NULL;
|
char **user_env_out = NULL;
|
||||||
char **argv, **run_argv = NULL;
|
char **argv = NULL, **run_argv = NULL;
|
||||||
|
int ret = 1;
|
||||||
size_t n;
|
size_t n;
|
||||||
int ok;
|
|
||||||
debug_decl(intercept_check_policy, SUDO_DEBUG_EXEC);
|
debug_decl(intercept_check_policy, SUDO_DEBUG_EXEC);
|
||||||
|
|
||||||
if (req->command == NULL || req->n_argv == 0 || req->n_envp == 0) {
|
if (req->command == NULL || req->n_argv == 0 || req->n_envp == 0) {
|
||||||
*errstr = N_("invalid PolicyCheckRequest");
|
*errstr = N_("invalid PolicyCheckRequest");
|
||||||
goto error;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sudo_debug_needed(SUDO_DEBUG_INFO)) {
|
if (sudo_debug_needed(SUDO_DEBUG_INFO)) {
|
||||||
@@ -571,104 +579,127 @@ intercept_check_policy(PolicyCheckRequest *req,
|
|||||||
argv = reallocarray(NULL, req->n_argv + 1, sizeof(char *));
|
argv = reallocarray(NULL, req->n_argv + 1, sizeof(char *));
|
||||||
if (argv == NULL) {
|
if (argv == NULL) {
|
||||||
*errstr = N_("unable to allocate memory");
|
*errstr = N_("unable to allocate memory");
|
||||||
goto error;
|
goto bad;
|
||||||
}
|
}
|
||||||
for (n = 0; n < req->n_argv; n++) {
|
argv[0] = req->command;
|
||||||
|
for (n = 1; n < req->n_argv; n++) {
|
||||||
argv[n] = req->argv[n];
|
argv[n] = req->argv[n];
|
||||||
}
|
}
|
||||||
argv[n] = NULL;
|
argv[n] = NULL;
|
||||||
|
|
||||||
/* We don't currently have a good way to validate the environment. */
|
if (ISSET(closure->details->flags, CD_INTERCEPT)) {
|
||||||
/* TODO: make sure LD_PRELOAD is preserved in environment */
|
/* We don't currently have a good way to validate the environment. */
|
||||||
sudo_debug_set_active_instance(policy_plugin.debug_instance);
|
sudo_debug_set_active_instance(policy_plugin.debug_instance);
|
||||||
ok = policy_plugin.u.policy->check_policy(n, argv, NULL,
|
ret = policy_plugin.u.policy->check_policy(n, argv, NULL,
|
||||||
&command_info, &run_argv, &user_env_out, errstr);
|
&command_info, &run_argv, &user_env_out, errstr);
|
||||||
sudo_debug_set_active_instance(sudo_debug_instance);
|
sudo_debug_set_active_instance(sudo_debug_instance);
|
||||||
free(argv);
|
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
|
||||||
|
"check_policy returns %d", ret);
|
||||||
|
|
||||||
switch (ok) {
|
switch (ret) {
|
||||||
case 1:
|
case 1:
|
||||||
/* Extract command path from command_info[] */
|
/* Extract command path from command_info[] */
|
||||||
if (command_info != NULL) {
|
if (command_info != NULL) {
|
||||||
for (n = 0; command_info[n] != NULL; n++) {
|
for (n = 0; command_info[n] != NULL; n++) {
|
||||||
const char *cp = command_info[n];
|
const char *cp = command_info[n];
|
||||||
if (strncmp(cp, "command=", sizeof("command=") - 1) == 0) {
|
if (strncmp(cp, "command=", sizeof("command=") - 1) == 0) {
|
||||||
closure->command = strdup(cp + sizeof("command=") - 1);
|
closure->command = strdup(cp + sizeof("command=") - 1);
|
||||||
if (closure->command == NULL) {
|
if (closure->command == NULL) {
|
||||||
*errstr = N_("unable to allocate memory");
|
*errstr = N_("unable to allocate memory");
|
||||||
goto error;
|
goto bad;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
if (*errstr == NULL)
|
||||||
|
*errstr = N_("command rejected by policy");
|
||||||
|
audit_reject(policy_plugin.name, SUDO_POLICY_PLUGIN, *errstr,
|
||||||
|
command_info);
|
||||||
|
goto done;
|
||||||
|
default:
|
||||||
|
goto bad;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
if (sudo_debug_needed(SUDO_DEBUG_INFO)) {
|
/* No actual policy check, just logging child processes. */
|
||||||
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
|
||||||
"run_command: %s", closure->command);
|
"not checking policy, audit only");
|
||||||
for (n = 0; run_argv[n] != NULL; n++) {
|
closure->command = strdup(req->command);
|
||||||
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
|
if (closure->command == NULL) {
|
||||||
"run_argv[%zu]: %s", n, run_argv[n]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* run_argv strings may be part of PolicyCheckReq, make a copy. */
|
|
||||||
for (n = 0; run_argv[n] != NULL; n++)
|
|
||||||
continue;
|
|
||||||
closure->run_argv = reallocarray(NULL, n + 1, sizeof(char *));
|
|
||||||
if (closure->run_argv == NULL) {
|
|
||||||
*errstr = N_("unable to allocate memory");
|
*errstr = N_("unable to allocate memory");
|
||||||
goto error;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
command_info = (char **)closure->details->info;
|
||||||
|
run_argv = argv;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sudo_debug_needed(SUDO_DEBUG_INFO)) {
|
||||||
|
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
|
||||||
|
"run_command: %s", closure->command);
|
||||||
for (n = 0; run_argv[n] != NULL; n++) {
|
for (n = 0; run_argv[n] != NULL; n++) {
|
||||||
closure->run_argv[n] = strdup(run_argv[n]);
|
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
|
||||||
if (closure->run_argv[n] == NULL) {
|
"run_argv[%zu]: %s", n, run_argv[n]);
|
||||||
*errstr = N_("unable to allocate memory");
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
closure->run_argv[n] = NULL;
|
}
|
||||||
|
|
||||||
/* envp strings are part of PolicyCheckReq, make a copy. */
|
/* run_argv strings may be part of PolicyCheckReq, make a copy. */
|
||||||
closure->run_envp = reallocarray(NULL, req->n_envp + 1, sizeof(char *));
|
for (n = 0; run_argv[n] != NULL; n++)
|
||||||
if (closure->run_envp == NULL) {
|
continue;
|
||||||
|
closure->run_argv = reallocarray(NULL, n + 1, sizeof(char *));
|
||||||
|
if (closure->run_argv == NULL) {
|
||||||
|
*errstr = N_("unable to allocate memory");
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
for (n = 0; run_argv[n] != NULL; n++) {
|
||||||
|
closure->run_argv[n] = strdup(run_argv[n]);
|
||||||
|
if (closure->run_argv[n] == NULL) {
|
||||||
*errstr = N_("unable to allocate memory");
|
*errstr = N_("unable to allocate memory");
|
||||||
goto error;
|
goto bad;
|
||||||
}
|
}
|
||||||
for (n = 0; n < req->n_envp; n++) {
|
}
|
||||||
closure->run_envp[n] = strdup(req->envp[n]);
|
closure->run_argv[n] = NULL;
|
||||||
if (closure->run_envp[n] == NULL) {
|
|
||||||
*errstr = N_("unable to allocate memory");
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
closure->run_envp[n] = NULL;
|
|
||||||
|
|
||||||
|
/* envp strings are part of PolicyCheckReq, make a copy. */
|
||||||
|
closure->run_envp = reallocarray(NULL, req->n_envp + 1, sizeof(char *));
|
||||||
|
if (closure->run_envp == NULL) {
|
||||||
|
*errstr = N_("unable to allocate memory");
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
for (n = 0; n < req->n_envp; n++) {
|
||||||
|
closure->run_envp[n] = strdup(req->envp[n]);
|
||||||
|
if (closure->run_envp[n] == NULL) {
|
||||||
|
*errstr = N_("unable to allocate memory");
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closure->run_envp[n] = NULL;
|
||||||
|
|
||||||
|
if (ISSET(closure->details->flags, CD_INTERCEPT)) {
|
||||||
audit_accept(policy_plugin.name, SUDO_POLICY_PLUGIN, command_info,
|
audit_accept(policy_plugin.name, SUDO_POLICY_PLUGIN, command_info,
|
||||||
closure->run_argv, closure->run_envp);
|
closure->run_argv, closure->run_envp);
|
||||||
|
|
||||||
/* Call approval plugins and audit the result. */
|
/* Call approval plugins and audit the result. */
|
||||||
if (!approval_check(command_info, closure->run_argv, closure->run_envp))
|
if (!approval_check(command_info, closure->run_argv, closure->run_envp))
|
||||||
debug_return_int(0);
|
debug_return_int(0);
|
||||||
|
|
||||||
/* Audit the event again for the sudo front-end. */
|
|
||||||
audit_accept("sudo", SUDO_FRONT_END, command_info, closure->run_argv,
|
|
||||||
closure->run_envp);
|
|
||||||
debug_return_int(1);
|
|
||||||
case 0:
|
|
||||||
if (*errstr == NULL)
|
|
||||||
*errstr = N_("command rejected by policy");
|
|
||||||
audit_reject(policy_plugin.name, SUDO_POLICY_PLUGIN, *errstr,
|
|
||||||
command_info);
|
|
||||||
debug_return_int(0);
|
|
||||||
default:
|
|
||||||
error:
|
|
||||||
if (*errstr == NULL)
|
|
||||||
*errstr = N_("policy plugin error");
|
|
||||||
audit_error(policy_plugin.name, SUDO_POLICY_PLUGIN, *errstr,
|
|
||||||
command_info);
|
|
||||||
debug_return_int(-1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Audit the event again for the sudo front-end. */
|
||||||
|
audit_accept("sudo", SUDO_FRONT_END, command_info, closure->run_argv,
|
||||||
|
closure->run_envp);
|
||||||
|
|
||||||
|
done:
|
||||||
|
free(argv);
|
||||||
|
debug_return_int(ret);
|
||||||
|
|
||||||
|
bad:
|
||||||
|
free(argv);
|
||||||
|
if (*errstr == NULL)
|
||||||
|
*errstr = N_("policy plugin error");
|
||||||
|
audit_error(policy_plugin.name, SUDO_POLICY_PLUGIN, *errstr,
|
||||||
|
command_info);
|
||||||
|
debug_return_int(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -945,7 +976,7 @@ void
|
|||||||
intercept_fd_cb(int fd, int what, void *v)
|
intercept_fd_cb(int fd, int what, void *v)
|
||||||
{
|
{
|
||||||
struct intercept_closure *closure = NULL;
|
struct intercept_closure *closure = NULL;
|
||||||
struct sudo_event_base *base = v;
|
struct intercept_fd_closure *fdc = v;
|
||||||
struct msghdr msg;
|
struct msghdr msg;
|
||||||
union {
|
union {
|
||||||
struct cmsghdr hdr;
|
struct cmsghdr hdr;
|
||||||
@@ -962,6 +993,7 @@ intercept_fd_cb(int fd, int what, void *v)
|
|||||||
sudo_warnx("%s", U_("unable to allocate memory"));
|
sudo_warnx("%s", U_("unable to allocate memory"));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
closure->details = fdc->details;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We send a single byte of data along with the fd; some systems
|
* We send a single byte of data along with the fd; some systems
|
||||||
@@ -1006,7 +1038,7 @@ intercept_fd_cb(int fd, int what, void *v)
|
|||||||
sudo_warn("%s", U_("unable to add event to queue"));
|
sudo_warn("%s", U_("unable to add event to queue"));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
if (sudo_ev_add(base, &closure->ev, NULL, false) == -1) {
|
if (sudo_ev_add(fdc->evbase, &closure->ev, NULL, false) == -1) {
|
||||||
sudo_warn("%s", U_("unable to add event to queue"));
|
sudo_warn("%s", U_("unable to add event to queue"));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
@@ -38,10 +38,8 @@
|
|||||||
#include "sudo_plugin.h"
|
#include "sudo_plugin.h"
|
||||||
#include "sudo_plugin_int.h"
|
#include "sudo_plugin_int.h"
|
||||||
|
|
||||||
|
/* Note that details and evbase must come first. */
|
||||||
struct exec_closure_nopty {
|
struct exec_closure_nopty {
|
||||||
pid_t cmnd_pid;
|
|
||||||
pid_t ppgrp;
|
|
||||||
struct command_status *cstat;
|
|
||||||
struct command_details *details;
|
struct command_details *details;
|
||||||
struct sudo_event_base *evbase;
|
struct sudo_event_base *evbase;
|
||||||
struct sudo_event *errpipe_event;
|
struct sudo_event *errpipe_event;
|
||||||
@@ -58,6 +56,9 @@ struct exec_closure_nopty {
|
|||||||
struct sudo_event *sigchld_event;
|
struct sudo_event *sigchld_event;
|
||||||
struct sudo_event *sigcont_event;
|
struct sudo_event *sigcont_event;
|
||||||
struct sudo_event *siginfo_event;
|
struct sudo_event *siginfo_event;
|
||||||
|
struct command_status *cstat;
|
||||||
|
pid_t cmnd_pid;
|
||||||
|
pid_t ppgrp;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void handle_sigchld_nopty(struct exec_closure_nopty *ec);
|
static void handle_sigchld_nopty(struct exec_closure_nopty *ec);
|
||||||
@@ -220,7 +221,7 @@ fill_exec_closure_nopty(struct exec_closure_nopty *ec,
|
|||||||
/* Event for sudo_intercept.so (optional). */
|
/* Event for sudo_intercept.so (optional). */
|
||||||
if (intercept_fd != -1) {
|
if (intercept_fd != -1) {
|
||||||
ec->intercept_event = sudo_ev_alloc(intercept_fd,
|
ec->intercept_event = sudo_ev_alloc(intercept_fd,
|
||||||
SUDO_EV_READ|SUDO_EV_PERSIST, intercept_fd_cb, ec->evbase);
|
SUDO_EV_READ|SUDO_EV_PERSIST, intercept_fd_cb, ec);
|
||||||
if (ec->intercept_event == NULL)
|
if (ec->intercept_event == NULL)
|
||||||
sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
||||||
if (sudo_ev_add(ec->evbase, ec->intercept_event, NULL, false) == -1)
|
if (sudo_ev_add(ec->evbase, ec->intercept_event, NULL, false) == -1)
|
||||||
|
@@ -55,13 +55,8 @@ struct monitor_message {
|
|||||||
};
|
};
|
||||||
TAILQ_HEAD(monitor_message_list, monitor_message);
|
TAILQ_HEAD(monitor_message_list, monitor_message);
|
||||||
|
|
||||||
|
/* Note that details and evbase must come first. */
|
||||||
struct exec_closure_pty {
|
struct exec_closure_pty {
|
||||||
pid_t monitor_pid;
|
|
||||||
pid_t cmnd_pid;
|
|
||||||
pid_t ppgrp;
|
|
||||||
short rows;
|
|
||||||
short cols;
|
|
||||||
struct command_status *cstat;
|
|
||||||
struct command_details *details;
|
struct command_details *details;
|
||||||
struct sudo_event_base *evbase;
|
struct sudo_event_base *evbase;
|
||||||
struct sudo_event *backchannel_event;
|
struct sudo_event *backchannel_event;
|
||||||
@@ -77,7 +72,13 @@ struct exec_closure_pty {
|
|||||||
struct sudo_event *sigusr2_event;
|
struct sudo_event *sigusr2_event;
|
||||||
struct sudo_event *sigchld_event;
|
struct sudo_event *sigchld_event;
|
||||||
struct sudo_event *sigwinch_event;
|
struct sudo_event *sigwinch_event;
|
||||||
|
struct command_status *cstat;
|
||||||
struct monitor_message_list monitor_messages;
|
struct monitor_message_list monitor_messages;
|
||||||
|
pid_t monitor_pid;
|
||||||
|
pid_t cmnd_pid;
|
||||||
|
pid_t ppgrp;
|
||||||
|
short rows;
|
||||||
|
short cols;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Reference in New Issue
Block a user