1267 lines
48 KiB
Groff
1267 lines
48 KiB
Groff
.\" Copyright (c) 2009-2011 Todd C. Miller <Todd.Miller@courtesan.com>
|
|
.\"
|
|
.\" Permission to use, copy, modify, and distribute this software for any
|
|
.\" purpose with or without fee is hereby granted, provided that the above
|
|
.\" copyright notice and this permission notice appear in all copies.
|
|
.\"
|
|
.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
.\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
.\"
|
|
.\" Automatically generated by Pod::Man 2.23 (Pod::Simple 3.14)
|
|
.\"
|
|
.\" Standard preamble:
|
|
.\" ========================================================================
|
|
.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@ "February 21, 2011" "1.8.0rc1" "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
|
|
.SH "NAME"
|
|
sudo_plugin \- Sudo Plugin API
|
|
.SH "DESCRIPTION"
|
|
.IX Header "DESCRIPTION"
|
|
Starting with version 1.8, \fBsudo\fR supports a plugin \s-1API\s0
|
|
for policy and session logging. By default, the \fIsudoers\fR policy
|
|
plugin and an associated I/O logging plugin are used. Via the plugin
|
|
\&\s-1API\s0, \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
|
|
The \s-1API\s0 is versioned with a major and minor number. The minor
|
|
version number is incremented when additions are made. The major
|
|
number is incremented when incompatible changes are made. A plugin
|
|
should be check the version passed to it and make sure that the
|
|
major version matches.
|
|
.PP
|
|
The plugin \s-1API\s0 is defined by the \f(CW\*(C`sudo_plugin.h\*(C'\fR header file.
|
|
.SS "The sudo.conf File"
|
|
.IX Subsection "The sudo.conf File"
|
|
The \fI@sysconfdir@/sudo.conf\fR file contains plugin configuration directives.
|
|
Currently, the only supported keyword is the \f(CW\*(C`Plugin\*(C'\fR directive,
|
|
which causes a plugin plugin to be loaded.
|
|
.PP
|
|
A \f(CW\*(C`Plugin\*(C'\fR line consists of the \f(CW\*(C`Plugin\*(C'\fR keyword, followed by the
|
|
\&\fIsymbol_name\fR and the \fIpath\fR to the shared object containing the
|
|
plugin. The \fIsymbol_name\fR is the name of the \f(CW\*(C`struct policy_plugin\*(C'\fR
|
|
or \f(CW\*(C`struct io_plugin\*(C'\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 ignored. Lines that don't begin
|
|
with \f(CW\*(C`Plugin\*(C'\fR or \f(CW\*(C`Path\*(C'\fR are silently ignored.
|
|
.PP
|
|
The same shared object may contain multiple plugins, each with a
|
|
different symbol name. The shared object file must be owned by uid
|
|
0 and only writable by its owner. Because of ambiguities that arise
|
|
from composite policies, only a single policy plugin may be specified.
|
|
This limitation does not apply to I/O plugins.
|
|
.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:
|
|
.IP "type" 4
|
|
.IX Item "type"
|
|
The \f(CW\*(C`type\*(C'\fR field should always be set to \s-1SUDO_POLICY_PLUGIN\s0.
|
|
.IP "version" 4
|
|
.IX Item "version"
|
|
The \f(CW\*(C`version\*(C'\fR field should be set to \s-1SUDO_API_VERSION\s0.
|
|
.Sp
|
|
This allows \fBsudo\fR to determine the \s-1API\s0 version the plugin was
|
|
built against.
|
|
.IP "open" 4
|
|
.IX Item "open"
|
|
.Vb 3
|
|
\& 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[]);
|
|
.Ve
|
|
.Sp
|
|
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 conversation or plugin_printf function
|
|
with \f(CW\*(C`SUDO_CONF_ERROR_MSG\*(C'\fR to present additional error information
|
|
to the user.
|
|
.Sp
|
|
The function arguments are as follows:
|
|
.RS 4
|
|
.IP "version" 4
|
|
.IX Item "version"
|
|
The version passed in by \fBsudo\fR allows the plugin to determine the
|
|
major and minor version number of the plugin \s-1API\s0 supported by
|
|
\&\fBsudo\fR.
|
|
.IP "conversation" 4
|
|
.IX Item "conversation"
|
|
A pointer to the conversation function that can be used by the
|
|
plugin to interact with the user (see below).
|
|
Returns 0 on success and \-1 on failure.
|
|
.IP "plugin_printf" 4
|
|
.IX Item "plugin_printf"
|
|
A pointer to a printf-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.
|
|
.IP "settings" 4
|
|
.IX Item "settings"
|
|
A vector of user-supplied \fBsudo\fR settings in the form of \*(L"name=value\*(R"
|
|
strings. The vector is terminated by a \f(CW\*(C`NULL\*(C'\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
|
|
been specified on the command line.
|
|
.Sp
|
|
When parsing \fIsettings\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.
|
|
.RS 4
|
|
.IP "debug_level=number" 4
|
|
.IX Item "debug_level=number"
|
|
A numeric debug level, from 1\-9, if specified via the \f(CW\*(C`\-D\*(C'\fR flag.
|
|
.IP "runas_user=string" 4
|
|
.IX Item "runas_user=string"
|
|
The user name or uid to to run the command as, if specified via the
|
|
\&\f(CW\*(C`\-u\*(C'\fR flag.
|
|
.IP "runas_group=string" 4
|
|
.IX Item "runas_group=string"
|
|
The group name or gid to to run the command as, if specified via
|
|
the \f(CW\*(C`\-g\*(C'\fR flag.
|
|
.IP "prompt=string" 4
|
|
.IX Item "prompt=string"
|
|
The prompt to use when requesting a password, if specified via
|
|
the \f(CW\*(C`\-p\*(C'\fR flag.
|
|
.IP "set_home=bool" 4
|
|
.IX Item "set_home=bool"
|
|
Set to true if the user specified the \f(CW\*(C`\-H\*(C'\fR flag. If true, set the
|
|
\&\f(CW\*(C`HOME\*(C'\fR environment variable to the target user's home directory.
|
|
.IP "preserve_environment=bool" 4
|
|
.IX Item "preserve_environment=bool"
|
|
Set to true if the user specified the \f(CW\*(C`\-E\*(C'\fR flag, indicating that
|
|
the user wishes to preserve the environment.
|
|
.IP "login_shell=bool" 4
|
|
.IX Item "login_shell=bool"
|
|
Set to true if the user specified the \f(CW\*(C`\-i\*(C'\fR flag, indicating that
|
|
the user wishes to run a login shell.
|
|
.IP "implied_shell=bool" 4
|
|
.IX Item "implied_shell=bool"
|
|
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
|
|
\&\fIimplied_shell\fR to true. This allows \fBsudo\fR with no arguments
|
|
to be used similarly to \fIsu\fR\|(1). If the plugin does not to support
|
|
this usage, it may return a value of \-2 from the \f(CW\*(C`check_policy\*(C'\fR
|
|
function, which will cause \fBsudo\fR to print a usage message and
|
|
exit.
|
|
.IP "preserve_groups=bool" 4
|
|
.IX Item "preserve_groups=bool"
|
|
Set to true if the user specified the \f(CW\*(C`\-P\*(C'\fR flag, indicating that
|
|
the user wishes to preserve the group vector instead of setting it
|
|
based on the runas user.
|
|
.IP "ignore_ticket=bool" 4
|
|
.IX Item "ignore_ticket=bool"
|
|
Set to true if the user specified the \f(CW\*(C`\-k\*(C'\fR flag along with a
|
|
command, indicating that the user wishes to ignore any cached
|
|
authentication credentials.
|
|
.IP "noninteractive=bool" 4
|
|
.IX Item "noninteractive=bool"
|
|
Set to true if the user specified the \f(CW\*(C`\-n\*(C'\fR flag, indicating that
|
|
\&\fBsudo\fR should operate in non-interactive mode. The plugin may
|
|
reject a command run in non-interactive mode if user interaction
|
|
is required.
|
|
.IP "login_class=string" 4
|
|
.IX Item "login_class=string"
|
|
\&\s-1BSD\s0 login class to use when setting resource limits and nice value,
|
|
if specified by the \f(CW\*(C`\-c\*(C'\fR flag.
|
|
.IP "selinux_role=string" 4
|
|
.IX Item "selinux_role=string"
|
|
SELinux role to use when executing the command, if specified by
|
|
the \f(CW\*(C`\-r\*(C'\fR flag.
|
|
.IP "selinux_type=string" 4
|
|
.IX Item "selinux_type=string"
|
|
SELinux type to use when executing the command, if specified by
|
|
the \f(CW\*(C`\-t\*(C'\fR flag.
|
|
.IP "bsdauth_type=string" 4
|
|
.IX Item "bsdauth_type=string"
|
|
Authentication type, if specified by the \f(CW\*(C`\-a\*(C'\fR flag, to use on
|
|
systems where \s-1BSD\s0 authentication is supported.
|
|
.IP "network_addrs=list" 4
|
|
.IX Item "network_addrs=list"
|
|
A space-separated list of \s-1IP\s0 network addresses and netmasks in the
|
|
form \*(L"addr/netmask\*(R", e.g. \*(L"192.168.1.2/255.255.255.0\*(R". 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.
|
|
.IP "progname=string" 4
|
|
.IX Item "progname=string"
|
|
The command name that sudo was run as, typically \*(L"sudo\*(R" or \*(L"sudoedit\*(R".
|
|
.IP "sudoedit=bool" 4
|
|
.IX Item "sudoedit=bool"
|
|
Set to true when the \f(CW\*(C`\-e\*(C'\fR flag is is specified or if invoked as
|
|
\&\fBsudoedit\fR. The plugin shall substitute an editor into \fIargv\fR
|
|
in the \fIcheck_policy\fR function or return \f(CW\*(C`\-2\*(C'\fR with a usage error
|
|
if the plugin does not support \fIsudoedit\fR. For more information,
|
|
see the \fIcheck_policy\fR section.
|
|
.IP "closefrom=number" 4
|
|
.IX Item "closefrom=number"
|
|
If specified, the user has requested via the \f(CW\*(C`\-C\*(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
|
|
\&\fIcommand_info\fR list.
|
|
.RE
|
|
.RS 4
|
|
.Sp
|
|
Additional settings may be added in the future so the plugin should
|
|
silently ignore settings that it does not recognize.
|
|
.RE
|
|
.IP "user_info" 4
|
|
.IX Item "user_info"
|
|
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.
|
|
.Sp
|
|
When parsing \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.
|
|
.RS 4
|
|
.IP "user=string" 4
|
|
.IX Item "user=string"
|
|
The name of the user invoking \fBsudo\fR.
|
|
.IP "uid=uid_t" 4
|
|
.IX Item "uid=uid_t"
|
|
The real user \s-1ID\s0 of the user invoking \fBsudo\fR.
|
|
.IP "gid=gid_t" 4
|
|
.IX Item "gid=gid_t"
|
|
The real group \s-1ID\s0 of the user invoking \fBsudo\fR.
|
|
.IP "groups=list" 4
|
|
.IX Item "groups=list"
|
|
The user's supplementary group list formatted as a string of
|
|
comma-separated group IDs.
|
|
.IP "cwd=string" 4
|
|
.IX Item "cwd=string"
|
|
The user's current working directory.
|
|
.IP "tty=string" 4
|
|
.IX Item "tty=string"
|
|
The path to the user's terminal device. If the user has no terminal
|
|
device associated with the session, the value will be empty, as in
|
|
\&\f(CW\*(C`tty=\*(C'\fR.
|
|
.IP "host=string" 4
|
|
.IX Item "host=string"
|
|
The local machine's hostname as returned by the \f(CW\*(C`gethostname()\*(C'\fR
|
|
system call.
|
|
.IP "lines=int" 4
|
|
.IX Item "lines=int"
|
|
The number of lines the user's terminal supports. If there is
|
|
no terminal device available, a default value of 24 is used.
|
|
.IP "cols=int" 4
|
|
.IX Item "cols=int"
|
|
The number of columns the user's terminal supports. If there is
|
|
no terminal device available, a default value of 80 is used.
|
|
.RE
|
|
.RS 4
|
|
.RE
|
|
.IP "user_env" 4
|
|
.IX Item "user_env"
|
|
The user's environment in the form of a \f(CW\*(C`NULL\*(C'\fR\-terminated vector of
|
|
\&\*(L"name=value\*(R" 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.
|
|
.RE
|
|
.RS 4
|
|
.RE
|
|
.IP "close" 4
|
|
.IX Item "close"
|
|
.Vb 1
|
|
\& void (*close)(int exit_status, int error);
|
|
.Ve
|
|
.Sp
|
|
The \f(CW\*(C`close\*(C'\fR function is called when the command being run by \fBsudo\fR
|
|
finishes.
|
|
.Sp
|
|
The function arguments are as follows:
|
|
.RS 4
|
|
.IP "exit_status" 4
|
|
.IX Item "exit_status"
|
|
The command's exit status, as returned by the \fIwait\fR\|(2) system call.
|
|
The value of \f(CW\*(C`exit_status\*(C'\fR is undefined if \f(CW\*(C`error\*(C'\fR is non-zero.
|
|
.IP "error" 4
|
|
.IX Item "error"
|
|
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
|
|
for displaying error information via the conversation or plugin_printf
|
|
function. If the command was successfully executed, the value of
|
|
\&\f(CW\*(C`error\*(C'\fR is 0.
|
|
.RE
|
|
.RS 4
|
|
.RE
|
|
.IP "show_version" 4
|
|
.IX Item "show_version"
|
|
.Vb 1
|
|
\& int (*show_version)(int verbose);
|
|
.Ve
|
|
.Sp
|
|
The \f(CW\*(C`show_version\*(C'\fR function is called by \fBsudo\fR when the user specifies
|
|
the \f(CW\*(C`\-V\*(C'\fR option. The plugin may display its version information
|
|
to the user via the conversation or plugin_printf function using
|
|
\&\f(CW\*(C`SUDO_CONV_INFO_MSG\*(C'\fR. If the user requests detailed version
|
|
information, the verbose flag will be set.
|
|
.IP "check_policy" 4
|
|
.IX Item "check_policy"
|
|
.Vb 3
|
|
\& int (*check_policy)(int argc, char * const argv[]
|
|
\& char *env_add[], char **command_info[],
|
|
\& char **argv_out[], char **user_env_out[]);
|
|
.Ve
|
|
.Sp
|
|
The \fIcheck_policy\fR function is called by \fBsudo\fR to determine
|
|
whether the user is allowed to run the specified commands.
|
|
.Sp
|
|
If the \fIsudoedit\fR option was enabled in the \fIsettings\fR array
|
|
passed to the \fIopen\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
|
|
elevated privileges. \fBsudo\fR achieves this by creating user-writable
|
|
temporary copies of the files to be edited and then overwriting the
|
|
originals with the temporary copies after editing is complete. If
|
|
the plugin supports \fBsudoedit\fR, it should choose the editor to be
|
|
used, potentially from a variable in the user's environment, such
|
|
as \f(CW\*(C`EDITOR\*(C'\fR, and include it in \fIargv_out\fR (note that environment
|
|
variables may include command line flags). The files to be edited
|
|
should be copied from \fIargv\fR into \fIargv_out\fR, separated from the
|
|
editor and its arguments by a \f(CW"\-\-"\fR element. The \f(CW"\-\-"\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 \fIcheck_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
|
|
or if \fBsudoedit\fR was specified but is unsupported by the plugin.
|
|
In the latter case, \fBsudo\fR will print a usage message before it
|
|
exits. If an error occurs, the plugin may optionally call the
|
|
conversation or plugin_printf function with \f(CW\*(C`SUDO_CONF_ERROR_MSG\*(C'\fR
|
|
to present additional error information to the user.
|
|
.Sp
|
|
The function arguments are as follows:
|
|
.RS 4
|
|
.IP "argc" 4
|
|
.IX Item "argc"
|
|
The number of elements in \fIargv\fR, not counting the final \f(CW\*(C`NULL\*(C'\fR
|
|
pointer.
|
|
.IP "argv" 4
|
|
.IX Item "argv"
|
|
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
|
|
call. The vector is terminated by a \f(CW\*(C`NULL\*(C'\fR pointer.
|
|
.IP "env_add" 4
|
|
.IX Item "env_add"
|
|
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"
|
|
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.
|
|
.Sp
|
|
When parsing \fIenv_add\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.
|
|
.IP "command_info" 4
|
|
.IX Item "command_info"
|
|
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
|
|
environment when running a command. The plugin is responsible for
|
|
creating and populating the vector, which must be terminated with
|
|
a \f(CW\*(C`NULL\*(C'\fR pointer. The following values are recognized by \fBsudo\fR:
|
|
.RS 4
|
|
.IP "command=string" 4
|
|
.IX Item "command=string"
|
|
Fully qualified path to the command to be executed.
|
|
.IP "runas_uid=uid" 4
|
|
.IX Item "runas_uid=uid"
|
|
User \s-1ID\s0 to run the command as.
|
|
.IP "runas_euid=uid" 4
|
|
.IX Item "runas_euid=uid"
|
|
Effective user \s-1ID\s0 to run the command as.
|
|
If not specified, the value of \fIrunas_uid\fR is used.
|
|
.IP "runas_gid=gid" 4
|
|
.IX Item "runas_gid=gid"
|
|
Group \s-1ID\s0 to run the command as.
|
|
.IP "runas_egid=gid" 4
|
|
.IX Item "runas_egid=gid"
|
|
Effective group \s-1ID\s0 to run the command as.
|
|
If not specified, the value of \fIrunas_gid\fR is used.
|
|
.IP "runas_groups=list" 4
|
|
.IX Item "runas_groups=list"
|
|
The supplementary group vector to use for the command in the form
|
|
of a comma-separated list of group IDs. If \fIpreserve_groups\fR
|
|
is set, this option is ignored.
|
|
.IP "login_class=login_class" 4
|
|
.IX Item "login_class=login_class"
|
|
\&\s-1BSD\s0 login class to use when setting resource limits and nice value
|
|
(optional). This option is only set on systems that support login
|
|
classes.
|
|
.IP "preserve_groups=bool" 4
|
|
.IX Item "preserve_groups=bool"
|
|
If set, \fBsudo\fR will preserve the user's group vector instead of
|
|
initializing the group vector based on \f(CW\*(C`runas_user\*(C'\fR.
|
|
.IP "cwd=string" 4
|
|
.IX Item "cwd=string"
|
|
The current working directory to change to when executing the command.
|
|
.IP "noexec=bool" 4
|
|
.IX Item "noexec=bool"
|
|
If set, prevent the command from executing other programs.
|
|
.IP "chroot=string" 4
|
|
.IX Item "chroot=string"
|
|
The root directory to use when running the command.
|
|
.IP "nice=int" 4
|
|
.IX Item "nice=int"
|
|
Nice value (priority) to use when executing the command. The nice
|
|
value, if specified, overrides the priority associated with the
|
|
\&\fIlogin_class\fR on \s-1BSD\s0 systems.
|
|
.IP "umask=octal" 4
|
|
.IX Item "umask=octal"
|
|
The file creation mask to use when executing the command.
|
|
.IP "selinux_role=string" 4
|
|
.IX Item "selinux_role=string"
|
|
SELinux role to use when executing the command.
|
|
.IP "selinux_type=string" 4
|
|
.IX Item "selinux_type=string"
|
|
SELinux type to use when executing the command.
|
|
.IP "timeout=int" 4
|
|
.IX Item "timeout=int"
|
|
Command timeout. If non-zero then when the timeout expires the
|
|
command will be killed.
|
|
.IP "sudoedit=bool" 4
|
|
.IX Item "sudoedit=bool"
|
|
Set to true when in \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
|
|
enable \fIsudoedit\fR when the user attempts to run an editor.
|
|
.IP "closefrom=number" 4
|
|
.IX Item "closefrom=number"
|
|
If specified, \fBsudo\fR will close all files descriptors with a value
|
|
of \fInumber\fR or higher.
|
|
.IP "iolog_compress=bool" 4
|
|
.IX Item "iolog_compress=bool"
|
|
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
|
|
to ignore it.
|
|
.IP "iolog_path=string" 4
|
|
.IX Item "iolog_path=string"
|
|
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
|
|
choose to ignore it. If no I/O logging plugin is loaded, this
|
|
setting has no effect.
|
|
.IP "iolog_stdin=bool" 4
|
|
.IX Item "iolog_stdin=bool"
|
|
Set to true if the I/O logging plugins, if any, should log the
|
|
standard input if it is not connected to a terminal device. This
|
|
is a hint to the I/O logging plugin which may choose to ignore it.
|
|
.IP "iolog_stdout=bool" 4
|
|
.IX Item "iolog_stdout=bool"
|
|
Set to true if the I/O logging plugins, if any, should log the
|
|
standard output if it is not connected to a terminal device. This
|
|
is a hint to the I/O logging plugin which may choose to ignore it.
|
|
.IP "iolog_stderr=bool" 4
|
|
.IX Item "iolog_stderr=bool"
|
|
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
|
|
is a hint to the I/O logging plugin which may choose to ignore it.
|
|
.IP "iolog_ttyin=bool" 4
|
|
.IX Item "iolog_ttyin=bool"
|
|
Set to true if the I/O logging plugins, if any, should log all
|
|
terminal input. This only includes input typed by the user and not
|
|
from a pipe or redirected from a file. This is a hint to the I/O
|
|
logging plugin which may choose to ignore it.
|
|
.IP "iolog_ttyout=bool" 4
|
|
.IX Item "iolog_ttyout=bool"
|
|
Set to true if the I/O logging plugins, if any, should log all
|
|
terminal output. This only includes output to the screen, not
|
|
output to a pipe or file. This is a hint to the I/O logging plugin
|
|
which may choose to ignore it.
|
|
.IP "use_pty=bool" 4
|
|
.IX Item "use_pty=bool"
|
|
Allocate a pseudo-tty to run the command in, regardless of whether
|
|
or not I/O logging is in use. By default, \fBsudo\fR will only run
|
|
the command in a pty when an I/O log plugin is loaded.
|
|
.RE
|
|
.RS 4
|
|
.Sp
|
|
Unsupported values will be ignored.
|
|
.RE
|
|
.IP "argv_out" 4
|
|
.IX Item "argv_out"
|
|
The \f(CW\*(C`NULL\*(C'\fR\-terminated argument vector to pass to the \fIexecve()\fR
|
|
system call when executing the command. The plugin is responsible
|
|
for allocating and populating the vector.
|
|
.IP "user_env_out" 4
|
|
.IX Item "user_env_out"
|
|
The \f(CW\*(C`NULL\*(C'\fR\-terminated environment vector to use when executing the
|
|
command. The plugin is responsible for allocating and populating
|
|
the vector.
|
|
.RE
|
|
.RS 4
|
|
.RE
|
|
.IP "list" 4
|
|
.IX Item "list"
|
|
.Vb 2
|
|
\& int (*list)(int verbose, const char *list_user,
|
|
\& int argc, char * const argv[]);
|
|
.Ve
|
|
.Sp
|
|
List available privileges for the invoking user. Returns 1 on
|
|
success, 0 on failure and \-1 on error. On error, the plugin may
|
|
optionally call the conversation or plugin_printf function with
|
|
\&\f(CW\*(C`SUDO_CONF_ERROR_MSG\*(C'\fR to present additional error information to
|
|
the user.
|
|
.Sp
|
|
Privileges should be output via the conversation or plugin_printf
|
|
function using \f(CW\*(C`SUDO_CONV_INFO_MSG\*(C'\fR.
|
|
.RS 4
|
|
.IP "verbose" 4
|
|
.IX Item "verbose"
|
|
Flag indicating whether to list in verbose mode or not.
|
|
.IP "list_user" 4
|
|
.IX Item "list_user"
|
|
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
|
|
the invoking user.
|
|
.IP "argc" 4
|
|
.IX Item "argc"
|
|
The number of elements in \fIargv\fR, not counting the final \f(CW\*(C`NULL\*(C'\fR
|
|
pointer.
|
|
.IP "argv" 4
|
|
.IX Item "argv"
|
|
If non\-\f(CW\*(C`NULL\*(C'\fR, an argument vector describing a command the user
|
|
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
|
|
by the policy, the fully-qualified path to the command should be
|
|
displayed along with any command line arguments.
|
|
.RE
|
|
.RS 4
|
|
.RE
|
|
.IP "validate" 4
|
|
.IX Item "validate"
|
|
.Vb 1
|
|
\& int (*validate)(void);
|
|
.Ve
|
|
.Sp
|
|
The \f(CW\*(C`validate\*(C'\fR function is called when \fBsudo\fR is run with the
|
|
\&\f(CW\*(C`\-v\*(C'\fR flag. For policy plugins such as \fIsudoers\fR that cache
|
|
authentication credentials, this function will validate and cache
|
|
the credentials.
|
|
.Sp
|
|
The \f(CW\*(C`validate\*(C'\fR function should be \f(CW\*(C`NULL\*(C'\fR if the plugin does not
|
|
support credential caching.
|
|
.Sp
|
|
Returns 1 on success, 0 on failure and \-1 on error.
|
|
On error, the plugin may optionally call the conversation or plugin_printf
|
|
function with \f(CW\*(C`SUDO_CONF_ERROR_MSG\*(C'\fR to present additional
|
|
error information to the user.
|
|
.IP "invalidate" 4
|
|
.IX Item "invalidate"
|
|
.Vb 1
|
|
\& void (*invalidate)(int remove);
|
|
.Ve
|
|
.Sp
|
|
The \f(CW\*(C`invalidate\*(C'\fR function is called when \fBsudo\fR is called with
|
|
the \f(CW\*(C`\-k\*(C'\fR or \f(CW\*(C`\-K\*(C'\fR flag. For policy plugins such as \fIsudoers\fR that
|
|
cache authentication credentials, this function will invalidate the
|
|
credentials. If the \fIremove\fR flag is set, the plugin may remove
|
|
the credentials instead of simply invalidating them.
|
|
.Sp
|
|
The \f(CW\*(C`invalidate\*(C'\fR function should be \f(CW\*(C`NULL\*(C'\fR if the plugin does not
|
|
support credential caching.
|
|
.IP "init_session" 4
|
|
.IX Item "init_session"
|
|
.Vb 1
|
|
\& int (*init_session)(struct passwd *pwd);
|
|
.Ve
|
|
.Sp
|
|
The \f(CW\*(C`init_session\*(C'\fR function is called when \fBsudo\fR sets up the
|
|
execution environment for the command, immediately before the
|
|
contents of the \fIcommand_info\fR list are applied (before the uid
|
|
changes). This can be used to do session setup that is not supported
|
|
by \fIcommand_info\fR, such as opening the \s-1PAM\s0 session.
|
|
.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
|
|
in the password database, otherwise it will be \s-1NULL\s0.
|
|
.Sp
|
|
Returns 1 on success, 0 on failure and \-1 on error.
|
|
On error, the plugin may optionally call the conversation or plugin_printf
|
|
function with \f(CW\*(C`SUDO_CONF_ERROR_MSG\*(C'\fR to present additional
|
|
error information to the user.
|
|
.PP
|
|
\fIVersion macros\fR
|
|
.IX Subsection "Version macros"
|
|
.PP
|
|
.Vb 8
|
|
\& #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)
|
|
\&
|
|
\& #define SUDO_API_VERSION_MAJOR 1
|
|
\& #define SUDO_API_VERSION_MINOR 0
|
|
\& #define SUDO_API_VERSION ((SUDO_API_VERSION_MAJOR << 16) | \e
|
|
\& SUDO_API_VERSION_MINOR)
|
|
.Ve
|
|
.SS "I/O Plugin \s-1API\s0"
|
|
.IX Subsection "I/O Plugin API"
|
|
.Vb 10
|
|
\& 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[]);
|
|
\& 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);
|
|
\& };
|
|
.Ve
|
|
.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
|
|
session. 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.
|
|
.PP
|
|
The log_ttyin function receives the raw user input from the terminal
|
|
device (note that this will include input even when echo is disabled,
|
|
such as when a password is read). The log_ttyout function receives
|
|
output from the pseudo-tty that is suitable for replaying the user's
|
|
session at a later time. The log_stdin, log_stdout and log_stderr
|
|
functions are only called if the standard input, standard output
|
|
or standard error respectively correspond to something other than
|
|
a tty.
|
|
.PP
|
|
Any of the logging functions may be set to the \s-1NULL\s0
|
|
pointer if no logging is to be performed. If the open function
|
|
returns \f(CW0\fR, no I/O will be sent to the plugin.
|
|
.PP
|
|
The io_plugin struct has the following fields:
|
|
.IP "type" 4
|
|
.IX Item "type"
|
|
The \f(CW\*(C`type\*(C'\fR field should always be set to \s-1SUDO_IO_PLUGIN\s0
|
|
.IP "version" 4
|
|
.IX Item "version"
|
|
The \f(CW\*(C`version\*(C'\fR field should be set to \s-1SUDO_API_VERSION\s0.
|
|
.Sp
|
|
This allows \fBsudo\fR to determine the \s-1API\s0 version the plugin was
|
|
built against.
|
|
.IP "open" 4
|
|
.IX Item "open"
|
|
.Vb 4
|
|
\& 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[]);
|
|
.Ve
|
|
.Sp
|
|
The \fIopen\fR function is run before the \fIlog_input\fR, \fIlog_output\fR
|
|
or \fIshow_version\fR functions are called. It is only called if the
|
|
version is being requested or the \fIcheck_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 conversation
|
|
or plugin_printf function with \f(CW\*(C`SUDO_CONF_ERROR_MSG\*(C'\fR to present
|
|
additional error information to the user.
|
|
.Sp
|
|
The function arguments are as follows:
|
|
.RS 4
|
|
.IP "version" 4
|
|
.IX Item "version"
|
|
The version passed in by \fBsudo\fR allows the plugin to determine the
|
|
major and minor version number of the plugin \s-1API\s0 supported by
|
|
\&\fBsudo\fR.
|
|
.IP "conversation" 4
|
|
.IX Item "conversation"
|
|
A pointer to the conversation function that may be used by the
|
|
\&\fIshow_version\fR function to display version information (see
|
|
show_version below). The conversation function may also be used
|
|
to display additional error message to the user.
|
|
The conversation function returns 0 on success and \-1 on failure.
|
|
.IP "plugin_printf" 4
|
|
.IX Item "plugin_printf"
|
|
A pointer to a printf-style function that may be used by the
|
|
\&\fIshow_version\fR function to display version information (see
|
|
show_version below). The plugin_printf function may also be used
|
|
to display additional error message to the user.
|
|
The plugin_printf function returns number of characters printed on
|
|
success and \-1 on failure.
|
|
.IP "settings" 4
|
|
.IX Item "settings"
|
|
A vector of user-supplied \fBsudo\fR settings in the form of \*(L"name=value\*(R"
|
|
strings. The vector is terminated by a \f(CW\*(C`NULL\*(C'\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
|
|
been specified on the command line.
|
|
.Sp
|
|
When parsing \fIsettings\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 \*(L"Policy Plugin \s-1API\s0\*(R" section for a list of all possible settings.
|
|
.IP "user_info" 4
|
|
.IX Item "user_info"
|
|
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.
|
|
.Sp
|
|
When parsing \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 \*(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.
|
|
.IP "argv" 4
|
|
.IX Item "argv"
|
|
If non\-\f(CW\*(C`NULL\*(C'\fR, an argument vector describing a command the user
|
|
wishes to run in the same form as what would be passed to the
|
|
\&\fIexecve()\fR system call.
|
|
.IP "user_env" 4
|
|
.IX Item "user_env"
|
|
The user's environment in the form of a \f(CW\*(C`NULL\*(C'\fR\-terminated vector of
|
|
\&\*(L"name=value\*(R" 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.
|
|
.RE
|
|
.RS 4
|
|
.RE
|
|
.IP "close" 4
|
|
.IX Item "close"
|
|
.Vb 1
|
|
\& void (*close)(int exit_status, int error);
|
|
.Ve
|
|
.Sp
|
|
The \f(CW\*(C`close\*(C'\fR function is called when the command being run by \fBsudo\fR
|
|
finishes.
|
|
.Sp
|
|
The function arguments are as follows:
|
|
.RS 4
|
|
.IP "exit_status" 4
|
|
.IX Item "exit_status"
|
|
The command's exit status, as returned by the \fIwait\fR\|(2) system call.
|
|
The value of \f(CW\*(C`exit_status\*(C'\fR is undefined if \f(CW\*(C`error\*(C'\fR is non-zero.
|
|
.IP "error" 4
|
|
.IX Item "error"
|
|
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
|
|
successfully executed, the value of \f(CW\*(C`error\*(C'\fR is 0.
|
|
.RE
|
|
.RS 4
|
|
.RE
|
|
.IP "show_version" 4
|
|
.IX Item "show_version"
|
|
.Vb 1
|
|
\& int (*show_version)(int verbose);
|
|
.Ve
|
|
.Sp
|
|
The \f(CW\*(C`show_version\*(C'\fR function is called by \fBsudo\fR when the user specifies
|
|
the \f(CW\*(C`\-V\*(C'\fR option. The plugin may display its version information
|
|
to the user via the conversation or plugin_printf function using
|
|
\&\f(CW\*(C`SUDO_CONV_INFO_MSG\*(C'\fR. If the user requests detailed version
|
|
information, the verbose flag will be set.
|
|
.IP "log_ttyin" 4
|
|
.IX Item "log_ttyin"
|
|
.Vb 1
|
|
\& int (*log_ttyin)(const char *buf, unsigned int len);
|
|
.Ve
|
|
.Sp
|
|
The \fIlog_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 \f(CW1\fR if the data
|
|
should be passed to the command, \f(CW0\fR if the data is rejected
|
|
(which will terminate the command) or \f(CW\*(C`\-1\*(C'\fR if an error occurred.
|
|
.Sp
|
|
The function arguments are as follows:
|
|
.RS 4
|
|
.IP "buf" 4
|
|
.IX Item "buf"
|
|
The buffer containing user input.
|
|
.IP "len" 4
|
|
.IX Item "len"
|
|
The length of \fIbuf\fR in bytes.
|
|
.RE
|
|
.RS 4
|
|
.RE
|
|
.IP "log_ttyout" 4
|
|
.IX Item "log_ttyout"
|
|
.Vb 1
|
|
\& int (*log_ttyout)(const char *buf, unsigned int len);
|
|
.Ve
|
|
.Sp
|
|
The \fIlog_ttyout\fR function is called whenever data can be read from
|
|
the command but before it is written to the user's terminal. This
|
|
allows the plugin to reject data if it chooses to (for instance
|
|
if the output contains banned content). Returns \f(CW1\fR if the data
|
|
should be passed to the user, \f(CW0\fR if the data is rejected
|
|
(which will terminate the command) or \f(CW\*(C`\-1\*(C'\fR if an error occurred.
|
|
.Sp
|
|
The function arguments are as follows:
|
|
.RS 4
|
|
.IP "buf" 4
|
|
.IX Item "buf"
|
|
The buffer containing command output.
|
|
.IP "len" 4
|
|
.IX Item "len"
|
|
The length of \fIbuf\fR in bytes.
|
|
.RE
|
|
.RS 4
|
|
.RE
|
|
.IP "log_stdin" 4
|
|
.IX Item "log_stdin"
|
|
.Vb 1
|
|
\& int (*log_stdin)(const char *buf, unsigned int len);
|
|
.Ve
|
|
.Sp
|
|
The \fIlog_stdin\fR function is only used if the standard input does
|
|
not correspond to a tty device. It is called whenever data can be
|
|
read from the standard input but before it is passed to the running
|
|
command. This allows the plugin to reject data if it chooses to
|
|
(for instance if the input contains banned content). Returns \f(CW1\fR
|
|
if the data should be passed to the command, \f(CW0\fR if the data is
|
|
rejected (which will terminate the command) or \f(CW\*(C`\-1\*(C'\fR if an error
|
|
occurred.
|
|
.Sp
|
|
The function arguments are as follows:
|
|
.RS 4
|
|
.IP "buf" 4
|
|
.IX Item "buf"
|
|
The buffer containing user input.
|
|
.IP "len" 4
|
|
.IX Item "len"
|
|
The length of \fIbuf\fR in bytes.
|
|
.RE
|
|
.RS 4
|
|
.RE
|
|
.IP "log_stdout" 4
|
|
.IX Item "log_stdout"
|
|
.Vb 1
|
|
\& int (*log_stdout)(const char *buf, unsigned int len);
|
|
.Ve
|
|
.Sp
|
|
The \fIlog_stdout\fR function is only used if the standard output does
|
|
not correspond to a tty device. It is called whenever data can be
|
|
read from the command but before it is written to the standard
|
|
output. This allows the plugin to reject data if it chooses to
|
|
(for instance if the output contains banned content). Returns \f(CW1\fR
|
|
if the data should be passed to the user, \f(CW0\fR if the data is
|
|
rejected (which will terminate the command) or \f(CW\*(C`\-1\*(C'\fR if an error
|
|
occurred.
|
|
.Sp
|
|
The function arguments are as follows:
|
|
.RS 4
|
|
.IP "buf" 4
|
|
.IX Item "buf"
|
|
The buffer containing command output.
|
|
.IP "len" 4
|
|
.IX Item "len"
|
|
The length of \fIbuf\fR in bytes.
|
|
.RE
|
|
.RS 4
|
|
.RE
|
|
.IP "log_stderr" 4
|
|
.IX Item "log_stderr"
|
|
.Vb 1
|
|
\& int (*log_stderr)(const char *buf, unsigned int len);
|
|
.Ve
|
|
.Sp
|
|
The \fIlog_stderr\fR function is only used if the standard error does
|
|
not correspond to a tty device. It is called whenever data can be
|
|
read from the command but before it is written to the standard
|
|
error. This allows the plugin to reject data if it chooses to
|
|
(for instance if the output contains banned content). Returns \f(CW1\fR
|
|
if the data should be passed to the user, \f(CW0\fR if the data is
|
|
rejected (which will terminate the command) or \f(CW\*(C`\-1\*(C'\fR if an error
|
|
occurred.
|
|
.Sp
|
|
The function arguments are as follows:
|
|
.RS 4
|
|
.IP "buf" 4
|
|
.IX Item "buf"
|
|
The buffer containing command output.
|
|
.IP "len" 4
|
|
.IX Item "len"
|
|
The length of \fIbuf\fR in bytes.
|
|
.RE
|
|
.RS 4
|
|
.RE
|
|
.PP
|
|
\fIVersion macros\fR
|
|
.IX Subsection "Version macros"
|
|
.PP
|
|
Same as for the \*(L"Policy Plugin \s-1API\s0\*(R".
|
|
.SS "Conversation \s-1API\s0"
|
|
.IX Subsection "Conversation API"
|
|
If the plugin needs to interact with the user, it may do so via the
|
|
conversation function. A plugin should not attempt to read directly
|
|
from the standard input or the user's tty (neither of which are
|
|
guaranteed to exist). The caller must include a trailing newline
|
|
in \f(CW\*(C`msg\*(C'\fR if one is to be printed.
|
|
.PP
|
|
A printf-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.
|
|
.PP
|
|
.Vb 11
|
|
\& 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_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, ...);
|
|
.Ve
|
|
.PP
|
|
Pointers to the conversation and printf-style functions are passed
|
|
in to the plugin's \f(CW\*(C`open\*(C'\fR function when the plugin is initialized.
|
|
.PP
|
|
To use the conversation function, the plugin must pass an array of
|
|
\&\f(CW\*(C`sudo_conv_message\*(C'\fR and \f(CW\*(C`sudo_conv_reply\*(C'\fR structures. There must
|
|
be a \f(CW\*(C`struct sudo_conv_message\*(C'\fR and \f(CW\*(C`struct sudo_conv_reply\*(C'\fR for
|
|
each message in the conversation. The plugin is responsible for
|
|
freeing the reply buffer filled in to the \f(CW\*(C`struct sudo_conv_reply\*(C'\fR,
|
|
if any.
|
|
.PP
|
|
The printf-style function uses the same underlying mechanism as the
|
|
conversation function but only supports \f(CW\*(C`SUDO_CONV_INFO_MSG\*(C'\fR and
|
|
\&\f(CW\*(C`SUDO_CONV_ERROR_MSG\*(C'\fR for the \fImsg_type\fR parameter. It can be
|
|
more convenient than using the conversation function if no user
|
|
reply is needed and supports standard \fIprintf()\fR escape sequences.
|
|
.PP
|
|
See the sample plugin for an example of the conversation function usage.
|
|
.SS "Sudoers Group Plugin \s-1API\s0"
|
|
.IX Subsection "Sudoers Group Plugin API"
|
|
The \fIsudoers\fR module supports a plugin interface to allow non-Unix
|
|
group lookups. This can be used to query a group source other than
|
|
the standard Unix group database. A sample group plugin is bundled
|
|
with \fBsudo\fR that implements file-based lookups. Third party group
|
|
plugins include a \s-1QAS\s0 \s-1AD\s0 plugin available from Quest Software.
|
|
.PP
|
|
A group plugin must declare and populate a \f(CW\*(C`sudoers_group_plugin\*(C'\fR
|
|
struct in the global scope. This structure contains pointers to
|
|
the functions that implement plugin initialization, cleanup and
|
|
group lookup.
|
|
.PP
|
|
.Vb 8
|
|
\& 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);
|
|
\&};
|
|
.Ve
|
|
.PP
|
|
The \f(CW\*(C`sudoers_group_plugin\*(C'\fR struct has the following fields:
|
|
.IP "version" 4
|
|
.IX Item "version"
|
|
The \f(CW\*(C`version\*(C'\fR field should be set to \s-1GROUP_API_VERSION\s0.
|
|
.Sp
|
|
This allows \fIsudoers\fR to determine the \s-1API\s0 version the group plugin
|
|
was built against.
|
|
.IP "init" 4
|
|
.IX Item "init"
|
|
.Vb 2
|
|
\& int (*init)(int version, sudo_printf_t plugin_printf,
|
|
\& char *const argv[]);
|
|
.Ve
|
|
.Sp
|
|
The \fIinit\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 plugin_printf function
|
|
with \f(CW\*(C`SUDO_CONF_ERROR_MSG\*(C'\fR to present additional error information
|
|
to the user.
|
|
.Sp
|
|
The function arguments are as follows:
|
|
.RS 4
|
|
.IP "version" 4
|
|
.IX Item "version"
|
|
The version passed in by \fIsudoers\fR allows the plugin to determine the
|
|
major and minor version number of the group plugin \s-1API\s0 supported by
|
|
\&\fIsudoers\fR.
|
|
.IP "plugin_printf" 4
|
|
.IX Item "plugin_printf"
|
|
A pointer to a printf-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.
|
|
.IP "argv" 4
|
|
.IX Item "argv"
|
|
A NULL-terminated array of arguments generated from the \fIgroup_plugin\fR
|
|
option in \fIsudoers\fR. If no arguments were given, \fIargv\fR will be
|
|
\&\s-1NULL\s0.
|
|
.RE
|
|
.RS 4
|
|
.RE
|
|
.IP "cleanup" 4
|
|
.IX Item "cleanup"
|
|
.Vb 1
|
|
\& void (*cleanup)();
|
|
.Ve
|
|
.Sp
|
|
The \fIcleanup\fR function is called when \fIsudoers\fR has finished its
|
|
group checks. The plugin should free any memory it has allocated
|
|
and close open file handles.
|
|
.IP "query" 4
|
|
.IX Item "query"
|
|
.Vb 2
|
|
\& int (*query)(const char *user, const char *group,
|
|
\& const struct passwd *pwd);
|
|
.Ve
|
|
.Sp
|
|
The \fIquery\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:
|
|
.RS 4
|
|
.IP "user" 4
|
|
.IX Item "user"
|
|
The name of the user being looked up in the external group database.
|
|
.IP "group" 4
|
|
.IX Item "group"
|
|
The name of the group being queried.
|
|
.IP "pwd" 4
|
|
.IX Item "pwd"
|
|
The password database entry for \fIuser\fR, if any. If \fIuser\fR is not
|
|
present in the password database, \fIpwd\fR will be \f(CW\*(C`NULL\*(C'\fR.
|
|
.RE
|
|
.RS 4
|
|
.RE
|
|
.PP
|
|
\fIVersion Macros\fR
|
|
.IX Subsection "Version Macros"
|
|
.PP
|
|
.Vb 5
|
|
\& /* Sudoers group plugin version major/minor */
|
|
\& #define GROUP_API_VERSION_MAJOR 1
|
|
\& #define GROUP_API_VERSION_MINOR 0
|
|
\& #define GROUP_API_VERSION ((GROUP_API_VERSION_MAJOR << 16) | \e
|
|
\& GROUP_API_VERSION_MINOR)
|
|
\&
|
|
\& /* Getters and setters for group version */
|
|
\& #define GROUP_API_VERSION_GET_MAJOR(v) ((v) >> 16)
|
|
\& #define GROUP_API_VERSION_GET_MINOR(v) ((v) & 0xffff)
|
|
\& #define GROUP_API_VERSION_SET_MAJOR(vp, n) do { \e
|
|
\& *(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \e
|
|
\& } while(0)
|
|
\& #define GROUP_API_VERSION_SET_MINOR(vp, n) do { \e
|
|
\& *(vp) = (*(vp) & 0xffff0000) | (n); \e
|
|
\& } while(0)
|
|
.Ve
|
|
.SH "SEE ALSO"
|
|
.IX Header "SEE ALSO"
|
|
\&\fIsudoers\fR\|(@mansectform@), \fIsudo\fR\|(@mansectsu@)
|
|
.SH "BUGS"
|
|
.IX Header "BUGS"
|
|
If you feel you have found a bug in \fBsudo\fR, please submit a bug report
|
|
at http://www.sudo.ws/sudo/bugs/
|
|
.SH "SUPPORT"
|
|
.IX Header "SUPPORT"
|
|
Limited free support is available via the sudo-workers mailing list,
|
|
see http://www.sudo.ws/mailman/listinfo/sudo\-workers to subscribe or
|
|
search the archives.
|
|
.SH "DISCLAIMER"
|
|
.IX Header "DISCLAIMER"
|
|
\&\fBsudo\fR is provided ``\s-1AS\s0 \s-1IS\s0'' and any express or implied warranties,
|
|
including, but not limited to, the implied warranties of merchantability
|
|
and fitness for a particular purpose are disclaimed. See the \s-1LICENSE\s0
|
|
file distributed with \fBsudo\fR or http://www.sudo.ws/sudo/license.html
|
|
for complete details.
|