]> granicus.if.org Git - sudo/commitdiff
Rename plugin.pod -> sudo_plugin.pod and wire into Makefile
authorTodd C. Miller <Todd.Miller@courtesan.com>
Mon, 22 Feb 2010 02:24:20 +0000 (21:24 -0500)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Mon, 22 Feb 2010 02:24:20 +0000 (21:24 -0500)
doc/Makefile.in
doc/sudo_plugin.cat [new file with mode: 0644]
doc/sudo_plugin.man.in [new file with mode: 0644]
doc/sudo_plugin.pod [moved from doc/plugin.pod with 100% similarity]

index 7ecc08f18892a7849e082080ec263fd707a8b6cf..37fa1d7f0ab2ac262d8dba6204656b1733bc9e1a 100644 (file)
@@ -50,7 +50,7 @@ install_gid = 0
 SHELL = /bin/sh
 
 DOCS = sudo.man visudo.man sudoers.man sudoers.ldap.man sudoers.man \
-       sudoreplay.man
+       sudoreplay.man sudo_plugin.man
 
 VERSION = @PACKAGE_VERSION@
 
@@ -106,7 +106,16 @@ sudoreplay.man.in: $(srcdir)/sudoreplay.pod
 sudoreplay.man:: sudoreplay.man.in
        CONFIG_FILES=$@ CONFIG_HEADERS= sh $(top_builddir)/config.status
 
-sudoers.cat: sudoers.man
+sudoreplay.cat: sudoreplay.man
+
+sudo_plugin.man.in: $(srcdir)/sudo_plugin.pod
+       @rm -f $(srcdir)/$@
+       ( cd $(srcdir); mansectsu=`echo @MANSECTSU@|tr A-Z a-z`; mansectform=`echo @MANSECTFORM@|tr A-Z a-z`; sed -n -e '/^=pod/q' -e 's/^/.\\" /p' sudo_plugin.pod > $@; pod2man --quotes=none --date="`date '+%B %e, %Y'`" --section=$$mansectsu --release=$(VERSION) --center="MAINTENANCE COMMANDS" sudo_plugin.pod | sed -e "s/(5)/($$mansectform)/" -e "s/(8)/($$mansectsu)/" -e 's|\\fI\\f\((CW*\)*I@\([^@]*\)\\fI@|\\fI@\2@|g' >> $@ )
+
+sudo_plugin.man:: sudo_plugin.man.in
+       CONFIG_FILES=$@ CONFIG_HEADERS= sh $(top_builddir)/config.status
+
+sudo_plugin.cat: sudo_plugin.man
 
 @DEV@HISTORY: history.pod
 @DEV@  pod2text -l -i0 $> > $@
