]> granicus.if.org Git - sudo/commitdiff
Document plugin_printf and new logging functions.
authorTodd C. Miller <Todd.Miller@courtesan.com>
Wed, 5 May 2010 17:22:21 +0000 (13:22 -0400)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Wed, 5 May 2010 17:22:21 +0000 (13:22 -0400)
doc/sudo_plugin.cat
doc/sudo_plugin.man.in
doc/sudo_plugin.pod

index 5a25cf69c4a4fff4f02d03f7c4a29805a808368b..6dd2f4eb298ea571f3a3cd15c67309dafa4357e6 100644 (file)
@@ -61,7 +61,7 @@ S\bSu\bud\bdo\bo P\bPl\blu\bug\bgi\bin\bn A\bAP\bPI\bI
 
 
 
-1.8.0a1                   April 14, 2010                        1
+1.8.0a1                    May  5, 2010                         1
 
 
 
@@ -75,11 +75,11 @@ SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
             unsigned int type; /* always SUDO_POLICY_PLUGIN */
             unsigned int version; /* always SUDO_API_VERSION */
             int (*open)(unsigned int version, sudo_conv_t conversation,
-                        char * const settings[], char * const user_info[],
-                        char * const user_env[]);
+                        sudo_printf_t plugin_printf, char * const settings[],
+                        char * const user_info[], char * const user_env[]);
             void (*close)(int exit_status, int error);
             int (*show_version)(int verbose);
