set_plugin(const char *entry)
{
struct plugin_info *info;
- const char *name, *path;
- size_t namelen;
+ const char *name, *path, *cp, *ep;
+ char **args = NULL;
+ size_t namelen, pathlen;
+ unsigned int nargs;
/* Parse Plugin line */
name = entry;
namelen = (size_t)(path - name);
while (isblank((unsigned char)*path))
path++;
+ if ((cp = strpbrk(path, " \t")) != NULL) {
+ /* Convert extra args to an array. */
+ pathlen = (size_t)(cp - path);
+ while (isblank((unsigned char)*cp))
+ cp++;
+ /* Count number of args and allocate array. */
+ for (ep = cp, nargs = 1; (ep = strpbrk(ep, " \t")) != NULL; nargs++) {
+ while (isblank((unsigned char)*ep))
+ ep++;
+ }
+ args = emalloc2(nargs + 1, sizeof(*args));
+ /* Fill in args array, there is at least one element. */
+ for (nargs = 0; (ep = strpbrk(cp, " \t")) != NULL; ) {
+ args[nargs++] = estrndup(cp, (size_t)(ep - cp));
+ while (isblank((unsigned char)*ep))
+ ep++;
+ cp = ep;
+ }
+ args[nargs++] = estrdup(cp);
+ args[nargs] = NULL;
+ } else {
+ /* No extra args. */
+ pathlen = strlen(path);
+ }
info = emalloc(sizeof(*info));
info->symbol_name = estrndup(name, namelen);
- info->path = estrdup(path);
+ info->path = estrndup(path, pathlen);
+ info->args = args;
info->prev = info;
info->next = NULL;
tq_append(&sudo_conf_data.plugins, info);
# Sample /etc/sudo.conf file
#
# Format:
-# Plugin plugin_name plugin_path
+# Plugin plugin_name plugin_path plugin_args ...
# Path askpass /path/to/askpass
# Path noexec /path/to/noexec.so
# Debug sudo /var/log/sudo_debug all@warn
# The plugin_path is relative to ${prefix}/libexec unless fully qualified.
# The plugin_name corresponds to a global symbol in the plugin
# that contains the plugin interface structure.
+# The plugin_args are optional.
#
# The sudoers plugin is used by default if no Plugin lines are present.
Plugin sudoers_policy sudoers.so
# Default @sysconfdir@/sudo.conf file
#
# Format:
- # Plugin plugin_name plugin_path
+ # Plugin plugin_name plugin_path plugin_args ...
# Path askpass /path/to/askpass
# Path noexec /path/to/noexec.so
# Debug sudo /var/log/sudo_debug all@warn
# fully qualified.
# The plugin_name corresponds to a global symbol in the plugin
# that contains the plugin interface structure.
+ # The plugin_args are optional.
#
Plugin policy_plugin sudoers.so
Plugin io_plugin sudoers.so
or C<struct io_plugin> in the plugin shared object. The I<path>
may be fully qualified or relative. If not fully qualified it is
relative to the F<@prefix@/libexec> directory. Any additional
-parameters after the I<path> are ignored. Lines that don't begin
-with C<Plugin> or C<Path> are silently ignored
+parameters after the I<path> are passed as arguments to the plugin's
+I<open> function. Lines that don't begin with C<Plugin>, C<Path>,
+C<Debug> or C<Set> are silently ignored.
For more information, see the L<sudo_plugin(8)> manual.
or C<struct io_plugin> in the plugin shared object. The I<path>
may be fully qualified or relative. If not fully qualified it is
relative to the F<@prefix@/libexec> directory. Any additional
-parameters after the I<path> are ignored. Lines that don't begin
-with C<Plugin> or C<Path> are silently ignored.
+parameters after the I<path> are passed as arguments to the plugin's
+I<open> function. Lines that don't begin with C<Plugin>, C<Path>,
+C<Debug> or C<Set> are silently ignored.
The same shared object may contain multiple plugins, each with a
different symbol name. The shared object file must be owned by uid
# Default @sysconfdir@/sudo.conf file
#
# Format:
- # Plugin plugin_name plugin_path
+ # Plugin plugin_name plugin_path optional_args
# Path askpass /path/to/askpass
+ # Path noexec /path/to/noexec.so
+ # Debug sudo /var/log/sudo_debug all@warn
+ # Set disable_coredump true
#
# The plugin_path is relative to @prefix@/libexec unless
# fully qualified.
# The plugin_name corresponds to a global symbol in the plugin
# that contains the plugin interface structure.
+ # The plugin_args are optional.
#
Plugin sudoers_policy sudoers.so
Plugin sudoers_io sudoers.so
unsigned int type; /* always SUDO_POLICY_PLUGIN */
unsigned int version; /* always SUDO_API_VERSION */
int (*open)(unsigned int version, sudo_conv_t conversation,
- sudo_printf_t plugin_printf, char * const settings[],
- char * const user_info[], char * const user_env[]);
+ sudo_printf_t plugin_printf, char * const settings[],
+ char * const user_info[], char * const user_env[],
+ char * const plugin_args[]);
void (*close)(int exit_status, int error);
int (*show_version)(int verbose);
int (*check_policy)(int argc, char * const argv[],
int (*open)(unsigned int version, sudo_conv_t conversation,
sudo_printf_t plugin_printf, char * const settings[],
- char * const user_info[], char * const user_env[]);
+ char * const user_info[], char * const user_env[],
+ char * const plugin_args[]);
Returns 1 on success, 0 on failure, -1 if a general error occurred,
or -2 if there was a usage error. In the latter case, B<sudo> will
equal sign ('=') since the I<name> field will never include one
itself but the I<value> might.
+=item plugin_args
+
+Any (non-comment) strings immediately after the plugin path are
+treated as arguments to the plugin. These arguments are split on
+a whitespace boundary and are passed to the plugin in the form of
+a C<NULL>-terminated array of strings. If no arguments were
+specified, I<plugin_args> will be the NULL pointer.
+
+NOTE: the I<plugin_args> parameter is only available starting with
+API version 1.2. A plugin B<must> check the API version specified
+by the B<sudo> front end before using I<plugin_args>. Failure to
+do so may result in a crash.
+
=back
=item close
int (*open)(unsigned int version, sudo_conv_t conversation
sudo_printf_t plugin_printf, char * const settings[],
char * const user_info[], int argc, char * const argv[],
- char * const user_env[]);
+ char * const user_env[], char * const plugin_args[]);
void (*close)(int exit_status, int error); /* wait status or error */
int (*show_version)(int verbose);
int (*log_ttyin)(const char *buf, unsigned int len);
int (*open)(unsigned int version, sudo_conv_t conversation
sudo_printf_t plugin_printf, char * const settings[],
char * const user_info[], int argc, char * const argv[],
- char * const user_env[]);
+ char * const user_env[], char * const plugin_args[]);
The I<open> function is run before the I<log_input>, I<log_output>
or I<show_version> functions are called. It is only called if the
equal sign ('=') since the I<name> field will never include one
itself but the I<value> might.
+=item plugin_args
+
+Any (non-comment) strings immediately after the plugin path are
+treated as arguments to the plugin. These arguments are split on
+a whitespace boundary and are passed to the plugin in the form of
+a C<NULL>-terminated array of strings. If no arguments were
+specified, I<plugin_args> will be the NULL pointer.
+
+NOTE: the I<plugin_args> parameter is only available starting with
+API version 1.2. A plugin B<must> check the API version specified
+by the B<sudo> front end before using I<plugin_args>. Failure to
+do so may result in a crash.
+
=back
=item close
aaron shanty = NOEXEC: /usr/bin/more, /usr/bin/vi
-See the L<PREVENTING SHELL ESCAPES> section below for more details
+See the L<Preventing Shell Escapes> section below for more details
on how C<NOEXEC> works and whether or not it will work on your system.
=head3 SETENV and NOSETENV
If set, all commands run via B<sudo> will behave as if the C<NOEXEC>
tag has been set, unless overridden by a C<EXEC> tag. See the
-description of I<NOEXEC and EXEC> below as well as the L<PREVENTING SHELL
-ESCAPES> section at the end of this manual. This flag is I<off> by default.
+description of I<NOEXEC and EXEC> below as well as the L<Preventing Shell
+Escapes> section at the end of this manual. This flag is I<off> by default.
=item path_info
=back
+=head1 SUDO.CONF
+
+The F<@sysconfdir@/sudo.conf> file determines which plugins the
+B<sudo> front end will load. If no F<@sysconfdir@/sudo.conf> file
+is present, or it contains no C<Plugin> lines, B<sudo> will use the
+I<sudoers> security policy and I/O logging, which corresponds to
+the following F<@sysconfdir@/sudo.conf> file.
+
+ #
+ # Default @sysconfdir@/sudo.conf file
+ #
+ # Format:
+ # Plugin plugin_name plugin_path plugin_args ...
+ # Path askpass /path/to/askpass
+ # Path noexec /path/to/noexec.so
+ # Debug sudo /var/log/sudo_debug all@warn
+ # Set disable_coredump true
+ #
+ # The plugin_path is relative to @prefix@/libexec unless
+ # fully qualified.
+ # The plugin_name corresponds to a global symbol in the plugin
+ # that contains the plugin interface structure.
+ # The plugin_args are optional.
+ #
+ Plugin policy_plugin sudoers.so
+ Plugin io_plugin sudoers.so
+
+=head2 PLUGIN OPTIONS
+
+Starting with B<sudo> 1.8.5 it is possible to pass options to the
+I<sudoers> plugin. Options may be listed after the path to the
+plugin (i.e. after F<sudoers.so>); multiple options should be
+space-separated. For example:
+
+ Plugin sudoers_policy sudoers.so sudoers_file=/etc/sudoers sudoers_uid=0 sudoers_gid=0 sudoers_mode=0440
+
+The following plugin options are supported:
+
+=over 10
+
+=item sudoers_file=pathname
+
+The I<sudoers_file> option can be used to override the default path
+to the I<sudoers> file.
+
+=item sudoers_uid=uid
+
+The I<sudoers_uid> option can be used to override the default owner
+of the sudoers file. It should be specified as a numeric user ID.
+
+=item sudoers_gid=gid
+
+The I<sudoers_gid> option can be used to override the default group
+of the sudoers file. It should be specified as a numeric group ID.
+
+=item sudoers_mode=mode
+
+The I<sudoers_mode> option can be used to override the default file
+mode for the sudoers file. It should be specified as an octal value.
+
+=back
+
+=head2 DEBUG FLAGS
+
+Versions 1.8.4 and higher of the I<sudoers> plugin supports a
+debugging framework that can help track down what the plugin is
+doing internally if there is a problem. This can be configured in
+the F<@sysconfdir@/sudo.conf> file as described in L<sudo(8)>.
+
+The I<sudoers> plugin uses the same debug flag format as B<sudo>
+itself: I<subsystem>@I<priority>.
+
+The priorities used by I<sudoers>, in order of decreasing severity,
+are: I<crit>, I<err>, I<warn>, I<notice>, I<diag>, I<info>, I<trace>
+and I<debug>. Each priority, when specified, also includes all
+priorities higher than it. For example, a priority of I<notice>
+would include debug messages logged at I<notice> and higher.
+
+The following subsystems are used by I<sudoers>:
+
+=over 10
+
+=item I<alias>
+
+C<User_Alias>, C<Runas_Alias>, C<Host_Alias> and C<Cmnd_Alias> processing
+
+=item I<all>
+
+matches every subsystem
+
+=item I<audit>
+
+BSM and Linux audit code
+
+=item I<auth>
+
+user authentication
+
+=item I<defaults>
+
+I<sudoers> I<Defaults> settings
+
+=item I<env>
+
+environment handling
+
+=item I<ldap>
+
+LDAP-based sudoers
+
+=item I<logging>
+
+logging support
+
+=item I<match>
+
+matching of users, groups, hosts and netgroups in I<sudoers>
+
+=item I<netif>
+
+network interface handling
+
+=item I<nss>
+
+network service switch handling in I<sudoers>
+
+=item I<parser>
+
+I<sudoers> file parsing
+
+=item I<perms>
+
+permission setting
+
+=item I<plugin>
+
+The equivalent of I<main> for the plugin.
+
+=item I<pty>
+
+pseudo-tty related code
+
+=item I<rbtree>
+
+redblack tree internals
+
+=item I<util>
+
+utility functions
+
+=back
+
=head1 FILES
=over 24
+=item F<@sysconfdir@/sudo.conf>
+
+Sudo front end configuration
+
=item F<@sysconfdir@/sudoers>
List of who can run what
=head1 SECURITY NOTES
+=head2 Limitations of the '!' operator
+
It is generally not effective to "subtract" commands from C<ALL>
using the '!' operator. A user can trivially circumvent this
by copying the desired command to a different name and then
program. Therefore, these kind of restrictions should be considered
advisory at best (and reinforced by policy).
-Furthermore, if the I<fast_glob> option is in use, it is not possible
+In general, if a user has sudo C<ALL> there is nothing to prevent
+them from creating their own program that gives them a root shell
+(or making their own copy of a shell) regardless of any '!' elements
+in the user specification.
+
+=head2 Security implications of I<fast_glob>
+
+If the I<fast_glob> option is in use, it is not possible
to reliably negate commands where the path name includes globbing
(aka wildcard) characters. This is because the C library's
L<fnmatch(3)> function cannot resolve relative paths. While this
User B<john> can still run C</usr/bin/passwd root> if I<fast_glob> is
enabled by changing to F</usr/bin> and running C<./passwd root> instead.
-=head1 PREVENTING SHELL ESCAPES
+=head2 Preventing Shell Escapes
Once B<sudo> executes a program, that program is free to do whatever
it pleases, including run other programs. This can be a security
editor, a safer approach is to give the user permission to run
B<sudoedit>.
-=head1 DEBUG FLAGS
-
-Versions 1.8.4 and higher of the I<sudoers> plugin supports a
-debugging framework that can help track down what the plugin is
-doing internally if there is a problem. This can be configured in
-the F<@sysconfdir@/sudo.conf> file as described in L<sudo(8)>.
-
-The I<sudoers> plugin uses the same debug flag format as B<sudo>
-itself: I<subsystem>@I<priority>.
-
-The priorities used by I<sudoers>, in order of decreasing severity,
-are: I<crit>, I<err>, I<warn>, I<notice>, I<diag>, I<info>, I<trace>
-and I<debug>. Each priority, when specified, also includes all
-priorities higher than it. For example, a priority of I<notice>
-would include debug messages logged at I<notice> and higher.
-
-The following subsystems are used by I<sudoers>:
-
-=over 10
-
-=item I<alias>
-
-C<User_Alias>, C<Runas_Alias>, C<Host_Alias> and C<Cmnd_Alias> processing
-
-=item I<all>
-
-matches every subsystem
-
-=item I<audit>
-
-BSM and Linux audit code
-
-=item I<auth>
-
-user authentication
-
-=item I<defaults>
-
-I<sudoers> I<Defaults> settings
-
-=item I<env>
-
-environment handling
-
-=item I<ldap>
-
-LDAP-based sudoers
-
-=item I<logging>
-
-logging support
-
-=item I<match>
-
-matching of users, groups, hosts and netgroups in I<sudoers>
-
-=item I<netif>
-
-network interface handling
-
-=item I<nss>
-
-network service switch handling in I<sudoers>
-
-=item I<parser>
-
-I<sudoers> file parsing
-
-=item I<perms>
-
-permission setting
-
-=item I<plugin>
-
-The equivalent of I<main> for the plugin.
-
-=item I<pty>
-
-pseudo-tty related code
-
-=item I<rbtree>
-
-redblack tree internals
-
-=item I<util>
-
-utility functions
-
-=back
-
-=head1 SECURITY NOTES
+=head2 Time stamp file checks
I<sudoers> will check the ownership of its time stamp directory
(F<@timedir@> by default) and ignore the directory's contents if
tty-based time stamp file is stale and will ignore it. Administrators
should not rely on this feature as it is not universally available.
-If users have sudo C<ALL> there is nothing to prevent them from
-creating their own program that gives them a root shell (or making
-their own copy of a shell) regardless of any '!' elements in the
-user specification.
-
=head1 SEE ALSO
L<rsh(1)>, L<su(1)>, L<fnmatch(3)>, L<glob(3)>, L<mktemp(3)>, L<strftime(3)>,
struct plugin_info *next; /* required */
const char *path;
const char *symbol_name;
+ char * const * args;
};
TQ_DECLARE(plugin_info)
/* API version major/minor */
#define SUDO_API_VERSION_MAJOR 1
-#define SUDO_API_VERSION_MINOR 1
+#define SUDO_API_VERSION_MINOR 2
#define SUDO_API_MKVERSION(x, y) ((x << 16) | y)
#define SUDO_API_VERSION SUDO_API_MKVERSION(SUDO_API_VERSION_MAJOR, SUDO_API_VERSION_MINOR)
unsigned int version; /* always SUDO_API_VERSION */
int (*open)(unsigned int version, sudo_conv_t conversation,
sudo_printf_t sudo_printf, char * const settings[],
- char * const user_info[], char * const user_env[]);
+ char * const user_info[], char * const user_env[],
+ char * const plugin_args[]);
void (*close)(int exit_status, int error); /* wait status or error */
int (*show_version)(int verbose);
int (*check_policy)(int argc, char * const argv[],
int (*open)(unsigned int version, sudo_conv_t conversation,
sudo_printf_t sudo_printf, char * const settings[],
char * const user_info[], char * const command_info[],
- int argc, char * const argv[], char * const user_env[]);
+ int argc, char * const argv[], char * const user_env[],
+ char * const plugin_args[]);
void (*close)(int exit_status, int error); /* wait status or error */
int (*show_version)(int verbose);
int (*log_ttyin)(const char *buf, unsigned int len);
static int
policy_open(unsigned int version, sudo_conv_t conversation,
sudo_printf_t sudo_printf, char * const settings[],
- char * const user_info[], char * const user_env[])
+ char * const user_info[], char * const user_env[], char * const args[])
{
char * const *ui;
struct passwd *pw;
io_open(unsigned int version, sudo_conv_t conversation,
sudo_printf_t sudo_printf, char * const settings[],
char * const user_info[], char * const command_info[],
- int argc, char * const argv[], char * const user_env[])
+ int argc, char * const argv[], char * const user_env[], char * const args[])
{
int fd;
char path[PATH_MAX];
sudoers_io_open(unsigned int version, sudo_conv_t conversation,
sudo_printf_t plugin_printf, char * const settings[],
char * const user_info[], char * const command_info[],
- int argc, char * const argv[], char * const user_env[])
+ int argc, char * const argv[], char * const user_env[], char * const args[])
{
struct iolog_details details;
char pathbuf[PATH_MAX], sessid[7];
static void set_runasgr(const char *);
static int cb_runas_default(const char *);
static int sudoers_policy_version(int verbose);
-static int deserialize_info(char * const settings[], char * const user_info[]);
+static int deserialize_info(char * const args[], char * const settings[],
+ char * const user_info[]);
static char *find_editor(int nfiles, char **files, char ***argv_out);
static void create_admin_success_flag(void);
static int
sudoers_policy_open(unsigned int version, sudo_conv_t conversation,
sudo_printf_t plugin_printf, char * const settings[],
- char * const user_info[], char * const envp[])
+ char * const user_info[], char * const envp[], char * const args[])
{
volatile int sources = 0;
sigaction_t sa;
struct sudo_nss *nss;
debug_decl(sudoers_policy_open, SUDO_DEBUG_PLUGIN)
+ /* Plugin args are only specified for API version 1.2 and higher. */
+ if (version < SUDO_API_MKVERSION(1, 2))
+ args = NULL;
+
if (!sudo_conv)
sudo_conv = conversation;
if (!sudo_printf)
/* Setup defaults data structures. */
init_defaults();
- /* Parse settings and user_info */
- sudo_mode = deserialize_info(settings, user_info);
+ /* Parse args, settings and user_info */
+ sudo_mode = deserialize_info(args, settings, user_info);
init_vars(envp); /* XXX - move this later? */
}
static int
-deserialize_info(char * const settings[], char * const user_info[])
+deserialize_info(char * const args[], char * const settings[], char * const user_info[])
{
char * const *cur;
const char *p, *groups = NULL;
#define MATCHES(s, v) (strncmp(s, v, sizeof(v) - 1) == 0)
+ /* Parse sudo.conf plugin args. */
+ if (args != NULL) {
+ for (cur = args; *cur != NULL; cur++) {
+ if (MATCHES(*cur, "sudoers_file=")) {
+ sudoers_file = *cur + sizeof("sudoers_file=") - 1;
+ continue;
+ }
+ if (MATCHES(*cur, "sudoers_uid=")) {
+ sudoers_uid = (uid_t) atoi(*cur + sizeof("sudoers_uid=") - 1);
+ continue;
+ }
+ if (MATCHES(*cur, "sudoers_gid=")) {
+ sudoers_gid = (gid_t) atoi(*cur + sizeof("sudoers_gid=") - 1);
+ continue;
+ }
+ if (MATCHES(*cur, "sudoers_mode=")) {
+ sudoers_mode = (mode_t) strtol(*cur + sizeof("sudoers_mode=") - 1,
+ NULL, 8);
+ continue;
+ }
+ }
+ }
+
/* Parse command line settings. */
user_closefrom = -1;
for (cur = settings; *cur != NULL; cur++) {
set_interfaces(interfaces_string);
continue;
}
- if (MATCHES(*cur, "sudoers_file=")) {
- sudoers_file = *cur + sizeof("sudoers_file=") - 1;
- continue;
- }
- if (MATCHES(*cur, "sudoers_uid=")) {
- sudoers_uid = (uid_t) atoi(*cur + sizeof("sudoers_uid=") - 1);
- continue;
- }
- if (MATCHES(*cur, "sudoers_gid=")) {
- sudoers_gid = (gid_t) atoi(*cur + sizeof("sudoers_gid=") - 1);
- continue;
- }
- if (MATCHES(*cur, "sudoers_mode=")) {
- sudoers_mode = (mode_t) strtol(*cur + sizeof("sudoers_mode=") - 1,
- NULL, 8);
- continue;
- }
}
for (cur = user_info; *cur != NULL; cur++) {
int last_token;
char *sudoers;
-/* Default sudoers path, mode and owner */
+/* Default sudoers path, mode and owner (may be set via sudo.conf) */
const char *sudoers_file = _PATH_SUDOERS;
mode_t sudoers_mode = SUDOERS_MODE;
uid_t sudoers_uid = SUDOERS_UID;
}
policy_plugin->handle = handle;
policy_plugin->name = info->symbol_name;
+ policy_plugin->args = info->args;
policy_plugin->u.generic = plugin;
} else if (plugin->type == SUDO_IO_PLUGIN) {
container = emalloc(sizeof(*container));
container->next = NULL;
container->handle = handle;
container->name = info->symbol_name;
+ container->args = info->args;
container->u.generic = plugin;
tq_append(io_plugins, container);
}
policy_open(struct plugin_container *plugin, char * const settings[],
char * const user_info[], char * const user_env[])
{
+ int rval;
debug_decl(policy_open, SUDO_DEBUG_PCOMM)
- debug_return_bool(plugin->u.policy->open(SUDO_API_VERSION,
- sudo_conversation, _sudo_printf, settings, user_info, user_env));
+
+ /*
+ * Backwards compatibility for older API versions
+ */
+ switch (plugin->u.generic->version) {
+ case SUDO_API_MKVERSION(1, 0):
+ case SUDO_API_MKVERSION(1, 1):
+ rval = plugin->u.policy_1_0->open(plugin->u.io_1_0->version,
+ sudo_conversation, _sudo_printf, settings, user_info, user_env);
+ break;
+ default:
+ rval = plugin->u.policy->open(SUDO_API_VERSION, sudo_conversation,
+ _sudo_printf, settings, user_info, user_env, plugin->args);
+ }
+
+ debug_return_bool(rval);
}
static void
debug_decl(iolog_open, SUDO_DEBUG_PCOMM)
/*
- * Backwards compatibility for API major 1, minor 0
+ * Backwards compatibility for older API versions
*/
switch (plugin->u.generic->version) {
case SUDO_API_MKVERSION(1, 0):
sudo_conversation, _sudo_printf, settings, user_info, argc, argv,
user_env);
break;
+ case SUDO_API_MKVERSION(1, 1):
+ rval = plugin->u.io_1_1->open(plugin->u.io_1_1->version,
+ sudo_conversation, _sudo_printf, settings, user_info,
+ command_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);
+ _sudo_printf, settings, user_info, command_info,
+ argc, argv, user_env, plugin->args);
}
debug_return_bool(rval);
}
/*
* Backwards-compatible structures for API bumps.
*/
+struct policy_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[], char * const user_env[]);
+ void (*close)(int exit_status, int error); /* wait status or error */
+ int (*show_version)(int verbose);
+ int (*check_policy)(int argc, char * const argv[],
+ char *env_add[], char **command_info[],
+ char **argv_out[], char **user_env_out[]);
+ int (*list)(int argc, char * const argv[], int verbose,
+ const char *list_user);
+ int (*validate)(void);
+ void (*invalidate)(int remove);
+ int (*init_session)(struct passwd *pwd);
+};
struct io_plugin_1_0 {
unsigned int type;
unsigned int version;
int (*log_stdout)(const char *buf, unsigned int len);
int (*log_stderr)(const char *buf, unsigned int len);
};
+struct io_plugin_1_1 {
+ 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[], char * const command_info[],
+ int argc, char * const argv[], char * const user_env[]);
+ void (*close)(int exit_status, int error); /* wait status or 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.
struct plugin_container *prev; /* required */
struct plugin_container *next; /* required */
const char *name;
+ char * const *args;
void *handle;
union {
struct generic_plugin *generic;
struct policy_plugin *policy;
+ struct policy_plugin_1_0 *policy_1_0;
struct io_plugin *io;
struct io_plugin_1_0 *io_1_0;
+ struct io_plugin_1_1 *io_1_1;
} u;
};
TQ_DECLARE(plugin_container)