|
version 1.1, 2012/02/21 16:23:02
|
version 1.1.1.6, 2014/06/15 16:12:54
|
|
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-2013 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" "December 20, 2013" "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 | Plugins may be compiled as dynamic shared objects (the default on |
| logging plugins provided by third parties. The plugins to be used | systems that support them) or compiled statically into the |
| are specified via the \fI@sysconfdir@/sudo.conf\fR file. | \fBsudo\fR |
| | binary itself. |
| | By default, the |
| | \fBsudoers\fR |
| | 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 in the |
| | sudo.conf(@mansectform@) |
| | 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 "Policy plugin API" |
| Currently, the only supported keyword is the \f(CW\*(C`Plugin\*(C'\fR directive, | A policy plugin must declare and populate a |
| which causes a plugin plugin to be loaded. | \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 |
| | sudo.conf(@mansectform@) |
| | 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 |
| 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: |
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 | .nf |
| \& int (*open)(unsigned int version, sudo_conv_t conversation, | .RS 6n |
| \& sudo_printf_t plugin_printf, char * const settings[], | int (*open)(unsigned int version, sudo_conv_t conversation, |
| \& char * const user_info[], char * const user_env[]); | sudo_printf_t plugin_printf, char * const settings[], |
| .Ve | char * const user_info[], char * const user_env[], |
| .Sp | char * const plugin_options[]); |
| | .RE |
| | .fi |
| | .RS 6n |
| | .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 |
| | \(lqname=value\(rq |
| | 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" | (\(oq=\(cq) |
| 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 |
| The user name or uid to to run the command as, if specified via the | itself but the |
| \&\f(CW\*(C`\-u\*(C'\fR flag. | \fIvalue\fR |
| .IP "runas_group=string" 4 | might. |
| .IX Item "runas_group=string" | .PP |
| The group name or gid to to run the command as, if specified via | .RS 6n |
| the \f(CW\*(C`\-g\*(C'\fR flag. | .PD 0 |
| .IP "prompt=string" 4 | .TP 6n |
| .IX Item "prompt=string" | bsdauth_type=string |
| The prompt to use when requesting a password, if specified via | Authentication type, if specified by the |
| the \f(CW\*(C`\-p\*(C'\fR flag. | \fB\-a\fR |
| .IP "set_home=bool" 4 | flag, to use on |
| .IX Item "set_home=bool" | systems where BSD authentication is supported. |
| Set to true if the user specified the \f(CW\*(C`\-H\*(C'\fR flag. If true, set the | .PD |
| \&\f(CW\*(C`HOME\*(C'\fR environment variable to the target user's home directory. | .TP 6n |
| .IP "preserve_environment=bool" 4 | closefrom=number |
| .IX Item "preserve_environment=bool" | If specified, the user has requested via the |
| Set to true if the user specified the \f(CW\*(C`\-E\*(C'\fR flag, indicating that | \fB\-C\fR |
| the user wishes to preserve the environment. | flag that |
| .IP "run_shell=bool" 4 | \fBsudo\fR |
| .IX Item "run_shell=bool" | close all files descriptors with a value of |
| Set to true if the user specified the \f(CW\*(C`\-s\*(C'\fR flag, indicating that | \fInumber\fR |
| the user wishes to run a shell. | or higher. |
| .IP "login_shell=bool" 4 | The plugin may optionally pass this, or another value, back in the |
| .IX Item "login_shell=bool" | \fIcommand_info\fR |
| Set to true if the user specified the \f(CW\*(C`\-i\*(C'\fR flag, indicating that | list. |
| the user wishes to run a login shell. | .TP 6n |
| .IP "implied_shell=bool" 4 | debug_flags=string |
| .IX Item "implied_shell=bool" | A comma-separated list of debug flags that correspond to |
| If the user does not specify a program on the command line, \fBsudo\fR | \fBsudo\fR's |
| will pass the plugin the path to the user's shell and set | \fRDebug\fR |
| \&\fIimplied_shell\fR to true. This allows \fBsudo\fR with no arguments | entry in |
| to be used similarly to \fIsu\fR\|(1). If the plugin does not to support | sudo.conf(@mansectform@), |
| this usage, it may return a value of \-2 from the \f(CW\*(C`check_policy\*(C'\fR | if there is one. |
| function, which will cause \fBsudo\fR to print a usage message and | The flags are passed to the plugin as they appear in |
| | sudo.conf(@mansectform@). |
| | The syntax used by |
| | \fBsudo\fR |
| | and the |
| | \fBsudoers\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 |
| | (\(oq,\&\(cq). |
| | 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 |
| | ignore_ticket=bool |
| | 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 |
| | authentication credentials. |
| | \fIimplied_shell\fR |
| | to true. |
| | This allows |
| | \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" | implied_shell=bool |
| Set to true if the user specified the \f(CW\*(C`\-P\*(C'\fR flag, indicating that | 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 |
| | .TP 6n |
| | login_class=string |
| | BSD login class to use when setting resource limits and nice value, |
| | if specified by the |
| | \fB\-c\fR |
| | flag. |
| | .TP 6n |
| | login_shell=bool |
| | Set to true if the user specified the |
| | \fB\-i\fR |
| | flag, indicating that |
| | the user wishes to run a login shell. |
| | .TP 6n |
| | max_groups=int |
| | The maximum number of groups a user may belong to. |
| | This will only be present if there is a corresponding setting in |
| | sudo.conf(@mansectform@). |
| | .TP 6n |
| | network_addrs=list |
| | A space-separated list of IP network addresses and netmasks in the |
| | form |
| | \(lqaddr/netmask\(rq, |
| | e.g.\& |
| | \(lq192.168.1.2/255.255.255.0\(rq. |
| | The address and netmask pairs may be either IPv4 or IPv6, depending on |
| | what the operating system supports. |
| | If the address contains a colon |
| | (\(oq:\&\(cq), |
| | it is an IPv6 address, else it is IPv4. |
| | .TP 6n |
| | noninteractive=bool |
| | Set to true if the user specified the |
| | \fB\-n\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. |
| | .TP 6n |
| | plugin_dir=string |
| | The default plugin directory used by the |
| | \fBsudo\fR |
| | front end. |
| | This is the default directory set at compile time and may not |
| | correspond to the directory the running plugin was loaded from. |
| | It may be used by a plugin to locate support files. |
| | .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. |
| | .TP 6n |
| | preserve_groups=bool |
| | 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" | progname=string |
| Set to true if the user specified the \f(CW\*(C`\-k\*(C'\fR flag along with a | The command name that sudo was run as, typically |
| command, indicating that the user wishes to ignore any cached | \(lqsudo\(rq |
| authentication credentials. | or |
| .IP "noninteractive=bool" 4 | \(lqsudoedit\(rq. |
| .IX Item "noninteractive=bool" | .TP 6n |
| Set to true if the user specified the \f(CW\*(C`\-n\*(C'\fR flag, indicating that | prompt=string |
| \&\fBsudo\fR should operate in non-interactive mode. The plugin may | The prompt to use when requesting a password, if specified via |
| reject a command run in non-interactive mode if user interaction | the |
| is required. | \fB\-p\fR |
| .IP "login_class=string" 4 | flag. |
| .IX Item "login_class=string" | .TP 6n |
| \&\s-1BSD\s0 login class to use when setting resource limits and nice value, | remote_host=string |
| if specified by the \f(CW\*(C`\-c\*(C'\fR flag. | The name of the remote host to run the command on, if specified via |
| .IP "selinux_role=string" 4 | the |
| .IX Item "selinux_role=string" | \fB\-h\fR |
| | option. |
| | Support for running the command on a remote host is meant to be implemented |
| | via a helper program that is executed in place of the user-specified command. |
| | The |
| | \fBsudo\fR |
| | front end is only capable of executing commands on the local host. |
| | Only available starting with API version 1.4. |
| | .TP 6n |
| | run_shell=bool |
| | Set to true if the user specified the |
| | \fB\-s\fR |
| | flag, indicating that the user wishes to run a shell. |
| | .TP 6n |
| | runas_group=string |
| | The group name or gid to run the command as, if specified via |
| | the |
| | \fB\-g\fR |
| | flag. |
| | .TP 6n |
| | runas_user=string |
| | The user name or uid to run the command as, if specified via the |
| | \fB\-u\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. | set_home=bool |
| .IP "network_addrs=list" 4 | Set to true if the user specified the |
| .IX Item "network_addrs=list" | \fB\-H\fR |
| A space-separated list of \s-1IP\s0 network addresses and netmasks in the | flag. |
| form \*(L"addr/netmask\*(R", e.g. \*(L"192.168.1.2/255.255.255.0\*(R". The address | If true, set the |
| and netmask pairs may be either IPv4 or IPv6, depending on what the | \fRHOME\fR |
| operating system supports. If the address contains a colon (':'), | environment variable to the target user's home directory. |
| it is an IPv6 address, else it is IPv4. | .TP 6n |
| .IP "progname=string" 4 | sudoedit=bool |
| .IX Item "progname=string" | Set to true when the |
| The command name that sudo was run as, typically \*(L"sudo\*(R" or \*(L"sudoedit\*(R". | \fB\-e\fR |
| .IP "sudoedit=bool" 4 | flag is is specified or if invoked as |
| .IX Item "sudoedit=bool" | \fBsudoedit\fR. |
| Set to true when the \f(CW\*(C`\-e\*(C'\fR flag is is specified or if invoked as | The plugin shall substitute an editor into |
| \&\fBsudoedit\fR. The plugin shall substitute an editor into \fIargv\fR | \fIargv\fR |
| in the \fIcheck_policy\fR function or return \f(CW\*(C`\-2\*(C'\fR with a usage error | in the |
| if the plugin does not support \fIsudoedit\fR. For more information, | \fBcheck_policy\fR() |
| see the \fIcheck_policy\fR section. | function or return \-2 with a usage error |
| .IP "closefrom=number" 4 | if the plugin does not support |
| .IX Item "closefrom=number" | \fIsudoedit\fR. |
| If specified, the user has requested via the \f(CW\*(C`\-C\*(C'\fR flag that \fBsudo\fR | For more information, see the |
| close all files descriptors with a value of \fInumber\fR or higher. | \fIcheck_policy\fR |
| The plugin may optionally pass this, or another value, back in the | section. |
| \&\fIcommand_info\fR list. | .PP |
| .RE | |
| .RS 4 | |
| .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. |
| .RE |
.RE |
| .IP "user_info" 4 | .TP 6n |
| .IX Item "user_info" | 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. | \(lqname=value\(rq |
| .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. | (\(oq=\(cq) |
| .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. |
| | .PP |
| | .RS 6n |
| | .PD 0 |
| | .TP 6n |
| | 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. |
| | .PD |
| | .TP 6n |
| | cwd=string |
| | The user's current working directory. |
| | .TP 6n |
| | egid=gid_t |
| | The effective group ID of the user invoking |
| | \fBsudo\fR. |
| | .TP 6n |
| | euid=uid_t |
| | The effective user 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" | host=string |
| The user's current working directory. | The local machine's hostname as returned by the |
| .IP "tty=string" 4 | gethostname(2) |
| .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. |
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" | pgid=int |
| The number of columns the user's terminal supports. If there is | The ID of the process group that the running |
| no terminal device available, a default value of 80 is used. | \fBsudo\fR |
| | process is a member of. |
| | Only available starting with API version 1.2. |
| | .TP 6n |
| | pid=int |
| | The process ID of the running |
| | \fBsudo\fR |
| | process. |
| | Only available starting with API version 1.2. |
| | .TP 6n |
| | plugin_options |
| | Any (non-comment) strings immediately after the plugin path are |
| | passed as arguments to the plugin. |
| | These arguments are split on a white space boundary and are passed to |
| | the plugin in the form of a |
| | \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. |
| | .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 |
| | tcpgid=int |
| | The ID of the foreground process group associated with the terminal |
| | device associated with the |
| | \fBsudo\fR |
| | process or \-1 if there is no |
| | terminal present. |
| | Only available starting with API version 1.2. |
| | .TP 6n |
| | 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 |
| | \(lq\fRtty=\fR\(rq. |
| | .TP 6n |
| | uid=uid_t |
| | The real user ID of the user invoking |
| | \fBsudo\fR. |
| | .TP 6n |
| | user=string |
| | The name of the user invoking |
| | \fBsudo\fR. |
| | .PD 0 |
| | .PP |
| .RE |
.RE |
| .RS 4 | .PD |
| | .TP 6n |
| | user_env |
| | The user's environment in the form of a |
| | \fRNULL\fR-terminated vector of |
| | \(lqname=value\(rq |
| | strings. |
| | .sp |
| | When parsing |
| | \fIuser_env\fR, |
| | the plugin should split on the |
| | \fBfirst\fR |
| | equal sign |
| | (\(oq=\(cq) |
| | since the |
| | \fIname\fR |
| | field will never include one |
| | itself but the |
| | \fIvalue\fR |
| | might. |
| | .PD 0 |
| | .PP |
| .RE |
.RE |
| .IP "user_env" 4 | .PD |
| .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 | .nf |
| When parsing \fIuser_env\fR, the plugin should split on the \fBfirst\fR | .RS 6n |
| equal sign ('=') since the \fIname\fR field will never include one | void (*close)(int exit_status, int error); |
| itself but the \fIvalue\fR might. | |
| .RE |
.RE |
| .RS 4 | .fi |
| .RE | .RS 6n |
| .IP "close" 4 | .sp |
| .IX Item "close" | The |
| .Vb 1 | \fBclose\fR() |
| \& void (*close)(int exit_status, int error); | function is called when the command being run by |
| .Ve | \fBsudo\fR |
| .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 | .TP 6n |
| .IP "exit_status" 4 | exit_status |
| .IX Item "exit_status" | The command's exit status, as returned by the |
| The command's exit status, as returned by the \fIwait\fR\|(2) system call. | wait(2) |
| The value of \f(CW\*(C`exit_status\*(C'\fR is undefined if \f(CW\*(C`error\*(C'\fR is non-zero. | system call. |
| .IP "error" 4 | The value of |
| .IX Item "error" | \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 |
| | If no |
| | \fBclose\fR() |
| | function is defined, no I/O logging plugins are loaded, |
| | and neither the |
| | \fItimeout\fR |
| | not |
| | \fIuse_pty\fR |
| | options are set in the |
| | \fRcommand_info\fR |
| | list, the |
| | \fBsudo\fR |
| | front end may execute the command directly instead of running |
| | it as a child process. |
| .RE |
.RE |
| .RS 4 | .TP 6n |
| | show_version |
| | .nf |
| | .RS 6n |
| | int (*show_version)(int verbose); |
| .RE |
.RE |
| .IP "show_version" 4 | .fi |
| .IX Item "show_version" | .RS 6n |
| .Vb 1 | .sp |
| \& int (*show_version)(int verbose); | The |
| .Ve | \fBshow_version\fR() |
| .Sp | function is called by |
| The \f(CW\*(C`show_version\*(C'\fR function is called by \fBsudo\fR when the user specifies | \fBsudo\fR |
| the \f(CW\*(C`\-V\*(C'\fR option. The plugin may display its version information | when the user specifies |
| to the user via the conversation or plugin_printf function using | the |
| \&\f(CW\*(C`SUDO_CONV_INFO_MSG\*(C'\fR. If the user requests detailed version | \fB\-V\fR |
| information, the verbose flag will be set. | option. |
| .IP "check_policy" 4 | The plugin may display its version information to the user via the |
| .IX Item "check_policy" | \fBconversation\fR() |
| .Vb 3 | or |
| \& int (*check_policy)(int argc, char * const argv[] | \fBplugin_printf\fR() |
| \& char *env_add[], char **command_info[], | function using |
| \& char **argv_out[], char **user_env_out[]); | \fRSUDO_CONV_INFO_MSG\fR. |
| .Ve | If the user requests detailed version information, the verbose flag will be set. |
| .Sp | .RE |
| The \fIcheck_policy\fR function is called by \fBsudo\fR to determine | .TP 6n |
| | check_policy |
| | .nf |
| | .RS 6n |
| | int (*check_policy)(int argc, char * const argv[] |
| | char *env_add[], char **command_info[], |
| | char **argv_out[], char **user_env_out[]); |
| | .RE |
| | .fi |
| | .RS 6n |
| | .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 |
| | \(lq\fR--\fR\(rq |
| | element. |
| | The |
| | \(lq\fR--\fR\(rq |
| | 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 | .TP 6n |
| .IP "argc" 4 | argc |
| .IX Item "argc" | The number of elements in |
| The number of elements in \fIargv\fR, not counting the final \f(CW\*(C`NULL\*(C'\fR | \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 |
| | \(lqname=value\(rq |
| | 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" | (\(oq=\(cq) |
| 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 |
| | \(lqname=value\(rq |
| | 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: |
| | .PP |
| | .RS 6n |
| | .PD 0 |
| | .TP 6n |
| | chroot=string |
| | The root directory to use when running the command. |
| | .PD |
| | .TP 6n |
| | closefrom=number |
| | If specified, |
| | \fBsudo\fR |
| | will close all files descriptors with a value |
| | of |
| | \fInumber\fR |
| | or higher. |
| | .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" | cwd=string |
| 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=string" 4 | |
| .IX Item "login_class=string" | |
| \&\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. |
The current working directory to change to when executing the command. |
| .IP "noexec=bool" 4 | .TP 6n |
| .IX Item "noexec=bool" | exec_background=bool |
| If set, prevent the command from executing other programs. | By default, |
| .IP "chroot=string" 4 | \fBsudo\fR |
| .IX Item "chroot=string" | runs a command as the foreground process as long as |
| The root directory to use when running the command. | \fBsudo\fR |
| .IP "nice=int" 4 | itself is running in the foreground. |
| .IX Item "nice=int" | When |
| Nice value (priority) to use when executing the command. The nice | \fIexec_background\fR |
| value, if specified, overrides the priority associated with the | is enabled and the command is being run in a pty (due to I/O logging |
| \&\fIlogin_class\fR on \s-1BSD\s0 systems. | or the |
| .IP "umask=octal" 4 | \fIuse_pty\fR |
| .IX Item "umask=octal" | setting), the command will be run as a background process. |
| The file creation mask to use when executing the command. | Attempts to read from the controlling terminal (or to change terminal |
| .IP "selinux_role=string" 4 | settings) will result in the command being suspended with the |
| .IX Item "selinux_role=string" | \fRSIGTTIN\fR |
| SELinux role to use when executing the command. | signal (or |
| .IP "selinux_type=string" 4 | \fRSIGTTOU\fR |
| .IX Item "selinux_type=string" | in the case of terminal settings). |
| SELinux type to use when executing the command. | If this happens when |
| .IP "timeout=int" 4 | \fBsudo\fR |
| .IX Item "timeout=int" | is a foreground process, the command will be granted the controlling terminal |
| Command timeout. If non-zero then when the timeout expires the | and resumed in the foreground with no user intervention required. |
| command will be killed. | The advantage of initially running the command in the background is that |
| .IP "sudoedit=bool" 4 | \fBsudo\fR |
| .IX Item "sudoedit=bool" | need not read from the terminal unless the command explicitly requests it. |
| Set to true when in \fIsudoedit\fR mode. The plugin may enable | Otherwise, any terminal input must be passed to the command, whether it |
| \&\fIsudoedit\fR mode even if \fBsudo\fR was not invoked as \fBsudoedit\fR. | has required it or not (the kernel buffers terminals so it is not possible |
| This allows the plugin to perform command substitution and transparently | to tell whether the command really wants the input). |
| enable \fIsudoedit\fR when the user attempts to run an editor. | This is different from historic |
| .IP "closefrom=number" 4 | \fIsudo\fR |
| .IX Item "closefrom=number" | behavior or when the command is not being run in a pty. |
| If specified, \fBsudo\fR will close all files descriptors with a value | .sp |
| of \fInumber\fR or higher. | For this to work seamlessly, the operating system must support the |
| .IP "iolog_compress=bool" 4 | automatic restarting of system calls. |
| .IX Item "iolog_compress=bool" | Unfortunately, not all operating systems do this by default, |
| | and even those that do may have bugs. |
| | For example, Mac OS X fails to restart the |
| | \fBtcgetattr\fR() |
| | and |
| | \fBtcsetattr\fR() |
| | system calls (this is a bug in Mac OS X). |
| | Furthermore, because this behavior depends on the command stopping with the |
| | \fRSIGTTIN\fR |
| | or |
| | \fRSIGTTOU\fR |
| | signals, programs that catch these signals and suspend themselves |
| | with a different signal (usually |
| | \fRSIGTOP\fR) |
| | will not be automatically foregrounded. |
| | Some versions of the linux |
| | su(1) |
| | command behave this way. |
| | Because of this, a plugin should not set |
| | \fIexec_background\fR |
| | unless it is explicitly enabled by the administrator and there should |
| | be a way to enabled or disable it on a per-command basis. |
| | .sp |
| | This setting has no effect unless I/O logging is enabled or |
| | \fIuse_pty\fR |
| | is enabled. |
| | .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" | login_class=string |
| | BSD login class to use when setting resource limits and nice value |
| | (optional). |
| | This option is only set on systems that support login classes. |
| | .TP 6n |
| | 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 BSD systems. |
| | .TP 6n |
| | noexec=bool |
| | If set, prevent the command from executing other programs. |
| | .TP 6n |
| | preserve_fds=list |
| | A comma-separated list of file descriptors that should be |
| | preserved, regardless of the value of the |
| | \fIclosefrom\fR |
| | setting. |
| | Only available starting with API version 1.5. |
| | .TP 6n |
| | preserve_groups=bool |
| | If set, |
| | \fBsudo\fR |
| | will preserve the user's group vector instead of |
| | initializing the group vector based on |
| | \fRrunas_user\fR. |
| | .TP 6n |
| | runas_egid=gid |
| | Effective group ID to run the command as. |
| | If not specified, the value of |
| | \fIrunas_gid\fR |
| | is used. |
| | .TP 6n |
| | runas_euid=uid |
| | Effective user ID to run the command as. |
| | If not specified, the value of |
| | \fIrunas_uid\fR |
| | is used. |
| | .TP 6n |
| | runas_gid=gid |
| | Group ID to run the command as. |
| | .TP 6n |
| | 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. |
| | .TP 6n |
| | runas_uid=uid |
| | User ID to run the command as. |
| | .TP 6n |
| | selinux_role=string |
| | SELinux role to use when executing the command. |
| | .TP 6n |
| | selinux_type=string |
| | SELinux type to use when executing the command. |
| | .TP 6n |
| | set_utmp=bool |
| | Create a utmp (or utmpx) entry when a pseudo-tty is allocated. |
| | 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. |
| | .TP 6n |
| | 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. |
| | .TP 6n |
| | timeout=int |
| | Command timeout. |
| | If non-zero then when the timeout expires the command will be killed. |
| | .TP 6n |
| | umask=octal |
| | The file creation mask to use when executing the command. |
| | .TP 6n |
| | 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" | utmp_user=string |
| Create a utmp (or utmpx) entry when a pseudo-tty is allocated. 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. | |
| .IP "utmp_user=string" 4 | |
| .IX Item "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. |
| .RE |
.RE |
| .IP "argv_out" 4 | .TP 6n |
| .IX Item "argv_out" | argv_out |
| The \f(CW\*(C`NULL\*(C'\fR\-terminated argument vector to pass to the \fIexecve()\fR | The |
| system call when executing the command. The plugin is responsible | \fRNULL\fR-terminated |
| for allocating and populating the vector. | argument vector to pass to the |
| .IP "user_env_out" 4 | execve(2) |
| .IX Item "user_env_out" | system call when executing the command. |
| The \f(CW\*(C`NULL\*(C'\fR\-terminated environment vector to use when executing the | The plugin is responsible for allocating and populating the vector. |
| command. The plugin is responsible for allocating and populating | .TP 6n |
| the vector. | 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. |
| | .PD 0 |
| | .PP |
| .RE |
.RE |
| .RS 4 | .PD |
| | .TP 6n |
| | list |
| | .nf |
| | .RS 6n |
| | int (*list)(int verbose, const char *list_user, |
| | int argc, char * const argv[]); |
| .RE |
.RE |
| .IP "list" 4 | .fi |
| .IX Item "list" | .RS 6n |
| .Vb 2 | .sp |
| \& int (*list)(int verbose, const char *list_user, | List available privileges for the invoking user. |
| \& int argc, char * const argv[]); | Returns 1 on success, 0 on failure and \-1 on error. |
| .Ve | On error, the plugin may optionally call the |
| .Sp | \fBconversation\fR() |
| List available privileges for the invoking user. Returns 1 on | or |
| success, 0 on failure and \-1 on error. On error, the plugin may | \fBplugin_printf\fR() |
| optionally call the conversation or plugin_printf function with | function with |
| \&\f(CW\*(C`SUDO_CONF_ERROR_MSG\*(C'\fR to present additional error information to | \fRSUDO_CONF_ERROR_MSG\fR |
| | 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, |
| | .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. |
| | .PD 0 |
| | .PP |
| .RE |
.RE |
| .RS 4 | .PD |
| | .TP 6n |
| | validate |
| | .nf |
| | .RS 6n |
| | int (*validate)(void); |
| .RE |
.RE |
| .IP "validate" 4 | .fi |
| .IX Item "validate" | .RS 6n |
| .Vb 1 | .sp |
| \& int (*validate)(void); | The |
| .Ve | \fBvalidate\fR() |
| .Sp | function is called when |
| The \f(CW\*(C`validate\*(C'\fR function is called when \fBsudo\fR is run with the | \fBsudo\fR |
| \&\f(CW\*(C`\-v\*(C'\fR flag. For policy plugins such as \fIsudoers\fR that cache | is run with the |
| | \fB\-v\fR |
| | flag. |
| | For policy plugins such as |
| | \fBsudoers\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 | .RE |
| .IX Item "invalidate" | .TP 6n |
| .Vb 1 | invalidate |
| \& void (*invalidate)(int remove); | .nf |
| .Ve | .RS 6n |
| .Sp | void (*invalidate)(int remove); |
| The \f(CW\*(C`invalidate\*(C'\fR function is called when \fBsudo\fR is called with | .RE |
| the \f(CW\*(C`\-k\*(C'\fR or \f(CW\*(C`\-K\*(C'\fR flag. For policy plugins such as \fIsudoers\fR that | .fi |
| | .RS 6n |
| | .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 |
| | \fBsudoers\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); | .RE |
| .Ve | .TP 6n |
| .Sp | init_session |
| The \f(CW\*(C`init_session\*(C'\fR function is called when \fBsudo\fR sets up the | .nf |
| execution environment for the command, immediately before the | .RS 6n |
| contents of the \fIcommand_info\fR list are applied (before the uid | int (*init_session)(struct passwd *pwd, char **user_envp[); |
| changes). This can be used to do session setup that is not supported | .RE |
| by \fIcommand_info\fR, such as opening the \s-1PAM\s0 session. | .fi |
| .Sp | .RS 6n |
| The \fIpwd\fR argument points to a passwd struct for the user the | .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 |
| | \(lqname=value\(rq |
| | 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. |
| |
.RE |
| |
.TP 6n |
| |
register_hooks |
| |
.nf |
| |
.RS 6n |
| |
void (*register_hooks)(int version, |
| |
int (*register_hook)(struct sudo_hook *hook)); |
| |
.RE |
| |
.fi |
| |
.RS 6n |
| |
.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. |
| |
.RE |
| |
.TP 6n |
| |
deregister_hooks |
| |
.nf |
| |
.RS 6n |
| |
void (*deregister_hooks)(int version, |
| |
int (*deregister_hook)(struct sudo_hook *hook)); |
| |
.RE |
| |
.fi |
| |
.RS 6n |
| |
.sp |
| |
The |
| |
\fBderegister_hooks\fR() |
| |
function is called by the sudo front end |
| |
to deregister any hooks the plugin has registered. |
| |
If the plugin does not support hooks, |
| |
\fRderegister_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 |
| |
\fBderegister_hook\fR() |
| |
function should be used to deregister any |
| |
hooks that were put in place by the |
| |
\fBregister_hook\fR() |
| |
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 |
| .PP |
.PP |
| \fIVersion macros\fR | \fIPolicy Plugin Version Macros\fR |
| .IX Subsection "Version macros" | .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[], char * const command_info[], |
| | int argc, char * const argv[], char * const user_env[], |
| | char * const plugin_options[]); |
| | void (*close)(int exit_status, int error); /* wait status or error */ |
| | int (*show_version)(int verbose); |
| | int (*log_ttyin)(const char *buf, unsigned int len); |
| | int (*log_ttyout)(const char *buf, unsigned int len); |
| | int (*log_stdin)(const char *buf, unsigned int len); |
| | int (*log_stdout)(const char *buf, unsigned int len); |
| | int (*log_stderr)(const char *buf, unsigned int len); |
| | void (*register_hooks)(int version, |
| | int (*register_hook)(struct sudo_hook *hook)); |
| | void (*deregister_hooks)(int version, |
| | int (*deregister_hook)(struct sudo_hook *hook)); |
| | }; |
| | .RE |
| | .fi |
| .PP |
.PP |
| .Vb 8 | When an I/O plugin is loaded, |
| \& #define SUDO_API_VERSION_GET_MAJOR(v) ((v) >> 16) | \fBsudo\fR |
| \& #define SUDO_API_VERSION_GET_MINOR(v) ((v) & 0xffff) | runs the command in a pseudo-tty. |
| \& #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 |
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 | .nf |
| \& int (*open)(unsigned int version, sudo_conv_t conversation | .RS 6n |
| \& sudo_printf_t plugin_printf, char * const settings[], | int (*open)(unsigned int version, sudo_conv_t conversation, |
| \& char * const user_info[], int argc, char * const argv[], | sudo_printf_t plugin_printf, char * const settings[], |
| \& char * const user_env[]); | char * const user_info[], int argc, char * const argv[], |
| .Ve | char * const user_env[], char * const plugin_options[]); |
| .Sp | .RE |
| The \fIopen\fR function is run before the \fIlog_input\fR, \fIlog_output\fR | .fi |
| or \fIshow_version\fR functions are called. It is only called if the | .RS 6n |
| 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 |
| | \(lqname=value\(rq |
| | 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 | (\(oq=\(cq) |
| .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. | \(lqname=value\(rq |
| .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 |
| | (\(oq=\(cq) |
| | 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 | \(lqname=value\(rq |
| itself but the \fIvalue\fR might. | strings. |
| | .sp |
| | When parsing |
| | \fIuser_env\fR, |
| | the plugin should split on the |
| | \fBfirst\fR |
| | equal sign |
| | (\(oq=\(cq) |
| | 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. |
| | .PD 0 |
| | .PP |
| .RE |
.RE |
| .RS 4 | .PD |
| | .TP 6n |
| | close |
| | .br |
| | .nf |
| | .RS 6n |
| | void (*close)(int exit_status, int error); |
| .RE |
.RE |
| .IP "close" 4 | .fi |
| .IX Item "close" | .RS 6n |
| .Vb 1 | .sp |
| \& void (*close)(int exit_status, int error); | The |
| .Ve | \fBclose\fR() |
| .Sp | function is called when the command being run by |
| The \f(CW\*(C`close\*(C'\fR function is called when the command being run by \fBsudo\fR | \fBsudo\fR |
| finishes. |
finishes. |
| .Sp | .sp |
| The function arguments are as follows: |
The function arguments are as follows: |
| .RS 4 | .TP 6n |
| .IP "exit_status" 4 | exit_status |
| .IX Item "exit_status" | The command's exit status, as returned by the |
| The command's exit status, as returned by the \fIwait\fR\|(2) system call. | wait(2) |
| The value of \f(CW\*(C`exit_status\*(C'\fR is undefined if \f(CW\*(C`error\*(C'\fR is non-zero. | system call. |
| .IP "error" 4 | The value of |
| .IX Item "error" | \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. |
| | .PD 0 |
| | .PP |
| .RE |
.RE |
| .RS 4 | .PD |
| | .TP 6n |
| | show_version |
| | .nf |
| | .RS 6n |
| | int (*show_version)(int verbose); |
| .RE |
.RE |
| .IP "show_version" 4 | .fi |
| .IX Item "show_version" | .RS 6n |
| .Vb 1 | .sp |
| \& int (*show_version)(int verbose); | The |
| .Ve | \fBshow_version\fR() |
| .Sp | function is called by |
| The \f(CW\*(C`show_version\*(C'\fR function is called by \fBsudo\fR when the user specifies | \fBsudo\fR |
| the \f(CW\*(C`\-V\*(C'\fR option. The plugin may display its version information | when the user specifies |
| to the user via the conversation or plugin_printf function using | the |
| \&\f(CW\*(C`SUDO_CONV_INFO_MSG\*(C'\fR. If the user requests detailed version | \fB\-V\fR |
| information, the verbose flag will be set. | option. |
| .IP "log_ttyin" 4 | The plugin may display its version information to the user via the |
| .IX Item "log_ttyin" | \fBconversation\fR() |
| .Vb 1 | or |
| \& int (*log_ttyin)(const char *buf, unsigned int len); | \fBplugin_printf\fR() |
| .Ve | function using |
| .Sp | \fRSUDO_CONV_INFO_MSG\fR. |
| The \fIlog_ttyin\fR function is called whenever data can be read from | If the user requests detailed version information, the verbose flag will be set. |
| the user but before it is passed to the running command. This | .RE |
| allows the plugin to reject data if it chooses to (for instance | .TP 6n |
| if the input contains banned content). Returns \f(CW1\fR if the data | log_ttyin |
| should be passed to the command, \f(CW0\fR if the data is rejected | .nf |
| (which will terminate the command) or \f(CW\*(C`\-1\*(C'\fR if an error occurred. | .RS 6n |
| .Sp | int (*log_ttyin)(const char *buf, unsigned int len); |
| | .RE |
| | .fi |
| | .RS 6n |
| | .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 | .TP 6n |
| .IP "buf" 4 | buf |
| .IX Item "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. |
| | .PD 0 |
| | .PP |
| .RE |
.RE |
| .RS 4 | .PD |
| | .TP 6n |
| | log_ttyout |
| | .nf |
| | .RS 6n |
| | int (*log_ttyout)(const char *buf, unsigned int len); |
| .RE |
.RE |
| .IP "log_ttyout" 4 | .fi |
| .IX Item "log_ttyout" | .RS 6n |
| .Vb 1 | .sp |
| \& int (*log_ttyout)(const char *buf, unsigned int len); | The |
| .Ve | \fBlog_ttyout\fR() |
| .Sp | function is called whenever data can be read from |
| 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. |
| the command but before it is written to the user's terminal. This | This allows the plugin to reject data if it chooses to (for instance |
| allows the plugin to reject data if it chooses to (for instance | if the output contains banned content). |
| if the output contains banned content). Returns \f(CW1\fR if the data | Returns 1 if the data should be passed to the user, 0 if the data is rejected |
| 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. |
| (which will terminate the command) or \f(CW\*(C`\-1\*(C'\fR if an error occurred. | .sp |
| .Sp | |
| The function arguments are as follows: |
The function arguments are as follows: |
| .RS 4 | .TP 6n |
| .IP "buf" 4 | buf |
| .IX Item "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. |
| | .PD 0 |
| | .PP |
| .RE |
.RE |
| .RS 4 | .PD |
| | .TP 6n |
| | log_stdin |
| | .nf |
| | .RS 6n |
| | int (*log_stdin)(const char *buf, unsigned int len); |
| .RE |
.RE |
| .IP "log_stdin" 4 | .fi |
| .IX Item "log_stdin" | .RS 6n |
| .Vb 1 | .sp |
| \& int (*log_stdin)(const char *buf, unsigned int len); | The |
| .Ve | \fBlog_stdin\fR() |
| .Sp | function is only used if the standard input does |
| The \fIlog_stdin\fR function is only used if the standard input does | not correspond to a tty device. |
| not correspond to a tty device. It is called whenever data can be | It is called whenever data can be read from the standard input but |
| read from the standard input but before it is passed to the running | before it is passed to the running command. |
| command. This allows the plugin to reject data if it chooses to | This allows the plugin to reject data if it chooses to |
| (for instance if the input contains banned content). Returns \f(CW1\fR | (for instance if the input contains banned content). |
| if the data should be passed to the command, \f(CW0\fR if the data is | Returns 1 if the data should be passed to the command, 0 if the data is |
| rejected (which will terminate the command) or \f(CW\*(C`\-1\*(C'\fR if an error | rejected (which will terminate the command) or \-1 if an error occurred. |
| occurred. | .sp |
| .Sp | |
| The function arguments are as follows: |
The function arguments are as follows: |
| .RS 4 | .TP 6n |
| .IP "buf" 4 | buf |
| .IX Item "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. |
| | .PD 0 |
| | .PP |
| .RE |
.RE |
| .RS 4 | .PD |
| | .TP 6n |
| | log_stdout |
| | .nf |
| | .RS 6n |
| | int (*log_stdout)(const char *buf, unsigned int len); |
| .RE |
.RE |
| .IP "log_stdout" 4 | .fi |
| .IX Item "log_stdout" | .RS 6n |
| .Vb 1 | .sp |
| \& int (*log_stdout)(const char *buf, unsigned int len); | The |
| .Ve | \fBlog_stdout\fR() |
| .Sp | function is only used if the standard output does not correspond |
| The \fIlog_stdout\fR function is only used if the standard output does | to a tty device. |
| not correspond to a tty device. It is called whenever data can be | It is called whenever data can be read from the command but before |
| read from the command but before it is written to the standard | it is written to the standard output. |
| output. This allows the plugin to reject data if it chooses to | This allows the plugin to reject data if it chooses to |
| (for instance if the output contains banned content). Returns \f(CW1\fR | (for instance if the output contains banned content). |
| if the data should be passed to the user, \f(CW0\fR if the data is | Returns 1 if the data should be passed to the user, 0 if the data is |
| rejected (which will terminate the command) or \f(CW\*(C`\-1\*(C'\fR if an error | rejected (which will terminate the command) or \-1 if an error occurred. |
| occurred. | .sp |
| .Sp | |
| The function arguments are as follows: |
The function arguments are as follows: |
| .RS 4 | .TP 6n |
| .IP "buf" 4 | buf |
| .IX Item "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. |
| | .PD 0 |
| | .PP |
| .RE |
.RE |
| .RS 4 | .PD |
| | .TP 6n |
| | log_stderr |
| | .nf |
| | .RS 6n |
| | int (*log_stderr)(const char *buf, unsigned int len); |
| .RE |
.RE |
| .IP "log_stderr" 4 | .fi |
| .IX Item "log_stderr" | .RS 6n |
| .Vb 1 | .sp |
| \& int (*log_stderr)(const char *buf, unsigned int len); | The |
| .Ve | \fBlog_stderr\fR() |
| .Sp | function is only used if the standard error does |
| The \fIlog_stderr\fR function is only used if the standard error does | not correspond to a tty device. |
| not correspond to a tty device. It is called whenever data can be | It is called whenever data can be read from the command but before it |
| read from the command but before it is written to the standard | is written to the standard error. |
| error. This allows the plugin to reject data if it chooses to | This allows the plugin to reject data if it chooses to |
| (for instance if the output contains banned content). Returns \f(CW1\fR | (for instance if the output contains banned content). |
| if the data should be passed to the user, \f(CW0\fR if the data is | Returns 1 if the data should be passed to the user, 0 if the data is |
| rejected (which will terminate the command) or \f(CW\*(C`\-1\*(C'\fR if an error | rejected (which will terminate the command) or \-1 if an error occurred. |
| occurred. | .sp |
| .Sp | |
| The function arguments are as follows: |
The function arguments are as follows: |
| .RS 4 | .TP 6n |
| .IP "buf" 4 | buf |
| .IX Item "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. |
| | .PD 0 |
| | .PP |
| .RE |
.RE |
| .RS 4 | .PD |
| | .TP 6n |
| | register_hooks |
| | See the |
| | \fIPolicy plugin API\fR |
| | section for a description of |
| | \fRregister_hooks\fR. |
| | .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 "Signal handlers" |
| | The |
| | \fBsudo\fR |
| | front end installs default signal handlers to trap common signals |
| | while the plugin functions are run. |
| | The following signals are trapped by default before the command is |
| | executed: |
| | .TP 4n |
| | \fBo\fR |
| | \fRSIGALRM\fR |
| | .PD 0 |
| | .TP 4n |
| | \fBo\fR |
| | \fRSIGHUP\fR |
| | .TP 4n |
| | \fBo\fR |
| | \fRSIGINT\fR |
| | .TP 4n |
| | \fBo\fR |
| | \fRSIGQUIT\fR |
| | .TP 4n |
| | \fBo\fR |
| | \fRSIGTERM\fR |
| | .TP 4n |
| | \fBo\fR |
| | \fRSIGTSTP\fR |
| | .TP 4n |
| | \fBo\fR |
| | \fRSIGUSR1\fR |
| | .TP 4n |
| | \fBo\fR |
| | \fRSIGUSR2\fR |
| | .PD |
| | .PP |
| | If a fatal signal is received before the command is executed, |
| | \fBsudo\fR |
| | will call the plugin's |
| | \fBclose\fR() |
| | function with an exit status of 128 plus the value of the signal |
| | that was received. |
| | This allows for consistent logging of commands killed by a signal |
| | for plugins that log such information in their |
| | \fBclose\fR() |
| | function. |
| | .PP |
| | A plugin may temporarily install its own signal handlers but must |
| | restore the original handler before the plugin function returns. |
| | .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: |
| .PP |
.PP |
| Same as for the \*(L"Policy Plugin \s-1API\s0\*(R". | .RS 6n |
| .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_SETENV\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 | setenv(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: |
| | .nf |
| | .sp |
| | .RS 6n |
| | typedef int (*sudo_hook_fn_setenv_t)(const char *name, |
| | const char *value, int overwrite, void *closure); |
| | .RE |
| | .fi |
| | .RS 6n |
| | .sp |
| | If the registered hook does not match the typedef the results are |
| | unspecified. |
| | .RE |
| | .PD |
| | .TP 6n |
| | \fRSUDO_HOOK_UNSETENV\fR |
| | The C library |
| | unsetenv(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: |
| | .nf |
| | .sp |
| | .RS 6n |
| | typedef int (*sudo_hook_fn_unsetenv_t)(const char *name, |
| | void *closure); |
| | .RE |
| | .fi |
| | .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: |
| | .nf |
| | .sp |
| | .RS 6n |
| | typedef int (*sudo_hook_fn_getenv_t)(const char *name, |
| | char **value, void *closure); |
| | .RE |
| | .fi |
| | .RS 6n |
| | .sp |
| | If the registered hook does not match the typedef the results are |
| | unspecified. |
| | .RE |
| | .TP 6n |
| | \fRSUDO_HOOK_PUTENV\fR |
| | The C library |
| | putenv(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: |
| | .nf |
| | .sp |
| | .RS 6n |
| | typedef int (*sudo_hook_fn_putenv_t)(char *string, |
| | void *closure); |
| | .RE |
| | .fi |
| | .RS 6n |
| | .sp |
| | If the registered hook does not match the typedef the results are |
| | unspecified. |
| | .RE |
| | .PD 0 |
| .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 |
| convenient for simple messages where no use input is required. | .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: |
| .PP |
.PP |
| .Vb 11 | .RS 6n |
| \& 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_RET_ERROR\fR |
| \& #define SUDO_CONV_ERROR_MSG 0x0003 /* error message */ | The hook function encountered an error. |
| \& #define SUDO_CONV_INFO_MSG 0x0004 /* informational message */ | .PD |
| \& #define SUDO_CONV_PROMPT_MASK 0x0005 /* mask user input */ | .TP 6n |
| \& #define SUDO_CONV_PROMPT_ECHO_OK 0x1000 /* flag: allow echo if no tty */ | \fRSUDO_HOOK_RET_NEXT\fR |
| \& int msg_type; | The hook completed without error, go on to the next hook (including |
| \& int timeout; | the native implementation if applicable). |
| \& const char *msg; | For example, a |
| \& }; | getenv(3) |
| \& | hook might return |
| \& struct sudo_conv_reply { | \fRSUDO_HOOK_RET_NEXT\fR |
| \& char *reply; | if the specified variable was not found in the private copy of the environment. |
| \& }; | .TP 6n |
| \& | \fRSUDO_HOOK_RET_STOP\fR |
| \& typedef int (*sudo_conv_t)(int num_msgs, | The hook completed without error, stop processing hooks for this invocation. |
| \& const struct sudo_conv_message msgs[], | This can be used to replace the native implementation. |
| \& struct sudo_conv_reply replies[]); | For example, a |
| \& | \fRsetenv\fR |
| \& typedef int (*sudo_printf_t)(int msg_type, const char *fmt, ...); | hook that operates on a private copy of |
| .Ve | the environment but leaves |
| | \fRenviron\fR |
| | unchanged. |
| | .PD 0 |
| .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 |
| .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 |
| if any. | 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 |
.PP |
| The printf-style function uses the same underlying mechanism as the | \fIHook API Version Macros\fR |
| conversation function but only supports \f(CW\*(C`SUDO_CONV_INFO_MSG\*(C'\fR and | .nf |
| \&\f(CW\*(C`SUDO_CONV_ERROR_MSG\*(C'\fR for the \fImsg_type\fR parameter. It can be | .sp |
| more convenient than using the conversation function if no user | .RS 0n |
| reply is needed and supports standard \fIprintf()\fR escape sequences. | /* 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 "Remote command execution" |
| | The |
| | \fBsudo\fR |
| | front end does not have native support for running remote commands. |
| | However, starting with |
| | \fBsudo\fR |
| | 1.8.8, the |
| | \fB\-h\fR |
| | option may be used to specify a remote host that is passed |
| | to the policy plugin. |
| | A plugin may also accept a |
| | \fIrunas_user\fR |
| | in the form of |
| | \(lquser@hostname\(rq |
| | which will work with older versions of |
| | \fBsudo\fR. |
| | It is anticipated that remote commands will be supported by executing a |
| | \(lqhelper\(rq |
| | program. |
| | The policy plugin should setup the execution environment such that the |
| | \fBsudo\fR |
| | front end will run the helper which, in turn, will connect to the |
| | remote host and run the command. |
| .PP |
.PP |
| See the sample plugin for an example of the conversation function usage. | For example, the policy plugin could utilize |
| .SS "Sudoers Group Plugin \s-1API\s0" | \fBssh\fR |
| .IX Subsection "Sudoers Group Plugin API" | to perform remote command execution. |
| The \fIsudoers\fR module supports a plugin interface to allow non-Unix | The helper program would be responsible for running |
| group lookups. This can be used to query a group source other than | \fBssh\fR |
| the standard Unix group database. A sample group plugin is bundled | with the proper options to use a private key or certificate |
| with \fBsudo\fR that implements file-based lookups. Third party group | that the remote host will accept and run a program |
| plugins include a \s-1QAS\s0 \s-1AD\s0 plugin available from Quest Software. | on the remote host that would setup the execution environment |
| | accordingly. |
| .PP |
.PP |
| A group plugin must declare and populate a \f(CW\*(C`sudoers_group_plugin\*(C'\fR | Note that remote |
| struct in the global scope. This structure contains pointers to | \fBsudoedit\fR |
| the functions that implement plugin initialization, cleanup and | functionality must be handled by the policy plugin, not |
| group lookup. | \fBsudo\fR |
| | itself as the front end has no knowledge that a remote command is |
| | being executed. |
| | This may be addressed in a future revision of the plugin API. |
| | .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 |
.PP |
| .Vb 8 | A |
| \& struct sudoers_group_plugin { | \fBprintf\fR()-style |
| \& unsigned int version; | function is also available that can be used to display informational |
| \& int (*init)(int version, sudo_printf_t sudo_printf, | or error messages to the user, which is usually more convenient for |
| \& char *const argv[]); | simple messages where no use input is required. |
| \& void (*cleanup)(void); | .nf |
| \& int (*query)(const char *user, const char *group, | .sp |
| \& const struct passwd *pwd); | .RS 0n |
| \&}; | struct sudo_conv_message { |
| .Ve | #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; |
| | }; |
| | |
| | #define SUDO_CONV_REPL_MAX 255 |
| | |
| | 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 |
.PP |
| The \f(CW\*(C`sudoers_group_plugin\*(C'\fR struct has the following fields: | Pointers to the |
| .IP "version" 4 | \fBconversation\fR() |
| .IX Item "version" | and |
| The \f(CW\*(C`version\*(C'\fR field should be set to \s-1GROUP_API_VERSION\s0. | \fBprintf\fR()-style |
| .Sp | functions are passed |
| This allows \fIsudoers\fR to determine the \s-1API\s0 version the group plugin | 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 located in each |
| | \fRstruct sudo_conv_reply\fR, |
| | if it is not |
| | \fRNULL\fR. |
| | \fRSUDO_CONV_REPL_MAX\fR |
| | represents the maximum length of the reply buffer (not including |
| | the trailing NUL character). |
| | In practical terms, this is the longest password |
| | \fBsudo\fR |
| | will support. |
| | It is also useful as a maximum value for the |
| | \fBmemset_s\fR() |
| | function when clearing passwords filled in by the conversation function. |
| | .PP |
| | The |
| | \fBprintf\fR()-style |
| | function uses the same underlying mechanism as the |
| | \fBconversation\fR() |
| | 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 |
| | Unlike, |
| | \fRSUDO_CONV_INFO_MSG\fR |
| | and |
| | Dv SUDO_CONV_ERROR_MSG , |
| | messages |
| | sent with the |
| | \fRSUDO_CONV_DEBUG_MSG\fR |
| | \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 |
| | sudo.conf(@mansectform@). |
| | file. |
| | This allows a plugin to log debugging information and is intended |
| | to be used in conjunction with the |
| | \fIdebug_flags\fR |
| | setting. |
| | .PP |
| | See the sample plugin for an example of the |
| | \fBconversation\fR() |
| | function usage. |
| | .SS "Sudoers group plugin API" |
| | The |
| | \fBsudoers\fR |
| | plugin supports its own plugin interface to allow non-Unix |
| | group lookups. |
| | This can be used to query a group source other than the standard Unix |
| | group database. |
| | Two sample group plugins are bundled with |
| | \fBsudo\fR, |
| | \fIgroup_file\fR |
| | and |
| | \fIsystem_group\fR, |
| | are detailed in |
| | sudoers(@mansectform@). |
| | Third party group plugins include a QAS AD plugin available from Quest Software. |
| | .PP |
| | A group plugin must declare and populate a |
| | \fRsudoers_group_plugin\fR |
| | struct in the global scope. |
| | This structure contains pointers to the functions that implement plugin |
| | initialization, cleanup and group lookup. |
| | .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 |
| | \fBsudoers\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 | .nf |
| \& int (*init)(int version, sudo_printf_t plugin_printf, | .RS 6n |
| \& char *const argv[]); | int (*init)(int version, sudo_printf_t plugin_printf, |
| .Ve | char *const argv[]); |
| .Sp | .RE |
| The \fIinit\fR function is called after \fIsudoers\fR has been parsed but | .fi |
| before any policy checks. It returns 1 on success, 0 on failure | .RS 6n |
| (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 | \fBsudoers\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 | \fBsudoers\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. |
| | .PD 0 |
| | .PP |
| .RE |
.RE |
| .RS 4 | .PD |
| | .TP 6n |
| | cleanup |
| | .nf |
| | .RS 6n |
| | void (*cleanup)(); |
| .RE |
.RE |
| .IP "cleanup" 4 | .fi |
| .IX Item "cleanup" | .RS 6n |
| .Vb 1 | .sp |
| \& void (*cleanup)(); | The |
| .Ve | \fBcleanup\fR() |
| .Sp | function is called when |
| The \fIcleanup\fR function is called when \fIsudoers\fR has finished its | \fBsudoers\fR |
| group checks. The plugin should free any memory it has allocated | has finished its |
| and close open file handles. | group checks. |
| .IP "query" 4 | The plugin should free any memory it has allocated and close open file handles. |
| .IX Item "query" | .RE |
| .Vb 2 | .TP 6n |
| \& int (*query)(const char *user, const char *group, | query |
| \& const struct passwd *pwd); | .br |
| .Ve | .nf |
| .Sp | .RS 6n |
| The \fIquery\fR function is used to ask the group plugin whether \fIuser\fR | int (*query)(const char *user, const char *group, |
| is a member of \fIgroup\fR. | const struct passwd *pwd); |
| .Sp | .RE |
| | .fi |
| | .RS 6n |
| | .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 | .TP 6n |
| .IP "user" 4 | user |
| .IX Item "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. |
| | .PD 0 |
| | .PP |
| .RE |
.RE |
| .RS 4 | .PD |
| .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 (sudo 1.8.0) |
| | 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 (sudo 1.8.5) |
| | The Policy and I/O logging plugins' |
| | \fBopen\fR() |
| | functions are now passed |
| | a list of plugin parameters if any are specified in |
| | sudo.conf(@mansectform@). |
| | .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. |
| | .TP 6n |
| | Version 1.3 (sudo 1.8.7) |
| | Support for the |
| | \fIexec_background\fR |
| | entry has been added to the |
| | \fRcommand_info\fR |
| | list. |
| | .sp |
| | The |
| | \fImax_groups\fR |
| | and |
| | \fIplugin_dir\fR |
| | entries were added to the |
| | \fRsettings\fR |
| | list. |
| | .sp |
| | The |
| | \fBversion\fR() |
| | and |
| | \fBclose\fR() |
| | functions are now optional. |
| | Previously, a missing |
| | \fBversion\fR() |
| | or |
| | \fBclose\fR() |
| | function would result in a crash. |
| | If no policy plugin |
| | \fBclose\fR() |
| | function is defined, a default |
| | \fBclose\fR() |
| | function will be provided by the |
| | \fBsudo\fR |
| | front end that displays a warning if the command could not be |
| | executed. |
| | .sp |
| | The |
| | \fBsudo\fR |
| | front end now installs default signal handlers to trap common signals |
| | while the plugin functions are run. |
| | .TP 6n |
| | Version 1.4 (sudo 1.8.8) |
| | The |
| | \fIremote_host\fR |
| | entry was added to the |
| | \fRsettings\fR |
| | list. |
| | .TP 6n |
| | Version 1.5 (sudo 1.8.9) |
| | The |
| | entry was added to the |
| | \fRcommand_info\fR |
| | list. |
| .SH "SEE ALSO" |
.SH "SEE ALSO" |
| .IX Header "SEE ALSO" | sudo.conf(@mansectform@), |
| \&\fIsudoers\fR\|(@mansectform@), \fIsudo\fR\|(@mansectsu@) | sudoers(@mansectform@), |
| | 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 | \(lqAS IS\(rq |
| 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. |