-            int (*check_policy)(int agrc, char * const argv[],
+            int (*check_policy)(int argc, char * const argv[],
                                 char *env_add[], char **command_info[],
                                 char **argv_out[], char **user_env_out[]);
             int (*list)(int argc, char * const argv[], int verbose,
@@ -101,15 +101,15 @@ SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
 
        open
             int (*open)(unsigned int version, sudo_conv_t conversation,
-                        char * const settings[], char * const user_info[],
-                        char * const user_env[]);
+                        sudo_printf_t plugin_printf, char * const settings[],
+                        char * const user_info[], char * const user_env[]);
 
-           Returns 1 on success, 0 on failure, -1 if a general error ocurred,
+           Returns 1 on success, 0 on failure, -1 if a general error occurred,
            or -2 if there was a usage error.  In the latter case, s\bsu\bud\bdo\bo will
            print a usage message before it exits.  If an error occurs, the
-           plugin may optionally call the conversation function with
-           SUDO_CONF_ERROR_MSG to present additional error information to the
-           user.
+           plugin may optionally call the conversation or plugin_printf
+           function with SUDO_CONF_ERROR_MSG to present additional error
+           information to the user.
 
            The function arguments are as follows:
 
@@ -122,12 +122,12 @@ SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
                A pointer to the conversation function that can be used by the
                plugin to interact with the user (see below).
 
-           settings
-               A vector of user-supplied s\bsu\bud\bdo\bo settings in the form of
+           plugin_printf
+               A pointer to a printf-style function that may be used to
 
 
 
-1.8.0a1                   April 14, 2010                        2
+1.8.0a1                    May  5, 2010                         2
 
 
 
@@ -136,6 +136,10 @@ SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
 SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
 
 
+               display informational or error messages (see below).
+
+           settings
+               A vector of user-supplied s\bsu\bud\bdo\bo settings in the form of
                "name=value" strings.  The vector is terminated by a NULL
                pointer.  These settings correspond to flags the user specified
                when running s\bsu\bud\bdo\bo.  As such, they will only be present when the
@@ -186,14 +190,10 @@ SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
                preserve_groups=bool
                    Set to true if the user specified the -P flag, indicating
                    that the user wishes to preserve the group vector instead
-                   of setting it based on the runas user.
-
-               ignore_ticket=bool
-                   Set to true if the user specified the -k flag along with a
 
 
 
-1.8.0a1                   April 14, 2010                        3
+1.8.0a1                    May  5, 2010                         3
 
 
 
@@ -202,6 +202,10 @@ SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
 SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
 
 
+                   of setting it based on the runas user.
+
+               ignore_ticket=bool
+                   Set to true if the user specified the -k flag along with a
                    command, indicating that the user wishes to ignore any
                    cached authentication credentials.
 
@@ -252,14 +256,10 @@ SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
                gid=gid_t
                    The real group ID of the user invoking s\bsu\bud\bdo\bo.
 
-               groups=list
-                   The user's supplementary group list formatted as a string
-                   of comma-separated group IDs.
-
 
 
 
-1.8.0a1                   April 14, 2010                        4
+1.8.0a1                    May  5, 2010                         4
 
 
 
@@ -268,6 +268,10 @@ SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
 SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
 
 
+               groups=list
+                   The user's supplementary group list formatted as a string
+                   of comma-separated group IDs.
+
                cwd=string
                    The user's current working directory.
 
@@ -315,17 +319,13 @@ SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
                If the command could not be executed, this is set to the value
                of errno set by the _\be_\bx_\be_\bc_\bv_\be(2) system call.  The plugin is
                responsible for displaying error information via the
-               conversation function.  If the command was successfully
-               executed, the value of error is 0.
+               conversation or plugin_printf function.  If the command was
+               successfully executed, the value of error is 0.
 
-       show_version
-            int (*show_version)(int verbose);
 
-           The show_version function is called by s\bsu\bud\bdo\bo when the user specifies
 
 
-
-1.8.0a1                   April 14, 2010                        5
+1.8.0a1                    May  5, 2010                         5
 
 
 
@@ -334,10 +334,14 @@ SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
 SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
 
 
+       show_version
+            int (*show_version)(int verbose);
+
+           The show_version function is called by s\bsu\bud\bdo\bo when the user specifies
            the -V option.  The plugin may display its version information to
-           the user via the conversation function using SUDO_CONV_INFO_MSG.
-           If the user requests detailed version information, the verbose flag
-           will be set.
+           the user via the conversation or plugin_printf function using
+           SUDO_CONV_INFO_MSG.  If the user requests detailed version
+           information, the verbose flag will be set.
 
        check_policy
             int (*check_policy)(int argc, char * const argv[]
@@ -349,8 +353,9 @@ SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
            the command is allowed, 0 if not allowed, -1 for a general error,
            or -2 for a usage error.  In the latter case, s\bsu\bud\bdo\bo will print a
            usage message before it exits.  If an error occurs, the plugin may
-           optionally call the conversation function with SUDO_CONF_ERROR_MSG
-           to present additional error information to the user.
+           optionally call the conversation or plugin_printf function with
+           SUDO_CONF_ERROR_MSG to present additional error information to the
+           user.
 
            The function arguments are as follows:
 
@@ -382,16 +387,11 @@ SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
                be terminated with a NULL pointer.  The following values are
                recognized by s\bsu\bud\bdo\bo:
 
-               command=string
-                   Fully qualified path to the command to be executed.
-
-               runas_uid=uid
-                   User ID to run the command as.
 
 
 
 
-1.8.0a1                   April 14, 2010                        6
+1.8.0a1                    May  5, 2010                         6
 
 
 
@@ -400,6 +400,12 @@ SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
 SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
 
 
+               command=string
+                   Fully qualified path to the command to be executed.
+
+               runas_uid=uid
+                   User ID to run the command as.
+
                runas_euid=uid
                    Effective user ID to run the command as.  If not specified,
                    the value of _\br_\bu_\bn_\ba_\bs_\b__\bu_\bi_\bd is used.
@@ -449,22 +455,22 @@ SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
                selinux_type=string
                    SELinux type to use when executing the command.
 
-               timeout=int
-                   Command timeout.  If non-zero then when the timeout expires
-                   the command will be killed.
 
-               Unsupported values will be ignored.
 
+1.8.0a1                    May  5, 2010                         7
 
 
-1.8.0a1                   April 14, 2010                        7
 
 
 
+SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
 
 
-SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
+               timeout=int
+                   Command timeout.  If non-zero then when the timeout expires
+                   the command will be killed.
 
+               Unsupported values will be ignored.
 
            argv_out
                The NULL-terminated argument vector to pass to the _\be_\bx_\be_\bc_\bv_\be_\b(_\b)
@@ -482,11 +488,12 @@ SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
 
            List available privileges for the invoking user.  Returns 1 on
            success, 0 on failure and -1 on error.  On error, the plugin may
-           optionally call the conversation function with SUDO_CONF_ERROR_MSG
-           to present additional error information to the user.
+           optionally call the conversation or plugin_printf function with
+           SUDO_CONF_ERROR_MSG to present additional error information to the
+           user.
 
-           Privileges should be output via the conversation function using
-           SUDO_CONV_INFO_MSG.
+           Privileges should be output via the conversation or plugin_printf
+           function using SUDO_CONV_INFO_MSG.
 
            verbose
                Flag indicating whether to list in verbose mode or not.
@@ -513,27 +520,27 @@ SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
 
            The validate function is called when s\bsu\bud\bdo\bo is run with the -v flag.
            For policy plugins such as _\bs_\bu_\bd_\bo_\be_\br_\bs that cache authentication
-           credentials, this function will validate and cache the credentials.
 
-           The validate function should be NULL if the plugin does not support
-           credential caching.
 
-           Returns 1 on success, 0 on failure and -1 on error.  On error, the
-           plugin may optionally call the conversation function with
 
+1.8.0a1                    May  5, 2010                         8
 
 
-1.8.0a1                   April 14, 2010                        8
 
 
 
+SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
 
 
-SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
+           credentials, this function will validate and cache the credentials.
 
+           The validate function should be NULL if the plugin does not support
+           credential caching.
 
-           SUDO_CONF_ERROR_MSG to present additional error information to the
-           user.
+           Returns 1 on success, 0 on failure and -1 on error.  On error, the
+           plugin may optionally call the conversation or plugin_printf
+           function with SUDO_CONF_ERROR_MSG to present additional error
+           information to the user.
 
        invalidate
             void (*invalidate)(int remove);
@@ -549,11 +556,15 @@ SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
 
        _\bC_\bo_\bn_\bv_\be_\br_\bs_\ba_\bt_\bi_\bo_\bn _\bA_\bP_\bI
 
-       If the plugin needs to interact with the user or display informational
-       or error messages, it may do so via the conversation function.  A
-       plugin should not attempt to read directly from the standard input or
-       the user's tty (neither of which are guaranteed to exist).  The caller
-       must include a trailing newline in msg if they want one to be printed.
+       If the plugin needs to interact with the user, it may do so via the
+       conversation function.  A plugin should not attempt to read directly
+       from the standard input or the user's tty (neither of which are
+       guaranteed to exist).  The caller must include a trailing newline in
+       msg if one is to be printed.
+
+       A printf-style function is also available that can be used to display
+       informational or error messages to the user, which is usually more
+       convenient for simple messages where no use input is required.
 
         struct sudo_conv_message {
         #define SUDO_CONV_PROMPT_ECHO_OFF      1
@@ -573,55 +584,86 @@ SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
                      const struct sudo_conv_message msgs[],
                      struct sudo_conv_reply replies[]);
 
-       A conversation function is passed in to the plugin's open function when
-       the plugin is initialized.  The plugin passes in a struct
-       sudo_conv_message and struct sudo_conv_reply for each message in the
-       conversation.  The plugin is responsible for freeing the actual reply
-       buffer in struct sudo_conv_reply.
+        typedef int (*sudo_printf_t)(int msg_type, const char *fmt, ...);
 
-       See the sample plugin for an example of the conversation function
-       usage.
 
-   I\bI/\b/O\bO P\bPl\blu\bug\bgi\bin\bn A\bAP\bPI\bI
 
 
+1.8.0a1                    May  5, 2010                         9
 
 
 
 
-1.8.0a1                   April 14, 2010                        9
 
+SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
 
 
+       Pointers to the conversation and printf-style functions are passed in
+       to the plugin's open function when the plugin is initialized.
 
+       To use the conversation function, the plugin must pass an array of
+       sudo_conv_message and sudo_conv_reply structures.  There must be a
+       struct sudo_conv_message and struct sudo_conv_reply for each message in
+       the conversation.  The plugin is responsible for freeing the reply
+       buffer filled in to the struct sudo_conv_reply, if any.
 
-SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
+       The printf-style function uses the same underlying mechanism as the
+       conversation function but only supports SUDO_CONV_INFO_MSG and
+       SUDO_CONV_ERROR_MSG for the _\bm_\bs_\bg_\b__\bt_\by_\bp_\be parameter.  It can be more
+       convenient than using the conversation function if no user reply is
+       needed and supports standard _\bp_\br_\bi_\bn_\bt_\bf_\b(_\b) escape sequences.
 
+       See the sample plugin for an example of the conversation function
+       usage.
 
+   I\bI/\b/O\bO P\bPl\blu\bug\bgi\bin\bn A\bAP\bPI\bI
         struct io_plugin {
         #define SUDO_IO_PLUGIN         2
             unsigned int type; /* always SUDO_IO_PLUGIN */
             unsigned int version; /* always SUDO_API_VERSION */
             int (*open)(unsigned int version, sudo_conv_t conversation
-                        char * const settings[], char * const user_info[],
-                        char * const user_env[]);
+                        sudo_printf_t plugin_printf, char * const settings[],
+                        char * const user_info[], char * const user_env[]);
             void (*close)(int exit_status, int error); /* wait status or error */
             int (*show_version)(int verbose);
-            int (*log_input)(const char *buf, unsigned int len);
-            int (*log_output)(const char *buf, unsigned int len);
+            int (*log_ttyin)(const char *buf, unsigned int len);
+            int (*log_ttyout)(const char *buf, unsigned int len);
+            int (*log_stdin)(const char *buf, unsigned int len);
+            int (*log_stdout)(const char *buf, unsigned int len);
+            int (*log_stderr)(const char *buf, unsigned int len);
         };
 
        When an I/O plugin is loaded, s\bsu\bud\bdo\bo runs the command in a pseudo-tty.
        This makes it possible to log the input and output from the user's
-       session.  If the log_input function is defined, it will receive the raw
-       user input (note that this will include input even when echo is
-       disabled, such as passwords).  The log_output function receives output
-       from the pseudo-tty that is suitable for replaying the user's session
-       at a later time.  Either log_input or log_output may be NULL.  If the
-       open function returns 0, no I/O will be sent to the plugin.
+       session.  If any of the standard input, standard output or standard
+       error do not correspond to a tty, s\bsu\bud\bdo\bo will open a pipe to capture the
+       I/O for logging before passing it on.
+
+       The log_ttyin function receives the raw user input from the terminal
+       device (note that this will include input even when echo is disabled,
+       such as when a password is read). The log_ttyout function receives
+       output from the pseudo-tty that is suitable for replaying the user's
+       session at a later time.  The log_stdin, log_stdout and log_stderr
+       functions are only called if the standard input, standard output or
+       standard error respectively correspond to something other than a tty.
+
+       Any of the logging functions may be set to the NULL pointer if no
+       logging is to be performed.  If the open function returns 0, no I/O
+       will be sent to the plugin.
 
        The io_plugin struct has the following fields:
 
