summaryrefslogtreecommitdiffstats
path: root/doc/sudo_plugin.man.in
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--doc/sudo_plugin.man.in2986
1 files changed, 2986 insertions, 0 deletions
diff --git a/doc/sudo_plugin.man.in b/doc/sudo_plugin.man.in
new file mode 100644
index 0000000..c336033
--- /dev/null
+++ b/doc/sudo_plugin.man.in
@@ -0,0 +1,2986 @@
+.\" Automatically generated from an mdoc input file. Do not edit.
+.\"
+.\" Copyright (c) 2009-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.TH "SUDO_PLUGIN" "5" "October 24, 2018" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
+.nh
+.if n .ad l
+.SH "NAME"
+\fBsudo_plugin\fR
+\- Sudo Plugin API
+.SH "DESCRIPTION"
+Starting with version 1.8,
+\fBsudo\fR
+supports a plugin API
+for policy and session logging.
+Plugins may be compiled as dynamic shared objects (the default on
+systems that support them) or compiled statically into the
+\fBsudo\fR
+binary itself.
+By default, the
+\fBsudoers\fR
+policy plugin and an associated I/O logging plugin are used.
+Via the plugin API,
+\fBsudo\fR
+can be configured to use alternate policy and/or I/O logging plugins
+provided by third parties.
+The plugins to be used are specified in the
+sudo.conf(@mansectform@)
+file.
+.PP
+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.
+.PP
+The plugin API is defined by the
+\fRsudo_plugin.h\fR
+header file.
+.SS "Policy plugin API"
+A policy plugin must declare and populate a
+\fRpolicy_plugin\fR
+struct in the global scope.
+This structure contains pointers to the functions that implement the
+\fBsudo\fR
+policy checks.
+The name of the symbol should be specified in
+sudo.conf(@mansectform@)
+along with a path to the plugin so that
+\fBsudo\fR
+can load it.
+.nf
+.sp
+.RS 0n
+struct policy_plugin {
+#define SUDO_POLICY_PLUGIN 1
+ unsigned int type; /* always SUDO_POLICY_PLUGIN */
+ unsigned int version; /* always SUDO_API_VERSION */
+ int (*open)(unsigned int version, sudo_conv_t conversation,
+ sudo_printf_t plugin_printf, char * const settings[],
+ char * const user_info[], char * const user_env[],
+ char * const plugin_options[]);
+ void (*close)(int exit_status, int error);
+ int (*show_version)(int verbose);
+ int (*check_policy)(int argc, char * const argv[],
+ char *env_add[], char **command_info[],
+ char **argv_out[], char **user_env_out[]);
+ int (*list)(int argc, char * const argv[], int verbose,
+ const char *list_user);
+ int (*validate)(void);
+ void (*invalidate)(int remove);
+ int (*init_session)(struct passwd *pwd, char **user_env[]);
+ void (*register_hooks)(int version,
+ int (*register_hook)(struct sudo_hook *hook));
+ void (*deregister_hooks)(int version,
+ int (*deregister_hook)(struct sudo_hook *hook));
+};
+.RE
+.fi
+.PP
+The policy_plugin struct has the following fields:
+.TP 6n
+type
+The
+\fRtype\fR
+field should always be set to SUDO_POLICY_PLUGIN.
+.TP 6n
+version
+The
+\fRversion\fR
+field should be set to
+\fRSUDO_API_VERSION\fR.
+.sp
+This allows
+\fBsudo\fR
+to determine the API version the plugin was
+built against.
+.TP 6n
+open
+.nf
+.RS 6n
+int (*open)(unsigned int version, sudo_conv_t conversation,
+ sudo_printf_t plugin_printf, char * const settings[],
+ char * const user_info[], char * const user_env[],
+ char * const plugin_options[]);
+.RE
+.fi
+.RS 6n
+.sp
+Returns 1 on success, 0 on failure, \-1 if a general error occurred,
+or \-2 if there was a usage error.
+In the latter case,
+\fBsudo\fR
+will print a usage message before it exits.
+If an error occurs, the plugin may optionally call the
+\fBconversation\fR()
+or
+\fBplugin_printf\fR()
+function with
+\fRSUDO_CONF_ERROR_MSG\fR
+to present additional error information to the user.
+.sp
+The function arguments are as follows:
+.TP 6n
+version
+The version passed in by
+\fBsudo\fR
+allows the plugin to determine the
+major and minor version number of the plugin API supported by
+\fBsudo\fR.
+.TP 6n
+conversation
+A pointer to the
+\fBconversation\fR()
+function that can be used by the plugin to interact with the user (see below).
+Returns 0 on success and \-1 on failure.
+.TP 6n
+plugin_printf
+A pointer to a
+\fBprintf\fR()-style
+function that may be used to display informational or error messages
+(see below).
+Returns the number of characters printed on success and \-1 on failure.
+.TP 6n
+settings
+A vector of user-supplied
+\fBsudo\fR
+settings in the form of
+\(lqname=value\(rq
+strings.
+The vector is terminated by a
+\fRNULL\fR
+pointer.
+These settings correspond to flags the user specified when running
+\fBsudo\fR.
+As such, they will only be present when the corresponding flag has
+been specified on the command line.
+.sp
+When parsing
+\fIsettings\fR,
+the plugin should split on the
+\fBfirst\fR
+equal sign
+(\(oq=\(cq)
+since the
+\fIname\fR
+field will never include one
+itself but the
+\fIvalue\fR
+might.
+.PP
+.RS 6n
+.PD 0
+.TP 6n
+bsdauth_type=string
+Authentication type, if specified by the
+\fB\-a\fR
+flag, to use on
+systems where
+BSD
+authentication is supported.
+.PD
+.TP 6n
+closefrom=number
+If specified, the user has requested via the
+\fB\-C\fR
+flag that
+\fBsudo\fR
+close all files descriptors with a value of
+\fInumber\fR
+or higher.
+The plugin may optionally pass this, or another value, back in the
+\fIcommand_info\fR
+list.
+.TP 6n
+debug_flags=string
+A debug file path name followed by a space and a comma-separated
+list of debug flags that correspond to the plugin's
+\fRDebug\fR
+entry in
+sudo.conf(@mansectform@),
+if there is one.
+The flags are passed to the plugin exactly as they appear in
+sudo.conf(@mansectform@).
+The syntax used by
+\fBsudo\fR
+and the
+\fBsudoers\fR
+plugin is
+\fIsubsystem\fR@\fIpriority\fR
+but a plugin is free to use a different
+format so long as it does not include a comma
+(\(oq,\&\(cq).
+Prior to
+\fBsudo\fR
+1.8.12, there was no way to specify plugin-specific
+\fIdebug_flags\fR
+so the value was always the same as that used by the
+\fBsudo\fR
+front end and did not include a path name, only the flags themselves.
+As of version 1.7 of the plugin interface,
+\fBsudo\fR
+will only pass
+\fIdebug_flags\fR
+if
+sudo.conf(@mansectform@)
+contains a plugin-specific
+\fRDebug\fR
+entry.
+.TP 6n
+debug_level=number
+This setting has been deprecated in favor of
+\fIdebug_flags\fR.
+.TP 6n
+ignore_ticket=bool
+Set to true if the user specified the
+\fB\-k\fR
+flag along with a
+command, indicating that the user wishes to ignore any cached
+authentication credentials.
+\fIimplied_shell\fR
+to true.
+This allows
+\fBsudo\fR
+with no arguments
+to be used similarly to
+su(1).
+If the plugin does not to support this usage, it may return a value of \-2
+from the
+\fBcheck_policy\fR()
+function, which will cause
+\fBsudo\fR
+to print a usage message and
+exit.
+.TP 6n
+implied_shell=bool
+If the user does not specify a program on the command line,
+\fBsudo\fR
+will pass the plugin the path to the user's shell and set
+.TP 6n
+login_class=string
+BSD
+login class to use when setting resource limits and nice value,
+if specified by the
+\fB\-c\fR
+flag.
+.TP 6n
+login_shell=bool
+Set to true if the user specified the
+\fB\-i\fR
+flag, indicating that
+the user wishes to run a login shell.
+.TP 6n
+max_groups=int
+The maximum number of groups a user may belong to.
+This will only be present if there is a corresponding setting in
+sudo.conf(@mansectform@).
+.TP 6n
+network_addrs=list
+A space-separated list of IP network addresses and netmasks in the
+form
+\(lqaddr/netmask\(rq,
+e.g.,
+\(lq192.168.1.2/255.255.255.0\(rq.
+The address and netmask pairs may be either IPv4 or IPv6, depending on
+what the operating system supports.
+If the address contains a colon
+(\(oq:\&\(cq),
+it is an IPv6 address, else it is IPv4.
+.TP 6n
+noninteractive=bool
+Set to true if the user specified the
+\fB\-n\fR
+flag, indicating that
+\fBsudo\fR
+should operate in non-interactive mode.
+The plugin may reject a command run in non-interactive mode if user
+interaction is required.
+.TP 6n
+plugin_dir=string
+The default plugin directory used by the
+\fBsudo\fR
+front end.
+This is the default directory set at compile time and may not
+correspond to the directory the running plugin was loaded from.
+It may be used by a plugin to locate support files.
+.TP 6n
+plugin_path=string
+The path name of plugin loaded by the
+\fBsudo\fR
+front end.
+The path name will be a fully-qualified unless the plugin was
+statically compiled into
+\fBsudo\fR.
+.TP 6n
+preserve_environment=bool
+Set to true if the user specified the
+\fB\-E\fR
+flag, indicating that
+the user wishes to preserve the environment.
+.TP 6n
+preserve_groups=bool
+Set to true if the user specified the
+\fB\-P\fR
+flag, indicating that
+the user wishes to preserve the group vector instead of setting it
+based on the runas user.
+.TP 6n
+progname=string
+The command name that sudo was run as, typically
+\(lqsudo\(rq
+or
+\(lqsudoedit\(rq.
+.TP 6n
+prompt=string
+The prompt to use when requesting a password, if specified via
+the
+\fB\-p\fR
+flag.
+.TP 6n
+remote_host=string
+The name of the remote host to run the command on, if specified via
+the
+\fB\-h\fR
+option.
+Support for running the command on a remote host is meant to be implemented
+via a helper program that is executed in place of the user-specified command.
+The
+\fBsudo\fR
+front end is only capable of executing commands on the local host.
+Only available starting with API version 1.4.
+.TP 6n
+run_shell=bool
+Set to true if the user specified the
+\fB\-s\fR
+flag, indicating that the user wishes to run a shell.
+.TP 6n
+runas_group=string
+The group name or gid to run the command as, if specified via
+the
+\fB\-g\fR
+flag.
+.TP 6n
+runas_user=string
+The user name or uid to run the command as, if specified via the
+\fB\-u\fR
+flag.
+.TP 6n
+selinux_role=string
+SELinux role to use when executing the command, if specified by
+the
+\fB\-r\fR
+flag.
+.TP 6n
+selinux_type=string
+SELinux type to use when executing the command, if specified by
+the
+\fB\-t\fR
+flag.
+.TP 6n
+set_home=bool
+Set to true if the user specified the
+\fB\-H\fR
+flag.
+If true, set the
+\fRHOME\fR
+environment variable to the target user's home directory.
+.TP 6n
+sudoedit=bool
+Set to true when the
+\fB\-e\fR
+flag is specified or if invoked as
+\fBsudoedit\fR.
+The plugin shall substitute an editor into
+\fIargv\fR
+in the
+\fBcheck_policy\fR()
+function or return \-2 with a usage error
+if the plugin does not support
+\fIsudoedit\fR.
+For more information, see the
+\fIcheck_policy\fR
+section.
+.TP 6n
+timeout=string
+User-specified command timeout.
+Not all plugins support command timeouts and the ability for the
+user to set a timeout may be restricted by policy.
+The format of the timeout string is plugin-specific.
+.PP
+Additional settings may be added in the future so the plugin should
+silently ignore settings that it does not recognize.
+.RE
+.TP 6n
+user_info
+A vector of information about the user running the command in the form of
+\(lqname=value\(rq
+strings.
+The vector is terminated by a
+\fRNULL\fR
+pointer.
+.sp
+When parsing
+\fIuser_info\fR,
+the plugin should split on the
+\fBfirst\fR
+equal sign
+(\(oq=\(cq)
+since the
+\fIname\fR
+field will never include one
+itself but the
+\fIvalue\fR
+might.
+.PP
+.RS 6n
+.PD 0
+.TP 6n
+cols=int
+The number of columns the user's terminal supports.
+If there is no terminal device available, a default value of 80 is used.
+.PD
+.TP 6n
+cwd=string
+The user's current working directory.
+.TP 6n
+egid=gid_t
+The effective group ID of the user invoking
+\fBsudo\fR.
+.TP 6n
+euid=uid_t
+The effective user ID of the user invoking
+\fBsudo\fR.
+.TP 6n
+gid=gid_t
+The real group ID of the user invoking
+\fBsudo\fR.
+.TP 6n
+groups=list
+The user's supplementary group list formatted as a string of
+comma-separated group IDs.
+.TP 6n
+host=string
+The local machine's hostname as returned by the
+gethostname(2)
+system call.
+.TP 6n
+lines=int
+The number of lines the user's terminal supports.
+If there is
+no terminal device available, a default value of 24 is used.
+.TP 6n
+pgid=int
+The ID of the process group that the running
+\fBsudo\fR
+process is a member of.
+Only available starting with API version 1.2.
+.TP 6n
+pid=int
+The process ID of the running
+\fBsudo\fR
+process.
+Only available starting with API version 1.2.
+.TP 6n
+plugin_options
+Any (non-comment) strings immediately after the plugin path are
+passed as arguments to the plugin.
+These arguments are split on a white space boundary and are passed to
+the plugin in the form of a
+\fRNULL\fR-terminated
+array of strings.
+If no arguments were
+specified,
+\fIplugin_options\fR
+will be the
+\fRNULL\fR
+pointer.
+.sp
+NOTE: the
+\fIplugin_options\fR
+parameter is only available starting with
+API version 1.2.
+A plugin
+\fBmust\fR
+check the API version specified
+by the
+\fBsudo\fR
+front end before using
+\fIplugin_options\fR.
+Failure to do so may result in a crash.
+.TP 6n
+ppid=int
+The parent process ID of the running
+\fBsudo\fR
+process.
+Only available starting with API version 1.2.
+.TP 6n
+sid=int
+The session ID of the running
+\fBsudo\fR
+process or 0 if
+\fBsudo\fR
+is not part of a POSIX job control session.
+Only available starting with API version 1.2.
+.TP 6n
+tcpgid=int
+The ID of the foreground process group associated with the terminal
+device associated with the
+\fBsudo\fR
+process or \-1 if there is no
+terminal present.
+Only available starting with API version 1.2.
+.TP 6n
+tty=string
+The path to the user's terminal device.
+If the user has no terminal device associated with the session,
+the value will be empty, as in
+\(lq\fRtty=\fR\(rq.
+.TP 6n
+uid=uid_t
+The real user ID of the user invoking
+\fBsudo\fR.
+.TP 6n
+umask=octal
+The invoking user's file creation mask.
+Only available starting with API version 1.10.
+.TP 6n
+user=string
+The name of the user invoking
+\fBsudo\fR.
+.PD 0
+.PP
+.RE
+.PD
+.TP 6n
+user_env
+The user's environment in the form of a
+\fRNULL\fR-terminated vector of
+\(lqname=value\(rq
+strings.
+.sp
+When parsing
+\fIuser_env\fR,
+the plugin should split on the
+\fBfirst\fR
+equal sign
+(\(oq=\(cq)
+since the
+\fIname\fR
+field will never include one
+itself but the
+\fIvalue\fR
+might.
+.PD 0
+.PP
+.RE
+.PD
+.TP 6n
+close
+.br
+.nf
+.RS 6n
+void (*close)(int exit_status, int error);
+.RE
+.fi
+.RS 6n
+.sp
+The
+\fBclose\fR()
+function is called when the command being run by
+\fBsudo\fR
+finishes.
+.sp
+The function arguments are as follows:
+.TP 6n
+exit_status
+The command's exit status, as returned by the
+wait(2)
+system call.
+The value of
+\fRexit_status\fR
+is undefined if
+\fRerror\fR
+is non-zero.
+.TP 6n
+error
+.br
+If the command could not be executed, this is set to the value of
+\fRerrno\fR
+set by the
+execve(2)
+system call.
+The plugin is responsible for displaying error information via the
+\fBconversation\fR()
+or
+\fBplugin_printf\fR()
+function.
+If the command was successfully executed, the value of
+\fRerror\fR
+is 0.
+.PP
+If no
+\fBclose\fR()
+function is defined, no I/O logging plugins are loaded,
+and neither the
+\fItimeout\fR
+not
+\fIuse_pty\fR
+options are set in the
+\fRcommand_info\fR
+list, the
+\fBsudo\fR
+front end may execute the command directly instead of running
+it as a child process.
+.RE
+.TP 6n
+show_version
+.nf
+.RS 6n
+int (*show_version)(int verbose);
+.RE
+.fi
+.RS 6n
+.sp
+The
+\fBshow_version\fR()
+function is called by
+\fBsudo\fR
+when the user specifies
+the
+\fB\-V\fR
+option.
+The plugin may display its version information to the user via the
+\fBconversation\fR()
+or
+\fBplugin_printf\fR()
+function using
+\fRSUDO_CONV_INFO_MSG\fR.
+If the user requests detailed version information, the verbose flag will be set.
+.sp
+Returns 1 on success, 0 on failure, \-1 if a general error occurred,
+or \-2 if there was a usage error, although the return value is currently
+ignored.
+.RE
+.TP 6n
+check_policy
+.nf
+.RS 6n
+int (*check_policy)(int argc, char * const argv[],
+ char *env_add[], char **command_info[],
+ char **argv_out[], char **user_env_out[]);
+.RE
+.fi
+.RS 6n
+.sp
+The
+\fBcheck_policy\fR()
+function is called by
+\fBsudo\fR
+to determine
+whether the user is allowed to run the specified commands.
+.sp
+If the
+\fIsudoedit\fR
+option was enabled in the
+\fIsettings\fR
+array
+passed to the
+\fBopen\fR()
+function, the user has requested
+\fIsudoedit\fR
+mode.
+\fIsudoedit\fR
+is a mechanism for editing one or more files
+where an editor is run with the user's credentials instead of with
+elevated privileges.
+\fBsudo\fR
+achieves this by creating user-writable
+temporary copies of the files to be edited and then overwriting the
+originals with the temporary copies after editing is complete.
+If the plugin supports
+\fIsudoedit\fR,
+it should choose the editor to be used, potentially from a variable
+in the user's environment, such as
+\fREDITOR\fR,
+and include it in
+\fIargv_out\fR
+(note that environment
+variables may include command line flags).
+The files to be edited should be copied from
+\fIargv\fR
+into
+\fIargv_out\fR,
+separated from the
+editor and its arguments by a
+\(lq\fR--\fR\(rq
+element.
+The
+\(lq\fR--\fR\(rq
+will
+be removed by
+\fBsudo\fR
+before the editor is executed.
+The plugin should also set
+\fIsudoedit=true\fR
+in the
+\fIcommand_info\fR
+list.
+.sp
+The
+\fBcheck_policy\fR()
+function returns 1 if the command is allowed,
+0 if not allowed, \-1 for a general error, or \-2 for a usage error
+or if
+\fIsudoedit\fR
+was specified but is unsupported by the plugin.
+In the latter case,
+\fBsudo\fR
+will print a usage message before it
+exits.
+If an error occurs, the plugin may optionally call the
+\fBconversation\fR()
+or
+\fBplugin_printf\fR()
+function with
+\fRSUDO_CONF_ERROR_MSG\fR
+to present additional error information to the user.
+.sp
+The function arguments are as follows:
+.TP 6n
+argc
+The number of elements in
+\fIargv\fR,
+not counting the final
+\fRNULL\fR
+pointer.
+.TP 6n
+argv
+The argument vector describing the command the user wishes to run,
+in the same form as what would be passed to the
+execve(2)
+system call.
+The vector is terminated by a
+\fRNULL\fR
+pointer.
+.TP 6n
+env_add
+Additional environment variables specified by the user on the command
+line in the form of a
+\fRNULL\fR-terminated
+vector of
+\(lqname=value\(rq
+strings.
+The plugin may reject the command if one or more variables
+are not allowed to be set, or it may silently ignore such variables.
+.sp
+When parsing
+\fIenv_add\fR,
+the plugin should split on the
+\fBfirst\fR
+equal sign
+(\(oq=\(cq)
+since the
+\fIname\fR
+field will never include one
+itself but the
+\fIvalue\fR
+might.
+.TP 6n
+command_info
+Information about the command being run in the form of
+\(lqname=value\(rq
+strings.
+These values are used by
+\fBsudo\fR
+to set the execution
+environment when running a command.
+The plugin is responsible for creating and populating the vector,
+which must be terminated with a
+\fRNULL\fR
+pointer.
+The following values are recognized by
+\fBsudo\fR:
+.PP
+.RS 6n
+.PD 0
+.TP 6n
+chroot=string
+The root directory to use when running the command.
+.PD
+.TP 6n
+closefrom=number
+If specified,
+\fBsudo\fR
+will close all files descriptors with a value
+of
+\fInumber\fR
+or higher.
+.TP 6n
+command=string
+Fully qualified path to the command to be executed.
+.TP 6n
+cwd=string
+The current working directory to change to when executing the command.
+.TP 6n
+exec_background=bool
+By default,
+\fBsudo\fR
+runs a command as the foreground process as long as
+\fBsudo\fR
+itself is running in the foreground.
+When
+\fIexec_background\fR
+is enabled and the command is being run in a pty (due to I/O logging
+or the
+\fIuse_pty\fR
+setting), the command will be run as a background process.
+Attempts to read from the controlling terminal (or to change terminal
+settings) will result in the command being suspended with the
+\fRSIGTTIN\fR
+signal (or
+\fRSIGTTOU\fR
+in the case of terminal settings).
+If this happens when
+\fBsudo\fR
+is a foreground process, the command will be granted the controlling terminal
+and resumed in the foreground with no user intervention required.
+The advantage of initially running the command in the background is that
+\fBsudo\fR
+need not read from the terminal unless the command explicitly requests it.
+Otherwise, any terminal input must be passed to the command, whether it
+has required it or not (the kernel buffers terminals so it is not possible
+to tell whether the command really wants the input).
+This is different from historic
+\fIsudo\fR
+behavior or when the command is not being run in a pty.
+.sp
+For this to work seamlessly, the operating system must support the
+automatic restarting of system calls.
+Unfortunately, not all operating systems do this by default,
+and even those that do may have bugs.
+For example, macOS fails to restart the
+\fBtcgetattr\fR()
+and
+\fBtcsetattr\fR()
+system calls (this is a bug in macOS).
+Furthermore, because this behavior depends on the command stopping with the
+\fRSIGTTIN\fR
+or
+\fRSIGTTOU\fR
+signals, programs that catch these signals and suspend themselves
+with a different signal (usually
+\fRSIGTOP\fR)
+will not be automatically foregrounded.
+Some versions of the linux
+su(1)
+command behave this way.
+Because of this, a plugin should not set
+\fIexec_background\fR
+unless it is explicitly enabled by the administrator and there should
+be a way to enabled or disable it on a per-command basis.
+.sp
+This setting has no effect unless I/O logging is enabled or
+\fIuse_pty\fR
+is enabled.
+.TP 6n
+execfd=number
+If specified,
+\fBsudo\fR
+will use the
+fexecve(2)
+system call to execute the command instead of
+execve(2).
+The specified
+\fInumber\fR
+must refer to an open file descriptor.
+.TP 6n
+iolog_compress=bool
+Set to true if the I/O logging plugins, if any, should compress the
+log data.
+This is a hint to the I/O logging plugin which may choose to ignore it.
+.TP 6n
+iolog_group=string
+The group that will own newly created I/O log files and directories.
+This is a hint to the I/O logging plugin which may choose to ignore it.
+.TP 6n
+iolog_mode=octal
+The file permission mode to use when creating I/O log files and directories.
+This is a hint to the I/O logging plugin which may choose to ignore it.
+.TP 6n
+iolog_user=string
+The user that will own newly created I/O log files and directories.
+This is a hint to the I/O logging plugin which may choose to ignore it.
+.TP 6n
+iolog_path=string
+Fully qualified path to the file or directory in which I/O log is
+to be stored.
+This is a hint to the I/O logging plugin which may choose to ignore it.
+If no I/O logging plugin is loaded, this setting has no effect.
+.TP 6n
+iolog_stdin=bool
+Set to true if the I/O logging plugins, if any, should log the
+standard input if it is not connected to a terminal device.
+This is a hint to the I/O logging plugin which may choose to ignore it.
+.TP 6n
+iolog_stdout=bool
+Set to true if the I/O logging plugins, if any, should log the
+standard output if it is not connected to a terminal device.
+This is a hint to the I/O logging plugin which may choose to ignore it.
+.TP 6n
+iolog_stderr=bool
+Set to true if the I/O logging plugins, if any, should log the
+standard error if it is not connected to a terminal device.
+This is a hint to the I/O logging plugin which may choose to ignore it.
+.TP 6n
+iolog_ttyin=bool
+Set to true if the I/O logging plugins, if any, should log all
+terminal input.
+This only includes input typed by the user and not from a pipe or
+redirected from a file.
+This is a hint to the I/O logging plugin which may choose to ignore it.
+.TP 6n
+iolog_ttyout=bool
+Set to true if the I/O logging plugins, if any, should log all
+terminal output.
+This only includes output to the screen, not output to a pipe or file.
+This is a hint to the I/O logging plugin which may choose to ignore it.
+.TP 6n
+login_class=string
+BSD
+login class to use when setting resource limits and nice value (optional).
+This option is only set on systems that support login classes.
+.TP 6n
+nice=int
+Nice value (priority) to use when executing the command.
+The nice value, if specified, overrides the priority associated with the
+\fIlogin_class\fR
+on
+BSD
+systems.
+.TP 6n
+noexec=bool
+If set, prevent the command from executing other programs.
+.TP 6n
+preserve_fds=list
+A comma-separated list of file descriptors that should be
+preserved, regardless of the value of the
+\fIclosefrom\fR
+setting.
+Only available starting with API version 1.5.
+.TP 6n
+preserve_groups=bool
+If set,
+\fBsudo\fR
+will preserve the user's group vector instead of
+initializing the group vector based on
+\fRrunas_user\fR.
+.TP 6n
+runas_egid=gid
+Effective group ID to run the command as.
+If not specified, the value of
+\fIrunas_gid\fR
+is used.
+.TP 6n
+runas_euid=uid
+Effective user ID to run the command as.
+If not specified, the value of
+\fIrunas_uid\fR
+is used.
+.TP 6n
+runas_gid=gid
+Group ID to run the command as.
+.TP 6n
+runas_groups=list
+The supplementary group vector to use for the command in the form
+of a comma-separated list of group IDs.
+If
+\fIpreserve_groups\fR
+is set, this option is ignored.
+.TP 6n
+runas_uid=uid
+User ID to run the command as.
+.TP 6n
+selinux_role=string
+SELinux role to use when executing the command.
+.TP 6n
+selinux_type=string
+SELinux type to use when executing the command.
+.TP 6n
+set_utmp=bool
+Create a utmp (or utmpx) entry when a pseudo-tty is allocated.
+By default, the new entry will be a copy of the user's existing utmp
+entry (if any), with the tty, time, type and pid fields updated.
+.TP 6n
+sudoedit=bool
+Set to true when in
+\fIsudoedit\fR
+mode.
+The plugin may enable
+\fIsudoedit\fR
+mode even if
+\fBsudo\fR
+was not invoked as
+\fBsudoedit\fR.
+This allows the plugin to perform command substitution and transparently
+enable
+\fIsudoedit\fR
+when the user attempts to run an editor.
+.TP 6n
+sudoedit_checkdir=bool
+Set to false to disable directory writability checks in
+\fBsudoedit\fR.
+By default,
+\fBsudoedit\fR
+1.8.16 and higher will check all directory components of the path to be
+edited for writability by the invoking user.
+Symbolic links will not be followed in writable directories and
+\fBsudoedit\fR
+will refuse to edit a file located in a writable directory.
+These restrictions are not enforced when
+\fBsudoedit\fR
+is run by root.
+The
+\fIsudoedit_follow\fR
+option can be set to false to disable this check.
+Only available starting with API version 1.8.
+.TP 6n
+sudoedit_follow=bool
+Set to true to allow
+\fBsudoedit\fR
+to edit files that are symbolic links.
+By default,
+\fBsudoedit\fR
+1.8.15 and higher will refuse to open a symbolic link.
+The
+\fIsudoedit_follow\fR
+option can be used to restore the older behavior and allow
+\fBsudoedit\fR
+to open symbolic links.
+Only available starting with API version 1.8.
+.TP 6n
+timeout=int
+Command timeout.
+If non-zero then when the timeout expires the command will be killed.
+.TP 6n
+umask=octal
+The file creation mask to use when executing the command.
+.TP 6n
+use_pty=bool
+Allocate a pseudo-tty to run the command in, regardless of whether
+or not I/O logging is in use.
+By default,
+\fBsudo\fR
+will only run
+the command in a pty when an I/O log plugin is loaded.
+.TP 6n
+utmp_user=string
+User name to use when constructing a new utmp (or utmpx) entry when
+\fIset_utmp\fR
+is enabled.
+This option can be used to set the user field in the utmp entry to
+the user the command runs as rather than the invoking user.
+If not set,
+\fBsudo\fR
+will base the new entry on
+the invoking user's existing entry.
+.PP
+Unsupported values will be ignored.
+.RE
+.TP 6n
+argv_out
+The
+\fRNULL\fR-terminated
+argument vector to pass to the
+execve(2)
+system call when executing the command.
+The plugin is responsible for allocating and populating the vector.
+.TP 6n
+user_env_out
+The
+\fRNULL\fR-terminated
+environment vector to use when executing the command.
+The plugin is responsible for allocating and populating the vector.
+.PD 0
+.PP
+.RE
+.PD
+.TP 6n
+list
+.nf
+.RS 6n
+int (*list)(int argc, char * const argv[],
+ int verbose, const char *list_user);
+.RE
+.fi
+.RS 6n
+.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
+\fBconversation\fR()
+or
+\fBplugin_printf\fR()
+function with
+\fRSUDO_CONF_ERROR_MSG\fR
+to present additional error information to
+the user.
+.sp
+Privileges should be output via the
+\fBconversation\fR()
+or
+\fBplugin_printf\fR()
+function using
+\fRSUDO_CONV_INFO_MSG\fR,
+.TP 6n
+verbose
+Flag indicating whether to list in verbose mode or not.
+.TP 6n
+list_user
+The name of a different user to list privileges for if the policy
+allows it.
+If
+\fRNULL\fR,
+the plugin should list the privileges of the invoking user.
+.TP 6n
+argc
+The number of elements in
+\fIargv\fR,
+not counting the final
+\fRNULL\fR
+pointer.
+.TP 6n
+argv
+If
+non-\fRNULL\fR,
+an argument vector describing a command the user
+wishes to check against the policy in the same form as what would
+be passed to the
+execve(2)
+system call.
+If the command is permitted by the policy, the fully-qualified path
+to the command should be displayed along with any command line arguments.
+.PD 0
+.PP
+.RE
+.PD
+.TP 6n
+validate
+.nf
+.RS 6n
+int (*validate)(void);
+.RE
+.fi
+.RS 6n
+.sp
+The
+\fBvalidate\fR()
+function is called when
+\fBsudo\fR
+is run with the
+\fB\-v\fR
+flag.
+For policy plugins such as
+\fBsudoers\fR
+that cache
+authentication credentials, this function will validate and cache
+the credentials.
+.sp
+The
+\fBvalidate\fR()
+function should be
+\fRNULL\fR
+if the plugin does not support credential caching.
+.sp
+Returns 1 on success, 0 on failure and \-1 on error.
+On error, the plugin may optionally call the
+\fBconversation\fR()
+or
+\fBplugin_printf\fR()
+function with
+\fRSUDO_CONF_ERROR_MSG\fR
+to present additional
+error information to the user.
+.RE
+.TP 6n
+invalidate
+.nf
+.RS 6n
+void (*invalidate)(int remove);
+.RE
+.fi
+.RS 6n
+.sp
+The
+\fBinvalidate\fR()
+function is called when
+\fBsudo\fR
+is called with
+the
+\fB\-k\fR
+or
+\fB\-K\fR
+flag.
+For policy plugins such as
+\fBsudoers\fR
+that
+cache authentication credentials, this function will invalidate the
+credentials.
+If the
+\fIremove\fR
+flag is set, the plugin may remove
+the credentials instead of simply invalidating them.
+.sp
+The
+\fBinvalidate\fR()
+function should be
+\fRNULL\fR
+if the plugin does not support credential caching.
+.RE
+.TP 6n
+init_session
+.nf
+.RS 6n
+int (*init_session)(struct passwd *pwd, char **user_envp[);
+.RE
+.fi
+.RS 6n
+.sp
+The
+\fBinit_session\fR()
+function is called before
+\fBsudo\fR
+sets up the
+execution environment for the command.
+It is run in the parent
+\fBsudo\fR
+process and before any uid or gid changes.
+This can be used to perform session setup that is not supported by
+\fIcommand_info\fR,
+such as opening the PAM session.
+The
+\fBclose\fR()
+function can be
+used to tear down the session that was opened by
+\fRinit_session\fR.
+.sp
+The
+\fIpwd\fR
+argument points to a passwd struct for the user the
+command will be run as if the uid the command will run as was found
+in the password database, otherwise it will be
+\fRNULL\fR.
+.sp
+The
+\fIuser_env\fR
+argument points to the environment the command will
+run in, in the form of a
+\fRNULL\fR-terminated
+vector of
+\(lqname=value\(rq
+strings.
+This is the same string passed back to the front end via
+the Policy Plugin's
+\fIuser_env_out\fR
+parameter.
+If the
+\fBinit_session\fR()
+function needs to modify the user environment, it should update the
+pointer stored in
+\fIuser_env\fR.
+The expected use case is to merge the contents of the PAM environment
+(if any) with the contents of
+\fIuser_env\fR.
+NOTE: the
+\fIuser_env\fR
+parameter is only available
+starting with API version 1.2.
+A plugin
+\fBmust\fR
+check the API
+version specified by the
+\fBsudo\fR
+front end before using
+\fIuser_env\fR.
+Failure to do so may result in a crash.
+.sp
+Returns 1 on success, 0 on failure and \-1 on error.
+On error, the plugin may optionally call the
+\fBconversation\fR()
+or
+\fBplugin_printf\fR()
+function with
+\fRSUDO_CONF_ERROR_MSG\fR
+to present additional
+error information to the user.
+.RE
+.TP 6n
+register_hooks
+.nf
+.RS 6n
+void (*register_hooks)(int version,
+ int (*register_hook)(struct sudo_hook *hook));
+.RE
+.fi
+.RS 6n
+.sp
+The
+\fBregister_hooks\fR()
+function is called by the sudo front end to
+register any hooks the plugin needs.
+If the plugin does not support hooks,
+\fRregister_hooks\fR
+should be set to the
+\fRNULL\fR
+pointer.
+.sp
+The
+\fIversion\fR
+argument describes the version of the hooks API
+supported by the
+\fBsudo\fR
+front end.
+.sp
+The
+\fBregister_hook\fR()
+function should be used to register any supported
+hooks the plugin needs.
+It returns 0 on success, 1 if the hook type is not supported and \-1
+if the major version in
+\fRstruct hook\fR
+does not match the front end's major hook API version.
+.sp
+See the
+\fIHook function API\fR
+section below for more information
+about hooks.
+.sp
+NOTE: the
+\fBregister_hooks\fR()
+function is only available starting
+with API version 1.2.
+If the
+\fBsudo\fR
+front end doesn't support API
+version 1.2 or higher,
+\fRregister_hooks\fR
+will not be called.
+.RE
+.TP 6n
+deregister_hooks
+.nf
+.RS 6n
+void (*deregister_hooks)(int version,
+ int (*deregister_hook)(struct sudo_hook *hook));
+.RE
+.fi
+.RS 6n
+.sp
+The
+\fBderegister_hooks\fR()
+function is called by the sudo front end
+to deregister any hooks the plugin has registered.
+If the plugin does not support hooks,
+\fRderegister_hooks\fR
+should be set to the
+\fRNULL\fR
+pointer.
+.sp
+The
+\fIversion\fR
+argument describes the version of the hooks API
+supported by the
+\fBsudo\fR
+front end.
+.sp
+The
+\fBderegister_hook\fR()
+function should be used to deregister any
+hooks that were put in place by the
+\fBregister_hook\fR()
+function.
+If the plugin tries to deregister a hook that the front end does not support,
+\fRderegister_hook\fR
+will return an error.
+.sp
+See the
+\fIHook function API\fR
+section below for more information
+about hooks.
+.sp
+NOTE: the
+\fBderegister_hooks\fR()
+function is only available starting
+with API version 1.2.
+If the
+\fBsudo\fR
+front end doesn't support API
+version 1.2 or higher,
+\fRderegister_hooks\fR
+will not be called.
+.RE
+.PP
+\fIPolicy Plugin Version Macros\fR
+.nf
+.sp
+.RS 0n
+/* Plugin API version major/minor. */
+#define SUDO_API_VERSION_MAJOR 1
+#define SUDO_API_VERSION_MINOR 13
+#define SUDO_API_MKVERSION(x, y) ((x << 16) | y)
+#define SUDO_API_VERSION SUDO_API_MKVERSION(SUDO_API_VERSION_MAJOR,\e
+ SUDO_API_VERSION_MINOR)
+
+/* Getters and setters for API version */
+#define SUDO_API_VERSION_GET_MAJOR(v) ((v) >> 16)
+#define SUDO_API_VERSION_GET_MINOR(v) ((v) & 0xffff)
+#define SUDO_API_VERSION_SET_MAJOR(vp, n) do { \e
+ *(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \e
+} while(0)
+#define SUDO_API_VERSION_SET_MINOR(vp, n) do { \e
+ *(vp) = (*(vp) & 0xffff0000) | (n); \e
+} while(0)
+.RE
+.fi
+.SS "I/O plugin API"
+.nf
+.RS 0n
+struct io_plugin {
+#define SUDO_IO_PLUGIN 2
+ unsigned int type; /* always SUDO_IO_PLUGIN */
+ unsigned int version; /* always SUDO_API_VERSION */
+ int (*open)(unsigned int version, sudo_conv_t conversation,
+ sudo_printf_t plugin_printf, char * const settings[],
+ char * const user_info[], char * const command_info[],
+ int argc, char * const argv[], char * const user_env[],
+ char * const plugin_options[]);
+ void (*close)(int exit_status, int error); /* wait status or error */
+ int (*show_version)(int verbose);
+ int (*log_ttyin)(const char *buf, unsigned int len);
+ int (*log_ttyout)(const char *buf, unsigned int len);
+ int (*log_stdin)(const char *buf, unsigned int len);
+ int (*log_stdout)(const char *buf, unsigned int len);
+ int (*log_stderr)(const char *buf, unsigned int len);
+ void (*register_hooks)(int version,
+ int (*register_hook)(struct sudo_hook *hook));
+ void (*deregister_hooks)(int version,
+ int (*deregister_hook)(struct sudo_hook *hook));
+ int (*change_winsize)(unsigned int lines, unsigned int cols);
+ int (*log_suspend)(int signo);
+};
+.RE
+.fi
+.PP
+When an I/O plugin is loaded,
+\fBsudo\fR
+runs the command in a pseudo-tty.
+This makes it possible to log the input and output from the user's
+session.
+If any of the standard input, standard output or standard error do not
+correspond to a tty,
+\fBsudo\fR
+will open a pipe to capture
+the I/O for logging before passing it on.
+.PP
+The log_ttyin function receives the raw user input from the terminal
+device (note that this will include input even when echo is disabled,
+such as when a password is read).
+The log_ttyout function receives output from the pseudo-tty that is
+suitable for replaying the user's session at a later time.
+The
+\fBlog_stdin\fR(),
+\fBlog_stdout\fR()
+and
+\fBlog_stderr\fR()
+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
+\fRNULL\fR
+pointer if no logging is to be performed.
+If the open function returns 0, no I/O will be sent to the plugin.
+.PP
+If a logging function returns an error
+(\-1),
+the running command will be terminated and all of the plugin's logging
+functions will be disabled.
+Other I/O logging plugins will still receive any remaining
+input or output that has not yet been processed.
+.PP
+If an input logging function rejects the data by returning 0, the
+command will be terminated and the data will not be passed to the
+command, though it will still be sent to any other I/O logging plugins.
+If an output logging function rejects the data by returning 0, the
+command will be terminated and the data will not be written to the
+terminal, though it will still be sent to any other I/O logging plugins.
+.PP
+The io_plugin struct has the following fields:
+.TP 6n
+type
+The
+\fRtype\fR
+field should always be set to
+\fRSUDO_IO_PLUGIN\fR.
+.TP 6n
+version
+The
+\fRversion\fR
+field should be set to
+\fRSUDO_API_VERSION\fR.
+.sp
+This allows
+\fBsudo\fR
+to determine the API version the plugin was
+built against.
+.TP 6n
+open
+.nf
+.RS 6n
+int (*open)(unsigned int version, sudo_conv_t conversation,
+ sudo_printf_t plugin_printf, char * const settings[],
+ char * const user_info[], char * const command_info[],
+ int argc, char * const argv[], char * const user_env[],
+ char * const plugin_options[]);
+.RE
+.fi
+.RS 6n
+.sp
+The
+\fBopen\fR()
+function is run before the
+\fBlog_ttyin\fR(),
+\fBlog_ttyout\fR(),
+\fBlog_stdin\fR(),
+\fBlog_stdout\fR(),
+\fBlog_stderr\fR(),
+\fBlog_suspend\fR(),
+\fBchange_winsize\fR(),
+or
+\fBshow_version\fR()
+functions are called.
+It is only called if the version is being requested or if the
+policy plugin's
+\fBcheck_policy\fR()
+function has returned successfully.
+It returns 1 on success, 0 on failure, \-1 if a general error occurred,
+or \-2 if there was a usage error.
+In the latter case,
+\fBsudo\fR
+will print a usage message before it exits.
+If an error occurs, the plugin may optionally call the
+\fBconversation\fR()
+or
+\fBplugin_printf\fR()
+function with
+\fRSUDO_CONF_ERROR_MSG\fR
+to present
+additional error information to the user.
+.sp
+The function arguments are as follows:
+.TP 6n
+version
+The version passed in by
+\fBsudo\fR
+allows the plugin to determine the
+major and minor version number of the plugin API supported by
+\fBsudo\fR.
+.TP 6n
+conversation
+A pointer to the
+\fBconversation\fR()
+function that may be used by the
+\fBshow_version\fR()
+function to display version information (see
+\fBshow_version\fR()
+below).
+The
+\fBconversation\fR()
+function may also be used to display additional error message to the user.
+The
+\fBconversation\fR()
+function returns 0 on success and \-1 on failure.
+.TP 6n
+plugin_printf
+A pointer to a
+\fBprintf\fR()-style
+function that may be used by the
+\fBshow_version\fR()
+function to display version information (see
+show_version below).
+The
+\fBplugin_printf\fR()
+function may also be used to display additional error message to the user.
+The
+\fBplugin_printf\fR()
+function returns number of characters printed on success and \-1 on failure.
+.TP 6n
+settings
+A vector of user-supplied
+\fBsudo\fR
+settings in the form of
+\(lqname=value\(rq
+strings.
+The vector is terminated by a
+\fRNULL\fR
+pointer.
+These settings correspond to flags the user specified when running
+\fBsudo\fR.
+As such, they will only be present when the corresponding flag has
+been specified on the command line.
+.sp
+When parsing
+\fIsettings\fR,
+the plugin should split on the
+\fBfirst\fR
+equal sign
+(\(oq=\(cq)
+since the
+\fIname\fR
+field will never include one
+itself but the
+\fIvalue\fR
+might.
+.sp
+See the
+\fIPolicy plugin API\fR
+section for a list of all possible settings.
+.TP 6n
+user_info
+A vector of information about the user running the command in the form of
+\(lqname=value\(rq
+strings.
+The vector is terminated by a
+\fRNULL\fR
+pointer.
+.sp
+When parsing
+\fIuser_info\fR,
+the plugin should split on the
+\fBfirst\fR
+equal sign
+(\(oq=\(cq)
+since the
+\fIname\fR
+field will never include one
+itself but the
+\fIvalue\fR
+might.
+.sp
+See the
+\fIPolicy plugin API\fR
+section for a list of all possible strings.
+.TP 6n
+argc
+The number of elements in
+\fIargv\fR,
+not counting the final
+\fRNULL\fR
+pointer.
+It can be zero, when
+\fBsudo\fR
+is called with
+\fB\-V\fR.
+.TP 6n
+argv
+If
+non-\fRNULL\fR,
+an argument vector describing a command the user
+wishes to run in the same form as what would be passed to the
+execve(2)
+system call.
+.TP 6n
+user_env
+The user's environment in the form of a
+\fRNULL\fR-terminated
+vector of
+\(lqname=value\(rq
+strings.
+.sp
+When parsing
+\fIuser_env\fR,
+the plugin should split on the
+\fBfirst\fR
+equal sign
+(\(oq=\(cq)
+since the
+\fIname\fR
+field will never include one
+itself but the
+\fIvalue\fR
+might.
+.TP 6n
+plugin_options
+Any (non-comment) strings immediately after the plugin path are
+treated as arguments to the plugin.
+These arguments are split on a white space boundary and are passed to
+the plugin in the form of a
+\fRNULL\fR-terminated
+array of strings.
+If no arguments were specified,
+\fIplugin_options\fR
+will be the
+\fRNULL\fR
+pointer.
+.sp
+NOTE: the
+\fIplugin_options\fR
+parameter is only available starting with
+API version 1.2.
+A plugin
+\fBmust\fR
+check the API version specified
+by the
+\fBsudo\fR
+front end before using
+\fIplugin_options\fR.
+Failure to do so may result in a crash.
+.PD 0
+.PP
+.RE
+.PD
+.TP 6n
+close
+.br
+.nf
+.RS 6n
+void (*close)(int exit_status, int error);
+.RE
+.fi
+.RS 6n
+.sp
+The
+\fBclose\fR()
+function is called when the command being run by
+\fBsudo\fR
+finishes.
+.sp
+The function arguments are as follows:
+.TP 6n
+exit_status
+The command's exit status, as returned by the
+wait(2)
+system call.
+The value of
+\fRexit_status\fR
+is undefined if
+\fRerror\fR
+is non-zero.
+.TP 6n
+error
+.br
+If the command could not be executed, this is set to the value of
+\fRerrno\fR
+set by the
+execve(2)
+system call.
+If the command was successfully executed, the value of
+\fRerror\fR
+is 0.
+.PD 0
+.PP
+.RE
+.PD
+.TP 6n
+show_version
+.nf
+.RS 6n
+int (*show_version)(int verbose);
+.RE
+.fi
+.RS 6n
+.sp
+The
+\fBshow_version\fR()
+function is called by
+\fBsudo\fR
+when the user specifies
+the
+\fB\-V\fR
+option.
+The plugin may display its version information to the user via the
+\fBconversation\fR()
+or
+\fBplugin_printf\fR()
+function using
+\fRSUDO_CONV_INFO_MSG\fR.
+If the user requests detailed version information, the verbose flag will be set.
+.sp
+Returns 1 on success, 0 on failure, \-1 if a general error occurred,
+or \-2 if there was a usage error, although the return value is currently
+ignored.
+.RE
+.TP 6n
+log_ttyin
+.nf
+.RS 6n
+int (*log_ttyin)(const char *buf, unsigned int len);
+.RE
+.fi
+.RS 6n
+.sp
+The
+\fBlog_ttyin\fR()
+function is called whenever data can be read from
+the user but before it is passed to the running command.
+This allows the plugin to reject data if it chooses to (for instance
+if the input contains banned content).
+Returns 1 if the data should be passed to the command, 0 if the data
+is rejected (which will terminate the running command) or \-1 if an
+error occurred.
+.sp
+The function arguments are as follows:
+.TP 6n
+buf
+The buffer containing user input.
+.TP 6n
+len
+The length of
+\fIbuf\fR
+in bytes.
+.PD 0
+.PP
+.RE
+.PD
+.TP 6n
+log_ttyout
+.nf
+.RS 6n
+int (*log_ttyout)(const char *buf, unsigned int len);
+.RE
+.fi
+.RS 6n
+.sp
+The
+\fBlog_ttyout\fR()
+function is called whenever data can be read from
+the command but before it is written to the user's terminal.
+This allows the plugin to reject data if it chooses to (for instance
+if the output contains banned content).
+Returns 1 if the data should be passed to the user, 0 if the data is rejected
+(which will terminate the running command) or \-1 if an error occurred.
+.sp
+The function arguments are as follows:
+.TP 6n
+buf
+The buffer containing command output.
+.TP 6n
+len
+The length of
+\fIbuf\fR
+in bytes.
+.PD 0
+.PP
+.RE
+.PD
+.TP 6n
+log_stdin
+.nf
+.RS 6n
+int (*log_stdin)(const char *buf, unsigned int len);
+.RE
+.fi
+.RS 6n
+.sp
+The
+\fBlog_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 1 if the data should be passed to the command, 0 if the data is
+rejected (which will terminate the running command) or \-1 if an error occurred.
+.sp
+The function arguments are as follows:
+.TP 6n
+buf
+The buffer containing user input.
+.TP 6n
+len
+The length of
+\fIbuf\fR
+in bytes.
+.PD 0
+.PP
+.RE
+.PD
+.TP 6n
+log_stdout
+.nf
+.RS 6n
+int (*log_stdout)(const char *buf, unsigned int len);
+.RE
+.fi
+.RS 6n
+.sp
+The
+\fBlog_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 1 if the data should be passed to the user, 0 if the data is
+rejected (which will terminate the running command) or \-1 if an error occurred.
+.sp
+The function arguments are as follows:
+.TP 6n
+buf
+The buffer containing command output.
+.TP 6n
+len
+The length of
+\fIbuf\fR
+in bytes.
+.PD 0
+.PP
+.RE
+.PD
+.TP 6n
+log_stderr
+.nf
+.RS 6n
+int (*log_stderr)(const char *buf, unsigned int len);
+.RE
+.fi
+.RS 6n
+.sp
+The
+\fBlog_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 1 if the data should be passed to the user, 0 if the data is
+rejected (which will terminate the running command) or \-1 if an error occurred.
+.sp
+The function arguments are as follows:
+.TP 6n
+buf
+The buffer containing command output.
+.TP 6n
+len
+The length of
+\fIbuf\fR
+in bytes.
+.PD 0
+.PP
+.RE
+.PD
+.TP 6n
+register_hooks
+See the
+\fIPolicy plugin API\fR
+section for a description of
+\fRregister_hooks\fR.
+.TP 6n
+deregister_hooks
+See the
+\fIPolicy plugin API\fR
+section for a description of
+\fRderegister_hooks\fR.
+.TP 6n
+change_winsize
+.nf
+.RS 6n
+int (*change_winsize)(unsigned int lines, unsigned int cols);
+.RE
+.fi
+.RS 6n
+.sp
+The
+\fBchange_winsize\fR()
+function is called whenever the window size of the terminal changes from
+the initial values specified in the
+\fRuser_info\fR
+list.
+Returns \-1 if an error occurred, in which case no further calls to
+\fBchange_winsize\fR()
+will be made,
+.RE
+.TP 6n
+log_suspend
+.nf
+.RS 6n
+int (*log_suspend)(int signo);
+.RE
+.fi
+.RS 6n
+.sp
+The
+\fBlog_suspend\fR()
+function is called whenever a command is suspended or resumed.
+The
+\fIsigno\fR
+argument is either the signal that caused the command to be suspended or
+\fRSIGCONT\fR
+if the command was resumed.
+Logging this information makes it possible to skip the period of time when
+the command was suspended during playback of a session.
+Returns \-1 if an error occurred, in which case no further calls to
+\fBlog_suspend\fR()
+will be made,
+.RE
+.PP
+\fII/O Plugin Version Macros\fR
+.PP
+Same as for the
+\fIPolicy plugin API\fR.
+.SS "Signal handlers"
+The
+\fBsudo\fR
+front end installs default signal handlers to trap common signals
+while the plugin functions are run.
+The following signals are trapped by default before the command is
+executed:
+.TP 3n
+\fB\(bu\fR
+\fRSIGALRM\fR
+.PD 0
+.TP 3n
+\fB\(bu\fR
+\fRSIGHUP\fR
+.TP 3n
+\fB\(bu\fR
+\fRSIGINT\fR
+.TP 3n
+\fB\(bu\fR
+\fRSIGPIPE\fR
+.TP 3n
+\fB\(bu\fR
+\fRSIGQUIT\fR
+.TP 3n
+\fB\(bu\fR
+\fRSIGTERM\fR
+.TP 3n
+\fB\(bu\fR
+\fRSIGTSTP\fR
+.TP 3n
+\fB\(bu\fR
+\fRSIGUSR1\fR
+.TP 3n
+\fB\(bu\fR
+\fRSIGUSR2\fR
+.PD
+.PP
+If a fatal signal is received before the command is executed,
+\fBsudo\fR
+will call the plugin's
+\fBclose\fR()
+function with an exit status of 128 plus the value of the signal
+that was received.
+This allows for consistent logging of commands killed by a signal
+for plugins that log such information in their
+\fBclose\fR()
+function.
+An exception to this is
+\fRSIGPIPE\fR,
+which is ignored until the command is executed.
+.PP
+A plugin may temporarily install its own signal handlers but must
+restore the original handler before the plugin function returns.
+.SS "Hook function API"
+Beginning with plugin API version 1.2, it is possible to install
+hooks for certain functions called by the
+\fBsudo\fR
+front end.
+.PP
+Currently, the only supported hooks relate to the handling of
+environment variables.
+Hooks can be used to intercept attempts to get, set, or remove
+environment variables so that these changes can be reflected in
+the version of the environment that is used to execute a command.
+A future version of the API will support hooking internal
+\fBsudo\fR
+front end functions as well.
+.PP
+\fIHook structure\fR
+.PP
+Hooks in
+\fBsudo\fR
+are described by the following structure:
+.nf
+.sp
+.RS 0n
+typedef int (*sudo_hook_fn_t)();
+
+struct sudo_hook {
+ unsigned int hook_version;
+ unsigned int hook_type;
+ sudo_hook_fn_t hook_fn;
+ void *closure;
+};
+.RE
+.fi
+.PP
+The
+\fRsudo_hook\fR
+structure has the following fields:
+.TP 6n
+hook_version
+The
+\fRhook_version\fR
+field should be set to
+\fRSUDO_HOOK_VERSION\fR.
+.TP 6n
+hook_type
+The
+\fRhook_type\fR
+field may be one of the following supported hook types:
+.PP
+.RS 6n
+.PD 0
+.TP 6n
+\fRSUDO_HOOK_SETENV\fR
+The C library
+setenv(3)
+function.
+Any registered hooks will run before the C library implementation.
+The
+\fRhook_fn\fR
+field should
+be a function that matches the following typedef:
+.nf
+.sp
+.RS 6n
+typedef int (*sudo_hook_fn_setenv_t)(const char *name,
+ const char *value, int overwrite, void *closure);
+.RE
+.fi
+.RS 6n
+.sp
+If the registered hook does not match the typedef the results are
+unspecified.
+.RE
+.PD
+.TP 6n
+\fRSUDO_HOOK_UNSETENV\fR
+The C library
+unsetenv(3)
+function.
+Any registered hooks will run before the C library implementation.
+The
+\fRhook_fn\fR
+field should
+be a function that matches the following typedef:
+.nf
+.sp
+.RS 6n
+typedef int (*sudo_hook_fn_unsetenv_t)(const char *name,
+ void *closure);
+.RE
+.fi
+.TP 6n
+\fRSUDO_HOOK_GETENV\fR
+The C library
+getenv(3)
+function.
+Any registered hooks will run before the C library implementation.
+The
+\fRhook_fn\fR
+field should
+be a function that matches the following typedef:
+.nf
+.sp
+.RS 6n
+typedef int (*sudo_hook_fn_getenv_t)(const char *name,
+ char **value, void *closure);
+.RE
+.fi
+.RS 6n
+.sp
+If the registered hook does not match the typedef the results are
+unspecified.
+.RE
+.TP 6n
+\fRSUDO_HOOK_PUTENV\fR
+The C library
+putenv(3)
+function.
+Any registered hooks will run before the C library implementation.
+The
+\fRhook_fn\fR
+field should
+be a function that matches the following typedef:
+.nf
+.sp
+.RS 6n
+typedef int (*sudo_hook_fn_putenv_t)(char *string,
+ void *closure);
+.RE
+.fi
+.RS 6n
+.sp
+If the registered hook does not match the typedef the results are
+unspecified.
+.RE
+.PD 0
+.PP
+.RE
+.PD
+.TP 6n
+hook_fn
+sudo_hook_fn_t hook_fn;
+.sp
+The
+\fRhook_fn\fR
+field should be set to the plugin's hook implementation.
+The actual function arguments will vary depending on the
+\fRhook_type\fR
+(see
+\fRhook_type\fR
+above).
+In all cases, the
+\fRclosure\fR
+field of
+\fRstruct sudo_hook\fR
+is passed as the last function parameter.
+This can be used to pass arbitrary data to the plugin's hook implementation.
+.sp
+The function return value may be one of the following:
+.PP
+.RS 6n
+.PD 0
+.TP 6n
+\fRSUDO_HOOK_RET_ERROR\fR
+The hook function encountered an error.
+.PD
+.TP 6n
+\fRSUDO_HOOK_RET_NEXT\fR
+The hook completed without error, go on to the next hook (including
+the native implementation if applicable).
+For example, a
+getenv(3)
+hook might return
+\fRSUDO_HOOK_RET_NEXT\fR
+if the specified variable was not found in the private copy of the environment.
+.TP 6n
+\fRSUDO_HOOK_RET_STOP\fR
+The hook completed without error, stop processing hooks for this invocation.
+This can be used to replace the native implementation.
+For example, a
+\fRsetenv\fR
+hook that operates on a private copy of
+the environment but leaves
+\fRenviron\fR
+unchanged.
+.PD 0
+.PP
+.RE
+.PD
+.PP
+Note that it is very easy to create an infinite loop when hooking
+C library functions.
+For example, a
+getenv(3)
+hook that calls the
+snprintf(3)
+function may create a loop if the
+snprintf(3)
+implementation calls
+getenv(3)
+to check the locale.
+To prevent this, you may wish to use a static variable in the hook
+function to guard against nested calls.
+For example:
+.nf
+.sp
+.RS 0n
+static int in_progress = 0; /* avoid recursion */
+if (in_progress)
+ return SUDO_HOOK_RET_NEXT;
+in_progress = 1;
+\&...
+in_progress = 0;
+return SUDO_HOOK_RET_STOP;
+.RE
+.fi
+.PP
+\fIHook API Version Macros\fR
+.nf
+.sp
+.RS 0n
+/* Hook API version major/minor */
+#define SUDO_HOOK_VERSION_MAJOR 1
+#define SUDO_HOOK_VERSION_MINOR 0
+#define SUDO_HOOK_VERSION SUDO_API_MKVERSION(SUDO_HOOK_VERSION_MAJOR,\e
+ SUDO_HOOK_VERSION_MINOR)
+.RE
+.fi
+.PP
+For getters and setters see the
+\fIPolicy plugin API\fR.
+.SS "Remote command execution"
+The
+\fBsudo\fR
+front end does not have native support for running remote commands.
+However, starting with
+\fBsudo\fR
+1.8.8, the
+\fB\-h\fR
+option may be used to specify a remote host that is passed
+to the policy plugin.
+A plugin may also accept a
+\fIrunas_user\fR
+in the form of
+\(lquser@hostname\(rq
+which will work with older versions of
+\fBsudo\fR.
+It is anticipated that remote commands will be supported by executing a
+\(lqhelper\(rq
+program.
+The policy plugin should setup the execution environment such that the
+\fBsudo\fR
+front end will run the helper which, in turn, will connect to the
+remote host and run the command.
+.PP
+For example, the policy plugin could utilize
+\fBssh\fR
+to perform remote command execution.
+The helper program would be responsible for running
+\fBssh\fR
+with the proper options to use a private key or certificate
+that the remote host will accept and run a program
+on the remote host that would setup the execution environment
+accordingly.
+.PP
+Note that remote
+\fBsudoedit\fR
+functionality must be handled by the policy plugin, not
+\fBsudo\fR
+itself as the front end has no knowledge that a remote command is
+being executed.
+This may be addressed in a future revision of the plugin API.
+.SS "Conversation API"
+If the plugin needs to interact with the user, it may do so via the
+\fBconversation\fR()
+function.
+A plugin should not attempt to read directly from the standard input
+or the user's tty (neither of which are guaranteed to exist).
+The caller must include a trailing newline in
+\fRmsg\fR
+if one is to be printed.
+.PP
+A
+\fBprintf\fR()-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
+\fIConversation function structures\fR
+.PP
+The conversation function takes as arguments pointers to the following
+structures:
+.nf
+.sp
+.RS 0n
+struct sudo_conv_message {
+#define SUDO_CONV_PROMPT_ECHO_OFF 0x0001 /* do not echo user input */
+#define SUDO_CONV_PROMPT_ECHO_ON 0x0002 /* echo user input */
+#define SUDO_CONV_ERROR_MSG 0x0003 /* error message */
+#define SUDO_CONV_INFO_MSG 0x0004 /* informational message */
+#define SUDO_CONV_PROMPT_MASK 0x0005 /* mask user input */
+#define SUDO_CONV_PROMPT_ECHO_OK 0x1000 /* flag: allow echo if no tty */
+#define SUDO_CONV_PREFER_TTY 0x2000 /* flag: use tty if possible */
+ int msg_type;
+ int timeout;
+ const char *msg;
+};
+
+#define SUDO_CONV_REPL_MAX 255
+
+struct sudo_conv_reply {
+ char *reply;
+};
+
+typedef int (*sudo_conv_callback_fn_t)(int signo, void *closure);
+struct sudo_conv_callback {
+ unsigned int version;
+ void *closure;
+ sudo_conv_callback_fn_t on_suspend;
+ sudo_conv_callback_fn_t on_resume;
+};
+.RE
+.fi
+.PP
+Pointers to the
+\fBconversation\fR()
+and
+\fBprintf\fR()-style
+functions are passed
+in to the plugin's
+\fBopen\fR()
+function when the plugin is initialized.
+The following type definitions can be used in the declaration of the
+\fBopen\fR()
+function:
+.nf
+.sp
+.RS 0n
+typedef int (*sudo_conv_t)(int num_msgs,
+ const struct sudo_conv_message msgs[],
+ struct sudo_conv_reply replies[],
+ struct sudo_conv_callback *callback);
+
+typedef int (*sudo_printf_t)(int msg_type, const char *fmt, ...);
+.RE
+.fi
+.PP
+To use the
+\fBconversation\fR()
+function, the plugin must pass an array of
+\fRsudo_conv_message\fR
+and
+\fRsudo_conv_reply\fR
+structures.
+There must be a
+\fRstruct sudo_conv_message\fR
+and
+\fRstruct sudo_conv_reply\fR
+for
+each message in the conversation, that is, both arrays must have the same
+number of elements.
+Each
+\fRstruct sudo_conv_reply\fR
+must have its
+\fIreply\fR
+member initialized to
+\fRNULL\fR.
+The
+\fRstruct sudo_conv_callback\fR
+pointer, if not
+\fRNULL\fR,
+should contain function pointers to be called when the
+\fBsudo\fR
+process is suspended and/or resumed during conversation input.
+The
+\fIon_suspend\fR
+and
+\fIon_resume\fR
+functions are called with the signal that caused
+\fBsudo\fR
+to be suspended and the
+\fIclosure\fR
+pointer from the
+\fRstruct sudo_conv_callback\fR.
+These functions should return 0 on success and \-1 on error.
+On error, the conversation will end and the conversation function
+will return a value of \-1.
+The intended use is to allow the plugin to release resources, such as locks,
+that should not be held indefinitely while suspended and then reacquire them
+when the process is resumed.
+Note that the functions are not actually invoked from within a signal handler.
+.PP
+The
+\fImsg_type\fR
+must be set to one of the following values:
+.TP 6n
+SUDO_CONV_PROMPT_ECHO_OFF
+Prompt the user for input with echo disabled;
+this is generally used for passwords.
+The reply will be stored in the
+\fIreplies\fR
+array, and it will never be
+\fRNULL\fR.
+.TP 6n
+SUDO_CONV_PROMPT_ECHO_ON
+Prompt the user for input with echo enabled.
+The reply will be stored in the
+\fIreplies\fR
+array, and it will never be
+\fRNULL\fR.
+.TP 6n
+SUDO_CONV_ERROR_MSG
+Display an error message.
+The message is written to the standard error unless the
+\fRSUDO_CONV_PREFER_TTY\fR
+flag is set, in which case it is written to the user's terminal if possible.
+.TP 6n
+SUDO_CONV_INFO_MSG
+Display a message.
+The message is written to the standard output unless the
+\fRSUDO_CONV_PREFER_TTY\fR
+flag is set, in which case it is written to the user's terminal if possible.
+.TP 6n
+SUDO_CONV_PROMPT_MASK
+Prompt the user for input but echo an asterisk character for each
+character read.
+The reply will be stored in the
+\fIreplies\fR
+array, and it will never be
+\fRNULL\fR.
+This can be used to provide visual feedback to the user while reading
+sensitive information that should not be displayed.
+.PP
+In addition to the above values, the following flag bits may also be set:
+.TP 6n
+SUDO_CONV_PROMPT_ECHO_OK
+Allow input to be read when echo cannot be disabled
+when the message type is
+\fRSUDO_CONV_PROMPT_ECHO_OFF\fR
+or
+\fRSUDO_CONV_PROMPT_MASK\fR.
+By default,
+\fBsudo\fR
+will refuse to read input if the echo cannot be disabled for those
+message types.
+.TP 6n
+SUDO_CONV_PREFER_TTY
+When displaying a message via
+\fRSUDO_CONV_ERROR_MSG\fR
+or
+\fRSUDO_CONV_INFO_MSG\fR,
+try to write the message to the user's terminal.
+If the terminal is unavailable, the standard error or standard output
+will be used, depending upon whether
+The user's terminal is always used when possible for input,
+this flag is only used for output.
+\fRSUDO_CONV_ERROR_MSG\fR
+or
+\fRSUDO_CONV_INFO_MSG\fR
+was used.
+.PP
+The
+\fItimeout\fR
+in seconds until the prompt will wait for no more input.
+A zero value implies an infinite timeout.
+.PP
+The plugin is responsible for freeing the reply buffer located in each
+\fRstruct sudo_conv_reply\fR,
+if it is not
+\fRNULL\fR.
+\fRSUDO_CONV_REPL_MAX\fR
+represents the maximum length of the reply buffer (not including
+the trailing NUL character).
+In practical terms, this is the longest password
+\fBsudo\fR
+will support.
+It is also useful as a maximum value for the
+\fBmemset_s\fR()
+function when clearing passwords filled in by the conversation function.
+.PP
+The
+\fBprintf\fR()-style
+function uses the same underlying mechanism as the
+\fBconversation\fR()
+function but only supports
+\fRSUDO_CONV_INFO_MSG\fR
+and
+\fRSUDO_CONV_ERROR_MSG\fR
+for the
+\fImsg_type\fR
+parameter.
+It can be more convenient than using the
+\fBconversation\fR()
+function if no user reply is needed and supports standard
+\fBprintf\fR()
+escape sequences.
+.PP
+See the sample plugin for an example of the
+\fBconversation\fR()
+function usage.
+.SS "Sudoers group plugin API"
+The
+\fBsudoers\fR
+plugin supports its own plugin interface to allow non-Unix
+group lookups.
+This can be used to query a group source other than the standard Unix
+group database.
+Two sample group plugins are bundled with
+\fBsudo\fR,
+\fIgroup_file\fR
+and
+\fIsystem_group\fR,
+are detailed in
+sudoers(@mansectform@).
+Third party group plugins include a QAS AD plugin available from Quest Software.
+.PP
+A group plugin must declare and populate a
+\fRsudoers_group_plugin\fR
+struct in the global scope.
+This structure contains pointers to the functions that implement plugin
+initialization, cleanup and group lookup.
+.nf
+.sp
+.RS 0n
+struct sudoers_group_plugin {
+ unsigned int version;
+ int (*init)(int version, sudo_printf_t sudo_printf,
+ char *const argv[]);
+ void (*cleanup)(void);
+ int (*query)(const char *user, const char *group,
+ const struct passwd *pwd);
+};
+.RE
+.fi
+.PP
+The
+\fRsudoers_group_plugin\fR
+struct has the following fields:
+.TP 6n
+version
+The
+\fRversion\fR
+field should be set to GROUP_API_VERSION.
+.sp
+This allows
+\fBsudoers\fR
+to determine the API version the group plugin
+was built against.
+.TP 6n
+init
+.nf
+.RS 6n
+int (*init)(int version, sudo_printf_t plugin_printf,
+ char *const argv[]);
+.RE
+.fi
+.RS 6n
+.sp
+The
+\fBinit\fR()
+function is called after
+\fIsudoers\fR
+has been parsed but
+before any policy checks.
+It returns 1 on success, 0 on failure (or if the plugin is not configured),
+and \-1 if a error occurred.
+If an error occurs, the plugin may call the
+\fBplugin_printf\fR()
+function with
+\fRSUDO_CONF_ERROR_MSG\fR
+to present additional error information
+to the user.
+.sp
+The function arguments are as follows:
+.TP 6n
+version
+The version passed in by
+\fBsudoers\fR
+allows the plugin to determine the
+major and minor version number of the group plugin API supported by
+\fBsudoers\fR.
+.TP 6n
+plugin_printf
+A pointer to a
+\fBprintf\fR()-style
+function that may be used to display informational or error message to the user.
+Returns the number of characters printed on success and \-1 on failure.
+.TP 6n
+argv
+A
+\fRNULL\fR-terminated
+array of arguments generated from the
+\fIgroup_plugin\fR
+option in
+\fIsudoers\fR.
+If no arguments were given,
+\fIargv\fR
+will be
+\fRNULL\fR.
+.PD 0
+.PP
+.RE
+.PD
+.TP 6n
+cleanup
+.nf
+.RS 6n
+void (*cleanup)();
+.RE
+.fi
+.RS 6n
+.sp
+The
+\fBcleanup\fR()
+function is called when
+\fBsudoers\fR
+has finished its
+group checks.
+The plugin should free any memory it has allocated and close open file handles.
+.RE
+.TP 6n
+query
+.br
+.nf
+.RS 6n
+int (*query)(const char *user, const char *group,
+ const struct passwd *pwd);
+.RE
+.fi
+.RS 6n
+.sp
+The
+\fBquery\fR()
+function is used to ask the group plugin whether
+\fIuser\fR
+is a member of
+\fIgroup\fR.
+.sp
+The function arguments are as follows:
+.TP 6n
+user
+The name of the user being looked up in the external group database.
+.TP 6n
+group
+.br
+The name of the group being queried.
+.TP 6n
+pwd
+The password database entry for
+\fIuser\fR,
+if any.
+If
+\fIuser\fR
+is not
+present in the password database,
+\fIpwd\fR
+will be
+\fRNULL\fR.
+.PD 0
+.PP
+.RE
+.PD
+.PP
+\fIGroup API Version Macros\fR
+.nf
+.sp
+.RS 0n
+/* Sudoers group plugin version major/minor */
+#define GROUP_API_VERSION_MAJOR 1
+#define GROUP_API_VERSION_MINOR 0
+#define GROUP_API_VERSION ((GROUP_API_VERSION_MAJOR << 16) | \e
+ GROUP_API_VERSION_MINOR)
+.RE
+.fi
+For getters and setters see the
+\fIPolicy plugin API\fR.
+.SH "PLUGIN API CHANGELOG"
+The following revisions have been made to the Sudo Plugin API.
+.TP 6n
+Version 1.0
+Initial API version.
+.TP 6n
+Version 1.1 (sudo 1.8.0)
+The I/O logging plugin's
+\fBopen\fR()
+function was modified to take the
+\fRcommand_info\fR
+list as an argument.
+.TP 6n
+Version 1.2 (sudo 1.8.5)
+The Policy and I/O logging plugins'
+\fBopen\fR()
+functions are now passed
+a list of plugin parameters if any are specified in
+sudo.conf(@mansectform@).
+.sp
+A simple hooks API has been introduced to allow plugins to hook in to the
+system's environment handling functions.
+.sp
+The
+\fRinit_session\fR
+Policy plugin function is now passed a pointer
+to the user environment which can be updated as needed.
+This can be used to merge in environment variables stored in the PAM
+handle before a command is run.
+.TP 6n
+Version 1.3 (sudo 1.8.7)
+Support for the
+\fIexec_background\fR
+entry has been added to the
+\fRcommand_info\fR
+list.
+.sp
+The
+\fImax_groups\fR
+and
+\fIplugin_dir\fR
+entries were added to the
+\fRsettings\fR
+list.
+.sp
+The
+\fBversion\fR()
+and
+\fBclose\fR()
+functions are now optional.
+Previously, a missing
+\fBversion\fR()
+or
+\fBclose\fR()
+function would result in a crash.
+If no policy plugin
+\fBclose\fR()
+function is defined, a default
+\fBclose\fR()
+function will be provided by the
+\fBsudo\fR
+front end that displays a warning if the command could not be
+executed.
+.sp
+The
+\fBsudo\fR
+front end now installs default signal handlers to trap common signals
+while the plugin functions are run.
+.TP 6n
+Version 1.4 (sudo 1.8.8)
+The
+\fIremote_host\fR
+entry was added to the
+\fRsettings\fR
+list.
+.TP 6n
+Version 1.5 (sudo 1.8.9)
+The
+\fIpreserve_fds\fR
+entry was added to the
+\fRcommand_info\fR
+list.
+.TP 6n
+Version 1.6 (sudo 1.8.11)
+The behavior when an I/O logging plugin returns an error
+(\-1)
+has changed.
+Previously, the
+\fBsudo\fR
+front end took no action when the
+\fBlog_ttyin\fR(),
+\fBlog_ttyout\fR(),
+\fBlog_stdin\fR(),
+\fBlog_stdout\fR(),
+or
+\fBlog_stderr\fR()
+function returned an error.
+.sp
+The behavior when an I/O logging plugin returns 0 has changed.
+Previously, output from the command would be displayed to the
+terminal even if an output logging function returned 0.
+.TP 6n
+Version 1.7 (sudo 1.8.12)
+The
+\fIplugin_path\fR
+entry was added to the
+\fRsettings\fR
+list.
+.sp
+The
+\fIdebug_flags\fR
+entry now starts with a debug file path name and may occur multiple
+times if there are multiple plugin-specific Debug lines in the
+sudo.conf(@mansectform@) file.
+.TP 6n
+Version 1.8 (sudo 1.8.15)
+The
+\fIsudoedit_checkdir\fR
+and
+\fIsudoedit_follow\fR
+entries were added to the
+\fRcommand_info\fR
+list.
+The default value of
+\fIsudoedit_checkdir\fR
+was changed to true in sudo 1.8.16.
+.sp
+The sudo
+\fIconversation\fR
+function now takes a pointer to a
+\fRstruct sudo_conv_callback\fR
+as its fourth argument.
+The
+\fRsudo_conv_t\fR
+definition has been updated to match.
+The plugin must specify that it supports plugin API version 1.8 or higher
+to receive a conversation function pointer that supports this argument.
+.TP 6n
+Version 1.9 (sudo 1.8.16)
+The
+\fIexecfd\fR
+entry was added to the
+\fRcommand_info\fR
+list.
+.TP 6n
+Version 1.10 (sudo 1.8.19)
+The
+\fIumask\fR
+entry was added to the
+\fRuser_info\fR
+list.
+The
+\fIiolog_group\fR,
+\fIiolog_mode\fR,
+and
+\fIiolog_user\fR
+entries were added to the
+\fRcommand_info\fR
+list.
+.TP 6n
+Version 1.11 (sudo 1.8.20)
+The
+\fItimeout\fR
+entry was added to the
+\fRsettings\fR
+list.
+.TP 6n
+Version 1.12 (sudo 1.8.21)
+The
+\fRchange_winsize\fR
+field was added to the io_plugin struct.
+.TP 6n
+Version 1.13 (sudo 1.8.26)
+The
+\fRlog_suspend\fR
+field was added to the io_plugin struct.
+.SH "SEE ALSO"
+sudo.conf(@mansectform@),
+sudoers(@mansectform@),
+sudo(@mansectsu@)
+.SH "AUTHORS"
+Many people have worked on
+\fBsudo\fR
+over the years; this version consists of code written primarily by:
+.sp
+.RS 6n
+Todd C. Miller
+.RE
+.PP
+See the CONTRIBUTORS file in the
+\fBsudo\fR
+distribution (https://www.sudo.ws/contributors.html) for an
+exhaustive list of people who have contributed to
+\fBsudo\fR.
+.SH "BUGS"
+If you feel you have found a bug in
+\fBsudo\fR,
+please submit a bug report at https://bugzilla.sudo.ws/
+.SH "SUPPORT"
+Limited free support is available via the sudo-users mailing list,
+see https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or
+search the archives.
+.SH "DISCLAIMER"
+\fBsudo\fR
+is provided
+\(lqAS IS\(rq
+and any express or implied warranties, including, but not limited
+to, the implied warranties of merchantability and fitness for a
+particular purpose are disclaimed.
+See the LICENSE file distributed with
+\fBsudo\fR
+or https://www.sudo.ws/license.html for complete details.