version 1.1, 2012/02/21 16:23:02
|
version 1.1.1.3, 2012/10/09 09:29:52
|
Line 1
|
Line 1
|
.\" Copyright (c) 2009-2011 Todd C. Miller <Todd.Miller@courtesan.com> | .\" DO NOT EDIT THIS FILE, IT IS NOT THE MASTER! |
.\" | .\" IT IS GENERATED AUTOMATICALLY FROM sudo_plugin.mdoc.in |
| .\" |
| .\" Copyright (c) 2009-2012 Todd C. Miller <Todd.Miller@courtesan.com> |
| .\" |
.\" Permission to use, copy, modify, and distribute this software for any |
.\" Permission to use, copy, modify, and distribute this software for any |
.\" purpose with or without fee is hereby granted, provided that the above |
.\" purpose with or without fee is hereby granted, provided that the above |
.\" copyright notice and this permission notice appear in all copies. |
.\" copyright notice and this permission notice appear in all copies. |
.\" | .\" |
.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
Line 12
|
Line 15
|
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
.\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
.\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
.\" |
|
.\" Automatically generated by Pod::Man 2.23 (Pod::Simple 3.14) |
|
.\" |
.\" |
.\" Standard preamble: | .TH "SUDO_PLUGIN" "5" "July 16, 2012" "Sudo @PACKAGE_VERSION@" "OpenBSD Programmer's Manual" |
.\" ======================================================================== | |
.de Sp \" Vertical space (when we can't use .PP) | |
.if t .sp .5v | |
.if n .sp | |
.. | |
.de Vb \" Begin verbatim text | |
.ft CW | |
.nf | |
.ne \\$1 | |
.. | |
.de Ve \" End verbatim text | |
.ft R | |
.fi | |
.. | |
.\" Set up some character translations and predefined strings. \*(-- will | |
.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left | |
.\" double quote, and \*(R" will give a right double quote. \*(C+ will | |
.\" give a nicer C++. Capital omega is used to do unbreakable dashes and | |
.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, | |
.\" nothing in troff, for use with C<>. | |
.tr \(*W- | |
.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' | |
.ie n \{\ | |
. ds -- \(*W- | |
. ds PI pi | |
. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch | |
. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch | |
. ds L" "" | |
. ds R" "" | |
. ds C` | |
. ds C' | |
'br\} | |
.el\{\ | |
. ds -- \|\(em\| | |
. ds PI \(*p | |
. ds L" `` | |
. ds R" '' | |
'br\} | |
.\" | |
.\" Escape single quotes in literal strings from groff's Unicode transform. | |
.ie \n(.g .ds Aq \(aq | |
.el .ds Aq ' | |
.\" | |
.\" If the F register is turned on, we'll generate index entries on stderr for | |
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index | |
.\" entries marked with X<> in POD. Of course, you'll have to process the | |
.\" output yourself in some meaningful fashion. | |
.ie \nF \{\ | |
. de IX | |
. tm Index:\\$1\t\\n%\t"\\$2" | |
.. | |
. nr % 0 | |
. rr F | |
.\} | |
.el \{\ | |
. de IX | |
.. | |
.\} | |
.\" | |
.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). | |
.\" Fear. Run. Save yourself. No user-serviceable parts. | |
. \" fudge factors for nroff and troff | |
.if n \{\ | |
. ds #H 0 | |
. ds #V .8m | |
. ds #F .3m | |
. ds #[ \f1 | |
. ds #] \fP | |
.\} | |
.if t \{\ | |
. ds #H ((1u-(\\\\n(.fu%2u))*.13m) | |
. ds #V .6m | |
. ds #F 0 | |
. ds #[ \& | |
. ds #] \& | |
.\} | |
. \" simple accents for nroff and troff | |
.if n \{\ | |
. ds ' \& | |
. ds ` \& | |
. ds ^ \& | |
. ds , \& | |
. ds ~ ~ | |
. ds / | |
.\} | |
.if t \{\ | |
. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" | |
. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' | |
. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' | |
. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' | |
. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' | |
. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' | |
.\} | |
. \" troff and (daisy-wheel) nroff accents | |
.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' | |
.ds 8 \h'\*(#H'\(*b\h'-\*(#H' | |
.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] | |
.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' | |
.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' | |
.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] | |
.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] | |
.ds ae a\h'-(\w'a'u*4/10)'e | |
.ds Ae A\h'-(\w'A'u*4/10)'E | |
. \" corrections for vroff | |
.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' | |
.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' | |
. \" for low resolution devices (crt and lpr) | |
.if \n(.H>23 .if \n(.V>19 \ | |
\{\ | |
. ds : e | |
. ds 8 ss | |
. ds o a | |
. ds d- d\h'-1'\(ga | |
. ds D- D\h'-1'\(hy | |
. ds th \o'bp' | |
. ds Th \o'LP' | |
. ds ae ae | |
. ds Ae AE | |
.\} | |
.rm #[ #] #H #V #F C | |
.\" ======================================================================== | |
.\" | |
.IX Title "SUDO_PLUGIN @mansectsu@" | |
.TH SUDO_PLUGIN @mansectsu@ "September 16, 2011" "1.8.3" "MAINTENANCE COMMANDS" | |
.\" For nroff, turn off justification. Always turn off hyphenation; it makes | |
.\" way too many mistakes in technical documents. | |
.if n .ad l | |
.nh |
.nh |
|
.if n .ad l |
.SH "NAME" |
.SH "NAME" |
sudo_plugin \- Sudo Plugin API | \fBsudo_plugin\fR |
| \- Sudo Plugin API |
.SH "DESCRIPTION" |
.SH "DESCRIPTION" |
.IX Header "DESCRIPTION" | Starting with version 1.8, |
Starting with version 1.8, \fBsudo\fR supports a plugin \s-1API\s0 | \fBsudo\fR |
for policy and session logging. By default, the \fIsudoers\fR policy | supports a plugin API |
plugin and an associated I/O logging plugin are used. Via the plugin | for policy and session logging. |
\&\s-1API\s0, \fBsudo\fR can be configured to use alternate policy and/or I/O | By default, the |
logging plugins provided by third parties. The plugins to be used | \fIsudoers\fR |
are specified via the \fI@sysconfdir@/sudo.conf\fR file. | policy plugin and an associated I/O logging plugin are used. |
| Via the plugin API, |
| \fBsudo\fR |
| can be configured to use alternate policy and/or I/O logging plugins |
| provided by third parties. |
| The plugins to be used are specified via the |
| \fI@sysconfdir@/sudo.conf\fR |
| file. |
.PP |
.PP |
The \s-1API\s0 is versioned with a major and minor number. The minor | The API is versioned with a major and minor number. |
version number is incremented when additions are made. The major | The minor version number is incremented when additions are made. |
number is incremented when incompatible changes are made. A plugin | The major number is incremented when incompatible changes are made. |
should be check the version passed to it and make sure that the | A plugin should be check the version passed to it and make sure that the |
major version matches. |
major version matches. |
.PP |
.PP |
The plugin \s-1API\s0 is defined by the \f(CW\*(C`sudo_plugin.h\*(C'\fR header file. | The plugin API is defined by the |
.SS "The sudo.conf File" | \fRsudo_plugin.h\fR |
.IX Subsection "The sudo.conf File" | header file. |
The \fI@sysconfdir@/sudo.conf\fR file contains plugin configuration directives. | .SS "The sudo.conf file" |
Currently, the only supported keyword is the \f(CW\*(C`Plugin\*(C'\fR directive, | The |
which causes a plugin plugin to be loaded. | \fI@sysconfdir@/sudo.conf\fR |
| file contains plugin configuration directives. |
| The primary keyword is the |
| \fRPlugin\fR |
| directive, which causes a plugin to be loaded. |
.PP |
.PP |
A \f(CW\*(C`Plugin\*(C'\fR line consists of the \f(CW\*(C`Plugin\*(C'\fR keyword, followed by the | A |
\&\fIsymbol_name\fR and the \fIpath\fR to the shared object containing the | \fRPlugin\fR |
plugin. The \fIsymbol_name\fR is the name of the \f(CW\*(C`struct policy_plugin\*(C'\fR | line consists of the |
or \f(CW\*(C`struct io_plugin\*(C'\fR in the plugin shared object. The \fIpath\fR | \fRPlugin\fR |
may be fully qualified or relative. If not fully qualified it is | keyword, followed by the |
relative to the \fI@prefix@/libexec\fR directory. Any additional | \fIsymbol_name\fR |
parameters after the \fIpath\fR are ignored. Lines that don't begin | and the |
with \f(CW\*(C`Plugin\*(C'\fR or \f(CW\*(C`Path\*(C'\fR are silently ignored. | \fIpath\fR |
| to the shared object containing the plugin. |
| The |
| \fIsymbol_name\fR |
| is the name of the |
| \fRstruct policy_plugin\fR |
| or |
| \fRstruct io_plugin\fR |
| in the plugin shared object. |
| The |
| \fIpath\fR |
| may be fully qualified or relative. |
| If not fully qualified it is relative to the |
| \fI@prefix@/libexec\fR |
| directory. |
| Any additional parameters after the |
| \fIpath\fR |
| are passed as options to the plugin's |
| \fBopen\fR() |
| function. |
| Lines that don't begin with |
| \fRPlugin\fR, |
| \fRPath\fR, |
| \fRDebug\fR |
| or |
| \fRSet\fR |
| are silently ignored. |
.PP |
.PP |
The same shared object may contain multiple plugins, each with a |
The same shared object may contain multiple plugins, each with a |
different symbol name. The shared object file must be owned by uid | different symbol name. |
0 and only writable by its owner. Because of ambiguities that arise | The shared object file must be owned by uid 0 and only writable by its owner. |
from composite policies, only a single policy plugin may be specified. | 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. |
This limitation does not apply to I/O plugins. |
|
.nf |
|
.sp |
|
.RS 0n |
|
# |
|
# Default @sysconfdir@/sudo.conf file |
|
# |
|
# Format: |
|
# Plugin plugin_name plugin_path plugin_options ... |
|
# Path askpass /path/to/askpass |
|
# Path noexec /path/to/sudo_noexec.so |
|
# Debug sudo /var/log/sudo_debug all@warn |
|
# Set disable_coredump true |
|
# |
|
# The plugin_path is relative to @prefix@/libexec unless |
|
# fully qualified. |
|
# The plugin_name corresponds to a global symbol in the plugin |
|
# that contains the plugin interface structure. |
|
# The plugin_options are optional. |
|
# |
|
Plugin sudoers_policy sudoers.so |
|
Plugin sudoers_io sudoers.so |
|
.RE |
|
.fi |
|
.SS "Policy plugin API" |
|
A policy plugin must declare and populate a |
|
\fRpolicy_plugin\fR |
|
struct in the global scope. |
|
This structure contains pointers to the functions that implement the |
|
\fBsudo\fR |
|
policy checks. |
|
The name of the symbol should be specified in |
|
\fI@sysconfdir@/sudo.conf\fR |
|
along with a path to the plugin so that |
|
\fBsudo\fR |
|
can load it. |
|
.nf |
|
.sp |
|
.RS 0n |
|
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[], |
|
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)); |
|
}; |
|
.RE |
|
.fi |
.PP |
.PP |
.Vb 10 |
|
\& # |
|
\& # Default @sysconfdir@/sudo.conf file |
|
\& # |
|
\& # Format: |
|
\& # Plugin plugin_name plugin_path |
|
\& # Path askpass /path/to/askpass |
|
\& # |
|
\& # The plugin_path is relative to @prefix@/libexec unless |
|
\& # fully qualified. |
|
\& # The plugin_name corresponds to a global symbol in the plugin |
|
\& # that contains the plugin interface structure. |
|
\& # |
|
\& Plugin sudoers_policy sudoers.so |
|
\& Plugin sudoers_io sudoers.so |
|
.Ve |
|
.SS "Policy Plugin \s-1API\s0" |
|
.IX Subsection "Policy Plugin API" |
|
A policy plugin must declare and populate a \f(CW\*(C`policy_plugin\*(C'\fR struct |
|
in the global scope. This structure contains pointers to the functions |
|
that implement the \fBsudo\fR policy checks. The name of the symbol should |
|
be specified in \fI@sysconfdir@/sudo.conf\fR along with a path to the plugin |
|
so that \fBsudo\fR can load it. |
|
.PP |
|
.Vb 10 |
|
\& 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); |
|
\& }; |
|
.Ve |
|
.PP |
|
The policy_plugin struct has the following fields: |
The policy_plugin struct has the following fields: |
.IP "type" 4 | .TP 6n |
.IX Item "type" | type |
The \f(CW\*(C`type\*(C'\fR field should always be set to \s-1SUDO_POLICY_PLUGIN\s0. | The |
.IP "version" 4 | \fRtype\fR |
.IX Item "version" | field should always be set to SUDO_POLICY_PLUGIN. |
The \f(CW\*(C`version\*(C'\fR field should be set to \s-1SUDO_API_VERSION\s0. | .TP 6n |
.Sp | version |
This allows \fBsudo\fR to determine the \s-1API\s0 version the plugin was | The |
| \fRversion\fR |
| field should be set to |
| \fRSUDO_API_VERSION\fR. |
| .sp |
| This allows |
| \fBsudo\fR |
| to determine the API version the plugin was |
built against. |
built against. |
.IP "open" 4 | .TP 6n |
.IX Item "open" | open |
.Vb 3 | .RS |
\& int (*open)(unsigned int version, sudo_conv_t conversation, | .nf |
\& sudo_printf_t plugin_printf, char * const settings[], | .RS 0n |
\& char * const user_info[], char * const user_env[]); | int (*open)(unsigned int version, sudo_conv_t conversation, |
.Ve | sudo_printf_t plugin_printf, char * const settings[], |
.Sp | char * const user_info[], char * const user_env[], |
| char * const plugin_options[]); |
| .RE |
| .fi |
| .sp |
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, \fBsudo\fR will | or \-2 if there was a usage error. |
print a usage message before it exits. If an error occurs, the | In the latter case, |
plugin may optionally call the conversation or plugin_printf function | \fBsudo\fR |
with \f(CW\*(C`SUDO_CONF_ERROR_MSG\*(C'\fR to present additional error information | will print a usage message before it exits. |
to the user. | If an error occurs, the plugin may optionally call the |
.Sp | \fBconversation\fR() |
| or |
| \fBplugin_printf\fR() |
| function with |
| \fRSUDO_CONF_ERROR_MSG\fR |
| to present additional error information to the user. |
| .sp |
The function arguments are as follows: |
The function arguments are as follows: |
.RS 4 | .TP 6n |
.IP "version" 4 | version |
.IX Item "version" | The version passed in by |
The version passed in by \fBsudo\fR allows the plugin to determine the | \fBsudo\fR |
major and minor version number of the plugin \s-1API\s0 supported by | allows the plugin to determine the |
\&\fBsudo\fR. | major and minor version number of the plugin API supported by |
.IP "conversation" 4 | \fBsudo\fR. |
.IX Item "conversation" | .TP 6n |
A pointer to the conversation function that can be used by the | conversation |
plugin to interact with the user (see below). | A pointer to the |
| \fBconversation\fR() |
| function that can be used by the plugin to interact with the user (see below). |
Returns 0 on success and \-1 on failure. |
Returns 0 on success and \-1 on failure. |
.IP "plugin_printf" 4 | .TP 6n |
.IX Item "plugin_printf" | plugin_printf |
A pointer to a printf-style function that may be used to display | A pointer to a |
informational or error messages (see below). | \fBprintf\fR()-style |
| function that may be used to display informational or error messages |
| (see below). |
Returns the number of characters printed on success and \-1 on failure. |
Returns the number of characters printed on success and \-1 on failure. |
.IP "settings" 4 | .TP 6n |
.IX Item "settings" | settings |
A vector of user-supplied \fBsudo\fR settings in the form of \*(L"name=value\*(R" | A vector of user-supplied |
strings. The vector is terminated by a \f(CW\*(C`NULL\*(C'\fR pointer. These | \fBsudo\fR |
settings correspond to flags the user specified when running \fBsudo\fR. | settings in the form of |
| ``name=value'' |
| strings. |
| The vector is terminated by a |
| \fRNULL\fR |
| pointer. |
| These settings correspond to flags the user specified when running |
| \fBsudo\fR. |
As such, they will only be present when the corresponding flag has |
As such, they will only be present when the corresponding flag has |
been specified on the command line. |
been specified on the command line. |
.Sp | .sp |
When parsing \fIsettings\fR, the plugin should split on the \fBfirst\fR | When parsing |
equal sign ('=') since the \fIname\fR field will never include one | \fIsettings\fR, |
itself but the \fIvalue\fR might. | the plugin should split on the |
.RS 4 | \fBfirst\fR |
.IP "debug_level=number" 4 | equal sign |
.IX Item "debug_level=number" | (`=') |
A numeric debug level, from 1\-9, if specified via the \f(CW\*(C`\-D\*(C'\fR flag. | since the |
.IP "runas_user=string" 4 | \fIname\fR |
.IX Item "runas_user=string" | field will never include one |
| itself but the |
| \fIvalue\fR |
| might. |
| .RS |
| .TP 6n |
| debug_flags=string |
| A comma-separated list of debug flags that correspond to |
| \fBsudo\fR's |
| \fRDebug\fR |
| entry in |
| \fI@sysconfdir@/sudo.conf\fR, |
| if there is one. |
| The flags are passed to the plugin as they appear in |
| \fI@sysconfdir@/sudo.conf\fR. |
| The syntax used by |
| \fBsudo\fR |
| and the |
| \fIsudoers\fR |
| plugin is |
| \fIsubsystem\fR@\fIpriority\fR |
| but the plugin is free to use a different |
| format so long as it does not include a comma |
| (`,\&'). |
| .sp |
| For reference, the priorities supported by the |
| \fBsudo\fR |
| front end and |
| \fIsudoers\fR |
| are: |
| \fIcrit\fR, |
| \fIerr\fR, |
| \fIwarn\fR, |
| \fInotice\fR, |
| \fIdiag\fR, |
| \fIinfo\fR, |
| \fItrace\fR |
| and |
| \fIdebug\fR. |
| .sp |
| The following subsystems are defined: |
| \fImain\fR, |
| \fImemory\fR, |
| \fIargs\fR, |
| \fIexec\fR, |
| \fIpty\fR, |
| \fIutmp\fR, |
| \fIconv\fR, |
| \fIpcomm\fR, |
| \fIutil\fR, |
| \fIlist\fR, |
| \fInetif\fR, |
| \fIaudit\fR, |
| \fIedit\fR, |
| \fIselinux\fR, |
| \fIldap\fR, |
| \fImatch\fR, |
| \fIparser\fR, |
| \fIalias\fR, |
| \fIdefaults\fR, |
| \fIauth\fR, |
| \fIenv\fR, |
| \fIlogging\fR, |
| \fInss\fR, |
| \fIrbtree\fR, |
| \fIperms\fR, |
| \fIplugin\fR. |
| The subsystem |
| \fIall\fR |
| includes every subsystem. |
| .sp |
| There is not currently a way to specify a set of debug flags specific |
| to the plugin--the flags are shared by |
| \fBsudo\fR |
| and the plugin. |
| .TP 6n |
| debug_level=number |
| This setting has been deprecated in favor of |
| \fIdebug_flags\fR. |
| .TP 6n |
| runas_user=string |
The user name or uid to to run the command as, if specified via the |
The user name or uid to to run the command as, if specified via the |
\&\f(CW\*(C`\-u\*(C'\fR flag. | \fB\-u\fR |
.IP "runas_group=string" 4 | flag. |
.IX Item "runas_group=string" | .TP 6n |
| runas_group=string |
The group name or gid to to run the command as, if specified via |
The group name or gid to to run the command as, if specified via |
the \f(CW\*(C`\-g\*(C'\fR flag. | the |
.IP "prompt=string" 4 | \fB\-g\fR |
.IX Item "prompt=string" | flag. |
| .TP 6n |
| prompt=string |
The prompt to use when requesting a password, if specified via |
The prompt to use when requesting a password, if specified via |
the \f(CW\*(C`\-p\*(C'\fR flag. | the |
.IP "set_home=bool" 4 | \fB\-p\fR |
.IX Item "set_home=bool" | flag. |
Set to true if the user specified the \f(CW\*(C`\-H\*(C'\fR flag. If true, set the | .TP 6n |
\&\f(CW\*(C`HOME\*(C'\fR environment variable to the target user's home directory. | set_home=bool |
.IP "preserve_environment=bool" 4 | Set to true if the user specified the |
.IX Item "preserve_environment=bool" | \fB\-H\fR |
Set to true if the user specified the \f(CW\*(C`\-E\*(C'\fR flag, indicating that | flag. |
| If true, set the |
| \fRHOME\fR |
| environment variable to the target user's home directory. |
| .TP 6n |
| preserve_environment=bool |
| Set to true if the user specified the |
| \fB\-E\fR |
| flag, indicating that |
the user wishes to preserve the environment. |
the user wishes to preserve the environment. |
.IP "run_shell=bool" 4 | .TP 6n |
.IX Item "run_shell=bool" | run_shell=bool |
Set to true if the user specified the \f(CW\*(C`\-s\*(C'\fR flag, indicating that | Set to true if the user specified the |
| \fB\-s\fR |
| flag, indicating that |
the user wishes to run a shell. |
the user wishes to run a shell. |
.IP "login_shell=bool" 4 | .TP 6n |
.IX Item "login_shell=bool" | login_shell=bool |
Set to true if the user specified the \f(CW\*(C`\-i\*(C'\fR flag, indicating that | Set to true if the user specified the |
| \fB\-i\fR |
| flag, indicating that |
the user wishes to run a login shell. |
the user wishes to run a login shell. |
.IP "implied_shell=bool" 4 | .TP 6n |
.IX Item "implied_shell=bool" | implied_shell=bool |
If the user does not specify a program on the command line, \fBsudo\fR | If the user does not specify a program on the command line, |
| \fBsudo\fR |
will pass the plugin the path to the user's shell and set |
will pass the plugin the path to the user's shell and set |
\&\fIimplied_shell\fR to true. This allows \fBsudo\fR with no arguments | \fIimplied_shell\fR |
to be used similarly to \fIsu\fR\|(1). If the plugin does not to support | to true. |
this usage, it may return a value of \-2 from the \f(CW\*(C`check_policy\*(C'\fR | This allows |
function, which will cause \fBsudo\fR to print a usage message and | \fBsudo\fR |
| 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 |
| \fBcheck_policy\fR() |
| function, which will cause |
| \fBsudo\fR |
| to print a usage message and |
exit. |
exit. |
.IP "preserve_groups=bool" 4 | .TP 6n |
.IX Item "preserve_groups=bool" | preserve_groups=bool |
Set to true if the user specified the \f(CW\*(C`\-P\*(C'\fR flag, indicating that | Set to true if the user specified the |
| \fB\-P\fR |
| flag, indicating that |
the user wishes to preserve the group vector instead of setting it |
the user wishes to preserve the group vector instead of setting it |
based on the runas user. |
based on the runas user. |
.IP "ignore_ticket=bool" 4 | .TP 6n |
.IX Item "ignore_ticket=bool" | ignore_ticket=bool |
Set to true if the user specified the \f(CW\*(C`\-k\*(C'\fR flag along with a | Set to true if the user specified the |
| \fB\-k\fR |
| flag along with a |
command, indicating that the user wishes to ignore any cached |
command, indicating that the user wishes to ignore any cached |
authentication credentials. |
authentication credentials. |
.IP "noninteractive=bool" 4 | .TP 6n |
.IX Item "noninteractive=bool" | noninteractive=bool |
Set to true if the user specified the \f(CW\*(C`\-n\*(C'\fR flag, indicating that | Set to true if the user specified the |
\&\fBsudo\fR should operate in non-interactive mode. The plugin may | \fB\-n\fR |
reject a command run in non-interactive mode if user interaction | flag, indicating that |
is required. | \fBsudo\fR |
.IP "login_class=string" 4 | should operate in non-interactive mode. |
.IX Item "login_class=string" | The plugin may reject a command run in non-interactive mode if user |
\&\s-1BSD\s0 login class to use when setting resource limits and nice value, | interaction is required. |
if specified by the \f(CW\*(C`\-c\*(C'\fR flag. | .TP 6n |
.IP "selinux_role=string" 4 | login_class=string |
.IX Item "selinux_role=string" | BSD login class to use when setting resource limits and nice value, |
| if specified by the |
| \fB\-c\fR |
| flag. |
| .TP 6n |
| selinux_role=string |
SELinux role to use when executing the command, if specified by |
SELinux role to use when executing the command, if specified by |
the \f(CW\*(C`\-r\*(C'\fR flag. | the |
.IP "selinux_type=string" 4 | \fB\-r\fR |
.IX Item "selinux_type=string" | flag. |
| .TP 6n |
| selinux_type=string |
SELinux type to use when executing the command, if specified by |
SELinux type to use when executing the command, if specified by |
the \f(CW\*(C`\-t\*(C'\fR flag. | the |
.IP "bsdauth_type=string" 4 | \fB\-t\fR |
.IX Item "bsdauth_type=string" | flag. |
Authentication type, if specified by the \f(CW\*(C`\-a\*(C'\fR flag, to use on | .TP 6n |
systems where \s-1BSD\s0 authentication is supported. | bsdauth_type=string |
.IP "network_addrs=list" 4 | Authentication type, if specified by the |
.IX Item "network_addrs=list" | \fB\-a\fR |
A space-separated list of \s-1IP\s0 network addresses and netmasks in the | flag, to use on |
form \*(L"addr/netmask\*(R", e.g. \*(L"192.168.1.2/255.255.255.0\*(R". The address | systems where BSD authentication is supported. |
and netmask pairs may be either IPv4 or IPv6, depending on what the | .TP 6n |
operating system supports. If the address contains a colon (':'), | network_addrs=list |
| A space-separated list of IP network addresses and netmasks in the |
| form |
| ``addr/netmask'', |
| e.g.\& |
| ``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. |
it is an IPv6 address, else it is IPv4. |
.IP "progname=string" 4 | .TP 6n |
.IX Item "progname=string" | progname=string |
The command name that sudo was run as, typically \*(L"sudo\*(R" or \*(L"sudoedit\*(R". | The command name that sudo was run as, typically |
.IP "sudoedit=bool" 4 | ``sudo'' |
.IX Item "sudoedit=bool" | or |
Set to true when the \f(CW\*(C`\-e\*(C'\fR flag is is specified or if invoked as | ``sudoedit''. |
\&\fBsudoedit\fR. The plugin shall substitute an editor into \fIargv\fR | .TP 6n |
in the \fIcheck_policy\fR function or return \f(CW\*(C`\-2\*(C'\fR with a usage error | sudoedit=bool |
if the plugin does not support \fIsudoedit\fR. For more information, | Set to true when the |
see the \fIcheck_policy\fR section. | \fB\-e\fR |
.IP "closefrom=number" 4 | flag is is specified or if invoked as |
.IX Item "closefrom=number" | \fBsudoedit\fR. |
If specified, the user has requested via the \f(CW\*(C`\-C\*(C'\fR flag that \fBsudo\fR | The plugin shall substitute an editor into |
close all files descriptors with a value of \fInumber\fR or higher. | \fIargv\fR |
| in the |
| \fBcheck_policy\fR() |
| function or return \-2 with a usage error |
| if the plugin does not support |
| \fIsudoedit\fR. |
| For more information, see the |
| \fIcheck_policy\fR |
| section. |
| .TP 6n |
| closefrom=number |
| If specified, the user has requested via the |
| \fB\-C\fR |
| flag that |
| \fBsudo\fR |
| close all files descriptors with a value of |
| \fInumber\fR |
| or higher. |
The plugin may optionally pass this, or another value, back in the |
The plugin may optionally pass this, or another value, back in the |
\&\fIcommand_info\fR list. | \fIcommand_info\fR |
.RE | list. |
.RS 4 | .PP |
.Sp | |
Additional settings may be added in the future so the plugin should |
Additional settings may be added in the future so the plugin should |
silently ignore settings that it does not recognize. |
silently ignore settings that it does not recognize. |
|
.PP |
.RE |
.RE |
.IP "user_info" 4 | .PD 0 |
.IX Item "user_info" | .TP 6n |
| user_info |
A vector of information about the user running the command in the form of |
A vector of information about the user running the command in the form of |
\&\*(L"name=value\*(R" strings. The vector is terminated by a \f(CW\*(C`NULL\*(C'\fR pointer. | ``name=value'' |
.Sp | strings. |
When parsing \fIuser_info\fR, the plugin should split on the \fBfirst\fR | The vector is terminated by a |
equal sign ('=') since the \fIname\fR field will never include one | \fRNULL\fR |
itself but the \fIvalue\fR might. | pointer. |
.RS 4 | .sp |
.IP "user=string" 4 | When parsing |
.IX Item "user=string" | \fIuser_info\fR, |
The name of the user invoking \fBsudo\fR. | the plugin should split on the |
.IP "uid=uid_t" 4 | \fBfirst\fR |
.IX Item "uid=uid_t" | equal sign |
The real user \s-1ID\s0 of the user invoking \fBsudo\fR. | (`=') |
.IP "gid=gid_t" 4 | since the |
.IX Item "gid=gid_t" | \fIname\fR |
The real group \s-1ID\s0 of the user invoking \fBsudo\fR. | field will never include one |
.IP "groups=list" 4 | itself but the |
.IX Item "groups=list" | \fIvalue\fR |
| might. |
| .RS |
| .PD |
| .TP 6n |
| pid=int |
| The process ID of the running |
| \fBsudo\fR |
| process. |
| Only available starting with API version 1.2 |
| .TP 6n |
| ppid=int |
| The parent process ID of the running |
| \fBsudo\fR |
| process. |
| Only available starting with API version 1.2 |
| .TP 6n |
| sid=int |
| The session ID of the running |
| \fBsudo\fR |
| process or 0 if |
| \fBsudo\fR |
| is |
| not part of a POSIX job control session. |
| Only available starting with API version 1.2 |
| .TP 6n |
| pgid=int |
| The ID of the process group that the running |
| \fBsudo\fR |
| process belongs |
| to. |
| Only available starting with API version 1.2 |
| .TP 6n |
| tcpgid=int |
| The ID of the forground process group associated with the terminal |
| device associcated with the |
| \fBsudo\fR |
| process or \-1 if there is no |
| terminal present. |
| Only available starting with API version 1.2 |
| .TP 6n |
| user=string |
| The name of the user invoking |
| \fBsudo\fR. |
| .TP 6n |
| euid=uid_t |
| The effective user ID of the user invoking |
| \fBsudo\fR. |
| .TP 6n |
| uid=uid_t |
| The real user ID of the user invoking |
| \fBsudo\fR. |
| .TP 6n |
| egid=gid_t |
| The effective group ID of the user invoking |
| \fBsudo\fR. |
| .TP 6n |
| gid=gid_t |
| The real group ID of the user invoking |
| \fBsudo\fR. |
| .TP 6n |
| groups=list |
The user's supplementary group list formatted as a string of |
The user's supplementary group list formatted as a string of |
comma-separated group IDs. |
comma-separated group IDs. |
.IP "cwd=string" 4 | .TP 6n |
.IX Item "cwd=string" | cwd=string |
The user's current working directory. |
The user's current working directory. |
.IP "tty=string" 4 | .TP 6n |
.IX Item "tty=string" | tty=string |
The path to the user's terminal device. If the user has no terminal | The path to the user's terminal device. |
device associated with the session, the value will be empty, as in | If the user has no terminal device associated with the session, |
\&\f(CW\*(C`tty=\*(C'\fR. | the value will be empty, as in |
.IP "host=string" 4 | ``\fRtty=\fR''. |
.IX Item "host=string" | .TP 6n |
The local machine's hostname as returned by the \f(CW\*(C`gethostname()\*(C'\fR | host=string |
| The local machine's hostname as returned by the |
| gethostname(2) |
system call. |
system call. |
.IP "lines=int" 4 | .TP 6n |
.IX Item "lines=int" | lines=int |
The number of lines the user's terminal supports. If there is | The number of lines the user's terminal supports. |
| If there is |
no terminal device available, a default value of 24 is used. |
no terminal device available, a default value of 24 is used. |
.IP "cols=int" 4 | .TP 6n |
.IX Item "cols=int" | cols=int |
The number of columns the user's terminal supports. If there is | The number of columns the user's terminal supports. |
no terminal device available, a default value of 80 is used. | If there is no terminal device available, a default value of 80 is used. |
| .PP |
.RE |
.RE |
.RS 4 | .PD 0 |
| .TP 6n |
| user_env |
| The user's environment in the form of a |
| \fRNULL\fR-terminated vector of |
| ``name=value'' |
| strings. |
| .sp |
| When parsing |
| \fIuser_env\fR, |
| the plugin should split on the |
| \fBfirst\fR |
| equal sign |
| (`=') |
| since the |
| \fIname\fR |
| field will never include one |
| itself but the |
| \fIvalue\fR |
| might. |
| .PD |
| .TP 6n |
| plugin_options |
| 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 |
| \fRNULL\fR-terminated |
| array of strings. |
| If no arguments were |
| specified, |
| \fIplugin_options\fR |
| will be the |
| \fRNULL\fR |
| pointer. |
| .sp |
| NOTE: the |
| \fIplugin_options\fR |
| parameter is only available starting with |
| API version 1.2. |
| A plugin |
| \fBmust\fR |
| check the API version specified |
| by the |
| \fBsudo\fR |
| front end before using |
| \fIplugin_options\fR. |
| Failure to do so may result in a crash. |
| .PP |
.RE |
.RE |
.IP "user_env" 4 | .PD 0 |
.IX Item "user_env" | .TP 6n |
The user's environment in the form of a \f(CW\*(C`NULL\*(C'\fR\-terminated vector of | close |
\&\*(L"name=value\*(R" strings. | .br |
.Sp | .RS |
When parsing \fIuser_env\fR, the plugin should split on the \fBfirst\fR | .nf |
equal sign ('=') since the \fIname\fR field will never include one | .RS 0n |
itself but the \fIvalue\fR might. | void (*close)(int exit_status, int error); |
.RE |
.RE |
.RS 4 | .fi |
.RE | .sp |
.IP "close" 4 | The |
.IX Item "close" | \fBclose\fR() |
.Vb 1 | function is called when the command being run by |
\& void (*close)(int exit_status, int error); | \fBsudo\fR |
.Ve | |
.Sp | |
The \f(CW\*(C`close\*(C'\fR function is called when the command being run by \fBsudo\fR | |
finishes. |
finishes. |
.Sp | .sp |
The function arguments are as follows: |
The function arguments are as follows: |
.RS 4 | .PD |
.IP "exit_status" 4 | .TP 6n |
.IX Item "exit_status" | exit_status |
The command's exit status, as returned by the \fIwait\fR\|(2) system call. | The command's exit status, as returned by the |
The value of \f(CW\*(C`exit_status\*(C'\fR is undefined if \f(CW\*(C`error\*(C'\fR is non-zero. | wait(2) |
.IP "error" 4 | system call. |
.IX Item "error" | The value of |
| \fRexit_status\fR |
| is undefined if |
| \fRerror\fR |
| is non-zero. |
| .TP 6n |
| error |
| .br |
If the command could not be executed, this is set to the value of |
If the command could not be executed, this is set to the value of |
\&\f(CW\*(C`errno\*(C'\fR set by the \fIexecve\fR\|(2) system call. The plugin is responsible | \fRerrno\fR |
for displaying error information via the conversation or plugin_printf | set by the |
function. If the command was successfully executed, the value of | execve(2) |
\&\f(CW\*(C`error\*(C'\fR is 0. | system call. |
| The plugin is responsible for displaying error information via the |
| \fBconversation\fR() |
| or |
| \fBplugin_printf\fR() |
| function. |
| If the command was successfully executed, the value of |
| \fRerror\fR |
| is 0. |
| .PP |
.RE |
.RE |
.RS 4 | .PD 0 |
| .TP 6n |
| show_version |
| .RS |
| .nf |
| .RS 0n |
| int (*show_version)(int verbose); |
.RE |
.RE |
.IP "show_version" 4 | .fi |
.IX Item "show_version" | .sp |
.Vb 1 | The |
\& int (*show_version)(int verbose); | \fBshow_version\fR() |
.Ve | function is called by |
.Sp | \fBsudo\fR |
The \f(CW\*(C`show_version\*(C'\fR function is called by \fBsudo\fR when the user specifies | when the user specifies |
the \f(CW\*(C`\-V\*(C'\fR option. The plugin may display its version information | the |
to the user via the conversation or plugin_printf function using | \fB\-V\fR |
\&\f(CW\*(C`SUDO_CONV_INFO_MSG\*(C'\fR. If the user requests detailed version | option. |
information, the verbose flag will be set. | The plugin may display its version information to the user via the |
.IP "check_policy" 4 | \fBconversation\fR() |
.IX Item "check_policy" | or |
.Vb 3 | \fBplugin_printf\fR() |
\& int (*check_policy)(int argc, char * const argv[] | function using |
\& char *env_add[], char **command_info[], | \fRSUDO_CONV_INFO_MSG\fR. |
\& char **argv_out[], char **user_env_out[]); | If the user requests detailed version information, the verbose flag will be set. |
.Ve | .PD |
.Sp | .PP |
The \fIcheck_policy\fR function is called by \fBsudo\fR to determine | .RE |
| .PD 0 |
| .TP 6n |
| check_policy |
| .RS |
| .nf |
| .RS 0n |
| int (*check_policy)(int argc, char * const argv[] |
| char *env_add[], char **command_info[], |
| char **argv_out[], char **user_env_out[]); |
| .RE |
| .fi |
| .sp |
| The |
| \fBcheck_policy\fR() |
| function is called by |
| \fBsudo\fR |
| to determine |
whether the user is allowed to run the specified commands. |
whether the user is allowed to run the specified commands. |
.Sp | .sp |
If the \fIsudoedit\fR option was enabled in the \fIsettings\fR array | If the |
passed to the \fIopen\fR function, the user has requested \fIsudoedit\fR | \fIsudoedit\fR |
mode. \fIsudoedit\fR is a mechanism for editing one or more files | option was enabled in the |
| \fIsettings\fR |
| array |
| passed to the |
| \fBopen\fR() |
| function, the user has requested |
| \fIsudoedit\fR |
| mode. |
| \fIsudoedit\fR |
| is a mechanism for editing one or more files |
where an editor is run with the user's credentials instead of with |
where an editor is run with the user's credentials instead of with |
elevated privileges. \fBsudo\fR achieves this by creating user-writable | elevated privileges. |
| \fBsudo\fR |
| achieves this by creating user-writable |
temporary copies of the files to be edited and then overwriting the |
temporary copies of the files to be edited and then overwriting the |
originals with the temporary copies after editing is complete. If | originals with the temporary copies after editing is complete. |
the plugin supports \fBsudoedit\fR, it should choose the editor to be | If the plugin supports |
used, potentially from a variable in the user's environment, such | \fIsudoedit\fR, |
as \f(CW\*(C`EDITOR\*(C'\fR, and include it in \fIargv_out\fR (note that environment | it should choose the editor to be used, potentially from a variable |
variables may include command line flags). The files to be edited | in the user's environment, such as |
should be copied from \fIargv\fR into \fIargv_out\fR, separated from the | \fREDITOR\fR, |
editor and its arguments by a \f(CW"\-\-"\fR element. The \f(CW"\-\-"\fR will | and include it in |
be removed by \fBsudo\fR before the editor is executed. The plugin | \fIargv_out\fR |
should also set \fIsudoedit=true\fR in the \fIcommand_info\fR list. | (note that environment |
.Sp | variables may include command line flags). |
The \fIcheck_policy\fR function returns 1 if the command is allowed, | The files to be edited should be copied from |
| \fIargv\fR |
| into |
| \fIargv_out\fR, |
| separated from the |
| editor and its arguments by a |
| ``\fR--\fR'' |
| element. |
| The |
| ``\fR--\fR'' |
| will |
| be removed by |
| \fBsudo\fR |
| before the editor is executed. |
| The plugin should also set |
| \fIsudoedit=true\fR |
| in the |
| \fIcommand_info\fR |
| list. |
| .sp |
| The |
| \fBcheck_policy\fR() |
| function returns 1 if the command is allowed, |
0 if not allowed, \-1 for a general error, or \-2 for a usage error |
0 if not allowed, \-1 for a general error, or \-2 for a usage error |
or if \fBsudoedit\fR was specified but is unsupported by the plugin. | or if |
In the latter case, \fBsudo\fR will print a usage message before it | \fIsudoedit\fR |
exits. If an error occurs, the plugin may optionally call the | was specified but is unsupported by the plugin. |
conversation or plugin_printf function with \f(CW\*(C`SUDO_CONF_ERROR_MSG\*(C'\fR | In the latter case, |
| \fBsudo\fR |
| will print a usage message before it |
| exits. |
| If an error occurs, the plugin may optionally call the |
| \fBconversation\fR() |
| or |
| \fBplugin_printf\fR() |
| function with |
| \fRSUDO_CONF_ERROR_MSG\fR |
to present additional error information to the user. |
to present additional error information to the user. |
.Sp | .sp |
The function arguments are as follows: |
The function arguments are as follows: |
.RS 4 | .PD |
.IP "argc" 4 | .TP 6n |
.IX Item "argc" | argc |
The number of elements in \fIargv\fR, not counting the final \f(CW\*(C`NULL\*(C'\fR | The number of elements in |
| \fIargv\fR, |
| not counting the final |
| \fRNULL\fR |
pointer. |
pointer. |
.IP "argv" 4 | .TP 6n |
.IX Item "argv" | argv |
The argument vector describing the command the user wishes to run, |
The argument vector describing the command the user wishes to run, |
in the same form as what would be passed to the \fIexecve()\fR system | in the same form as what would be passed to the |
call. The vector is terminated by a \f(CW\*(C`NULL\*(C'\fR pointer. | execve(2) |
.IP "env_add" 4 | system call. |
.IX Item "env_add" | The vector is terminated by a |
| \fRNULL\fR |
| pointer. |
| .TP 6n |
| env_add |
Additional environment variables specified by the user on the command |
Additional environment variables specified by the user on the command |
line in the form of a \f(CW\*(C`NULL\*(C'\fR\-terminated vector of \*(L"name=value\*(R" | line in the form of a |
strings. The plugin may reject the command if one or more variables | \fRNULL\fR-terminated |
| vector of |
| ``name=value'' |
| strings. |
| The plugin may reject the command if one or more variables |
are not allowed to be set, or it may silently ignore such variables. |
are not allowed to be set, or it may silently ignore such variables. |
.Sp | .sp |
When parsing \fIenv_add\fR, the plugin should split on the \fBfirst\fR | When parsing |
equal sign ('=') since the \fIname\fR field will never include one | \fIenv_add\fR, |
itself but the \fIvalue\fR might. | the plugin should split on the |
.IP "command_info" 4 | \fBfirst\fR |
.IX Item "command_info" | equal sign |
Information about the command being run in the form of \*(L"name=value\*(R" | (`=') |
strings. These values are used by \fBsudo\fR to set the execution | since the |
environment when running a command. The plugin is responsible for | \fIname\fR |
creating and populating the vector, which must be terminated with | field will never include one |
a \f(CW\*(C`NULL\*(C'\fR pointer. The following values are recognized by \fBsudo\fR: | itself but the |
.RS 4 | \fIvalue\fR |
.IP "command=string" 4 | might. |
.IX Item "command=string" | .TP 6n |
| command_info |
| Information about the command being run in the form of |
| ``name=value'' |
| strings. |
| These values are used by |
| \fBsudo\fR |
| to set the execution |
| environment when running a command. |
| The plugin is responsible for creating and populating the vector, |
| which must be terminated with a |
| \fRNULL\fR |
| pointer. |
| The following values are recognized by |
| \fBsudo\fR: |
| .RS |
| .TP 6n |
| command=string |
Fully qualified path to the command to be executed. |
Fully qualified path to the command to be executed. |
.IP "runas_uid=uid" 4 | .TP 6n |
.IX Item "runas_uid=uid" | runas_uid=uid |
User \s-1ID\s0 to run the command as. | User ID to run the command as. |
.IP "runas_euid=uid" 4 | .TP 6n |
.IX Item "runas_euid=uid" | runas_euid=uid |
Effective user \s-1ID\s0 to run the command as. | Effective user ID to run the command as. |
If not specified, the value of \fIrunas_uid\fR is used. | If not specified, the value of |
.IP "runas_gid=gid" 4 | \fIrunas_uid\fR |
.IX Item "runas_gid=gid" | is used. |
Group \s-1ID\s0 to run the command as. | .TP 6n |
.IP "runas_egid=gid" 4 | runas_gid=gid |
.IX Item "runas_egid=gid" | Group ID to run the command as. |
Effective group \s-1ID\s0 to run the command as. | .TP 6n |
If not specified, the value of \fIrunas_gid\fR is used. | runas_egid=gid |
.IP "runas_groups=list" 4 | Effective group ID to run the command as. |
.IX Item "runas_groups=list" | If not specified, the value of |
| \fIrunas_gid\fR |
| is used. |
| .TP 6n |
| runas_groups=list |
The supplementary group vector to use for the command in the form |
The supplementary group vector to use for the command in the form |
of a comma-separated list of group IDs. If \fIpreserve_groups\fR | of a comma-separated list of group IDs. |
| If |
| \fIpreserve_groups\fR |
is set, this option is ignored. |
is set, this option is ignored. |
.IP "login_class=string" 4 | .TP 6n |
.IX Item "login_class=string" | login_class=string |
\&\s-1BSD\s0 login class to use when setting resource limits and nice value | BSD login class to use when setting resource limits and nice value |
(optional). This option is only set on systems that support login | (optional). |
classes. | This option is only set on systems that support login classes. |
.IP "preserve_groups=bool" 4 | .TP 6n |
.IX Item "preserve_groups=bool" | preserve_groups=bool |
If set, \fBsudo\fR will preserve the user's group vector instead of | If set, |
initializing the group vector based on \f(CW\*(C`runas_user\*(C'\fR. | \fBsudo\fR |
.IP "cwd=string" 4 | will preserve the user's group vector instead of |
.IX Item "cwd=string" | initializing the group vector based on |
| \fRrunas_user\fR. |
| .TP 6n |
| cwd=string |
The current working directory to change to when executing the command. |
The current working directory to change to when executing the command. |
.IP "noexec=bool" 4 | .TP 6n |
.IX Item "noexec=bool" | noexec=bool |
If set, prevent the command from executing other programs. |
If set, prevent the command from executing other programs. |
.IP "chroot=string" 4 | .TP 6n |
.IX Item "chroot=string" | chroot=string |
The root directory to use when running the command. |
The root directory to use when running the command. |
.IP "nice=int" 4 | .TP 6n |
.IX Item "nice=int" | nice=int |
Nice value (priority) to use when executing the command. The nice | Nice value (priority) to use when executing the command. |
value, if specified, overrides the priority associated with the | The nice value, if specified, overrides the priority associated with the |
\&\fIlogin_class\fR on \s-1BSD\s0 systems. | \fIlogin_class\fR |
.IP "umask=octal" 4 | on BSD systems. |
.IX Item "umask=octal" | .TP 6n |
| umask=octal |
The file creation mask to use when executing the command. |
The file creation mask to use when executing the command. |
.IP "selinux_role=string" 4 | .TP 6n |
.IX Item "selinux_role=string" | selinux_role=string |
SELinux role to use when executing the command. |
SELinux role to use when executing the command. |
.IP "selinux_type=string" 4 | .TP 6n |
.IX Item "selinux_type=string" | selinux_type=string |
SELinux type to use when executing the command. |
SELinux type to use when executing the command. |
.IP "timeout=int" 4 | .TP 6n |
.IX Item "timeout=int" | timeout=int |
Command timeout. If non-zero then when the timeout expires the | Command timeout. |
command will be killed. | If non-zero then when the timeout expires the command will be killed. |
.IP "sudoedit=bool" 4 | .TP 6n |
.IX Item "sudoedit=bool" | sudoedit=bool |
Set to true when in \fIsudoedit\fR mode. The plugin may enable | Set to true when in |
\&\fIsudoedit\fR mode even if \fBsudo\fR was not invoked as \fBsudoedit\fR. | \fIsudoedit\fR |
| mode. |
| The plugin may enable |
| \fIsudoedit\fR |
| mode even if |
| \fBsudo\fR |
| was not invoked as |
| \fBsudoedit\fR. |
This allows the plugin to perform command substitution and transparently |
This allows the plugin to perform command substitution and transparently |
enable \fIsudoedit\fR when the user attempts to run an editor. | enable |
.IP "closefrom=number" 4 | \fIsudoedit\fR |
.IX Item "closefrom=number" | when the user attempts to run an editor. |
If specified, \fBsudo\fR will close all files descriptors with a value | .TP 6n |
of \fInumber\fR or higher. | closefrom=number |
.IP "iolog_compress=bool" 4 | If specified, |
.IX Item "iolog_compress=bool" | \fBsudo\fR |
| will close all files descriptors with a value |
| of |
| \fInumber\fR |
| or higher. |
| .TP 6n |
| iolog_compress=bool |
Set to true if the I/O logging plugins, if any, should compress the |
Set to true if the I/O logging plugins, if any, should compress the |
log data. This is a hint to the I/O logging plugin which may choose | log data. |
to ignore it. | This is a hint to the I/O logging plugin which may choose to ignore it. |
.IP "iolog_path=string" 4 | .TP 6n |
.IX Item "iolog_path=string" | iolog_path=string |
Fully qualified path to the file or directory in which I/O log is |
Fully qualified path to the file or directory in which I/O log is |
to be stored. This is a hint to the I/O logging plugin which may | to be stored. |
choose to ignore it. If no I/O logging plugin is loaded, this | This is a hint to the I/O logging plugin which may choose to ignore it. |
setting has no effect. | If no I/O logging plugin is loaded, this setting has no effect. |
.IP "iolog_stdin=bool" 4 | .TP 6n |
.IX Item "iolog_stdin=bool" | iolog_stdin=bool |
Set to true if the I/O logging plugins, if any, should log the |
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 | standard input if it is not connected to a terminal device. |
is a hint to the I/O logging plugin which may choose to ignore it. | This is a hint to the I/O logging plugin which may choose to ignore it. |
.IP "iolog_stdout=bool" 4 | .TP 6n |
.IX Item "iolog_stdout=bool" | iolog_stdout=bool |
Set to true if the I/O logging plugins, if any, should log the |
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 | standard output if it is not connected to a terminal device. |
is a hint to the I/O logging plugin which may choose to ignore it. | This is a hint to the I/O logging plugin which may choose to ignore it. |
.IP "iolog_stderr=bool" 4 | .TP 6n |
.IX Item "iolog_stderr=bool" | iolog_stderr=bool |
Set to true if the I/O logging plugins, if any, should log the |
Set to true if the I/O logging plugins, if any, should log the |
standard error if it is not connected to a terminal device. This | standard error if it is not connected to a terminal device. |
is a hint to the I/O logging plugin which may choose to ignore it. | This is a hint to the I/O logging plugin which may choose to ignore it. |
.IP "iolog_ttyin=bool" 4 | .TP 6n |
.IX Item "iolog_ttyin=bool" | iolog_ttyin=bool |
Set to true if the I/O logging plugins, if any, should log all |
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 | terminal input. |
from a pipe or redirected from a file. This is a hint to the I/O | This only includes input typed by the user and not from a pipe or |
logging plugin which may choose to ignore it. | redirected from a file. |
.IP "iolog_ttyout=bool" 4 | This is a hint to the I/O logging plugin which may choose to ignore it. |
.IX Item "iolog_ttyout=bool" | .TP 6n |
| iolog_ttyout=bool |
Set to true if the I/O logging plugins, if any, should log all |
Set to true if the I/O logging plugins, if any, should log all |
terminal output. This only includes output to the screen, not | terminal output. |
output to a pipe or file. This is a hint to the I/O logging plugin | This only includes output to the screen, not output to a pipe or file. |
which may choose to ignore it. | This is a hint to the I/O logging plugin which may choose to ignore it. |
.IP "use_pty=bool" 4 | .TP 6n |
.IX Item "use_pty=bool" | use_pty=bool |
Allocate a pseudo-tty to run the command in, regardless of whether |
Allocate a pseudo-tty to run the command in, regardless of whether |
or not I/O logging is in use. By default, \fBsudo\fR will only run | or not I/O logging is in use. |
| By default, |
| \fBsudo\fR |
| will only run |
the command in a pty when an I/O log plugin is loaded. |
the command in a pty when an I/O log plugin is loaded. |
.IP "set_utmp=bool" 4 | .TP 6n |
.IX Item "set_utmp=bool" | set_utmp=bool |
Create a utmp (or utmpx) entry when a pseudo-tty is allocated. By | Create a utmp (or utmpx) entry when a pseudo-tty is allocated. |
default, the new entry will be a copy of the user's existing utmp | By default, the new entry will be a copy of the user's existing utmp |
entry (if any), with the tty, time, type and pid fields updated. |
entry (if any), with the tty, time, type and pid fields updated. |
.IP "utmp_user=string" 4 | .TP 6n |
.IX Item "utmp_user=string" | utmp_user=string |
User name to use when constructing a new utmp (or utmpx) entry when |
User name to use when constructing a new utmp (or utmpx) entry when |
\&\fIset_utmp\fR is enabled. This option can be used to set the user | \fIset_utmp\fR |
field in the utmp entry to the user the command runs as rather than | is enabled. |
the invoking user. If not set, \fBsudo\fR will base the new entry on | 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, |
| \fBsudo\fR |
| will base the new entry on |
the invoking user's existing entry. |
the invoking user's existing entry. |
.RE | .PP |
.RS 4 | |
.Sp | |
Unsupported values will be ignored. |
Unsupported values will be ignored. |
|
.PP |
.RE |
.RE |
.IP "argv_out" 4 | .PD 0 |
.IX Item "argv_out" | .TP 6n |
The \f(CW\*(C`NULL\*(C'\fR\-terminated argument vector to pass to the \fIexecve()\fR | argv_out |
system call when executing the command. The plugin is responsible | The |
for allocating and populating the vector. | \fRNULL\fR-terminated |
.IP "user_env_out" 4 | argument vector to pass to the |
.IX Item "user_env_out" | execve(2) |
The \f(CW\*(C`NULL\*(C'\fR\-terminated environment vector to use when executing the | system call when executing the command. |
command. The plugin is responsible for allocating and populating | The plugin is responsible for allocating and populating the vector. |
the vector. | .PD |
| .TP 6n |
| user_env_out |
| The |
| \fRNULL\fR-terminated |
| environment vector to use when executing the command. |
| The plugin is responsible for allocating and populating the vector. |
| .PP |
.RE |
.RE |
.RS 4 | .PD 0 |
| .TP 6n |
| list |
| .RS |
| .nf |
| .RS 0n |
| int (*list)(int verbose, const char *list_user, |
| int argc, char * const argv[]); |
.RE |
.RE |
.IP "list" 4 | .fi |
.IX Item "list" | .sp |
.Vb 2 | List available privileges for the invoking user. |
\& int (*list)(int verbose, const char *list_user, | Returns 1 on success, 0 on failure and \-1 on error. |
\& int argc, char * const argv[]); | On error, the plugin may optionally call the |
.Ve | \fBconversation\fR() |
.Sp | or |
List available privileges for the invoking user. Returns 1 on | \fBplugin_printf\fR() |
success, 0 on failure and \-1 on error. On error, the plugin may | function with |
optionally call the conversation or plugin_printf function with | \fRSUDO_CONF_ERROR_MSG\fR |
\&\f(CW\*(C`SUDO_CONF_ERROR_MSG\*(C'\fR to present additional error information to | to present additional error information to |
the user. |
the user. |
.Sp | .sp |
Privileges should be output via the conversation or plugin_printf | Privileges should be output via the |
function using \f(CW\*(C`SUDO_CONV_INFO_MSG\*(C'\fR. | \fBconversation\fR() |
.RS 4 | or |
.IP "verbose" 4 | \fBplugin_printf\fR() |
.IX Item "verbose" | function using |
| \fRSUDO_CONV_INFO_MSG\fR, |
| .PD |
| .TP 6n |
| verbose |
Flag indicating whether to list in verbose mode or not. |
Flag indicating whether to list in verbose mode or not. |
.IP "list_user" 4 | .TP 6n |
.IX Item "list_user" | list_user |
The name of a different user to list privileges for if the policy |
The name of a different user to list privileges for if the policy |
allows it. If \f(CW\*(C`NULL\*(C'\fR, the plugin should list the privileges of | allows it. |
the invoking user. | If |
.IP "argc" 4 | \fRNULL\fR, |
.IX Item "argc" | the plugin should list the privileges of the invoking user. |
The number of elements in \fIargv\fR, not counting the final \f(CW\*(C`NULL\*(C'\fR | .TP 6n |
| argc |
| The number of elements in |
| \fIargv\fR, |
| not counting the final |
| \fRNULL\fR |
pointer. |
pointer. |
.IP "argv" 4 | .TP 6n |
.IX Item "argv" | argv |
If non\-\f(CW\*(C`NULL\*(C'\fR, an argument vector describing a command the user | If |
| non-\fRNULL\fR, |
| an argument vector describing a command the user |
wishes to check against the policy in the same form as what would |
wishes to check against the policy in the same form as what would |
be passed to the \fIexecve()\fR system call. If the command is permitted | be passed to the |
by the policy, the fully-qualified path to the command should be | execve(2) |
displayed along with any command line arguments. | system call. |
| If the command is permitted by the policy, the fully-qualified path |
| to the command should be displayed along with any command line arguments. |
| .PP |
.RE |
.RE |
.RS 4 | .PD 0 |
| .TP 6n |
| validate |
| .RS |
| .nf |
| .RS 0n |
| int (*validate)(void); |
.RE |
.RE |
.IP "validate" 4 | .fi |
.IX Item "validate" | .sp |
.Vb 1 | The |
\& int (*validate)(void); | \fBvalidate\fR() |
.Ve | function is called when |
.Sp | \fBsudo\fR |
The \f(CW\*(C`validate\*(C'\fR function is called when \fBsudo\fR is run with the | is run with the |
\&\f(CW\*(C`\-v\*(C'\fR flag. For policy plugins such as \fIsudoers\fR that cache | \fB\-v\fR |
| flag. |
| For policy plugins such as |
| \fIsudoers\fR |
| that cache |
authentication credentials, this function will validate and cache |
authentication credentials, this function will validate and cache |
the credentials. |
the credentials. |
.Sp | .sp |
The \f(CW\*(C`validate\*(C'\fR function should be \f(CW\*(C`NULL\*(C'\fR if the plugin does not | The |
support credential caching. | \fBvalidate\fR() |
.Sp | function should be |
| \fRNULL\fR |
| if the plugin does not support credential caching. |
| .sp |
Returns 1 on success, 0 on failure and \-1 on error. |
Returns 1 on success, 0 on failure and \-1 on error. |
On error, the plugin may optionally call the conversation or plugin_printf | On error, the plugin may optionally call the |
function with \f(CW\*(C`SUDO_CONF_ERROR_MSG\*(C'\fR to present additional | \fBconversation\fR() |
| or |
| \fBplugin_printf\fR() |
| function with |
| \fRSUDO_CONF_ERROR_MSG\fR |
| to present additional |
error information to the user. |
error information to the user. |
.IP "invalidate" 4 | .PD |
.IX Item "invalidate" | .PP |
.Vb 1 | .RE |
\& void (*invalidate)(int remove); | .PD 0 |
.Ve | .TP 6n |
.Sp | invalidate |
The \f(CW\*(C`invalidate\*(C'\fR function is called when \fBsudo\fR is called with | .RS |
the \f(CW\*(C`\-k\*(C'\fR or \f(CW\*(C`\-K\*(C'\fR flag. For policy plugins such as \fIsudoers\fR that | .nf |
| .RS 0n |
| void (*invalidate)(int remove); |
| .RE |
| .fi |
| .sp |
| The |
| \fBinvalidate\fR() |
| function is called when |
| \fBsudo\fR |
| is called with |
| the |
| \fB\-k\fR |
| or |
| \fB\-K\fR |
| flag. |
| For policy plugins such as |
| \fIsudoers\fR |
| that |
cache authentication credentials, this function will invalidate the |
cache authentication credentials, this function will invalidate the |
credentials. If the \fIremove\fR flag is set, the plugin may remove | credentials. |
| If the |
| \fIremove\fR |
| flag is set, the plugin may remove |
the credentials instead of simply invalidating them. |
the credentials instead of simply invalidating them. |
.Sp | .sp |
The \f(CW\*(C`invalidate\*(C'\fR function should be \f(CW\*(C`NULL\*(C'\fR if the plugin does not | The |
support credential caching. | \fBinvalidate\fR() |
.IP "init_session" 4 | function should be |
.IX Item "init_session" | \fRNULL\fR |
.Vb 1 | if the plugin does not support credential caching. |
\& int (*init_session)(struct passwd *pwd); | .PD |
.Ve | .PP |
.Sp | .RE |
The \f(CW\*(C`init_session\*(C'\fR function is called when \fBsudo\fR sets up the | .PD 0 |
execution environment for the command, immediately before the | .TP 6n |
contents of the \fIcommand_info\fR list are applied (before the uid | init_session |
changes). This can be used to do session setup that is not supported | .RS |
by \fIcommand_info\fR, such as opening the \s-1PAM\s0 session. | .nf |
.Sp | .RS 0n |
The \fIpwd\fR argument points to a passwd struct for the user the | int (*init_session)(struct passwd *pwd, char **user_envp[); |
| .RE |
| .fi |
| .sp |
| The |
| \fBinit_session\fR() |
| function is called before |
| \fBsudo\fR |
| sets up the |
| execution environment for the command. |
| It is run in the parent |
| \fBsudo\fR |
| process and before any uid or gid changes. |
| This can be used to perform session setup that is not supported by |
| \fIcommand_info\fR, |
| such as opening the PAM session. |
| The |
| \fBclose\fR() |
| function can be |
| used to tear down the session that was opened by |
| \fRinit_session\fR. |
| .sp |
| The |
| \fIpwd\fR |
| 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 |
command will be run as if the uid the command will run as was found |
in the password database, otherwise it will be \s-1NULL\s0. | in the password database, otherwise it will be |
.Sp | \fRNULL\fR. |
| .sp |
| The |
| \fIuser_env\fR |
| argument points to the environment the command will |
| run in, in the form of a |
| \fRNULL\fR-terminated |
| vector of |
| ``name=value'' |
| strings. |
| This is the same string passed back to the front end via |
| the Policy Plugin's |
| \fIuser_env_out\fR |
| parameter. |
| If the |
| \fBinit_session\fR() |
| function needs to modify the user environment, it should update the |
| pointer stored in |
| \fIuser_env\fR. |
| The expected use case is to merge the contents of the PAM environment |
| (if any) with the contents of |
| \fIuser_env\fR. |
| NOTE: the |
| \fIuser_env\fR |
| parameter is only available |
| starting with API version 1.2. |
| A plugin |
| \fBmust\fR |
| check the API |
| version specified by the |
| \fBsudo\fR |
| front end before using |
| \fIuser_env\fR. |
| Failure to do so may result in a crash. |
| .sp |
Returns 1 on success, 0 on failure and \-1 on error. |
Returns 1 on success, 0 on failure and \-1 on error. |
On error, the plugin may optionally call the conversation or plugin_printf | On error, the plugin may optionally call the |
function with \f(CW\*(C`SUDO_CONF_ERROR_MSG\*(C'\fR to present additional | \fBconversation\fR() |
| or |
| \fBplugin_printf\fR() |
| function with |
| \fRSUDO_CONF_ERROR_MSG\fR |
| to present additional |
error information to the user. |
error information to the user. |
|
.PD |
.PP |
.PP |
\fIVersion macros\fR | .RE |
.IX Subsection "Version macros" | .PD 0 |
| .TP 6n |
| register_hooks |
| .RS |
| .nf |
| .RS 0n |
| void (*register_hooks)(int version, |
| int (*register_hook)(struct sudo_hook *hook)); |
| .RE |
| .fi |
| .sp |
| The |
| \fBregister_hooks\fR() |
| function is called by the sudo front end to |
| register any hooks the plugin needs. |
| If the plugin does not support hooks, |
| \fRregister_hooks\fR |
| should be set to the |
| \fRNULL\fR |
| pointer. |
| .sp |
| The |
| \fIversion\fR |
| argument describes the version of the hooks API |
| supported by the |
| \fBsudo\fR |
| front end. |
| .sp |
| The |
| \fBregister_hook\fR() |
| function should be used to register any supported |
| hooks the plugin needs. |
| It returns 0 on success, 1 if the hook type is not supported and \-1 |
| if the major version in |
| \fRstruct hook\fR |
| does not match the front end's major hook API version. |
| .sp |
| See the |
| \fIHook function API\fR |
| section below for more information |
| about hooks. |
| .sp |
| NOTE: the |
| \fBregister_hooks\fR() |
| function is only available starting |
| with API version 1.2. |
| If the |
| \fBsudo\fR |
| front end doesn't support API |
| version 1.2 or higher, |
| \fRregister_hooks\fR |
| will not be called. |
| .PD |
.PP |
.PP |
.Vb 8 | .RE |
\& #define SUDO_API_VERSION_GET_MAJOR(v) ((v) >> 16) | .PD 0 |
\& #define SUDO_API_VERSION_GET_MINOR(v) ((v) & 0xffff) | .TP 6n |
\& #define SUDO_API_VERSION_SET_MAJOR(vp, n) do { \e | deregister_hooks |
\& *(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \e | .RS |
\& } while(0) | .nf |
\& #define SUDO_VERSION_SET_MINOR(vp, n) do { \e | .RS 0n |
\& *(vp) = (*(vp) & 0xffff0000) | (n); \e | void (*deregister_hooks)(int version, |
\& } while(0) | int (*deregister_hook)(struct sudo_hook *hook)); |
\& | .RE |
\& #define SUDO_API_VERSION_MAJOR 1 | .fi |
\& #define SUDO_API_VERSION_MINOR 0 | .sp |
\& #define SUDO_API_VERSION ((SUDO_API_VERSION_MAJOR << 16) | \e | The |
\& SUDO_API_VERSION_MINOR) | \fBderegister_hooks\fR() |
.Ve | function is called by the sudo front end |
.SS "I/O Plugin \s-1API\s0" | to deregister any hooks the plugin has registered. |
.IX Subsection "I/O Plugin API" | If the plugin does not support hooks, |
.Vb 10 | \fRderegister_hooks\fR |
\& struct io_plugin { | should be set to the |
\& #define SUDO_IO_PLUGIN 2 | \fRNULL\fR |
\& unsigned int type; /* always SUDO_IO_PLUGIN */ | pointer. |
\& unsigned int version; /* always SUDO_API_VERSION */ | .sp |
\& int (*open)(unsigned int version, sudo_conv_t conversation | The |
\& sudo_printf_t plugin_printf, char * const settings[], | \fIversion\fR |
\& char * const user_info[], int argc, char * const argv[], | argument describes the version of the hooks API |
\& char * const user_env[]); | supported by the |
\& void (*close)(int exit_status, int error); /* wait status or error */ | \fBsudo\fR |
\& int (*show_version)(int verbose); | front end. |
\& int (*log_ttyin)(const char *buf, unsigned int len); | .sp |
\& int (*log_ttyout)(const char *buf, unsigned int len); | The |
\& int (*log_stdin)(const char *buf, unsigned int len); | \fBderegister_hook\fR() |
\& int (*log_stdout)(const char *buf, unsigned int len); | function should be used to deregister any |
\& int (*log_stderr)(const char *buf, unsigned int len); | hooks that were put in place by the |
\& }; | \fBregister_hook\fR() |
.Ve | function. |
| If the plugin tries to deregister a hook that the front end does not support, |
| \fRderegister_hook\fR |
| will return an error. |
| .sp |
| See the |
| \fIHook function API\fR |
| section below for more information |
| about hooks. |
| .sp |
| NOTE: the |
| \fBderegister_hooks\fR() |
| function is only available starting |
| with API version 1.2. |
| If the |
| \fBsudo\fR |
| front end doesn't support API |
| version 1.2 or higher, |
| \fRderegister_hooks\fR |
| will not be called. |
| .RE |
| .PD |
.PP |
.PP |
When an I/O plugin is loaded, \fBsudo\fR runs the command in a pseudo-tty. | \fIPolicy Plugin Version Macros\fR |
| .nf |
| .sp |
| .RS 0n |
| /* 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,\e |
| 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 { \e |
| *(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \e |
| } while(0) |
| #define SUDO_VERSION_SET_MINOR(vp, n) do { \e |
| *(vp) = (*(vp) & 0xffff0000) | (n); \e |
| } while(0) |
| .RE |
| .fi |
| .SS "I/O plugin API" |
| .nf |
| .RS 0n |
| 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[], 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)); |
| }; |
| .RE |
| .fi |
| .PP |
| When an I/O plugin is loaded, |
| \fBsudo\fR |
| runs the command in a pseudo-tty. |
This makes it possible to log the input and output from the user's |
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 | session. |
error do not correspond to a tty, \fBsudo\fR will open a pipe to capture | If any of the standard input, standard output or standard error do not |
| correspond to a tty, |
| \fBsudo\fR |
| will open a pipe to capture |
the I/O for logging before passing it on. |
the I/O for logging before passing it on. |
.PP |
.PP |
The log_ttyin function receives the raw user input from the terminal |
The log_ttyin function receives the raw user input from the terminal |
device (note that this will include input even when echo is disabled, |
device (note that this will include input even when echo is disabled, |
such as when a password is read). The log_ttyout function receives | such as when a password is read). |
output from the pseudo-tty that is suitable for replaying the user's | The log_ttyout function receives output from the pseudo-tty that is |
session at a later time. The log_stdin, log_stdout and log_stderr | suitable for replaying the user's session at a later time. |
| The |
| \fBlog_stdin\fR(), |
| \fBlog_stdout\fR() |
| and |
| \fBlog_stderr\fR() |
functions are only called if the standard input, standard output |
functions are only called if the standard input, standard output |
or standard error respectively correspond to something other than |
or standard error respectively correspond to something other than |
a tty. |
a tty. |
.PP |
.PP |
Any of the logging functions may be set to the \s-1NULL\s0 | Any of the logging functions may be set to the |
pointer if no logging is to be performed. If the open function | \fRNULL\fR |
returns \f(CW0\fR, no I/O will be sent to the plugin. | pointer if no logging is to be performed. |
| If the open function returns 0, no I/O will be sent to the plugin. |
.PP |
.PP |
The io_plugin struct has the following fields: |
The io_plugin struct has the following fields: |
.IP "type" 4 | .TP 6n |
.IX Item "type" | type |
The \f(CW\*(C`type\*(C'\fR field should always be set to \s-1SUDO_IO_PLUGIN\s0 | The |
.IP "version" 4 | \fRtype\fR |
.IX Item "version" | field should always be set to |
The \f(CW\*(C`version\*(C'\fR field should be set to \s-1SUDO_API_VERSION\s0. | \fRSUDO_IO_PLUGIN\fR. |
.Sp | .TP 6n |
This allows \fBsudo\fR to determine the \s-1API\s0 version the plugin was | version |
| The |
| \fRversion\fR |
| field should be set to |
| \fRSUDO_API_VERSION\fR. |
| .sp |
| This allows |
| \fBsudo\fR |
| to determine the API version the plugin was |
built against. |
built against. |
.IP "open" 4 | .TP 6n |
.IX Item "open" | open |
.Vb 4 | .RS |
\& int (*open)(unsigned int version, sudo_conv_t conversation | .nf |
\& sudo_printf_t plugin_printf, char * const settings[], | .RS 0n |
\& char * const user_info[], int argc, char * const argv[], | int (*open)(unsigned int version, sudo_conv_t conversation |
\& char * const user_env[]); | sudo_printf_t plugin_printf, char * const settings[], |
.Ve | char * const user_info[], int argc, char * const argv[], |
.Sp | char * const user_env[], char * const plugin_options[]); |
The \fIopen\fR function is run before the \fIlog_input\fR, \fIlog_output\fR | .RE |
or \fIshow_version\fR functions are called. It is only called if the | .fi |
version is being requested or the \fIcheck_policy\fR function has | .sp |
returned successfully. It returns 1 on success, 0 on failure, \-1 | The |
if a general error occurred, or \-2 if there was a usage error. In | \fBopen\fR() |
the latter case, \fBsudo\fR will print a usage message before it exits. | function is run before the |
If an error occurs, the plugin may optionally call the conversation | \fBlog_input\fR(), |
or plugin_printf function with \f(CW\*(C`SUDO_CONF_ERROR_MSG\*(C'\fR to present | \fBlog_output\fR() |
| or |
| \fBshow_version\fR() |
| functions are called. |
| It is only called if the version is being requested or the |
| \fBcheck_policy\fR() |
| function has |
| 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 the latter case, |
| \fBsudo\fR |
| will print a usage message before it exits. |
| If an error occurs, the plugin may optionally call the |
| \fBconversation\fR() |
| or |
| \fBplugin_printf\fR() |
| function with |
| \fRSUDO_CONF_ERROR_MSG\fR |
| to present |
additional error information to the user. |
additional error information to the user. |
.Sp | .sp |
The function arguments are as follows: |
The function arguments are as follows: |
.RS 4 | .TP 6n |
.IP "version" 4 | version |
.IX Item "version" | The version passed in by |
The version passed in by \fBsudo\fR allows the plugin to determine the | \fBsudo\fR |
major and minor version number of the plugin \s-1API\s0 supported by | allows the plugin to determine the |
\&\fBsudo\fR. | major and minor version number of the plugin API supported by |
.IP "conversation" 4 | \fBsudo\fR. |
.IX Item "conversation" | .TP 6n |
A pointer to the conversation function that may be used by the | conversation |
\&\fIshow_version\fR function to display version information (see | A pointer to the |
show_version below). The conversation function may also be used | \fBconversation\fR() |
to display additional error message to the user. | function that may be used by the |
The conversation function returns 0 on success and \-1 on failure. | \fBshow_version\fR() |
.IP "plugin_printf" 4 | function to display version information (see |
.IX Item "plugin_printf" | \fBshow_version\fR() |
A pointer to a printf-style function that may be used by the | below). |
\&\fIshow_version\fR function to display version information (see | The |
show_version below). The plugin_printf function may also be used | \fBconversation\fR() |
to display additional error message to the user. | function may also be used to display additional error message to the user. |
The plugin_printf function returns number of characters printed on | The |
success and \-1 on failure. | \fBconversation\fR() |
.IP "settings" 4 | function returns 0 on success and \-1 on failure. |
.IX Item "settings" | .TP 6n |
A vector of user-supplied \fBsudo\fR settings in the form of \*(L"name=value\*(R" | plugin_printf |
strings. The vector is terminated by a \f(CW\*(C`NULL\*(C'\fR pointer. These | A pointer to a |
settings correspond to flags the user specified when running \fBsudo\fR. | \fBprintf\fR()-style |
| function that may be used by the |
| \fBshow_version\fR() |
| function to display version information (see |
| show_version below). |
| The |
| \fBplugin_printf\fR() |
| function may also be used to display additional error message to the user. |
| The |
| \fBplugin_printf\fR() |
| function returns number of characters printed on success and \-1 on failure. |
| .TP 6n |
| settings |
| A vector of user-supplied |
| \fBsudo\fR |
| settings in the form of |
| ``name=value'' |
| strings. |
| The vector is terminated by a |
| \fRNULL\fR |
| pointer. |
| These settings correspond to flags the user specified when running |
| \fBsudo\fR. |
As such, they will only be present when the corresponding flag has |
As such, they will only be present when the corresponding flag has |
been specified on the command line. |
been specified on the command line. |
.Sp | .sp |
When parsing \fIsettings\fR, the plugin should split on the \fBfirst\fR | When parsing |
equal sign ('=') since the \fIname\fR field will never include one | \fIsettings\fR, |
itself but the \fIvalue\fR might. | the plugin should split on the |
.Sp | \fBfirst\fR |
See the \*(L"Policy Plugin \s-1API\s0\*(R" section for a list of all possible settings. | equal sign |
.IP "user_info" 4 | (`=') |
.IX Item "user_info" | since the |
| \fIname\fR |
| field will never include one |
| itself but the |
| \fIvalue\fR |
| might. |
| .sp |
| See the |
| \fIPolicy plugin API\fR |
| section for a list of all possible settings. |
| .TP 6n |
| user_info |
A vector of information about the user running the command in the form of |
A vector of information about the user running the command in the form of |
\&\*(L"name=value\*(R" strings. The vector is terminated by a \f(CW\*(C`NULL\*(C'\fR pointer. | ``name=value'' |
.Sp | strings. |
When parsing \fIuser_info\fR, the plugin should split on the \fBfirst\fR | The vector is terminated by a |
equal sign ('=') since the \fIname\fR field will never include one | \fRNULL\fR |
itself but the \fIvalue\fR might. | |
.Sp | |
See the \*(L"Policy Plugin \s-1API\s0\*(R" section for a list of all possible strings. | |
.IP "argc" 4 | |
.IX Item "argc" | |
The number of elements in \fIargv\fR, not counting the final \f(CW\*(C`NULL\*(C'\fR | |
pointer. |
pointer. |
.IP "argv" 4 | .sp |
.IX Item "argv" | When parsing |
If non\-\f(CW\*(C`NULL\*(C'\fR, an argument vector describing a command the user | \fIuser_info\fR, |
| the plugin should split on the |
| \fBfirst\fR |
| equal sign |
| (`=') |
| since the |
| \fIname\fR |
| field will never include one |
| itself but the |
| \fIvalue\fR |
| might. |
| .sp |
| See the |
| \fIPolicy plugin API\fR |
| section for a list of all possible strings. |
| .TP 6n |
| argc |
| The number of elements in |
| \fIargv\fR, |
| not counting the final |
| \fRNULL\fR |
| pointer. |
| .TP 6n |
| argv |
| If |
| non-\fRNULL\fR, |
| 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 |
\&\fIexecve()\fR system call. | execve(2) |
.IP "user_env" 4 | system call. |
.IX Item "user_env" | .TP 6n |
The user's environment in the form of a \f(CW\*(C`NULL\*(C'\fR\-terminated vector of | user_env |
\&\*(L"name=value\*(R" strings. | The user's environment in the form of a |
.Sp | \fRNULL\fR-terminated |
When parsing \fIuser_env\fR, the plugin should split on the \fBfirst\fR | vector of |
equal sign ('=') since the \fIname\fR field will never include one | ``name=value'' |
itself but the \fIvalue\fR might. | strings. |
| .sp |
| When parsing |
| \fIuser_env\fR, |
| the plugin should split on the |
| \fBfirst\fR |
| equal sign |
| (`=') |
| since the |
| \fIname\fR |
| field will never include one |
| itself but the |
| \fIvalue\fR |
| might. |
| .TP 6n |
| plugin_options |
| 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 |
| \fRNULL\fR-terminated |
| array of strings. |
| If no arguments were specified, |
| \fIplugin_options\fR |
| will be the |
| \fRNULL\fR |
| pointer. |
| .sp |
| NOTE: the |
| \fIplugin_options\fR |
| parameter is only available starting with |
| API version 1.2. |
| A plugin |
| \fBmust\fR |
| check the API version specified |
| by the |
| \fBsudo\fR |
| front end before using |
| \fIplugin_options\fR. |
| Failure to do so may result in a crash. |
| .PP |
.RE |
.RE |
.RS 4 | .PD 0 |
| .TP 6n |
| close |
| .br |
| .RS |
| .nf |
| .RS 0n |
| void (*close)(int exit_status, int error); |
.RE |
.RE |
.IP "close" 4 | .fi |
.IX Item "close" | .sp |
.Vb 1 | The |
\& void (*close)(int exit_status, int error); | \fBclose\fR() |
.Ve | function is called when the command being run by |
.Sp | \fBsudo\fR |
The \f(CW\*(C`close\*(C'\fR function is called when the command being run by \fBsudo\fR | |
finishes. |
finishes. |
.Sp | .sp |
The function arguments are as follows: |
The function arguments are as follows: |
.RS 4 | .PD |
.IP "exit_status" 4 | .TP 6n |
.IX Item "exit_status" | exit_status |
The command's exit status, as returned by the \fIwait\fR\|(2) system call. | The command's exit status, as returned by the |
The value of \f(CW\*(C`exit_status\*(C'\fR is undefined if \f(CW\*(C`error\*(C'\fR is non-zero. | wait(2) |
.IP "error" 4 | system call. |
.IX Item "error" | The value of |
| \fRexit_status\fR |
| is undefined if |
| \fRerror\fR |
| is non-zero. |
| .TP 6n |
| error |
| .br |
If the command could not be executed, this is set to the value of |
If the command could not be executed, this is set to the value of |
\&\f(CW\*(C`errno\*(C'\fR set by the \fIexecve\fR\|(2) system call. If the command was | \fRerrno\fR |
successfully executed, the value of \f(CW\*(C`error\*(C'\fR is 0. | set by the |
| execve(2) |
| system call. |
| If the command was successfully executed, the value of |
| \fRerror\fR |
| is 0. |
| .PP |
.RE |
.RE |
.RS 4 | .PD 0 |
| .TP 6n |
| show_version |
| .RS |
| .nf |
| .RS 0n |
| int (*show_version)(int verbose); |
.RE |
.RE |
.IP "show_version" 4 | .fi |
.IX Item "show_version" | .sp |
.Vb 1 | The |
\& int (*show_version)(int verbose); | \fBshow_version\fR() |
.Ve | function is called by |
.Sp | \fBsudo\fR |
The \f(CW\*(C`show_version\*(C'\fR function is called by \fBsudo\fR when the user specifies | when the user specifies |
the \f(CW\*(C`\-V\*(C'\fR option. The plugin may display its version information | the |
to the user via the conversation or plugin_printf function using | \fB\-V\fR |
\&\f(CW\*(C`SUDO_CONV_INFO_MSG\*(C'\fR. If the user requests detailed version | option. |
information, the verbose flag will be set. | The plugin may display its version information to the user via the |
.IP "log_ttyin" 4 | \fBconversation\fR() |
.IX Item "log_ttyin" | or |
.Vb 1 | \fBplugin_printf\fR() |
\& int (*log_ttyin)(const char *buf, unsigned int len); | function using |
.Ve | \fRSUDO_CONV_INFO_MSG\fR. |
.Sp | If the user requests detailed version information, the verbose flag will be set. |
The \fIlog_ttyin\fR function is called whenever data can be read from | .PD |
the user but before it is passed to the running command. This | .PP |
allows the plugin to reject data if it chooses to (for instance | .RE |
if the input contains banned content). Returns \f(CW1\fR if the data | .PD 0 |
should be passed to the command, \f(CW0\fR if the data is rejected | .TP 6n |
(which will terminate the command) or \f(CW\*(C`\-1\*(C'\fR if an error occurred. | log_ttyin |
.Sp | .RS |
| .nf |
| .RS 0n |
| int (*log_ttyin)(const char *buf, unsigned int len); |
| .RE |
| .fi |
| .sp |
| The |
| \fBlog_ttyin\fR() |
| function is called whenever data can be read from |
| the user but before it is passed to the running command. |
| This allows the plugin to reject data if it chooses to (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 (which will terminate the command) or \-1 if an error occurred. |
| .sp |
The function arguments are as follows: |
The function arguments are as follows: |
.RS 4 | .PD |
.IP "buf" 4 | .TP 6n |
.IX Item "buf" | buf |
The buffer containing user input. |
The buffer containing user input. |
.IP "len" 4 | .TP 6n |
.IX Item "len" | len |
The length of \fIbuf\fR in bytes. | The length of |
| \fIbuf\fR |
| in bytes. |
| .PP |
.RE |
.RE |
.RS 4 | .PD 0 |
| .TP 6n |
| log_ttyout |
| .RS |
| .nf |
| .RS 0n |
| int (*log_ttyout)(const char *buf, unsigned int len); |
.RE |
.RE |
.IP "log_ttyout" 4 | .fi |
.IX Item "log_ttyout" | .sp |
.Vb 1 | The |
\& int (*log_ttyout)(const char *buf, unsigned int len); | \fBlog_ttyout\fR() |
.Ve | function is called whenever data can be read from |
.Sp | the command but before it is written to the user's terminal. |
The \fIlog_ttyout\fR function is called whenever data can be read from | This allows the plugin to reject data if it chooses to (for instance |
the command but before it is written to the user's terminal. This | if the output contains banned content). |
allows the plugin to reject data if it chooses to (for instance | Returns 1 if the data should be passed to the user, 0 if the data is rejected |
if the output contains banned content). Returns \f(CW1\fR if the data | (which will terminate the command) or \-1 if an error occurred. |
should be passed to the user, \f(CW0\fR if the data is rejected | .sp |
(which will terminate the command) or \f(CW\*(C`\-1\*(C'\fR if an error occurred. | |
.Sp | |
The function arguments are as follows: |
The function arguments are as follows: |
.RS 4 | .PD |
.IP "buf" 4 | .TP 6n |
.IX Item "buf" | buf |
The buffer containing command output. |
The buffer containing command output. |
.IP "len" 4 | .TP 6n |
.IX Item "len" | len |
The length of \fIbuf\fR in bytes. | The length of |
| \fIbuf\fR |
| in bytes. |
| .PP |
.RE |
.RE |
.RS 4 | .PD 0 |
| .TP 6n |
| log_stdin |
| .RS |
| .nf |
| .RS 0n |
| int (*log_stdin)(const char *buf, unsigned int len); |
.RE |
.RE |
.IP "log_stdin" 4 | .fi |
.IX Item "log_stdin" | .sp |
.Vb 1 | The |
\& int (*log_stdin)(const char *buf, unsigned int len); | \fBlog_stdin\fR() |
.Ve | function is only used if the standard input does |
.Sp | not correspond to a tty device. |
The \fIlog_stdin\fR function is only used if the standard input does | It is called whenever data can be read from the standard input but |
not correspond to a tty device. It is called whenever data can be | before it is passed to the running command. |
read from the standard input but before it is passed to the running | 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). |
(for instance if the input contains banned content). Returns \f(CW1\fR | Returns 1 if the data should be passed to the command, 0 if the data is |
if the data should be passed to the command, \f(CW0\fR if the data is | rejected (which will terminate the command) or \-1 if an error occurred. |
rejected (which will terminate the command) or \f(CW\*(C`\-1\*(C'\fR if an error | .sp |
occurred. | |
.Sp | |
The function arguments are as follows: |
The function arguments are as follows: |
.RS 4 | .PD |
.IP "buf" 4 | .TP 6n |
.IX Item "buf" | buf |
The buffer containing user input. |
The buffer containing user input. |
.IP "len" 4 | .TP 6n |
.IX Item "len" | len |
The length of \fIbuf\fR in bytes. | The length of |
| \fIbuf\fR |
| in bytes. |
| .PP |
.RE |
.RE |
.RS 4 | .PD 0 |
| .TP 6n |
| log_stdout |
| .RS |
| .nf |
| .RS 0n |
| int (*log_stdout)(const char *buf, unsigned int len); |
.RE |
.RE |
.IP "log_stdout" 4 | .fi |
.IX Item "log_stdout" | .sp |
.Vb 1 | The |
\& int (*log_stdout)(const char *buf, unsigned int len); | \fBlog_stdout\fR() |
.Ve | function is only used if the standard output does not correspond |
.Sp | to a tty device. |
The \fIlog_stdout\fR function is only used if the standard output does | It is called whenever data can be read from the command but before |
not correspond to a tty device. It is called whenever data can be | it is written to the standard output. |
read from the command but before it is written to the standard | This allows the plugin to reject data if it chooses to |
output. This allows the plugin to reject data if it chooses to | (for instance if the output contains banned content). |
(for instance if the output contains banned content). Returns \f(CW1\fR | Returns 1 if the data should be passed to the user, 0 if the data is |
if the data should be passed to the user, \f(CW0\fR if the data is | rejected (which will terminate the command) or \-1 if an error occurred. |
rejected (which will terminate the command) or \f(CW\*(C`\-1\*(C'\fR if an error | .sp |
occurred. | |
.Sp | |
The function arguments are as follows: |
The function arguments are as follows: |
.RS 4 | .PD |
.IP "buf" 4 | .TP 6n |
.IX Item "buf" | buf |
The buffer containing command output. |
The buffer containing command output. |
.IP "len" 4 | .TP 6n |
.IX Item "len" | len |
The length of \fIbuf\fR in bytes. | The length of |
| \fIbuf\fR |
| in bytes. |
| .PP |
.RE |
.RE |
.RS 4 | .PD 0 |
| .TP 6n |
| log_stderr |
| .RS |
| .nf |
| .RS 0n |
| int (*log_stderr)(const char *buf, unsigned int len); |
.RE |
.RE |
.IP "log_stderr" 4 | .fi |
.IX Item "log_stderr" | .sp |
.Vb 1 | The |
\& int (*log_stderr)(const char *buf, unsigned int len); | \fBlog_stderr\fR() |
.Ve | function is only used if the standard error does |
.Sp | not correspond to a tty device. |
The \fIlog_stderr\fR function is only used if the standard error does | It is called whenever data can be read from the command but before it |
not correspond to a tty device. It is called whenever data can be | 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 |
error. This allows the plugin to reject data if it chooses to | (for instance if the output contains banned content). |
(for instance if the output contains banned content). Returns \f(CW1\fR | Returns 1 if the data should be passed to the user, 0 if the data is |
if the data should be passed to the user, \f(CW0\fR if the data is | rejected (which will terminate the command) or \-1 if an error occurred. |
rejected (which will terminate the command) or \f(CW\*(C`\-1\*(C'\fR if an error | .sp |
occurred. | |
.Sp | |
The function arguments are as follows: |
The function arguments are as follows: |
.RS 4 | .PD |
.IP "buf" 4 | .TP 6n |
.IX Item "buf" | buf |
The buffer containing command output. |
The buffer containing command output. |
.IP "len" 4 | .TP 6n |
.IX Item "len" | len |
The length of \fIbuf\fR in bytes. | The length of |
| \fIbuf\fR |
| in bytes. |
| .PP |
.RE |
.RE |
.RS 4 | .PD 0 |
| .TP 6n |
| register_hooks |
| See the |
| \fIPolicy plugin API\fR |
| section for a description of |
| \fRregister_hooks\fR. |
| .PD |
| .TP 6n |
| deregister_hooks |
| See the |
| \fIPolicy plugin API\fR |
| section for a description of |
| \fRderegister_hooks.\fR |
| .PP |
| \fII/O Plugin Version Macros\fR |
| .PP |
| Same as for the |
| \fIPolicy plugin API\fR. |
| .SS "Hook function API" |
| Beginning with plugin API version 1.2, it is possible to install |
| hooks for certain functions called by the |
| \fBsudo\fR |
| front end. |
| .PP |
| 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 |
| \fBsudo\fR |
| front end functions as well. |
| .PP |
| \fIHook structure\fR |
| .PP |
| Hooks in |
| \fBsudo\fR |
| are described by the following structure: |
| .nf |
| .sp |
| .RS 0n |
| typedef int (*sudo_hook_fn_t)(); |
| |
| struct sudo_hook { |
| int hook_version; |
| int hook_type; |
| sudo_hook_fn_t hook_fn; |
| void *closure; |
| }; |
.RE |
.RE |
|
.fi |
.PP |
.PP |
\fIVersion macros\fR | The |
.IX Subsection "Version macros" | \fRsudo_hook\fR |
| structure has the following fields: |
| .TP 6n |
| hook_version |
| The |
| \fRhook_version\fR |
| field should be set to |
| \fRSUDO_HOOK_VERSION\fR. |
| .TP 6n |
| hook_type |
| The |
| \fRhook_type\fR |
| field may be one of the following supported hook types: |
| .RS |
| .TP 6n |
| \fRSUDO_HOOK_SETENV\fR |
| The C library |
| setenv(3) |
| function. |
| Any registered hooks will run before the C library implementation. |
| The |
| \fRhook_fn\fR |
| field should |
| be a function that matches the following typedef: |
| .RS |
| .nf |
| .sp |
| .RS 0n |
| typedef int (*sudo_hook_fn_setenv_t)(const char *name, |
| const char *value, int overwrite, void *closure); |
| .RE |
| .fi |
| .sp |
| If the registered hook does not match the typedef the results are |
| unspecified. |
.PP |
.PP |
Same as for the \*(L"Policy Plugin \s-1API\s0\*(R". | .RE |
.SS "Conversation \s-1API\s0" | .PD 0 |
.IX Subsection "Conversation API" | .TP 6n |
If the plugin needs to interact with the user, it may do so via the | \fRSUDO_HOOK_UNSETENV\fR |
conversation function. A plugin should not attempt to read directly | The C library |
from the standard input or the user's tty (neither of which are | unsetenv(3) |
guaranteed to exist). The caller must include a trailing newline | function. |
in \f(CW\*(C`msg\*(C'\fR if one is to be printed. | Any registered hooks will run before the C library implementation. |
| The |
| \fRhook_fn\fR |
| field should |
| be a function that matches the following typedef: |
| .RS |
| .nf |
| .sp |
| .RS 0n |
| typedef int (*sudo_hook_fn_unsetenv_t)(const char *name, |
| void *closure); |
| .RE |
| .fi |
| .PD |
.PP |
.PP |
A printf-style function is also available that can be used to display | .RE |
informational or error messages to the user, which is usually more | .PD 0 |
convenient for simple messages where no use input is required. | .TP 6n |
| \fRSUDO_HOOK_GETENV\fR |
| The C library |
| getenv(3) |
| function. |
| Any registered hooks will run before the C library implementation. |
| The |
| \fRhook_fn\fR |
| field should |
| be a function that matches the following typedef: |
| .RS |
| .nf |
| .sp |
| .RS 0n |
| typedef int (*sudo_hook_fn_getenv_t)(const char *name, |
| char **value, void *closure); |
| .RE |
| .fi |
| .sp |
| If the registered hook does not match the typedef the results are |
| unspecified. |
| .PD |
.PP |
.PP |
.Vb 11 | .RE |
\& struct sudo_conv_message { | .PD 0 |
\& #define SUDO_CONV_PROMPT_ECHO_OFF 0x0001 /* do not echo user input */ | .TP 6n |
\& #define SUDO_CONV_PROMPT_ECHO_ON 0x0002 /* echo user input */ | \fRSUDO_HOOK_PUTENV\fR |
\& #define SUDO_CONV_ERROR_MSG 0x0003 /* error message */ | The C library |
\& #define SUDO_CONV_INFO_MSG 0x0004 /* informational message */ | putenv(3) |
\& #define SUDO_CONV_PROMPT_MASK 0x0005 /* mask user input */ | function. |
\& #define SUDO_CONV_PROMPT_ECHO_OK 0x1000 /* flag: allow echo if no tty */ | Any registered hooks will run before the C library implementation. |
\& int msg_type; | The |
\& int timeout; | \fRhook_fn\fR |
\& const char *msg; | field should |
\& }; | be a function that matches the following typedef: |
\& | .RS |
\& struct sudo_conv_reply { | .nf |
\& char *reply; | .sp |
\& }; | .RS 0n |
\& | typedef int (*sudo_hook_fn_putenv_t)(char *string, |
\& typedef int (*sudo_conv_t)(int num_msgs, | void *closure); |
\& const struct sudo_conv_message msgs[], | .RE |
\& struct sudo_conv_reply replies[]); | .fi |
\& | .sp |
\& typedef int (*sudo_printf_t)(int msg_type, const char *fmt, ...); | If the registered hook does not match the typedef the results are |
.Ve | unspecified. |
| .RE |
| .PD |
.PP |
.PP |
Pointers to the conversation and printf-style functions are passed | .RE |
in to the plugin's \f(CW\*(C`open\*(C'\fR function when the plugin is initialized. | .PD 0 |
| .TP 6n |
| hook_fn |
| sudo_hook_fn_t hook_fn; |
| .sp |
| The |
| \fRhook_fn\fR |
| field should be set to the plugin's hook implementation. |
| The actual function arguments will vary depending on the |
| \fRhook_type\fR |
| (see |
| \fRhook_type\fR |
| above). |
| In all cases, the |
| \fRclosure\fR |
| field of |
| \fRstruct sudo_hook\fR |
| is passed as the last function parameter. |
| This can be used to pass arbitrary data to the plugin's hook implementation. |
| .sp |
| The function return value may be one of the following: |
| .RS |
| .PD |
| .TP 6n |
| \fRSUDO_HOOK_RET_ERROR\fR |
| The hook function encountered an error. |
| .TP 6n |
| \fRSUDO_HOOK_RET_NEXT\fR |
| 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 |
| \fRSUDO_HOOK_RET_NEXT\fR |
| if the specified variable was not found in the private copy of the environment. |
| .TP 6n |
| \fRSUDO_HOOK_RET_STOP\fR |
| The hook completed without error, stop processing hooks for this invocation. |
| This can be used to replace the native implementation. |
| For example, a |
| \fRsetenv\fR |
| hook that operates on a private copy of |
| the environment but leaves |
| \fRenviron\fR |
| unchanged. |
| .RE |
.PP |
.PP |
To use the conversation function, the plugin must pass an array of | Note that it is very easy to create an infinite loop when hooking |
\&\f(CW\*(C`sudo_conv_message\*(C'\fR and \f(CW\*(C`sudo_conv_reply\*(C'\fR structures. There must | C library functions. |
be a \f(CW\*(C`struct sudo_conv_message\*(C'\fR and \f(CW\*(C`struct sudo_conv_reply\*(C'\fR for | For example, a |
each message in the conversation. The plugin is responsible for | getenv(3) |
freeing the reply buffer filled in to the \f(CW\*(C`struct sudo_conv_reply\*(C'\fR, | 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: |
| .nf |
| .sp |
| .RS 0n |
| 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; |
| .RE |
| .fi |
| .PP |
| \fIHook API Version Macros\fR |
| .nf |
| .sp |
| .RS 0n |
| /* 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,\e |
| 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 { \e |
| *(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \e |
| } while(0) |
| #define SUDO_HOOK_VERSION_SET_MINOR(vp, n) do { \e |
| *(vp) = (*(vp) & 0xffff0000) | (n); \e |
| } while(0) |
| .RE |
| .fi |
| .SS "Conversation API" |
| If the plugin needs to interact with the user, it may do so via the |
| \fBconversation\fR() |
| function. |
| A plugin should not attempt to read directly from the standard input |
| or the user's tty (neither of which are guaranteed to exist). |
| The caller must include a trailing newline in |
| \fRmsg\fR |
| if one is to be printed. |
| .PP |
| A |
| \fBprintf\fR()-style |
| function is also available that can be used to display informational |
| or error messages to the user, which is usually more convenient for |
| simple messages where no use input is required. |
| .nf |
| .sp |
| .RS 0n |
| struct sudo_conv_message { |
| #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_ERROR_MSG 0x0003 /* error message */ |
| #define SUDO_CONV_INFO_MSG 0x0004 /* informational message */ |
| #define SUDO_CONV_PROMPT_MASK 0x0005 /* mask user input */ |
| #define SUDO_CONV_DEBUG_MSG 0x0006 /* debugging message */ |
| #define SUDO_CONV_PROMPT_ECHO_OK 0x1000 /* flag: allow echo if no tty */ |
| int msg_type; |
| int timeout; |
| const char *msg; |
| }; |
| |
| struct sudo_conv_reply { |
| char *reply; |
| }; |
| |
| typedef int (*sudo_conv_t)(int num_msgs, |
| const struct sudo_conv_message msgs[], |
| struct sudo_conv_reply replies[]); |
| |
| typedef int (*sudo_printf_t)(int msg_type, const char *fmt, ...); |
| .RE |
| .fi |
| .PP |
| Pointers to the |
| \fBconversation\fR() |
| and |
| \fBprintf\fR()-style |
| functions are passed |
| in to the plugin's |
| \fBopen\fR() |
| function when the plugin is initialized. |
| .PP |
| To use the |
| \fBconversation\fR() |
| function, the plugin must pass an array of |
| \fRsudo_conv_message\fR |
| and |
| \fRsudo_conv_reply\fR |
| structures. |
| There must be a |
| \fRstruct sudo_conv_message\fR |
| and |
| \fRstruct sudo_conv_reply\fR |
| for |
| each message in the conversation. |
| The plugin is responsible for freeing the reply buffer filled in to the |
| \fRstruct sudo_conv_reply\fR, |
if any. |
if any. |
.PP |
.PP |
The printf-style function uses the same underlying mechanism as the | The |
conversation function but only supports \f(CW\*(C`SUDO_CONV_INFO_MSG\*(C'\fR and | \fBprintf\fR()-style |
\&\f(CW\*(C`SUDO_CONV_ERROR_MSG\*(C'\fR for the \fImsg_type\fR parameter. It can be | function uses the same underlying mechanism as the |
more convenient than using the conversation function if no user | \fBconversation\fR() |
reply is needed and supports standard \fIprintf()\fR escape sequences. | function but only supports |
| \fRSUDO_CONV_INFO_MSG\fR, |
| \fRSUDO_CONV_ERROR_MSG\fR |
| and |
| \fRSUDO_CONV_DEBUG_MSG\fR |
| for the |
| \fImsg_type\fR |
| parameter. |
| It can be more convenient than using the |
| \fBconversation\fR() |
| function if no user reply is needed and supports standard |
| \fBprintf\fR() |
| escape sequences. |
.PP |
.PP |
See the sample plugin for an example of the conversation function usage. | Unlike, |
.SS "Sudoers Group Plugin \s-1API\s0" | \fRSUDO_CONV_INFO_MSG\fR |
.IX Subsection "Sudoers Group Plugin API" | and |
The \fIsudoers\fR module supports a plugin interface to allow non-Unix | Dv SUDO_CONV_ERROR_MSG , |
group lookups. This can be used to query a group source other than | messages |
the standard Unix group database. A sample group plugin is bundled | sent with the |
with \fBsudo\fR that implements file-based lookups. Third party group | \fRSUDO_CONV_DEBUG_MSG\fR |
plugins include a \s-1QAS\s0 \s-1AD\s0 plugin available from Quest Software. | \fImsg_type\fR |
| are not directly |
| user-visible. |
| Instead, they are logged to the file specified in the |
| \fRDebug\fR |
| statement (if any) in the |
| \fI@sysconfdir@/sudo.conf\fR |
.PP |
.PP |
A group plugin must declare and populate a \f(CW\*(C`sudoers_group_plugin\*(C'\fR | file. |
struct in the global scope. This structure contains pointers to | This allows a plugin to log debugging information and is intended |
the functions that implement plugin initialization, cleanup and | to be used in conjunction with the |
group lookup. | \fIdebug_flags\fR |
| setting. |
.PP |
.PP |
.Vb 8 | See the sample plugin for an example of the |
\& struct sudoers_group_plugin { | \fBconversation\fR() |
\& unsigned int version; | function usage. |
\& int (*init)(int version, sudo_printf_t sudo_printf, | .SS "Sudoers group plugin API" |
\& char *const argv[]); | The |
\& void (*cleanup)(void); | \fIsudoers\fR |
\& int (*query)(const char *user, const char *group, | module supports a plugin interface to allow non-Unix |
\& const struct passwd *pwd); | group lookups. |
\&}; | This can be used to query a group source other than the standard Unix |
.Ve | group database. |
| A sample group plugin is bundled with |
| \fBsudo\fR |
| that implements file-based lookups. |
| Third party group plugins include a QAS AD plugin available from Quest Software. |
.PP |
.PP |
The \f(CW\*(C`sudoers_group_plugin\*(C'\fR struct has the following fields: | A group plugin must declare and populate a |
.IP "version" 4 | \fRsudoers_group_plugin\fR |
.IX Item "version" | struct in the global scope. |
The \f(CW\*(C`version\*(C'\fR field should be set to \s-1GROUP_API_VERSION\s0. | This structure contains pointers to the functions that implement plugin |
.Sp | initialization, cleanup and group lookup. |
This allows \fIsudoers\fR to determine the \s-1API\s0 version the group plugin | .nf |
| .sp |
| .RS 0n |
| 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); |
| }; |
| .RE |
| .fi |
| .PP |
| The |
| \fRsudoers_group_plugin\fR |
| struct has the following fields: |
| .TP 6n |
| version |
| The |
| \fRversion\fR |
| field should be set to GROUP_API_VERSION. |
| .sp |
| This allows |
| \fIsudoers\fR |
| to determine the API version the group plugin |
was built against. |
was built against. |
.IP "init" 4 | .TP 6n |
.IX Item "init" | init |
.Vb 2 | .RS |
\& int (*init)(int version, sudo_printf_t plugin_printf, | .nf |
\& char *const argv[]); | .RS 0n |
.Ve | int (*init)(int version, sudo_printf_t plugin_printf, |
.Sp | char *const argv[]); |
The \fIinit\fR function is called after \fIsudoers\fR has been parsed but | .RE |
before any policy checks. It returns 1 on success, 0 on failure | .fi |
(or if the plugin is not configured), and \-1 if a error occurred. | .sp |
If an error occurs, the plugin may call the plugin_printf function | The |
with \f(CW\*(C`SUDO_CONF_ERROR_MSG\*(C'\fR to present additional error information | \fBinit\fR() |
| function is called after |
| \fIsudoers\fR |
| has been parsed but |
| 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. |
| If an error occurs, the plugin may call the |
| \fBplugin_printf\fR() |
| function with |
| \fRSUDO_CONF_ERROR_MSG\fR |
| to present additional error information |
to the user. |
to the user. |
.Sp | .sp |
The function arguments are as follows: |
The function arguments are as follows: |
.RS 4 | .TP 6n |
.IP "version" 4 | version |
.IX Item "version" | The version passed in by |
The version passed in by \fIsudoers\fR allows the plugin to determine the | \fIsudoers\fR |
major and minor version number of the group plugin \s-1API\s0 supported by | allows the plugin to determine the |
\&\fIsudoers\fR. | major and minor version number of the group plugin API supported by |
.IP "plugin_printf" 4 | \fIsudoers\fR. |
.IX Item "plugin_printf" | .TP 6n |
A pointer to a printf-style function that may be used to display | plugin_printf |
informational or error message to the user. | A pointer to a |
| \fBprintf\fR()-style |
| function that may be used to display informational or error message to the user. |
Returns the number of characters printed on success and \-1 on failure. |
Returns the number of characters printed on success and \-1 on failure. |
.IP "argv" 4 | .TP 6n |
.IX Item "argv" | argv |
A NULL-terminated array of arguments generated from the \fIgroup_plugin\fR | A |
option in \fIsudoers\fR. If no arguments were given, \fIargv\fR will be | \fRNULL\fR-terminated |
\&\s-1NULL\s0. | array of arguments generated from the |
| \fIgroup_plugin\fR |
| option in |
| \fIsudoers\fR. |
| If no arguments were given, |
| \fIargv\fR |
| will be |
| \fRNULL\fR. |
| .PP |
.RE |
.RE |
.RS 4 | .PD 0 |
| .TP 6n |
| cleanup |
| .RS |
| .nf |
| .RS 0n |
| void (*cleanup)(); |
.RE |
.RE |
.IP "cleanup" 4 | .fi |
.IX Item "cleanup" | .sp |
.Vb 1 | The |
\& void (*cleanup)(); | \fBcleanup\fR() |
.Ve | function is called when |
.Sp | \fIsudoers\fR |
The \fIcleanup\fR function is called when \fIsudoers\fR has finished its | has finished its |
group checks. The plugin should free any memory it has allocated | group checks. |
and close open file handles. | The plugin should free any memory it has allocated and close open file handles. |
.IP "query" 4 | .PD |
.IX Item "query" | .PP |
.Vb 2 | .RE |
\& int (*query)(const char *user, const char *group, | .PD 0 |
\& const struct passwd *pwd); | .TP 6n |
.Ve | query |
.Sp | .br |
The \fIquery\fR function is used to ask the group plugin whether \fIuser\fR | .RS |
is a member of \fIgroup\fR. | .nf |
.Sp | .RS 0n |
| int (*query)(const char *user, const char *group, |
| const struct passwd *pwd); |
| .RE |
| .fi |
| .sp |
| The |
| \fBquery\fR() |
| function is used to ask the group plugin whether |
| \fIuser\fR |
| is a member of |
| \fIgroup\fR. |
| .sp |
The function arguments are as follows: |
The function arguments are as follows: |
.RS 4 | .PD |
.IP "user" 4 | .TP 6n |
.IX Item "user" | user |
The name of the user being looked up in the external group database. |
The name of the user being looked up in the external group database. |
.IP "group" 4 | .TP 6n |
.IX Item "group" | group |
| .br |
The name of the group being queried. |
The name of the group being queried. |
.IP "pwd" 4 | .TP 6n |
.IX Item "pwd" | pwd |
The password database entry for \fIuser\fR, if any. If \fIuser\fR is not | The password database entry for |
present in the password database, \fIpwd\fR will be \f(CW\*(C`NULL\*(C'\fR. | \fIuser\fR, |
| if any. |
| If |
| \fIuser\fR |
| is not |
| present in the password database, |
| \fIpwd\fR |
| will be |
| \fRNULL\fR. |
.RE |
.RE |
.RS 4 |
|
.RE |
|
.PP |
.PP |
\fIVersion Macros\fR | \fIGroup API Version Macros\fR |
.IX Subsection "Version Macros" | .nf |
.PP | .sp |
.Vb 5 | .RS 0n |
\& /* 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) | \e | #define GROUP_API_VERSION ((GROUP_API_VERSION_MAJOR << 16) | \e |
\& 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 { \e | #define GROUP_API_VERSION_SET_MAJOR(vp, n) do { \e |
\& *(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \e | *(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \e |
\& } while(0) | } while(0) |
\& #define GROUP_API_VERSION_SET_MINOR(vp, n) do { \e | #define GROUP_API_VERSION_SET_MINOR(vp, n) do { \e |
\& *(vp) = (*(vp) & 0xffff0000) | (n); \e | *(vp) = (*(vp) & 0xffff0000) | (n); \e |
\& } while(0) | } while(0) |
.Ve | .RE |
| .fi |
| .SH "PLUGIN API CHANGELOG" |
| The following revisions have been made to the Sudo Plugin API. |
| .TP 6n |
| Version 1.0 |
| Initial API version. |
| .TP 6n |
| Version 1.1 |
| The I/O logging plugin's |
| \fBopen\fR() |
| function was modified to take the |
| \fRcommand_info\fR |
| list as an argument. |
| .TP 6n |
| Version 1.2 |
| The Policy and I/O logging plugins' |
| \fBopen\fR() |
| functions are now passed |
| a list of plugin options if any are specified in |
| \fI@sysconfdir@/sudo.conf\fR. |
| .sp |
| A simple hooks API has been introduced to allow plugins to hook in to the |
| system's environment handling functions. |
| .sp |
| The |
| \fRinit_session\fR |
| 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. |
.SH "SEE ALSO" |
.SH "SEE ALSO" |
.IX Header "SEE ALSO" | sudoers(@mansectform@), |
\&\fIsudoers\fR\|(@mansectform@), \fIsudo\fR\|(@mansectsu@) | sudo(@mansectsu@) |
.SH "BUGS" |
.SH "BUGS" |
.IX Header "BUGS" | If you feel you have found a bug in |
If you feel you have found a bug in \fBsudo\fR, please submit a bug report | \fBsudo\fR, |
at http://www.sudo.ws/sudo/bugs/ | please submit a bug report at http://www.sudo.ws/sudo/bugs/ |
.SH "SUPPORT" |
.SH "SUPPORT" |
.IX Header "SUPPORT" | Limited free support is available via the sudo-users mailing list, |
Limited free support is available via the sudo-workers mailing list, | see http://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or |
see http://www.sudo.ws/mailman/listinfo/sudo\-workers to subscribe or | |
search the archives. |
search the archives. |
.SH "DISCLAIMER" |
.SH "DISCLAIMER" |
.IX Header "DISCLAIMER" | \fBsudo\fR |
\&\fBsudo\fR is provided ``\s-1AS\s0 \s-1IS\s0'' and any express or implied warranties, | is provided |
including, but not limited to, the implied warranties of merchantability | ``AS IS'' |
and fitness for a particular purpose are disclaimed. See the \s-1LICENSE\s0 | and any express or implied warranties, including, but not limited |
file distributed with \fBsudo\fR or http://www.sudo.ws/sudo/license.html | to, the implied warranties of merchantability and fitness for a |
for complete details. | particular purpose are disclaimed. |
| See the LICENSE file distributed with |
| \fBsudo\fR |
| or http://www.sudo.ws/sudo/license.html for complete details. |