+
+
+1.8.0a1                    May  5, 2010                        10
+
+
+
+
+
+SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
+
+
        type
            The type field should always be set to SUDO_IO_PLUGIN
 
@@ -633,18 +675,18 @@ SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
 
        open
             int (*open)(unsigned int version, sudo_conv_t conversation
-                        char * const settings[], char * const user_info[],
-                        char * const user_env[]);
+                        sudo_printf_t plugin_printf, char * const settings[],
+                        char * const user_info[], char * const user_env[]);
 
            The _\bo_\bp_\be_\bn function is run before the _\bl_\bo_\bg_\b__\bi_\bn_\bp_\bu_\bt, _\bl_\bo_\bg_\b__\bo_\bu_\bt_\bp_\bu_\bt or
            _\bs_\bh_\bo_\bw_\b__\bv_\be_\br_\bs_\bi_\bo_\bn functions are called.  It is only called if the
            version is being requested or the _\bc_\bh_\be_\bc_\bk_\b__\bp_\bo_\bl_\bi_\bc_\by function has
            returned successfully.  It returns 1 on success, 0 on failure, -1
-           if a general error ocurred, or -2 if there was a usage error.  In
+           if a general error occurred, or -2 if there was a usage error.  In
            the latter case, s\bsu\bud\bdo\bo will print a usage message before it exits.
            If an error occurs, the plugin may optionally call the conversation
-           function with SUDO_CONF_ERROR_MSG to present additional error
-           information to the user.
+           or plugin_printf function with SUDO_CONF_ERROR_MSG to present
+           additional error information to the user.
 
            The function arguments are as follows:
 
@@ -653,23 +695,18 @@ SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
                the major and minor version number of the plugin API supported
                by s\bsu\bud\bdo\bo.
 
-
-
-1.8.0a1                   April 14, 2010                       10
-
-
-
-
-
-SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
-
-
            conversation
                A pointer to the conversation function that may be used by the
                _\bs_\bh_\bo_\bw_\b__\bv_\be_\br_\bs_\bi_\bo_\bn function to display version information (see
                show_version below).  The conversation function may also be
                used to display additional error message to the user.
 
+           plugin_printf
+               A pointer to a printf-style function that may be used by the
+               _\bs_\bh_\bo_\bw_\b__\bv_\be_\br_\bs_\bi_\bo_\bn function to display version information (see
+               show_version below).  The plugin_printf function may also be
+               used to display additional error message to the user.
+
            settings
                A vector of user-supplied s\bsu\bud\bdo\bo settings in the form of
                "name=value" strings.  The vector is terminated by a NULL
@@ -681,6 +718,18 @@ SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
                equal sign ('=') since the _\bn_\ba_\bm_\be field will never include one
                itself but the _\bv_\ba_\bl_\bu_\be might.
 
+
+
+
+1.8.0a1                    May  5, 2010                        11
+
+
+
+
+
+SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
+
+
                See the "Policy Plugin API" section for a list of all possible
                settings.
 
@@ -717,37 +766,36 @@ SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
                call.  The value of exit_status is undefined if error is non-
                zero.
 
+           error
+               If the command could not be executed, this is set to the value
+               of errno set by the _\be_\bx_\be_\bc_\bv_\be(2) system call.  If the command was
+               successfully executed, the value of error is 0.
 
+       show_version
+            int (*show_version)(int verbose);
 
+           The show_version function is called by s\bsu\bud\bdo\bo when the user specifies
+           the -V option.  The plugin may display its version information to
+           the user via the conversation or plugin_printf function using
+           SUDO_CONV_INFO_MSG.  If the user requests detailed version
+           information, the verbose flag will be set.
 
+       log_ttyin
+            int (*log_ttyin)(const char *buf, unsigned int len);
 
-1.8.0a1                   April 14, 2010                       11
-
+           The _\bl_\bo_\bg_\b__\bt_\bt_\by_\bi_\bn function is called whenever data can be read from the
 
 
 
+1.8.0a1                    May  5, 2010                        12
 
-SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
 
 
-           error
-               If the command could not be executed, this is set to the value
-               of errno set by the _\be_\bx_\be_\bc_\bv_\be(2) system call.  If the command was
-               successfully executed, the value of error is 0.
 
-       show_version
-            int (*show_version)(int verbose);
 
-           The show_version function is called by s\bsu\bud\bdo\bo when the user specifies
-           the -V option.  The plugin may display its version information to
-           the user via the conversation function using SUDO_CONV_INFO_MSG.
-           If the user requests detailed version information, the verbose flag
-           will be set.
+SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
 
-       log_input
-            int (*log_input)(const char *buf, unsigned int len);
 
-           The _\bl_\bo_\bg_\b__\bi_\bn_\bp_\bu_\bt function is called whenever data can be read from the
            user but before it is passed to the running command.  This allows
            the plugin to reject data if it chooses to (for instance if the
            input contains banned content).  Returns 1 if the data should be
@@ -760,13 +808,13 @@ SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
 
            len The length of _\bb_\bu_\bf in bytes.
 
-       log_output
-            int (*log_output)(const char *buf, unsigned int len);
+       log_ttyout
+            int (*log_ttyout)(const char *buf, unsigned int len);
 
-           The _\bl_\bo_\bg_\b__\bo_\bu_\bt_\bp_\bu_\bt function is called whenever data can be read from
+           The _\bl_\bo_\bg_\b__\bt_\bt_\by_\bo_\bu_\bt function is called whenever data can be read from
            the command but before it is written to the user's terminal.  This
            allows the plugin to reject data if it chooses to (for instance if
-           the input contains banned content).  Returns 1 if the data should
+           the output contains banned content).  Returns 1 if the data should
            be passed to the user, 0 if the data is rejected (which will
            terminate the command) or -1 if an error occurred.
 
@@ -776,18 +824,36 @@ SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
 
            len The length of _\bb_\bu_\bf in bytes.
 
-   U\bUn\bnh\bha\ban\bnd\bdl\ble\bed\bd c\bco\bom\bmm\bma\ban\bnd\bd l\bli\bin\bne\be o\bop\bpt\bti\bio\bon\bns\bs
-       The -L command line option has been deprecated as its output is covered
-       by the _\bs_\bu_\bd_\bo_\be_\br_\bs manual page.
+       log_stdin
+            int (*log_stdin)(const char *buf, unsigned int len);
 
-   S\bSu\bud\bdo\bo i\bim\bmp\bpl\ble\bem\bme\ben\bnt\bta\bat\bti\bio\bon\bn d\bde\bet\bta\bai\bil\bls\bs
-       Version macros:
+           The _\bl_\bo_\bg_\b__\bs_\bt_\bd_\bi_\bn function is only used if the standard input does not
+           correspond to a tty device.  It is called whenever data can be read
+           from the standard input but before it is passed to the running
+           command.  This allows the plugin to reject data if it chooses to
+           (for instance if the input contains banned content).  Returns 1 if
+           the data should be passed to the command, 0 if the data is rejected
+           (which will terminate the command) or -1 if an error occurred.
+
+           The function arguments are as follows:
+
+           buf The buffer containing user input.
+
+           len The length of _\bb_\bu_\bf in bytes.
 
+       log_stdout
+            int (*log_stdout)(const char *buf, unsigned int len);
 
