version 1.1.1.1, 2012/02/21 16:23:02
|
version 1.1.1.4, 2013/07/22 10:46:12
|
Line 1
|
Line 1
|
SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m) | SUDO_PLUGIN(4) Programmer's Manual SUDO_PLUGIN(4) |
|
|
|
|
|
|
NNAAMMEE |
NNAAMMEE |
sudo_plugin - Sudo Plugin API | ssuuddoo__pplluuggiinn - Sudo Plugin API |
|
|
DDEESSCCRRIIPPTTIIOONN |
DDEESSCCRRIIPPTTIIOONN |
Starting with version 1.8, ssuuddoo supports a plugin API for policy and | Starting with version 1.8, ssuuddoo supports a plugin API for policy and |
session logging. By default, the _s_u_d_o_e_r_s policy plugin and an | session logging. By default, the ssuuddooeerrss policy plugin and an associated |
associated I/O logging plugin are used. Via the plugin API, ssuuddoo can | I/O logging plugin are used. Via the plugin API, ssuuddoo can be configured |
be configured to use alternate policy and/or I/O logging plugins | to use alternate policy and/or I/O logging plugins provided by third |
provided by third parties. The plugins to be used are specified via | parties. The plugins to be used are specified in the sudo.conf(4) file. |
the _/_e_t_c_/_s_u_d_o_._c_o_n_f file. | |
|
|
The API is versioned with a major and minor number. The minor version | The API is versioned with a major and minor number. The minor version |
number is incremented when additions are made. The major number is | number is incremented when additions are made. The major number is |
incremented when incompatible changes are made. A plugin should be | incremented when incompatible changes are made. A plugin should be check |
check the version passed to it and make sure that the major version | the version passed to it and make sure that the major version matches. |
matches. | |
|
|
The plugin API is defined by the sudo_plugin.h header file. | The plugin API is defined by the sudo_plugin.h header file. |
|
|
TThhee ssuuddoo..ccoonnff FFiillee | PPoolliiccyy pplluuggiinn AAPPII |
The _/_e_t_c_/_s_u_d_o_._c_o_n_f file contains plugin configuration directives. | A policy plugin must declare and populate a policy_plugin struct in the |
Currently, the only supported keyword is the Plugin directive, which | global scope. This structure contains pointers to the functions that |
causes a plugin plugin to be loaded. | implement the ssuuddoo policy checks. The name of the symbol should be |
| specified in sudo.conf(4) along with a path to the plugin so that ssuuddoo |
| can load it. |
|
|
A Plugin line consists of the Plugin keyword, followed by the | struct policy_plugin { |
_s_y_m_b_o_l___n_a_m_e and the _p_a_t_h to the shared object containing the plugin. | #define SUDO_POLICY_PLUGIN 1 |
The _s_y_m_b_o_l___n_a_m_e is the name of the struct policy_plugin or struct | unsigned int type; /* always SUDO_POLICY_PLUGIN */ |
io_plugin in the plugin shared object. The _p_a_t_h may be fully qualified | unsigned int version; /* always SUDO_API_VERSION */ |
or relative. If not fully qualified it is relative to the | int (*open)(unsigned int version, sudo_conv_t conversation, |
_/_u_s_r_/_l_o_c_a_l_/_l_i_b_e_x_e_c directory. Any additional parameters after the _p_a_t_h | sudo_printf_t plugin_printf, char * const settings[], |
are ignored. Lines that don't begin with Plugin or Path are silently | char * const user_info[], char * const user_env[], |
ignored. | char * const plugin_options[]); |
| void (*close)(int exit_status, int 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, char **user_env[]); |
| void (*register_hooks)(int version, |
| int (*register_hook)(struct sudo_hook *hook)); |
| void (*deregister_hooks)(int version, |
| int (*deregister_hook)(struct sudo_hook *hook)); |
| }; |
|
|
The same shared object may contain multiple plugins, each with a | The policy_plugin struct has the following fields: |
different symbol name. The shared object file must be owned by uid 0 | |
and only writable by its owner. Because of ambiguities that arise from | |
composite policies, only a single policy plugin may be specified. This | |
limitation does not apply to I/O plugins. | |
|
|
# | type The type field should always be set to SUDO_POLICY_PLUGIN. |
# Default /etc/sudo.conf file | |
# | |
# Format: | |
# Plugin plugin_name plugin_path | |
# Path askpass /path/to/askpass | |
# | |
# The plugin_path is relative to /usr/local/libexec unless | |
# fully qualified. | |
# The plugin_name corresponds to a global symbol in the plugin | |
# that contains the plugin interface structure. | |
# | |
Plugin sudoers_policy sudoers.so | |
Plugin sudoers_io sudoers.so | |
|
|
PPoolliiccyy PPlluuggiinn AAPPII | version |
A policy plugin must declare and populate a policy_plugin struct in the | |
global scope. This structure contains pointers to the functions that | |
implement the ssuuddoo policy checks. The name of the symbol should be | |
specified in _/_e_t_c_/_s_u_d_o_._c_o_n_f along with a path to the plugin so that | |
ssuuddoo can load it. | |
| |
struct policy_plugin { | |
#define SUDO_POLICY_PLUGIN 1 | |
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[]); | |
void (*close)(int exit_status, int 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); | |
}; | |
| |
The policy_plugin struct has the following fields: | |
| |
type | |
The type field should always be set to SUDO_POLICY_PLUGIN. | |
| |
version | |
The version field should be set to SUDO_API_VERSION. |
The version field should be set to SUDO_API_VERSION. |
|
|
This allows ssuuddoo to determine the API version the plugin was built |
This allows ssuuddoo to determine the API version the plugin was built |
against. |
against. |
|
|
open | open |
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_options[]); |
|
|
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, ssuuddoo will |
or -2 if there was a usage error. In the latter case, ssuuddoo will |
print a usage message before it exits. If an error occurs, the |
print a usage message before it exits. If an error occurs, the |
plugin may optionally call the conversation or plugin_printf | plugin may optionally call the ccoonnvveerrssaattiioonn() or pplluuggiinn__pprriinnttff() |
function with SUDO_CONF_ERROR_MSG to present additional error |
function with SUDO_CONF_ERROR_MSG to present additional error |
information to the user. |
information to the user. |
|
|
The function arguments are as follows: |
The function arguments are as follows: |
|
|
version |
version |
The version passed in by ssuuddoo allows the plugin to determine | The version passed in by ssuuddoo allows the plugin to determine |
the major and minor version number of the plugin API supported | the major and minor version number of the plugin API |
by ssuuddoo. | supported by ssuuddoo. |
|
|
conversation |
conversation |
A pointer to the conversation function that can be used by the | A pointer to the ccoonnvveerrssaattiioonn() function that can be used by |
plugin to interact with the user (see below). Returns 0 on | the plugin to interact with the user (see below). Returns 0 |
success and -1 on failure. | on success and -1 on failure. |
|
|
plugin_printf |
plugin_printf |
A pointer to a printf-style function that may be used to | A pointer to a pprriinnttff()-style function that may be used to |
display informational or error messages (see below). Returns | display informational or error messages (see below). Returns |
the number of characters printed on success and -1 on failure. | the number of characters printed on success and -1 on |
| failure. |
|
|
settings |
settings |
A vector of user-supplied ssuuddoo settings in the form of | A vector of user-supplied ssuuddoo settings in the form of |
"name=value" strings. The vector is terminated by a NULL | ``name=value'' strings. The vector is terminated by a NULL |
pointer. These settings correspond to flags the user specified | pointer. These settings correspond to flags the user |
when running ssuuddoo. As such, they will only be present when the | specified when running ssuuddoo. As such, they will only be |
corresponding flag has been specified on the command line. | present when the corresponding flag has been specified on the |
| command line. |
|
|
When parsing _s_e_t_t_i_n_g_s, the plugin should split on the ffiirrsstt | When parsing _s_e_t_t_i_n_g_s, the plugin should split on the ffiirrsstt |
equal sign ('=') since the _n_a_m_e field will never include one | equal sign (`=') since the _n_a_m_e field will never include one |
itself but the _v_a_l_u_e might. | itself but the _v_a_l_u_e might. |
|
|
debug_level=number | bsdauth_type=string |
A numeric debug level, from 1-9, if specified via the -D | Authentication type, if specified by the --aa flag, to |
flag. | use on systems where BSD authentication is supported. |
|
|
runas_user=string | closefrom=number |
The user name or uid to to run the command as, if specified | If specified, the user has requested via the --CC flag |
via the -u flag. | that ssuuddoo close all files descriptors with a value of |
| _n_u_m_b_e_r or higher. The plugin may optionally pass this, |
| or another value, back in the _c_o_m_m_a_n_d___i_n_f_o list. |
|
|
runas_group=string | debug_flags=string |
The group name or gid to to run the command as, if | A comma-separated list of debug flags that correspond |
specified via the -g flag. | to ssuuddoo's Debug entry in sudo.conf(4), if there is one. |
| The flags are passed to the plugin as they appear in |
| sudo.conf(4). The syntax used by ssuuddoo and the ssuuddooeerrss |
| plugin is _s_u_b_s_y_s_t_e_m@_p_r_i_o_r_i_t_y but the plugin is free to |
| use a different format so long as it does not include a |
| comma (`,'). There is not currently a way to specify a |
| set of debug flags specific to the plugin--the flags |
| are shared by ssuuddoo and the plugin. |
|
|
prompt=string | debug_level=number |
The prompt to use when requesting a password, if specified | This setting has been deprecated in favor of |
via the -p flag. | _d_e_b_u_g___f_l_a_g_s. |
|
|
set_home=bool | ignore_ticket=bool |
Set to true if the user specified the -H flag. If true, | Set to true if the user specified the --kk flag along |
set the HOME environment variable to the target user's home | with a command, indicating that the user wishes to |
directory. | ignore any cached authentication credentials. |
| _i_m_p_l_i_e_d___s_h_e_l_l to true. This allows ssuuddoo with no |
| arguments to be used similarly to su(1). If the plugin |
| does not to support this usage, it may return a value |
| of -2 from the cchheecckk__ppoolliiccyy() function, which will |
| cause ssuuddoo to print a usage message and exit. |
|
|
preserve_environment=bool | implied_shell=bool |
Set to true if the user specified the -E flag, indicating | If the user does not specify a program on the command |
that the user wishes to preserve the environment. | line, ssuuddoo will pass the plugin the path to the user's |
| shell and set |
|
|
run_shell=bool | login_class=string |
Set to true if the user specified the -s flag, indicating | BSD login class to use when setting resource limits and |
that the user wishes to run a shell. | nice value, if specified by the --cc flag. |
|
|
login_shell=bool | login_shell=bool |
Set to true if the user specified the -i flag, indicating | Set to true if the user specified the --ii flag, |
that the user wishes to run a login shell. | indicating that the user wishes to run a login shell. |
|
|
implied_shell=bool | max_groups=int |
If the user does not specify a program on the command line, | The maximum number of groups a user may belong to. |
ssuuddoo will pass the plugin the path to the user's shell and | This will only be present if there is a corresponding |
set _i_m_p_l_i_e_d___s_h_e_l_l to true. This allows ssuuddoo with no | setting in sudo.conf(4). |
arguments to be used similarly to _s_u(1). If the plugin | |
does not to support this usage, it may return a value of -2 | |
from the check_policy function, which will cause ssuuddoo to | |
print a usage message and exit. | |
|
|
preserve_groups=bool | network_addrs=list |
Set to true if the user specified the -P flag, indicating | A space-separated list of IP network addresses and |
that the user wishes to preserve the group vector instead | netmasks in the form ``addr/netmask'', e.g. |
of setting it based on the runas user. | ``192.168.1.2/255.255.255.0''. The address and netmask |
| pairs may be either IPv4 or IPv6, depending on what the |
| operating system supports. If the address contains a |
| colon (`:'), it is an IPv6 address, else it is IPv4. |
|
|
ignore_ticket=bool | noninteractive=bool |
Set to true if the user specified the -k flag along with a | Set to true if the user specified the --nn flag, |
command, indicating that the user wishes to ignore any | indicating that ssuuddoo should operate in non-interactive |
cached authentication credentials. | mode. The plugin may reject a command run in non- |
| interactive mode if user interaction is required. |
|
|
noninteractive=bool | plugin_dir=string |
Set to true if the user specified the -n flag, indicating | The default plugin directory used by the ssuuddoo front |
that ssuuddoo should operate in non-interactive mode. The | end. This is the default directory set at compile time |
plugin may reject a command run in non-interactive mode if | and may not correspond to the directory the running |
user interaction is required. | plugin was loaded from. It may be used by a plugin to |
| locate support files. |
|
|
login_class=string | preserve_environment=bool |
BSD login class to use when setting resource limits and | Set to true if the user specified the --EE flag, |
nice value, if specified by the -c flag. | indicating that the user wishes to preserve the |
| environment. |
|
|
selinux_role=string | preserve_groups=bool |
SELinux role to use when executing the command, if | Set to true if the user specified the --PP flag, |
specified by the -r flag. | indicating that the user wishes to preserve the group |
| vector instead of setting it based on the runas user. |
|
|
selinux_type=string | progname=string |
SELinux type to use when executing the command, if | The command name that sudo was run as, typically |
specified by the -t flag. | ``sudo'' or ``sudoedit''. |
|
|
bsdauth_type=string | prompt=string |
Authentication type, if specified by the -a flag, to use on | The prompt to use when requesting a password, if |
systems where BSD authentication is supported. | specified via the --pp flag. |
|
|
network_addrs=list | run_shell=bool |
A space-separated list of IP network addresses and netmasks | Set to true if the user specified the --ss flag, |
in the form "addr/netmask", e.g. | indicating that the user wishes to run a shell. |
"192.168.1.2/255.255.255.0". The address and netmask pairs | |
may be either IPv4 or IPv6, depending on what the operating | |
system supports. If the address contains a colon (':'), it | |
is an IPv6 address, else it is IPv4. | |
|
|
progname=string | runas_group=string |
The command name that sudo was run as, typically "sudo" or | The group name or gid to to run the command as, if |
"sudoedit". | specified via the --gg flag. |
|
|
sudoedit=bool | runas_user=string |
Set to true when the -e flag is is specified or if invoked | The user name or uid to to run the command as, if |
as ssuuddooeeddiitt. The plugin shall substitute an editor into | specified via the --uu flag. |
_a_r_g_v in the _c_h_e_c_k___p_o_l_i_c_y function or return -2 with a usage | |
error if the plugin does not support _s_u_d_o_e_d_i_t. For more | |
information, see the _c_h_e_c_k___p_o_l_i_c_y section. | |
|
|
closefrom=number | selinux_role=string |
If specified, the user has requested via the -C flag that | SELinux role to use when executing the command, if |
ssuuddoo close all files descriptors with a value of _n_u_m_b_e_r or | specified by the --rr flag. |
higher. The plugin may optionally pass this, or another | |
value, back in the _c_o_m_m_a_n_d___i_n_f_o list. | |
|
|
Additional settings may be added in the future so the plugin | selinux_type=string |
should silently ignore settings that it does not recognize. | SELinux type to use when executing the command, if |
| specified by the --tt flag. |
|
|
|
set_home=bool |
|
Set to true if the user specified the --HH flag. If |
|
true, set the HOME environment variable to the target |
|
user's home directory. |
|
|
|
sudoedit=bool |
|
Set to true when the --ee flag is is specified or if |
|
invoked as ssuuddooeeddiitt. The plugin shall substitute an |
|
editor into _a_r_g_v in the cchheecckk__ppoolliiccyy() function or |
|
return -2 with a usage error if the plugin does not |
|
support _s_u_d_o_e_d_i_t. For more information, see the |
|
_c_h_e_c_k___p_o_l_i_c_y section. |
|
|
|
Additional settings may be added in the future so the plugin |
|
should silently ignore settings that it does not recognize. |
|
|
user_info |
user_info |
A vector of information about the user running the command in | A vector of information about the user running the command in |
the form of "name=value" strings. The vector is terminated by | the form of ``name=value'' strings. The vector is terminated |
a NULL pointer. | by a NULL pointer. |
|
|
When parsing _u_s_e_r___i_n_f_o, the plugin should split on the ffiirrsstt | When parsing _u_s_e_r___i_n_f_o, the plugin should split on the ffiirrsstt |
equal sign ('=') since the _n_a_m_e field will never include one | equal sign (`=') since the _n_a_m_e field will never include one |
itself but the _v_a_l_u_e might. | itself but the _v_a_l_u_e might. |
|
|
user=string | cols=int |
The name of the user invoking ssuuddoo. | The number of columns the user's terminal supports. If |
| there is no terminal device available, a default value |
| of 80 is used. |
|
|
uid=uid_t | cwd=string |
The real user ID of the user invoking ssuuddoo. | The user's current working directory. |
|
|
gid=gid_t | egid=gid_t |
The real group ID of the user invoking ssuuddoo. | The effective group ID of the user invoking ssuuddoo. |
|
|
groups=list | euid=uid_t |
The user's supplementary group list formatted as a string | The effective user ID of the user invoking ssuuddoo. |
of comma-separated group IDs. | |
|
|
cwd=string | gid=gid_t |
The user's current working directory. | The real group ID of the user invoking ssuuddoo. |
|
|
tty=string | groups=list |
The path to the user's terminal device. If the user has no | The user's supplementary group list formatted as a |
terminal device associated with the session, the value will | string of comma-separated group IDs. |
be empty, as in tty=. | |
|
|
host=string | host=string |
The local machine's hostname as returned by the | The local machine's hostname as returned by the |
gethostname() system call. | gethostname(2) system call. |
|
|
lines=int | lines=int |
The number of lines the user's terminal supports. If there | The number of lines the user's terminal supports. If |
is no terminal device available, a default value of 24 is | there is no terminal device available, a default value |
used. | of 24 is used. |
|
|
cols=int | pgid=int |
The number of columns the user's terminal supports. If | The ID of the process group that the running ssuuddoo |
there is no terminal device available, a default value of | process is a member of. Only available starting with |
80 is used. | API version 1.2 |
|
|
|
pid=int |
|
The process ID of the running ssuuddoo process. Only |
|
available starting with API version 1.2 |
|
|
|
plugin_options |
|
Any (non-comment) strings immediately after the plugin |
|
path are passed as arguments to the plugin. These |
|
arguments are split on a white space boundary and are |
|
passed to the plugin in the form of a NULL-terminated |
|
array of strings. If no arguments were specified, |
|
_p_l_u_g_i_n___o_p_t_i_o_n_s will be the NULL pointer. |
|
|
|
NOTE: the _p_l_u_g_i_n___o_p_t_i_o_n_s parameter is only available |
|
starting with API version 1.2. A plugin mmuusstt check the |
|
API version specified by the ssuuddoo front end before |
|
using _p_l_u_g_i_n___o_p_t_i_o_n_s. Failure to do so may result in a |
|
crash. |
|
|
|
ppid=int |
|
The parent process ID of the running ssuuddoo process. |
|
Only available starting with API version 1.2 |
|
|
|
sid=int |
|
The session ID of the running ssuuddoo process or 0 if ssuuddoo |
|
is not part of a POSIX job control session. Only |
|
available starting with API version 1.2 |
|
|
|
tcpgid=int |
|
The ID of the foreground process group associated with |
|
the terminal device associated with the ssuuddoo process or |
|
-1 if there is no terminal present. Only available |
|
starting with API version 1.2 |
|
|
|
tty=string |
|
The path to the user's terminal device. If the user |
|
has no terminal device associated with the session, the |
|
value will be empty, as in ``tty=''. |
|
|
|
uid=uid_t |
|
The real user ID of the user invoking ssuuddoo. |
|
|
|
user=string |
|
The name of the user invoking ssuuddoo. |
|
|
user_env |
user_env |
The user's environment in the form of a NULL-terminated vector | The user's environment in the form of a NULL-terminated |
of "name=value" strings. | vector of ``name=value'' strings. |
|
|
When parsing _u_s_e_r___e_n_v, the plugin should split on the ffiirrsstt | When parsing _u_s_e_r___e_n_v, the plugin should split on the ffiirrsstt |
equal sign ('=') since the _n_a_m_e field will never include one | equal sign (`=') since the _n_a_m_e field will never include one |
itself but the _v_a_l_u_e might. | itself but the _v_a_l_u_e might. |
|
|
close | close |
void (*close)(int exit_status, int error); | void (*close)(int exit_status, int error); |
|
|
The close function is called when the command being run by ssuuddoo | The cclloossee() function is called when the command being run by ssuuddoo |
finishes. |
finishes. |
|
|
The function arguments are as follows: |
The function arguments are as follows: |
|
|
exit_status |
exit_status |
The command's exit status, as returned by the _w_a_i_t(2) system | The command's exit status, as returned by the wait(2) system |
call. The value of exit_status is undefined if error is non- | call. The value of exit_status is undefined if error is non- |
zero. | zero. |
|
|
error |
error |
If the command could not be executed, this is set to the value | If the command could not be executed, this is set to the |
of errno set by the _e_x_e_c_v_e(2) system call. The plugin is | value of errno set by the execve(2) system call. The plugin |
responsible for displaying error information via the | is responsible for displaying error information via the |
conversation or plugin_printf function. If the command was | ccoonnvveerrssaattiioonn() or pplluuggiinn__pprriinnttff() function. If the command |
successfully executed, the value of error is 0. | was successfully executed, the value of error is 0. |
|
|
show_version | If no cclloossee() function is defined, no I/O logging plugins are |
int (*show_version)(int verbose); | loaded, and neither the _t_i_m_e_o_u_t not _u_s_e___p_t_y options are set in the |
| command_info list, the ssuuddoo front end may execute the command |
| directly instead of running it as a child process. |
|
|
The show_version function is called by ssuuddoo when the user specifies | show_version |
the -V option. The plugin may display its version information to | int (*show_version)(int verbose); |
the user via the conversation or plugin_printf function using | |
SUDO_CONV_INFO_MSG. If the user requests detailed version | |
information, the verbose flag will be set. | |
|
|
check_policy | The sshhooww__vveerrssiioonn() function is called by ssuuddoo when the user |
int (*check_policy)(int argc, char * const argv[] | specifies the --VV option. The plugin may display its version |
char *env_add[], char **command_info[], | information to the user via the ccoonnvveerrssaattiioonn() or pplluuggiinn__pprriinnttff() |
char **argv_out[], char **user_env_out[]); | function using SUDO_CONV_INFO_MSG. If the user requests detailed |
| version information, the verbose flag will be set. |
|
|
The _c_h_e_c_k___p_o_l_i_c_y function is called by ssuuddoo to determine whether | check_policy |
| int (*check_policy)(int argc, char * const argv[] |
| char *env_add[], char **command_info[], |
| char **argv_out[], char **user_env_out[]); |
| |
| The cchheecckk__ppoolliiccyy() function is called by ssuuddoo to determine whether |
the user is allowed to run the specified commands. |
the user is allowed to run the specified commands. |
|
|
If the _s_u_d_o_e_d_i_t option was enabled in the _s_e_t_t_i_n_g_s array passed to |
If the _s_u_d_o_e_d_i_t option was enabled in the _s_e_t_t_i_n_g_s array passed to |
the _o_p_e_n function, the user has requested _s_u_d_o_e_d_i_t mode. _s_u_d_o_e_d_i_t | the ooppeenn() function, the user has requested _s_u_d_o_e_d_i_t mode. |
is a mechanism for editing one or more files where an editor is run | _s_u_d_o_e_d_i_t is a mechanism for editing one or more files where an |
with the user's credentials instead of with elevated privileges. | editor is run with the user's credentials instead of with elevated |
ssuuddoo achieves this by creating user-writable temporary copies of | privileges. ssuuddoo achieves this by creating user-writable temporary |
the files to be edited and then overwriting the originals with the | copies of the files to be edited and then overwriting the originals |
temporary copies after editing is complete. If the plugin supports | with the temporary copies after editing is complete. If the plugin |
ssuuddooeeddiitt, it should choose the editor to be used, potentially from | supports _s_u_d_o_e_d_i_t, it should choose the editor to be used, |
a variable in the user's environment, such as EDITOR, and include | potentially from a variable in the user's environment, such as |
it in _a_r_g_v___o_u_t (note that environment variables may include command | EDITOR, and include it in _a_r_g_v___o_u_t (note that environment variables |
line flags). The files to be edited should be copied from _a_r_g_v | may include command line flags). The files to be edited should be |
into _a_r_g_v___o_u_t, separated from the editor and its arguments by a | copied from _a_r_g_v into _a_r_g_v___o_u_t, separated from the editor and its |
"--" element. The "--" will be removed by ssuuddoo before the editor | arguments by a ``--'' element. The ``--'' will be removed by ssuuddoo |
is executed. The plugin should also set _s_u_d_o_e_d_i_t_=_t_r_u_e in the | before the editor is executed. The plugin should also set |
_c_o_m_m_a_n_d___i_n_f_o list. | _s_u_d_o_e_d_i_t_=_t_r_u_e in the _c_o_m_m_a_n_d___i_n_f_o list. |
|
|
The _c_h_e_c_k___p_o_l_i_c_y function returns 1 if the command is allowed, 0 if | The cchheecckk__ppoolliiccyy() function returns 1 if the command is allowed, 0 |
not allowed, -1 for a general error, or -2 for a usage error or if | if not allowed, -1 for a general error, or -2 for a usage error or |
ssuuddooeeddiitt was specified but is unsupported by the plugin. In the | if _s_u_d_o_e_d_i_t was specified but is unsupported by the plugin. In the |
latter case, ssuuddoo will print a usage message before it exits. If |
latter case, ssuuddoo will print a usage message before it exits. If |
an error occurs, the plugin may optionally call the conversation or | an error occurs, the plugin may optionally call the ccoonnvveerrssaattiioonn() |
plugin_printf function with SUDO_CONF_ERROR_MSG to present | or pplluuggiinn__pprriinnttff() function with SUDO_CONF_ERROR_MSG to present |
additional error information to the user. |
additional error information to the user. |
|
|
The function arguments are as follows: |
The function arguments are as follows: |
|
|
argc | argc The number of elements in _a_r_g_v, not counting the final NULL |
The number of elements in _a_r_g_v, not counting the final NULL | pointer. |
pointer. | |
|
|
argv | argv The argument vector describing the command the user wishes to |
The argument vector describing the command the user wishes to | run, in the same form as what would be passed to the |
run, in the same form as what would be passed to the _e_x_e_c_v_e_(_) | execve(2) system call. The vector is terminated by a NULL |
system call. The vector is terminated by a NULL pointer. | pointer. |
|
|
env_add |
env_add |
Additional environment variables specified by the user on the | Additional environment variables specified by the user on the |
command line in the form of a NULL-terminated vector of | command line in the form of a NULL-terminated vector of |
"name=value" strings. The plugin may reject the command if one | ``name=value'' strings. The plugin may reject the command if |
or more variables are not allowed to be set, or it may silently | one or more variables are not allowed to be set, or it may |
ignore such variables. | silently ignore such variables. |
|
|
When parsing _e_n_v___a_d_d, the plugin should split on the ffiirrsstt | When parsing _e_n_v___a_d_d, the plugin should split on the ffiirrsstt |
equal sign ('=') since the _n_a_m_e field will never include one | equal sign (`=') since the _n_a_m_e field will never include one |
itself but the _v_a_l_u_e might. | itself but the _v_a_l_u_e might. |
|
|
command_info |
command_info |
Information about the command being run in the form of | Information about the command being run in the form of |
"name=value" strings. These values are used by ssuuddoo to set the | ``name=value'' strings. These values are used by ssuuddoo to set |
execution environment when running a command. The plugin is | the execution environment when running a command. The plugin |
responsible for creating and populating the vector, which must | is responsible for creating and populating the vector, which |
be terminated with a NULL pointer. The following values are | must be terminated with a NULL pointer. The following values |
recognized by ssuuddoo: | are recognized by ssuuddoo: |
|
|
command=string | chroot=string |
Fully qualified path to the command to be executed. | The root directory to use when running the command. |
|
|
runas_uid=uid | closefrom=number |
User ID to run the command as. | If specified, ssuuddoo will close all files descriptors |
| with a value of _n_u_m_b_e_r or higher. |
|
|
runas_euid=uid | command=string |
Effective user ID to run the command as. If not specified, | Fully qualified path to the command to be executed. |
the value of _r_u_n_a_s___u_i_d is used. | |
|
|
runas_gid=gid | cwd=string |
Group ID to run the command as. | The current working directory to change to when |
| executing the command. |
|
|
runas_egid=gid | exec_background=bool |
Effective group ID to run the command as. If not | By default, ssuuddoo runs a command as the foreground |
specified, the value of _r_u_n_a_s___g_i_d is used. | process as long as ssuuddoo itself is running in the |
| foreground. When _e_x_e_c___b_a_c_k_g_r_o_u_n_d is enabled and the |
| command is being run in a pty (due to I/O logging or |
| the _u_s_e___p_t_y setting), the command will be run as a |
| background process. Attempts to read from the |
| controlling terminal (or to change terminal settings) |
| will result in the command being suspended with the |
| SIGTTIN signal (or SIGTTOU in the case of terminal |
| settings). If this happens when ssuuddoo is a foreground |
| process, the command will be granted the controlling |
| terminal and resumed in the foreground with no user |
| intervention required. The advantage of initially |
| running the command in the background is that ssuuddoo need |
| not read from the terminal unless the command |
| explicitly requests it. Otherwise, any terminal input |
| must be passed to the command, whether it has required |
| it or not (the kernel buffers terminals so it is not |
| possible to tell whether the command really wants the |
| input). This is different from historic _s_u_d_o behavior |
| or when the command is not being run in a pty. |
|
|
runas_groups=list | For this to work seamlessly, the operating system must |
The supplementary group vector to use for the command in | support the automatic restarting of system calls. |
the form of a comma-separated list of group IDs. If | Unfortunately, not all operating systems do this by |
_p_r_e_s_e_r_v_e___g_r_o_u_p_s is set, this option is ignored. | default, and even those that do may have bugs. For |
| example, Mac OS X fails to restart the ttccggeettaattttrr() and |
| ttccsseettaattttrr() system calls (this is a bug in Mac OS X). |
| Furthermore, because this behavior depends on the |
| command stopping with the SIGTTIN or SIGTTOU signals, |
| programs that catch these signals and suspend |
| themselves with a different signal (usually SIGTOP) |
| will not be automatically foregrounded. Some versions |
| of the linux su(1) command behave this way. Because of |
| this, a plugin should not set _e_x_e_c___b_a_c_k_g_r_o_u_n_d unless it |
| is explicitly enabled by the administrator and there |
| should be a way to enabled or disable it on a per- |
| command basis. |
|
|
login_class=string | This setting has no effect unless I/O logging is |
BSD login class to use when setting resource limits and | enabled or _u_s_e___p_t_y is enabled. |
nice value (optional). This option is only set on systems | |
that support login classes. | |
|
|
preserve_groups=bool | iolog_compress=bool |
If set, ssuuddoo will preserve the user's group vector instead | Set to true if the I/O logging plugins, if any, should |
of initializing the group vector based on runas_user. | compress the log data. This is a hint to the I/O |
| logging plugin which may choose to ignore it. |
|
|
cwd=string | iolog_path=string |
The current working directory to change to when executing | Fully qualified path to the file or directory in which |
the command. | I/O log is to be stored. This is a hint to the I/O |
| logging plugin which may choose to ignore it. If no |
| I/O logging plugin is loaded, this setting has no |
| effect. |
|
|
noexec=bool | iolog_stdin=bool |
If set, prevent the command from executing other programs. | Set to true if the I/O logging plugins, if any, should |
| log the standard input if it is not connected to a |
| terminal device. This is a hint to the I/O logging |
| plugin which may choose to ignore it. |
|
|
chroot=string | iolog_stdout=bool |
The root directory to use when running the command. | Set to true if the I/O logging plugins, if any, should |
| log the standard output if it is not connected to a |
| terminal device. This is a hint to the I/O logging |
| plugin which may choose to ignore it. |
|
|
nice=int | iolog_stderr=bool |
Nice value (priority) to use when executing the command. | Set to true if the I/O logging plugins, if any, should |
The nice value, if specified, overrides the priority | log the standard error if it is not connected to a |
associated with the _l_o_g_i_n___c_l_a_s_s on BSD systems. | terminal device. This is a hint to the I/O logging |
| plugin which may choose to ignore it. |
|
|
umask=octal | iolog_ttyin=bool |
The file creation mask to use when executing the command. | Set to true if the I/O logging plugins, if any, should |
| log all terminal input. This only includes input typed |
| by the user and not from a pipe or redirected from a |
| file. This is a hint to the I/O logging plugin which |
| may choose to ignore it. |
|
|
selinux_role=string | iolog_ttyout=bool |
SELinux role to use when executing the command. | Set to true if the I/O logging plugins, if any, should |
| log all terminal output. This only includes output to |
| the screen, not output to a pipe or file. This is a |
| hint to the I/O logging plugin which may choose to |
| ignore it. |
|
|
selinux_type=string | login_class=string |
SELinux type to use when executing the command. | BSD login class to use when setting resource limits and |
| nice value (optional). This option is only set on |
| systems that support login classes. |
|
|
timeout=int | nice=int |
Command timeout. If non-zero then when the timeout expires | Nice value (priority) to use when executing the |
the command will be killed. | command. The nice value, if specified, overrides the |
| priority associated with the _l_o_g_i_n___c_l_a_s_s on BSD |
| systems. |
|
|
sudoedit=bool | noexec=bool |
Set to true when in _s_u_d_o_e_d_i_t mode. The plugin may enable | If set, prevent the command from executing other |
_s_u_d_o_e_d_i_t mode even if ssuuddoo was not invoked as ssuuddooeeddiitt. | programs. |
This allows the plugin to perform command substitution and | |
transparently enable _s_u_d_o_e_d_i_t when the user attempts to run | |
an editor. | |
|
|
closefrom=number | preserve_groups=bool |
If specified, ssuuddoo will close all files descriptors with a | If set, ssuuddoo will preserve the user's group vector |
value of _n_u_m_b_e_r or higher. | instead of initializing the group vector based on |
| runas_user. |
|
|
iolog_compress=bool | runas_egid=gid |
Set to true if the I/O logging plugins, if any, should | Effective group ID to run the command as. If not |
compress the log data. This is a hint to the I/O logging | specified, the value of _r_u_n_a_s___g_i_d is used. |
plugin which may choose to ignore it. | |
|
|
iolog_path=string | runas_euid=uid |
Fully qualified path to the file or directory in which I/O | Effective user ID to run the command as. If not |
log is to be stored. This is a hint to the I/O logging | specified, the value of _r_u_n_a_s___u_i_d is used. |
plugin which may choose to ignore it. If no I/O logging | |
plugin is loaded, this setting has no effect. | |
|
|
iolog_stdin=bool | runas_gid=gid |
Set to true if the I/O logging plugins, if any, should log | Group ID to run the command as. |
the standard input if it is not connected to a terminal | |
device. This is a hint to the I/O logging plugin which may | |
choose to ignore it. | |
|
|
iolog_stdout=bool | runas_groups=list |
Set to true if the I/O logging plugins, if any, should log | The supplementary group vector to use for the command |
the standard output if it is not connected to a terminal | in the form of a comma-separated list of group IDs. If |
device. This is a hint to the I/O logging plugin which may | _p_r_e_s_e_r_v_e___g_r_o_u_p_s is set, this option is ignored. |
choose to ignore it. | |
|
|
iolog_stderr=bool | runas_uid=uid |
Set to true if the I/O logging plugins, if any, should log | User ID to run the command as. |
the standard error if it is not connected to a terminal | |
device. This is a hint to the I/O logging plugin which may | |
choose to ignore it. | |
|
|
iolog_ttyin=bool | selinux_role=string |
Set to true if the I/O logging plugins, if any, should log | SELinux role to use when executing the command. |
all terminal input. This only includes input typed by the | |
user and not from a pipe or redirected from a file. This | |
is a hint to the I/O logging plugin which may choose to | |
ignore it. | |
|
|
iolog_ttyout=bool | selinux_type=string |
Set to true if the I/O logging plugins, if any, should log | SELinux type to use when executing the command. |
all terminal output. This only includes output to the | |
screen, not output to a pipe or file. This is a hint to | |
the I/O logging plugin which may choose to ignore it. | |
|
|
use_pty=bool | set_utmp=bool |
Allocate a pseudo-tty to run the command in, regardless of | Create a utmp (or utmpx) entry when a pseudo-tty is |
whether or not I/O logging is in use. By default, ssuuddoo | allocated. By default, the new entry will be a copy of |
will only run the command in a pty when an I/O log plugin | the user's existing utmp entry (if any), with the tty, |
is loaded. | time, type and pid fields updated. |
|
|
set_utmp=bool | sudoedit=bool |
Create a utmp (or utmpx) entry when a pseudo-tty is | Set to true when in _s_u_d_o_e_d_i_t mode. The plugin may |
allocated. By default, the new entry will be a copy of the | enable _s_u_d_o_e_d_i_t mode even if ssuuddoo was not invoked as |
user's existing utmp entry (if any), with the tty, time, | ssuuddooeeddiitt. This allows the plugin to perform command |
type and pid fields updated. | substitution and transparently enable _s_u_d_o_e_d_i_t when the |
| user attempts to run an editor. |
|
|
utmp_user=string | timeout=int |
User name to use when constructing a new utmp (or utmpx) | Command timeout. If non-zero then when the timeout |
entry when _s_e_t___u_t_m_p is enabled. This option can be used to | expires the command will be killed. |
set the user field in the utmp entry to the user the | |
command runs as rather than the invoking user. If not set, | |
ssuuddoo will base the new entry on the invoking user's | |
existing entry. | |
|
|
Unsupported values will be ignored. | umask=octal |
| The file creation mask to use when executing the |
| command. |
|
|
|
use_pty=bool |
|
Allocate a pseudo-tty to run the command in, regardless |
|
of whether or not I/O logging is in use. By default, |
|
ssuuddoo will only run the command in a pty when an I/O log |
|
plugin is loaded. |
|
|
|
utmp_user=string |
|
User name to use when constructing a new utmp (or |
|
utmpx) entry when _s_e_t___u_t_m_p is enabled. This option can |
|
be used to set the user field in the utmp entry to the |
|
user the command runs as rather than the invoking user. |
|
If not set, ssuuddoo will base the new entry on the |
|
invoking user's existing entry. |
|
|
|
Unsupported values will be ignored. |
|
|
argv_out |
argv_out |
The NULL-terminated argument vector to pass to the _e_x_e_c_v_e_(_) | The NULL-terminated argument vector to pass to the execve(2) |
system call when executing the command. The plugin is | system call when executing the command. The plugin is |
responsible for allocating and populating the vector. | responsible for allocating and populating the vector. |
|
|
user_env_out |
user_env_out |
The NULL-terminated environment vector to use when executing | The NULL-terminated environment vector to use when executing |
the command. The plugin is responsible for allocating and | the command. The plugin is responsible for allocating and |
populating the vector. | populating the vector. |
|
|
list | list |
int (*list)(int verbose, const char *list_user, | int (*list)(int verbose, const char *list_user, |
int argc, char * const argv[]); | int argc, char * const argv[]); |
|
|
List available privileges for the invoking user. Returns 1 on |
List available privileges for the invoking user. Returns 1 on |
success, 0 on failure and -1 on error. On error, the plugin may |
success, 0 on failure and -1 on error. On error, the plugin may |
optionally call the conversation or plugin_printf function with | optionally call the ccoonnvveerrssaattiioonn() or pplluuggiinn__pprriinnttff() function with |
SUDO_CONF_ERROR_MSG to present additional error information to the |
SUDO_CONF_ERROR_MSG to present additional error information to the |
user. |
user. |
|
|
Privileges should be output via the conversation or plugin_printf | Privileges should be output via the ccoonnvveerrssaattiioonn() or |
function using SUDO_CONV_INFO_MSG. | pplluuggiinn__pprriinnttff() function using SUDO_CONV_INFO_MSG, |
|
|
verbose |
verbose |
Flag indicating whether to list in verbose mode or not. | Flag indicating whether to list in verbose mode or not. |
|
|
list_user |
list_user |
The name of a different user to list privileges for if the | The name of a different user to list privileges for if the |
policy allows it. If NULL, the plugin should list the | policy allows it. If NULL, the plugin should list the |
privileges of the invoking user. | privileges of the invoking user. |
|
|
argc | argc The number of elements in _a_r_g_v, not counting the final NULL |
The number of elements in _a_r_g_v, not counting the final NULL | pointer. |
pointer. | |
|
|
argv | argv If non-NULL, an argument vector describing a command the user |
If non-NULL, an argument vector describing a command the user | wishes to check against the policy in the same form as what |
wishes to check against the policy in the same form as what | would be passed to the execve(2) system call. If the command |
would be passed to the _e_x_e_c_v_e_(_) system call. If the command is | is permitted by the policy, the fully-qualified path to the |
permitted by the policy, the fully-qualified path to the | command should be displayed along with any command line |
command should be displayed along with any command line | arguments. |
arguments. | |
|
|
validate | validate |
int (*validate)(void); | int (*validate)(void); |
|
|
The validate function is called when ssuuddoo is run with the -v flag. | The vvaalliiddaattee() function is called when ssuuddoo is run with the --vv |
For policy plugins such as _s_u_d_o_e_r_s that cache authentication | flag. For policy plugins such as ssuuddooeerrss that cache authentication |
credentials, this function will validate and cache the credentials. |
credentials, this function will validate and cache the credentials. |
|
|
The validate function should be NULL if the plugin does not support | The vvaalliiddaattee() function should be NULL if the plugin does not |
credential caching. | support credential caching. |
|
|
Returns 1 on success, 0 on failure and -1 on error. On error, the |
Returns 1 on success, 0 on failure and -1 on error. On error, the |
plugin may optionally call the conversation or plugin_printf | plugin may optionally call the ccoonnvveerrssaattiioonn() or pplluuggiinn__pprriinnttff() |
function with SUDO_CONF_ERROR_MSG to present additional error |
function with SUDO_CONF_ERROR_MSG to present additional error |
information to the user. |
information to the user. |
|
|
invalidate | invalidate |
void (*invalidate)(int remove); | void (*invalidate)(int remove); |
|
|
The invalidate function is called when ssuuddoo is called with the -k | The iinnvvaalliiddaattee() function is called when ssuuddoo is called with the --kk |
or -K flag. For policy plugins such as _s_u_d_o_e_r_s that cache | or --KK flag. For policy plugins such as ssuuddooeerrss that cache |
authentication credentials, this function will invalidate the |
authentication credentials, this function will invalidate the |
credentials. If the _r_e_m_o_v_e flag is set, the plugin may remove the |
credentials. If the _r_e_m_o_v_e flag is set, the plugin may remove the |
credentials instead of simply invalidating them. |
credentials instead of simply invalidating them. |
|
|
The invalidate function should be NULL if the plugin does not | The iinnvvaalliiddaattee() function should be NULL if the plugin does not |
support credential caching. |
support credential caching. |
|
|
init_session | init_session |
int (*init_session)(struct passwd *pwd); | int (*init_session)(struct passwd *pwd, char **user_envp[); |
|
|
The init_session function is called when ssuuddoo sets up the execution | The iinniitt__sseessssiioonn() function is called before ssuuddoo sets up the |
environment for the command, immediately before the contents of the | execution environment for the command. It is run in the parent |
_c_o_m_m_a_n_d___i_n_f_o list are applied (before the uid changes). This can | ssuuddoo process and before any uid or gid changes. This can be used |
be used to do session setup that is not supported by _c_o_m_m_a_n_d___i_n_f_o, | to perform session setup that is not supported by _c_o_m_m_a_n_d___i_n_f_o, |
such as opening the PAM session. | such as opening the PAM session. The cclloossee() function can be used |
| to tear down the session that was opened by init_session. |
|
|
The _p_w_d argument points to a passwd struct for the user the command |
The _p_w_d argument points to a passwd struct for the user the command |
will be run as if the uid the command will run as was found in the |
will be run as if the uid the command will run as was found in the |
password database, otherwise it will be NULL. |
password database, otherwise it will be NULL. |
|
|
|
The _u_s_e_r___e_n_v argument points to the environment the command will |
|
run in, in the form of a NULL-terminated vector of ``name=value'' |
|
strings. This is the same string passed back to the front end via |
|
the Policy Plugin's _u_s_e_r___e_n_v___o_u_t parameter. If the iinniitt__sseessssiioonn() |
|
function needs to modify the user environment, it should update the |
|
pointer stored in _u_s_e_r___e_n_v. The expected use case is to merge the |
|
contents of the PAM environment (if any) with the contents of |
|
_u_s_e_r___e_n_v. NOTE: the _u_s_e_r___e_n_v parameter is only available starting |
|
with API version 1.2. A plugin mmuusstt check the API version |
|
specified by the ssuuddoo front end before using _u_s_e_r___e_n_v. Failure to |
|
do so may result in a crash. |
|
|
Returns 1 on success, 0 on failure and -1 on error. On error, the |
Returns 1 on success, 0 on failure and -1 on error. On error, the |
plugin may optionally call the conversation or plugin_printf | plugin may optionally call the ccoonnvveerrssaattiioonn() or pplluuggiinn__pprriinnttff() |
function with SUDO_CONF_ERROR_MSG to present additional error |
function with SUDO_CONF_ERROR_MSG to present additional error |
information to the user. |
information to the user. |
|
|
_V_e_r_s_i_o_n _m_a_c_r_o_s | register_hooks |
| void (*register_hooks)(int version, |
| int (*register_hook)(struct sudo_hook *hook)); |
|
|
#define SUDO_API_VERSION_GET_MAJOR(v) ((v) >> 16) | The rreeggiisstteerr__hhooookkss() function is called by the sudo front end to |
#define SUDO_API_VERSION_GET_MINOR(v) ((v) & 0xffff) | register any hooks the plugin needs. If the plugin does not |
#define SUDO_API_VERSION_SET_MAJOR(vp, n) do { \ | support hooks, register_hooks should be set to the NULL pointer. |
*(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \ | |
} while(0) | |
#define SUDO_VERSION_SET_MINOR(vp, n) do { \ | |
*(vp) = (*(vp) & 0xffff0000) | (n); \ | |
} while(0) | |
|
|
#define SUDO_API_VERSION_MAJOR 1 | The _v_e_r_s_i_o_n argument describes the version of the hooks API |
#define SUDO_API_VERSION_MINOR 0 | supported by the ssuuddoo front end. |
#define SUDO_API_VERSION ((SUDO_API_VERSION_MAJOR << 16) | \ | |
SUDO_API_VERSION_MINOR) | |
|
|
II//OO PPlluuggiinn AAPPII | The rreeggiisstteerr__hhooookk() function should be used to register any |
struct io_plugin { | supported hooks the plugin needs. It returns 0 on success, 1 if |
#define SUDO_IO_PLUGIN 2 | the hook type is not supported and -1 if the major version in |
unsigned int type; /* always SUDO_IO_PLUGIN */ | struct hook does not match the front end's major hook API version. |
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[], 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); | |
}; | |
|
|
When an I/O plugin is loaded, ssuuddoo runs the command in a pseudo-tty. | See the _H_o_o_k _f_u_n_c_t_i_o_n _A_P_I section below for more information about |
This makes it possible to log the input and output from the user's | hooks. |
session. If any of the standard input, standard output or standard | |
error do not correspond to a tty, ssuuddoo will open a pipe to capture the | |
I/O for logging before passing it on. | |
|
|
The log_ttyin function receives the raw user input from the terminal | NOTE: the rreeggiisstteerr__hhooookkss() function is only available starting with |
device (note that this will include input even when echo is disabled, | API version 1.2. If the ssuuddoo front end doesn't support API version |
such as when a password is read). The log_ttyout function receives | 1.2 or higher, register_hooks will not be called. |
output from the pseudo-tty that is suitable for replaying the user's | |
session at a later time. The log_stdin, log_stdout and log_stderr | |
functions are only called if the standard input, standard output or | |
standard error respectively correspond to something other than a tty. | |
|
|
Any of the logging functions may be set to the NULL pointer if no | deregister_hooks |
logging is to be performed. If the open function returns 0, no I/O | void (*deregister_hooks)(int version, |
will be sent to the plugin. | int (*deregister_hook)(struct sudo_hook *hook)); |
|
|
The io_plugin struct has the following fields: | The ddeerreeggiisstteerr__hhooookkss() function is called by the sudo front end to |
| deregister any hooks the plugin has registered. If the plugin does |
| not support hooks, deregister_hooks should be set to the NULL |
| pointer. |
|
|
type | The _v_e_r_s_i_o_n argument describes the version of the hooks API |
The type field should always be set to SUDO_IO_PLUGIN | supported by the ssuuddoo front end. |
|
|
version | The ddeerreeggiisstteerr__hhooookk() function should be used to deregister any |
| hooks that were put in place by the rreeggiisstteerr__hhooookk() function. If |
| the plugin tries to deregister a hook that the front end does not |
| support, deregister_hook will return an error. |
| |
| See the _H_o_o_k _f_u_n_c_t_i_o_n _A_P_I section below for more information about |
| hooks. |
| |
| NOTE: the ddeerreeggiisstteerr__hhooookkss() function is only available starting |
| with API version 1.2. If the ssuuddoo front end doesn't support API |
| version 1.2 or higher, deregister_hooks will not be called. |
| |
| _P_o_l_i_c_y _P_l_u_g_i_n _V_e_r_s_i_o_n _M_a_c_r_o_s |
| |
| /* Plugin API version major/minor. */ |
| #define SUDO_API_VERSION_MAJOR 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) |
| |
| /* Getters and setters for API version */ |
| #define SUDO_API_VERSION_GET_MAJOR(v) ((v) >> 16) |
| #define SUDO_API_VERSION_GET_MINOR(v) ((v) & 0xffff) |
| #define SUDO_API_VERSION_SET_MAJOR(vp, n) do { \ |
| *(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \ |
| } while(0) |
| #define SUDO_VERSION_SET_MINOR(vp, n) do { \ |
| *(vp) = (*(vp) & 0xffff0000) | (n); \ |
| } while(0) |
| |
| II//OO pplluuggiinn AAPPII |
| struct io_plugin { |
| #define SUDO_IO_PLUGIN 2 |
| unsigned int type; /* always SUDO_IO_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 command_info[], |
| int argc, char * const argv[], char * const user_env[], |
| char * const plugin_options[]); |
| 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); |
| void (*register_hooks)(int version, |
| int (*register_hook)(struct sudo_hook *hook)); |
| void (*deregister_hooks)(int version, |
| int (*deregister_hook)(struct sudo_hook *hook)); |
| }; |
| |
| When an I/O plugin is loaded, ssuuddoo runs the command in a pseudo-tty. |
| This makes it possible to log the input and output from the user's |
| session. If any of the standard input, standard output or standard error |
| do not correspond to a tty, ssuuddoo will open a pipe to capture the I/O for |
| logging before passing it on. |
| |
| The log_ttyin function receives the raw user input from the terminal |
| device (note that this will include input even when echo is disabled, |
| such as when a password is read). The log_ttyout function receives |
| output from the pseudo-tty that is suitable for replaying the user's |
| session at a later time. The lloogg__ssttddiinn(), lloogg__ssttddoouutt() and lloogg__ssttddeerrrr() |
| functions are only called if the standard input, standard output or |
| standard error respectively correspond to something other than a tty. |
| |
| Any of the logging functions may be set to the NULL pointer if no logging |
| is to be performed. If the open function returns 0, no I/O will be sent |
| to the plugin. |
| |
| The io_plugin struct has the following fields: |
| |
| type The type field should always be set to SUDO_IO_PLUGIN. |
| |
| version |
The version field should be set to SUDO_API_VERSION. |
The version field should be set to SUDO_API_VERSION. |
|
|
This allows ssuuddoo to determine the API version the plugin was built |
This allows ssuuddoo to determine the API version the plugin was built |
against. |
against. |
|
|
open | open |
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_options[]); |
|
|
The _o_p_e_n function is run before the _l_o_g___i_n_p_u_t, _l_o_g___o_u_t_p_u_t or | The ooppeenn() function is run before the lloogg__iinnppuutt(), lloogg__oouuttppuutt() or |
_s_h_o_w___v_e_r_s_i_o_n functions are called. It is only called if the | sshhooww__vveerrssiioonn() functions are called. It is only called if the |
version is being requested or the _c_h_e_c_k___p_o_l_i_c_y function has | version is being requested or the cchheecckk__ppoolliiccyy() function has |
returned successfully. It returns 1 on success, 0 on failure, -1 |
returned successfully. It returns 1 on success, 0 on failure, -1 |
if a general error occurred, or -2 if there was a usage error. In |
if a general error occurred, or -2 if there was a usage error. In |
the latter case, ssuuddoo will print a usage message before it exits. |
the latter case, ssuuddoo will print a usage message before it exits. |
If an error occurs, the plugin may optionally call the conversation | If an error occurs, the plugin may optionally call the |
or plugin_printf function with SUDO_CONF_ERROR_MSG to present | ccoonnvveerrssaattiioonn() or pplluuggiinn__pprriinnttff() function with SUDO_CONF_ERROR_MSG |
additional error information to the user. | to present additional error information to the user. |
|
|
The function arguments are as follows: |
The function arguments are as follows: |
|
|
version |
version |
The version passed in by ssuuddoo allows the plugin to determine | The version passed in by ssuuddoo allows the plugin to determine |
the major and minor version number of the plugin API supported | the major and minor version number of the plugin API |
by ssuuddoo. | supported by ssuuddoo. |
|
|
conversation |
conversation |
A pointer to the conversation function that may be used by the | A pointer to the ccoonnvveerrssaattiioonn() function that may be used by |
_s_h_o_w___v_e_r_s_i_o_n function to display version information (see | the sshhooww__vveerrssiioonn() function to display version information |
show_version below). The conversation function may also be | (see sshhooww__vveerrssiioonn() below). The ccoonnvveerrssaattiioonn() function may |
used to display additional error message to the user. The | also be used to display additional error message to the user. |
conversation function returns 0 on success and -1 on failure. | The ccoonnvveerrssaattiioonn() function returns 0 on success and -1 on |
| failure. |
|
|
plugin_printf |
plugin_printf |
A pointer to a printf-style function that may be used by the | A pointer to a pprriinnttff()-style function that may be used by |
_s_h_o_w___v_e_r_s_i_o_n function to display version information (see | the sshhooww__vveerrssiioonn() function to display version information |
show_version below). The plugin_printf function may also be | (see show_version below). The pplluuggiinn__pprriinnttff() function may |
used to display additional error message to the user. The | also be used to display additional error message to the user. |
plugin_printf function returns number of characters printed on | The pplluuggiinn__pprriinnttff() function returns number of characters |
success and -1 on failure. | printed on success and -1 on failure. |
|
|
settings |
settings |
A vector of user-supplied ssuuddoo settings in the form of | A vector of user-supplied ssuuddoo settings in the form of |
"name=value" strings. The vector is terminated by a NULL | ``name=value'' strings. The vector is terminated by a NULL |
pointer. These settings correspond to flags the user specified | pointer. These settings correspond to flags the user |
when running ssuuddoo. As such, they will only be present when the | specified when running ssuuddoo. As such, they will only be |
corresponding flag has been specified on the command line. | present when the corresponding flag has been specified on the |
| command line. |
|
|
When parsing _s_e_t_t_i_n_g_s, the plugin should split on the ffiirrsstt | When parsing _s_e_t_t_i_n_g_s, the plugin should split on the ffiirrsstt |
equal sign ('=') since the _n_a_m_e field will never include one | equal sign (`=') since the _n_a_m_e field will never include one |
itself but the _v_a_l_u_e might. | itself but the _v_a_l_u_e might. |
|
|
See the "Policy Plugin API" section for a list of all possible | See the _P_o_l_i_c_y _p_l_u_g_i_n _A_P_I section for a list of all possible |
settings. | settings. |
|
|
user_info |
user_info |
A vector of information about the user running the command in | A vector of information about the user running the command in |
the form of "name=value" strings. The vector is terminated by | the form of ``name=value'' strings. The vector is terminated |
a NULL pointer. | by a NULL pointer. |
|
|
When parsing _u_s_e_r___i_n_f_o, the plugin should split on the ffiirrsstt | When parsing _u_s_e_r___i_n_f_o, the plugin should split on the ffiirrsstt |
equal sign ('=') since the _n_a_m_e field will never include one | equal sign (`=') since the _n_a_m_e field will never include one |
itself but the _v_a_l_u_e might. | itself but the _v_a_l_u_e might. |
|
|
See the "Policy Plugin API" section for a list of all possible | See the _P_o_l_i_c_y _p_l_u_g_i_n _A_P_I section for a list of all possible |
strings. | strings. |
|
|
argc | argc The number of elements in _a_r_g_v, not counting the final NULL |
The number of elements in _a_r_g_v, not counting the final NULL | pointer. |
pointer. | |
|
|
argv | argv If non-NULL, an argument vector describing a command the user |
If non-NULL, an argument vector describing a command the user | wishes to run in the same form as what would be passed to the |
wishes to run in the same form as what would be passed to the | execve(2) system call. |
_e_x_e_c_v_e_(_) system call. | |
|
|
user_env |
user_env |
The user's environment in the form of a NULL-terminated vector | The user's environment in the form of a NULL-terminated |
of "name=value" strings. | vector of ``name=value'' strings. |
|
|
When parsing _u_s_e_r___e_n_v, the plugin should split on the ffiirrsstt | When parsing _u_s_e_r___e_n_v, the plugin should split on the ffiirrsstt |
equal sign ('=') since the _n_a_m_e field will never include one | equal sign (`=') since the _n_a_m_e field will never include one |
itself but the _v_a_l_u_e might. | itself but the _v_a_l_u_e might. |
|
|
close | plugin_options |
void (*close)(int exit_status, int error); | Any (non-comment) strings immediately after the plugin path |
| are treated as arguments to the plugin. These arguments are |
| split on a white space boundary and are passed to the plugin |
| in the form of a NULL-terminated array of strings. If no |
| arguments were specified, _p_l_u_g_i_n___o_p_t_i_o_n_s will be the NULL |
| pointer. |
|
|
The close function is called when the command being run by ssuuddoo | NOTE: the _p_l_u_g_i_n___o_p_t_i_o_n_s parameter is only available starting |
| with API version 1.2. A plugin mmuusstt check the API version |
| specified by the ssuuddoo front end before using _p_l_u_g_i_n___o_p_t_i_o_n_s. |
| Failure to do so may result in a crash. |
| |
| close |
| void (*close)(int exit_status, int error); |
| |
| The cclloossee() function is called when the command being run by ssuuddoo |
finishes. |
finishes. |
|
|
The function arguments are as follows: |
The function arguments are as follows: |
|
|
exit_status |
exit_status |
The command's exit status, as returned by the _w_a_i_t(2) system | The command's exit status, as returned by the wait(2) system |
call. The value of exit_status is undefined if error is non- | call. The value of exit_status is undefined if error is non- |
zero. | zero. |
|
|
error |
error |
If the command could not be executed, this is set to the value | If the command could not be executed, this is set to the |
of errno set by the _e_x_e_c_v_e(2) system call. If the command was | value of errno set by the execve(2) system call. If the |
successfully executed, the value of error is 0. | command was successfully executed, the value of error is 0. |
|
|
show_version | show_version |
int (*show_version)(int verbose); | int (*show_version)(int verbose); |
|
|
The show_version function is called by ssuuddoo when the user specifies | The sshhooww__vveerrssiioonn() function is called by ssuuddoo when the user |
the -V option. The plugin may display its version information to | specifies the --VV option. The plugin may display its version |
the user via the conversation or plugin_printf function using | information to the user via the ccoonnvveerrssaattiioonn() or pplluuggiinn__pprriinnttff() |
SUDO_CONV_INFO_MSG. If the user requests detailed version | function using SUDO_CONV_INFO_MSG. If the user requests detailed |
information, the verbose flag will be set. | version information, the verbose flag will be set. |
|
|
log_ttyin | log_ttyin |
int (*log_ttyin)(const char *buf, unsigned int len); | int (*log_ttyin)(const char *buf, unsigned int len); |
|
|
The _l_o_g___t_t_y_i_n function is called whenever data can be read from the | The lloogg__ttttyyiinn() function is called whenever data can be read from |
user but before it is passed to the running command. This allows | the user but before it is passed to the running command. This |
the plugin to reject data if it chooses to (for instance if the | allows the plugin to reject data if it chooses to (for instance if |
input contains banned content). Returns 1 if the data should be | the input contains banned content). Returns 1 if the data should |
passed to the command, 0 if the data is rejected (which will | be passed to the command, 0 if the data is rejected (which will |
terminate the command) or -1 if an error occurred. |
terminate the command) or -1 if an error occurred. |
|
|
The function arguments are as follows: |
The function arguments are as follows: |
|
|
buf The buffer containing user input. | buf The buffer containing user input. |
|
|
len The length of _b_u_f in bytes. | len The length of _b_u_f in bytes. |
|
|
log_ttyout | log_ttyout |
int (*log_ttyout)(const char *buf, unsigned int len); | int (*log_ttyout)(const char *buf, unsigned int len); |
|
|
The _l_o_g___t_t_y_o_u_t function is called whenever data can be read from | The lloogg__ttttyyoouutt() function is called whenever data can be read from |
the command but before it is written to the user's terminal. This |
the command but before it is written to the user's terminal. This |
allows the plugin to reject data if it chooses to (for instance if |
allows the plugin to reject data if it chooses to (for instance if |
the output contains banned content). Returns 1 if the data should |
the output contains banned content). Returns 1 if the data should |
Line 799 DDEESSCCRRIIPPTTIIOONN
|
Line 968 DDEESSCCRRIIPPTTIIOONN
|
|
|
The function arguments are as follows: |
The function arguments are as follows: |
|
|
buf The buffer containing command output. | buf The buffer containing command output. |
|
|
len The length of _b_u_f in bytes. | len The length of _b_u_f in bytes. |
|
|
log_stdin | log_stdin |
int (*log_stdin)(const char *buf, unsigned int len); | int (*log_stdin)(const char *buf, unsigned int len); |
|
|
The _l_o_g___s_t_d_i_n function is only used if the standard input does not | The lloogg__ssttddiinn() function is only used if the standard input does |
correspond to a tty device. It is called whenever data can be read | not correspond to a tty device. It is called whenever data can be |
from the standard input but before it is passed to the running | read from the standard input but before it is passed to the running |
command. This allows the plugin to reject data if it chooses to |
command. This allows the plugin to reject data if it chooses to |
(for instance if the input contains banned content). Returns 1 if |
(for instance if the input contains banned content). Returns 1 if |
the data should be passed to the command, 0 if the data is rejected |
the data should be passed to the command, 0 if the data is rejected |
Line 816 DDEESSCCRRIIPPTTIIOONN
|
Line 985 DDEESSCCRRIIPPTTIIOONN
|
|
|
The function arguments are as follows: |
The function arguments are as follows: |
|
|
buf The buffer containing user input. | buf The buffer containing user input. |
|
|
len The length of _b_u_f in bytes. | len The length of _b_u_f in bytes. |
|
|
log_stdout | log_stdout |
int (*log_stdout)(const char *buf, unsigned int len); | int (*log_stdout)(const char *buf, unsigned int len); |
|
|
The _l_o_g___s_t_d_o_u_t function is only used if the standard output does | The lloogg__ssttddoouutt() function is only used if the standard output does |
not correspond to a tty device. It is called whenever data can be |
not correspond to a tty device. It is called whenever data can be |
read from the command but before it is written to the standard |
read from the command but before it is written to the standard |
output. This allows the plugin to reject data if it chooses to |
output. This allows the plugin to reject data if it chooses to |
Line 833 DDEESSCCRRIIPPTTIIOONN
|
Line 1002 DDEESSCCRRIIPPTTIIOONN
|
|
|
The function arguments are as follows: |
The function arguments are as follows: |
|
|
buf The buffer containing command output. | buf The buffer containing command output. |
|
|
len The length of _b_u_f in bytes. | len The length of _b_u_f in bytes. |
|
|
log_stderr | log_stderr |
int (*log_stderr)(const char *buf, unsigned int len); | int (*log_stderr)(const char *buf, unsigned int len); |
|
|
The _l_o_g___s_t_d_e_r_r function is only used if the standard error does not | The lloogg__ssttddeerrrr() function is only used if the standard error does |
correspond to a tty device. It is called whenever data can be read | not correspond to a tty device. It is called whenever data can be |
from the command but before it is written to the standard error. | read from the command but before it is written to the standard |
This allows the plugin to reject data if it chooses to (for | error. This allows the plugin to reject data if it chooses to (for |
instance if the output contains banned content). Returns 1 if the |
instance if the output contains banned content). Returns 1 if the |
data should be passed to the user, 0 if the data is rejected (which |
data should be passed to the user, 0 if the data is rejected (which |
will terminate the command) or -1 if an error occurred. |
will terminate the command) or -1 if an error occurred. |
|
|
The function arguments are as follows: |
The function arguments are as follows: |
|
|
buf The buffer containing command output. | buf The buffer containing command output. |
|
|
len The length of _b_u_f in bytes. | len The length of _b_u_f in bytes. |
|
|
_V_e_r_s_i_o_n _m_a_c_r_o_s | register_hooks |
| See the _P_o_l_i_c_y _p_l_u_g_i_n _A_P_I section for a description of |
| register_hooks. |
|
|
Same as for the "Policy Plugin API". | deregister_hooks |
| See the _P_o_l_i_c_y _p_l_u_g_i_n _A_P_I section for a description of |
| deregister_hooks. |
|
|
|
_I_/_O _P_l_u_g_i_n _V_e_r_s_i_o_n _M_a_c_r_o_s |
|
|
|
Same as for the _P_o_l_i_c_y _p_l_u_g_i_n _A_P_I. |
|
|
|
SSiiggnnaall hhaannddlleerrss |
|
The ssuuddoo front end installs default signal handlers to trap common |
|
signals while the plugin functions are run. The following signals are |
|
trapped by default before the command is executed: |
|
|
|
oo SIGALRM |
|
oo SIGHUP |
|
oo SIGINT |
|
oo SIGQUIT |
|
oo SIGTERM |
|
oo SIGTSTP |
|
oo SIGUSR1 |
|
oo SIGUSR2 |
|
|
|
If a fatal signal is received before the command is executed, ssuuddoo will |
|
call the plugin's cclloossee() function with an exit status of 128 plus the |
|
value of the signal that was received. This allows for consistent |
|
logging of commands killed by a signal for plugins that log such |
|
information in their cclloossee() function. |
|
|
|
A plugin may temporarily install its own signal handlers but must restore |
|
the original handler before the plugin function returns. |
|
|
|
HHooookk ffuunnccttiioonn AAPPII |
|
Beginning with plugin API version 1.2, it is possible to install hooks |
|
for certain functions called by the ssuuddoo front end. |
|
|
|
Currently, the only supported hooks relate to the handling of environment |
|
variables. Hooks can be used to intercept attempts to get, set, or |
|
remove environment variables so that these changes can be reflected in |
|
the version of the environment that is used to execute a command. A |
|
future version of the API will support hooking internal ssuuddoo front end |
|
functions as well. |
|
|
|
_H_o_o_k _s_t_r_u_c_t_u_r_e |
|
|
|
Hooks in ssuuddoo are described by the following structure: |
|
|
|
typedef int (*sudo_hook_fn_t)(); |
|
|
|
struct sudo_hook { |
|
int hook_version; |
|
int hook_type; |
|
sudo_hook_fn_t hook_fn; |
|
void *closure; |
|
}; |
|
|
|
The sudo_hook structure has the following fields: |
|
|
|
hook_version |
|
The hook_version field should be set to SUDO_HOOK_VERSION. |
|
|
|
hook_type |
|
The hook_type field may be one of the following supported hook |
|
types: |
|
|
|
SUDO_HOOK_SETENV |
|
The C library setenv(3) function. Any registered hooks will |
|
run before the C library implementation. The hook_fn field |
|
should be a function that matches the following typedef: |
|
|
|
typedef int (*sudo_hook_fn_setenv_t)(const char *name, |
|
const char *value, int overwrite, void *closure); |
|
|
|
If the registered hook does not match the typedef the results |
|
are unspecified. |
|
|
|
SUDO_HOOK_UNSETENV |
|
The C library unsetenv(3) function. Any registered hooks |
|
will run before the C library implementation. The hook_fn |
|
field should be a function that matches the following |
|
typedef: |
|
|
|
typedef int (*sudo_hook_fn_unsetenv_t)(const char *name, |
|
void *closure); |
|
|
|
SUDO_HOOK_GETENV |
|
The C library getenv(3) function. Any registered hooks will |
|
run before the C library implementation. The hook_fn field |
|
should be a function that matches the following typedef: |
|
|
|
typedef int (*sudo_hook_fn_getenv_t)(const char *name, |
|
char **value, void *closure); |
|
|
|
If the registered hook does not match the typedef the results |
|
are unspecified. |
|
|
|
SUDO_HOOK_PUTENV |
|
The C library putenv(3) function. Any registered hooks will |
|
run before the C library implementation. The hook_fn field |
|
should be a function that matches the following typedef: |
|
|
|
typedef int (*sudo_hook_fn_putenv_t)(char *string, |
|
void *closure); |
|
|
|
If the registered hook does not match the typedef the results |
|
are unspecified. |
|
|
|
hook_fn |
|
sudo_hook_fn_t hook_fn; |
|
|
|
The hook_fn field should be set to the plugin's hook |
|
implementation. The actual function arguments will vary depending |
|
on the hook_type (see hook_type above). In all cases, the closure |
|
field of struct sudo_hook is passed as the last function parameter. |
|
This can be used to pass arbitrary data to the plugin's hook |
|
implementation. |
|
|
|
The function return value may be one of the following: |
|
|
|
SUDO_HOOK_RET_ERROR |
|
The hook function encountered an error. |
|
|
|
SUDO_HOOK_RET_NEXT |
|
The hook completed without error, go on to the next hook |
|
(including the native implementation if applicable). For |
|
example, a getenv(3) hook might return SUDO_HOOK_RET_NEXT if |
|
the specified variable was not found in the private copy of |
|
the environment. |
|
|
|
SUDO_HOOK_RET_STOP |
|
The hook completed without error, stop processing hooks for |
|
this invocation. This can be used to replace the native |
|
implementation. For example, a setenv hook that operates on |
|
a private copy of the environment but leaves environ |
|
unchanged. |
|
|
|
Note that it is very easy to create an infinite loop when hooking C |
|
library functions. For example, a getenv(3) hook that calls the |
|
snprintf(3) function may create a loop if the snprintf(3) implementation |
|
calls getenv(3) to check the locale. To prevent this, you may wish to |
|
use a static variable in the hook function to guard against nested calls. |
|
For example: |
|
|
|
static int in_progress = 0; /* avoid recursion */ |
|
if (in_progress) |
|
return SUDO_HOOK_RET_NEXT; |
|
in_progress = 1; |
|
... |
|
in_progress = 0; |
|
return SUDO_HOOK_RET_STOP; |
|
|
|
_H_o_o_k _A_P_I _V_e_r_s_i_o_n _M_a_c_r_o_s |
|
|
|
/* Hook API version major/minor */ |
|
#define SUDO_HOOK_VERSION_MAJOR 1 |
|
#define SUDO_HOOK_VERSION_MINOR 0 |
|
#define SUDO_HOOK_MKVERSION(x, y) ((x << 16) | y) |
|
#define SUDO_HOOK_VERSION SUDO_HOOK_MKVERSION(SUDO_HOOK_VERSION_MAJOR,\ |
|
SUDO_HOOK_VERSION_MINOR) |
|
|
|
/* Getters and setters for hook API version */ |
|
#define SUDO_HOOK_VERSION_GET_MAJOR(v) ((v) >> 16) |
|
#define SUDO_HOOK_VERSION_GET_MINOR(v) ((v) & 0xffff) |
|
#define SUDO_HOOK_VERSION_SET_MAJOR(vp, n) do { \ |
|
*(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \ |
|
} while(0) |
|
#define SUDO_HOOK_VERSION_SET_MINOR(vp, n) do { \ |
|
*(vp) = (*(vp) & 0xffff0000) | (n); \ |
|
} while(0) |
|
|
CCoonnvveerrssaattiioonn AAPPII |
CCoonnvveerrssaattiioonn AAPPII |
If the plugin needs to interact with the user, it may do so via the | If the plugin needs to interact with the user, it may do so via the |
conversation function. A plugin should not attempt to read directly | ccoonnvveerrssaattiioonn() function. A plugin should not attempt to read directly |
from the standard input or the user's tty (neither of which are | from the standard input or the user's tty (neither of which are |
guaranteed to exist). The caller must include a trailing newline in | guaranteed to exist). The caller must include a trailing newline in msg |
msg if one is to be printed. | if one is to be printed. |
|
|
A printf-style function is also available that can be used to display | A pprriinnttff()-style function is also available that can be used to display |
informational or error messages to the user, which is usually more | informational or error messages to the user, which is usually more |
convenient for simple messages where no use input is required. | convenient for simple messages where no use input is required. |
|
|
struct sudo_conv_message { | struct sudo_conv_message { |
#define SUDO_CONV_PROMPT_ECHO_OFF 0x0001 /* do not echo user input */ | #define SUDO_CONV_PROMPT_ECHO_OFF 0x0001 /* do not echo user input */ |
#define SUDO_CONV_PROMPT_ECHO_ON 0x0002 /* echo user input */ | #define SUDO_CONV_PROMPT_ECHO_ON 0x0002 /* echo user input */ |
#define SUDO_CONV_ERROR_MSG 0x0003 /* error message */ | #define SUDO_CONV_ERROR_MSG 0x0003 /* error message */ |
#define SUDO_CONV_INFO_MSG 0x0004 /* informational message */ | #define SUDO_CONV_INFO_MSG 0x0004 /* informational message */ |
#define SUDO_CONV_PROMPT_MASK 0x0005 /* mask user input */ | #define SUDO_CONV_PROMPT_MASK 0x0005 /* mask user input */ |
#define SUDO_CONV_PROMPT_ECHO_OK 0x1000 /* flag: allow echo if no tty */ | #define SUDO_CONV_DEBUG_MSG 0x0006 /* debugging message */ |
int msg_type; | #define SUDO_CONV_PROMPT_ECHO_OK 0x1000 /* flag: allow echo if no tty */ |
int timeout; | int msg_type; |
const char *msg; | int timeout; |
}; | const char *msg; |
| }; |
|
|
struct sudo_conv_reply { | struct sudo_conv_reply { |
char *reply; | char *reply; |
}; | }; |
|
|
typedef int (*sudo_conv_t)(int num_msgs, | typedef int (*sudo_conv_t)(int num_msgs, |
const struct sudo_conv_message msgs[], | const struct sudo_conv_message msgs[], |
struct sudo_conv_reply replies[]); | struct sudo_conv_reply replies[]); |
|
|
typedef int (*sudo_printf_t)(int msg_type, const char *fmt, ...); | typedef int (*sudo_printf_t)(int msg_type, const char *fmt, ...); |
|
|
Pointers to the conversation and printf-style functions are passed in | Pointers to the ccoonnvveerrssaattiioonn() and pprriinnttff()-style functions are passed in |
to the plugin's open function when the plugin is initialized. | to the plugin's ooppeenn() function when the plugin is initialized. |
|
|
To use the conversation function, the plugin must pass an array of | To use the ccoonnvveerrssaattiioonn() function, the plugin must pass an array of |
sudo_conv_message and sudo_conv_reply structures. There must be a | sudo_conv_message and sudo_conv_reply structures. There must be a struct |
struct sudo_conv_message and struct sudo_conv_reply for each message in | sudo_conv_message and struct sudo_conv_reply for each message in the |
the conversation. The plugin is responsible for freeing the reply | conversation. The plugin is responsible for freeing the reply buffer |
buffer filled in to the struct sudo_conv_reply, if any. | filled in to the struct sudo_conv_reply, if any. |
|
|
The printf-style function uses the same underlying mechanism as the | The pprriinnttff()-style function uses the same underlying mechanism as the |
conversation function but only supports SUDO_CONV_INFO_MSG and | ccoonnvveerrssaattiioonn() function but only supports SUDO_CONV_INFO_MSG, |
SUDO_CONV_ERROR_MSG for the _m_s_g___t_y_p_e parameter. It can be more | SUDO_CONV_ERROR_MSG and SUDO_CONV_DEBUG_MSG for the _m_s_g___t_y_p_e parameter. |
convenient than using the conversation function if no user reply is | It can be more convenient than using the ccoonnvveerrssaattiioonn() function if no |
needed and supports standard _p_r_i_n_t_f_(_) escape sequences. | user reply is needed and supports standard pprriinnttff() escape sequences. |
|
|
See the sample plugin for an example of the conversation function | Unlike, SUDO_CONV_INFO_MSG and Dv SUDO_CONV_ERROR_MSG , messages sent |
usage. | with the SUDO_CONV_DEBUG_MSG _m_s_g___t_y_p_e are not directly user-visible. |
| Instead, they are logged to the file specified in the Debug statement (if |
| any) in the sudo.conf(4). file. This allows a plugin to log debugging |
| information and is intended to be used in conjunction with the |
| _d_e_b_u_g___f_l_a_g_s setting. |
|
|
SSuuddooeerrss GGrroouupp PPlluuggiinn AAPPII | See the sample plugin for an example of the ccoonnvveerrssaattiioonn() function |
The _s_u_d_o_e_r_s module supports a plugin interface to allow non-Unix group | usage. |
lookups. This can be used to query a group source other than the | |
standard Unix group database. A sample group plugin is bundled with | |
ssuuddoo that implements file-based lookups. Third party group plugins | |
include a QAS AD plugin available from Quest Software. | |
|
|
A group plugin must declare and populate a sudoers_group_plugin struct | SSuuddooeerrss ggrroouupp pplluuggiinn AAPPII |
in the global scope. This structure contains pointers to the functions | The ssuuddooeerrss plugin supports its own plugin interface to allow non-Unix |
that implement plugin initialization, cleanup and group lookup. | group lookups. This can be used to query a group source other than the |
| standard Unix group database. Two sample group plugins are bundled with |
| ssuuddoo, _g_r_o_u_p___f_i_l_e and _s_y_s_t_e_m___g_r_o_u_p, are detailed in sudoers(4). Third |
| party group plugins include a QAS AD plugin available from Quest |
| Software. |
|
|
struct sudoers_group_plugin { | A group plugin must declare and populate a sudoers_group_plugin struct in |
unsigned int version; | the global scope. This structure contains pointers to the functions that |
int (*init)(int version, sudo_printf_t sudo_printf, | implement plugin initialization, cleanup and group lookup. |
char *const argv[]); | |
void (*cleanup)(void); | |
int (*query)(const char *user, const char *group, | |
const struct passwd *pwd); | |
}; | |
|
|
The sudoers_group_plugin struct has the following fields: | struct sudoers_group_plugin { |
| unsigned int version; |
| int (*init)(int version, sudo_printf_t sudo_printf, |
| char *const argv[]); |
| void (*cleanup)(void); |
| int (*query)(const char *user, const char *group, |
| const struct passwd *pwd); |
| }; |
|
|
version | The sudoers_group_plugin struct has the following fields: |
| |
| version |
The version field should be set to GROUP_API_VERSION. |
The version field should be set to GROUP_API_VERSION. |
|
|
This allows _s_u_d_o_e_r_s to determine the API version the group plugin | This allows ssuuddooeerrss to determine the API version the group plugin |
was built against. |
was built against. |
|
|
init | init |
int (*init)(int version, sudo_printf_t plugin_printf, | int (*init)(int version, sudo_printf_t plugin_printf, |
char *const argv[]); | char *const argv[]); |
|
|
The _i_n_i_t function is called after _s_u_d_o_e_r_s has been parsed but | The iinniitt() function is called after _s_u_d_o_e_r_s has been parsed but |
before any policy checks. It returns 1 on success, 0 on failure |
before any policy checks. It returns 1 on success, 0 on failure |
(or if the plugin is not configured), and -1 if a error occurred. |
(or if the plugin is not configured), and -1 if a error occurred. |
If an error occurs, the plugin may call the plugin_printf function | If an error occurs, the plugin may call the pplluuggiinn__pprriinnttff() |
with SUDO_CONF_ERROR_MSG to present additional error information to | function with SUDO_CONF_ERROR_MSG to present additional error |
the user. | information to the user. |
|
|
The function arguments are as follows: |
The function arguments are as follows: |
|
|
version |
version |
The version passed in by _s_u_d_o_e_r_s allows the plugin to determine | The version passed in by ssuuddooeerrss allows the plugin to |
the major and minor version number of the group plugin API | determine the major and minor version number of the group |
supported by _s_u_d_o_e_r_s. | plugin API supported by ssuuddooeerrss. |
|
|
plugin_printf |
plugin_printf |
A pointer to a printf-style function that may be used to | A pointer to a pprriinnttff()-style function that may be used to |
display informational or error message to the user. Returns | display informational or error message to the user. Returns |
the number of characters printed on success and -1 on failure. | the number of characters printed on success and -1 on |
| failure. |
|
|
argv | argv A NULL-terminated array of arguments generated from the |
A NULL-terminated array of arguments generated from the | _g_r_o_u_p___p_l_u_g_i_n option in _s_u_d_o_e_r_s. If no arguments were given, |
_g_r_o_u_p___p_l_u_g_i_n option in _s_u_d_o_e_r_s. If no arguments were given, | _a_r_g_v will be NULL. |
_a_r_g_v will be NULL. | |
|
|
cleanup | cleanup |
void (*cleanup)(); | void (*cleanup)(); |
|
|
The _c_l_e_a_n_u_p function is called when _s_u_d_o_e_r_s has finished its group | The cclleeaannuupp() function is called when ssuuddooeerrss has finished its |
checks. The plugin should free any memory it has allocated and | group checks. The plugin should free any memory it has allocated |
close open file handles. | and close open file handles. |
|
|
query | query |
int (*query)(const char *user, const char *group, | int (*query)(const char *user, const char *group, |
const struct passwd *pwd); | const struct passwd *pwd); |
|
|
The _q_u_e_r_y function is used to ask the group plugin whether _u_s_e_r is | The qquueerryy() function is used to ask the group plugin whether _u_s_e_r |
a member of _g_r_o_u_p. | is a member of _g_r_o_u_p. |
|
|
The function arguments are as follows: |
The function arguments are as follows: |
|
|
user | user The name of the user being looked up in the external group |
The name of the user being looked up in the external group | database. |
database. | |
|
|
group |
group |
The name of the group being queried. | The name of the group being queried. |
|
|
pwd The password database entry for _u_s_e_r, if any. If _u_s_e_r is not | pwd The password database entry for _u_s_e_r, if any. If _u_s_e_r is not |
present in the password database, _p_w_d will be NULL. | present in the password database, _p_w_d will be NULL. |
|
|
_V_e_r_s_i_o_n _M_a_c_r_o_s | _G_r_o_u_p _A_P_I _V_e_r_s_i_o_n _M_a_c_r_o_s |
|
|
/* Sudoers group plugin version major/minor */ | /* Sudoers group plugin version major/minor */ |
#define GROUP_API_VERSION_MAJOR 1 | #define GROUP_API_VERSION_MAJOR 1 |
#define GROUP_API_VERSION_MINOR 0 | #define GROUP_API_VERSION_MINOR 0 |
#define GROUP_API_VERSION ((GROUP_API_VERSION_MAJOR << 16) | \ | #define GROUP_API_VERSION ((GROUP_API_VERSION_MAJOR << 16) | \ |
GROUP_API_VERSION_MINOR) | GROUP_API_VERSION_MINOR) |
|
|
/* Getters and setters for group version */ | /* Getters and setters for group version */ |
#define GROUP_API_VERSION_GET_MAJOR(v) ((v) >> 16) | #define GROUP_API_VERSION_GET_MAJOR(v) ((v) >> 16) |
#define GROUP_API_VERSION_GET_MINOR(v) ((v) & 0xffff) | #define GROUP_API_VERSION_GET_MINOR(v) ((v) & 0xffff) |
#define GROUP_API_VERSION_SET_MAJOR(vp, n) do { \ | #define GROUP_API_VERSION_SET_MAJOR(vp, n) do { \ |
*(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \ | *(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \ |
} while(0) | } while(0) |
#define GROUP_API_VERSION_SET_MINOR(vp, n) do { \ | #define GROUP_API_VERSION_SET_MINOR(vp, n) do { \ |
*(vp) = (*(vp) & 0xffff0000) | (n); \ | *(vp) = (*(vp) & 0xffff0000) | (n); \ |
} while(0) | } while(0) |
|
|
|
PPLLUUGGIINN AAPPII CCHHAANNGGEELLOOGG |
|
The following revisions have been made to the Sudo Plugin API. |
|
|
|
Version 1.0 |
|
Initial API version. |
|
|
|
Version 1.1 (sudo 1.8.0) |
|
The I/O logging plugin's ooppeenn() function was modified to take the |
|
command_info list as an argument. |
|
|
|
Version 1.2 (sudo 1.8.5) |
|
The Policy and I/O logging plugins' ooppeenn() functions are now passed |
|
a list of plugin parameters if any are specified in sudo.conf(4). |
|
|
|
A simple hooks API has been introduced to allow plugins to hook in |
|
to the system's environment handling functions. |
|
|
|
The init_session Policy plugin function is now passed a pointer to |
|
the user environment which can be updated as needed. This can be |
|
used to merge in environment variables stored in the PAM handle |
|
before a command is run. |
|
|
|
Version 1.3 (sudo 1.8.7) |
|
Support for the _e_x_e_c___b_a_c_k_g_r_o_u_n_d entry has been added to the |
|
command_info list. |
|
|
|
The _m_a_x___g_r_o_u_p_s and _p_l_u_g_i_n___d_i_r entries were added to the settings |
|
list. |
|
|
|
The vveerrssiioonn() and cclloossee() functions are now optional. Previously, |
|
a missing vveerrssiioonn() or cclloossee() function would result in a crash. |
|
If no policy plugin cclloossee() function is defined, a default cclloossee() |
|
function will be provided by the ssuuddoo front end that displays a |
|
warning if the command could not be executed. |
|
|
|
The ssuuddoo front end now installs default signal handlers to trap |
|
common signals while the plugin functions are run. |
|
|
SSEEEE AALLSSOO |
SSEEEE AALLSSOO |
_s_u_d_o_e_r_s(4), _s_u_d_o(1m) | sudo.conf(4), sudoers(4), sudo(1m) |
|
|
BBUUGGSS |
BBUUGGSS |
If you feel you have found a bug in ssuuddoo, please submit a bug report at | If you feel you have found a bug in ssuuddoo, please submit a bug report at |
http://www.sudo.ws/sudo/bugs/ | http://www.sudo.ws/sudo/bugs/ |
|
|
SSUUPPPPOORRTT |
SSUUPPPPOORRTT |
Limited free support is available via the sudo-workers mailing list, | Limited free support is available via the sudo-users mailing list, see |
see http://www.sudo.ws/mailman/listinfo/sudo-workers to subscribe or | http://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or search the |
search the archives. | archives. |
|
|
DDIISSCCLLAAIIMMEERR |
DDIISSCCLLAAIIMMEERR |
ssuuddoo is provided ``AS IS'' and any express or implied warranties, | ssuuddoo is provided ``AS IS'' and any express or implied warranties, |
including, but not limited to, the implied warranties of | including, but not limited to, the implied warranties of merchantability |
merchantability and fitness for a particular purpose are disclaimed. | and fitness for a particular purpose are disclaimed. See the LICENSE |
See the LICENSE file distributed with ssuuddoo or | file distributed with ssuuddoo or http://www.sudo.ws/sudo/license.html for |
http://www.sudo.ws/sudo/license.html for complete details. | complete details. |
|
|
| Sudo 1.8.7 March 5, 2013 Sudo 1.8.7 |
| |
1.8.3 September 16, 2011 SUDO_PLUGIN(1m) | |