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)
|
set_plugin(const char *entry)
|
||||||
{
|
{
|
||||||
struct plugin_info *info;
|
struct plugin_info *info;
|
||||||
const char *name, *path;
|
const char *name, *path, *cp, *ep;
|
||||||
size_t namelen;
|
char **args = NULL;
|
||||||
|
size_t namelen, pathlen;
|
||||||
|
unsigned int nargs;
|
||||||
|
|
||||||
/* Parse Plugin line */
|
/* Parse Plugin line */
|
||||||
name = entry;
|
name = entry;
|
||||||
@@ -215,10 +217,35 @@ set_plugin(const char *entry)
|
|||||||
namelen = (size_t)(path - name);
|
namelen = (size_t)(path - name);
|
||||||
while (isblank((unsigned char)*path))
|
while (isblank((unsigned char)*path))
|
||||||
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 = emalloc(sizeof(*info));
|
||||||
info->symbol_name = estrndup(name, namelen);
|
info->symbol_name = estrndup(name, namelen);
|
||||||
info->path = estrdup(path);
|
info->path = estrndup(path, pathlen);
|
||||||
|
info->args = args;
|
||||||
info->prev = info;
|
info->prev = info;
|
||||||
info->next = NULL;
|
info->next = NULL;
|
||||||
tq_append(&sudo_conf_data.plugins, info);
|
tq_append(&sudo_conf_data.plugins, info);
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
# Sample /etc/sudo.conf file
|
# Sample /etc/sudo.conf file
|
||||||
#
|
#
|
||||||
# Format:
|
# Format:
|
||||||
# Plugin plugin_name plugin_path
|
# Plugin plugin_name plugin_path plugin_args ...
|
||||||
# Path askpass /path/to/askpass
|
# Path askpass /path/to/askpass
|
||||||
# Path noexec /path/to/noexec.so
|
# Path noexec /path/to/noexec.so
|
||||||
# Debug sudo /var/log/sudo_debug all@warn
|
# 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_path is relative to ${prefix}/libexec unless fully qualified.
|
||||||
# The plugin_name corresponds to a global symbol in the plugin
|
# The plugin_name corresponds to a global symbol in the plugin
|
||||||
# that contains the plugin interface structure.
|
# that contains the plugin interface structure.
|
||||||
|
# The plugin_args are optional.
|
||||||
#
|
#
|
||||||
# The sudoers plugin is used by default if no Plugin lines are present.
|
# The sudoers plugin is used by default if no Plugin lines are present.
|
||||||
Plugin sudoers_policy sudoers.so
|
Plugin sudoers_policy sudoers.so
|
||||||
|
@@ -421,7 +421,7 @@ which corresponds to the following F<@sysconfdir@/sudo.conf> file.
|
|||||||
# Default @sysconfdir@/sudo.conf file
|
# Default @sysconfdir@/sudo.conf file
|
||||||
#
|
#
|
||||||
# Format:
|
# Format:
|
||||||
# Plugin plugin_name plugin_path
|
# Plugin plugin_name plugin_path plugin_args ...
|
||||||
# Path askpass /path/to/askpass
|
# Path askpass /path/to/askpass
|
||||||
# Path noexec /path/to/noexec.so
|
# Path noexec /path/to/noexec.so
|
||||||
# Debug sudo /var/log/sudo_debug all@warn
|
# Debug sudo /var/log/sudo_debug all@warn
|
||||||
@@ -431,6 +431,7 @@ which corresponds to the following F<@sysconfdir@/sudo.conf> file.
|
|||||||
# fully qualified.
|
# fully qualified.
|
||||||
# The plugin_name corresponds to a global symbol in the plugin
|
# The plugin_name corresponds to a global symbol in the plugin
|
||||||
# that contains the plugin interface structure.
|
# that contains the plugin interface structure.
|
||||||
|
# The plugin_args are optional.
|
||||||
#
|
#
|
||||||
Plugin policy_plugin sudoers.so
|
Plugin policy_plugin sudoers.so
|
||||||
Plugin io_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>
|
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
|
may be fully qualified or relative. If not fully qualified it is
|
||||||
relative to the F<@prefix@/libexec> directory. Any additional
|
relative to the F<@prefix@/libexec> directory. Any additional
|
||||||
parameters after the I<path> are ignored. Lines that don't begin
|
parameters after the I<path> are passed as arguments to the plugin's
|
||||||
with C<Plugin> or C<Path> are silently ignored
|
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.
|
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>
|
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
|
may be fully qualified or relative. If not fully qualified it is
|
||||||
relative to the F<@prefix@/libexec> directory. Any additional
|
relative to the F<@prefix@/libexec> directory. Any additional
|
||||||
parameters after the I<path> are ignored. Lines that don't begin
|
parameters after the I<path> are passed as arguments to the plugin's
|
||||||
with C<Plugin> or C<Path> are silently ignored.
|
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
|
The same shared object may contain multiple plugins, each with a
|
||||||
different symbol name. The shared object file must be owned by uid
|
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
|
# Default @sysconfdir@/sudo.conf file
|
||||||
#
|
#
|
||||||
# Format:
|
# Format:
|
||||||
# Plugin plugin_name plugin_path
|
# Plugin plugin_name plugin_path optional_args
|
||||||
# Path askpass /path/to/askpass
|
# 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
|
# The plugin_path is relative to @prefix@/libexec unless
|
||||||
# fully qualified.
|
# fully qualified.
|
||||||
# The plugin_name corresponds to a global symbol in the plugin
|
# The plugin_name corresponds to a global symbol in the plugin
|
||||||
# that contains the plugin interface structure.
|
# that contains the plugin interface structure.
|
||||||
|
# The plugin_args are optional.
|
||||||
#
|
#
|
||||||
Plugin sudoers_policy sudoers.so
|
Plugin sudoers_policy sudoers.so
|
||||||
Plugin sudoers_io 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 */
|
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 plugin_printf, char * const settings[],
|
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);
|
void (*close)(int exit_status, int error);
|
||||||
int (*show_version)(int verbose);
|
int (*show_version)(int verbose);
|
||||||
int (*check_policy)(int argc, char * const argv[],
|
int (*check_policy)(int argc, char * const argv[],
|
||||||
@@ -118,7 +124,8 @@ built against.
|
|||||||
|
|
||||||
int (*open)(unsigned int version, sudo_conv_t conversation,
|
int (*open)(unsigned int version, sudo_conv_t conversation,
|
||||||
sudo_printf_t plugin_printf, char * const settings[],
|
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,
|
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
|
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
|
equal sign ('=') since the I<name> field will never include one
|
||||||
itself but the I<value> might.
|
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
|
=back
|
||||||
|
|
||||||
=item close
|
=item close
|
||||||
@@ -762,7 +782,7 @@ error information to the user.
|
|||||||
int (*open)(unsigned int version, sudo_conv_t conversation
|
int (*open)(unsigned int version, sudo_conv_t conversation
|
||||||
sudo_printf_t plugin_printf, char * const settings[],
|
sudo_printf_t plugin_printf, char * const settings[],
|
||||||
char * const user_info[], int argc, char * const argv[],
|
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 */
|
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);
|
||||||
@@ -811,7 +831,7 @@ built against.
|
|||||||
int (*open)(unsigned int version, sudo_conv_t conversation
|
int (*open)(unsigned int version, sudo_conv_t conversation
|
||||||
sudo_printf_t plugin_printf, char * const settings[],
|
sudo_printf_t plugin_printf, char * const settings[],
|
||||||
char * const user_info[], int argc, char * const argv[],
|
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>
|
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
|
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
|
equal sign ('=') since the I<name> field will never include one
|
||||||
itself but the I<value> might.
|
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
|
=back
|
||||||
|
|
||||||
=item close
|
=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
|
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.
|
on how C<NOEXEC> works and whether or not it will work on your system.
|
||||||
|
|
||||||
=head3 SETENV and NOSETENV
|
=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>
|
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
|
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
|
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.
|
Escapes> section at the end of this manual. This flag is I<off> by default.
|
||||||
|
|
||||||
=item path_info
|
=item path_info
|
||||||
|
|
||||||
@@ -1594,10 +1594,166 @@ is displayed when B<sudo> is run by root with the I<-V> option.
|
|||||||
|
|
||||||
=back
|
=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
|
=head1 FILES
|
||||||
|
|
||||||
=over 24
|
=over 24
|
||||||
|
|
||||||
|
=item F<@sysconfdir@/sudo.conf>
|
||||||
|
|
||||||
|
Sudo front end configuration
|
||||||
|
|
||||||
=item F<@sysconfdir@/sudoers>
|
=item F<@sysconfdir@/sudoers>
|
||||||
|
|
||||||
List of who can run what
|
List of who can run what
|
||||||
@@ -1810,6 +1966,8 @@ for encapsulating in a shell script.
|
|||||||
|
|
||||||
=head1 SECURITY NOTES
|
=head1 SECURITY NOTES
|
||||||
|
|
||||||
|
=head2 Limitations of the '!' operator
|
||||||
|
|
||||||
It is generally not effective to "subtract" commands from C<ALL>
|
It is generally not effective to "subtract" commands from C<ALL>
|
||||||
using the '!' operator. A user can trivially circumvent this
|
using the '!' operator. A user can trivially circumvent this
|
||||||
by copying the desired command to a different name and then
|
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
|
program. Therefore, these kind of restrictions should be considered
|
||||||
advisory at best (and reinforced by policy).
|
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
|
to reliably negate commands where the path name includes globbing
|
||||||
(aka wildcard) characters. This is because the C library's
|
(aka wildcard) characters. This is because the C library's
|
||||||
L<fnmatch(3)> function cannot resolve relative paths. While this
|
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
|
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.
|
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
|
Once B<sudo> executes a program, that program is free to do whatever
|
||||||
it pleases, including run other programs. This can be a security
|
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
|
editor, a safer approach is to give the user permission to run
|
||||||
B<sudoedit>.
|
B<sudoedit>.
|
||||||
|
|
||||||
=head1 DEBUG FLAGS
|
=head2 Time stamp file checks
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
I<sudoers> will check the ownership of its time stamp directory
|
I<sudoers> will check the ownership of its time stamp directory
|
||||||
(F<@timedir@> by default) and ignore the directory's contents if
|
(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
|
tty-based time stamp file is stale and will ignore it. Administrators
|
||||||
should not rely on this feature as it is not universally available.
|
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
|
=head1 SEE ALSO
|
||||||
|
|
||||||
L<rsh(1)>, L<su(1)>, L<fnmatch(3)>, L<glob(3)>, L<mktemp(3)>, L<strftime(3)>,
|
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 */
|
struct plugin_info *next; /* required */
|
||||||
const char *path;
|
const char *path;
|
||||||
const char *symbol_name;
|
const char *symbol_name;
|
||||||
|
char * const * args;
|
||||||
};
|
};
|
||||||
TQ_DECLARE(plugin_info)
|
TQ_DECLARE(plugin_info)
|
||||||
|
|
||||||
|
@@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
/* 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 1
|
#define SUDO_API_VERSION_MINOR 2
|
||||||
#define SUDO_API_MKVERSION(x, y) ((x << 16) | y)
|
#define SUDO_API_MKVERSION(x, y) ((x << 16) | y)
|
||||||
#define SUDO_API_VERSION SUDO_API_MKVERSION(SUDO_API_VERSION_MAJOR, SUDO_API_VERSION_MINOR)
|
#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 */
|
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[], 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 */
|
void (*close)(int exit_status, int error); /* wait status or error */
|
||||||
int (*show_version)(int verbose);
|
int (*show_version)(int verbose);
|
||||||
int (*check_policy)(int argc, char * const argv[],
|
int (*check_policy)(int argc, char * const argv[],
|
||||||
@@ -84,7 +85,8 @@ struct io_plugin {
|
|||||||
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[], char * const command_info[],
|
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 */
|
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);
|
||||||
|
@@ -111,7 +111,7 @@ fmt_string(const char *var, const char *val)
|
|||||||
static int
|
static int
|
||||||
policy_open(unsigned int version, sudo_conv_t conversation,
|
policy_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[], char * const user_env[])
|
char * const user_info[], char * const user_env[], char * const args[])
|
||||||
{
|
{
|
||||||
char * const *ui;
|
char * const *ui;
|
||||||
struct passwd *pw;
|
struct passwd *pw;
|
||||||
@@ -422,7 +422,7 @@ static int
|
|||||||
io_open(unsigned int version, sudo_conv_t conversation,
|
io_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[], char * const command_info[],
|
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;
|
int fd;
|
||||||
char path[PATH_MAX];
|
char path[PATH_MAX];
|
||||||
|
@@ -417,7 +417,7 @@ static int
|
|||||||
sudoers_io_open(unsigned int version, sudo_conv_t conversation,
|
sudoers_io_open(unsigned int version, sudo_conv_t conversation,
|
||||||
sudo_printf_t plugin_printf, char * const settings[],
|
sudo_printf_t plugin_printf, char * const settings[],
|
||||||
char * const user_info[], char * const command_info[],
|
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;
|
struct iolog_details details;
|
||||||
char pathbuf[PATH_MAX], sessid[7];
|
char pathbuf[PATH_MAX], sessid[7];
|
||||||
|
@@ -96,7 +96,8 @@ static void set_runaspw(const char *);
|
|||||||
static void set_runasgr(const char *);
|
static void set_runasgr(const char *);
|
||||||
static int cb_runas_default(const char *);
|
static int cb_runas_default(const char *);
|
||||||
static int sudoers_policy_version(int verbose);
|
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 char *find_editor(int nfiles, char **files, char ***argv_out);
|
||||||
static void create_admin_success_flag(void);
|
static void create_admin_success_flag(void);
|
||||||
|
|
||||||
@@ -135,13 +136,17 @@ sigjmp_buf error_jmp;
|
|||||||
static int
|
static int
|
||||||
sudoers_policy_open(unsigned int version, sudo_conv_t conversation,
|
sudoers_policy_open(unsigned int version, sudo_conv_t conversation,
|
||||||
sudo_printf_t plugin_printf, char * const settings[],
|
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;
|
volatile int sources = 0;
|
||||||
sigaction_t sa;
|
sigaction_t sa;
|
||||||
struct sudo_nss *nss;
|
struct sudo_nss *nss;
|
||||||
debug_decl(sudoers_policy_open, SUDO_DEBUG_PLUGIN)
|
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)
|
if (!sudo_conv)
|
||||||
sudo_conv = conversation;
|
sudo_conv = conversation;
|
||||||
if (!sudo_printf)
|
if (!sudo_printf)
|
||||||
@@ -178,8 +183,8 @@ sudoers_policy_open(unsigned int version, sudo_conv_t conversation,
|
|||||||
/* Setup defaults data structures. */
|
/* Setup defaults data structures. */
|
||||||
init_defaults();
|
init_defaults();
|
||||||
|
|
||||||
/* Parse settings and user_info */
|
/* Parse args, settings and user_info */
|
||||||
sudo_mode = deserialize_info(settings, user_info);
|
sudo_mode = deserialize_info(args, settings, user_info);
|
||||||
|
|
||||||
init_vars(envp); /* XXX - move this later? */
|
init_vars(envp); /* XXX - move this later? */
|
||||||
|
|
||||||
@@ -1181,7 +1186,7 @@ sudoers_policy_version(int verbose)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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;
|
char * const *cur;
|
||||||
const char *p, *groups = NULL;
|
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)
|
#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. */
|
/* Parse command line settings. */
|
||||||
user_closefrom = -1;
|
user_closefrom = -1;
|
||||||
for (cur = settings; *cur != NULL; cur++) {
|
for (cur = settings; *cur != NULL; cur++) {
|
||||||
@@ -1294,23 +1322,6 @@ deserialize_info(char * const settings[], char * const user_info[])
|
|||||||
set_interfaces(interfaces_string);
|
set_interfaces(interfaces_string);
|
||||||
continue;
|
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++) {
|
for (cur = user_info; *cur != NULL; cur++) {
|
||||||
|
@@ -81,7 +81,7 @@ int sudolineno;
|
|||||||
int last_token;
|
int last_token;
|
||||||
char *sudoers;
|
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;
|
const char *sudoers_file = _PATH_SUDOERS;
|
||||||
mode_t sudoers_mode = SUDOERS_MODE;
|
mode_t sudoers_mode = SUDOERS_MODE;
|
||||||
uid_t sudoers_uid = SUDOERS_UID;
|
uid_t sudoers_uid = SUDOERS_UID;
|
||||||
|
@@ -131,6 +131,7 @@ sudo_load_plugins(struct plugin_container *policy_plugin,
|
|||||||
}
|
}
|
||||||
policy_plugin->handle = handle;
|
policy_plugin->handle = handle;
|
||||||
policy_plugin->name = info->symbol_name;
|
policy_plugin->name = info->symbol_name;
|
||||||
|
policy_plugin->args = info->args;
|
||||||
policy_plugin->u.generic = plugin;
|
policy_plugin->u.generic = plugin;
|
||||||
} else if (plugin->type == SUDO_IO_PLUGIN) {
|
} else if (plugin->type == SUDO_IO_PLUGIN) {
|
||||||
container = emalloc(sizeof(*container));
|
container = emalloc(sizeof(*container));
|
||||||
@@ -138,6 +139,7 @@ sudo_load_plugins(struct plugin_container *policy_plugin,
|
|||||||
container->next = NULL;
|
container->next = NULL;
|
||||||
container->handle = handle;
|
container->handle = handle;
|
||||||
container->name = info->symbol_name;
|
container->name = info->symbol_name;
|
||||||
|
container->args = info->args;
|
||||||
container->u.generic = plugin;
|
container->u.generic = plugin;
|
||||||
tq_append(io_plugins, container);
|
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[],
|
policy_open(struct plugin_container *plugin, char * const settings[],
|
||||||
char * const user_info[], char * const user_env[])
|
char * const user_info[], char * const user_env[])
|
||||||
{
|
{
|
||||||
|
int rval;
|
||||||
debug_decl(policy_open, SUDO_DEBUG_PCOMM)
|
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
|
static void
|
||||||
@@ -1141,7 +1156,7 @@ iolog_open(struct plugin_container *plugin, char * const settings[],
|
|||||||
debug_decl(iolog_open, SUDO_DEBUG_PCOMM)
|
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) {
|
switch (plugin->u.generic->version) {
|
||||||
case SUDO_API_MKVERSION(1, 0):
|
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,
|
sudo_conversation, _sudo_printf, settings, user_info, argc, argv,
|
||||||
user_env);
|
user_env);
|
||||||
break;
|
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:
|
default:
|
||||||
rval = plugin->u.io->open(SUDO_API_VERSION, sudo_conversation,
|
rval = plugin->u.io->open(SUDO_API_VERSION, sudo_conversation,
|
||||||
_sudo_printf, settings, user_info, command_info, argc, argv,
|
_sudo_printf, settings, user_info, command_info,
|
||||||
user_env);
|
argc, argv, user_env, plugin->args);
|
||||||
}
|
}
|
||||||
debug_return_bool(rval);
|
debug_return_bool(rval);
|
||||||
}
|
}
|
||||||
|
@@ -29,6 +29,23 @@ struct generic_plugin {
|
|||||||
/*
|
/*
|
||||||
* Backwards-compatible structures for API bumps.
|
* 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 {
|
struct io_plugin_1_0 {
|
||||||
unsigned int type;
|
unsigned int type;
|
||||||
unsigned int version;
|
unsigned int version;
|
||||||
@@ -44,6 +61,21 @@ struct io_plugin_1_0 {
|
|||||||
int (*log_stdout)(const char *buf, unsigned int len);
|
int (*log_stdout)(const char *buf, unsigned int len);
|
||||||
int (*log_stderr)(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.
|
* Sudo plugin internals.
|
||||||
@@ -52,12 +84,15 @@ struct plugin_container {
|
|||||||
struct plugin_container *prev; /* required */
|
struct plugin_container *prev; /* required */
|
||||||
struct plugin_container *next; /* required */
|
struct plugin_container *next; /* required */
|
||||||
const char *name;
|
const char *name;
|
||||||
|
char * const *args;
|
||||||
void *handle;
|
void *handle;
|
||||||
union {
|
union {
|
||||||
struct generic_plugin *generic;
|
struct generic_plugin *generic;
|
||||||
struct policy_plugin *policy;
|
struct policy_plugin *policy;
|
||||||
|
struct policy_plugin_1_0 *policy_1_0;
|
||||||
struct io_plugin *io;
|
struct io_plugin *io;
|
||||||
struct io_plugin_1_0 *io_1_0;
|
struct io_plugin_1_0 *io_1_0;
|
||||||
|
struct io_plugin_1_1 *io_1_1;
|
||||||
} u;
|
} u;
|
||||||
};
|
};
|
||||||
TQ_DECLARE(plugin_container)
|
TQ_DECLARE(plugin_container)
|
||||||
|
Reference in New Issue
Block a user