+           The _\bl_\bo_\bg_\b__\bs_\bt_\bd_\bo_\bu_\bt function is only used if the standard output does
+           not correspond to a tty device.  It is called whenever data can be
+           read from the command but before it is written to the standard
+           output.  This allows the plugin to reject data if it chooses to
+           (for instance if the output contains banned content).  Returns 1 if
+           the data should be passed to the user, 0 if the data is rejected
 
 
 
-1.8.0a1                   April 14, 2010                       12
+1.8.0a1                    May  5, 2010                        13
 
 
 
@@ -796,6 +862,38 @@ SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
 SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
 
 
+           (which will terminate the command) or -1 if an error occurred.
+
+           The function arguments are as follows:
+
+           buf The buffer containing command output.
+
+           len The length of _\bb_\bu_\bf in bytes.
+
+       log_stderr
+            int (*log_stderr)(const char *buf, unsigned int len);
+
+           The _\bl_\bo_\bg_\b__\bs_\bt_\bd_\be_\br_\br function is only used if the standard error does not
+           correspond to a tty device.  It is called whenever data can be read
+           from the command but before it is written to the standard error.
+           This allows the plugin to reject data if it chooses to (for
+           instance if the output contains banned content).  Returns 1 if the
+           data should be passed to the user, 0 if the data is rejected (which
+           will terminate the command) or -1 if an error occurred.
+
+           The function arguments are as follows:
+
+           buf The buffer containing command output.
+
+           len The length of _\bb_\bu_\bf in bytes.
+
+   U\bUn\bns\bsu\bup\bpp\bpo\bor\brt\bte\bed\bd c\bco\bom\bmm\bma\ban\bnd\bd l\bli\bin\bne\be o\bop\bpt\bti\bio\bon\bns\bs
+       The -L command line option has been deprecated as its output is covered
+       by the _\bs_\bu_\bd_\bo_\be_\br_\bs manual page.
+
+   S\bSu\bud\bdo\bo i\bim\bmp\bpl\ble\bem\bme\ben\bnt\bta\bat\bti\bio\bon\bn d\bde\bet\bta\bai\bil\bls\bs
+       Version macros:
+
         #define SUDO_API_VERSION_GET_MAJOR(v) ((v) >> 16)
         #define SUDO_API_VERSION_GET_MINOR(v) ((v) & 0xffff)
         #define SUDO_API_VERSION_SET_MAJOR(vp, n) do { \
@@ -821,38 +919,6 @@ SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
 
 
 
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-1.8.0a1                   April 14, 2010                       13
+1.8.0a1                    May  5, 2010                        14
 
 
index 11006f33c8052388f219ce8e5bbc7521036d4f34..11e23a274a9801ec598a96d28efdb5df00641736 100644 (file)
 .\" ========================================================================
 .\"
 .IX Title "SUDO_PLUGIN @mansectsu@"
-.TH SUDO_PLUGIN @mansectsu@ "April 14, 2010" "1.8.0a1" "MAINTENANCE COMMANDS"
+.TH SUDO_PLUGIN @mansectsu@ "May  5, 2010" "1.8.0a1" "MAINTENANCE COMMANDS"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
@@ -208,11 +208,11 @@ so that \fBsudo\fR can load it.
 \&     unsigned int type; /* always SUDO_POLICY_PLUGIN */
 \&     unsigned int version; /* always SUDO_API_VERSION */
 \&     int (*open)(unsigned int version, sudo_conv_t conversation,
-\&                 char * const settings[], char * const user_info[],
-\&                 char * const user_env[]);
+\&                 sudo_printf_t plugin_printf, char * const settings[],
+\&                 char * const user_info[], char * const user_env[]);
 \&     void (*close)(int exit_status, int error);
 \&     int (*show_version)(int verbose);
