Starting with version 1.8, 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 binary itself.  By default, the policy plugin
     and an associated I/O logging plugin are used.   Via  the  plugin
     API, 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  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 header file.  A policy
     plugin  must  declare  and populate a struct in the global scope.
     This structure contains pointers to the functions that  implement
     the policy checks.  The name of the symbol should be specified in
     along with a path to the plugin so  that  can  load  it.   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[], const char **errstr);
         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[],  const  char
     **errstr);
         int (*list)(int argc, char * const argv[], int verbose,
             const char *list_user, const char **errstr);
         int (*validate)(const char **errstr);
         void (*invalidate)(int remove);
         int (*init_session)(struct passwd *pwd, char **user_env[],
             const char **errstr);
         void (*register_hooks)(int version,
            int (*register_hook)(struct sudo_hook *hook));
         void (*deregister_hooks)(int version,
            int (*deregister_hook)(struct sudo_hook *hook));
         struct  sudo_plugin_event  *  (*event_alloc)(void);  };   The
     policy_plugin  struct  has the following fields: The field should
     always be set to SUDO_POLICY_PLUGIN.  The field should be set  to
     This  allows  to  determine  the API version the plugin was built
     against.    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[], const char **errstr);  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,  will  print  a
     usage  message  before  it exits.  If an error occurs, the plugin
     may optionally call the or function with  to  present  additional
     error  information  to  the  user.  The function arguments are as
     follows: The version passed in by allows the plugin to  determine
     the major and minor version number of the plugin API supported by
     A pointer to the function that can  be  used  by  the  plugin  to
     interact  with  the user (see for details).  Returns 0 on success
     and -1 on failure.  A pointer to a function that may be  used  to
     display  informational  or  error  messages  (see  for  details).
     Returns the number of characters printed on  success  and  -1  on
     failure.   A  vector  of  user-supplied  settings  in the form of
     strings.  The vector is terminated by a pointer.  These  settings
     correspond  to  options  the user specified when running As such,
     they will only be present when the corresponding option has  been
     specified  on  the  command line.  When parsing the plugin should
     split on the equal sign since the field will  never  include  one
     itself  but  the  might.   The  following  values  may  be set by
     Authentication type, if  specified  by  the  option,  to  use  on
     systems  where  authentication  is  supported.  If specified, the
     user  has  requested  via  the  option  that  close   all   files
     descriptors with a value of or higher.  The plugin may optionally
     pass this,  or  another  value,  back  in  the  list.   The  root
     directory  (see  to  run the command in, as specified by the user
     via the option.  The plugin may ignore  or  restrict  the  user's
     ability to specify a new root directory.  Only available starting
     with API version 1.16.  The working directory to run the  command
     in,  as  specified  by  the  user via the option.  The plugin may
     ignore or restrict the user's ability to specify  a  new  working
     directory.   Only  available  starting  with API version 1.16.  A
     debug file path name followed by a space  and  a  comma-separated
     list  of  debug flags that correspond to the plugin's entry in if
     there is one.  The flags are passed to the plugin exactly as they
     appear  in  The  syntax used by and the plugin is but a plugin is
     free to use a different format so long as it does not  include  a
     comma  Prior  to  1.8.12,  there  was  no  way to specify plugin-
     specific so the value was always the same as  that  used  by  the
     front  end  and  did  not  include  a  path  name, only the flags
     themselves.  As of version 1.7 of the plugin interface, will only
     pass  if  contains  a  plugin-specific entry.  Set to true if the
     user specified the option along with a command,  indicating  that
     the  user wishes to ignore any cached authentication credentials.
     to true.  This allows with no arguments to be used  similarly  to
     If  the  plugin  does  not to support this usage, it may return a
     value of -2 from the function, which will cause to print a  usage
     message  and exit.  If the user does not specify a program on the
     command line, will pass the plugin the path to the  user's  shell
     and  set login class to use when setting resource limits and nice
     value, if specified by the option.   Set  to  true  if  the  user
     specified  the  option,  indicating that the user wishes to run a
     login shell.  The maximum number of groups a user may belong  to.
     This  will only be present if there is a corresponding setting in
     A space-separated list of IP network addresses  and  netmasks  in
     the  form  e.g., The address and netmask pairs may be either IPv4
     or IPv6, depending on what the operating system supports.  If the
     address  contains a colon it is an IPv6 address, else it is IPv4.
     Set to true if the user specified  the  option,  indicating  that
     should  operate in non-interactive mode.  The plugin may reject a
     command run  in  non-interactive  mode  if  user  interaction  is
     required.   The  default  plugin directory used by the 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.   The  path
     name  of plugin loaded by the front end.  The path name will be a
     fully-qualified unless the plugin was  statically  compiled  into
     Set to true if the user specified the option, indicating that the
     user wishes to preserve the environment.  Set to true if the user
     specified the option, indicating that the user wishes to preserve
     the group vector instead of setting it based on the  runas  user.
     The command name that sudo was run as, typically or The prompt to
     use when requesting a password, if specified via the option.  The
     name  of  the remote host to run the command on, if specified via
     the 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  front  end  is  only
     capable  of executing commands on the local host.  Only available
     starting with API version 1.4.  Set to true if the user specified
     the  option, indicating that the user wishes to run a shell.  The
     group name or gid to run the command as,  if  specified  via  the
     option.  The user name or uid to run the command as, if specified
     via the option.  SELinux role to use when executing the  command,
     if  specified  by the option.  SELinux type to use when executing
     the command, if specified by the option.  Set to true if the user
     specified  the  option.  If true, set the environment variable to
     the target user's home directory.  Set to true when the option is
     specified  or if invoked as The plugin shall substitute an editor
     into in the function or return -2  with  a  usage  error  if  the
     plugin  does  not  support For more information, see the section.
     Command timeout specified by the user via the  option.   Not  all
     plugins  support  command timeouts and the ability of the user to
     set a timeout may be restricted by policy.   The  format  of  the
     timeout  string  is  plugin-specific.  Additional settings may be
     added in the future so the plugin should silently ignore settings
     that  it  does  not recognize.  A vector of information about the
     user running the command in the form of strings.  The  vector  is
     terminated by a pointer.  When parsing the plugin should split on
     the equal sign since the field will never include one itself  but
     the  might.   The  following  values  may be set by The number of
     columns the user's terminal supports.  If there  is  no  terminal
     device  available,  a  default  value  of 80 is used.  The user's
     current working directory.  The effective group-ID  of  the  user
     invoking  The  effective  user-ID  of  the user invoking The real
     group-ID of the user invoking The user's supplementary group list
     formatted  as  a  string of comma-separated group-IDs.  The local
     machine's hostname as returned by the system call.  The number of
     lines  the  user's  terminal  supports.   If there is no terminal
     device available, a default value of 24 is used.  The ID  of  the
     process  group  that  the  running  process is a member of.  Only
     available starting with API version 1.2.  The process ID  of  the
     running  process.   Only available starting with API version 1.2.
     The parent process ID of the  running  process.   Only  available
     starting  with  API  version  1.2.  The maximum size to which the
     process's address space may grow (in bytes), if supported by  the
     operating  system.   The  soft and hard limits are separated by a
     comma.  A value of  indicates  that  there  is  no  limit.   Only
     available  starting with API version 1.16.  The largest size core
     dump file that may be created (in  bytes).   The  soft  and  hard
     limits are separated by a comma.  A value of indicates that there
     is no limit.  Only available starting with API version 1.16.  The
     maximum amount of CPU time that the process may use (in seconds).
     The soft and hard limits are separated by a comma.   A  value  of
     indicates  that  there is no limit.  Only available starting with
     API version 1.16.  The maximum size of the data segment  for  the
     process  (in bytes).  The soft and hard limits are separated by a
     comma.  A value of  indicates  that  there  is  no  limit.   Only
     available  starting with API version 1.16.  The largest size file
     that the process may create (in bytes).  The soft and hard limits
     are  separated by a comma.  A value of indicates that there is no
     limit.  Only available  starting  with  API  version  1.16.   The
     maximum  number  of  locks  that  the  process  may establish, if
     supported by the operating system.  The soft and hard limits  are
     separated  by  a  comma.   A  value of indicates that there is no
     limit.  Only available  starting  with  API  version  1.16.   The
     maximum  size  that the process may lock in memory (in bytes), if
     supported by the operating system.  The soft and hard limits  are
     separated  by  a  comma.   A  value of indicates that there is no
     limit.  Only available  starting  with  API  version  1.16.   The
     maximum number of files that the process may have open.  The soft
     and hard limits are separated by a comma.  A value  of  indicates
     that there is no limit.  Only available starting with API version
     1.16.  The maximum number of processes  that  the  user  may  run
     simultaneously.   The  soft  and  hard  limits are separated by a
     comma.  A value of  indicates  that  there  is  no  limit.   Only
     available  starting  with  API version 1.16.  The maximum size to
     which the process's resident set size may grow (in  bytes).   The
     soft  and  hard  limits  are  separated  by  a comma.  A value of
     indicates that there is no limit.  Only available  starting  with
     API  version 1.16.  The maximum size to which the process's stack
     may grow (in bytes).  The soft and hard limits are separated by a
     comma.   A  value  of  indicates  that  there  is no limit.  Only
     available starting with API version 1.16.  The session ID of  the
     running  process  or  0  if  is  not  part of a POSIX job control
     session.  Only available starting with API version 1.2.   The  ID
     of  the  foreground  process  group  associated with the terminal
     device associated with the process or 0 if there is  no  terminal
     present.  Only available starting with API version 1.2.  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 The real user-ID of the user invoking The invoking user's file
     creation  mask.   Only  available starting with API version 1.10.
     The name of the user invoking The user's environment in the  form
     of  a strings.  When parsing the plugin should split on the equal
     sign since the field will never include one itself but the might.
     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 array of strings.  If no arguments were specified,  will  be
     the pointer.  NOTE: the parameter is only available starting with
     API version 1.2.  A plugin check the API version specified by the
     front  end  before  using Failure to do so may result in a crash.
     If the function returns a value other  than  1,  the  plugin  may
     store  a message describing the failure or error in The front end
     will then pass this value to any registered audit  plugins.   The
     string stored in must remain valid until the plugin's function is
     called.  NOTE: the parameter is only available starting with  API
     version  1.15.   A  plugin check the API version specified by the
     front end before using Failure to do so may result  in  a  crash.
     void (*close)(int exit_status, int error); The function is called
     when is finished, shortly before it  exits.   Starting  with  API
     version  1.15,  is  called regardless of whether or not a command
     was actually executed.  This makes it  possible  for  plugins  to
     perform  cleanup  even  when  a  command  was not run.  It is not
     possible to tell whether a command was run based  solely  on  the
     arguments  passed to the function.  To determine if a command was
     actually run, the plugin must keep track of whether  or  not  the
     function  returned  successfully.   The function arguments are as
     follows: The command's exit status, as  returned  by  the  system
     call,  or  zero if no command was run.  The value of is undefined
     if is non-zero.  If the command could not be  executed,  this  is
     set  to  the  value  of  set  by  the system call.  The plugin is
     responsible for displaying error information via the or function.
     If  the  command was successfully executed, the value of is zero.
     If no function is defined, no I/O logging plugins are loaded, and
     neither  the  not  options are set in the list, the front end may
     execute the command directly instead of running  it  as  a  child
     process.   int  (*show_version)(int  verbose);  The  function  is
     called by when the user specifies the  option.   The  plugin  may
     display  its  version information to the user via the or function
     using If the user  requests  detailed  version  information,  the
     verbose flag will be set.  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.   int
     (*check_policy)(int argc, char * const argv[], char *env_add[],
         char    **command_info[],     char     **argv_out[],     char
     **user_env_out[],
         const char **errstr); The function is called by to  determine
     whether  the  user  is allowed to run the specified commands.  If
     the option was enabled in the array passed to the  function,  the
     user  has requested mode.  is a mechanism for editing one or more
     files where an editor is run with the user's credentials  instead
     of  with  elevated  privileges.   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 it should choose the  editor
     to   be   used,   potentially  from  a  variable  in  the  user's
     environment, such as and include it  in  (note  that  environment
     variables  may  include  command  line options).  The files to be
     edited should be copied from into separated from the  editor  and
     its  arguments  by  a element.  The will be removed by before the
     editor is executed.  The plugin should also set in the list.  The
     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  was
     specified  but is unsupported by the plugin.  In the latter case,
     will print a usage message before it exits.  If an error  occurs,
     the  plugin  may  optionally call the or function with to present
     additional error information to the user.  The function arguments
     are  as follows: The number of elements in not counting the final
     pointer.  The argument vector describing  the  command  the  user
     wishes  to  run,  in the same form as what would be passed to the
     system call.  The vector is terminated by a pointer.   Additional
     environment  variables  specified by the user on the command line
     in the form of a vector of 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  the  plugin
     should split on the equal sign since the field will never include
     one itself but the might.  Information about  the  command  being
     run  in the form of strings.  These values are used by 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 pointer.  The following values  are  recognized
     by  The  root  directory  to  use  when  running the command.  If
     specified, will close all files descriptors with a  value  of  or
     higher.  Fully qualified path to the command to be executed.  The
     current  working  directory  to  change  to  when  executing  the
     command.   If  is  unable to change to the new working directory,
     the command will not be run unless is also set (see  below).   If
     enabled,  will  treat  an  inability to change to the new working
     directory as a non-fatal  error.   This  setting  has  no  effect
     unless is also set.  By default, runs a command as the foreground
     process as long as itself is running in the foreground.  When  is
     enabled and the command is being run in a pseudo-terminal (due to
     I/O logging or the  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  signal  (or  in the case of
     terminal  settings).   If  this  happens  when  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 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  behavior  or  when  the  command  is not being run in a
     pseudo-terminal.  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  and  system  calls  (this  is  a  bug  in   macOS).
     Furthermore,   because  this  behavior  depends  on  the  command
     stopping with the or signals, programs that catch  these  signals
     and  suspend themselves with a different signal (usually will not
     be  automatically  foregrounded.   Some  versions  of  the  linux
     command  behave  this  way.  Because of this, a plugin should not
     set unless it is explicitly  enabled  by  the  administrator  and
     there  should  be a way to enabled or disable it on a per-command
     basis.  This setting has no effect unless I/O logging is  enabled
     or is enabled.  If specified, will use the system call to execute
     the command instead of The specified must refer to an  open  file
     descriptor.   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.  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.  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.  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.  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.
     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.   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.  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.  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.   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.  login class to use
     when  setting  resource  limits  and nice value (optional).  This
     option is only set on systems that support login  classes.   Nice
     value  (priority)  to  use  when executing the command.  The nice
     value, if specified, overrides the priority associated  with  the
     on  systems.   If  set,  prevent the command from executing other
     programs.  A comma-separated list of file descriptors that should
     be  preserved,  regardless  of  the  value  of the setting.  Only
     available starting with API version 1.5.  If set,  will  preserve
     the  user's group vector instead of initializing the group vector
     based on Effective group-ID  to  run  the  command  as.   If  not
     specified,  the  value  of is used.  Effective user-ID to run the
     command as.  If not specified, the value of is used.  Group-ID to
     run  the  command as.  The name of the group the command will run
     as, if it is different from the default  group.   This  value  is
     provided  for auditing purposes only, the front-end uses and when
     executing the command.  The supplementary group vector to use for
     the  command  in the form of a comma-separated list of group-IDs.
     If is set, this option is ignored.  User-ID to  run  the  command
     as.   The  name of the user the command will run as, which should
     correspond to (or if is not set).  This  value  is  provided  for
     auditing purposes only, the front-end uses and when executing the
     command.   SELinux  role  to  use  when  executing  the  command.
     SELinux  type  to  use when executing the command.  Create a utmp
     (or  utmpx)  entry  when  a  pseudo-terminal  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.
     Set to true when in mode.  The plugin may enable mode even if was
     not  invoked  as  This  allows  the  plugin  to  perform  command
     substitution  and  transparently enable when the user attempts to
     run an editor.  Set to false  to  disable  directory  writability
     checks  in By default, 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 will refuse to edit a file located in a  writable
     directory.   These  restrictions  are not enforced when is run by
     root.  The option can be set to  false  to  disable  this  check.
     Only  available  starting  with  API version 1.8.  Set to true to
     allow to edit files that are symbolic links.  By default,  1.8.15
     and  higher  will refuse to open a symbolic link.  The option can
     be used to restore the older behavior and allow to open  symbolic
     links.   Only  available  starting with API version 1.8.  Command
     timeout.  If non-zero then when the timeout expires  the  command
     will be killed.  The file creation mask to use when executing the
     command.  This value may be overridden by PAM  or  login.conf  on
     some  systems  unless  the  option  is also set.  Force the value
     specified by the option to override  any  umask  set  by  PAM  or
     login.conf.   Allocate  a  pseudo-terminal to run the command in,
     regardless of whether or not I/O logging is in use.  By  default,
     will  only  run  the command in a pseudo-terminal when an I/O log
     plugin is loaded.  User name to use when constructing a new  utmp
     (or utmpx) entry when 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, will base the new
     entry on the invoking user's existing entry.  Unsupported  values
     will  be ignored.  The argument vector to pass to the system call
     when executing  the  command.   The  plugin  is  responsible  for
     allocating  and populating the vector.  The environment vector to
     use when executing the command.  The plugin  is  responsible  for
     allocating  and populating the vector.  If the function returns a
     value other than 1, the plugin may store a message describing the
     failure  or  error  in The front end will then pass this value to
     any registered audit plugins.  The string stored in  must  remain
     valid until the plugin's function is called.  NOTE: the parameter
     is only available starting with API version 1.15.  A plugin check
     the  API  version specified by the front end before using Failure
     to do so may result in a crash.  int  (*list)(int  argc,  char  *
     const argv[], int verbose,
         const char *list_user, const char **errstr);  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 or function with to present additional error information
     to the user.  Privileges should be output  via  the  or  function
     using  The  function  arguments  are  as  follows:  The number of
     elements in not counting  the  final  pointer.   If  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  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.   Flag  indicating  whether  to list in
     verbose mode or not.  The  name  of  a  different  user  to  list
     privileges  for  if  the  policy allows it.  If the plugin should
     list the privileges  of  the  invoking  user.   If  the  function
     returns  a  value  other  than  1, the plugin may store a message
     describing the failure or error in The front end will  then  pass
     this value to any registered audit plugins.  The string stored in
     must remain valid until the plugin's function is  called.   NOTE:
     the  parameter  is only available starting with API version 1.15.
     A plugin check the API version specified by the front end  before
     using   Failure   to   do   so   may  result  in  a  crash.   int
     (*validate)(const char **errstr); The function is called when  is
     run  with  the  option.   For  policy  plugins such as that cache
     authentication credentials, this function will validate and cache
     the  credentials.   The function should be 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 or
     function with to present  additional  error  information  to  the
     user.   The  function  arguments  are as follows: If the function
     returns a value other than 1, the  plugin  may  store  a  message
     describing  the  failure or error in The front end will then pass
     this value to any registered audit plugins.  The string stored in
     must  remain  valid until the plugin's function is called.  NOTE:
     the parameter is only available starting with API  version  1.15.
     A  plugin check the API version specified by the front end before
     using  Failure  to  do  so  may  result   in   a   crash.    void
     (*invalidate)(int  remove);  The  function  is called when is run
     with the or option.   For  policy  plugins  such  as  that  cache
     authentication  credentials,  this  function  will invalidate the
     credentials.  If the flag is  set,  the  plugin  may  remove  the
     credentials  instead  of  simply invalidating them.  The function
     should be if the plugin does not support credential caching.  int
     (*init_session)(struct  passwd  *pwd, char **user_env_out[]); The
     function is called before sets up the execution  environment  for
     the  command.  It is run in the parent process and before any uid
     or gid changes.  This can be used to perform session  setup  that
     is  not  supported  by  such  as  opening  the  PAM session.  The
     function can be used to tear down the session that was opened  by
     The  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 The argument points
     to the environment the command will run in,  in  the  form  of  a
     vector  of  strings.   This is the same string passed back to the
     front end via the Policy Plugin's  parameter.   If  the  function
     needs  to  modify  the  user  environment,  it  should update the
     pointer stored in The expected use case is to merge the  contents
     of  the  PAM  environment (if any) with the contents of NOTE: the
     parameter is only available starting with  API  version  1.2.   A
     plugin  check  the  API version specified by the front end before
     using Failure to do so may result  in  a  crash.   Returns  1  on
     success,  0 on failure and -1 on error.  On error, the plugin may
     optionally call the or function with to present additional  error
     information to the user.  void (*register_hooks)(int version,
        int (*register_hook)(struct sudo_hook *hook)); The function is
     called  by  the  sudo  front end to register any hooks the plugin
     needs.  If the plugin does not support hooks, should  be  set  to
     the pointer.  The argument describes the version of the hooks API
     supported by the front end.   The  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 does not match the front end's major hook API version.
     See the section below for more information  about  hooks.   NOTE:
     the function is only available starting with API version 1.2.  If
     the front end doesn't support API version 1.2 or higher, will not
     be called.  void (*deregister_hooks)(int version,
        int (*deregister_hook)(struct sudo_hook *hook)); The  function
     is  called  by  the  sudo  front  end to deregister any hooks the
     plugin has registered.  If the plugin  does  not  support  hooks,
     should be set to the pointer.  The argument describes the version
     of the hooks API supported by the front end.  The function should
     be  used  to  deregister  any hooks that were put in place by the
     function.  If the plugin tries to  deregister  a  hook  that  the
     front  end  does  not  support,  will  return  an error.  See the
     section below  for  more  information  about  hooks.   NOTE:  the
     function is only available starting with API version 1.2.  If the
     front end doesn't support API version 1.2 or higher, will not  be
     called.   struct  sudo_plugin_event  *  (*event_alloc)(void); The
     function is used to allocate a which provides access to the  main
     event loop.  Unlike the other fields, the pointer is filled in by
     the front end, not by the plugin.  See the section below for more
     information  about  events.  NOTE: the function is only available
     starting with API version 1.15.  If the front end doesn't support
     API  version  1.15  or  higher, will not be set.  If the function
     returns a value other than 1, the  plugin  may  store  a  message
     describing  the  failure or error in The front end will then pass
     this value to any registered audit plugins.  The string stored in
     must  remain  valid until the plugin's function is called.  NOTE:
     the parameter is only available starting with API  version  1.15.
     A  plugin check the API version specified by the front end before
     using Failure to do so may result in  a  crash.   /*  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,\
                                                 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 { \
         *(vp) = (*(vp) & 0x0000ffff) | ((n)  <<  16);  \  }  while(0)
     #define SUDO_API_VERSION_SET_MINOR(vp, n) do { \
         *(vp) = (*(vp) & 0xffff0000)  |  (n);  \  }  while(0)  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[], const char **errstr);
         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,
             const char **errstr);
         int (*log_ttyout)(const char *buf, unsigned int len,
             const char **errstr);
         int (*log_stdin)(const char *buf, unsigned int len,
             const char **errstr);
         int (*log_stdout)(const char *buf, unsigned int len,
             const char **errstr);
         int (*log_stderr)(const char *buf, unsigned int len,
             const char **errstr);
         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,
             const char **errstr);
         int (*log_suspend)(int signo, const char **errstr);
         struct sudo_plugin_event * (*event_alloc)(void); };  When  an
     I/O  plugin  is  loaded,  runs  the command in a pseudo-terminal.
     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, will open  a  pipe  to
     capture  the I/O for logging before passing it on.  The log_ttyin
     function receives the raw user input  from  the  terminal  device
     (note  that  this  will include input even when echo is disabled,
     such as when  a  password  is  read).   The  log_ttyout  function
     receives  output  from  the  pseudo-terminal that is suitable for
     replaying the user's session at a later time.  The and  functions
     are  only  called  if  the  standard  input,  standard  output or
     standard error respectively correspond to something other than  a
     tty.   Any  of the logging functions may be set to the pointer if
     no logging is to be performed.  If the open function  returns  0,
     no I/O will be sent to the plugin.  If a logging function returns
     an error 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.  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.  The audit_plugin
     struct has the following fields: The field should always  be  set
     to  The  field  should be set to This allows to determine the API
     version the plugin was built against.  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[]); The function  is  run  before
     the or functions are called.  It is only called if the version is
     being requested or if the policy plugin's 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,  will print a usage message before it exits.  If an
     error occurs, the plugin may optionally call the or function with
     to  present  additional  error  information  to  the  user.   The
     function arguments are as  follows:  The  version  passed  in  by
     allows the plugin to determine the major and minor version number
     of the plugin API supported by A pointer to the function that may
     be  used  by  the  function  to  display version information (see
     below).  The function may also  be  used  to  display  additional
     error message to the user.  The function returns 0 on success and
     -1 on failure.  A pointer to a function that may be used  by  the
     function to display version information (see show_version below).
     The function may also be used to display additional error message
     to  the  user.  The function returns number of characters printed
     on success and -1 on failure.  A vector of user-supplied settings
     in  the  form of strings.  The vector is terminated by a pointer.
     These settings correspond to  options  the  user  specified  when
     running As such, they will only be present when the corresponding
     option has been specified on the command line.  When parsing  the
     plugin  should split on the equal sign since the field will never
     include one itself but the might.  See the section for a list  of
     all  possible  settings.   A vector of information about the user
     running the command in  the  form  of  strings.   The  vector  is
     terminated by a pointer.  When parsing the plugin should split on
     the equal sign since the field will never include one itself  but
     the  might.   See the section for a list of all possible strings.
     A vector of information describing the command being run  in  the
     form  of  strings.   The vector is terminated by a pointer.  When
     parsing the plugin should split on the equal sign since the field
     will never include one itself but the might.  See the section for
     a list of all possible strings.  The number of  elements  in  not
     counting  the final pointer.  It can be zero, when is called with
     If an argument vector describing a command the user wishes to run
     in the same form as what would be passed to the system call.  The
     user's environment in the form of  a  vector  of  strings.   When
     parsing the plugin should split on the equal sign since the field
     will never include one itself but the might.   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
     array of strings.  If no arguments were specified,  will  be  the
     pointer.  NOTE: the parameter is only available starting with API
     version 1.2.  A plugin check the API  version  specified  by  the
     front  end  before  using Failure to do so may result in a crash.
     If the function returns a value other  than  1,  the  plugin  may
     store  a message describing the failure or error in The front end
     will then pass this value to any registered audit  plugins.   The
     string stored in must remain valid until the plugin's function is
     called.  NOTE: the parameter is only available starting with  API
     version  1.15.   A  plugin check the API version specified by the
     front end before using Failure to do so may result  in  a  crash.
     void (*close)(int exit_status, int error); The function is called
     when  is  finished,  shortly  before  it  exits.   The   function
     arguments  are as follows: The command's exit status, as returned
     by the system call, or zero if no command was run.  The value  of
     is  undefined  if  is  non-zero.   If  the  command  could not be
     executed, this is set to the value of set by the system call.  If
     the command was successfully executed, the value of is zero.  int
     (*show_version)(int verbose); The function is called by when  the
     user  specifies  the  option.  The plugin may display its version
     information to the user via the or function using  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.  int (*log_ttyin)(const char *buf, unsigned int len,
         const char **errstr); The 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.  The  function  arguments  are  as  follows:  The
     buffer  containing  user  input.  The length of in bytes.  If the
     function returns a value other than 1, the  plugin  may  store  a
     message  describing  the  failure  or error in The front end will
     then pass this value to any registered audit plugins.  The string
     stored  in  must  remain  valid  until  the  plugin's function is
     called.  NOTE: the parameter is only available starting with  API
     version  1.15.   A  plugin check the API version specified by the
     front end before using Failure to do so may result  in  a  crash.
     int (*log_ttyout)(const char *buf, unsigned int len,
         const char **errstr); The 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.  The function arguments are  as  follows:  The
     buffer  containing  command  output.  The length of in bytes.  If
     the function returns a value other than 1, the plugin may store a
     message  describing  the  failure  or error in The front end will
     then pass this value to any registered audit plugins.  The string
     stored  in  must  remain  valid  until  the  plugin's function is
     called.  NOTE: the parameter is only available starting with  API
     version  1.15.   A  plugin check the API version specified by the
     front end before using Failure to do so may result  in  a  crash.
     int (*log_stdin)(const char *buf, unsigned int len,
         const char **errstr);  The  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.  The function
     arguments are as follows: The buffer containing user input.   The
     length  of  in bytes.  If the function returns a value other than
     1, the plugin may store a message describing the failure or error
     in  The  front  end  will  then pass this value to any registered
     audit plugins.  The string stored in must remain valid until  the
     plugin's  function  is  called.   NOTE:  the  parameter  is  only
     available starting with API version 1.15.  A plugin check the API
     version  specified by the front end before using Failure to do so
     may result  in  a  crash.   int  (*log_stdout)(const  char  *buf,
     unsigned int len,
         const char **errstr);  The  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.  The function arguments are
     as follows: The buffer containing command output.  The length  of
     in  bytes.   If  the  function  returns a value other than 1, the
     plugin may store a message describing the failure or error in The
     front  end  will  then  pass  this  value to any registered audit
     plugins.  The string  stored  in  must  remain  valid  until  the
     plugin's  function  is  called.   NOTE:  the  parameter  is  only
     available starting with API version 1.15.  A plugin check the API
     version  specified by the front end before using Failure to do so
     may result  in  a  crash.   int  (*log_stderr)(const  char  *buf,
     unsigned int len,
         const char **errstr);  The  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.  The function arguments are
     as follows: The buffer containing command output.  The length  of
     in  bytes.   If  the  function  returns a value other than 1, the
     plugin may store a message describing the failure or error in The
     front  end  will  then  pass  this  value to any registered audit
     plugins.  The string  stored  in  must  remain  valid  until  the
     plugin's  function  is  called.   NOTE:  the  parameter  is  only
     available starting with API version 1.15.  A plugin check the API
     version  specified by the front end before using Failure to do so
     may result in a crash.  See the section for a description of  See
     the  section  for a description of int (*change_winsize)(unsigned
     int lines, unsigned int cols,
         const char **errstr); The function  is  called  whenever  the
     window  size  of  the  terminal  changes  from the initial values
     specified in the list.  Returns -1 if an error occurred, in which
     case no further calls to will be made, The function arguments are
     as follows: The number of lines (rows) in the re-sized  terminal.
     The  number of columns in the re-sized terminal.  If the function
     returns a value other than 1, the  plugin  may  store  a  message
     describing  the  failure or error in The front end will then pass
     this value to any registered audit plugins.  The string stored in
     must  remain  valid until the plugin's function is called.  NOTE:
     the parameter is only available starting with API  version  1.15.
     A  plugin check the API version specified by the front end before
     using  Failure  to  do  so  may   result   in   a   crash.    int
     (*log_suspend)(int  signo,  const char **errstr); The function is
     called whenever a command is suspended or 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 will be
     made, The function arguments are  as  follows:  The  signal  that
     caused  the  command  to  be  suspended,  or  if  the command was
     resumed.  If the function returns  a  value  other  than  1,  the
     plugin may store a message describing the failure or error in The
     front end will then pass  this  value  to  any  registered  audit
     plugins.   The  string  stored  in  must  remain  valid until the
     plugin's  function  is  called.   NOTE:  the  parameter  is  only
     available starting with API version 1.15.  A plugin check the API
     version specified by the front end before using Failure to do  so
     may    result   in   a   crash.    struct   sudo_plugin_event   *
     (*event_alloc)(void); The function is used to  allocate  a  which
     provides access to the main event loop.  Unlike the other fields,
     the pointer is filled in by the front end,  not  by  the  plugin.
     See  the  section below for more information about events.  NOTE:
     the function is only available starting with  API  version  1.15.
     If the front end doesn't support API version 1.15 or higher, will
     not be set.  Same as for  the  /*  Audit  plugin  close  function
     status   types.   */  #define  SUDO_PLUGIN_NO_STATUS            0
     #define      SUDO_PLUGIN_WAIT_STATUS              1       #define
     SUDO_PLUGIN_EXEC_ERROR           2 #define SUDO_PLUGIN_SUDO_ERROR
     3

     #define SUDO_AUDIT_PLUGIN 3 struct audit_plugin {
         unsigned int type; /* always SUDO_AUDIT_PLUGIN */
         unsigned int version; /* always SUDO_API_VERSION */
         int (*open)(unsigned int version, sudo_conv_t conversation,
             sudo_printf_t sudo_printf, char * const settings[],
             char * const user_info[], int submit_optind,
             char * const submit_argv[], char * const submit_envp[],
             char * const plugin_options[], const char **errstr);
         void (*close)(int status_type, int status);
         int (*accept)(const char *plugin_name,
             unsigned int plugin_type, char * const command_info[],
             char * const run_argv[], char * const run_envp[],
             const char **errstr);
         int   (*reject)(const   char   *plugin_name,   unsigned   int
     plugin_type,
             const char *audit_msg, char * const command_info[],
             const char **errstr);
         int   (*error)(const   char   *plugin_name,   unsigned    int
     plugin_type,
             const char *audit_msg, char * const command_info[],
             const char **errstr);
         int (*show_version)(int verbose);
         void (*register_hooks)(int version,
             int (*register_hook)(struct sudo_hook *hook));
         void (*deregister_hooks)(int version,
             int (*deregister_hook)(struct sudo_hook *hook));
         struct sudo_plugin_event * (*event_alloc)(void); }  An  audit
     plugin can be used to log successful and unsuccessful attempts to
     run independent of the policy or any I/O plugins.  Multiple audit
     plugins  may  be  specified  in  The  audit_plugin struct has the
     following fields: The field should always be  set  to  The  field
     should  be  set  to  This allows to determine the API version the
     plugin was built  against.   int  (*open)(unsigned  int  version,
     sudo_conv_t conversation,
         sudo_printf_t sudo_printf, char * const settings[],
         char * const user_info[], int submit_optind,
         char * const submit_argv[], char * const submit_envp[],
         char * const  plugin_options[],  const  char  **errstr);  The
     audit  function  is  run  before  any other plugin API functions.
     This makes it possible to audit failures in  the  other  plugins.
     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,
     will  print a usage message before it exits.  If an error occurs,
     the plugin may optionally call the or function  with  to  present
     additional error information to the user.  The function arguments
     are as follows: The version passed in by  allows  the  plugin  to
     determine  the  major  and minor version number of the plugin API
     supported by A pointer to the function that may be  used  by  the
     function   to  display  version  information  (see  below).   The
     function may also be used to display additional error message  to
     the  user.   The function returns 0 on success and -1 on failure.
     A pointer to a function that may  be  used  by  the  function  to
     display   version  information  (see  show_version  below).   The
     function may also be used to display additional error message  to
     the  user.   The function returns number of characters printed on
     success and -1 on failure.  A vector of user-supplied settings in
     the  form  of  strings.   The  vector is terminated by a pointer.
     These settings correspond to  options  the  user  specified  when
     running As such, they will only be present when the corresponding
     option has been specified on the command line.  When parsing  the
     plugin  should split on the equal sign since the field will never
     include one itself but the might.  See the section for a list  of
     all  possible  settings.   A vector of information about the user
     running the command in  the  form  of  strings.   The  vector  is
     terminated by a pointer.  When parsing the plugin should split on
     the equal sign since the field will never include one itself  but
     the  might.   See the section for a list of all possible strings.
     The index into that corresponds to the first entry that is not  a
     command  line  option.  If only consists of options, which may be
     the case with the or options, will evaluate to the NULL  pointer.
     The  argument vector was invoked with, including all command line
     options.  The argument can be used to determine the  end  of  the
     command  line  options.   The  invoking user's environment in the
     form of a vector of strings.   When  parsing  the  plugin  should
     split  on  the  equal sign since the field will never include one
     itself but the  might.   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 array of strings.  If no
     arguments were specified, will be the pointer.  If  the  function
     returns  a  value  other  than  1, the plugin may store a message
     describing the failure or error in The front end will  then  pass
     this value to any registered audit plugins.  The string stored in
     must remain valid until the plugin's function  is  called.   void
     (*close)(int  status_type,  int  status);  The function is called
     when  is  finished,  shortly  before  it  exits.   The   function
     arguments  are  as follows: The type of status being passed.  One
     of or Depending on the value of this value is either ignored, the
     command's  exit  status as returned by the system call, the value
     of set by the system call, or the  value  of  resulting  from  an
     error  in  the front end.  int (*accept)(const char *plugin_name,
     unsigned int plugin_type,
         char * const command_info[], char * const run_argv[],
         char * const run_envp[], const char **errstr);  The  function
     is  called  when  a  command or action is accepted by a policy or
     approval plugin.  The function arguments are as follows: The name
     of  the  plugin  that  accepted the command or for the front-end.
     The type of plugin that accepted the command, currently either or
     The  function  is  called multiple times--once for each policy or
     approval plugin that succeeds and once for  the  sudo  front-end.
     When  called  on  behalf  of  the  sudo  front-end,  may  include
     information from an I/O logging plugin as  well.   Typically,  an
     audit  plugin  is interested in either the accept status from the
     front-end or from the various policy and  approval  plugins,  but
     not  both.   It  is  possible  for  the policy plugin to accept a
     command that is later rejected by an approval  plugin,  in  which
     case  the  audit  plugin's  and  functions  will  be  called.  An
     optional vector of information describing the command  being  run
     in  the  form of strings.  The vector is terminated by a pointer.
     When parsing the plugin should split on the equal sign since  the
     field  will  never  include  one  itself  but the might.  See the
     section for a list of all possible strings.   A  argument  vector
     describing  a  command  that will be run in the same form as what
     would be passed to the system call.  The environment the  command
     will  be  run  with  in  the  form  of a vector of strings.  When
     parsing the plugin should split on the equal sign since the field
     will  never  include  one  itself but the might.  If the function
     returns a value other than 1, the  plugin  may  store  a  message
     describing  the  failure or error in The front end will then pass
     this value to any registered audit plugins.  The string stored in
     must  remain  valid  until  the plugin's function is called.  int
     (*reject)(const char *plugin_name, unsigned int plugin_type,
         const char *audit_msg, char * const command_info[],
         const char **errstr); The function is called when  a  command
     or action is rejected by a plugin.  The function arguments are as
     follows: The name of the plugin that rejected the  command.   The
     type  of  plugin  that  rejected the command, currently either or
     Unlike the function, the function is not called on behalf of  the
     front-end.   An optional string describing the reason the command
     was rejected by the plugin.  If the  plugin  did  not  provide  a
     reason,  will  be the pointer.  An optional vector of information
     describing the command being run in the  form  of  strings.   The
     vector  is  terminated  by  a  pointer.   When parsing the plugin
     should split on the equal sign since the field will never include
     one  itself  but  the  might.   See the section for a list of all
     possible strings.  If the function returns a value other than  1,
     the plugin may store a message describing the failure or error in
     The front end will then pass this value to any  registered  audit
     plugins.   The  string  stored  in  must  remain  valid until the
     plugin's   function   is   called.    int   (*error)(const   char
     *plugin_name, unsigned int plugin_type,
         const char *audit_msg, char * const command_info[],
         const char **errstr); The function is called when a plugin or
     the  front-end  returns  an error.  The function arguments are as
     follows: The name of the plugin that generated the error  or  for
     the  front-end.   The type of plugin that generated the error, or
     for the front-end.  An  optional  string  describing  the  plugin
     error.   If the plugin did not provide a description, will be the
     pointer.   An  optional  vector  of  information  describing  the
     command  being  run  in  the  form  of  strings.   The  vector is
     terminated by a pointer.  When parsing the plugin should split on
     the  equal sign since the field will never include one itself but
     the might.  See the section for a list of all  possible  strings.
     If  the  function  returns  a  value other than 1, the plugin may
     store a message describing the failure or error in The front  end
     will  then  pass this value to any registered audit plugins.  The
     string stored in must remain valid until the plugin's function is
     called.  int (*show_version)(int verbose); The function is called
     by when the user specifies the option.  The  plugin  may  display
     its  version information to the user via the or function using If
     the user requests detailed version information, the verbose  flag
     will be set.  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.   See  the  section  for a
     description of See  the  section  for  a  description  of  struct
     sudo_plugin_event * (*event_alloc)(void); The function is used to
     allocate a which provides access to the main event loop.   Unlike
     the  other fields, the pointer is filled in by the front end, not
     by the plugin.  See the section below for more information  about
     events.   NOTE:  the function is only available starting with API
     version 1.17.  If the front end doesn't support API version  1.17
     or  higher,  will  not  be set.  struct approval_plugin { #define
     SUDO_APPROVAL_PLUGIN 4
         unsigned int type; /* always SUDO_APPROVAL_PLUGIN */
         unsigned int version; /* always SUDO_API_VERSION */
         int (*open)(unsigned int version, sudo_conv_t conversation,
             sudo_printf_t sudo_printf, char * const settings[],
             char * const user_info[], int submit_optind,
             char * const submit_argv[], char * const submit_envp[],
             char * const plugin_options[], const char **errstr);
         void (*close)(void);
         int  (*check)(char  *  const  command_info[],  char  *  const
     run_argv[],
             char * const run_envp[], const char **errstr);
         int (*show_version)(int verbose); }; An approval  plugin  can
     be  used  to  apply  extra  constraints  after a command has been
     accepted by the policy plugin.  Unlike the other plugin types, it
     does  not remain open until the command completes.  The plugin is
     opened before a call to or and closed shortly  thereafter  (audit
     plugin  functions  must  be  called before the plugin is closed).
     Multiple approval plugins may be specified in The approval_plugin
     struct  has  the following fields: The field should always be set
     to The field should be set to This allows to  determine  the  API
     version  the  plugin was built against.  int (*open)(unsigned int
     version, sudo_conv_t conversation,
         sudo_printf_t sudo_printf, char * const settings[],
         char * const user_info[], int submit_optind,
         char * const submit_argv[], char * const submit_envp[],
         char * const  plugin_options[],  const  char  **errstr);  The
     approval  function  is  run  immediately  before  a  call  to the
     plugin's or functions.  It is only called if the version is being
     requested  or  if  the  policy  plugin's  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, will print a usage message before it exits.   If  an
     error occurs, the plugin may optionally call the or function with
     to  present  additional  error  information  to  the  user.   The
     function  arguments  are  as  follows:  The  version passed in by
     allows the plugin to determine the major and minor version number
     of the plugin API supported by A pointer to the function that can
     be used by  the  plugin  to  interact  with  the  user  (see  for
     details).   Returns 0 on success and -1 on failure.  A pointer to
     a function that may be used to  display  informational  or  error
     messages  (see  for  details).   Returns the number of characters
     printed on success and -1 on failure.  A vector of  user-supplied
     settings  in  the form of strings.  The vector is terminated by a
     pointer.  These settings correspond to options the user specified
     when  running  As  such,  they  will  only  be  present  when the
     corresponding option has been  specified  on  the  command  line.
     When  parsing the plugin should split on the equal sign since the
     field will never include one  itself  but  the  might.   See  the
     section  for  a  list  of  all  possible  settings.   A vector of
     information about the user running the command  in  the  form  of
     strings.   The  vector  is terminated by a pointer.  When parsing
     the plugin should split on the equal sign since  the  field  will
     never  include  one  itself but the might.  See the section for a
     list of all possible strings.  The index into that corresponds to
     the  first  entry  that  is  not  a command line option.  If only
     consists of options, which may be the case with the  or  options,
     will  evaluate  to  the  NULL  pointer.   The argument vector was
     invoked with, including all command line options.   The  argument
     can  be  used  to  determine the end of the command line options.
     The invoking user's environment  in  the  form  of  a  vector  of
     strings.   When parsing the plugin should split on the equal sign
     since the field will never include one itself but the might.  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 array of strings.  If no arguments were specified,  will  be
     the  pointer.   If the function returns a value other than 1, the
     plugin may store a message describing the failure or error in The
     front  end  will  then  pass  this  value to any registered audit
     plugins.  The string  stored  in  must  remain  valid  until  the
     plugin's  function  is called.  void (*close)(void); The function
     is called after the approval  plugin's  or  functions  have  been
     called.   It  takes no arguments.  The function is typically used
     to perform plugin-specific cleanup, such as the freeing of memory
     objects  allocated by the plugin.  If the plugin does not need to
     perform  any  cleanup,  may  be  set   to   the   pointer.    int
     (*check)(char * const command_info[], char * const run_argv[],
         char * const run_envp[], const char **errstr);  The  approval
     function  is  run after the policy plugin function and before any
     I/O logging plugins.  If multiple approval  plugins  are  loaded,
     they  must all succeed for the command to be allowed.  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, will print a
     usage message before it exits.  If an error  occurs,  the  plugin
     may  optionally  call  the or function with to present additional
     error information to the user.  The  function  arguments  are  as
     follows: A vector of information describing the command being run
     in the form of strings.  The vector is terminated by  a  pointer.
     When  parsing the plugin should split on the equal sign since the
     field will never include one  itself  but  the  might.   See  the
     section  for  a  list of all possible strings.  A argument vector
     describing a command that will be run in the same  form  as  what
     would  be passed to the system call.  The environment the command
     will be run with in the  form  of  a  vector  of  strings.   When
     parsing the plugin should split on the equal sign since the field
     will never include one itself but the  might.   If  the  function
     returns  a  value  other  than  1, the plugin may store a message
     describing the failure or error in The front end will  then  pass
     this value to any registered audit plugins.  The string stored in
     must remain valid until the plugin's  function  is  called.   int
     (*show_version)(int  verbose); The function is called by when the
     user specifies the option.  The plugin may  display  its  version
     information  to  the  user  via the or function using If the user
     requests detailed version information, the verbose flag  will  be
     set.   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.   The  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: If a fatal signal  is  received  before  the
     command is executed, will call the plugin's 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  function.   An
     exception  to  this  is  which  is  ignored  until the command is
     executed.  A  plugin  may  temporarily  install  its  own  signal
     handlers  but must restore the original handler before the plugin
     function returns.  Beginning with plugin API version 1.2,  it  is
     possible  to  install  hooks  for certain functions called by the
     front end.  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 front end functions as
     well.  Hooks in are described by the following structure: 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; }; The structure has the following fields: The
     field  should  be  set  to  The field may be one of the following
     supported hook types: The C  library  function.   Any  registered
     hooks  will  run  before the C library implementation.  The field
     should be a function that matches the following typedef:  typedef
     int (*sudo_hook_fn_setenv_t)(const char *name,
        const char *value,  int  overwrite,  void  *closure);  If  the
     registered  hook  does  not  match  the  typedef  the results are
     unspecified.  The C library function.  Any registered hooks  will
     run  before  the C library implementation.  The field should be a
     function  that  matches  the  following  typedef:   typedef   int
     (*sudo_hook_fn_unsetenv_t)(const char *name,
        void *closure); The C library function.  Any registered  hooks
     will  run  before the C library implementation.  The field should
     be a function that matches the  following  typedef:  typedef  int
     (*sudo_hook_fn_getenv_t)(const char *name,
        char **value, void *closure); If the registered hook does  not
     match  the  typedef  the  results are unspecified.  The C library
     function.  Any registered hooks will run  before  the  C  library
     implementation.   The field should be a function that matches the
     following  typedef:  typedef  int   (*sudo_hook_fn_putenv_t)(char
     *string,
        void *closure); If the registered  hook  does  not  match  the
     typedef the results are unspecified.  sudo_hook_fn_t hook_fn; The
     field should be set to the  plugin's  hook  implementation.   The
     actual function arguments will vary depending on the (see above).
     In all cases, the  field  of  is  passed  as  the  last  function
     parameter.   This  can  be  used  to  pass  arbitrary data to the
     plugin's hook implementation.  The function return value  may  be
     one  of  the  following:  The hook function encountered an error.
     The hook  completed  without  error,  go  on  to  the  next  hook
     (including   the   system  implementation  if  applicable).   For
     example, a hook might return if the specified  variable  was  not
     found in the private copy of the environment.  The hook completed
     without error, stop processing hooks for this  invocation.   This
     can be used to replace the system implementation.  For example, a
     hook that operates on a  private  copy  of  the  environment  but
     leaves  unchanged.   Note  that  it  is  very  easy  to create an
     infinite loop when hooking C library functions.  For  example,  a
     hook   that   calls  the  function  may  create  a  loop  if  the
     implementation calls 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: 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; /* 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,\
                                                   SUDO_HOOK_VERSION_MINOR)
     For  getters  and setters see the When runs a command, it uses an
     event loop to service signals and I/O.  Events may  be  triggered
     based on time, a file or socket descriptor becoming ready, or due
     to receipt of a signal.  Starting with API version  1.15,  it  is
     possible  for  a  plugin  to  participate  in  this event loop by
     calling the function.  Events  are  described  by  the  following
     structure:  typedef void (*sudo_plugin_ev_callback_t)(int fd, int
     what, void *closure);

     struct sudo_plugin_event {
         int (*set)(struct sudo_plugin_event *pev, int fd, int events,
             sudo_plugin_ev_callback_t callback, void *closure);
         int (*add)(struct  sudo_plugin_event  *pev,  struct  timespec
     *timeout);
         int (*del)(struct sudo_plugin_event *pev);
         int (*pending)(struct sudo_plugin_event *pev, int events,
             struct timespec *ts);
         int (*fd)(struct sudo_plugin_event *pev);
         void (*setbase)(struct sudo_plugin_event *pev, void *base);
         void (*loopbreak)(struct sudo_plugin_event *pev);
         void   (*free)(struct   sudo_plugin_event   *pev);   };   The
     sudo_plugin_event   struct   contains   the   following  function
     pointers: int (*set)(struct sudo_plugin_event *pev, int  fd,  int
     events,
         sudo_plugin_ev_callback_t  callback,  void   *closure);   The
     function  takes  the following arguments: A pointer to the struct
     sudo_plugin_event itself.  The  file  or  socket  descriptor  for
     I/O-based  events  or  the  signal number for signal events.  For
     time-based events, must be -1.  The  following  values  determine
     what  will  trigger the event callback: callback is run after the
     specified  timeout  expires  callback  is  run  when   the   file
     descriptor  is  readable callback is run when the file descriptor
     is  writable  event  is  persistent  and  remains  enabled  until
     explicitly  deleted  callback is run when the specified signal is
     received The flag may be ORed with any of the event types.  It is
     also  possible  to  OR  and  together  to run the callback when a
     descriptor is ready to be either read from or  written  to.   All
     other   event   values  are  mutually  exclusive.   typedef  void
     (*sudo_plugin_ev_callback_t)(int fd, int what,
         void *closure);  The  function  to  call  when  an  event  is
     triggered.  The function is run with the following arguments: The
     file or socket descriptor for  I/O-based  events  or  the  signal
     number  for  signal  events.   The event type that triggered that
     callback.  For events that have multiple event types (for example
     and  or  have an associated timeout, can be used to determine why
     the callback was run.  The generic pointer that was specified  in
     the  function.   A  generic  pointer  that  will be passed to the
     callback function.  The function returns 1 on success, and -1  if
     a  error  occurred.   int  (*add)(struct  sudo_plugin_event *pev,
     struct timespec *timeout); The function adds the event  to  event
     loop.   The  event  must have previously been initialized via the
     function.  If the argument is  not  NULL,  it  should  specify  a
     (relative) timeout after which the event will be triggered if the
     main event criteria has not been met.   This  is  often  used  to
     implement  an  I/O  timeout  where  the  event  will  fire  if  a
     descriptor is not ready within a certain  time  period.   If  the
     event  is already present in the event loop, its will be adjusted
     to match the new value,  if  any.   The  function  returns  1  on
     success,   and   -1  if  a  error  occurred.   int  (*del)(struct
     sudo_plugin_event *pev); The  function  deletes  the  event  from
     event  loop.   Deleted events can be added back via the function.
     The function returns 1 on success, and -1 if  a  error  occurred.
     int (*pending)(struct sudo_plugin_event *pev, int events,
         struct timespec *ts); The function can be used  to  determine
     whether  one  or  more events is pending.  The argument specifies
     which events to check for.  See the function for a list of  valid
     event  types.   If  is  specified  in the event has an associated
     timeout and the pointer is non-NULL, it will be  filled  in  with
     the  remaining  time.   int (*fd)(struct sudo_plugin_event *pev);
     The function returns the descriptor or signal  number  associated
     with  the  event  void  (*setbase)(struct sudo_plugin_event *pev,
     void *base); The function sets the underlying event  for  to  the
     specified  value.   This can be used to move an event created via
     to a new event loop allocated by sudo's event subsystem.   If  is
     event  base  is  reset to the default value, which corresponds to
     main event loop.  Using this function requires linking the plugin
     with the sudo_util library.  It is unlikely to be used outside of
     the plugin.  void  (*loopbreak)(struct  sudo_plugin_event  *pev);
     The  function  causes  event  loop  to  exit  immediately and the
     running  command   to   be   terminated.    void   (*free)(struct
     sudo_plugin_event  *pev); The function deletes the event from the
     event loop and frees the memory associated with  it.   The  front
     end  does not support running remote commands.  However, starting
     with 1.8.8, the option may be used to specify a remote host  that
     is  passed  to  the policy plugin.  A plugin may also accept a in
     the form of  which  will  work  with  older  versions  of  It  is
     anticipated that remote commands will be supported by executing a
     program.   The  policy  plugin   should   setup   the   execution
     environment such that the front end will run the helper which, in
     turn, will connect to the remote host and run the  command.   For
     example,  the  policy  plugin  could  utilize  to  perform remote
     command execution.  The helper program would be  responsible  for
     running  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.  Note that remote functionality must be  handled  by
     the  policy  plugin, not 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.  If the plugin needs to
     interact with the user, it may do so via the 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  if  one is to be
     printed.  A 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.   The conversation function takes as arguments pointers
     to the following structures: 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      1023

     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; };  Pointers  to  the  and
     functions  are passed in to the plugin's function when the plugin
     is initialized.  The following type definitions can  be  used  in
     the  declaration  of the function: 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, ...);
     To  use  the  function,  the  plugin  must  pass  an array of and
     structures.  There  must  be  a  and  for  each  message  in  the
     conversation,  that  is, both arrays must have the same number of
     elements.  Each must have its member initialized to The  pointer,
     if  not  should  contain  function pointers to be called when the
     process is suspended and/or resumed  during  conversation  input.
     The  and  functions  are called with the signal that caused to be
     suspended and the pointer from the 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.
     The  must  be set to one of the following values: Prompt the user
     for  input  with  echo  disabled;  this  is  generally  used  for
     passwords.   The  reply  will be stored in the array, and it will
     never be Prompt the user for input with echo enabled.  The  reply
     will  be  stored  in  the  array, and it will never be Display an
     error message.  The message is  written  to  the  standard  error
     unless the flag is set, in which case it is written to the user's
     terminal if possible.  Display a message.  The message is written
     to  the  standard output unless the flag is set, in which case it
     is written to the user's terminal if possible.  Prompt  the  user
     for input but echo an asterisk character for each character read.
     The reply will be stored in the array, and it will never be  This
     can  be used to provide visual feedback to the user while reading
     sensitive information that should not be displayed.  In  addition
     to  the  above  values,  the following flag bits may also be set:
     Allow input to be read when echo  cannot  be  disabled  when  the
     message  type  is or By default, will refuse to read input if the
     echo cannot be disabled for those message types.  When displaying
     a message via or 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.   or was used.  The in seconds until the prompt will
     wait for no  more  input.   A  zero  value  implies  an  infinite
     timeout.   The plugin is responsible for freeing the reply buffer
     located in each if it is not represents the maximum length of the
     reply  buffer  (not  including  the  trailing NUL character).  In
     practical terms, this is the longest password will support.   The
     function  uses  the same underlying mechanism as the function but
     only supports and for the parameter.  It can be  more  convenient
     than  using  the function if no user reply is needed and supports
     standard escape sequences.  See the sample plugin for an  example
     of the function usage.  As of 1.9.0, the plugin and functions are
     called in the following order: audit open  policy  open  approval
     open  approval  close I/O log open command runs command exits I/O
     log close policy close audit close sudo exits Prior to 1.9.0, the
     I/O  log  function  was  called  the policy function.  The 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  and  are  detailed  in  Third  party group plugins
     include a QAS AD plugin available from Quest Software.   A  group
     plugin  must  declare  and populate a struct in the global scope.
     This structure contains pointers to the functions that  implement
     plugin   initialization,   cleanup   and  group  lookup.   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);  };  The  struct  has   the
     following  fields:  The field should be set to GROUP_API_VERSION.
     This allows to determine the API version  the  group  plugin  was
     built    against.    int   (*init)(int   version,   sudo_printf_t
     plugin_printf,
         char *const argv[]); The function is called  after  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
     function with to present  additional  error  information  to  the
     user.   The function arguments are as follows: The version passed
     in by allows the plugin to determine the major and minor  version
     number  of  the  group  plugin  API  supported  by A pointer to a
     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.  A array of arguments  generated  from
     the   option  in  If  no  arguments  were  given,  will  be  void
     (*cleanup)(); The function is called when has finished its  group
     checks.   The  plugin should free any memory it has allocated and
     close open file handles.  int (*query)(const  char  *user,  const
     char *group,
         const struct passwd *pwd); The function is used  to  ask  the
     group plugin whether is a member of The function arguments are as
     follows: The name of the user being looked  up  in  the  external
     group  database.   The  name  of  the  group  being queried.  The
     password database entry for if any.  If is  not  present  in  the
     password  database,  will  be  /*  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) | \
                                GROUP_API_VERSION_MINOR)  For  getters
     and setters see the The following revisions have been made to the
     Sudo Plugin API.  Initial API version.  The I/O logging  plugin's
     function  was  modified  to  take  the  list as an argument.  The
     Policy and I/O logging plugins' functions are now passed  a  list
     of  plugin  parameters if any are specified in A simple hooks API
     has been introduced to allow plugins to hook in to  the  system's
     environment  handling  functions.   The 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.   Support  for
     the entry has been added to the list.  The and entries were added
     to the list.  The and functions are now optional.  Previously,  a
     missing or function would result in a crash.  If no policy plugin
     function is defined, a default function will be provided  by  the
     front  end  that  displays  a warning if the command could not be
     executed.  The front end now installs default signal handlers  to
     trap  common  signals  while  the  plugin functions are run.  The
     entry was added to the list.  The entry was added  to  the  list.
     The  behavior  when  an  I/O  logging plugin returns an error has
     changed.  Previously, the front end took no action  when  the  or
     function  returned  an  error.   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.  The entry was added  to  the  list.
     The  entry  now  starts with a debug file path name and may occur
     multiple times if there are multiple plugin-specific Debug  lines
     in the The and entries were added to the list.  The default value
     of was changed to true in sudo 1.8.16.   The  sudo  function  now
     takes  a pointer to a as its fourth argument.  The 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.   The  entry  was
     added  to  the  list.   The entry was added to the list.  The and
     entries were added to the list.  The entry was added to the list.
     The field was added to the io_plugin struct.  The field was added
     to the io_plugin struct.  The entry was added to the  list.   The
     entry  was  added  to  the  list.   The  field  was  added to the
     policy_plugin and io_plugin structs.  The argument was  added  to
     the policy and I/O plugin functions which the plugin function can
     use to return an error string.  This string may be  used  by  the
     audit  plugin  to  report  failure or error conditions set by the
     other plugins.  The function  is  now  is  called  regardless  of
     whether  or  not  a command was actually executed.  This makes it
     possible for plugins to perform cleanup even when a  command  was
     not  run.   has  increased  from  255 to 1023 bytes.  Support for
     audit and approval plugins was  added.   Initial  resource  limit
     values  were added to the list.  The and enties were added to the
     list.   The   field   was   added   to   the   audit_plugin   and
     approval_plugin  structs.   Many  people  have worked on over the
     years; this version consists of code written  primarily  by:  See
     the      CONTRIBUTORS      file      in      the     distribution
     (https://www.sudo.ws/contributors.html) for an exhaustive list of
     people  who  have contributed to If you feel you have found a bug
     in  please  submit  a  bug  report  at  https://bugzilla.sudo.ws/
     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.  is provided 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 or
     https://www.sudo.ws/license.html for complete details.