Add support for plugin args at the end of a Plugin line in sudo.conf.
Bump the minor number accordingly and update the documentation. A plugin must check the sudo front end's version before using the plugin_args parameter since it is only supported for API version 1.2 and higher.
This commit is contained in:
@@ -204,8 +204,10 @@ static bool
|
||||
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;
|
||||
@@ -215,10 +217,35 @@ set_plugin(const char *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);
|
||||
|
@@ -2,7 +2,7 @@
|
||||
# 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
|
||||
@@ -13,6 +13,7 @@
|
||||
# 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
|
||||
|
@@ -421,7 +421,7 @@ which corresponds to the following F<@sysconfdir@/sudo.conf> file.
|
||||
# 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
|
||||
@@ -431,6 +431,7 @@ which corresponds to the following F<@sysconfdir@/sudo.conf> file.
|
||||
# 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
|
||||
@@ -441,8 +442,9 @@ plugin. The I<symbol_name> is the name of the C<struct policy_plugin>
|
||||
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.
|
||||
|
||||
|
@@ -48,8 +48,9 @@ plugin. The I<symbol_name> is the name of the C<struct policy_plugin>
|
||||
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
|
||||
@@ -61,13 +62,17 @@ This limitation does not apply to I/O plugins.
|
||||
# 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
|
||||
@@ -86,7 +91,8 @@ so that B<sudo> can load it.
|
||||
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[]);
|
||||
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[],
|
||||
@@ -118,7 +124,8 @@ built against.
|
||||
|
||||
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
|
||||
@@ -369,6 +376,19 @@ When parsing I<user_env>, the plugin should split on the B<first>
|
||||
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
|
||||
@@ -762,7 +782,7 @@ error information to the user.
|
||||
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);
|
||||
@@ -811,7 +831,7 @@ built against.
|
||||
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
|
||||
@@ -895,6 +915,19 @@ When parsing I<user_env>, the plugin should split on the B<first>
|
||||
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
|
||||
|
272
doc/sudoers.pod
272
doc/sudoers.pod
@@ -540,7 +540,7 @@ and F</usr/bin/vi> but shell escapes will be disabled.
|
||||
|
||||
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
|
||||
@@ -940,8 +940,8 @@ by default.
|
||||
|
||||
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
|
||||
|
||||
@@ -1594,10 +1594,166 @@ is displayed when B<sudo> is run by root with the I<-V> option.
|
||||
|
||||
=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
|
||||
@@ -1810,6 +1966,8 @@ for encapsulating in a shell script.
|
||||
|
||||
=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
|
||||
@@ -1823,7 +1981,14 @@ different name, or use a shell escape from an editor or other
|
||||
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
|
||||
@@ -1839,7 +2004,7 @@ For example, given the following I<sudoers> entry:
|
||||
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
|
||||
@@ -1903,97 +2068,7 @@ to unintended privilege escalation. In the specific case of an
|
||||
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
|
||||
@@ -2034,11 +2109,6 @@ created (such as Mac OS X), I<sudoers> is able to determine when a
|
||||
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)>,
|
||||
|
@@ -24,6 +24,7 @@ struct plugin_info {
|
||||
struct plugin_info *next; /* required */
|
||||
const char *path;
|
||||
const char *symbol_name;
|
||||
char * const * args;
|
||||
};
|
||||
TQ_DECLARE(plugin_info)
|
||||
|
||||
|
@@ -19,7 +19,7 @@
|
||||
|
||||
/* 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)
|
||||
|
||||
@@ -63,7 +63,8 @@ struct policy_plugin {
|
||||
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[],
|
||||
@@ -84,7 +85,8 @@ struct io_plugin {
|
||||
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);
|
||||
|
@@ -111,7 +111,7 @@ fmt_string(const char *var, const char *val)
|
||||
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;
|
||||
@@ -422,7 +422,7 @@ static int
|
||||
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];
|
||||
|
@@ -417,7 +417,7 @@ static int
|
||||
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];
|
||||
|
@@ -96,7 +96,8 @@ static void set_runaspw(const char *);
|
||||
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);
|
||||
|
||||
@@ -135,13 +136,17 @@ sigjmp_buf error_jmp;
|
||||
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)
|
||||
@@ -178,8 +183,8 @@ sudoers_policy_open(unsigned int version, sudo_conv_t conversation,
|
||||
/* 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? */
|
||||
|
||||
@@ -1181,7 +1186,7 @@ sudoers_policy_version(int verbose)
|
||||
}
|
||||
|
||||
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;
|
||||
@@ -1191,6 +1196,29 @@ deserialize_info(char * const settings[], char * const user_info[])
|
||||
|
||||
#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++) {
|
||||
@@ -1294,23 +1322,6 @@ deserialize_info(char * const settings[], char * const user_info[])
|
||||
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++) {
|
||||
|
@@ -81,7 +81,7 @@ int sudolineno;
|
||||
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;
|
||||
|
@@ -131,6 +131,7 @@ sudo_load_plugins(struct plugin_container *policy_plugin,
|
||||
}
|
||||
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));
|
||||
@@ -138,6 +139,7 @@ sudo_load_plugins(struct plugin_container *policy_plugin,
|
||||
container->next = NULL;
|
||||
container->handle = handle;
|
||||
container->name = info->symbol_name;
|
||||
container->args = info->args;
|
||||
container->u.generic = plugin;
|
||||
tq_append(io_plugins, container);
|
||||
}
|
||||
|
30
src/sudo.c
30
src/sudo.c
@@ -1056,9 +1056,24 @@ static int
|
||||
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
|
||||
@@ -1141,7 +1156,7 @@ iolog_open(struct plugin_container *plugin, char * const settings[],
|
||||
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):
|
||||
@@ -1149,10 +1164,15 @@ iolog_open(struct plugin_container *plugin, char * const settings[],
|
||||
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);
|
||||
}
|
||||
|
@@ -29,6 +29,23 @@ struct generic_plugin {
|
||||
/*
|
||||
* 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;
|
||||
@@ -44,6 +61,21 @@ struct io_plugin_1_0 {
|
||||
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.
|
||||
@@ -52,12 +84,15 @@ struct plugin_container {
|
||||
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)
|
||||
|
Reference in New Issue
Block a user