Annotation of embedaddon/sudo/doc/sudo_plugin.man.in, revision 1.1.1.2

1.1.1.2 ! misho       1: .\" Copyright (c) 2009-2012 Todd C. Miller <Todd.Miller@courtesan.com>
1.1       misho       2: .\" 
                      3: .\" Permission to use, copy, modify, and distribute this software for any
                      4: .\" purpose with or without fee is hereby granted, provided that the above
                      5: .\" copyright notice and this permission notice appear in all copies.
                      6: .\" 
                      7: .\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                      8: .\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                      9: .\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     10: .\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     11: .\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     12: .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
                     13: .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     14: .\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     15: .\" 
                     16: .\" Automatically generated by Pod::Man 2.23 (Pod::Simple 3.14)
                     17: .\"
                     18: .\" Standard preamble:
                     19: .\" ========================================================================
                     20: .de Sp \" Vertical space (when we can't use .PP)
                     21: .if t .sp .5v
                     22: .if n .sp
                     23: ..
                     24: .de Vb \" Begin verbatim text
                     25: .ft CW
                     26: .nf
                     27: .ne \\$1
                     28: ..
                     29: .de Ve \" End verbatim text
                     30: .ft R
                     31: .fi
                     32: ..
                     33: .\" Set up some character translations and predefined strings.  \*(-- will
                     34: .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
                     35: .\" double quote, and \*(R" will give a right double quote.  \*(C+ will
                     36: .\" give a nicer C++.  Capital omega is used to do unbreakable dashes and
                     37: .\" therefore won't be available.  \*(C` and \*(C' expand to `' in nroff,
                     38: .\" nothing in troff, for use with C<>.
                     39: .tr \(*W-
                     40: .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
                     41: .ie n \{\
                     42: .    ds -- \(*W-
                     43: .    ds PI pi
                     44: .    if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
                     45: .    if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\"  diablo 12 pitch
                     46: .    ds L" ""
                     47: .    ds R" ""
                     48: .    ds C` 
                     49: .    ds C' 
                     50: 'br\}
                     51: .el\{\
                     52: .    ds -- \|\(em\|
                     53: .    ds PI \(*p
                     54: .    ds L" ``
                     55: .    ds R" ''
                     56: 'br\}
                     57: .\"
                     58: .\" Escape single quotes in literal strings from groff's Unicode transform.
                     59: .ie \n(.g .ds Aq \(aq
                     60: .el       .ds Aq '
                     61: .\"
                     62: .\" If the F register is turned on, we'll generate index entries on stderr for
                     63: .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
                     64: .\" entries marked with X<> in POD.  Of course, you'll have to process the
                     65: .\" output yourself in some meaningful fashion.
                     66: .ie \nF \{\
                     67: .    de IX
                     68: .    tm Index:\\$1\t\\n%\t"\\$2"
                     69: ..
                     70: .    nr % 0
                     71: .    rr F
                     72: .\}
                     73: .el \{\
                     74: .    de IX
                     75: ..
                     76: .\}
                     77: .\"
                     78: .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
                     79: .\" Fear.  Run.  Save yourself.  No user-serviceable parts.
                     80: .    \" fudge factors for nroff and troff
                     81: .if n \{\
                     82: .    ds #H 0
                     83: .    ds #V .8m
                     84: .    ds #F .3m
                     85: .    ds #[ \f1
                     86: .    ds #] \fP
                     87: .\}
                     88: .if t \{\
                     89: .    ds #H ((1u-(\\\\n(.fu%2u))*.13m)
                     90: .    ds #V .6m
                     91: .    ds #F 0
                     92: .    ds #[ \&
                     93: .    ds #] \&
                     94: .\}
                     95: .    \" simple accents for nroff and troff
                     96: .if n \{\
                     97: .    ds ' \&
                     98: .    ds ` \&
                     99: .    ds ^ \&
                    100: .    ds , \&
                    101: .    ds ~ ~
                    102: .    ds /
                    103: .\}
                    104: .if t \{\
                    105: .    ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
                    106: .    ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
                    107: .    ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
                    108: .    ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
                    109: .    ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
                    110: .    ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
                    111: .\}
                    112: .    \" troff and (daisy-wheel) nroff accents
                    113: .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
                    114: .ds 8 \h'\*(#H'\(*b\h'-\*(#H'
                    115: .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
                    116: .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
                    117: .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
                    118: .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
                    119: .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
                    120: .ds ae a\h'-(\w'a'u*4/10)'e
                    121: .ds Ae A\h'-(\w'A'u*4/10)'E
                    122: .    \" corrections for vroff
                    123: .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
                    124: .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
                    125: .    \" for low resolution devices (crt and lpr)
                    126: .if \n(.H>23 .if \n(.V>19 \
                    127: \{\
                    128: .    ds : e
                    129: .    ds 8 ss
                    130: .    ds o a
                    131: .    ds d- d\h'-1'\(ga
                    132: .    ds D- D\h'-1'\(hy
                    133: .    ds th \o'bp'
                    134: .    ds Th \o'LP'
                    135: .    ds ae ae
                    136: .    ds Ae AE
                    137: .\}
                    138: .rm #[ #] #H #V #F C
                    139: .\" ========================================================================
                    140: .\"
                    141: .IX Title "SUDO_PLUGIN @mansectsu@"
1.1.1.2 ! misho     142: .TH SUDO_PLUGIN @mansectsu@ "April 23, 2012" "1.8.5" "MAINTENANCE COMMANDS"
1.1       misho     143: .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
                    144: .\" way too many mistakes in technical documents.
                    145: .if n .ad l
                    146: .nh
                    147: .SH "NAME"
                    148: sudo_plugin \- Sudo Plugin API
                    149: .SH "DESCRIPTION"
                    150: .IX Header "DESCRIPTION"
                    151: Starting with version 1.8, \fBsudo\fR supports a plugin \s-1API\s0
                    152: for policy and session logging.  By default, the \fIsudoers\fR policy
                    153: plugin and an associated I/O logging plugin are used.  Via the plugin
                    154: \&\s-1API\s0, \fBsudo\fR can be configured to use alternate policy and/or I/O
                    155: logging plugins provided by third parties.  The plugins to be used
                    156: are specified via the \fI@sysconfdir@/sudo.conf\fR file.
                    157: .PP
                    158: The \s-1API\s0 is versioned with a major and minor number.  The minor
                    159: version number is incremented when additions are made.  The major
                    160: number is incremented when incompatible changes are made.  A plugin
                    161: should be check the version passed to it and make sure that the
                    162: major version matches.
                    163: .PP
                    164: The plugin \s-1API\s0 is defined by the \f(CW\*(C`sudo_plugin.h\*(C'\fR header file.
                    165: .SS "The sudo.conf File"
                    166: .IX Subsection "The sudo.conf File"
                    167: The \fI@sysconfdir@/sudo.conf\fR file contains plugin configuration directives.
                    168: Currently, the only supported keyword is the \f(CW\*(C`Plugin\*(C'\fR directive,
                    169: which causes a plugin plugin to be loaded.
                    170: .PP
                    171: A \f(CW\*(C`Plugin\*(C'\fR line consists of the \f(CW\*(C`Plugin\*(C'\fR keyword, followed by the
                    172: \&\fIsymbol_name\fR and the \fIpath\fR to the shared object containing the
                    173: plugin.  The \fIsymbol_name\fR is the name of the \f(CW\*(C`struct policy_plugin\*(C'\fR
                    174: or \f(CW\*(C`struct io_plugin\*(C'\fR in the plugin shared object.  The \fIpath\fR
                    175: may be fully qualified or relative.  If not fully qualified it is
                    176: relative to the \fI@prefix@/libexec\fR directory.  Any additional
1.1.1.2 ! misho     177: parameters after the \fIpath\fR are passed as options to the plugin's
        !           178: \&\fIopen\fR function.  Lines that don't begin with \f(CW\*(C`Plugin\*(C'\fR, \f(CW\*(C`Path\*(C'\fR,
        !           179: \&\f(CW\*(C`Debug\*(C'\fR or \f(CW\*(C`Set\*(C'\fR are silently ignored.
1.1       misho     180: .PP
                    181: The same shared object may contain multiple plugins, each with a
                    182: different symbol name.  The shared object file must be owned by uid
                    183: 0 and only writable by its owner.  Because of ambiguities that arise
                    184: from composite policies, only a single policy plugin may be specified.
                    185: This limitation does not apply to I/O plugins.
                    186: .PP
                    187: .Vb 10
                    188: \& #
                    189: \& # Default @sysconfdir@/sudo.conf file
                    190: \& #
                    191: \& # Format:
1.1.1.2 ! misho     192: \& #   Plugin plugin_name plugin_path plugin_options ...
1.1       misho     193: \& #   Path askpass /path/to/askpass
1.1.1.2 ! misho     194: \& #   Path noexec /path/to/sudo_noexec.so
        !           195: \& #   Debug sudo /var/log/sudo_debug all@warn
        !           196: \& #   Set disable_coredump true
1.1       misho     197: \& #
                    198: \& # The plugin_path is relative to @prefix@/libexec unless
                    199: \& #   fully qualified.
                    200: \& # The plugin_name corresponds to a global symbol in the plugin
                    201: \& #   that contains the plugin interface structure.
1.1.1.2 ! misho     202: \& # The plugin_options are optional.
1.1       misho     203: \& #
                    204: \& Plugin sudoers_policy sudoers.so
                    205: \& Plugin sudoers_io sudoers.so
                    206: .Ve
                    207: .SS "Policy Plugin \s-1API\s0"
                    208: .IX Subsection "Policy Plugin API"
                    209: A policy plugin must declare and populate a \f(CW\*(C`policy_plugin\*(C'\fR struct
                    210: in the global scope.  This structure contains pointers to the functions
                    211: that implement the \fBsudo\fR policy checks.  The name of the symbol should
                    212: be specified in \fI@sysconfdir@/sudo.conf\fR along with a path to the plugin
                    213: so that \fBsudo\fR can load it.
                    214: .PP
                    215: .Vb 10
                    216: \& struct policy_plugin {
                    217: \& #define SUDO_POLICY_PLUGIN     1
                    218: \&     unsigned int type; /* always SUDO_POLICY_PLUGIN */
                    219: \&     unsigned int version; /* always SUDO_API_VERSION */
                    220: \&     int (*open)(unsigned int version, sudo_conv_t conversation,
                    221: \&                 sudo_printf_t plugin_printf, char * const settings[],
1.1.1.2 ! misho     222: \&                 char * const user_info[], char * const user_env[],
        !           223: \&                 char * const plugin_options[]);
1.1       misho     224: \&     void (*close)(int exit_status, int error);
                    225: \&     int (*show_version)(int verbose);
                    226: \&     int (*check_policy)(int argc, char * const argv[],
                    227: \&                         char *env_add[], char **command_info[],
                    228: \&                         char **argv_out[], char **user_env_out[]);
                    229: \&     int (*list)(int argc, char * const argv[], int verbose,
                    230: \&                 const char *list_user);
                    231: \&     int (*validate)(void);
                    232: \&     void (*invalidate)(int remove);
1.1.1.2 ! misho     233: \&     int (*init_session)(struct passwd *pwd, char **user_env[]);
        !           234: \&     void (*register_hooks)(int version,
        !           235: \&        int (*register_hook)(struct sudo_hook *hook));
        !           236: \&     void (*deregister_hooks)(int version,
        !           237: \&        int (*deregister_hook)(struct sudo_hook *hook));
1.1       misho     238: \& };
                    239: .Ve
                    240: .PP
                    241: The policy_plugin struct has the following fields:
                    242: .IP "type" 4
                    243: .IX Item "type"
                    244: The \f(CW\*(C`type\*(C'\fR field should always be set to \s-1SUDO_POLICY_PLUGIN\s0.
                    245: .IP "version" 4
                    246: .IX Item "version"
                    247: The \f(CW\*(C`version\*(C'\fR field should be set to \s-1SUDO_API_VERSION\s0.
                    248: .Sp
                    249: This allows \fBsudo\fR to determine the \s-1API\s0 version the plugin was
                    250: built against.
                    251: .IP "open" 4
                    252: .IX Item "open"
1.1.1.2 ! misho     253: .Vb 4
1.1       misho     254: \& int (*open)(unsigned int version, sudo_conv_t conversation,
                    255: \&             sudo_printf_t plugin_printf, char * const settings[],
1.1.1.2 ! misho     256: \&             char * const user_info[], char * const user_env[],
        !           257: \&             char * const plugin_options[]);
1.1       misho     258: .Ve
                    259: .Sp
                    260: Returns 1 on success, 0 on failure, \-1 if a general error occurred,
                    261: or \-2 if there was a usage error.  In the latter case, \fBsudo\fR will
                    262: print a usage message before it exits.  If an error occurs, the
                    263: plugin may optionally call the conversation or plugin_printf function
                    264: with \f(CW\*(C`SUDO_CONF_ERROR_MSG\*(C'\fR to present additional error information
                    265: to the user.
                    266: .Sp
                    267: The function arguments are as follows:
                    268: .RS 4
                    269: .IP "version" 4
                    270: .IX Item "version"
                    271: The version passed in by \fBsudo\fR allows the plugin to determine the
                    272: major and minor version number of the plugin \s-1API\s0 supported by
                    273: \&\fBsudo\fR.
                    274: .IP "conversation" 4
                    275: .IX Item "conversation"
                    276: A pointer to the conversation function that can be used by the
                    277: plugin to interact with the user (see below).
                    278: Returns 0 on success and \-1 on failure.
                    279: .IP "plugin_printf" 4
                    280: .IX Item "plugin_printf"
                    281: A pointer to a printf-style function that may be used to display
                    282: informational or error messages (see below).
                    283: Returns the number of characters printed on success and \-1 on failure.
                    284: .IP "settings" 4
                    285: .IX Item "settings"
                    286: A vector of user-supplied \fBsudo\fR settings in the form of \*(L"name=value\*(R"
                    287: strings.  The vector is terminated by a \f(CW\*(C`NULL\*(C'\fR pointer.  These
                    288: settings correspond to flags the user specified when running \fBsudo\fR.
                    289: As such, they will only be present when the corresponding flag has
                    290: been specified on the command line.
                    291: .Sp
                    292: When parsing \fIsettings\fR, the plugin should split on the \fBfirst\fR
                    293: equal sign ('=') since the \fIname\fR field will never include one
                    294: itself but the \fIvalue\fR might.
                    295: .RS 4
1.1.1.2 ! misho     296: .IP "debug_flags=string" 4
        !           297: .IX Item "debug_flags=string"
        !           298: A comma-separated list of debug flags that correspond to \fBsudo\fR's
        !           299: \&\f(CW\*(C`Debug\*(C'\fR entry in \fI@sysconfdir@/sudo.conf\fR, if there is one.  The
        !           300: flags are passed to the plugin as they appear in \fI@sysconfdir@/sudo.conf\fR.
        !           301: The syntax used by \fBsudo\fR and the \fIsudoers\fR plugin is
        !           302: \&\fIsubsystem\fR@\fIpriority\fR but the plugin is free to use a different
        !           303: format so long as it does not include a command \f(CW\*(C`,\*(C'\fR.
        !           304: .Sp
        !           305: For reference, the priorities supported by the \fBsudo\fR front end and
        !           306: \&\fIsudoers\fR are: \fIcrit\fR, \fIerr\fR, \fIwarn\fR, \fInotice\fR, \fIdiag\fR,
        !           307: \&\fIinfo\fR, \fItrace\fR and \fIdebug\fR.
        !           308: .Sp
        !           309: The following subsystems are defined: \fImain\fR, \fImemory\fR, \fIargs\fR,
        !           310: \&\fIexec\fR, \fIpty\fR, \fIutmp\fR, \fIconv\fR, \fIpcomm\fR, \fIutil\fR, \fIlist\fR,
        !           311: \&\fInetif\fR, \fIaudit\fR, \fIedit\fR, \fIselinux\fR, \fIldap\fR, \fImatch\fR, \fIparser\fR,
        !           312: \&\fIalias\fR, \fIdefaults\fR, \fIauth\fR, \fIenv\fR, \fIlogging\fR, \fInss\fR, \fIrbtree\fR,
        !           313: \&\fIperms\fR, \fIplugin\fR.  The subsystem \fIall\fR includes every subsystem.
        !           314: .Sp
        !           315: There is not currently a way to specify a set of debug flags specific
        !           316: to the plugin\*(--the flags are shared by \fBsudo\fR and the plugin.
1.1       misho     317: .IP "debug_level=number" 4
                    318: .IX Item "debug_level=number"
1.1.1.2 ! misho     319: This setting has been deprecated in favor of \fIdebug_flags\fR.
1.1       misho     320: .IP "runas_user=string" 4
                    321: .IX Item "runas_user=string"
                    322: The user name or uid to to run the command as, if specified via the
                    323: \&\f(CW\*(C`\-u\*(C'\fR flag.
                    324: .IP "runas_group=string" 4
                    325: .IX Item "runas_group=string"
                    326: The group name or gid to to run the command as, if specified via
                    327: the \f(CW\*(C`\-g\*(C'\fR flag.
                    328: .IP "prompt=string" 4
                    329: .IX Item "prompt=string"
                    330: The prompt to use when requesting a password, if specified via
                    331: the \f(CW\*(C`\-p\*(C'\fR flag.
                    332: .IP "set_home=bool" 4
                    333: .IX Item "set_home=bool"
                    334: Set to true if the user specified the \f(CW\*(C`\-H\*(C'\fR flag.  If true, set the
                    335: \&\f(CW\*(C`HOME\*(C'\fR environment variable to the target user's home directory.
                    336: .IP "preserve_environment=bool" 4
                    337: .IX Item "preserve_environment=bool"
                    338: Set to true if the user specified the \f(CW\*(C`\-E\*(C'\fR flag, indicating that
                    339: the user wishes to preserve the environment.
                    340: .IP "run_shell=bool" 4
                    341: .IX Item "run_shell=bool"
                    342: Set to true if the user specified the \f(CW\*(C`\-s\*(C'\fR flag, indicating that
                    343: the user wishes to run a shell.
                    344: .IP "login_shell=bool" 4
                    345: .IX Item "login_shell=bool"
                    346: Set to true if the user specified the \f(CW\*(C`\-i\*(C'\fR flag, indicating that
                    347: the user wishes to run a login shell.
                    348: .IP "implied_shell=bool" 4
                    349: .IX Item "implied_shell=bool"
                    350: If the user does not specify a program on the command line, \fBsudo\fR
                    351: will pass the plugin the path to the user's shell and set
                    352: \&\fIimplied_shell\fR to true.  This allows \fBsudo\fR with no arguments
                    353: to be used similarly to \fIsu\fR\|(1).  If the plugin does not to support
                    354: this usage, it may return a value of \-2 from the \f(CW\*(C`check_policy\*(C'\fR
                    355: function, which will cause \fBsudo\fR to print a usage message and
                    356: exit.
                    357: .IP "preserve_groups=bool" 4
                    358: .IX Item "preserve_groups=bool"
                    359: Set to true if the user specified the \f(CW\*(C`\-P\*(C'\fR flag, indicating that
                    360: the user wishes to preserve the group vector instead of setting it
                    361: based on the runas user.
                    362: .IP "ignore_ticket=bool" 4
                    363: .IX Item "ignore_ticket=bool"
                    364: Set to true if the user specified the \f(CW\*(C`\-k\*(C'\fR flag along with a
                    365: command, indicating that the user wishes to ignore any cached
                    366: authentication credentials.
                    367: .IP "noninteractive=bool" 4
                    368: .IX Item "noninteractive=bool"
                    369: Set to true if the user specified the \f(CW\*(C`\-n\*(C'\fR flag, indicating that
                    370: \&\fBsudo\fR should operate in non-interactive mode.  The plugin may
                    371: reject a command run in non-interactive mode if user interaction
                    372: is required.
                    373: .IP "login_class=string" 4
                    374: .IX Item "login_class=string"
                    375: \&\s-1BSD\s0 login class to use when setting resource limits and nice value,
                    376: if specified by the \f(CW\*(C`\-c\*(C'\fR flag.
                    377: .IP "selinux_role=string" 4
                    378: .IX Item "selinux_role=string"
                    379: SELinux role to use when executing the command, if specified by
                    380: the \f(CW\*(C`\-r\*(C'\fR flag.
                    381: .IP "selinux_type=string" 4
                    382: .IX Item "selinux_type=string"
                    383: SELinux type to use when executing the command, if specified by
                    384: the \f(CW\*(C`\-t\*(C'\fR flag.
                    385: .IP "bsdauth_type=string" 4
                    386: .IX Item "bsdauth_type=string"
                    387: Authentication type, if specified by the \f(CW\*(C`\-a\*(C'\fR flag, to use on
                    388: systems where \s-1BSD\s0 authentication is supported.
                    389: .IP "network_addrs=list" 4
                    390: .IX Item "network_addrs=list"
                    391: A space-separated list of \s-1IP\s0 network addresses and netmasks in the
                    392: form \*(L"addr/netmask\*(R", e.g. \*(L"192.168.1.2/255.255.255.0\*(R".  The address
                    393: and netmask pairs may be either IPv4 or IPv6, depending on what the
                    394: operating system supports.  If the address contains a colon (':'),
                    395: it is an IPv6 address, else it is IPv4.
                    396: .IP "progname=string" 4
                    397: .IX Item "progname=string"
                    398: The command name that sudo was run as, typically \*(L"sudo\*(R" or \*(L"sudoedit\*(R".
                    399: .IP "sudoedit=bool" 4
                    400: .IX Item "sudoedit=bool"
                    401: Set to true when the \f(CW\*(C`\-e\*(C'\fR flag is is specified or if invoked as
                    402: \&\fBsudoedit\fR.  The plugin shall substitute an editor into \fIargv\fR
                    403: in the \fIcheck_policy\fR function or return \f(CW\*(C`\-2\*(C'\fR with a usage error
                    404: if the plugin does not support \fIsudoedit\fR.  For more information,
                    405: see the \fIcheck_policy\fR section.
                    406: .IP "closefrom=number" 4
                    407: .IX Item "closefrom=number"
                    408: If specified, the user has requested via the \f(CW\*(C`\-C\*(C'\fR flag that \fBsudo\fR
                    409: close all files descriptors with a value of \fInumber\fR or higher.
                    410: The plugin may optionally pass this, or another value, back in the
                    411: \&\fIcommand_info\fR list.
                    412: .RE
                    413: .RS 4
                    414: .Sp
                    415: Additional settings may be added in the future so the plugin should
                    416: silently ignore settings that it does not recognize.
                    417: .RE
                    418: .IP "user_info" 4
                    419: .IX Item "user_info"
                    420: A vector of information about the user running the command in the form of
                    421: \&\*(L"name=value\*(R" strings.  The vector is terminated by a \f(CW\*(C`NULL\*(C'\fR pointer.
                    422: .Sp
                    423: When parsing \fIuser_info\fR, the plugin should split on the \fBfirst\fR
                    424: equal sign ('=') since the \fIname\fR field will never include one
                    425: itself but the \fIvalue\fR might.
                    426: .RS 4
1.1.1.2 ! misho     427: .IP "pid=int" 4
        !           428: .IX Item "pid=int"
        !           429: The process \s-1ID\s0 of the running \fBsudo\fR process.
        !           430: Only available starting with \s-1API\s0 version 1.2
        !           431: .IP "ppid=int" 4
        !           432: .IX Item "ppid=int"
        !           433: The parent process \s-1ID\s0 of the running \fBsudo\fR process.
        !           434: Only available starting with \s-1API\s0 version 1.2
        !           435: .IP "sid=int" 4
        !           436: .IX Item "sid=int"
        !           437: The session \s-1ID\s0 of the running \fBsudo\fR process or 0 if \fBsudo\fR is
        !           438: not part of a \s-1POSIX\s0 job control session.
        !           439: Only available starting with \s-1API\s0 version 1.2
        !           440: .IP "pgid=int" 4
        !           441: .IX Item "pgid=int"
        !           442: The \s-1ID\s0 of the process group that the running \fBsudo\fR process belongs
        !           443: to.
        !           444: Only available starting with \s-1API\s0 version 1.2
        !           445: .IP "tcpgid=int" 4
        !           446: .IX Item "tcpgid=int"
        !           447: The \s-1ID\s0 of the forground process group associated with the terminal
        !           448: device associcated with the \fBsudo\fR process or \-1 if there is no
        !           449: terminal present.
        !           450: Only available starting with \s-1API\s0 version 1.2
1.1       misho     451: .IP "user=string" 4
                    452: .IX Item "user=string"
                    453: The name of the user invoking \fBsudo\fR.
1.1.1.2 ! misho     454: .IP "euid=uid_t" 4
        !           455: .IX Item "euid=uid_t"
        !           456: The effective user \s-1ID\s0 of the user invoking \fBsudo\fR.
1.1       misho     457: .IP "uid=uid_t" 4
                    458: .IX Item "uid=uid_t"
                    459: The real user \s-1ID\s0 of the user invoking \fBsudo\fR.
1.1.1.2 ! misho     460: .IP "egid=gid_t" 4
        !           461: .IX Item "egid=gid_t"
        !           462: The effective group \s-1ID\s0 of the user invoking \fBsudo\fR.
1.1       misho     463: .IP "gid=gid_t" 4
                    464: .IX Item "gid=gid_t"
                    465: The real group \s-1ID\s0 of the user invoking \fBsudo\fR.
                    466: .IP "groups=list" 4
                    467: .IX Item "groups=list"
                    468: The user's supplementary group list formatted as a string of
                    469: comma-separated group IDs.
                    470: .IP "cwd=string" 4
                    471: .IX Item "cwd=string"
                    472: The user's current working directory.
                    473: .IP "tty=string" 4
                    474: .IX Item "tty=string"
                    475: The path to the user's terminal device.  If the user has no terminal
                    476: device associated with the session, the value will be empty, as in
                    477: \&\f(CW\*(C`tty=\*(C'\fR.
                    478: .IP "host=string" 4
                    479: .IX Item "host=string"
                    480: The local machine's hostname as returned by the \f(CW\*(C`gethostname()\*(C'\fR
                    481: system call.
                    482: .IP "lines=int" 4
                    483: .IX Item "lines=int"
                    484: The number of lines the user's terminal supports.  If there is
                    485: no terminal device available, a default value of 24 is used.
                    486: .IP "cols=int" 4
                    487: .IX Item "cols=int"
                    488: The number of columns the user's terminal supports.  If there is
                    489: no terminal device available, a default value of 80 is used.
                    490: .RE
                    491: .RS 4
                    492: .RE
                    493: .IP "user_env" 4
                    494: .IX Item "user_env"
                    495: The user's environment in the form of a \f(CW\*(C`NULL\*(C'\fR\-terminated vector of
                    496: \&\*(L"name=value\*(R" strings.
                    497: .Sp
                    498: When parsing \fIuser_env\fR, the plugin should split on the \fBfirst\fR
                    499: equal sign ('=') since the \fIname\fR field will never include one
                    500: itself but the \fIvalue\fR might.
1.1.1.2 ! misho     501: .IP "plugin_options" 4
        !           502: .IX Item "plugin_options"
        !           503: Any (non-comment) strings immediately after the plugin path are
        !           504: treated as arguments to the plugin.  These arguments are split on
        !           505: a white space boundary and are passed to the plugin in the form of
        !           506: a \f(CW\*(C`NULL\*(C'\fR\-terminated array of strings.  If no arguments were
        !           507: specified, \fIplugin_options\fR will be the \s-1NULL\s0 pointer.
        !           508: .Sp
        !           509: \&\s-1NOTE:\s0 the \fIplugin_options\fR parameter is only available starting with
        !           510: \&\s-1API\s0 version 1.2.  A plugin \fBmust\fR check the \s-1API\s0 version specified
        !           511: by the \fBsudo\fR front end before using \fIplugin_options\fR.  Failure to
        !           512: do so may result in a crash.
1.1       misho     513: .RE
                    514: .RS 4
                    515: .RE
                    516: .IP "close" 4
                    517: .IX Item "close"
                    518: .Vb 1
                    519: \& void (*close)(int exit_status, int error);
                    520: .Ve
                    521: .Sp
                    522: The \f(CW\*(C`close\*(C'\fR function is called when the command being run by \fBsudo\fR
                    523: finishes.
                    524: .Sp
                    525: The function arguments are as follows:
                    526: .RS 4
                    527: .IP "exit_status" 4
                    528: .IX Item "exit_status"
                    529: The command's exit status, as returned by the \fIwait\fR\|(2) system call.
                    530: The value of \f(CW\*(C`exit_status\*(C'\fR is undefined if \f(CW\*(C`error\*(C'\fR is non-zero.
                    531: .IP "error" 4
                    532: .IX Item "error"
                    533: If the command could not be executed, this is set to the value of
                    534: \&\f(CW\*(C`errno\*(C'\fR set by the \fIexecve\fR\|(2) system call.  The plugin is responsible
                    535: for displaying error information via the conversation or plugin_printf
                    536: function.  If the command was successfully executed, the value of
                    537: \&\f(CW\*(C`error\*(C'\fR is 0.
                    538: .RE
                    539: .RS 4
                    540: .RE
                    541: .IP "show_version" 4
                    542: .IX Item "show_version"
                    543: .Vb 1
                    544: \& int (*show_version)(int verbose);
                    545: .Ve
                    546: .Sp
                    547: The \f(CW\*(C`show_version\*(C'\fR function is called by \fBsudo\fR when the user specifies
                    548: the \f(CW\*(C`\-V\*(C'\fR option.  The plugin may display its version information
                    549: to the user via the conversation or plugin_printf function using
                    550: \&\f(CW\*(C`SUDO_CONV_INFO_MSG\*(C'\fR.  If the user requests detailed version
                    551: information, the verbose flag will be set.
                    552: .IP "check_policy" 4
                    553: .IX Item "check_policy"
                    554: .Vb 3
                    555: \& int (*check_policy)(int argc, char * const argv[]
                    556: \&                     char *env_add[], char **command_info[],
                    557: \&                     char **argv_out[], char **user_env_out[]);
                    558: .Ve
                    559: .Sp
                    560: The \fIcheck_policy\fR function is called by \fBsudo\fR to determine
                    561: whether the user is allowed to run the specified commands.
                    562: .Sp
                    563: If the \fIsudoedit\fR option was enabled in the \fIsettings\fR array
                    564: passed to the \fIopen\fR function, the user has requested \fIsudoedit\fR
                    565: mode.  \fIsudoedit\fR is a mechanism for editing one or more files
                    566: where an editor is run with the user's credentials instead of with
                    567: elevated privileges.  \fBsudo\fR achieves this by creating user-writable
                    568: temporary copies of the files to be edited and then overwriting the
                    569: originals with the temporary copies after editing is complete.  If
                    570: the plugin supports \fBsudoedit\fR, it should choose the editor to be
                    571: used, potentially from a variable in the user's environment, such
                    572: as \f(CW\*(C`EDITOR\*(C'\fR, and include it in \fIargv_out\fR (note that environment
                    573: variables may include command line flags).  The files to be edited
                    574: should be copied from \fIargv\fR into \fIargv_out\fR, separated from the
                    575: editor and its arguments by a \f(CW"\-\-"\fR element.  The \f(CW"\-\-"\fR will
                    576: be removed by \fBsudo\fR before the editor is executed.  The plugin
                    577: should also set \fIsudoedit=true\fR in the \fIcommand_info\fR list.
                    578: .Sp
                    579: The \fIcheck_policy\fR function returns 1 if the command is allowed,
                    580: 0 if not allowed, \-1 for a general error, or \-2 for a usage error
                    581: or if \fBsudoedit\fR was specified but is unsupported by the plugin.
                    582: In the latter case, \fBsudo\fR will print a usage message before it
                    583: exits.  If an error occurs, the plugin may optionally call the
                    584: conversation or plugin_printf function with \f(CW\*(C`SUDO_CONF_ERROR_MSG\*(C'\fR
                    585: to present additional error information to the user.
                    586: .Sp
                    587: The function arguments are as follows:
                    588: .RS 4
                    589: .IP "argc" 4
                    590: .IX Item "argc"
                    591: The number of elements in \fIargv\fR, not counting the final \f(CW\*(C`NULL\*(C'\fR
                    592: pointer.
                    593: .IP "argv" 4
                    594: .IX Item "argv"
                    595: The argument vector describing the command the user wishes to run,
                    596: in the same form as what would be passed to the \fIexecve()\fR system
                    597: call.  The vector is terminated by a \f(CW\*(C`NULL\*(C'\fR pointer.
                    598: .IP "env_add" 4
                    599: .IX Item "env_add"
                    600: Additional environment variables specified by the user on the command
                    601: line in the form of a \f(CW\*(C`NULL\*(C'\fR\-terminated vector of \*(L"name=value\*(R"
                    602: strings.  The plugin may reject the command if one or more variables
                    603: are not allowed to be set, or it may silently ignore such variables.
                    604: .Sp
                    605: When parsing \fIenv_add\fR, the plugin should split on the \fBfirst\fR
                    606: equal sign ('=') since the \fIname\fR field will never include one
                    607: itself but the \fIvalue\fR might.
                    608: .IP "command_info" 4
                    609: .IX Item "command_info"
                    610: Information about the command being run in the form of \*(L"name=value\*(R"
                    611: strings.  These values are used by \fBsudo\fR to set the execution
                    612: environment when running a command.  The plugin is responsible for
                    613: creating and populating the vector, which must be terminated with
                    614: a \f(CW\*(C`NULL\*(C'\fR pointer.  The following values are recognized by \fBsudo\fR:
                    615: .RS 4
                    616: .IP "command=string" 4
                    617: .IX Item "command=string"
                    618: Fully qualified path to the command to be executed.
                    619: .IP "runas_uid=uid" 4
                    620: .IX Item "runas_uid=uid"
                    621: User \s-1ID\s0 to run the command as.
                    622: .IP "runas_euid=uid" 4
                    623: .IX Item "runas_euid=uid"
                    624: Effective user \s-1ID\s0 to run the command as.
                    625: If not specified, the value of \fIrunas_uid\fR is used.
                    626: .IP "runas_gid=gid" 4
                    627: .IX Item "runas_gid=gid"
                    628: Group \s-1ID\s0 to run the command as.
                    629: .IP "runas_egid=gid" 4
                    630: .IX Item "runas_egid=gid"
                    631: Effective group \s-1ID\s0 to run the command as.
                    632: If not specified, the value of \fIrunas_gid\fR is used.
                    633: .IP "runas_groups=list" 4
                    634: .IX Item "runas_groups=list"
                    635: The supplementary group vector to use for the command in the form
                    636: of a comma-separated list of group IDs.  If \fIpreserve_groups\fR
                    637: is set, this option is ignored.
                    638: .IP "login_class=string" 4
                    639: .IX Item "login_class=string"
                    640: \&\s-1BSD\s0 login class to use when setting resource limits and nice value
                    641: (optional).  This option is only set on systems that support login
                    642: classes.
                    643: .IP "preserve_groups=bool" 4
                    644: .IX Item "preserve_groups=bool"
                    645: If set, \fBsudo\fR will preserve the user's group vector instead of
                    646: initializing the group vector based on \f(CW\*(C`runas_user\*(C'\fR.
                    647: .IP "cwd=string" 4
                    648: .IX Item "cwd=string"
                    649: The current working directory to change to when executing the command.
                    650: .IP "noexec=bool" 4
                    651: .IX Item "noexec=bool"
                    652: If set, prevent the command from executing other programs.
                    653: .IP "chroot=string" 4
                    654: .IX Item "chroot=string"
                    655: The root directory to use when running the command.
                    656: .IP "nice=int" 4
                    657: .IX Item "nice=int"
                    658: Nice value (priority) to use when executing the command.  The nice
                    659: value, if specified, overrides the priority associated with the
                    660: \&\fIlogin_class\fR on \s-1BSD\s0 systems.
                    661: .IP "umask=octal" 4
                    662: .IX Item "umask=octal"
                    663: The file creation mask to use when executing the command.
                    664: .IP "selinux_role=string" 4
                    665: .IX Item "selinux_role=string"
                    666: SELinux role to use when executing the command.
                    667: .IP "selinux_type=string" 4
                    668: .IX Item "selinux_type=string"
                    669: SELinux type to use when executing the command.
                    670: .IP "timeout=int" 4
                    671: .IX Item "timeout=int"
                    672: Command timeout.  If non-zero then when the timeout expires the
                    673: command will be killed.
                    674: .IP "sudoedit=bool" 4
                    675: .IX Item "sudoedit=bool"
                    676: Set to true when in \fIsudoedit\fR mode.  The plugin may enable
                    677: \&\fIsudoedit\fR mode even if \fBsudo\fR was not invoked as \fBsudoedit\fR.
                    678: This allows the plugin to perform command substitution and transparently
                    679: enable \fIsudoedit\fR when the user attempts to run an editor.
                    680: .IP "closefrom=number" 4
                    681: .IX Item "closefrom=number"
                    682: If specified, \fBsudo\fR will close all files descriptors with a value
                    683: of \fInumber\fR or higher.
                    684: .IP "iolog_compress=bool" 4
                    685: .IX Item "iolog_compress=bool"
                    686: Set to true if the I/O logging plugins, if any, should compress the
                    687: log data.  This is a hint to the I/O logging plugin which may choose
                    688: to ignore it.
                    689: .IP "iolog_path=string" 4
                    690: .IX Item "iolog_path=string"
                    691: Fully qualified path to the file or directory in which I/O log is
                    692: to be stored.  This is a hint to the I/O logging plugin which may
                    693: choose to ignore it.  If no I/O logging plugin is loaded, this
                    694: setting has no effect.
                    695: .IP "iolog_stdin=bool" 4
                    696: .IX Item "iolog_stdin=bool"
                    697: Set to true if the I/O logging plugins, if any, should log the
                    698: standard input if it is not connected to a terminal device.  This
                    699: is a hint to the I/O logging plugin which may choose to ignore it.
                    700: .IP "iolog_stdout=bool" 4
                    701: .IX Item "iolog_stdout=bool"
                    702: Set to true if the I/O logging plugins, if any, should log the
                    703: standard output if it is not connected to a terminal device.  This
                    704: is a hint to the I/O logging plugin which may choose to ignore it.
                    705: .IP "iolog_stderr=bool" 4
                    706: .IX Item "iolog_stderr=bool"
                    707: Set to true if the I/O logging plugins, if any, should log the
                    708: standard error if it is not connected to a terminal device.  This
                    709: is a hint to the I/O logging plugin which may choose to ignore it.
                    710: .IP "iolog_ttyin=bool" 4
                    711: .IX Item "iolog_ttyin=bool"
                    712: Set to true if the I/O logging plugins, if any, should log all
                    713: terminal input.  This only includes input typed by the user and not
                    714: from a pipe or redirected from a file.  This is a hint to the I/O
                    715: logging plugin which may choose to ignore it.
                    716: .IP "iolog_ttyout=bool" 4
                    717: .IX Item "iolog_ttyout=bool"
                    718: Set to true if the I/O logging plugins, if any, should log all
                    719: terminal output.  This only includes output to the screen, not
                    720: output to a pipe or file.  This is a hint to the I/O logging plugin
                    721: which may choose to ignore it.
                    722: .IP "use_pty=bool" 4
                    723: .IX Item "use_pty=bool"
                    724: Allocate a pseudo-tty to run the command in, regardless of whether
                    725: or not I/O logging is in use.  By default, \fBsudo\fR will only run
                    726: the command in a pty when an I/O log plugin is loaded.
                    727: .IP "set_utmp=bool" 4
                    728: .IX Item "set_utmp=bool"
                    729: Create a utmp (or utmpx) entry when a pseudo-tty is allocated.  By
                    730: default, the new entry will be a copy of the user's existing utmp
                    731: entry (if any), with the tty, time, type and pid fields updated.
                    732: .IP "utmp_user=string" 4
                    733: .IX Item "utmp_user=string"
                    734: User name to use when constructing a new utmp (or utmpx) entry when
                    735: \&\fIset_utmp\fR is enabled.  This option can be used to set the user
                    736: field in the utmp entry to the user the command runs as rather than
                    737: the invoking user.  If not set, \fBsudo\fR will base the new entry on
                    738: the invoking user's existing entry.
                    739: .RE
                    740: .RS 4
                    741: .Sp
                    742: Unsupported values will be ignored.
                    743: .RE
                    744: .IP "argv_out" 4
                    745: .IX Item "argv_out"
                    746: The \f(CW\*(C`NULL\*(C'\fR\-terminated argument vector to pass to the \fIexecve()\fR
                    747: system call when executing the command.  The plugin is responsible
                    748: for allocating and populating the vector.
                    749: .IP "user_env_out" 4
                    750: .IX Item "user_env_out"
                    751: The \f(CW\*(C`NULL\*(C'\fR\-terminated environment vector to use when executing the
                    752: command.  The plugin is responsible for allocating and populating
                    753: the vector.
                    754: .RE
                    755: .RS 4
                    756: .RE
                    757: .IP "list" 4
                    758: .IX Item "list"
                    759: .Vb 2
                    760: \& int (*list)(int verbose, const char *list_user,
                    761: \&             int argc, char * const argv[]);
                    762: .Ve
                    763: .Sp
                    764: List available privileges for the invoking user.  Returns 1 on
                    765: success, 0 on failure and \-1 on error.  On error, the plugin may
                    766: optionally call the conversation or plugin_printf function with
                    767: \&\f(CW\*(C`SUDO_CONF_ERROR_MSG\*(C'\fR to present additional error information to
                    768: the user.
                    769: .Sp
                    770: Privileges should be output via the conversation or plugin_printf
                    771: function using \f(CW\*(C`SUDO_CONV_INFO_MSG\*(C'\fR.
                    772: .RS 4
                    773: .IP "verbose" 4
                    774: .IX Item "verbose"
                    775: Flag indicating whether to list in verbose mode or not.
                    776: .IP "list_user" 4
                    777: .IX Item "list_user"
                    778: The name of a different user to list privileges for if the policy
                    779: allows it.  If \f(CW\*(C`NULL\*(C'\fR, the plugin should list the privileges of
                    780: the invoking user.
                    781: .IP "argc" 4
                    782: .IX Item "argc"
                    783: The number of elements in \fIargv\fR, not counting the final \f(CW\*(C`NULL\*(C'\fR
                    784: pointer.
                    785: .IP "argv" 4
                    786: .IX Item "argv"
                    787: If non\-\f(CW\*(C`NULL\*(C'\fR, an argument vector describing a command the user
                    788: wishes to check against the policy in the same form as what would
                    789: be passed to the \fIexecve()\fR system call.  If the command is permitted
                    790: by the policy, the fully-qualified path to the command should be
                    791: displayed along with any command line arguments.
                    792: .RE
                    793: .RS 4
                    794: .RE
                    795: .IP "validate" 4
                    796: .IX Item "validate"
                    797: .Vb 1
                    798: \& int (*validate)(void);
                    799: .Ve
                    800: .Sp
                    801: The \f(CW\*(C`validate\*(C'\fR function is called when \fBsudo\fR is run with the
                    802: \&\f(CW\*(C`\-v\*(C'\fR flag.  For policy plugins such as \fIsudoers\fR that cache
                    803: authentication credentials, this function will validate and cache
                    804: the credentials.
                    805: .Sp
                    806: The \f(CW\*(C`validate\*(C'\fR function should be \f(CW\*(C`NULL\*(C'\fR if the plugin does not
                    807: support credential caching.
                    808: .Sp
                    809: Returns 1 on success, 0 on failure and \-1 on error.
                    810: On error, the plugin may optionally call the conversation or plugin_printf
                    811: function with \f(CW\*(C`SUDO_CONF_ERROR_MSG\*(C'\fR to present additional
                    812: error information to the user.
                    813: .IP "invalidate" 4
                    814: .IX Item "invalidate"
                    815: .Vb 1
                    816: \& void (*invalidate)(int remove);
                    817: .Ve
                    818: .Sp
                    819: The \f(CW\*(C`invalidate\*(C'\fR function is called when \fBsudo\fR is called with
                    820: the \f(CW\*(C`\-k\*(C'\fR or \f(CW\*(C`\-K\*(C'\fR flag.  For policy plugins such as \fIsudoers\fR that
                    821: cache authentication credentials, this function will invalidate the
                    822: credentials.  If the \fIremove\fR flag is set, the plugin may remove
                    823: the credentials instead of simply invalidating them.
                    824: .Sp
                    825: The \f(CW\*(C`invalidate\*(C'\fR function should be \f(CW\*(C`NULL\*(C'\fR if the plugin does not
                    826: support credential caching.
                    827: .IP "init_session" 4
                    828: .IX Item "init_session"
                    829: .Vb 1
1.1.1.2 ! misho     830: \& int (*init_session)(struct passwd *pwd, char **user_envp[);
1.1       misho     831: .Ve
                    832: .Sp
1.1.1.2 ! misho     833: The \f(CW\*(C`init_session\*(C'\fR function is called before \fBsudo\fR sets up the
        !           834: execution environment for the command.  It is run in the parent
        !           835: \&\fBsudo\fR process and before any uid or gid changes.  This can be used
        !           836: to perform session setup that is not supported by \fIcommand_info\fR,
        !           837: such as opening the \s-1PAM\s0 session.  The \f(CW\*(C`close\*(C'\fR function can be
        !           838: used to tear down the session that was opened by \f(CW\*(C`init_session\*(C'\fR.
1.1       misho     839: .Sp
                    840: The \fIpwd\fR argument points to a passwd struct for the user the
                    841: command will be run as if the uid the command will run as was found
                    842: in the password database, otherwise it will be \s-1NULL\s0.
                    843: .Sp
1.1.1.2 ! misho     844: The \fIuser_env\fR argument points to the environment the command will
        !           845: run in, in the form of a \f(CW\*(C`NULL\*(C'\fR\-terminated vector of \*(L"name=value\*(R"
        !           846: strings.  This is the same string passed back to the front end via
        !           847: the Policy Plugin's \fIuser_env_out\fR parameter.  If the \f(CW\*(C`init_session\*(C'\fR
        !           848: function needs to modify the user environment, it should update the
        !           849: pointer stored in \fIuser_env\fR.  The expected use case is to merge
        !           850: the contents of the \s-1PAM\s0 environment (if any) with the contents of
        !           851: \&\fIuser_env\fR.  \s-1NOTE:\s0 the \fIuser_env\fR parameter is only available
        !           852: starting with \s-1API\s0 version 1.2.  A plugin \fBmust\fR check the \s-1API\s0
        !           853: version specified by the \fBsudo\fR front end before using \fIuser_env\fR.
        !           854: Failure to do so may result in a crash.
        !           855: .Sp
1.1       misho     856: Returns 1 on success, 0 on failure and \-1 on error.
                    857: On error, the plugin may optionally call the conversation or plugin_printf
                    858: function with \f(CW\*(C`SUDO_CONF_ERROR_MSG\*(C'\fR to present additional
                    859: error information to the user.
1.1.1.2 ! misho     860: .IP "register_hooks" 4
        !           861: .IX Item "register_hooks"
        !           862: .Vb 2
        !           863: \& void (*register_hooks)(int version,
        !           864: \&    int (*register_hook)(struct sudo_hook *hook));
        !           865: .Ve
        !           866: .Sp
        !           867: The \f(CW\*(C`register_hooks\*(C'\fR function is called by the sudo front end to
        !           868: register any hooks the plugin needs.  If the plugin does not support
        !           869: hooks, \f(CW\*(C`register_hooks\*(C'\fR should be set to the \s-1NULL\s0 pointer.
        !           870: .Sp
        !           871: The \fIversion\fR argument describes the version of the hooks \s-1API\s0
        !           872: supported by the \fBsudo\fR front end.
        !           873: .Sp
        !           874: The \f(CW\*(C`register_hook\*(C'\fR function should be used to register any supported
        !           875: hooks the plugin needs.  It returns 0 on success, 1 if the hook
        !           876: type is not supported and \-1 if the major version in \f(CW\*(C`struct hook\*(C'\fR
        !           877: does not match the front end's major hook \s-1API\s0 version.
        !           878: .Sp
        !           879: See the \*(L"Hook Function \s-1API\s0\*(R" section below for more information
        !           880: about hooks.
        !           881: .Sp
        !           882: \&\s-1NOTE:\s0 the \f(CW\*(C`register_hooks\*(C'\fR function is only available starting
        !           883: with \s-1API\s0 version 1.2.  If the \fBsudo\fR front end doesn't support \s-1API\s0
        !           884: version 1.2 or higher, \f(CW\*(C`register_hooks\*(C'\fR will not be called.
        !           885: .IP "deregister_hooks" 4
        !           886: .IX Item "deregister_hooks"
        !           887: .Vb 2
        !           888: \& void (*deregister_hooks)(int version,
        !           889: \&    int (*deregister_hook)(struct sudo_hook *hook));
        !           890: .Ve
        !           891: .Sp
        !           892: The \f(CW\*(C`deregister_hooks\*(C'\fR function is called by the sudo front end
        !           893: to deregister any hooks the plugin has registered.  If the plugin
        !           894: does not support hooks, \f(CW\*(C`deregister_hooks\*(C'\fR should be set to the
        !           895: \&\s-1NULL\s0 pointer.
        !           896: .Sp
        !           897: The \fIversion\fR argument describes the version of the hooks \s-1API\s0
        !           898: supported by the \fBsudo\fR front end.
        !           899: .Sp
        !           900: The \f(CW\*(C`deregister_hook\*(C'\fR function should be used to deregister any
        !           901: hooks that were put in place by the \f(CW\*(C`register_hook\*(C'\fR function.  If
        !           902: the plugin tries to deregister a hook that the front end does not
        !           903: support, \f(CW\*(C`deregister_hook\*(C'\fR will return an error.
        !           904: .Sp
        !           905: See the \*(L"Hook Function \s-1API\s0\*(R" section below for more information
        !           906: about hooks.
        !           907: .Sp
        !           908: \&\s-1NOTE:\s0 the \f(CW\*(C`deregister_hooks\*(C'\fR function is only available starting
        !           909: with \s-1API\s0 version 1.2.  If the \fBsudo\fR front end doesn't support \s-1API\s0
        !           910: version 1.2 or higher, \f(CW\*(C`deregister_hooks\*(C'\fR will not be called.
1.1       misho     911: .PP
1.1.1.2 ! misho     912: \fIPolicy Plugin Version Macros\fR
        !           913: .IX Subsection "Policy Plugin Version Macros"
1.1       misho     914: .PP
1.1.1.2 ! misho     915: .Vb 6
        !           916: \& /* Plugin API version major/minor. */
        !           917: \& #define SUDO_API_VERSION_MAJOR 1
        !           918: \& #define SUDO_API_VERSION_MINOR 2
        !           919: \& #define SUDO_API_MKVERSION(x, y) ((x << 16) | y)
        !           920: \& #define SUDO_API_VERSION SUDO_API_MKVERSION(SUDO_API_VERSION_MAJOR,\e
        !           921: \&                                             SUDO_API_VERSION_MINOR)
        !           922: \&
        !           923: \& /* Getters and setters for API version */
1.1       misho     924: \& #define SUDO_API_VERSION_GET_MAJOR(v) ((v) >> 16)
                    925: \& #define SUDO_API_VERSION_GET_MINOR(v) ((v) & 0xffff)
                    926: \& #define SUDO_API_VERSION_SET_MAJOR(vp, n) do { \e
                    927: \&     *(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \e
                    928: \& } while(0)
                    929: \& #define SUDO_VERSION_SET_MINOR(vp, n) do { \e
                    930: \&     *(vp) = (*(vp) & 0xffff0000) | (n); \e
                    931: \& } while(0)
                    932: .Ve
                    933: .SS "I/O Plugin \s-1API\s0"
                    934: .IX Subsection "I/O Plugin API"
                    935: .Vb 10
                    936: \& struct io_plugin {
                    937: \& #define SUDO_IO_PLUGIN         2
                    938: \&     unsigned int type; /* always SUDO_IO_PLUGIN */
                    939: \&     unsigned int version; /* always SUDO_API_VERSION */
                    940: \&     int (*open)(unsigned int version, sudo_conv_t conversation
                    941: \&                 sudo_printf_t plugin_printf, char * const settings[],
                    942: \&                 char * const user_info[], int argc, char * const argv[],
1.1.1.2 ! misho     943: \&                 char * const user_env[], char * const plugin_options[]);
1.1       misho     944: \&     void (*close)(int exit_status, int error); /* wait status or error */
                    945: \&     int (*show_version)(int verbose);
                    946: \&     int (*log_ttyin)(const char *buf, unsigned int len);
                    947: \&     int (*log_ttyout)(const char *buf, unsigned int len);
                    948: \&     int (*log_stdin)(const char *buf, unsigned int len);
                    949: \&     int (*log_stdout)(const char *buf, unsigned int len);
                    950: \&     int (*log_stderr)(const char *buf, unsigned int len);
1.1.1.2 ! misho     951: \&     void (*register_hooks)(int version,
        !           952: \&        int (*register_hook)(struct sudo_hook *hook));
        !           953: \&     void (*deregister_hooks)(int version,
        !           954: \&        int (*deregister_hook)(struct sudo_hook *hook));
1.1       misho     955: \& };
                    956: .Ve
                    957: .PP
                    958: When an I/O plugin is loaded, \fBsudo\fR runs the command in a pseudo-tty.
                    959: This makes it possible to log the input and output from the user's
                    960: session.  If any of the standard input, standard output or standard
                    961: error do not correspond to a tty, \fBsudo\fR will open a pipe to capture
                    962: the I/O for logging before passing it on.
                    963: .PP
                    964: The log_ttyin function receives the raw user input from the terminal
                    965: device (note that this will include input even when echo is disabled,
                    966: such as when a password is read). The log_ttyout function receives
                    967: output from the pseudo-tty that is suitable for replaying the user's
                    968: session at a later time.  The log_stdin, log_stdout and log_stderr
                    969: functions are only called if the standard input, standard output
                    970: or standard error respectively correspond to something other than
                    971: a tty.
                    972: .PP
                    973: Any of the logging functions may be set to the \s-1NULL\s0
                    974: pointer if no logging is to be performed.  If the open function
                    975: returns \f(CW0\fR, no I/O will be sent to the plugin.
                    976: .PP
                    977: The io_plugin struct has the following fields:
                    978: .IP "type" 4
                    979: .IX Item "type"
                    980: The \f(CW\*(C`type\*(C'\fR field should always be set to \s-1SUDO_IO_PLUGIN\s0
                    981: .IP "version" 4
                    982: .IX Item "version"
                    983: The \f(CW\*(C`version\*(C'\fR field should be set to \s-1SUDO_API_VERSION\s0.
                    984: .Sp
                    985: This allows \fBsudo\fR to determine the \s-1API\s0 version the plugin was
                    986: built against.
                    987: .IP "open" 4
                    988: .IX Item "open"
                    989: .Vb 4
                    990: \& int (*open)(unsigned int version, sudo_conv_t conversation
                    991: \&             sudo_printf_t plugin_printf, char * const settings[],
                    992: \&             char * const user_info[], int argc, char * const argv[],
1.1.1.2 ! misho     993: \&             char * const user_env[], char * const plugin_options[]);
1.1       misho     994: .Ve
                    995: .Sp
                    996: The \fIopen\fR function is run before the \fIlog_input\fR, \fIlog_output\fR
                    997: or \fIshow_version\fR functions are called.  It is only called if the
                    998: version is being requested or the \fIcheck_policy\fR function has
                    999: returned successfully.  It returns 1 on success, 0 on failure, \-1
                   1000: if a general error occurred, or \-2 if there was a usage error.  In
                   1001: the latter case, \fBsudo\fR will print a usage message before it exits.
                   1002: If an error occurs, the plugin may optionally call the conversation
                   1003: or plugin_printf function with \f(CW\*(C`SUDO_CONF_ERROR_MSG\*(C'\fR to present
                   1004: additional error information to the user.
                   1005: .Sp
                   1006: The function arguments are as follows:
                   1007: .RS 4
                   1008: .IP "version" 4
                   1009: .IX Item "version"
                   1010: The version passed in by \fBsudo\fR allows the plugin to determine the
                   1011: major and minor version number of the plugin \s-1API\s0 supported by
                   1012: \&\fBsudo\fR.
                   1013: .IP "conversation" 4
                   1014: .IX Item "conversation"
                   1015: A pointer to the conversation function that may be used by the
                   1016: \&\fIshow_version\fR function to display version information (see
                   1017: show_version below).  The conversation function may also be used
                   1018: to display additional error message to the user.
                   1019: The conversation function returns 0 on success and \-1 on failure.
                   1020: .IP "plugin_printf" 4
                   1021: .IX Item "plugin_printf"
                   1022: A pointer to a printf-style function that may be used by the
                   1023: \&\fIshow_version\fR function to display version information (see
                   1024: show_version below).  The plugin_printf function may also be used
                   1025: to display additional error message to the user.
                   1026: The plugin_printf function returns number of characters printed on
                   1027: success and \-1 on failure.
                   1028: .IP "settings" 4
                   1029: .IX Item "settings"
                   1030: A vector of user-supplied \fBsudo\fR settings in the form of \*(L"name=value\*(R"
                   1031: strings.  The vector is terminated by a \f(CW\*(C`NULL\*(C'\fR pointer.  These
                   1032: settings correspond to flags the user specified when running \fBsudo\fR.
                   1033: As such, they will only be present when the corresponding flag has
                   1034: been specified on the command line.
                   1035: .Sp
                   1036: When parsing \fIsettings\fR, the plugin should split on the \fBfirst\fR
                   1037: equal sign ('=') since the \fIname\fR field will never include one
                   1038: itself but the \fIvalue\fR might.
                   1039: .Sp
                   1040: See the \*(L"Policy Plugin \s-1API\s0\*(R" section for a list of all possible settings.
                   1041: .IP "user_info" 4
                   1042: .IX Item "user_info"
                   1043: A vector of information about the user running the command in the form of
                   1044: \&\*(L"name=value\*(R" strings.  The vector is terminated by a \f(CW\*(C`NULL\*(C'\fR pointer.
                   1045: .Sp
                   1046: When parsing \fIuser_info\fR, the plugin should split on the \fBfirst\fR
                   1047: equal sign ('=') since the \fIname\fR field will never include one
                   1048: itself but the \fIvalue\fR might.
                   1049: .Sp
                   1050: See the \*(L"Policy Plugin \s-1API\s0\*(R" section for a list of all possible strings.
                   1051: .IP "argc" 4
                   1052: .IX Item "argc"
                   1053: The number of elements in \fIargv\fR, not counting the final \f(CW\*(C`NULL\*(C'\fR
                   1054: pointer.
                   1055: .IP "argv" 4
                   1056: .IX Item "argv"
                   1057: If non\-\f(CW\*(C`NULL\*(C'\fR, an argument vector describing a command the user
                   1058: wishes to run in the same form as what would be passed to the
                   1059: \&\fIexecve()\fR system call.
                   1060: .IP "user_env" 4
                   1061: .IX Item "user_env"
                   1062: The user's environment in the form of a \f(CW\*(C`NULL\*(C'\fR\-terminated vector of
                   1063: \&\*(L"name=value\*(R" strings.
                   1064: .Sp
                   1065: When parsing \fIuser_env\fR, the plugin should split on the \fBfirst\fR
                   1066: equal sign ('=') since the \fIname\fR field will never include one
                   1067: itself but the \fIvalue\fR might.
1.1.1.2 ! misho    1068: .IP "plugin_options" 4
        !          1069: .IX Item "plugin_options"
        !          1070: Any (non-comment) strings immediately after the plugin path are
        !          1071: treated as arguments to the plugin.  These arguments are split on
        !          1072: a white space boundary and are passed to the plugin in the form of
        !          1073: a \f(CW\*(C`NULL\*(C'\fR\-terminated array of strings.  If no arguments were
        !          1074: specified, \fIplugin_options\fR will be the \s-1NULL\s0 pointer.
        !          1075: .Sp
        !          1076: \&\s-1NOTE:\s0 the \fIplugin_options\fR parameter is only available starting with
        !          1077: \&\s-1API\s0 version 1.2.  A plugin \fBmust\fR check the \s-1API\s0 version specified
        !          1078: by the \fBsudo\fR front end before using \fIplugin_options\fR.  Failure to
        !          1079: do so may result in a crash.
1.1       misho    1080: .RE
                   1081: .RS 4
                   1082: .RE
                   1083: .IP "close" 4
                   1084: .IX Item "close"
                   1085: .Vb 1
                   1086: \& void (*close)(int exit_status, int error);
                   1087: .Ve
                   1088: .Sp
                   1089: The \f(CW\*(C`close\*(C'\fR function is called when the command being run by \fBsudo\fR
                   1090: finishes.
                   1091: .Sp
                   1092: The function arguments are as follows:
                   1093: .RS 4
                   1094: .IP "exit_status" 4
                   1095: .IX Item "exit_status"
                   1096: The command's exit status, as returned by the \fIwait\fR\|(2) system call.
                   1097: The value of \f(CW\*(C`exit_status\*(C'\fR is undefined if \f(CW\*(C`error\*(C'\fR is non-zero.
                   1098: .IP "error" 4
                   1099: .IX Item "error"
                   1100: If the command could not be executed, this is set to the value of
                   1101: \&\f(CW\*(C`errno\*(C'\fR set by the \fIexecve\fR\|(2) system call.  If the command was
                   1102: successfully executed, the value of \f(CW\*(C`error\*(C'\fR is 0.
                   1103: .RE
                   1104: .RS 4
                   1105: .RE
                   1106: .IP "show_version" 4
                   1107: .IX Item "show_version"
                   1108: .Vb 1
                   1109: \& int (*show_version)(int verbose);
                   1110: .Ve
                   1111: .Sp
                   1112: The \f(CW\*(C`show_version\*(C'\fR function is called by \fBsudo\fR when the user specifies
                   1113: the \f(CW\*(C`\-V\*(C'\fR option.  The plugin may display its version information
                   1114: to the user via the conversation or plugin_printf function using
                   1115: \&\f(CW\*(C`SUDO_CONV_INFO_MSG\*(C'\fR.  If the user requests detailed version
                   1116: information, the verbose flag will be set.
                   1117: .IP "log_ttyin" 4
                   1118: .IX Item "log_ttyin"
                   1119: .Vb 1
                   1120: \& int (*log_ttyin)(const char *buf, unsigned int len);
                   1121: .Ve
                   1122: .Sp
                   1123: The \fIlog_ttyin\fR function is called whenever data can be read from
                   1124: the user but before it is passed to the running command.  This
                   1125: allows the plugin to reject data if it chooses to (for instance
                   1126: if the input contains banned content).  Returns \f(CW1\fR if the data
                   1127: should be passed to the command, \f(CW0\fR if the data is rejected
                   1128: (which will terminate the command) or \f(CW\*(C`\-1\*(C'\fR if an error occurred.
                   1129: .Sp
                   1130: The function arguments are as follows:
                   1131: .RS 4
                   1132: .IP "buf" 4
                   1133: .IX Item "buf"
                   1134: The buffer containing user input.
                   1135: .IP "len" 4
                   1136: .IX Item "len"
                   1137: The length of \fIbuf\fR in bytes.
                   1138: .RE
                   1139: .RS 4
                   1140: .RE
                   1141: .IP "log_ttyout" 4
                   1142: .IX Item "log_ttyout"
                   1143: .Vb 1
                   1144: \& int (*log_ttyout)(const char *buf, unsigned int len);
                   1145: .Ve
                   1146: .Sp
                   1147: The \fIlog_ttyout\fR function is called whenever data can be read from
                   1148: the command but before it is written to the user's terminal.  This
                   1149: allows the plugin to reject data if it chooses to (for instance
                   1150: if the output contains banned content).  Returns \f(CW1\fR if the data
                   1151: should be passed to the user, \f(CW0\fR if the data is rejected
                   1152: (which will terminate the command) or \f(CW\*(C`\-1\*(C'\fR if an error occurred.
                   1153: .Sp
                   1154: The function arguments are as follows:
                   1155: .RS 4
                   1156: .IP "buf" 4
                   1157: .IX Item "buf"
                   1158: The buffer containing command output.
                   1159: .IP "len" 4
                   1160: .IX Item "len"
                   1161: The length of \fIbuf\fR in bytes.
                   1162: .RE
                   1163: .RS 4
                   1164: .RE
                   1165: .IP "log_stdin" 4
                   1166: .IX Item "log_stdin"
                   1167: .Vb 1
                   1168: \& int (*log_stdin)(const char *buf, unsigned int len);
                   1169: .Ve
                   1170: .Sp
                   1171: The \fIlog_stdin\fR function is only used if the standard input does
                   1172: not correspond to a tty device.  It is called whenever data can be
                   1173: read from the standard input but before it is passed to the running
                   1174: command.  This allows the plugin to reject data if it chooses to
                   1175: (for instance if the input contains banned content).  Returns \f(CW1\fR
                   1176: if the data should be passed to the command, \f(CW0\fR if the data is
                   1177: rejected (which will terminate the command) or \f(CW\*(C`\-1\*(C'\fR if an error
                   1178: occurred.
                   1179: .Sp
                   1180: The function arguments are as follows:
                   1181: .RS 4
                   1182: .IP "buf" 4
                   1183: .IX Item "buf"
                   1184: The buffer containing user input.
                   1185: .IP "len" 4
                   1186: .IX Item "len"
                   1187: The length of \fIbuf\fR in bytes.
                   1188: .RE
                   1189: .RS 4
                   1190: .RE
                   1191: .IP "log_stdout" 4
                   1192: .IX Item "log_stdout"
                   1193: .Vb 1
                   1194: \& int (*log_stdout)(const char *buf, unsigned int len);
                   1195: .Ve
                   1196: .Sp
                   1197: The \fIlog_stdout\fR function is only used if the standard output does
                   1198: not correspond to a tty device.  It is called whenever data can be
                   1199: read from the command but before it is written to the standard
                   1200: output.  This allows the plugin to reject data if it chooses to
                   1201: (for instance if the output contains banned content).  Returns \f(CW1\fR
                   1202: if the data should be passed to the user, \f(CW0\fR if the data is
                   1203: rejected (which will terminate the command) or \f(CW\*(C`\-1\*(C'\fR if an error
                   1204: occurred.
                   1205: .Sp
                   1206: The function arguments are as follows:
                   1207: .RS 4
                   1208: .IP "buf" 4
                   1209: .IX Item "buf"
                   1210: The buffer containing command output.
                   1211: .IP "len" 4
                   1212: .IX Item "len"
                   1213: The length of \fIbuf\fR in bytes.
                   1214: .RE
                   1215: .RS 4
                   1216: .RE
                   1217: .IP "log_stderr" 4
                   1218: .IX Item "log_stderr"
                   1219: .Vb 1
                   1220: \& int (*log_stderr)(const char *buf, unsigned int len);
                   1221: .Ve
                   1222: .Sp
                   1223: The \fIlog_stderr\fR function is only used if the standard error does
                   1224: not correspond to a tty device.  It is called whenever data can be
                   1225: read from the command but before it is written to the standard
                   1226: error.  This allows the plugin to reject data if it chooses to
                   1227: (for instance if the output contains banned content).  Returns \f(CW1\fR
                   1228: if the data should be passed to the user, \f(CW0\fR if the data is
                   1229: rejected (which will terminate the command) or \f(CW\*(C`\-1\*(C'\fR if an error
                   1230: occurred.
                   1231: .Sp
                   1232: The function arguments are as follows:
                   1233: .RS 4
                   1234: .IP "buf" 4
                   1235: .IX Item "buf"
                   1236: The buffer containing command output.
                   1237: .IP "len" 4
                   1238: .IX Item "len"
                   1239: The length of \fIbuf\fR in bytes.
                   1240: .RE
                   1241: .RS 4
                   1242: .RE
1.1.1.2 ! misho    1243: .IP "register_hooks" 4
        !          1244: .IX Item "register_hooks"
        !          1245: See the \*(L"Policy Plugin \s-1API\s0\*(R" section for a description of
        !          1246: \&\f(CW\*(C`register_hooks\*(C'\fR.
        !          1247: .IP "deregister_hooks" 4
        !          1248: .IX Item "deregister_hooks"
        !          1249: See the \*(L"Policy Plugin \s-1API\s0\*(R" section for a description of
        !          1250: \&\f(CW\*(C`deregister_hooks\*(C'\fR.
1.1       misho    1251: .PP
1.1.1.2 ! misho    1252: \fII/O Plugin Version Macros\fR
        !          1253: .IX Subsection "I/O Plugin Version Macros"
1.1       misho    1254: .PP
                   1255: Same as for the \*(L"Policy Plugin \s-1API\s0\*(R".
1.1.1.2 ! misho    1256: .SS "Hook Function \s-1API\s0"
        !          1257: .IX Subsection "Hook Function API"
        !          1258: Beginning with plugin \s-1API\s0 version 1.2, it is possible to install
        !          1259: hooks for certain functions called by the \fBsudo\fR front end.
        !          1260: .PP
        !          1261: Currently, the only supported hooks relate to the handling of
        !          1262: environment variables.  Hooks can be used to intercept attempts to
        !          1263: get, set, or remove environment variables so that these changes can
        !          1264: be reflected in the version of the environment that is used to
        !          1265: execute a command.  A future version of the \s-1API\s0 will support
        !          1266: hooking internal \fBsudo\fR front end functions as well.
        !          1267: .PP
        !          1268: \fIHook structure\fR
        !          1269: .IX Subsection "Hook structure"
        !          1270: .PP
        !          1271: Hooks in \fBsudo\fR are described by the following structure:
        !          1272: .PP
        !          1273: .Vb 1
        !          1274: \& typedef int (*sudo_hook_fn_t)();
        !          1275: \&
        !          1276: \& struct sudo_hook {
        !          1277: \&     int hook_version;
        !          1278: \&     int hook_type;
        !          1279: \&     sudo_hook_fn_t hook_fn;
        !          1280: \&     void *closure;
        !          1281: \& };
        !          1282: .Ve
        !          1283: .PP
        !          1284: The \f(CW\*(C`sudo_hook\*(C'\fR structure has the following fields:
        !          1285: .IP "hook_version" 4
        !          1286: .IX Item "hook_version"
        !          1287: The \f(CW\*(C`hook_version\*(C'\fR field should be set to \s-1SUDO_HOOK_VERSION\s0.
        !          1288: .IP "hook_type" 4
        !          1289: .IX Item "hook_type"
        !          1290: The \f(CW\*(C`hook_type\*(C'\fR field may be one of the following supported hook types:
        !          1291: .RS 4
        !          1292: .IP "\s-1SUDO_HOOK_SETENV\s0" 4
        !          1293: .IX Item "SUDO_HOOK_SETENV"
        !          1294: The C library \f(CW\*(C`setenv()\*(C'\fR function.  Any registered hooks will run
        !          1295: before the C library implementation.  The \f(CW\*(C`hook_fn\*(C'\fR field should
        !          1296: be a function that matches the following typedef:
        !          1297: .Sp
        !          1298: .Vb 2
        !          1299: \& typedef int (*sudo_hook_fn_setenv_t)(const char *name,
        !          1300: \&    const char *value, int overwrite, void *closure);
        !          1301: .Ve
        !          1302: .Sp
        !          1303: If the registered hook does not match the typedef the results are
        !          1304: unspecified.
        !          1305: .IP "\s-1SUDO_HOOK_UNSETENV\s0" 4
        !          1306: .IX Item "SUDO_HOOK_UNSETENV"
        !          1307: The C library \f(CW\*(C`unsetenv()\*(C'\fR function.  Any registered hooks will run
        !          1308: before the C library implementation.  The \f(CW\*(C`hook_fn\*(C'\fR field should
        !          1309: be a function that matches the following typedef:
        !          1310: .Sp
        !          1311: .Vb 2
        !          1312: \& typedef int (*sudo_hook_fn_unsetenv_t)(const char *name,
        !          1313: \&    void *closure);
        !          1314: .Ve
        !          1315: .IP "\s-1SUDO_HOOK_GETENV\s0" 4
        !          1316: .IX Item "SUDO_HOOK_GETENV"
        !          1317: The C library \f(CW\*(C`getenv()\*(C'\fR function.  Any registered hooks will run
        !          1318: before the C library implementation.  The \f(CW\*(C`hook_fn\*(C'\fR field should
        !          1319: be a function that matches the following typedef:
        !          1320: .Sp
        !          1321: .Vb 2
        !          1322: \& typedef int (*sudo_hook_fn_getenv_t)(const char *name,
        !          1323: \&    char **value, void *closure);
        !          1324: .Ve
        !          1325: .Sp
        !          1326: If the registered hook does not match the typedef the results are
        !          1327: unspecified.
        !          1328: .IP "\s-1SUDO_HOOK_PUTENV\s0" 4
        !          1329: .IX Item "SUDO_HOOK_PUTENV"
        !          1330: The C library \f(CW\*(C`putenv()\*(C'\fR function.  Any registered hooks will run
        !          1331: before the C library implementation.  The \f(CW\*(C`hook_fn\*(C'\fR field should
        !          1332: be a function that matches the following typedef:
        !          1333: .Sp
        !          1334: .Vb 2
        !          1335: \& typedef int (*sudo_hook_fn_putenv_t)(char *string,
        !          1336: \&    void *closure);
        !          1337: .Ve
        !          1338: .Sp
        !          1339: If the registered hook does not match the typedef the results are
        !          1340: unspecified.
        !          1341: .RE
        !          1342: .RS 4
        !          1343: .RE
        !          1344: .IP "hook_fn" 4
        !          1345: .IX Item "hook_fn"
        !          1346: .Vb 1
        !          1347: \& sudo_hook_fn_t hook_fn;
        !          1348: .Ve
        !          1349: .Sp
        !          1350: The \f(CW\*(C`hook_fn\*(C'\fR field should be set to the plugin's hook implementation.
        !          1351: The actual function arguments will vary depending on the \f(CW\*(C`hook_type\*(C'\fR
        !          1352: (see \f(CW\*(C`hook_type\*(C'\fR above).  In all cases, the \f(CW\*(C`closure\*(C'\fR field of
        !          1353: \&\f(CW\*(C`struct sudo_hook\*(C'\fR is passed as the last function parameter.  This
        !          1354: can be used to pass arbitrary data to the plugin's hook implementation.
        !          1355: .Sp
        !          1356: The function return value may be one of the following:
        !          1357: .RS 4
        !          1358: .IP "\s-1SUDO_HOOK_RET_ERROR\s0" 4
        !          1359: .IX Item "SUDO_HOOK_RET_ERROR"
        !          1360: The hook function encountered an error.
        !          1361: .IP "\s-1SUDO_HOOK_RET_NEXT\s0" 4
        !          1362: .IX Item "SUDO_HOOK_RET_NEXT"
        !          1363: The hook completed without error, go on to the next hook (including
        !          1364: the native implementation if applicable).  For example, a \f(CW\*(C`getenv\*(C'\fR
        !          1365: hook might return \f(CW\*(C`SUDO_HOOK_RET_NEXT\*(C'\fR if the specified variable
        !          1366: was not found in the private copy of the environment.
        !          1367: .IP "\s-1SUDO_HOOK_RET_STOP\s0" 4
        !          1368: .IX Item "SUDO_HOOK_RET_STOP"
        !          1369: The hook completed without error, stop processing hooks for this
        !          1370: invocation.  This can be used to replace the native implementation.
        !          1371: For example, a \f(CW\*(C`setenv\*(C'\fR hook that operates on a private copy of
        !          1372: the environment but leaves \f(CW\*(C`environ\*(C'\fR unchanged.
        !          1373: .RE
        !          1374: .RS 4
        !          1375: .RE
        !          1376: .PP
        !          1377: Note that it is very easy to create an infinite loop when hooking
        !          1378: C library functions.  For example, a \f(CW\*(C`getenv\*(C'\fR hook that calls the
        !          1379: \&\f(CW\*(C`snprintf\*(C'\fR function may create a loop if the \f(CW\*(C`snprintf\*(C'\fR implementation
        !          1380: calls \f(CW\*(C`getenv\*(C'\fR to check the locale.  To prevent this, you may wish
        !          1381: to use a static variable in the hook function to guard against
        !          1382: nested calls.  E.g.
        !          1383: .PP
        !          1384: .Vb 7
        !          1385: \& static int in_progress = 0; /* avoid recursion */
        !          1386: \& if (in_progress)
        !          1387: \&     return SUDO_HOOK_RET_NEXT;
        !          1388: \& in_progress = 1;
        !          1389: \& ...
        !          1390: \& in_progress = 0;
        !          1391: \& return SUDO_HOOK_RET_STOP;
        !          1392: .Ve
        !          1393: .PP
        !          1394: \fIHook \s-1API\s0 Version Macros\fR
        !          1395: .IX Subsection "Hook API Version Macros"
        !          1396: .PP
        !          1397: .Vb 6
        !          1398: \& /* Hook API version major/minor */
        !          1399: \& #define SUDO_HOOK_VERSION_MAJOR 1
        !          1400: \& #define SUDO_HOOK_VERSION_MINOR 0
        !          1401: \& #define SUDO_HOOK_MKVERSION(x, y) ((x << 16) | y)
        !          1402: \& #define SUDO_HOOK_VERSION SUDO_HOOK_MKVERSION(SUDO_HOOK_VERSION_MAJOR,\e
        !          1403: \&                                               SUDO_HOOK_VERSION_MINOR)
        !          1404: \&
        !          1405: \& /* Getters and setters for hook API version */
        !          1406: \& #define SUDO_HOOK_VERSION_GET_MAJOR(v) ((v) >> 16)
        !          1407: \& #define SUDO_HOOK_VERSION_GET_MINOR(v) ((v) & 0xffff)
        !          1408: \& #define SUDO_HOOK_VERSION_SET_MAJOR(vp, n) do { \e
        !          1409: \&     *(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \e
        !          1410: \& } while(0)
        !          1411: \& #define SUDO_HOOK_VERSION_SET_MINOR(vp, n) do { \e
        !          1412: \&     *(vp) = (*(vp) & 0xffff0000) | (n); \e
        !          1413: \& } while(0)
        !          1414: .Ve
1.1       misho    1415: .SS "Conversation \s-1API\s0"
                   1416: .IX Subsection "Conversation API"
                   1417: If the plugin needs to interact with the user, it may do so via the
                   1418: conversation function.  A plugin should not attempt to read directly
                   1419: from the standard input or the user's tty (neither of which are
                   1420: guaranteed to exist).  The caller must include a trailing newline
                   1421: in \f(CW\*(C`msg\*(C'\fR if one is to be printed.
                   1422: .PP
                   1423: A printf-style function is also available that can be used to display
                   1424: informational or error messages to the user, which is usually more
                   1425: convenient for simple messages where no use input is required.
                   1426: .PP
1.1.1.2 ! misho    1427: .Vb 12
1.1       misho    1428: \& struct sudo_conv_message {
                   1429: \& #define SUDO_CONV_PROMPT_ECHO_OFF  0x0001 /* do not echo user input */
                   1430: \& #define SUDO_CONV_PROMPT_ECHO_ON   0x0002 /* echo user input */
                   1431: \& #define SUDO_CONV_ERROR_MSG        0x0003 /* error message */
                   1432: \& #define SUDO_CONV_INFO_MSG         0x0004 /* informational message */
                   1433: \& #define SUDO_CONV_PROMPT_MASK      0x0005 /* mask user input */
1.1.1.2 ! misho    1434: \& #define SUDO_CONV_DEBUG_MSG        0x0006 /* debugging message */
1.1       misho    1435: \& #define SUDO_CONV_PROMPT_ECHO_OK   0x1000 /* flag: allow echo if no tty */
                   1436: \&     int msg_type;
                   1437: \&     int timeout;
                   1438: \&     const char *msg;
                   1439: \& };
                   1440: \&
                   1441: \& struct sudo_conv_reply {
                   1442: \&     char *reply;
                   1443: \& };
                   1444: \&
                   1445: \& typedef int (*sudo_conv_t)(int num_msgs,
                   1446: \&              const struct sudo_conv_message msgs[],
                   1447: \&              struct sudo_conv_reply replies[]);
                   1448: \&
                   1449: \& typedef int (*sudo_printf_t)(int msg_type, const char *fmt, ...);
                   1450: .Ve
                   1451: .PP
                   1452: Pointers to the conversation and printf-style functions are passed
                   1453: in to the plugin's \f(CW\*(C`open\*(C'\fR function when the plugin is initialized.
                   1454: .PP
                   1455: To use the conversation function, the plugin must pass an array of
                   1456: \&\f(CW\*(C`sudo_conv_message\*(C'\fR and \f(CW\*(C`sudo_conv_reply\*(C'\fR structures.  There must
                   1457: be a \f(CW\*(C`struct sudo_conv_message\*(C'\fR and \f(CW\*(C`struct sudo_conv_reply\*(C'\fR for
                   1458: each message in the conversation.  The plugin is responsible for
                   1459: freeing the reply buffer filled in to the \f(CW\*(C`struct sudo_conv_reply\*(C'\fR,
                   1460: if any.
                   1461: .PP
                   1462: The printf-style function uses the same underlying mechanism as the
1.1.1.2 ! misho    1463: conversation function but only supports \f(CW\*(C`SUDO_CONV_INFO_MSG\*(C'\fR,
        !          1464: \&\f(CW\*(C`SUDO_CONV_ERROR_MSG\*(C'\fR and \f(CW\*(C`SUDO_CONV_DEBUG_MSG\*(C'\fR for the \fImsg_type\fR
        !          1465: parameter.  It can be more convenient than using the conversation
        !          1466: function if no user reply is needed and supports standard \fIprintf()\fR
        !          1467: escape sequences.
        !          1468: .PP
        !          1469: Unlike, \f(CW\*(C`SUDO_CONV_INFO_MSG\*(C'\fR and \f(CW\*(C`SUDO_CONV_ERROR_MSG\*(C'\fR, messages
        !          1470: sent with the <\s-1SUDO_CONV_DEBUG_MSG\s0> \fImsg_type\fR are not directly
        !          1471: user-visible.  Instead, they are logged to the file specified in
        !          1472: the \f(CW\*(C`Debug\*(C'\fR statement (if any) in the \fI@sysconfdir@/sudo.conf\fR
        !          1473: file.  This allows a plugin to log debugging information and is
        !          1474: intended to be used in conjunction with the \fIdebug_flags\fR setting.
1.1       misho    1475: .PP
                   1476: See the sample plugin for an example of the conversation function usage.
                   1477: .SS "Sudoers Group Plugin \s-1API\s0"
                   1478: .IX Subsection "Sudoers Group Plugin API"
                   1479: The \fIsudoers\fR module supports a plugin interface to allow non-Unix
                   1480: group lookups.  This can be used to query a group source other than
                   1481: the standard Unix group database.  A sample group plugin is bundled
                   1482: with \fBsudo\fR that implements file-based lookups.  Third party group
                   1483: plugins include a \s-1QAS\s0 \s-1AD\s0 plugin available from Quest Software.
                   1484: .PP
                   1485: A group plugin must declare and populate a \f(CW\*(C`sudoers_group_plugin\*(C'\fR
                   1486: struct in the global scope.  This structure contains pointers to
                   1487: the functions that implement plugin initialization, cleanup and
                   1488: group lookup.
                   1489: .PP
                   1490: .Vb 8
                   1491: \& struct sudoers_group_plugin {
                   1492: \&    unsigned int version;
                   1493: \&    int (*init)(int version, sudo_printf_t sudo_printf,
                   1494: \&                char *const argv[]);
                   1495: \&    void (*cleanup)(void);
                   1496: \&    int (*query)(const char *user, const char *group,
                   1497: \&                 const struct passwd *pwd);
                   1498: \&};
                   1499: .Ve
                   1500: .PP
                   1501: The \f(CW\*(C`sudoers_group_plugin\*(C'\fR struct has the following fields:
                   1502: .IP "version" 4
                   1503: .IX Item "version"
                   1504: The \f(CW\*(C`version\*(C'\fR field should be set to \s-1GROUP_API_VERSION\s0.
                   1505: .Sp
                   1506: This allows \fIsudoers\fR to determine the \s-1API\s0 version the group plugin
                   1507: was built against.
                   1508: .IP "init" 4
                   1509: .IX Item "init"
                   1510: .Vb 2
                   1511: \& int (*init)(int version, sudo_printf_t plugin_printf,
                   1512: \&             char *const argv[]);
                   1513: .Ve
                   1514: .Sp
                   1515: The \fIinit\fR function is called after \fIsudoers\fR has been parsed but
                   1516: before any policy checks.  It returns 1 on success, 0 on failure
                   1517: (or if the plugin is not configured), and \-1 if a error occurred.
                   1518: If an error occurs, the plugin may call the plugin_printf function
                   1519: with \f(CW\*(C`SUDO_CONF_ERROR_MSG\*(C'\fR to present additional error information
                   1520: to the user.
                   1521: .Sp
                   1522: The function arguments are as follows:
                   1523: .RS 4
                   1524: .IP "version" 4
                   1525: .IX Item "version"
                   1526: The version passed in by \fIsudoers\fR allows the plugin to determine the
                   1527: major and minor version number of the group plugin \s-1API\s0 supported by
                   1528: \&\fIsudoers\fR.
                   1529: .IP "plugin_printf" 4
                   1530: .IX Item "plugin_printf"
                   1531: A pointer to a printf-style function that may be used to display
                   1532: informational or error message to the user.
                   1533: Returns the number of characters printed on success and \-1 on failure.
                   1534: .IP "argv" 4
                   1535: .IX Item "argv"
                   1536: A NULL-terminated array of arguments generated from the \fIgroup_plugin\fR
                   1537: option in \fIsudoers\fR.  If no arguments were given, \fIargv\fR will be
                   1538: \&\s-1NULL\s0.
                   1539: .RE
                   1540: .RS 4
                   1541: .RE
                   1542: .IP "cleanup" 4
                   1543: .IX Item "cleanup"
                   1544: .Vb 1
                   1545: \& void (*cleanup)();
                   1546: .Ve
                   1547: .Sp
                   1548: The \fIcleanup\fR function is called when \fIsudoers\fR has finished its
                   1549: group checks.  The plugin should free any memory it has allocated
                   1550: and close open file handles.
                   1551: .IP "query" 4
                   1552: .IX Item "query"
                   1553: .Vb 2
                   1554: \& int (*query)(const char *user, const char *group,
                   1555: \&              const struct passwd *pwd);
                   1556: .Ve
                   1557: .Sp
                   1558: The \fIquery\fR function is used to ask the group plugin whether \fIuser\fR
                   1559: is a member of \fIgroup\fR.
                   1560: .Sp
                   1561: The function arguments are as follows:
                   1562: .RS 4
                   1563: .IP "user" 4
                   1564: .IX Item "user"
                   1565: The name of the user being looked up in the external group database.
                   1566: .IP "group" 4
                   1567: .IX Item "group"
                   1568: The name of the group being queried.
                   1569: .IP "pwd" 4
                   1570: .IX Item "pwd"
                   1571: The password database entry for \fIuser\fR, if any.  If \fIuser\fR is not
                   1572: present in the password database, \fIpwd\fR will be \f(CW\*(C`NULL\*(C'\fR.
                   1573: .RE
                   1574: .RS 4
                   1575: .RE
                   1576: .PP
1.1.1.2 ! misho    1577: \fIGroup \s-1API\s0 Version Macros\fR
        !          1578: .IX Subsection "Group API Version Macros"
1.1       misho    1579: .PP
                   1580: .Vb 5
                   1581: \& /* Sudoers group plugin version major/minor */
                   1582: \& #define GROUP_API_VERSION_MAJOR 1
                   1583: \& #define GROUP_API_VERSION_MINOR 0
                   1584: \& #define GROUP_API_VERSION ((GROUP_API_VERSION_MAJOR << 16) | \e
                   1585: \&                            GROUP_API_VERSION_MINOR)
                   1586: \&
                   1587: \& /* Getters and setters for group version */
                   1588: \& #define GROUP_API_VERSION_GET_MAJOR(v) ((v) >> 16)
                   1589: \& #define GROUP_API_VERSION_GET_MINOR(v) ((v) & 0xffff)
                   1590: \& #define GROUP_API_VERSION_SET_MAJOR(vp, n) do { \e
                   1591: \&     *(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \e
                   1592: \& } while(0)
                   1593: \& #define GROUP_API_VERSION_SET_MINOR(vp, n) do { \e
                   1594: \&     *(vp) = (*(vp) & 0xffff0000) | (n); \e
                   1595: \& } while(0)
                   1596: .Ve
1.1.1.2 ! misho    1597: .SH "PLUGIN API CHANGELOG"
        !          1598: .IX Header "PLUGIN API CHANGELOG"
        !          1599: The following revisions have been made to the Sudo Plugin \s-1API\s0.
        !          1600: .IP "Version 1.0" 4
        !          1601: .IX Item "Version 1.0"
        !          1602: Initial \s-1API\s0 version.
        !          1603: .IP "Version 1.1" 4
        !          1604: .IX Item "Version 1.1"
        !          1605: The I/O logging plugin's \f(CW\*(C`open\*(C'\fR function was modified to take the
        !          1606: \&\f(CW\*(C`command_info\*(C'\fR list as an argument.
        !          1607: .IP "Version 1.2" 4
        !          1608: .IX Item "Version 1.2"
        !          1609: The Policy and I/O logging plugins' \f(CW\*(C`open\*(C'\fR functions are now passed
        !          1610: a list of plugin options if any are specified in \fI@sysconfdir@/sudo.conf\fR.
        !          1611: .Sp
        !          1612: A simple hooks \s-1API\s0 has been introduced to allow plugins to hook in to the
        !          1613: system's environment handling functions.
        !          1614: .Sp
        !          1615: The \f(CW\*(C`init_session\*(C'\fR Policy plugin function is now passed a pointer
        !          1616: to the user environment which can be updated as needed.  This can
        !          1617: be used to merge in environment variables stored in the \s-1PAM\s0 handle
        !          1618: before a command is run.
1.1       misho    1619: .SH "SEE ALSO"
                   1620: .IX Header "SEE ALSO"
                   1621: \&\fIsudoers\fR\|(@mansectform@), \fIsudo\fR\|(@mansectsu@)
                   1622: .SH "BUGS"
                   1623: .IX Header "BUGS"
                   1624: If you feel you have found a bug in \fBsudo\fR, please submit a bug report
                   1625: at http://www.sudo.ws/sudo/bugs/
                   1626: .SH "SUPPORT"
                   1627: .IX Header "SUPPORT"
                   1628: Limited free support is available via the sudo-workers mailing list,
                   1629: see http://www.sudo.ws/mailman/listinfo/sudo\-workers to subscribe or
                   1630: search the archives.
                   1631: .SH "DISCLAIMER"
                   1632: .IX Header "DISCLAIMER"
                   1633: \&\fBsudo\fR is provided ``\s-1AS\s0 \s-1IS\s0'' and any express or implied warranties,
                   1634: including, but not limited to, the implied warranties of merchantability
                   1635: and fitness for a particular purpose are disclaimed.  See the \s-1LICENSE\s0
                   1636: file distributed with \fBsudo\fR or http://www.sudo.ws/sudo/license.html
                   1637: for complete details.

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>