diff --git a/doc/sudo_plugin.cat b/doc/sudo_plugin.cat
new file mode 100644 (file)
index 0000000..092be6e
--- /dev/null
@@ -0,0 +1,792 @@
+
+
+
+SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
+
+
+S\bSu\bud\bdo\bo P\bPl\blu\bug\bgi\bin\bn A\bAP\bPI\bI
+       Starting with version 1.8, s\bsu\bud\bdo\bo supports a plugin API for policy and
+       session logging.  By default, the _\bs_\bu_\bd_\bo_\be_\br_\bs policy plugin and an
+       associated I/O logging plugin are used.  Via the plugin API, s\bsu\bud\bdo\bo can
+       be configured to use alternate policy and/or I/O logging plugins
+       provided by third parties.  The plugins to be used are specified via
+       the _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\b._\bc_\bo_\bn_\bf file.
+
+       The API is versioned with a major and minor number.  The minor version
+       number is incremented when additions are made.  The major number is
+       incremented when incompatible changes are made.  A plugin should be
+       check the version passed to it and make sure that the major version
+       matches.
+
+       The plugin API is defined by the sudo_plugin.h header file.
+
+   T\bTh\bhe\be s\bsu\bud\bdo\bo.\b.c\bco\bon\bnf\bf F\bFi\bil\ble\be
+       The _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\b._\bc_\bo_\bn_\bf file contains plugin configuration directives.
+       Currently, the only supported keyword is the Plugin directive, which
+       causes a plugin plugin to be loaded.
+
+       A Plugin line consists of the Plugin keyword, followed by the
+       _\bs_\by_\bm_\bb_\bo_\bl_\b__\bn_\ba_\bm_\be and the _\bp_\ba_\bt_\bh to the shared object containing the plugin.
+       The _\bs_\by_\bm_\bb_\bo_\bl_\b__\bn_\ba_\bm_\be is the name of the struct policy_plugin or struct
+       io_plugin in the plugin shared object.  The _\bp_\ba_\bt_\bh may be fully qualified
+       or relative.  If not fully qualified it is relative to the
+       $prefix/libexec directory where the prefix is specified at build time
+       (/usr/local by default).
+
+       The same shared object may contain multiple plugins, each with a
+       different symbol name.  The shared object file must be owned by uid 0
+       and only writable by its owner.  Because of ambiguities that arise from
+       composite policies, only a single policy plugin may be specified.  This
+       limitation does not apply to I/O plugins.
+
+        #
+        # Default /etc/sudo.conf file
+        #
+        # Format:
+        #   Plugin plugin_name plugin_path
+        #
+        # The plugin_path relative to prefix/libexec unless fully qualified
+        # The plugin_name corresponds to a global symbol in the plugin
+        #   that contains the plugin interface.
+        #
+        Plugin policy_plugin sudoers.so
+        Plugin io_plugin sudoers.so
+
+   P\bPo\bol\bli\bic\bcy\by P\bPl\blu\bug\bgi\bin\bn A\bAP\bPI\bI
+       A policy plugin must declare and populate a policy_plugin struct in the
+       global scope.  This structure contains pointers to the functions that
+       implement the s\bsu\bud\bdo\bo policy checks.  The name of the symbol should be
+       specified in _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\b._\bc_\bo_\bn_\bf along with a path to the plugin so that
+       s\bsu\bud\bdo\bo can load it.
+
+
+
+1.8.0a1                 February 21, 2010                       1
+
+
+
+
+
+SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
+
+
+        struct policy_plugin {
+        #define SUDO_POLICY_PLUGIN     1
+            unsigned int type; /* always SUDO_POLICY_PLUGIN */
+            unsigned int version; /* always SUDO_API_VERSION */
+            int (*open)(unsigned int version, sudo_conv_t conversation,
+                        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[],
+                                char *env_add[], char **command_info[],
+                                char **argv_out[], char **user_env_out[]);
+            int (*list)(int argc, char * const argv[], int verbose,
+                        const char *list_user);
+            int (*validate)(void);
+            void (*invalidate)(int remove);
+        };
+
+       The policy_plugin struct has the following fields:
+
+       type
+           The type field should always be set to SUDO_POLICY_PLUGIN
+
+       version
+           The version field should be set to SUDO_API_VERSION.
+
+           This allows s\bsu\bud\bdo\bo to determine the API version the plugin was built
+           against.
+
+       open
+            int (*open)(unsigned int version, sudo_conv_t conversation,
+                        char * const settings[], char * const user_info[],
+                        char * const user_env[]);
+
+           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.
+
+           The function arguments are as follows:
+
+           version
+               The version passed in by s\bsu\bud\bdo\bo allows the plugin to determine
+               the major and minor version number of the plugin API supported
+               by s\bsu\bud\bdo\bo.
+
+           conversation
+               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
+               "name=value" strings.  The vector is terminated by a NULL
+               pointer.  These settings correspond to flags the user specified
+
+
+
+1.8.0a1                 February 21, 2010                       2
+
+
+
+
+
+SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
+
+
+               when running s\bsu\bud\bdo\bo.  As such, they will only be present when the
+               corresponding flag has been specified on the command line.
+
+               When parsing _\bs_\be_\bt_\bt_\bi_\bn_\bg_\bs, the plugin should split on the f\bfi\bir\brs\bst\bt
+               equal sign ('=') since the _\bn_\ba_\bm_\be field will never include one
+               itself but the _\bv_\ba_\bl_\bu_\be might.
+
+               runas_user=string
+                   The user name or uid to to run the command as, if specified
+                   via the -u flag.
+
+               runas_group=string
+                   The group name or gid to to run the command as, if
+                   specified via the -g flag.
+
+               prompt=string
+                   The prompt to use when requesting a password, if specified
+                   via the -p flag.
+
+               set_home=bool
+                   Set to true if the user specified the -H flag.  If true,
+                   set the HOME environment variable to the target user's home
+                   directory.
+
+               preserve_environment=bool
+                   Set to true if the user specified the -E flag, indicating
+                   that the user wishes to preserve the environment.
+
+               login_shell=bool
+                   Set to true if the user specified the -i flag, indicating
+                   that the user wishes to run a login shell.
+
+               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
+                   command, indicating that the user wishes to ignore any
+                   cached authentication credentials.
+
+               login_class=string
+                   BSD login class to use when setting resource limits and
+                   nice value, if specified by the -c flag.
+
+               selinux_role=string
+                   SELinux role to use when executing the command, if
+                   specified by the -r flag.
+
+               selinux_type=string
+                   SELinux type to use when executing the command, if
+                   specified by the -t flag.
+
+
+
+
+1.8.0a1                 February 21, 2010                       3
+
+
+
+
+
+SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
+
+
+               bsdauth_type=string
+                   Authentication type, if specified by the -a flag, to use on
+                   systems where BSD authentication is supported.
+
+               Additional settings may be added in the future so the plugin
+               should silently ignore settings that it does not recognize.
+
+           user_info
+               A vector of information about the user running the command in
+               the form of "name=value" strings.  The vector is terminated by
+               a NULL pointer.
+
+               When parsing _\bu_\bs_\be_\br_\b__\bi_\bn_\bf_\bo, the plugin should split on the f\bfi\bir\brs\bst\bt
+               equal sign ('=') since the _\bn_\ba_\bm_\be field will never include one
+               itself but the _\bv_\ba_\bl_\bu_\be might.
+
+               user=string
+                   The name of the user invoking s\bsu\bud\bdo\bo.
+
+               uid=uid_t
+                   The real user ID of the user invoking s\bsu\bud\bdo\bo.
+
+               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.
+
+               cwd=string
+                   The user's current working directory.
+
+               tty=string
+                   The path to the user's terminal device.  If the user has no
+                   terminal device associated with the session, the value will
+                   be empty, as in tty=.
+
+               host=string
+                   The local machine's hostname as returned by the
+                   gethostname() system call.
+
+           user_env
+               The user's environment in the form of a NULL-terminated vector
+               of "name=value" strings.
+
+               When parsing _\bu_\bs_\be_\br_\b__\be_\bn_\bv, the plugin should split on the f\bfi\bir\brs\bst\bt
+               equal sign ('=') since the _\bn_\ba_\bm_\be field will never include one
+               itself but the _\bv_\ba_\bl_\bu_\be might.
+
+       close
+            void (*close)(int exit_status, int error);
+
+           The close function is called when the command being run by s\bsu\bud\bdo\bo
+           finishes.
+
+
+
+1.8.0a1                 February 21, 2010                       4
+
+
+
+
+
+SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
+
+
+           The function arguments are as follows:
+
+           exit_status
+               The command's exit status, as returned by the _\bw_\ba_\bi_\bt(2) system
+               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.  The plugin is
+               responsible for displaying error information via the
+               conversation 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
+           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.
+
+       check_policy
+            int (*check_policy)(int argc, char * const argv[]
+                                char *env_add[], char **command_info[],
+                                char **argv_out[], char **user_env_out[]);
+
+           The _\bc_\bh_\be_\bc_\bk_\b__\bp_\bo_\bl_\bi_\bc_\by function is called by s\bsu\bud\bdo\bo to determine whether
+           the user is allowed to run the specified commands.  Returns 1 if
+           the command is allowed, 0 if not 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.
+
+           The function arguments are as follows:
+
+           argc
+               The number of elements in _\ba_\br_\bg_\bv, not counting the final NULL
+               pointer.
+
+           argv
+               The argument vector describing the command the user wishes to
+               run, in the same form as what would be passed to the _\be_\bx_\be_\bc_\bv_\be_\b(_\b)
+               system call.  The vector is terminated by a NULL pointer.
+
+           env_add
+               Additional environment variables specified by the user on the
+               command line in the form of a NULL-terminated vector of
+               "name=value" strings.  The plugin may reject the command if one
+               or more variables are not allowed to be set, or it may silently
+               ignore such variables.
+
+               When parsing _\be_\bn_\bv_\b__\ba_\bd_\bd, the plugin should split on the f\bfi\bir\brs\bst\bt
+
+
+
+1.8.0a1                 February 21, 2010                       5
+
+
+
+
+
+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.
+
+           command_info
+               Information about the command being run in the form of
+               "name=value" strings.  These values are used by s\bsu\bud\bdo\bo to set the
+               execution environment when running a command.  The plugin is
+               responsible for creating and populating the vector, which must
+               be terminated with a 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.
+
+               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.
+
+               runas_gid=gid
+                   Group ID to run the command as.
+
+               runas_egid=gid
+                   Effective group ID to run the command as.  If not
+                   specified, the value of _\br_\bu_\bn_\ba_\bs_\b__\bg_\bi_\bd is used.
+
+               runas_groups=list
+                   The supplementary group vector to use for the command in
+                   the form of a comma-separated list of group IDs.  If
+                   _\bp_\br_\be_\bs_\be_\br_\bv_\be_\b__\bg_\br_\bo_\bu_\bp_\bs is set, this option is ignored.
+
+               login_class=login_class
+                   BSD login class to use when setting resource limits and
+                   nice value (optional).  This option is only set on systems
+                   that support login classes.
+
+               preserve_groups=bool
+                   If set, s\bsu\bud\bdo\bo will preserve the user's group vector instead
+                   of initializing the group vector based on runas_user.
+
+               cwd=string
+                   The current working directory to change to when executing
+                   the command.
+
+               noexec=bool
+                   If set, prevent the command from executing other programs.
+
+               chroot=string
+                   The root directory to use when running the command.
+
+               nice=int
+                   Nice value (priority) to use when executing the command.
+
+
+
+1.8.0a1                 February 21, 2010                       6
+
+
+
+
+
+SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
+
+
+                   The nice value, if specified, overrides the priority
+                   associated with the _\bl_\bo_\bg_\bi_\bn_\b__\bc_\bl_\ba_\bs_\bs on BSD systems.
+
+               umask=octal
+                   The file creation mask to use when executing the command.
+
+               selinux_role=string
+                   SELinux role to use when executing the command.
+
+               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.
+
+           argv_out
+               The NULL-terminated argument vector to pass to the _\be_\bx_\be_\bc_\bv_\be_\b(_\b)
+               system call when executing the command.  The plugin is
+               responsible for allocating and populating the vector.
+
+           user_env_out
+               The NULL-terminated environment vector to use when executing
+               the command.  The plugin is responsible for allocating and
+               populating the vector.
+
+       list
+            int (*list)(int verbose, const char *list_user,
+                        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 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.
+
+           verbose
+               Flag indicating whether to list in verbose mode or not.
+
+           list_user
+               The name of a different user to list privileges for if the
+               policy allows it.  If NULL, the plugin should list the
+               privileges of the invoking user.
+
+           argc
+               The number of elements in _\ba_\br_\bg_\bv, not counting the final NULL
+               pointer.
+
+           argv
+               If non-NULL, an argument vector describing a command the user
+
+
+
+1.8.0a1                 February 21, 2010                       7
+
+
+
+
+
+SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
+
+
+               wishes to check against the policy in the same form as what
+               would be passed to the _\be_\bx_\be_\bc_\bv_\be_\b(_\b) system call.  If the command is
+               permitted by the policy, the fully-qualified path to the
+               command should be displayed along with any command line
+               arguments.
+
+       validate
+            int (*validate)(void);
+
+           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
+           SUDO_CONF_ERROR_MSG to present additional error information to the
+           user.
+
+       invalidate
+            void (*invalidate)(int remove);
+
+           The invalidate function is called when s\bsu\bud\bdo\bo is called with the -k
+           or -K flag.  For policy plugins such as _\bs_\bu_\bd_\bo_\be_\br_\bs that cache
+           authentication credentials, this function will invalidate the
+           credentials.  If the _\br_\be_\bm_\bo_\bv_\be flag is set, the plugin may remove the
+           credentials instead of simply invalidating them.
+
+           The invalidate function should be NULL if the plugin does not
+           support credential caching.
+
+       _\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.
+
+        struct sudo_conv_message {
+        #define SUDO_CONV_PROMPT_ECHO_OFF      1
+        #define SUDO_CONV_PROMPT_ECHO_ON       2
+        #define SUDO_CONV_ERROR_MSG            3
+        #define SUDO_CONV_INFO_MSG             4
+            int msg_type;
+            int timeout;
+            const char *msg;
+        };
+
+        struct sudo_conv_reply {
+            char *reply;
+        };
+
+
+
+
+1.8.0a1                 February 21, 2010                       8
+
+
+
+
+
+SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
+
+
+        typedef int (*sudo_conv_t)(int num_msgs,
+                     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.
+
+       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[]);
+            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);
+        };
+
+       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.
+
+       The io_plugin struct has the following fields:
+
+       type
+           The type field should always be set to SUDO_IO_PLUGIN
+
+       version
+           The version field should be set to SUDO_API_VERSION.
+
+           This allows s\bsu\bud\bdo\bo to determine the API version the plugin was built
+           against.
+
+       open
+            int (*open)(unsigned int version, sudo_conv_t conversation
+                        char * const settings[], char * const user_info[],
+                        char * const user_env[]);
+
+           Returns 1 on success, 0 if the command should not be logged and -1
+           on error.  On error, the plugin may optionally call the
+
+
+
+1.8.0a1                 February 21, 2010                       9
+
+
+
+
+
+SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
+
+
+           conversation function with SUDO_CONF_ERROR_MSG to present
+           additional error information to the user.
+
+           The function arguments are as follows:
+
+           version
+               The version passed in by s\bsu\bud\bdo\bo allows the plugin to determine
+               the major and minor version number of the plugin API supported
+               by s\bsu\bud\bdo\bo.
+
+           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.
+
+           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
+               corresponding flag has been specified on the command line.
+
+               When parsing _\bs_\be_\bt_\bt_\bi_\bn_\bg_\bs, the plugin should split on the f\bfi\bir\brs\bst\bt
+               equal sign ('=') since the _\bn_\ba_\bm_\be field will never include one
+               itself but the _\bv_\ba_\bl_\bu_\be might.
+
+               See the "Policy Plugin API" section for a list of all possible
+               settings.
+
+           user_info
+               A vector of information about the user running the command in
+               the form of "name=value" strings.  The vector is terminated by
+               a NULL pointer.
+
+               When parsing _\bu_\bs_\be_\br_\b__\bi_\bn_\bf_\bo, the plugin should split on the f\bfi\bir\brs\bst\bt
+               equal sign ('=') since the _\bn_\ba_\bm_\be field will never include one
+               itself but the _\bv_\ba_\bl_\bu_\be might.
+
+               See the "Policy Plugin API" section for a list of all possible
+               strings.
+
+           user_env
+               The user's environment in the form of a NULL-terminated vector
+               of "name=value" strings.
+
+               When parsing _\bu_\bs_\be_\br_\b__\be_\bn_\bv, the plugin should split on the f\bfi\bir\brs\bst\bt
+               equal sign ('=') since the _\bn_\ba_\bm_\be field will never include one
+               itself but the _\bv_\ba_\bl_\bu_\be might.
+
+       close
+            void (*close)(int exit_status, int error);
+
+           The close function is called when the command being run by s\bsu\bud\bdo\bo
+
+
+
+1.8.0a1                 February 21, 2010                      10
+
+
+
+
+
+SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
+
+
+           finishes.
+
+           The function arguments are as follows:
+
+           exit_status
+               The command's exit status, as returned by the _\bw_\ba_\bi_\bt(2) system
+               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 function using SUDO_CONV_INFO_MSG.
+           If the user requests detailed version information, the verbose flag
+           will be set.
+
+       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
+           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_output
+            int (*log_output)(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 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
+           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.
+
+
+
+1.8.0a1                 February 21, 2010                      11
+
+
+
+
+
+SUDO_PLUGIN(1m)        MAINTENANCE COMMANDS       SUDO_PLUGIN(1m)
+
+
+   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.
+
+   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 { \
+            *(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \
+        } while(0)
+        #define SUDO_VERSION_SET_MINOR(vp, n) do { \
+            *(vp) = (*(vp) & 0xffff0000) | (n); \
+        } while(0)
+
+        #define SUDO_API_VERSION_MAJOR 1
+        #define SUDO_API_VERSION_MINOR 0
+        #define SUDO_API_VERSION ((SUDO_API_VERSION_MAJOR << 16) | SUDO_API_VERSION_MINOR)
+
+       Sudo will cast the plugin symbol to the following when determining the
+       plugin type.
+
+        union sudo_plugin {
+            struct policy_plugin policy;
+            struct io_plugin io;
+        };
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1.8.0a1                 February 21, 2010                      12
+
+
diff --git a/doc/sudo_plugin.man.in b/doc/sudo_plugin.man.in
new file mode 100644 (file)
index 0000000..10c1783
--- /dev/null
@@ -0,0 +1,831 @@
+.\" Automatically generated by Pod::Man 2.22 (Pod::Simple 3.07)
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" Set up some character translations and predefined strings.  \*(-- will
+.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
+.\" double quote, and \*(R" will give a right double quote.  \*(C+ will
+.\" give a nicer C++.  Capital omega is used to do unbreakable dashes and
+.\" therefore won't be available.  \*(C` and \*(C' expand to `' in nroff,
+.\" nothing in troff, for use with C<>.
+.tr \(*W-
+.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.ie n \{\
+.    ds -- \(*W-
+.    ds PI pi
+.    if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+.    if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\"  diablo 12 pitch
+.    ds L" ""
+.    ds R" ""
+.    ds C` 
+.    ds C' 
+'br\}
+.el\{\
+.    ds -- \|\(em\|
+.    ds PI \(*p
+.    ds L" ``
+.    ds R" ''
+'br\}
+.\"
+.\" Escape single quotes in literal strings from groff's Unicode transform.
+.ie \n(.g .ds Aq \(aq
+.el       .ds Aq '
+.\"
+.\" If the F register is turned on, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
+.\" entries marked with X<> in POD.  Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.ie \nF \{\
+.    de IX
+.    tm Index:\\$1\t\\n%\t"\\$2"
+..
+.    nr % 0
+.    rr F
+.\}
+.el \{\
+.    de IX
+..
+.\}
+.\"
+.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
+.\" Fear.  Run.  Save yourself.  No user-serviceable parts.
+.    \" fudge factors for nroff and troff
+.if n \{\
+.    ds #H 0
+.    ds #V .8m
+.    ds #F .3m
+.    ds #[ \f1
+.    ds #] \fP
+.\}
+.if t \{\
+.    ds #H ((1u-(\\\\n(.fu%2u))*.13m)
+.    ds #V .6m
+.    ds #F 0
+.    ds #[ \&
+.    ds #] \&
+.\}
+.    \" simple accents for nroff and troff
+.if n \{\
+.    ds ' \&
+.    ds ` \&
+.    ds ^ \&
+.    ds , \&
+.    ds ~ ~
+.    ds /
+.\}
+.if t \{\
+.    ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
+.    ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
+.    ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
+.    ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
+.    ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
+.    ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
+.\}
+.    \" troff and (daisy-wheel) nroff accents
+.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
+.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
+.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
+.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
+.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
+.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
+.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
+.ds ae a\h'-(\w'a'u*4/10)'e
+.ds Ae A\h'-(\w'A'u*4/10)'E
+.    \" corrections for vroff
+.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
+.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
+.    \" for low resolution devices (crt and lpr)
+.if \n(.H>23 .if \n(.V>19 \
+\{\
+.    ds : e
+.    ds 8 ss
+.    ds o a
+.    ds d- d\h'-1'\(ga
+.    ds D- D\h'-1'\(hy
+.    ds th \o'bp'
+.    ds Th \o'LP'
+.    ds ae ae
+.    ds Ae AE
+.\}
+.rm #[ #] #H #V #F C
+.\" ========================================================================
+.\"
+.IX Title "SUDO_PLUGIN @mansectsu@"
+.TH SUDO_PLUGIN @mansectsu@ "February 21, 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
+.nh
+.SH "Sudo Plugin API"
+.IX Header "Sudo Plugin API"
+Starting with version 1.8, \fBsudo\fR supports a plugin \s-1API\s0
+for policy and session logging.  By default, the \fIsudoers\fR policy
+plugin and an associated I/O logging plugin are used.  Via the plugin
+\&\s-1API\s0, \fBsudo\fR can be configured to use alternate policy and/or I/O
+logging plugins provided by third parties.  The plugins to be used
+are specified via the \fI/etc/sudo.conf\fR file.
+.PP
+The \s-1API\s0 is versioned with a major and minor number.  The minor
+version number is incremented when additions are made.  The major
+number is incremented when incompatible changes are made.  A plugin
+should be check the version passed to it and make sure that the
+major version matches.
+.PP
+The plugin \s-1API\s0 is defined by the \f(CW\*(C`sudo_plugin.h\*(C'\fR header file.
+.SS "The sudo.conf File"
+.IX Subsection "The sudo.conf File"
+The \fI/etc/sudo.conf\fR file contains plugin configuration directives.
+Currently, the only supported keyword is the \f(CW\*(C`Plugin\*(C'\fR directive,
+which causes a plugin plugin to be loaded.
+.PP
+A \f(CW\*(C`Plugin\*(C'\fR line consists of the \f(CW\*(C`Plugin\*(C'\fR keyword, followed by the
+\&\fIsymbol_name\fR and the \fIpath\fR to the shared object containing the
+plugin.  The \fIsymbol_name\fR is the name of the \f(CW\*(C`struct policy_plugin\*(C'\fR
+or \f(CW\*(C`struct io_plugin\*(C'\fR in the plugin shared object.  The \fIpath\fR
+may be fully qualified or relative.  If not fully qualified it is
+relative to the \f(CW$prefix\fR/libexec directory where the prefix is
+specified at build time (/usr/local by default).
+.PP
+The same shared object may contain multiple plugins, each with a
+different symbol name.  The shared object file must be owned by uid
+0 and only writable by its owner.  Because of ambiguities that arise
+from composite policies, only a single policy plugin may be specified.
+This limitation does not apply to I/O plugins.
+.PP
+.Vb 12
+\& #
+\& # Default /etc/sudo.conf file
+\& #
+\& # Format:
+\& #   Plugin plugin_name plugin_path
+\& #
+\& # The plugin_path relative to prefix/libexec unless fully qualified
+\& # The plugin_name corresponds to a global symbol in the plugin
+\& #   that contains the plugin interface.
+\& #
+\& Plugin policy_plugin sudoers.so
+\& Plugin io_plugin sudoers.so
+.Ve
+.SS "Policy Plugin \s-1API\s0"
+.IX Subsection "Policy Plugin API"
+A policy plugin must declare and populate a \f(CW\*(C`policy_plugin\*(C'\fR struct
+in the global scope.  This structure contains pointers to the functions
+that implement the \fBsudo\fR policy checks.  The name of the symbol should
+be specified in \fI/etc/sudo.conf\fR along with a path to the plugin
+so that \fBsudo\fR can load it.
+.PP
+.Vb 10
+\& struct policy_plugin {
+\& #define SUDO_POLICY_PLUGIN     1
+\&     unsigned int type; /* always SUDO_POLICY_PLUGIN */
+\&     unsigned int version; /* always SUDO_API_VERSION */
+\&     int (*open)(unsigned int version, sudo_conv_t conversation,
+\&                 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[],
+\&                         char *env_add[], char **command_info[],
+\&                         char **argv_out[], char **user_env_out[]);
+\&     int (*list)(int argc, char * const argv[], int verbose,
+\&                 const char *list_user);
+\&     int (*validate)(void);
+\&     void (*invalidate)(int remove);
+\& };
+.Ve
+.PP
+The policy_plugin struct has the following fields:
+.IP "type" 4
+.IX Item "type"
+The \f(CW\*(C`type\*(C'\fR field should always be set to \s-1SUDO_POLICY_PLUGIN\s0
+.IP "version" 4
+.IX Item "version"
+The \f(CW\*(C`version\*(C'\fR field should be set to \s-1SUDO_API_VERSION\s0.
+.Sp
+This allows \fBsudo\fR to determine the \s-1API\s0 version the plugin was
+built against.
+.IP "open" 4
+.IX Item "open"
+.Vb 3
+\& int (*open)(unsigned int version, sudo_conv_t conversation,
+\&             char * const settings[], char * const user_info[],
+\&             char * const user_env[]);
+.Ve
+.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.
+.Sp
+The function arguments are as follows:
+.RS 4
+.IP "version" 4
+.IX Item "version"
+The version passed in by \fBsudo\fR allows the plugin to determine the
+major and minor version number of the plugin \s-1API\s0 supported by
+\&\fBsudo\fR.
+.IP "conversation" 4
+.IX Item "conversation"
+A pointer to the conversation function that can be used by the
+plugin to interact with the user (see below).
+.IP "settings" 4
+.IX Item "settings"
+A vector of user-supplied \fBsudo\fR settings in the form of \*(L"name=value\*(R"
+strings.  The vector is terminated by a \f(CW\*(C`NULL\*(C'\fR pointer.  These
+settings correspond to flags the user specified when running \fBsudo\fR.
+As such, they will only be present when the corresponding flag has
+been specified on the command line.
+.Sp
+When parsing \fIsettings\fR, the plugin should split on the \fBfirst\fR
+equal sign ('=') since the \fIname\fR field will never include one
+itself but the \fIvalue\fR might.
+.RS 4
+.IP "runas_user=string" 4
+.IX Item "runas_user=string"
+The user name or uid to to run the command as, if specified via the
+\&\f(CW\*(C`\-u\*(C'\fR flag.
+.IP "runas_group=string" 4
+.IX Item "runas_group=string"
+The group name or gid to to run the command as, if specified via
+the \f(CW\*(C`\-g\*(C'\fR flag.
+.IP "prompt=string" 4
+.IX Item "prompt=string"
+The prompt to use when requesting a password, if specified via
+the \f(CW\*(C`\-p\*(C'\fR flag.
+.IP "set_home=bool" 4
+.IX Item "set_home=bool"
+Set to true if the user specified the \f(CW\*(C`\-H\*(C'\fR flag.  If true, set the
+\&\f(CW\*(C`HOME\*(C'\fR environment variable to the target user's home directory.
+.IP "preserve_environment=bool" 4
+.IX Item "preserve_environment=bool"
+Set to true if the user specified the \f(CW\*(C`\-E\*(C'\fR flag, indicating that
+the user wishes to preserve the environment.
+.IP "login_shell=bool" 4
+.IX Item "login_shell=bool"
+Set to true if the user specified the \f(CW\*(C`\-i\*(C'\fR flag, indicating that
+the user wishes to run a login shell.
+.IP "preserve_groups=bool" 4
+.IX Item "preserve_groups=bool"
+Set to true if the user specified the \f(CW\*(C`\-P\*(C'\fR flag, indicating that
+the user wishes to preserve the group vector instead of setting it
+based on the runas user.
+.IP "ignore_ticket=bool" 4
+.IX Item "ignore_ticket=bool"
+Set to true if the user specified the \f(CW\*(C`\-k\*(C'\fR flag along with a
+command, indicating that the user wishes to ignore any cached
+authentication credentials.
+.IP "login_class=string" 4
+.IX Item "login_class=string"
+\&\s-1BSD\s0 login class to use when setting resource limits and nice value,
+if specified by the \f(CW\*(C`\-c\*(C'\fR flag.
+.IP "selinux_role=string" 4
+.IX Item "selinux_role=string"
+SELinux role to use when executing the command, if specified by
+the \f(CW\*(C`\-r\*(C'\fR flag.
+.IP "selinux_type=string" 4
+.IX Item "selinux_type=string"
+SELinux type to use when executing the command, if specified by
+the \f(CW\*(C`\-t\*(C'\fR flag.
+.IP "bsdauth_type=string" 4
+.IX Item "bsdauth_type=string"
+Authentication type, if specified by the \f(CW\*(C`\-a\*(C'\fR flag, to use on
+systems where \s-1BSD\s0 authentication is supported.
+.RE
+.RS 4
+.Sp
+Additional settings may be added in the future so the plugin should
+silently ignore settings that it does not recognize.
+.RE
+.IP "user_info" 4
+.IX Item "user_info"
+A vector of information about the user running the command in the form of
+\&\*(L"name=value\*(R" strings.  The vector is terminated by a \f(CW\*(C`NULL\*(C'\fR pointer.
+.Sp
+When parsing \fIuser_info\fR, the plugin should split on the \fBfirst\fR
+equal sign ('=') since the \fIname\fR field will never include one
+itself but the \fIvalue\fR might.
+.RS 4
+.IP "user=string" 4
+.IX Item "user=string"
+The name of the user invoking \fBsudo\fR.
+.IP "uid=uid_t" 4
+.IX Item "uid=uid_t"
+The real user \s-1ID\s0 of the user invoking \fBsudo\fR.
+.IP "gid=gid_t" 4
+.IX Item "gid=gid_t"
+The real group \s-1ID\s0 of the user invoking \fBsudo\fR.
+.IP "groups=list" 4
+.IX Item "groups=list"
+The user's supplementary group list formatted as a string of
+comma-separated group IDs.
+.IP "cwd=string" 4
+.IX Item "cwd=string"
+The user's current working directory.
+.IP "tty=string" 4
+.IX Item "tty=string"
+The path to the user's terminal device.  If the user has no terminal
+device associated with the session, the value will be empty, as in
+\&\f(CW\*(C`tty=\*(C'\fR.
+.IP "host=string" 4
+.IX Item "host=string"
+The local machine's hostname as returned by the \f(CW\*(C`gethostname()\*(C'\fR
+system call.
+.RE
+.RS 4
+.RE
+.IP "user_env" 4
+.IX Item "user_env"
+The user's environment in the form of a \f(CW\*(C`NULL\*(C'\fR\-terminated vector of
+\&\*(L"name=value\*(R" strings.
+.Sp
+When parsing \fIuser_env\fR, the plugin should split on the \fBfirst\fR
+equal sign ('=') since the \fIname\fR field will never include one
+itself but the \fIvalue\fR might.
+.RE
+.RS 4
+.RE
+.IP "close" 4
+.IX Item "close"
+.Vb 1
+\& void (*close)(int exit_status, int error);
+.Ve
+.Sp
+The \f(CW\*(C`close\*(C'\fR function is called when the command being run by \fBsudo\fR
+finishes.
+.Sp
+The function arguments are as follows:
+.RS 4
+.IP "exit_status" 4
+.IX Item "exit_status"
+The command's exit status, as returned by the \fIwait\fR\|(2) system call.
+The value of \f(CW\*(C`exit_status\*(C'\fR is undefined if \f(CW\*(C`error\*(C'\fR is non-zero.
+.IP "error" 4
+.IX Item "error"
+If the command could not be executed, this is set to the value of
+\&\f(CW\*(C`errno\*(C'\fR set by the \fIexecve\fR\|(2) system call.  The plugin is responsible
+for displaying error information via the conversation function.  If
+the command was successfully executed, the value of \f(CW\*(C`error\*(C'\fR is 0.
+.RE
+.RS 4
+.RE
+.IP "show_version" 4
+.IX Item "show_version"
+.Vb 1
+\& int (*show_version)(int verbose);
+.Ve
+.Sp
+The \f(CW\*(C`show_version\*(C'\fR function is called by \fBsudo\fR when the user specifies
+the \f(CW\*(C`\-V\*(C'\fR option.  The plugin may display its version information
+to the user via the conversation function using \f(CW\*(C`SUDO_CONV_INFO_MSG\*(C'\fR.
+If the user requests detailed version information, the verbose flag
+will be set.
+.IP "check_policy" 4
+.IX Item "check_policy"
+.Vb 3
+\& int (*check_policy)(int argc, char * const argv[]
+\&                     char *env_add[], char **command_info[],
+\&                     char **argv_out[], char **user_env_out[]);
+.Ve
+.Sp
+The \fIcheck_policy\fR function is called by \fBsudo\fR to determine
+whether the user is allowed to run the specified commands.
+Returns 1 if the command is allowed, 0 if not 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.
+.Sp
+The function arguments are as follows:
+.RS 4
+.IP "argc" 4
+.IX Item "argc"
+The number of elements in \fIargv\fR, not counting the final \f(CW\*(C`NULL\*(C'\fR
+pointer.
+.IP "argv" 4
+.IX Item "argv"
+The argument vector describing the command the user wishes to run,
+in the same form as what would be passed to the \fIexecve()\fR system
+call.  The vector is terminated by a \f(CW\*(C`NULL\*(C'\fR pointer.
+.IP "env_add" 4
+.IX Item "env_add"
+Additional environment variables specified by the user on the command
+line in the form of a \f(CW\*(C`NULL\*(C'\fR\-terminated vector of \*(L"name=value\*(R"
+strings.  The plugin may reject the command if one or more variables
+are not allowed to be set, or it may silently ignore such variables.
+.Sp
+When parsing \fIenv_add\fR, the plugin should split on the \fBfirst\fR
+equal sign ('=') since the \fIname\fR field will never include one
+itself but the \fIvalue\fR might.
+.IP "command_info" 4
+.IX Item "command_info"
+Information about the command being run in the form of \*(L"name=value\*(R"
+strings.  These values are used by \fBsudo\fR to set the execution
+environment when running a command.  The plugin is responsible for
+creating and populating the vector, which must be terminated with
+a \f(CW\*(C`NULL\*(C'\fR pointer.  The following values are recognized by \fBsudo\fR:
+.RS 4
+.IP "command=string" 4
+.IX Item "command=string"
+Fully qualified path to the command to be executed.
+.IP "runas_uid=uid" 4
+.IX Item "runas_uid=uid"
+User \s-1ID\s0 to run the command as.
+.IP "runas_euid=uid" 4
+.IX Item "runas_euid=uid"
+Effective user \s-1ID\s0 to run the command as.
+If not specified, the value of \fIrunas_uid\fR is used.
+.IP "runas_gid=gid" 4
+.IX Item "runas_gid=gid"
+Group \s-1ID\s0 to run the command as.
+.IP "runas_egid=gid" 4
+.IX Item "runas_egid=gid"
+Effective group \s-1ID\s0 to run the command as.
+If not specified, the value of \fIrunas_gid\fR is used.
+.IP "runas_groups=list" 4
+.IX Item "runas_groups=list"
+The supplementary group vector to use for the command in the form
+of a comma-separated list of group IDs.  If \fIpreserve_groups\fR
+is set, this option is ignored.
+.IP "login_class=login_class" 4
+.IX Item "login_class=login_class"
+\&\s-1BSD\s0 login class to use when setting resource limits and nice value
+(optional).  This option is only set on systems that support login
+classes.
+.IP "preserve_groups=bool" 4
+.IX Item "preserve_groups=bool"
+If set, \fBsudo\fR will preserve the user's group vector instead of
+initializing the group vector based on \f(CW\*(C`runas_user\*(C'\fR.
+.IP "cwd=string" 4
+.IX Item "cwd=string"
+The current working directory to change to when executing the command.
+.IP "noexec=bool" 4
+.IX Item "noexec=bool"
+If set, prevent the command from executing other programs.
+.IP "chroot=string" 4
+.IX Item "chroot=string"
+The root directory to use when running the command.
+.IP "nice=int" 4
+.IX Item "nice=int"
+Nice value (priority) to use when executing the command.  The nice
+value, if specified, overrides the priority associated with the
+\&\fIlogin_class\fR on \s-1BSD\s0 systems.
+.IP "umask=octal" 4
+.IX Item "umask=octal"
+The file creation mask to use when executing the command.
+.IP "selinux_role=string" 4
+.IX Item "selinux_role=string"
+SELinux role to use when executing the command.
+.IP "selinux_type=string" 4
+.IX Item "selinux_type=string"
+SELinux type to use when executing the command.
+.IP "timeout=int" 4
+.IX Item "timeout=int"
+Command timeout.  If non-zero then when the timeout expires the
+command will be killed.
+.RE
+.RS 4
+.Sp
+Unsupported values will be ignored.
+.RE
+.IP "argv_out" 4
+.IX Item "argv_out"
+The \f(CW\*(C`NULL\*(C'\fR\-terminated argument vector to pass to the \fIexecve()\fR
+system call when executing the command.  The plugin is responsible
+for allocating and populating the vector.
+.IP "user_env_out" 4
+.IX Item "user_env_out"
+The \f(CW\*(C`NULL\*(C'\fR\-terminated environment vector to use when executing the
+command.  The plugin is responsible for allocating and populating
+the vector.
+.RE
+.RS 4
+.RE
+.IP "list" 4
+.IX Item "list"
+.Vb 2
+\& int (*list)(int verbose, const char *list_user,
+\&             int argc, char * const argv[]);
+.Ve
+.Sp
+List available privileges for the invoking user.  Returns 1 on
+success, 0 on failure and \-1 on error.
+On error, the plugin may optionally call the conversation 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.
+.RS 4
+.IP "verbose" 4
+.IX Item "verbose"
+Flag indicating whether to list in verbose mode or not.
+.IP "list_user" 4
+.IX Item "list_user"
+The name of a different user to list privileges for if the policy
+allows it.  If \f(CW\*(C`NULL\*(C'\fR, the plugin should list the privileges of
+the invoking user.
+.IP "argc" 4
+.IX Item "argc"
+The number of elements in \fIargv\fR, not counting the final \f(CW\*(C`NULL\*(C'\fR
+pointer.
+.IP "argv" 4
+.IX Item "argv"
+If non\-\f(CW\*(C`NULL\*(C'\fR, an argument vector describing a command the user
+wishes to check against the policy in the same form as what would
+be passed to the \fIexecve()\fR system call.  If the command is permitted
+by the policy, the fully-qualified path to the command should be
+displayed along with any command line arguments.
+.RE
+.RS 4
+.RE
+.IP "validate" 4
+.IX Item "validate"
+.Vb 1
+\& int (*validate)(void);
+.Ve
+.Sp
+The \f(CW\*(C`validate\*(C'\fR function is called when \fBsudo\fR is run with the
+\&\f(CW\*(C`\-v\*(C'\fR flag.  For policy plugins such as \fIsudoers\fR that cache
+authentication credentials, this function will validate and cache
+the credentials.
+.Sp
+The \f(CW\*(C`validate\*(C'\fR function should be \f(CW\*(C`NULL\*(C'\fR if the plugin does not
+support credential caching.
+.Sp
+Returns 1 on success, 0 on failure and \-1 on error.
+On error, the plugin may optionally call the conversation function with
+\&\f(CW\*(C`SUDO_CONF_ERROR_MSG\*(C'\fR to present additional error information to the
+user.
+.IP "invalidate" 4
+.IX Item "invalidate"
+.Vb 1
+\& void (*invalidate)(int remove);
+.Ve
+.Sp
+The \f(CW\*(C`invalidate\*(C'\fR function is called when \fBsudo\fR is called with
+the \f(CW\*(C`\-k\*(C'\fR or \f(CW\*(C`\-K\*(C'\fR flag.  For policy plugins such as \fIsudoers\fR that
+cache authentication credentials, this function will invalidate the
+credentials.  If the \fIremove\fR flag is set, the plugin may remove
+the credentials instead of simply invalidating them.
+.Sp
+The \f(CW\*(C`invalidate\*(C'\fR function should be \f(CW\*(C`NULL\*(C'\fR if the plugin does not
+support credential caching.
+.PP
+\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.
+.PP
+.Vb 9
+\& struct sudo_conv_message {
+\& #define SUDO_CONV_PROMPT_ECHO_OFF      1
+\& #define SUDO_CONV_PROMPT_ECHO_ON       2
+\& #define SUDO_CONV_ERROR_MSG            3
+\& #define SUDO_CONV_INFO_MSG             4
+\&     int msg_type;
+\&     int timeout;
+\&     const char *msg;
+\& };
+\&
+\& struct sudo_conv_reply {
+\&     char *reply;
+\& };
+\&
+\& typedef int (*sudo_conv_t)(int num_msgs,
+\&              const struct sudo_conv_message msgs[],
+\&              struct sudo_conv_reply replies[]);
+.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.
+.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
+\& 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[]);
+\&     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);
+\& };
+.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
+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.
+.PP
+The io_plugin struct has the following fields:
+.IP "type" 4
+.IX Item "type"
+The \f(CW\*(C`type\*(C'\fR field should always be set to \s-1SUDO_IO_PLUGIN\s0
+.IP "version" 4
+.IX Item "version"
+The \f(CW\*(C`version\*(C'\fR field should be set to \s-1SUDO_API_VERSION\s0.
+.Sp
+This allows \fBsudo\fR to determine the \s-1API\s0 version the plugin was
+built against.
+.IP "open" 4
+.IX Item "open"
+.Vb 3
+\& int (*open)(unsigned int version, sudo_conv_t conversation
+\&             char * const settings[], char * const user_info[],
+\&             char * const user_env[]);
+.Ve
+.Sp
+Returns 1 on success, 0 if the command should not be logged 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.
+.Sp
+The function arguments are as follows:
+.RS 4
+.IP "version" 4
+.IX Item "version"
+The version passed in by \fBsudo\fR allows the plugin to determine the
+major and minor version number of the plugin \s-1API\s0 supported by
+\&\fBsudo\fR.
+.IP "conversation" 4
+.IX Item "conversation"
+A pointer to the conversation function that may be used by the
+\&\fIshow_version\fR function to display version information (see
+show_version below).  The conversation function may also be used
+to display additional error message to the user.
+.IP "settings" 4
+.IX Item "settings"
+A vector of user-supplied \fBsudo\fR settings in the form of \*(L"name=value\*(R"
+strings.  The vector is terminated by a \f(CW\*(C`NULL\*(C'\fR pointer.  These
+settings correspond to flags the user specified when running \fBsudo\fR.
+As such, they will only be present when the corresponding flag has
+been specified on the command line.
+.Sp
+When parsing \fIsettings\fR, the plugin should split on the \fBfirst\fR
+equal sign ('=') since the \fIname\fR field will never include one
+itself but the \fIvalue\fR might.
+.Sp
+See the \*(L"Policy Plugin \s-1API\s0\*(R" section for a list of all possible settings.
+.IP "user_info" 4
+.IX Item "user_info"
+A vector of information about the user running the command in the form of
+\&\*(L"name=value\*(R" strings.  The vector is terminated by a \f(CW\*(C`NULL\*(C'\fR pointer.
+.Sp
+When parsing \fIuser_info\fR, the plugin should split on the \fBfirst\fR
+equal sign ('=') since the \fIname\fR field will never include one
+itself but the \fIvalue\fR might.
+.Sp
+See the \*(L"Policy Plugin \s-1API\s0\*(R" section for a list of all possible strings.
+.IP "user_env" 4
+.IX Item "user_env"
+The user's environment in the form of a \f(CW\*(C`NULL\*(C'\fR\-terminated vector of
+\&\*(L"name=value\*(R" strings.
+.Sp
+When parsing \fIuser_env\fR, the plugin should split on the \fBfirst\fR
+equal sign ('=') since the \fIname\fR field will never include one
+itself but the \fIvalue\fR might.
+.RE
+.RS 4
+.RE
+.IP "close" 4
+.IX Item "close"
+.Vb 1
+\& void (*close)(int exit_status, int error);
+.Ve
+.Sp
+The \f(CW\*(C`close\*(C'\fR function is called when the command being run by \fBsudo\fR
+finishes.
+.Sp
+The function arguments are as follows:
+.RS 4
+.IP "exit_status" 4
+.IX Item "exit_status"
+The command's exit status, as returned by the \fIwait\fR\|(2) system call.
+The value of \f(CW\*(C`exit_status\*(C'\fR is undefined if \f(CW\*(C`error\*(C'\fR is non-zero.
+.IP "error" 4
+.IX Item "error"
+If the command could not be executed, this is set to the value of
+\&\f(CW\*(C`errno\*(C'\fR set by the \fIexecve\fR\|(2) system call.  If the command was
+successfully executed, the value of \f(CW\*(C`error\*(C'\fR is 0.
+.RE
+.RS 4
+.RE
+.IP "show_version" 4
+.IX Item "show_version"
+.Vb 1
+\& int (*show_version)(int verbose);
+.Ve
+.Sp
+The \f(CW\*(C`show_version\*(C'\fR function is called by \fBsudo\fR when the user specifies
+the \f(CW\*(C`\-V\*(C'\fR option.  The plugin may display its version information
+to the user via the conversation 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"
+.Vb 1
+\& int (*log_input)(const char *buf, unsigned int len);
+.Ve
+.Sp
+The \fIlog_input\fR function is called whenever data can be read from
+the user but before it is passed to the running command.  This
+allows the plugin to reject data if it chooses to (for instance
+if the input contains banned content).  Returns \f(CW1\fR if the data
+should be passed to the command, \f(CW0\fR if the data is rejected
+(which will terminate the command) or \f(CW\*(C`\-1\*(C'\fR if an error occurred.
+.Sp
+The function arguments are as follows:
+.RS 4
+.IP "buf" 4
+.IX Item "buf"
+The buffer containing user input.
+.IP "len" 4
+.IX Item "len"
+The length of \fIbuf\fR in bytes.
+.RE
+.RS 4
+.RE
+.IP "log_output" 4
+.IX Item "log_output"
+.Vb 1
+\& int (*log_output)(const char *buf, unsigned int len);
+.Ve
+.Sp
+The \fIlog_output\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
+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 "Unhandled command line options"
+.IX Subsection "Unhandled 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"
+.IX Subsection "Sudo implementation details"
+Version macros:
+.PP
+.Vb 8
+\& #define SUDO_API_VERSION_GET_MAJOR(v) ((v) >> 16)
+\& #define SUDO_API_VERSION_GET_MINOR(v) ((v) & 0xffff)
+\& #define SUDO_API_VERSION_SET_MAJOR(vp, n) do { \e
+\&     *(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \e
+\& } while(0)
+\& #define SUDO_VERSION_SET_MINOR(vp, n) do { \e
+\&     *(vp) = (*(vp) & 0xffff0000) | (n); \e
+\& } while(0)
+\&
+\& #define SUDO_API_VERSION_MAJOR 1
+\& #define SUDO_API_VERSION_MINOR 0
+\& #define SUDO_API_VERSION ((SUDO_API_VERSION_MAJOR << 16) | SUDO_API_VERSION_MINOR)
+.Ve
+.PP
+Sudo will cast the plugin symbol to the following when determining
+the plugin type.
+.PP
+.Vb 4
+\& union sudo_plugin {
+\&     struct policy_plugin policy;
+\&     struct io_plugin io;
+\& };
+.Ve
similarity index 100%
rename from doc/plugin.pod
rename to doc/sudo_plugin.pod