Change I/O log API to pass in command info to the I/O log open function.
Add iolog_file and iolog_dir parameters to command info. This allows the policy plugin to specify the I/O log pathname. Add convenience functions for calling plugin functions that handle ABI backwards compatibility.
This commit is contained in:
@@ -19,8 +19,9 @@
|
|||||||
|
|
||||||
/* API version major/minor */
|
/* API version major/minor */
|
||||||
#define SUDO_API_VERSION_MAJOR 1
|
#define SUDO_API_VERSION_MAJOR 1
|
||||||
#define SUDO_API_VERSION_MINOR 0
|
#define SUDO_API_VERSION_MINOR 1
|
||||||
#define SUDO_API_VERSION ((SUDO_API_VERSION_MAJOR << 16) | SUDO_API_VERSION_MINOR)
|
#define SUDO_API_MKVERSION(x, y) ((x << 16) | y)
|
||||||
|
#define SUDO_API_VERSION SUDO_API_MKVERSION(SUDO_API_VERSION_MAJOR, SUDO_API_VERSION_MINOR)
|
||||||
|
|
||||||
/* Getters and setters for API version */
|
/* Getters and setters for API version */
|
||||||
#define SUDO_API_VERSION_GET_MAJOR(v) ((v) >> 16)
|
#define SUDO_API_VERSION_GET_MAJOR(v) ((v) >> 16)
|
||||||
@@ -81,8 +82,8 @@ struct io_plugin {
|
|||||||
unsigned int version; /* always SUDO_API_VERSION */
|
unsigned int version; /* always SUDO_API_VERSION */
|
||||||
int (*open)(unsigned int version, sudo_conv_t conversation,
|
int (*open)(unsigned int version, sudo_conv_t conversation,
|
||||||
sudo_printf_t sudo_printf, char * const settings[],
|
sudo_printf_t sudo_printf, char * const settings[],
|
||||||
char * const user_info[], int argc, char * const argv[],
|
char * const user_info[], char * const command_info[],
|
||||||
char * const user_env[]);
|
int argc, char * const argv[], char * const user_env[]);
|
||||||
void (*close)(int exit_status, int error); /* wait status or error */
|
void (*close)(int exit_status, int error); /* wait status or error */
|
||||||
int (*show_version)(int verbose);
|
int (*show_version)(int verbose);
|
||||||
int (*log_ttyin)(const char *buf, unsigned int len);
|
int (*log_ttyin)(const char *buf, unsigned int len);
|
||||||
|
76
src/sudo.c
76
src/sudo.c
@@ -108,6 +108,15 @@ static void disable_coredumps(void);
|
|||||||
static char **get_user_info(struct user_details *);
|
static char **get_user_info(struct user_details *);
|
||||||
static void command_info_to_details(char * const info[],
|
static void command_info_to_details(char * const info[],
|
||||||
struct command_details *details);
|
struct command_details *details);
|
||||||
|
static int policy_open(struct plugin_container *plugin, char * const settings[],
|
||||||
|
char * const user_info[], char * const user_env[]);
|
||||||
|
static void policy_close(struct plugin_container *plugin, int exit_status,
|
||||||
|
int error);
|
||||||
|
static int iolog_open(struct plugin_container *plugin, char * const settings[],
|
||||||
|
char * const user_info[], char * const command_details[],
|
||||||
|
int argc, char * const argv[], char * const user_env[]);
|
||||||
|
static void iolog_close(struct plugin_container *plugin, int exit_status,
|
||||||
|
int error);
|
||||||
|
|
||||||
#if defined(RLIMIT_CORE) && !defined(SUDO_DEVEL)
|
#if defined(RLIMIT_CORE) && !defined(SUDO_DEVEL)
|
||||||
static struct rlimit corelimit;
|
static struct rlimit corelimit;
|
||||||
@@ -168,8 +177,7 @@ main(int argc, char *argv[], char *envp[])
|
|||||||
sudo_mode = parse_args(argc, argv, &nargc, &nargv, &settings, &env_add);
|
sudo_mode = parse_args(argc, argv, &nargc, &nargv, &settings, &env_add);
|
||||||
|
|
||||||
/* Open policy plugin. */
|
/* Open policy plugin. */
|
||||||
ok = policy_plugin.u.policy->open(SUDO_API_VERSION, sudo_conversation,
|
ok = policy_open(&policy_plugin, settings, user_info, envp);
|
||||||
_sudo_printf, settings, user_info, envp);
|
|
||||||
if (ok != TRUE) {
|
if (ok != TRUE) {
|
||||||
if (ok == -2)
|
if (ok == -2)
|
||||||
usage(1);
|
usage(1);
|
||||||
@@ -185,8 +193,8 @@ main(int argc, char *argv[], char *envp[])
|
|||||||
(void) printf("Configure args: %s\n", CONFIGURE_ARGS);
|
(void) printf("Configure args: %s\n", CONFIGURE_ARGS);
|
||||||
policy_plugin.u.policy->show_version(!user_details.uid);
|
policy_plugin.u.policy->show_version(!user_details.uid);
|
||||||
tq_foreach_fwd(&io_plugins, plugin) {
|
tq_foreach_fwd(&io_plugins, plugin) {
|
||||||
ok = plugin->u.io->open(SUDO_API_VERSION, sudo_conversation,
|
ok = iolog_open(plugin, settings, user_info, NULL,
|
||||||
_sudo_printf, settings, user_info, nargc, nargv, envp);
|
nargc, nargv, envp);
|
||||||
if (ok == TRUE)
|
if (ok == TRUE)
|
||||||
plugin->u.io->show_version(user_details.uid == ROOT_UID);
|
plugin->u.io->show_version(user_details.uid == ROOT_UID);
|
||||||
}
|
}
|
||||||
@@ -237,8 +245,8 @@ main(int argc, char *argv[], char *envp[])
|
|||||||
/* Open I/O plugins once policy plugin succeeds. */
|
/* Open I/O plugins once policy plugin succeeds. */
|
||||||
for (plugin = io_plugins.first; plugin != NULL; plugin = next) {
|
for (plugin = io_plugins.first; plugin != NULL; plugin = next) {
|
||||||
next = plugin->next;
|
next = plugin->next;
|
||||||
ok = plugin->u.io->open(SUDO_API_VERSION, sudo_conversation,
|
ok = iolog_open(plugin, settings, user_info,
|
||||||
_sudo_printf, settings, user_info, nargc, nargv, envp);
|
command_info, nargc, nargv, envp);
|
||||||
switch (ok) {
|
switch (ok) {
|
||||||
case TRUE:
|
case TRUE:
|
||||||
break;
|
break;
|
||||||
@@ -451,6 +459,10 @@ command_info_to_details(char * const info[], struct command_details *details)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'i':
|
||||||
|
SET_STRING("iolog_dir=", iolog_dir)
|
||||||
|
SET_STRING("iolog_file=", iolog_file)
|
||||||
|
break;
|
||||||
case 'l':
|
case 'l':
|
||||||
SET_STRING("login_class=", login_class)
|
SET_STRING("login_class=", login_class)
|
||||||
break;
|
break;
|
||||||
@@ -905,20 +917,20 @@ run_command(struct command_details *details, char *argv[], char *envp[])
|
|||||||
case CMD_ERRNO:
|
case CMD_ERRNO:
|
||||||
/* exec_setup() or execve() returned an error. */
|
/* exec_setup() or execve() returned an error. */
|
||||||
sudo_debug(9, "calling policy close with errno");
|
sudo_debug(9, "calling policy close with errno");
|
||||||
policy_plugin.u.policy->close(0, cstat.val);
|
policy_close(&policy_plugin, 0, cstat.val);
|
||||||
tq_foreach_fwd(&io_plugins, plugin) {
|
tq_foreach_fwd(&io_plugins, plugin) {
|
||||||
sudo_debug(9, "calling I/O close with errno");
|
sudo_debug(9, "calling I/O close with errno");
|
||||||
plugin->u.io->close(0, cstat.val);
|
iolog_close(plugin, 0, cstat.val);
|
||||||
}
|
}
|
||||||
exitcode = 1;
|
exitcode = 1;
|
||||||
break;
|
break;
|
||||||
case CMD_WSTATUS:
|
case CMD_WSTATUS:
|
||||||
/* Command ran, exited or was killed. */
|
/* Command ran, exited or was killed. */
|
||||||
sudo_debug(9, "calling policy close with wait status");
|
sudo_debug(9, "calling policy close with wait status");
|
||||||
policy_plugin.u.policy->close(cstat.val, 0);
|
policy_close(&policy_plugin, cstat.val, 0);
|
||||||
tq_foreach_fwd(&io_plugins, plugin) {
|
tq_foreach_fwd(&io_plugins, plugin) {
|
||||||
sudo_debug(9, "calling I/O close with wait status");
|
sudo_debug(9, "calling I/O close with wait status");
|
||||||
plugin->u.io->close(cstat.val, 0);
|
iolog_close(plugin, cstat.val, 0);
|
||||||
}
|
}
|
||||||
if (WIFEXITED(cstat.val))
|
if (WIFEXITED(cstat.val))
|
||||||
exitcode = WEXITSTATUS(cstat.val);
|
exitcode = WEXITSTATUS(cstat.val);
|
||||||
@@ -932,6 +944,50 @@ run_command(struct command_details *details, char *argv[], char *envp[])
|
|||||||
return exitcode;
|
return exitcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
policy_open(struct plugin_container *plugin, char * const settings[],
|
||||||
|
char * const user_info[], char * const user_env[])
|
||||||
|
{
|
||||||
|
return plugin->u.policy->open(SUDO_API_VERSION, sudo_conversation,
|
||||||
|
_sudo_printf, settings, user_info, user_env);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
policy_close(struct plugin_container *plugin, int exit_status, int error)
|
||||||
|
{
|
||||||
|
plugin->u.policy->close(exit_status, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
iolog_open(struct plugin_container *plugin, char * const settings[],
|
||||||
|
char * const user_info[], char * const command_info[],
|
||||||
|
int argc, char * const argv[], char * const user_env[])
|
||||||
|
{
|
||||||
|
int rval;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Backwards compatibility for API major 1, minor 0
|
||||||
|
*/
|
||||||
|
switch (plugin->u.generic->version) {
|
||||||
|
case SUDO_API_MKVERSION(1, 0):
|
||||||
|
rval = plugin->u.io_1_0->open(plugin->u.io_1_0->version,
|
||||||
|
sudo_conversation, _sudo_printf, settings, user_info, argc, argv,
|
||||||
|
user_env);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
rval = plugin->u.io->open(SUDO_API_VERSION, sudo_conversation,
|
||||||
|
_sudo_printf, settings, user_info, command_info, argc, argv,
|
||||||
|
user_env);
|
||||||
|
}
|
||||||
|
return rval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
iolog_close(struct plugin_container *plugin, int exit_status, int error)
|
||||||
|
{
|
||||||
|
plugin->u.io->close(exit_status, error);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Simple debugging/logging.
|
* Simple debugging/logging.
|
||||||
*/
|
*/
|
||||||
|
@@ -138,6 +138,8 @@ struct command_details {
|
|||||||
const char *chroot;
|
const char *chroot;
|
||||||
const char *selinux_role;
|
const char *selinux_role;
|
||||||
const char *selinux_type;
|
const char *selinux_type;
|
||||||
|
const char *iolog_dir;
|
||||||
|
const char *iolog_file;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Status passed between parent and child via socketpair */
|
/* Status passed between parent and child via socketpair */
|
||||||
|
@@ -17,6 +17,25 @@
|
|||||||
#ifndef _SUDO_PLUGIN_INT_H
|
#ifndef _SUDO_PLUGIN_INT_H
|
||||||
#define _SUDO_PLUGIN_INT_H
|
#define _SUDO_PLUGIN_INT_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Backwards-compatible structures for API bumps.
|
||||||
|
*/
|
||||||
|
struct io_plugin_1_0 {
|
||||||
|
unsigned int type;
|
||||||
|
unsigned int version;
|
||||||
|
int (*open)(unsigned int version, sudo_conv_t conversation,
|
||||||
|
sudo_printf_t sudo_printf, char * const settings[],
|
||||||
|
char * const user_info[], int argc, char * const argv[],
|
||||||
|
char * const user_env[]);
|
||||||
|
void (*close)(int exit_status, int error);
|
||||||
|
int (*show_version)(int verbose);
|
||||||
|
int (*log_ttyin)(const char *buf, unsigned int len);
|
||||||
|
int (*log_ttyout)(const char *buf, unsigned int len);
|
||||||
|
int (*log_stdin)(const char *buf, unsigned int len);
|
||||||
|
int (*log_stdout)(const char *buf, unsigned int len);
|
||||||
|
int (*log_stderr)(const char *buf, unsigned int len);
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sudo plugin internals.
|
* Sudo plugin internals.
|
||||||
*/
|
*/
|
||||||
@@ -38,6 +57,7 @@ struct plugin_container {
|
|||||||
struct generic_plugin *generic;
|
struct generic_plugin *generic;
|
||||||
struct policy_plugin *policy;
|
struct policy_plugin *policy;
|
||||||
struct io_plugin *io;
|
struct io_plugin *io;
|
||||||
|
struct io_plugin_1_0 *io_1_0;
|
||||||
} u;
|
} u;
|
||||||
};
|
};
|
||||||
TQ_DECLARE(plugin_container)
|
TQ_DECLARE(plugin_container)
|
||||||
|
Reference in New Issue
Block a user