-\&     int (*check_policy)(int agrc, char * const argv[],
+\&     int (*check_policy)(int argc, char * const argv[],
 \&                         char *env_add[], char **command_info[],
 \&                         char **argv_out[], char **user_env_out[]);
 \&     int (*list)(int argc, char * const argv[], int verbose,
@@ -236,16 +236,16 @@ built against.
 .IX Item "open"
 .Vb 3
 \& int (*open)(unsigned int version, sudo_conv_t conversation,
-\&             char * const settings[], char * const user_info[],
-\&             char * const user_env[]);
+\&             sudo_printf_t plugin_printf, char * const settings[],
+\&             char * const user_info[], char * const user_env[]);
 .Ve
 .Sp
-Returns 1 on success, 0 on failure, \-1 if a general error ocurred,
+Returns 1 on success, 0 on failure, \-1 if a general error occurred,
 or \-2 if there was a usage error.  In the latter case, \fBsudo\fR will
 print a usage message before it exits.  If an error occurs, the
-plugin may optionally call the conversation function with
-\&\f(CW\*(C`SUDO_CONF_ERROR_MSG\*(C'\fR to present additional error information to
-the user.
+plugin may optionally call the conversation or plugin_printf function
+with \f(CW\*(C`SUDO_CONF_ERROR_MSG\*(C'\fR to present additional error information
+to the user.
 .Sp
 The function arguments are as follows:
 .RS 4
@@ -258,6 +258,10 @@ major and minor version number of the plugin \s-1API\s0 supported by
 .IX Item "conversation"
 A pointer to the conversation function that can be used by the
 plugin to interact with the user (see below).
+.IP "plugin_printf" 4
+.IX Item "plugin_printf"
+A pointer to a printf-style function that may be used to display
+informational or error messages (see below).
 .IP "settings" 4
 .IX Item "settings"
 A vector of user-supplied \fBsudo\fR settings in the form of \*(L"name=value\*(R"
@@ -422,8 +426,9 @@ The value of \f(CW\*(C`exit_status\*(C'\fR is undefined if \f(CW\*(C`error\*(C'\
 .IX Item "error"
 If the command could not be executed, this is set to the value of
 \&\f(CW\*(C`errno\*(C'\fR set by the \fIexecve\fR\|(2) system call.  The plugin is responsible
-for displaying error information via the conversation function.  If
-the command was successfully executed, the value of \f(CW\*(C`error\*(C'\fR is 0.
+for displaying error information via the conversation or plugin_printf
+function.  If the command was successfully executed, the value of
+\&\f(CW\*(C`error\*(C'\fR is 0.
 .RE
 .RS 4
 .RE
@@ -435,9 +440,9 @@ the command was successfully executed, the value of \f(CW\*(C`error\*(C'\fR is 0
 .Sp
 The \f(CW\*(C`show_version\*(C'\fR function is called by \fBsudo\fR when the user specifies
 the \f(CW\*(C`\-V\*(C'\fR option.  The plugin may display its version information
-to the user via the conversation function using \f(CW\*(C`SUDO_CONV_INFO_MSG\*(C'\fR.
-If the user requests detailed version information, the verbose flag
-will be set.
+to the user via the conversation or plugin_printf function using
+\&\f(CW\*(C`SUDO_CONV_INFO_MSG\*(C'\fR.  If the user requests detailed version
+information, the verbose flag will be set.
 .IP "check_policy" 4
 .IX Item "check_policy"
 .Vb 3
@@ -451,9 +456,9 @@ whether the user is allowed to run the specified commands.  Returns
 1 if the command is allowed, 0 if not allowed, \-1 for a general
 error, or \-2 for a usage error.  In the latter case, \fBsudo\fR will
 print a usage message before it exits.  If an error occurs, the
-plugin may optionally call the conversation function with
-\&\f(CW\*(C`SUDO_CONF_ERROR_MSG\*(C'\fR to present additional error information to
-the user.
+plugin may optionally call the conversation or plugin_printf function
+with \f(CW\*(C`SUDO_CONF_ERROR_MSG\*(C'\fR to present additional error information
+to the user.
 .Sp
 The function arguments are as follows:
 .RS 4
@@ -568,13 +573,13 @@ the vector.
 .Ve
 .Sp
 List available privileges for the invoking user.  Returns 1 on
-success, 0 on failure and \-1 on error.
-On error, the plugin may optionally call the conversation function with
-\&\f(CW\*(C`SUDO_CONF_ERROR_MSG\*(C'\fR to present additional error information to the
-user.
+success, 0 on failure and \-1 on error.  On error, the plugin may
+optionally call the conversation or plugin_printf function with
+\&\f(CW\*(C`SUDO_CONF_ERROR_MSG\*(C'\fR to present additional error information to
+the user.
 .Sp
-Privileges should be output via the conversation function using
-\&\f(CW\*(C`SUDO_CONV_INFO_MSG\*(C'\fR.
+Privileges should be output via the conversation or plugin_printf
+function using \f(CW\*(C`SUDO_CONV_INFO_MSG\*(C'\fR.
 .RS 4
 .IP "verbose" 4
 .IX Item "verbose"
@@ -613,9 +618,9 @@ The \f(CW\*(C`validate\*(C'\fR function should be \f(CW\*(C`NULL\*(C'\fR if the
 support credential caching.
 .Sp
 Returns 1 on success, 0 on failure and \-1 on error.
-On error, the plugin may optionally call the conversation function with
-\&\f(CW\*(C`SUDO_CONF_ERROR_MSG\*(C'\fR to present additional error information to the
-user.
+On error, the plugin may optionally call the conversation or plugin_printf
+function with \f(CW\*(C`SUDO_CONF_ERROR_MSG\*(C'\fR to present additional
+error information to the user.
 .IP "invalidate" 4
 .IX Item "invalidate"
 .Vb 1
@@ -634,12 +639,15 @@ support credential caching.
 \fIConversation \s-1API\s0\fR
 .IX Subsection "Conversation API"
 .PP
-If the plugin needs to interact with the user or display informational
-or error messages, it may do so via the conversation function.  A
-plugin should not attempt to read directly from the standard input
-or the user's tty (neither of which are guaranteed to exist).  The
-caller must include a trailing newline in \f(CW\*(C`msg\*(C'\fR if they want one
-to be printed.
+If the plugin needs to interact with the user, it may do so via the
+conversation function.  A plugin should not attempt to read directly
+from the standard input or the user's tty (neither of which are
+guaranteed to exist).  The caller must include a trailing newline
+in \f(CW\*(C`msg\*(C'\fR if one is to be printed.
+.PP
+A printf-style function is also available that can be used to display
+informational or error messages to the user, which is usually more
+convenient for simple messages where no use input is required.
 .PP
 .Vb 9
 \& struct sudo_conv_message {
@@ -659,41 +667,65 @@ to be printed.
 \& typedef int (*sudo_conv_t)(int num_msgs,
 \&              const struct sudo_conv_message msgs[],
 \&              struct sudo_conv_reply replies[]);
+\&
+\& typedef int (*sudo_printf_t)(int msg_type, const char *fmt, ...);
 .Ve
 .PP
-A conversation function is passed in to the plugin's \f(CW\*(C`open\*(C'\fR function
-when the plugin is initialized.  The plugin passes in a \f(CW\*(C`struct
-sudo_conv_message\*(C'\fR and \f(CW\*(C`struct sudo_conv_reply\*(C'\fR for each message
-in the conversation.  The plugin is responsible for freeing the
-actual reply buffer in \f(CW\*(C`struct sudo_conv_reply\*(C'\fR.
+Pointers to the conversation and printf-style functions are passed
+in to the plugin's \f(CW\*(C`open\*(C'\fR function when the plugin is initialized.
+.PP
+To use the conversation function, the plugin must pass an array of
+\&\f(CW\*(C`sudo_conv_message\*(C'\fR and \f(CW\*(C`sudo_conv_reply\*(C'\fR structures.  There must
+be a \f(CW\*(C`struct sudo_conv_message\*(C'\fR and \f(CW\*(C`struct sudo_conv_reply\*(C'\fR for
+each message in the conversation.  The plugin is responsible for
+freeing the reply buffer filled in to the \f(CW\*(C`struct sudo_conv_reply\*(C'\fR,
+if any.
+.PP
+The printf-style function uses the same underlying mechanism as the
+conversation function but only supports \f(CW\*(C`SUDO_CONV_INFO_MSG\*(C'\fR and
+\&\f(CW\*(C`SUDO_CONV_ERROR_MSG\*(C'\fR for the \fImsg_type\fR parameter.  It can be
+more convenient than using the conversation function if no user
+reply is needed and supports standard \fIprintf()\fR escape sequences.
 .PP
 See the sample plugin for an example of the conversation function usage.
 .SS "I/O Plugin \s-1API\s0"
 .IX Subsection "I/O Plugin API"
-.Vb 12
+.Vb 10
 \& struct io_plugin {
 \& #define SUDO_IO_PLUGIN         2
 \&     unsigned int type; /* always SUDO_IO_PLUGIN */
 \&     unsigned int version; /* always SUDO_API_VERSION */
 \&     int (*open)(unsigned int version, sudo_conv_t conversation
-\&                 char * const settings[], char * const user_info[],
-\&                 char * const user_env[]);
+\&                 sudo_printf_t plugin_printf, char * const settings[],
+\&                 char * const user_info[], char * const user_env[]);
 \&     void (*close)(int exit_status, int error); /* wait status or error */
 \&     int (*show_version)(int verbose);
-\&     int (*log_input)(const char *buf, unsigned int len);
-\&     int (*log_output)(const char *buf, unsigned int len);
+\&     int (*log_ttyin)(const char *buf, unsigned int len);
+\&     int (*log_ttyout)(const char *buf, unsigned int len);
+\&     int (*log_stdin)(const char *buf, unsigned int len);
+\&     int (*log_stdout)(const char *buf, unsigned int len);
+\&     int (*log_stderr)(const char *buf, unsigned int len);
 \& };
 .Ve
 .PP
 When an I/O plugin is loaded, \fBsudo\fR runs the command in a pseudo-tty.
 This makes it possible to log the input and output from the user's
-session.  If the log_input function is defined, it will receive the
-raw user input (note that this will include input even when echo
-is disabled, such as passwords).  The log_output function receives
+session.  If any of the standard input, standard output or standard
+error do not correspond to a tty, \fBsudo\fR will open a pipe to capture
+the I/O for logging before passing it on.
+.PP
+The log_ttyin function receives the raw user input from the terminal
+device (note that this will include input even when echo is disabled,
+such as when a password is read). The log_ttyout function receives
 output from the pseudo-tty that is suitable for replaying the user's
-session at a later time.  Either log_input or log_output may be
-\&\s-1NULL\s0.  If the open function returns \f(CW0\fR, no I/O will be sent to
-the plugin.
+session at a later time.  The log_stdin, log_stdout and log_stderr
+functions are only called if the standard input, standard output
+or standard error respectively correspond to something other than
+a tty.
+.PP
+Any of the logging functions may be set to the \s-1NULL\s0
+pointer if no logging is to be performed.  If the open function
+returns \f(CW0\fR, no I/O will be sent to the plugin.
 .PP
 The io_plugin struct has the following fields:
 .IP "type" 4
@@ -709,19 +741,19 @@ built against.
 .IX Item "open"
 .Vb 3
 \& int (*open)(unsigned int version, sudo_conv_t conversation
-\&             char * const settings[], char * const user_info[],
-\&             char * const user_env[]);
+\&             sudo_printf_t plugin_printf, char * const settings[],
+\&             char * const user_info[], char * const user_env[]);
 .Ve
 .Sp
 The \fIopen\fR function is run before the \fIlog_input\fR, \fIlog_output\fR
 or \fIshow_version\fR functions are called.  It is only called if the
 version is being requested or the \fIcheck_policy\fR function has
 returned successfully.  It returns 1 on success, 0 on failure, \-1
-if a general error ocurred, or \-2 if there was a usage error.  In
+if a general error occurred, or \-2 if there was a usage error.  In
 the latter case, \fBsudo\fR will print a usage message before it exits.
 If an error occurs, the plugin may optionally call the conversation
-function with \f(CW\*(C`SUDO_CONF_ERROR_MSG\*(C'\fR to present additional error
-information to the user.
+or plugin_printf function with \f(CW\*(C`SUDO_CONF_ERROR_MSG\*(C'\fR to present
+additional error information to the user.
 .Sp
 The function arguments are as follows:
 .RS 4
@@ -736,6 +768,12 @@ A pointer to the conversation function that may be used by the
 \&\fIshow_version\fR function to display version information (see
 show_version below).  The conversation function may also be used
 to display additional error message to the user.
+.IP "plugin_printf" 4
+.IX Item "plugin_printf"
+A pointer to a printf-style function that may be used by the
+\&\fIshow_version\fR function to display version information (see
+show_version below).  The plugin_printf function may also be used
+to display additional error message to the user.
 .IP "settings" 4
 .IX Item "settings"
 A vector of user-supplied \fBsudo\fR settings in the form of \*(L"name=value\*(R"
@@ -801,16 +839,16 @@ successfully executed, the value of \f(CW\*(C`error\*(C'\fR is 0.
 .Sp
 The \f(CW\*(C`show_version\*(C'\fR function is called by \fBsudo\fR when the user specifies
 the \f(CW\*(C`\-V\*(C'\fR option.  The plugin may display its version information
-to the user via the conversation function using \f(CW\*(C`SUDO_CONV_INFO_MSG\*(C'\fR.
-If the user requests detailed version information, the verbose flag
-will be set.
-.IP "log_input" 4
-.IX Item "log_input"
+to the user via the conversation or plugin_printf function using
+\&\f(CW\*(C`SUDO_CONV_INFO_MSG\*(C'\fR.  If the user requests detailed version
+information, the verbose flag will be set.
+.IP "log_ttyin" 4
+.IX Item "log_ttyin"
 .Vb 1
-\& int (*log_input)(const char *buf, unsigned int len);
+\& int (*log_ttyin)(const char *buf, unsigned int len);
 .Ve
 .Sp
-The \fIlog_input\fR function is called whenever data can be read from
+The \fIlog_ttyin\fR function is called whenever data can be read from
 the user but before it is passed to the running command.  This
 allows the plugin to reject data if it chooses to (for instance
 if the input contains banned content).  Returns \f(CW1\fR if the data
@@ -828,16 +866,16 @@ The length of \fIbuf\fR in bytes.
 .RE
 .RS 4
 .RE
-.IP "log_output" 4
-.IX Item "log_output"
+.IP "log_ttyout" 4
+.IX Item "log_ttyout"
 .Vb 1
-\& int (*log_output)(const char *buf, unsigned int len);
+\& int (*log_ttyout)(const char *buf, unsigned int len);
 .Ve
 .Sp
-The \fIlog_output\fR function is called whenever data can be read from
+The \fIlog_ttyout\fR function is called whenever data can be read from
 the command but before it is written to the user's terminal.  This
 allows the plugin to reject data if it chooses to (for instance
-if the input contains banned content).  Returns \f(CW1\fR if the data
+if the output contains banned content).  Returns \f(CW1\fR if the data
 should be passed to the user, \f(CW0\fR if the data is rejected
 (which will terminate the command) or \f(CW\*(C`\-1\*(C'\fR if an error occurred.
 .Sp
@@ -852,8 +890,86 @@ The length of \fIbuf\fR in bytes.
 .RE
 .RS 4
 .RE
-.SS "Unhandled command line options"
-.IX Subsection "Unhandled command line options"
+.IP "log_stdin" 4
+.IX Item "log_stdin"
+.Vb 1
+\& int (*log_stdin)(const char *buf, unsigned int len);
+.Ve
+.Sp
+The \fIlog_stdin\fR function is only used if the standard input does
+not correspond to a tty device.  It is called whenever data can be
+read from the standard input but before it is passed to the running
+command.  This allows the plugin to reject data if it chooses to
+(for instance if the input contains banned content).  Returns \f(CW1\fR
+if the data should be passed to the command, \f(CW0\fR if the data is
+rejected (which will terminate the command) or \f(CW\*(C`\-1\*(C'\fR if an error
+occurred.
+.Sp
+The function arguments are as follows:
+.RS 4
+.IP "buf" 4
+.IX Item "buf"
+The buffer containing user input.
+.IP "len" 4
+.IX Item "len"
+The length of \fIbuf\fR in bytes.
+.RE
+.RS 4
+.RE
+.IP "log_stdout" 4
+.IX Item "log_stdout"
+.Vb 1
+\& int (*log_stdout)(const char *buf, unsigned int len);
+.Ve
+.Sp
+The \fIlog_stdout\fR function is only used if the standard output does
+not correspond to a tty device.  It is called whenever data can be
+read from the command but before it is written to the standard
+output.  This allows the plugin to reject data if it chooses to
+(for instance if the output contains banned content).  Returns \f(CW1\fR
+if the data should be passed to the user, \f(CW0\fR if the data is
+rejected (which will terminate the command) or \f(CW\*(C`\-1\*(C'\fR if an error
+occurred.
+.Sp
+The function arguments are as follows:
+.RS 4
+.IP "buf" 4
+.IX Item "buf"
+The buffer containing command output.
+.IP "len" 4
+.IX Item "len"
+The length of \fIbuf\fR in bytes.
+.RE
+.RS 4
+.RE
+.IP "log_stderr" 4
+.IX Item "log_stderr"
+.Vb 1
+\& int (*log_stderr)(const char *buf, unsigned int len);
+.Ve
+.Sp
+The \fIlog_stderr\fR function is only used if the standard error does
+not correspond to a tty device.  It is called whenever data can be
+read from the command but before it is written to the standard
+error.  This allows the plugin to reject data if it chooses to
+(for instance if the output contains banned content).  Returns \f(CW1\fR
+if the data should be passed to the user, \f(CW0\fR if the data is
+rejected (which will terminate the command) or \f(CW\*(C`\-1\*(C'\fR if an error
+occurred.
+.Sp
+The function arguments are as follows:
+.RS 4
+.IP "buf" 4
+.IX Item "buf"
+The buffer containing command output.
+.IP "len" 4
+.IX Item "len"
+The length of \fIbuf\fR in bytes.
+.RE
+.RS 4
+.RE
+.SS "Unsupported command line options"
+.IX Subsection "Unsupported command line options"
 The \f(CW\*(C`\-L\*(C'\fR command line option has been deprecated as its output is
 covered by the \fIsudoers\fR manual page.
 .SS "Sudo implementation details"
index 1bf0f7ae3d0193a5d53ee074d526bd5265a74bd0..3209df492253175515180fc9c8ce4e38bea8ed43 100644 (file)
@@ -78,11 +78,11 @@ so that B<sudo> can load it.
      unsigned int type; /* always SUDO_POLICY_PLUGIN */
      unsigned int version; /* always SUDO_API_VERSION */
      int (*open)(unsigned int version, sudo_conv_t conversation,
-                 char * const settings[], char * const user_info[],
-                 char * const user_env[]);
+                sudo_printf_t plugin_printf, char * const settings[],
+                char * const user_info[], char * const user_env[]);
      void (*close)(int exit_status, int error);
      int (*show_version)(int verbose);
-     int (*check_policy)(int agrc, char * const argv[],
+     int (*check_policy)(int argc, char * const argv[],
                          char *env_add[], char **command_info[],
                          char **argv_out[], char **user_env_out[]);
      int (*list)(int argc, char * const argv[], int verbose,
@@ -109,15 +109,15 @@ built against.
 =item open
 
  int (*open)(unsigned int version, sudo_conv_t conversation,
-             char * const settings[], char * const user_info[],
-             char * const user_env[]);
+             sudo_printf_t plugin_printf, char * const settings[],
+             char * const user_info[], char * const user_env[]);
 
-Returns 1 on success, 0 on failure, -1 if a general error ocurred,
+Returns 1 on success, 0 on failure, -1 if a general error occurred,
 or -2 if there was a usage error.  In the latter case, B<sudo> will
 print a usage message before it exits.  If an error occurs, the
-plugin may optionally call the conversation function with
-C<SUDO_CONF_ERROR_MSG> to present additional error information to
-the user.
+plugin may optionally call the conversation or plugin_printf function
+with C<SUDO_CONF_ERROR_MSG> to present additional error information
+to the user.
 
 The function arguments are as follows:
 
@@ -134,6 +134,11 @@ B<sudo>.
 A pointer to the conversation function that can be used by the
 plugin to interact with the user (see below).
 
+=item plugin_printf
+
+A pointer to a printf-style function that may be used to display
+informational or error messages (see below).
+
 =item settings
 
 A vector of user-supplied B<sudo> settings in the form of "name=value"
@@ -326,8 +331,9 @@ The value of C<exit_status> is undefined if C<error> is non-zero.
 
 If the command could not be executed, this is set to the value of
 C<errno> set by the execve(2) system call.  The plugin is responsible
-for displaying error information via the conversation function.  If
-the command was successfully executed, the value of C<error> is 0.
+for displaying error information via the conversation or plugin_printf
+function.  If the command was successfully executed, the value of
+C<error> is 0.
 
 =back
 
@@ -337,9 +343,9 @@ the command was successfully executed, the value of C<error> is 0.
 
 The C<show_version> function is called by B<sudo> when the user specifies
 the C<-V> option.  The plugin may display its version information
-to the user via the conversation function using C<SUDO_CONV_INFO_MSG>.
-If the user requests detailed version information, the verbose flag
-will be set.
+to the user via the conversation or plugin_printf function using
+C<SUDO_CONV_INFO_MSG>.  If the user requests detailed version
+information, the verbose flag will be set.
 
 =item check_policy
 
@@ -352,9 +358,9 @@ whether the user is allowed to run the specified commands.  Returns
 1 if the command is allowed, 0 if not allowed, -1 for a general
 error, or -2 for a usage error.  In the latter case, B<sudo> will
 print a usage message before it exits.  If an error occurs, the
-plugin may optionally call the conversation function with
-C<SUDO_CONF_ERROR_MSG> to present additional error information to
-the user.
+plugin may optionally call the conversation or plugin_printf function
+with C<SUDO_CONF_ERROR_MSG> to present additional error information
+to the user.
 
 The function arguments are as follows:
 
@@ -490,13 +496,13 @@ the vector.
              int argc, char * const argv[]);
 
 List available privileges for the invoking user.  Returns 1 on
-success, 0 on failure and -1 on error.
-On error, the plugin may optionally call the conversation function with
-C<SUDO_CONF_ERROR_MSG> to present additional error information to the
-user.
+success, 0 on failure and -1 on error.  On error, the plugin may
+optionally call the conversation or plugin_printf function with
+C<SUDO_CONF_ERROR_MSG> to present additional error information to
+the user.
 
-Privileges should be output via the conversation function using
-C<SUDO_CONV_INFO_MSG>.
+Privileges should be output via the conversation or plugin_printf
+function using C<SUDO_CONV_INFO_MSG>.
 
 =over 4
 
@@ -538,9 +544,9 @@ The C<validate> function should be C<NULL> if the plugin does not
 support credential caching.
 
 Returns 1 on success, 0 on failure and -1 on error.
-On error, the plugin may optionally call the conversation function with
-C<SUDO_CONF_ERROR_MSG> to present additional error information to the
-user.
+On error, the plugin may optionally call the conversation or plugin_printf
+function with C<SUDO_CONF_ERROR_MSG> to present additional
+error information to the user.
 
 =item invalidate
 
@@ -559,12 +565,15 @@ support credential caching.
 
 =head3 Conversation API
 
-If the plugin needs to interact with the user or display informational
-or error messages, it may do so via the conversation function.  A
-plugin should not attempt to read directly from the standard input
-or the user's tty (neither of which are guaranteed to exist).  The
-caller must include a trailing newline in C<msg> if they want one
-to be printed.
+If the plugin needs to interact with the user, it may do so via the
+conversation function.  A plugin should not attempt to read directly
+from the standard input or the user's tty (neither of which are
+guaranteed to exist).  The caller must include a trailing newline
+in C<msg> if one is to be printed.
+
+A printf-style function is also available that can be used to display
+informational or error messages to the user, which is usually more
+convenient for simple messages where no use input is required.
 
  struct sudo_conv_message {
  #define SUDO_CONV_PROMPT_ECHO_OFF     1
@@ -584,11 +593,23 @@ to be printed.
              const struct sudo_conv_message msgs[],
               struct sudo_conv_reply replies[]);
 
-A conversation function is passed in to the plugin's C<open> function
-when the plugin is initialized.  The plugin passes in a C<struct
-sudo_conv_message> and C<struct sudo_conv_reply> for each message
-in the conversation.  The plugin is responsible for freeing the
-actual reply buffer in C<struct sudo_conv_reply>.
+ typedef int (*sudo_printf_t)(int msg_type, const char *fmt, ...);
+
+Pointers to the conversation and printf-style functions are passed
+in to the plugin's C<open> function when the plugin is initialized.
+
+To use the conversation function, the plugin must pass an array of
+C<sudo_conv_message> and C<sudo_conv_reply> structures.  There must
+be a C<struct sudo_conv_message> and C<struct sudo_conv_reply> for
+each message in the conversation.  The plugin is responsible for
+freeing the reply buffer filled in to the C<struct sudo_conv_reply>,
+if any.
+
+The printf-style function uses the same underlying mechanism as the
+conversation function but only supports C<SUDO_CONV_INFO_MSG> and
+C<SUDO_CONV_ERROR_MSG> for the I<msg_type> parameter.  It can be
+more convenient than using the conversation function if no user
+reply is needed and supports standard printf() escape sequences.
 
 See the sample plugin for an example of the conversation function usage.
 
@@ -599,23 +620,35 @@ See the sample plugin for an example of the conversation function usage.
      unsigned int type; /* always SUDO_IO_PLUGIN */
      unsigned int version; /* always SUDO_API_VERSION */
      int (*open)(unsigned int version, sudo_conv_t conversation
-                 char * const settings[], char * const user_info[],
-                 char * const user_env[]);
+                 sudo_printf_t plugin_printf, char * const settings[],
+                 char * const user_info[], char * const user_env[]);
      void (*close)(int exit_status, int error); /* wait status or error */
      int (*show_version)(int verbose);
-     int (*log_input)(const char *buf, unsigned int len);
-     int (*log_output)(const char *buf, unsigned int len);
+     int (*log_ttyin)(const char *buf, unsigned int len);
+     int (*log_ttyout)(const char *buf, unsigned int len);
+     int (*log_stdin)(const char *buf, unsigned int len);
+     int (*log_stdout)(const char *buf, unsigned int len);
+     int (*log_stderr)(const char *buf, unsigned int len);
  };
 
 When an I/O plugin is loaded, B<sudo> runs the command in a pseudo-tty.
 This makes it possible to log the input and output from the user's
-session.  If the log_input function is defined, it will receive the
-raw user input (note that this will include input even when echo
-is disabled, such as passwords).  The log_output function receives
+session.  If any of the standard input, standard output or standard
+error do not correspond to a tty, B<sudo> will open a pipe to capture
+the I/O for logging before passing it on.
+
+The log_ttyin function receives the raw user input from the terminal
+device (note that this will include input even when echo is disabled,
+such as when a password is read). The log_ttyout function receives
 output from the pseudo-tty that is suitable for replaying the user's
-session at a later time.  Either log_input or log_output may be
-NULL.  If the open function returns C<0>, no I/O will be sent to
-the plugin.
+session at a later time.  The log_stdin, log_stdout and log_stderr
+functions are only called if the standard input, standard output
+or standard error respectively correspond to something other than
+a tty.
+
+Any of the logging functions may be set to the NULL
+pointer if no logging is to be performed.  If the open function
+returns C<0>, no I/O will be sent to the plugin.
 
 The io_plugin struct has the following fields:
 
@@ -635,18 +668,18 @@ built against.
 =item open
 
  int (*open)(unsigned int version, sudo_conv_t conversation
-             char * const settings[], char * const user_info[],
-             char * const user_env[]);
+             sudo_printf_t plugin_printf, char * const settings[],
+             char * const user_info[], char * const user_env[]);
 
 The I<open> function is run before the I<log_input>, I<log_output>
 or I<show_version> functions are called.  It is only called if the
 version is being requested or the I<check_policy> function has
 returned successfully.  It returns 1 on success, 0 on failure, -1
-if a general error ocurred, or -2 if there was a usage error.  In
+if a general error occurred, or -2 if there was a usage error.  In
 the latter case, B<sudo> will print a usage message before it exits.
 If an error occurs, the plugin may optionally call the conversation
-function with C<SUDO_CONF_ERROR_MSG> to present additional error
-information to the user.
+or plugin_printf function with C<SUDO_CONF_ERROR_MSG> to present
+additional error information to the user.
 
 The function arguments are as follows:
 
@@ -665,6 +698,13 @@ I<show_version> function to display version information (see
 show_version below).  The conversation function may also be used
 to display additional error message to the user.
 
+=item plugin_printf
+
+A pointer to a printf-style function that may be used by the
+I<show_version> function to display version information (see
+show_version below).  The plugin_printf function may also be used
+to display additional error message to the user.
+
 =item settings
 
 A vector of user-supplied B<sudo> settings in the form of "name=value"
@@ -731,15 +771,15 @@ successfully executed, the value of C<error> is 0.
 
 The C<show_version> function is called by B<sudo> when the user specifies
 the C<-V> option.  The plugin may display its version information
-to the user via the conversation function using C<SUDO_CONV_INFO_MSG>.
-If the user requests detailed version information, the verbose flag
-will be set.
+to the user via the conversation or plugin_printf function using
+C<SUDO_CONV_INFO_MSG>.  If the user requests detailed version
+information, the verbose flag will be set.
 
-=item log_input
+=item log_ttyin
 
- int (*log_input)(const char *buf, unsigned int len);
+ int (*log_ttyin)(const char *buf, unsigned int len);
 
-The I<log_input> function is called whenever data can be read from
+The I<log_ttyin> function is called whenever data can be read from
 the user but before it is passed to the running command.  This
 allows the plugin to reject data if it chooses to (for instance
 if the input contains banned content).  Returns C<1> if the data
@@ -760,14 +800,14 @@ The length of I<buf> in bytes.
 
 =back
 
-=item log_output
+=item log_ttyout
 
- int (*log_output)(const char *buf, unsigned int len);
+ int (*log_ttyout)(const char *buf, unsigned int len);
 
-The I<log_output> function is called whenever data can be read from
+The I<log_ttyout> function is called whenever data can be read from
 the command but before it is written to the user's terminal.  This
 allows the plugin to reject data if it chooses to (for instance
-if the input contains banned content).  Returns C<1> if the data
+if the output contains banned content).  Returns C<1> if the data
 should be passed to the user, C<0> if the data is rejected
 (which will terminate the command) or C<-1> if an error occurred.
 
@@ -785,9 +825,90 @@ The length of I<buf> in bytes.
 
 =back
 
+=item log_stdin
+
+ int (*log_stdin)(const char *buf, unsigned int len);
+
+The I<log_stdin> function is only used if the standard input does
+not correspond to a tty device.  It is called whenever data can be
+read from the standard input but before it is passed to the running
+command.  This allows the plugin to reject data if it chooses to
+(for instance if the input contains banned content).  Returns C<1>
+if the data should be passed to the command, C<0> if the data is
+rejected (which will terminate the command) or C<-1> if an error
+occurred.
+
+The function arguments are as follows:
+
+=over 4
+
+=item buf
+
+The buffer containing user input.
+
+=item len
+
+The length of I<buf> in bytes.
+
+=back
+
+=item log_stdout
+
+ int (*log_stdout)(const char *buf, unsigned int len);
+
+The I<log_stdout> function is only used if the standard output does
+not correspond to a tty device.  It is called whenever data can be
+read from the command but before it is written to the standard
+output.  This allows the plugin to reject data if it chooses to
+(for instance if the output contains banned content).  Returns C<1>
+if the data should be passed to the user, C<0> if the data is
+rejected (which will terminate the command) or C<-1> if an error
+occurred.
+
+The function arguments are as follows:
+
+=over 4
+
+=item buf
+
+The buffer containing command output.
+
+=item len
+
+The length of I<buf> in bytes.
+
+=back
+
+=item log_stderr
+
+ int (*log_stderr)(const char *buf, unsigned int len);
+
+The I<log_stderr> function is only used if the standard error does
+not correspond to a tty device.  It is called whenever data can be
+read from the command but before it is written to the standard
+error.  This allows the plugin to reject data if it chooses to
+(for instance if the output contains banned content).  Returns C<1>
+if the data should be passed to the user, C<0> if the data is
+rejected (which will terminate the command) or C<-1> if an error
+occurred.
+
+The function arguments are as follows:
+
+=over 4
+
+=item buf
+
+The buffer containing command output.
+
+=item len
+
+The length of I<buf> in bytes.
+
+=back
+
 =back
 
-=head2 Unhandled command line options
+=head2 Unsupported command line options
 
 The C<-L> command line option has been deprecated as its output is
 covered by the I<sudoers> manual page.