File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / sudo / doc / sudo_plugin.mdoc.in
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Oct 14 07:56:34 2013 UTC (10 years, 8 months ago) by misho
Branches: sudo, MAIN
CVS tags: v1_8_8p0, v1_8_8, HEAD
v 1.8.8

    1: .\"
    2: .\" Copyright (c) 2009-2013 Todd C. Miller <Todd.Miller@courtesan.com>
    3: .\"
    4: .\" Permission to use, copy, modify, and distribute this software for any
    5: .\" purpose with or without fee is hereby granted, provided that the above
    6: .\" copyright notice and this permission notice appear in all copies.
    7: .\"
    8: .\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
    9: .\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   10: .\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   11: .\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   12: .\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   13: .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   14: .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   15: .\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   16: .\"
   17: .Dd August 16, 2013
   18: .Dt SUDO_PLUGIN @mansectform@
   19: .Os Sudo @PACKAGE_VERSION@
   20: .Sh NAME
   21: .Nm sudo_plugin
   22: .Nd Sudo Plugin API
   23: .Sh DESCRIPTION
   24: Starting with version 1.8,
   25: .Nm sudo
   26: supports a plugin API
   27: for policy and session logging.
   28: By default, the
   29: .Nm sudoers
   30: policy plugin and an associated I/O logging plugin are used.
   31: Via the plugin API,
   32: .Nm sudo
   33: can be configured to use alternate policy and/or I/O logging plugins
   34: provided by third parties.
   35: The plugins to be used are specified in the
   36: .Xr sudo.conf @mansectform@
   37: file.
   38: .Pp
   39: The API is versioned with a major and minor number.
   40: The minor version number is incremented when additions are made.
   41: The major number is incremented when incompatible changes are made.
   42: A plugin should be check the version passed to it and make sure that the
   43: major version matches.
   44: .Pp
   45: The plugin API is defined by the
   46: .Li sudo_plugin.h
   47: header file.
   48: .Ss Policy plugin API
   49: A policy plugin must declare and populate a
   50: .Li policy_plugin
   51: struct in the global scope.
   52: This structure contains pointers to the functions that implement the
   53: .Nm sudo
   54: policy checks.
   55: The name of the symbol should be specified in
   56: .Xr sudo.conf @mansectform@
   57: along with a path to the plugin so that
   58: .Nm sudo
   59: can load it.
   60: .Bd -literal
   61: struct policy_plugin {
   62: #define SUDO_POLICY_PLUGIN     1
   63:     unsigned int type; /* always SUDO_POLICY_PLUGIN */
   64:     unsigned int version; /* always SUDO_API_VERSION */
   65:     int (*open)(unsigned int version, sudo_conv_t conversation,
   66:                 sudo_printf_t plugin_printf, char * const settings[],
   67:                 char * const user_info[], char * const user_env[],
   68:                 char * const plugin_options[]);
   69:     void (*close)(int exit_status, int error);
   70:     int (*show_version)(int verbose);
   71:     int (*check_policy)(int argc, char * const argv[],
   72:                         char *env_add[], char **command_info[],
   73:                         char **argv_out[], char **user_env_out[]);
   74:     int (*list)(int argc, char * const argv[], int verbose,
   75:                 const char *list_user);
   76:     int (*validate)(void);
   77:     void (*invalidate)(int remove);
   78:     int (*init_session)(struct passwd *pwd, char **user_env[]);
   79:     void (*register_hooks)(int version,
   80:        int (*register_hook)(struct sudo_hook *hook));
   81:     void (*deregister_hooks)(int version,
   82:        int (*deregister_hook)(struct sudo_hook *hook));
   83: };
   84: .Ed
   85: .Pp
   86: The policy_plugin struct has the following fields:
   87: .Bl -tag -width 4n
   88: .It type
   89: The
   90: .Li type
   91: field should always be set to SUDO_POLICY_PLUGIN.
   92: .It version
   93: The
   94: .Li version
   95: field should be set to
   96: .Dv SUDO_API_VERSION .
   97: .Pp
   98: This allows
   99: .Nm sudo
  100: to determine the API version the plugin was
  101: built against.
  102: .It open
  103: .Bd -literal -compact
  104: int (*open)(unsigned int version, sudo_conv_t conversation,
  105:             sudo_printf_t plugin_printf, char * const settings[],
  106:             char * const user_info[], char * const user_env[],
  107:             char * const plugin_options[]);
  108: .Ed
  109: .Pp
  110: Returns 1 on success, 0 on failure, \-1 if a general error occurred,
  111: or \-2 if there was a usage error.
  112: In the latter case,
  113: .Nm sudo
  114: will print a usage message before it exits.
  115: If an error occurs, the plugin may optionally call the
  116: .Fn conversation
  117: or
  118: .Fn plugin_printf
  119: function with
  120: .Dv SUDO_CONF_ERROR_MSG
  121: to present additional error information to the user.
  122: .Pp
  123: The function arguments are as follows:
  124: .Bl -tag -width 4n
  125: .It version
  126: The version passed in by
  127: .Nm sudo
  128: allows the plugin to determine the
  129: major and minor version number of the plugin API supported by
  130: .Nm sudo .
  131: .It conversation
  132: A pointer to the
  133: .Fn conversation
  134: function that can be used by the plugin to interact with the user (see below).
  135: Returns 0 on success and \-1 on failure.
  136: .It plugin_printf
  137: A pointer to a
  138: .Fn printf Ns No -style
  139: function that may be used to display informational or error messages
  140: (see below).
  141: Returns the number of characters printed on success and \-1 on failure.
  142: .It settings
  143: A vector of user-supplied
  144: .Nm sudo
  145: settings in the form of
  146: .Dq name=value
  147: strings.
  148: The vector is terminated by a
  149: .Dv NULL
  150: pointer.
  151: These settings correspond to flags the user specified when running
  152: .Nm sudo .
  153: As such, they will only be present when the corresponding flag has
  154: been specified on the command line.
  155: .Pp
  156: When parsing
  157: .Em settings ,
  158: the plugin should split on the
  159: .Sy first
  160: equal sign
  161: .Pq Ql =
  162: since the
  163: .Em name
  164: field will never include one
  165: itself but the
  166: .Em value
  167: might.
  168: .Bl -tag -width 4n
  169: .It bsdauth_type=string
  170: Authentication type, if specified by the
  171: .Fl a
  172: flag, to use on
  173: systems where BSD authentication is supported.
  174: .It closefrom=number
  175: If specified, the user has requested via the
  176: .Fl C
  177: flag that
  178: .Nm sudo
  179: close all files descriptors with a value of
  180: .Em number
  181: or higher.
  182: The plugin may optionally pass this, or another value, back in the
  183: .Em command_info
  184: list.
  185: .It debug_flags=string
  186: A comma-separated list of debug flags that correspond to
  187: .Nm sudo Ns No 's
  188: .Li Debug
  189: entry in
  190: .Xr sudo.conf @mansectform@ ,
  191: if there is one.
  192: The flags are passed to the plugin as they appear in
  193: .Xr sudo.conf @mansectform@ .
  194: The syntax used by
  195: .Nm sudo
  196: and the
  197: .Nm sudoers
  198: plugin is
  199: .Em subsystem Ns No @ Ns Em priority
  200: but the plugin is free to use a different
  201: format so long as it does not include a comma
  202: .Pq Ql ,\& .
  203: There is not currently a way to specify a set of debug flags specific
  204: to the plugin--the flags are shared by
  205: .Nm sudo
  206: and the plugin.
  207: .It debug_level=number
  208: This setting has been deprecated in favor of
  209: .Em debug_flags .
  210: .It ignore_ticket=bool
  211: Set to true if the user specified the
  212: .Fl k
  213: flag along with a
  214: command, indicating that the user wishes to ignore any cached
  215: authentication credentials.
  216: .Em implied_shell
  217: to true.
  218: This allows
  219: .Nm sudo
  220: with no arguments
  221: to be used similarly to
  222: .Xr su 1 .
  223: If the plugin does not to support this usage, it may return a value of \-2
  224: from the
  225: .Fn check_policy
  226: function, which will cause
  227: .Nm sudo
  228: to print a usage message and
  229: exit.
  230: .It implied_shell=bool
  231: If the user does not specify a program on the command line,
  232: .Nm sudo
  233: will pass the plugin the path to the user's shell and set
  234: .It login_class=string
  235: BSD login class to use when setting resource limits and nice value,
  236: if specified by the
  237: .Fl c
  238: flag.
  239: .It login_shell=bool
  240: Set to true if the user specified the
  241: .Fl i
  242: flag, indicating that
  243: the user wishes to run a login shell.
  244: .It max_groups=int
  245: The maximum number of groups a user may belong to.
  246: This will only be present if there is a corresponding setting in
  247: .Xr sudo.conf @mansectform@ .
  248: .It network_addrs=list
  249: A space-separated list of IP network addresses and netmasks in the
  250: form
  251: .Dq addr/netmask ,
  252: e.g.\&
  253: .Dq 192.168.1.2/255.255.255.0 .
  254: The address and netmask pairs may be either IPv4 or IPv6, depending on
  255: what the operating system supports.
  256: If the address contains a colon
  257: .Pq Ql :\& ,
  258: it is an IPv6 address, else it is IPv4.
  259: .It noninteractive=bool
  260: Set to true if the user specified the
  261: .Fl n
  262: flag, indicating that
  263: .Nm sudo
  264: should operate in non-interactive mode.
  265: The plugin may reject a command run in non-interactive mode if user
  266: interaction is required.
  267: .It plugin_dir=string
  268: The default plugin directory used by the
  269: .Nm sudo
  270: front end.
  271: This is the default directory set at compile time and may not
  272: correspond to the directory the running plugin was loaded from.
  273: It may be used by a plugin to locate support files.
  274: .It preserve_environment=bool
  275: Set to true if the user specified the
  276: .Fl E
  277: flag, indicating that
  278: the user wishes to preserve the environment.
  279: .It preserve_groups=bool
  280: Set to true if the user specified the
  281: .Fl P
  282: flag, indicating that
  283: the user wishes to preserve the group vector instead of setting it
  284: based on the runas user.
  285: .It progname=string
  286: The command name that sudo was run as, typically
  287: .Dq sudo
  288: or
  289: .Dq sudoedit .
  290: .It prompt=string
  291: The prompt to use when requesting a password, if specified via
  292: the
  293: .Fl p
  294: flag.
  295: .It remote_host=string
  296: The name of the remote host to run the command on, if specified via
  297: the
  298: .Fl h
  299: option.
  300: Support for running the command on a remote host is meant to be implemented
  301: via a helper program that is executed in place of the user-specified command.
  302: The
  303: .Nm sudo
  304: front end is only capable of executing commands on the local host.
  305: Only available starting with API version 1.4.
  306: .It run_shell=bool
  307: Set to true if the user specified the
  308: .Fl s
  309: flag, indicating that the user wishes to run a shell.
  310: .It runas_group=string
  311: The group name or gid to run the command as, if specified via
  312: the
  313: .Fl g
  314: flag.
  315: .It runas_user=string
  316: The user name or uid to run the command as, if specified via the
  317: .Fl u
  318: flag.
  319: .It selinux_role=string
  320: SELinux role to use when executing the command, if specified by
  321: the
  322: .Fl r
  323: flag.
  324: .It selinux_type=string
  325: SELinux type to use when executing the command, if specified by
  326: the
  327: .Fl t
  328: flag.
  329: .It set_home=bool
  330: Set to true if the user specified the
  331: .Fl H
  332: flag.
  333: If true, set the
  334: .Li HOME
  335: environment variable to the target user's home directory.
  336: .It sudoedit=bool
  337: Set to true when the
  338: .Fl e
  339: flag is is specified or if invoked as
  340: .Nm sudoedit .
  341: The plugin shall substitute an editor into
  342: .Em argv
  343: in the
  344: .Fn check_policy
  345: function or return \-2 with a usage error
  346: if the plugin does not support
  347: .Em sudoedit .
  348: For more information, see the
  349: .Em check_policy
  350: section.
  351: .El
  352: .Pp
  353: Additional settings may be added in the future so the plugin should
  354: silently ignore settings that it does not recognize.
  355: .It user_info
  356: A vector of information about the user running the command in the form of
  357: .Dq name=value
  358: strings.
  359: The vector is terminated by a
  360: .Dv NULL
  361: pointer.
  362: .Pp
  363: When parsing
  364: .Em user_info ,
  365: the plugin should split on the
  366: .Sy first
  367: equal sign
  368: .Pq Ql =
  369: since the
  370: .Em name
  371: field will never include one
  372: itself but the
  373: .Em value
  374: might.
  375: .Bl -tag -width 4n
  376: .It cols=int
  377: The number of columns the user's terminal supports.
  378: If there is no terminal device available, a default value of 80 is used.
  379: .It cwd=string
  380: The user's current working directory.
  381: .It egid=gid_t
  382: The effective group ID of the user invoking
  383: .Nm sudo .
  384: .It euid=uid_t
  385: The effective user ID of the user invoking
  386: .Nm sudo .
  387: .It gid=gid_t
  388: The real group ID of the user invoking
  389: .Nm sudo .
  390: .It groups=list
  391: The user's supplementary group list formatted as a string of
  392: comma-separated group IDs.
  393: .It host=string
  394: The local machine's hostname as returned by the
  395: .Xr gethostname 2
  396: system call.
  397: .It lines=int
  398: The number of lines the user's terminal supports.
  399: If there is
  400: no terminal device available, a default value of 24 is used.
  401: .It pgid=int
  402: The ID of the process group that the running
  403: .Nm sudo
  404: process is a member of.
  405: Only available starting with API version 1.2.
  406: .It pid=int
  407: The process ID of the running
  408: .Nm sudo
  409: process.
  410: Only available starting with API version 1.2.
  411: .It plugin_options
  412: Any (non-comment) strings immediately after the plugin path are
  413: passed as arguments to the plugin.
  414: These arguments are split on a white space boundary and are passed to
  415: the plugin in the form of a
  416: .Dv NULL Ns No -terminated
  417: array of strings.
  418: If no arguments were
  419: specified,
  420: .Em plugin_options
  421: will be the
  422: .Dv NULL
  423: pointer.
  424: .Pp
  425: NOTE: the
  426: .Em plugin_options
  427: parameter is only available starting with
  428: API version 1.2.
  429: A plugin
  430: .Sy must
  431: check the API version specified
  432: by the
  433: .Nm sudo
  434: front end before using
  435: .Em plugin_options .
  436: Failure to do so may result in a crash.
  437: .It ppid=int
  438: The parent process ID of the running
  439: .Nm sudo
  440: process.
  441: Only available starting with API version 1.2.
  442: .It sid=int
  443: The session ID of the running
  444: .Nm sudo
  445: process or 0 if
  446: .Nm sudo
  447: is not part of a POSIX job control session.
  448: Only available starting with API version 1.2.
  449: .It tcpgid=int
  450: The ID of the foreground process group associated with the terminal
  451: device associated with the
  452: .Nm sudo
  453: process or \-1 if there is no
  454: terminal present.
  455: Only available starting with API version 1.2.
  456: .It tty=string
  457: The path to the user's terminal device.
  458: If the user has no terminal device associated with the session,
  459: the value will be empty, as in
  460: .Dq Li tty= .
  461: .It uid=uid_t
  462: The real user ID of the user invoking
  463: .Nm sudo .
  464: .It user=string
  465: The name of the user invoking
  466: .Nm sudo .
  467: .El
  468: .It user_env
  469: The user's environment in the form of a
  470: .Dv NULL Ns No -terminated vector of
  471: .Dq name=value
  472: strings.
  473: .Pp
  474: When parsing
  475: .Em user_env ,
  476: the plugin should split on the
  477: .Sy first
  478: equal sign
  479: .Pq Ql =
  480: since the
  481: .Em name
  482: field will never include one
  483: itself but the
  484: .Em value
  485: might.
  486: .El
  487: .It close
  488: .Bd -literal -compact
  489: void (*close)(int exit_status, int error);
  490: .Ed
  491: .Pp
  492: The
  493: .Fn close
  494: function is called when the command being run by
  495: .Nm sudo
  496: finishes.
  497: .Pp
  498: The function arguments are as follows:
  499: .Bl -tag -width 4n
  500: .It exit_status
  501: The command's exit status, as returned by the
  502: .Xr wait 2
  503: system call.
  504: The value of
  505: .Li exit_status
  506: is undefined if
  507: .Li error
  508: is non-zero.
  509: .It error
  510: If the command could not be executed, this is set to the value of
  511: .Li errno
  512: set by the
  513: .Xr execve 2
  514: system call.
  515: The plugin is responsible for displaying error information via the
  516: .Fn conversation
  517: or
  518: .Fn plugin_printf
  519: function.
  520: If the command was successfully executed, the value of
  521: .Li error
  522: is 0.
  523: .El
  524: .Pp
  525: If no
  526: .Fn close
  527: function is defined, no I/O logging plugins are loaded,
  528: and neither the
  529: .Em timeout
  530: not
  531: .Em use_pty
  532: options are set in the
  533: .Li command_info
  534: list, the
  535: .Nm sudo
  536: front end may execute the command directly instead of running
  537: it as a child process.
  538: .It show_version
  539: .Bd -literal -compact
  540: int (*show_version)(int verbose);
  541: .Ed
  542: .Pp
  543: The
  544: .Fn show_version
  545: function is called by
  546: .Nm sudo
  547: when the user specifies
  548: the
  549: .Fl V
  550: option.
  551: The plugin may display its version information to the user via the
  552: .Fn conversation
  553: or
  554: .Fn plugin_printf
  555: function using
  556: .Dv SUDO_CONV_INFO_MSG .
  557: If the user requests detailed version information, the verbose flag will be set.
  558: .It check_policy
  559: .Bd -literal -compact
  560: int (*check_policy)(int argc, char * const argv[]
  561:                     char *env_add[], char **command_info[],
  562:                     char **argv_out[], char **user_env_out[]);
  563: .Ed
  564: .Pp
  565: The
  566: .Fn check_policy
  567: function is called by
  568: .Nm sudo
  569: to determine
  570: whether the user is allowed to run the specified commands.
  571: .Pp
  572: If the
  573: .Em sudoedit
  574: option was enabled in the
  575: .Em settings
  576: array
  577: passed to the
  578: .Fn open
  579: function, the user has requested
  580: .Em sudoedit
  581: mode.
  582: .Em sudoedit
  583: is a mechanism for editing one or more files
  584: where an editor is run with the user's credentials instead of with
  585: elevated privileges.
  586: .Nm sudo
  587: achieves this by creating user-writable
  588: temporary copies of the files to be edited and then overwriting the
  589: originals with the temporary copies after editing is complete.
  590: If the plugin supports
  591: .Em sudoedit ,
  592: it should choose the editor to be used, potentially from a variable
  593: in the user's environment, such as
  594: .Li EDITOR ,
  595: and include it in
  596: .Em argv_out
  597: (note that environment
  598: variables may include command line flags).
  599: The files to be edited should be copied from
  600: .Em argv
  601: into
  602: .Em argv_out ,
  603: separated from the
  604: editor and its arguments by a
  605: .Dq Li --
  606: element.
  607: The
  608: .Dq Li --
  609: will
  610: be removed by
  611: .Nm sudo
  612: before the editor is executed.
  613: The plugin should also set
  614: .Em sudoedit=true
  615: in the
  616: .Em command_info
  617: list.
  618: .Pp
  619: The
  620: .Fn check_policy
  621: function returns 1 if the command is allowed,
  622: 0 if not allowed, \-1 for a general error, or \-2 for a usage error
  623: or if
  624: .Em sudoedit
  625: was specified but is unsupported by the plugin.
  626: In the latter case,
  627: .Nm sudo
  628: will print a usage message before it
  629: exits.
  630: If an error occurs, the plugin may optionally call the
  631: .Fn conversation
  632: or
  633: .Fn plugin_printf
  634: function with
  635: .Dv SUDO_CONF_ERROR_MSG
  636: to present additional error information to the user.
  637: .Pp
  638: The function arguments are as follows:
  639: .Bl -tag -width 4n
  640: .It argc
  641: The number of elements in
  642: .Em argv ,
  643: not counting the final
  644: .Dv NULL
  645: pointer.
  646: .It argv
  647: The argument vector describing the command the user wishes to run,
  648: in the same form as what would be passed to the
  649: .Xr execve 2
  650: system call.
  651: The vector is terminated by a
  652: .Dv NULL
  653: pointer.
  654: .It env_add
  655: Additional environment variables specified by the user on the command
  656: line in the form of a
  657: .Dv NULL Ns No -terminated
  658: vector of
  659: .Dq name=value
  660: strings.
  661: The plugin may reject the command if one or more variables
  662: are not allowed to be set, or it may silently ignore such variables.
  663: .Pp
  664: When parsing
  665: .Em env_add ,
  666: the plugin should split on the
  667: .Sy first
  668: equal sign
  669: .Pq Ql =
  670: since the
  671: .Em name
  672: field will never include one
  673: itself but the
  674: .Em value
  675: might.
  676: .It command_info
  677: Information about the command being run in the form of
  678: .Dq name=value
  679: strings.
  680: These values are used by
  681: .Nm sudo
  682: to set the execution
  683: environment when running a command.
  684: The plugin is responsible for creating and populating the vector,
  685: which must be terminated with a
  686: .Dv NULL
  687: pointer.
  688: The following values are recognized by
  689: .Nm sudo :
  690: .Bl -tag -width 4n
  691: .It chroot=string
  692: The root directory to use when running the command.
  693: .It closefrom=number
  694: If specified,
  695: .Nm sudo
  696: will close all files descriptors with a value
  697: of
  698: .Em number
  699: or higher.
  700: .It command=string
  701: Fully qualified path to the command to be executed.
  702: .It cwd=string
  703: The current working directory to change to when executing the command.
  704: .It exec_background=bool
  705: By default,
  706: .Nm sudo
  707: runs a command as the foreground process as long as
  708: .Nm sudo
  709: itself is running in the foreground.
  710: When
  711: .Em exec_background
  712: is enabled and the command is being run in a pty (due to I/O logging
  713: or the
  714: .Em use_pty
  715: setting), the command will be run as a background process.
  716: Attempts to read from the controlling terminal (or to change terminal
  717: settings) will result in the command being suspended with the
  718: .Dv SIGTTIN
  719: signal (or
  720: .Dv SIGTTOU
  721: in the case of terminal settings).
  722: If this happens when
  723: .Nm sudo
  724: is a foreground process, the command will be granted the controlling terminal
  725: and resumed in the foreground with no user intervention required.
  726: The advantage of initially running the command in the background is that
  727: .Nm sudo
  728: need not read from the terminal unless the command explicitly requests it.
  729: Otherwise, any terminal input must be passed to the command, whether it
  730: has required it or not (the kernel buffers terminals so it is not possible
  731: to tell whether the command really wants the input).
  732: This is different from historic
  733: .Em sudo
  734: behavior or when the command is not being run in a pty.
  735: .Pp
  736: For this to work seamlessly, the operating system must support the
  737: automatic restarting of system calls.
  738: Unfortunately, not all operating systems do this by default,
  739: and even those that do may have bugs.
  740: For example, Mac OS X fails to restart the
  741: .Fn tcgetattr
  742: and
  743: .Fn tcsetattr
  744: system calls (this is a bug in Mac OS X).
  745: Furthermore, because this behavior depends on the command stopping with the
  746: .Dv SIGTTIN
  747: or
  748: .Dv SIGTTOU
  749: signals, programs that catch these signals and suspend themselves
  750: with a different signal (usually
  751: .Dv SIGTOP )
  752: will not be automatically foregrounded.
  753: Some versions of the linux
  754: .Xr su 1
  755: command behave this way.
  756: Because of this, a plugin should not set
  757: .Em exec_background
  758: unless it is explicitly enabled by the administrator and there should
  759: be a way to enabled or disable it on a per-command basis.
  760: .Pp
  761: This setting has no effect unless I/O logging is enabled or
  762: .Em use_pty
  763: is enabled.
  764: .It iolog_compress=bool
  765: Set to true if the I/O logging plugins, if any, should compress the
  766: log data.
  767: This is a hint to the I/O logging plugin which may choose to ignore it.
  768: .It iolog_path=string
  769: Fully qualified path to the file or directory in which I/O log is
  770: to be stored.
  771: This is a hint to the I/O logging plugin which may choose to ignore it.
  772: If no I/O logging plugin is loaded, this setting has no effect.
  773: .It iolog_stdin=bool
  774: Set to true if the I/O logging plugins, if any, should log the
  775: standard input if it is not connected to a terminal device.
  776: This is a hint to the I/O logging plugin which may choose to ignore it.
  777: .It iolog_stdout=bool
  778: Set to true if the I/O logging plugins, if any, should log the
  779: standard output if it is not connected to a terminal device.
  780: This is a hint to the I/O logging plugin which may choose to ignore it.
  781: .It iolog_stderr=bool
  782: Set to true if the I/O logging plugins, if any, should log the
  783: standard error if it is not connected to a terminal device.
  784: This is a hint to the I/O logging plugin which may choose to ignore it.
  785: .It iolog_ttyin=bool
  786: Set to true if the I/O logging plugins, if any, should log all
  787: terminal input.
  788: This only includes input typed by the user and not from a pipe or
  789: redirected from a file.
  790: This is a hint to the I/O logging plugin which may choose to ignore it.
  791: .It iolog_ttyout=bool
  792: Set to true if the I/O logging plugins, if any, should log all
  793: terminal output.
  794: This only includes output to the screen, not output to a pipe or file.
  795: This is a hint to the I/O logging plugin which may choose to ignore it.
  796: .It login_class=string
  797: BSD login class to use when setting resource limits and nice value
  798: (optional).
  799: This option is only set on systems that support login classes.
  800: .It nice=int
  801: Nice value (priority) to use when executing the command.
  802: The nice value, if specified, overrides the priority associated with the
  803: .Em login_class
  804: on BSD systems.
  805: .It noexec=bool
  806: If set, prevent the command from executing other programs.
  807: .It preserve_groups=bool
  808: If set,
  809: .Nm sudo
  810: will preserve the user's group vector instead of
  811: initializing the group vector based on
  812: .Li runas_user .
  813: .It runas_egid=gid
  814: Effective group ID to run the command as.
  815: If not specified, the value of
  816: .Em runas_gid
  817: is used.
  818: .It runas_euid=uid
  819: Effective user ID to run the command as.
  820: If not specified, the value of
  821: .Em runas_uid
  822: is used.
  823: .It runas_gid=gid
  824: Group ID to run the command as.
  825: .It runas_groups=list
  826: The supplementary group vector to use for the command in the form
  827: of a comma-separated list of group IDs.
  828: If
  829: .Em preserve_groups
  830: is set, this option is ignored.
  831: .It runas_uid=uid
  832: User ID to run the command as.
  833: .It selinux_role=string
  834: SELinux role to use when executing the command.
  835: .It selinux_type=string
  836: SELinux type to use when executing the command.
  837: .It set_utmp=bool
  838: Create a utmp (or utmpx) entry when a pseudo-tty is allocated.
  839: By default, the new entry will be a copy of the user's existing utmp
  840: entry (if any), with the tty, time, type and pid fields updated.
  841: .It sudoedit=bool
  842: Set to true when in
  843: .Em sudoedit
  844: mode.
  845: The plugin may enable
  846: .Em sudoedit
  847: mode even if
  848: .Nm sudo
  849: was not invoked as
  850: .Nm sudoedit .
  851: This allows the plugin to perform command substitution and transparently
  852: enable
  853: .Em sudoedit
  854: when the user attempts to run an editor.
  855: .It timeout=int
  856: Command timeout.
  857: If non-zero then when the timeout expires the command will be killed.
  858: .It umask=octal
  859: The file creation mask to use when executing the command.
  860: .It use_pty=bool
  861: Allocate a pseudo-tty to run the command in, regardless of whether
  862: or not I/O logging is in use.
  863: By default,
  864: .Nm sudo
  865: will only run
  866: the command in a pty when an I/O log plugin is loaded.
  867: .It utmp_user=string
  868: User name to use when constructing a new utmp (or utmpx) entry when
  869: .Em set_utmp
  870: is enabled.
  871: This option can be used to set the user field in the utmp entry to
  872: the user the command runs as rather than the invoking user.
  873: If not set,
  874: .Nm sudo
  875: will base the new entry on
  876: the invoking user's existing entry.
  877: .El
  878: .Pp
  879: Unsupported values will be ignored.
  880: .It argv_out
  881: The
  882: .Dv NULL Ns No -terminated
  883: argument vector to pass to the
  884: .Xr execve 2
  885: system call when executing the command.
  886: The plugin is responsible for allocating and populating the vector.
  887: .It user_env_out
  888: The
  889: .Dv NULL Ns No -terminated
  890: environment vector to use when executing the command.
  891: The plugin is responsible for allocating and populating the vector.
  892: .El
  893: .It list
  894: .Bd -literal -compact
  895: int (*list)(int verbose, const char *list_user,
  896:             int argc, char * const argv[]);
  897: .Ed
  898: .Pp
  899: List available privileges for the invoking user.
  900: Returns 1 on success, 0 on failure and \-1 on error.
  901: On error, the plugin may optionally call the
  902: .Fn conversation
  903: or
  904: .Fn plugin_printf
  905: function with
  906: .Dv SUDO_CONF_ERROR_MSG
  907: to present additional error information to
  908: the user.
  909: .Pp
  910: Privileges should be output via the
  911: .Fn conversation
  912: or
  913: .Fn plugin_printf
  914: function using
  915: .Dv SUDO_CONV_INFO_MSG ,
  916: .Bl -tag -width 4n
  917: .It verbose
  918: Flag indicating whether to list in verbose mode or not.
  919: .It list_user
  920: The name of a different user to list privileges for if the policy
  921: allows it.
  922: If
  923: .Dv NULL ,
  924: the plugin should list the privileges of the invoking user.
  925: .It argc
  926: The number of elements in
  927: .Em argv ,
  928: not counting the final
  929: .Dv NULL
  930: pointer.
  931: .It argv
  932: If
  933: .No non- Ns Dv NULL ,
  934: an argument vector describing a command the user
  935: wishes to check against the policy in the same form as what would
  936: be passed to the
  937: .Xr execve 2
  938: system call.
  939: If the command is permitted by the policy, the fully-qualified path
  940: to the command should be displayed along with any command line arguments.
  941: .El
  942: .It validate
  943: .Bd -literal -compact
  944: int (*validate)(void);
  945: .Ed
  946: .Pp
  947: The
  948: .Fn validate
  949: function is called when
  950: .Nm sudo
  951: is run with the
  952: .Fl v
  953: flag.
  954: For policy plugins such as
  955: .Nm sudoers
  956: that cache
  957: authentication credentials, this function will validate and cache
  958: the credentials.
  959: .Pp
  960: The
  961: .Fn validate
  962: function should be
  963: .Dv NULL
  964: if the plugin does not support credential caching.
  965: .Pp
  966: Returns 1 on success, 0 on failure and \-1 on error.
  967: On error, the plugin may optionally call the
  968: .Fn conversation
  969: or
  970: .Fn plugin_printf
  971: function with
  972: .Dv SUDO_CONF_ERROR_MSG
  973: to present additional
  974: error information to the user.
  975: .It invalidate
  976: .Bd -literal -compact
  977: void (*invalidate)(int remove);
  978: .Ed
  979: .Pp
  980: The
  981: .Fn invalidate
  982: function is called when
  983: .Nm sudo
  984: is called with
  985: the
  986: .Fl k
  987: or
  988: .Fl K
  989: flag.
  990: For policy plugins such as
  991: .Nm sudoers
  992: that
  993: cache authentication credentials, this function will invalidate the
  994: credentials.
  995: If the
  996: .Em remove
  997: flag is set, the plugin may remove
  998: the credentials instead of simply invalidating them.
  999: .Pp
 1000: The
 1001: .Fn invalidate
 1002: function should be
 1003: .Dv NULL
 1004: if the plugin does not support credential caching.
 1005: .It init_session
 1006: .Bd -literal -compact
 1007: int (*init_session)(struct passwd *pwd, char **user_envp[);
 1008: .Ed
 1009: .Pp
 1010: The
 1011: .Fn init_session
 1012: function is called before
 1013: .Nm sudo
 1014: sets up the
 1015: execution environment for the command.
 1016: It is run in the parent
 1017: .Nm sudo
 1018: process and before any uid or gid changes.
 1019: This can be used to perform session setup that is not supported by
 1020: .Em command_info ,
 1021: such as opening the PAM session.
 1022: The
 1023: .Fn close
 1024: function can be
 1025: used to tear down the session that was opened by
 1026: .Li init_session .
 1027: .Pp
 1028: The
 1029: .Em pwd
 1030: argument points to a passwd struct for the user the
 1031: command will be run as if the uid the command will run as was found
 1032: in the password database, otherwise it will be
 1033: .Dv NULL .
 1034: .Pp
 1035: The
 1036: .Em user_env
 1037: argument points to the environment the command will
 1038: run in, in the form of a
 1039: .Dv NULL Ns No -terminated
 1040: vector of
 1041: .Dq name=value
 1042: strings.
 1043: This is the same string passed back to the front end via
 1044: the Policy Plugin's
 1045: .Em user_env_out
 1046: parameter.
 1047: If the
 1048: .Fn init_session
 1049: function needs to modify the user environment, it should update the
 1050: pointer stored in
 1051: .Em user_env .
 1052: The expected use case is to merge the contents of the PAM environment
 1053: (if any) with the contents of
 1054: .Em user_env .
 1055: NOTE: the
 1056: .Em user_env
 1057: parameter is only available
 1058: starting with API version 1.2.
 1059: A plugin
 1060: .Sy must
 1061: check the API
 1062: version specified by the
 1063: .Nm sudo
 1064: front end before using
 1065: .Em user_env .
 1066: Failure to do so may result in a crash.
 1067: .Pp
 1068: Returns 1 on success, 0 on failure and \-1 on error.
 1069: On error, the plugin may optionally call the
 1070: .Fn conversation
 1071: or
 1072: .Fn plugin_printf
 1073: function with
 1074: .Dv SUDO_CONF_ERROR_MSG
 1075: to present additional
 1076: error information to the user.
 1077: .It register_hooks
 1078: .Bd -literal -compact
 1079: void (*register_hooks)(int version,
 1080:    int (*register_hook)(struct sudo_hook *hook));
 1081: .Ed
 1082: .Pp
 1083: The
 1084: .Fn register_hooks
 1085: function is called by the sudo front end to
 1086: register any hooks the plugin needs.
 1087: If the plugin does not support hooks,
 1088: .Li register_hooks
 1089: should be set to the
 1090: .Dv NULL
 1091: pointer.
 1092: .Pp
 1093: The
 1094: .Em version
 1095: argument describes the version of the hooks API
 1096: supported by the
 1097: .Nm sudo
 1098: front end.
 1099: .Pp
 1100: The
 1101: .Fn register_hook
 1102: function should be used to register any supported
 1103: hooks the plugin needs.
 1104: It returns 0 on success, 1 if the hook type is not supported and \-1
 1105: if the major version in
 1106: .Li struct hook
 1107: does not match the front end's major hook API version.
 1108: .Pp
 1109: See the
 1110: .Sx Hook function API
 1111: section below for more information
 1112: about hooks.
 1113: .Pp
 1114: NOTE: the
 1115: .Fn register_hooks
 1116: function is only available starting
 1117: with API version 1.2.
 1118: If the
 1119: .Nm sudo
 1120: front end doesn't support API
 1121: version 1.2 or higher,
 1122: .Li register_hooks
 1123: will not be called.
 1124: .It deregister_hooks
 1125: .Bd -literal -compact
 1126: void (*deregister_hooks)(int version,
 1127:    int (*deregister_hook)(struct sudo_hook *hook));
 1128: .Ed
 1129: .Pp
 1130: The
 1131: .Fn deregister_hooks
 1132: function is called by the sudo front end
 1133: to deregister any hooks the plugin has registered.
 1134: If the plugin does not support hooks,
 1135: .Li deregister_hooks
 1136: should be set to the
 1137: .Dv NULL
 1138: pointer.
 1139: .Pp
 1140: The
 1141: .Em version
 1142: argument describes the version of the hooks API
 1143: supported by the
 1144: .Nm sudo
 1145: front end.
 1146: .Pp
 1147: The
 1148: .Fn deregister_hook
 1149: function should be used to deregister any
 1150: hooks that were put in place by the
 1151: .Fn register_hook
 1152: function.
 1153: If the plugin tries to deregister a hook that the front end does not support,
 1154: .Li deregister_hook
 1155: will return an error.
 1156: .Pp
 1157: See the
 1158: .Sx Hook function API
 1159: section below for more information
 1160: about hooks.
 1161: .Pp
 1162: NOTE: the
 1163: .Fn deregister_hooks
 1164: function is only available starting
 1165: with API version 1.2.
 1166: If the
 1167: .Nm sudo
 1168: front end doesn't support API
 1169: version 1.2 or higher,
 1170: .Li deregister_hooks
 1171: will not be called.
 1172: .El
 1173: .Pp
 1174: .Em Policy Plugin Version Macros
 1175: .Bd -literal
 1176: /* Plugin API version major/minor. */
 1177: #define SUDO_API_VERSION_MAJOR 1
 1178: #define SUDO_API_VERSION_MINOR 2
 1179: #define SUDO_API_MKVERSION(x, y) ((x << 16) | y)
 1180: #define SUDO_API_VERSION SUDO_API_MKVERSION(SUDO_API_VERSION_MAJOR,\e
 1181:                                             SUDO_API_VERSION_MINOR)
 1182: 
 1183: /* Getters and setters for API version */
 1184: #define SUDO_API_VERSION_GET_MAJOR(v) ((v) >> 16)
 1185: #define SUDO_API_VERSION_GET_MINOR(v) ((v) & 0xffff)
 1186: #define SUDO_API_VERSION_SET_MAJOR(vp, n) do { \e
 1187:     *(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \e
 1188: } while(0)
 1189: #define SUDO_VERSION_SET_MINOR(vp, n) do { \e
 1190:     *(vp) = (*(vp) & 0xffff0000) | (n); \e
 1191: } while(0)
 1192: .Ed
 1193: .Ss I/O plugin API
 1194: .Bd -literal
 1195: struct io_plugin {
 1196: #define SUDO_IO_PLUGIN 2
 1197:     unsigned int type; /* always SUDO_IO_PLUGIN */
 1198:     unsigned int version; /* always SUDO_API_VERSION */
 1199:     int (*open)(unsigned int version, sudo_conv_t conversation,
 1200:                 sudo_printf_t plugin_printf, char * const settings[],
 1201:                 char * const user_info[], char * const command_info[],
 1202:                 int argc, char * const argv[], char * const user_env[],
 1203:                 char * const plugin_options[]);
 1204:     void (*close)(int exit_status, int error); /* wait status or error */
 1205:     int (*show_version)(int verbose);
 1206:     int (*log_ttyin)(const char *buf, unsigned int len);
 1207:     int (*log_ttyout)(const char *buf, unsigned int len);
 1208:     int (*log_stdin)(const char *buf, unsigned int len);
 1209:     int (*log_stdout)(const char *buf, unsigned int len);
 1210:     int (*log_stderr)(const char *buf, unsigned int len);
 1211:     void (*register_hooks)(int version,
 1212:        int (*register_hook)(struct sudo_hook *hook));
 1213:     void (*deregister_hooks)(int version,
 1214:        int (*deregister_hook)(struct sudo_hook *hook));
 1215: };
 1216: .Ed
 1217: .Pp
 1218: When an I/O plugin is loaded,
 1219: .Nm sudo
 1220: runs the command in a pseudo-tty.
 1221: This makes it possible to log the input and output from the user's
 1222: session.
 1223: If any of the standard input, standard output or standard error do not
 1224: correspond to a tty,
 1225: .Nm sudo
 1226: will open a pipe to capture
 1227: the I/O for logging before passing it on.
 1228: .Pp
 1229: The log_ttyin function receives the raw user input from the terminal
 1230: device (note that this will include input even when echo is disabled,
 1231: such as when a password is read).
 1232: The log_ttyout function receives output from the pseudo-tty that is
 1233: suitable for replaying the user's session at a later time.
 1234: The
 1235: .Fn log_stdin ,
 1236: .Fn log_stdout
 1237: and
 1238: .Fn log_stderr
 1239: functions are only called if the standard input, standard output
 1240: or standard error respectively correspond to something other than
 1241: a tty.
 1242: .Pp
 1243: Any of the logging functions may be set to the
 1244: .Dv NULL
 1245: pointer if no logging is to be performed.
 1246: If the open function returns 0, no I/O will be sent to the plugin.
 1247: .Pp
 1248: The io_plugin struct has the following fields:
 1249: .Bl -tag -width 4n
 1250: .It type
 1251: The
 1252: .Li type
 1253: field should always be set to
 1254: .Dv SUDO_IO_PLUGIN .
 1255: .It version
 1256: The
 1257: .Li version
 1258: field should be set to
 1259: .Dv SUDO_API_VERSION .
 1260: .Pp
 1261: This allows
 1262: .Nm sudo
 1263: to determine the API version the plugin was
 1264: built against.
 1265: .It open
 1266: .Bd -literal -compact
 1267: int (*open)(unsigned int version, sudo_conv_t conversation,
 1268:             sudo_printf_t plugin_printf, char * const settings[],
 1269:             char * const user_info[], int argc, char * const argv[],
 1270:             char * const user_env[], char * const plugin_options[]);
 1271: .Ed
 1272: .Pp
 1273: The
 1274: .Fn open
 1275: function is run before the
 1276: .Fn log_input ,
 1277: .Fn log_output
 1278: or
 1279: .Fn show_version
 1280: functions are called.
 1281: It is only called if the version is being requested or the
 1282: .Fn check_policy
 1283: function has
 1284: returned successfully.
 1285: It returns 1 on success, 0 on failure, \-1 if a general error occurred,
 1286: or \-2 if there was a usage error.
 1287: In the latter case,
 1288: .Nm sudo
 1289: will print a usage message before it exits.
 1290: If an error occurs, the plugin may optionally call the
 1291: .Fn conversation
 1292: or
 1293: .Fn plugin_printf
 1294: function with
 1295: .Dv SUDO_CONF_ERROR_MSG
 1296: to present
 1297: additional error information to the user.
 1298: .Pp
 1299: The function arguments are as follows:
 1300: .Bl -tag -width 4n
 1301: .It version
 1302: The version passed in by
 1303: .Nm sudo
 1304: allows the plugin to determine the
 1305: major and minor version number of the plugin API supported by
 1306: .Nm sudo .
 1307: .It conversation
 1308: A pointer to the
 1309: .Fn conversation
 1310: function that may be used by the
 1311: .Fn show_version
 1312: function to display version information (see
 1313: .Fn show_version
 1314: below).
 1315: The
 1316: .Fn conversation
 1317: function may also be used to display additional error message to the user.
 1318: The
 1319: .Fn conversation
 1320: function returns 0 on success and \-1 on failure.
 1321: .It plugin_printf
 1322: A pointer to a
 1323: .Fn printf Ns No -style
 1324: function that may be used by the
 1325: .Fn show_version
 1326: function to display version information (see
 1327: show_version below).
 1328: The
 1329: .Fn plugin_printf
 1330: function may also be used to display additional error message to the user.
 1331: The
 1332: .Fn plugin_printf
 1333: function returns number of characters printed on success and \-1 on failure.
 1334: .It settings
 1335: A vector of user-supplied
 1336: .Nm sudo
 1337: settings in the form of
 1338: .Dq name=value
 1339: strings.
 1340: The vector is terminated by a
 1341: .Dv NULL
 1342: pointer.
 1343: These settings correspond to flags the user specified when running
 1344: .Nm sudo .
 1345: As such, they will only be present when the corresponding flag has
 1346: been specified on the command line.
 1347: .Pp
 1348: When parsing
 1349: .Em settings ,
 1350: the plugin should split on the
 1351: .Sy first
 1352: equal sign
 1353: .Pq Ql =
 1354: since the
 1355: .Em name
 1356: field will never include one
 1357: itself but the
 1358: .Em value
 1359: might.
 1360: .Pp
 1361: See the
 1362: .Sx Policy plugin API
 1363: section for a list of all possible settings.
 1364: .It user_info
 1365: A vector of information about the user running the command in the form of
 1366: .Dq name=value
 1367: strings.
 1368: The vector is terminated by a
 1369: .Dv NULL
 1370: pointer.
 1371: .Pp
 1372: When parsing
 1373: .Em user_info ,
 1374: the plugin should split on the
 1375: .Sy first
 1376: equal sign
 1377: .Pq Ql =
 1378: since the
 1379: .Em name
 1380: field will never include one
 1381: itself but the
 1382: .Em value
 1383: might.
 1384: .Pp
 1385: See the
 1386: .Sx Policy plugin API
 1387: section for a list of all possible strings.
 1388: .It argc
 1389: The number of elements in
 1390: .Em argv ,
 1391: not counting the final
 1392: .Dv NULL
 1393: pointer.
 1394: .It argv
 1395: If
 1396: .No non- Ns Dv NULL ,
 1397: an argument vector describing a command the user
 1398: wishes to run in the same form as what would be passed to the
 1399: .Xr execve 2
 1400: system call.
 1401: .It user_env
 1402: The user's environment in the form of a
 1403: .Dv NULL Ns No -terminated
 1404: vector of
 1405: .Dq name=value
 1406: strings.
 1407: .Pp
 1408: When parsing
 1409: .Em user_env ,
 1410: the plugin should split on the
 1411: .Sy first
 1412: equal sign
 1413: .Pq Ql =
 1414: since the
 1415: .Em name
 1416: field will never include one
 1417: itself but the
 1418: .Em value
 1419: might.
 1420: .It plugin_options
 1421: Any (non-comment) strings immediately after the plugin path are
 1422: treated as arguments to the plugin.
 1423: These arguments are split on a white space boundary and are passed to
 1424: the plugin in the form of a
 1425: .Dv NULL Ns No -terminated
 1426: array of strings.
 1427: If no arguments were specified,
 1428: .Em plugin_options
 1429: will be the
 1430: .Dv NULL
 1431: pointer.
 1432: .Pp
 1433: NOTE: the
 1434: .Em plugin_options
 1435: parameter is only available starting with
 1436: API version 1.2.
 1437: A plugin
 1438: .Sy must
 1439: check the API version specified
 1440: by the
 1441: .Nm sudo
 1442: front end before using
 1443: .Em plugin_options .
 1444: Failure to do so may result in a crash.
 1445: .El
 1446: .It close
 1447: .Bd -literal -compact
 1448: void (*close)(int exit_status, int error);
 1449: .Ed
 1450: .Pp
 1451: The
 1452: .Fn close
 1453: function is called when the command being run by
 1454: .Nm sudo
 1455: finishes.
 1456: .Pp
 1457: The function arguments are as follows:
 1458: .Bl -tag -width 4n
 1459: .It exit_status
 1460: The command's exit status, as returned by the
 1461: .Xr wait 2
 1462: system call.
 1463: The value of
 1464: .Li exit_status
 1465: is undefined if
 1466: .Li error
 1467: is non-zero.
 1468: .It error
 1469: If the command could not be executed, this is set to the value of
 1470: .Li errno
 1471: set by the
 1472: .Xr execve 2
 1473: system call.
 1474: If the command was successfully executed, the value of
 1475: .Li error
 1476: is 0.
 1477: .El
 1478: .It show_version
 1479: .Bd -literal -compact
 1480: int (*show_version)(int verbose);
 1481: .Ed
 1482: .Pp
 1483: The
 1484: .Fn show_version
 1485: function is called by
 1486: .Nm sudo
 1487: when the user specifies
 1488: the
 1489: .Fl V
 1490: option.
 1491: The plugin may display its version information to the user via the
 1492: .Fn conversation
 1493: or
 1494: .Fn plugin_printf
 1495: function using
 1496: .Dv SUDO_CONV_INFO_MSG .
 1497: If the user requests detailed version information, the verbose flag will be set.
 1498: .It log_ttyin
 1499: .Bd -literal -compact
 1500: int (*log_ttyin)(const char *buf, unsigned int len);
 1501: .Ed
 1502: .Pp
 1503: The
 1504: .Fn log_ttyin
 1505: function is called whenever data can be read from
 1506: the user but before it is passed to the running command.
 1507: This allows the plugin to reject data if it chooses to (for instance
 1508: if the input contains banned content).
 1509: Returns 1 if the data should be passed to the command, 0 if the data
 1510: is rejected (which will terminate the command) or \-1 if an error occurred.
 1511: .Pp
 1512: The function arguments are as follows:
 1513: .Bl -tag -width 4n
 1514: .It buf
 1515: The buffer containing user input.
 1516: .It len
 1517: The length of
 1518: .Em buf
 1519: in bytes.
 1520: .El
 1521: .It log_ttyout
 1522: .Bd -literal -compact
 1523: int (*log_ttyout)(const char *buf, unsigned int len);
 1524: .Ed
 1525: .Pp
 1526: The
 1527: .Fn log_ttyout
 1528: function is called whenever data can be read from
 1529: the command but before it is written to the user's terminal.
 1530: This allows the plugin to reject data if it chooses to (for instance
 1531: if the output contains banned content).
 1532: Returns 1 if the data should be passed to the user, 0 if the data is rejected
 1533: (which will terminate the command) or \-1 if an error occurred.
 1534: .Pp
 1535: The function arguments are as follows:
 1536: .Bl -tag -width 4n
 1537: .It buf
 1538: The buffer containing command output.
 1539: .It len
 1540: The length of
 1541: .Em buf
 1542: in bytes.
 1543: .El
 1544: .It log_stdin
 1545: .Bd -literal -compact
 1546: int (*log_stdin)(const char *buf, unsigned int len);
 1547: .Ed
 1548: .Pp
 1549: The
 1550: .Fn log_stdin
 1551: function is only used if the standard input does
 1552: not correspond to a tty device.
 1553: It is called whenever data can be read from the standard input but
 1554: before it is passed to the running command.
 1555: This allows the plugin to reject data if it chooses to
 1556: (for instance if the input contains banned content).
 1557: Returns 1 if the data should be passed to the command, 0 if the data is
 1558: rejected (which will terminate the command) or \-1 if an error occurred.
 1559: .Pp
 1560: The function arguments are as follows:
 1561: .Bl -tag -width 4n
 1562: .It buf
 1563: The buffer containing user input.
 1564: .It len
 1565: The length of
 1566: .Em buf
 1567: in bytes.
 1568: .El
 1569: .It log_stdout
 1570: .Bd -literal -compact
 1571: int (*log_stdout)(const char *buf, unsigned int len);
 1572: .Ed
 1573: .Pp
 1574: The
 1575: .Fn log_stdout
 1576: function is only used if the standard output does not correspond
 1577: to a tty device.
 1578: It is called whenever data can be read from the command but before
 1579: it is written to the standard output.
 1580: This allows the plugin to reject data if it chooses to
 1581: (for instance if the output contains banned content).
 1582: Returns 1 if the data should be passed to the user, 0 if the data is
 1583: rejected (which will terminate the command) or \-1 if an error occurred.
 1584: .Pp
 1585: The function arguments are as follows:
 1586: .Bl -tag -width 4n
 1587: .It buf
 1588: The buffer containing command output.
 1589: .It len
 1590: The length of
 1591: .Em buf
 1592: in bytes.
 1593: .El
 1594: .It log_stderr
 1595: .Bd -literal -compact
 1596: int (*log_stderr)(const char *buf, unsigned int len);
 1597: .Ed
 1598: .Pp
 1599: The
 1600: .Fn log_stderr
 1601: function is only used if the standard error does
 1602: not correspond to a tty device.
 1603: It is called whenever data can be read from the command but before it
 1604: is written to the standard error.
 1605: This allows the plugin to reject data if it chooses to
 1606: (for instance if the output contains banned content).
 1607: Returns 1 if the data should be passed to the user, 0 if the data is
 1608: rejected (which will terminate the command) or \-1 if an error occurred.
 1609: .Pp
 1610: The function arguments are as follows:
 1611: .Bl -tag -width 4n
 1612: .It buf
 1613: The buffer containing command output.
 1614: .It len
 1615: The length of
 1616: .Em buf
 1617: in bytes.
 1618: .El
 1619: .It register_hooks
 1620: See the
 1621: .Sx Policy plugin API
 1622: section for a description of
 1623: .Li register_hooks .
 1624: .It deregister_hooks
 1625: See the
 1626: .Sx Policy plugin API
 1627: section for a description of
 1628: .Li deregister_hooks.
 1629: .El
 1630: .Pp
 1631: .Em I/O Plugin Version Macros
 1632: .Pp
 1633: Same as for the
 1634: .Sx Policy plugin API .
 1635: .Ss Signal handlers
 1636: The
 1637: .Nm sudo
 1638: front end installs default signal handlers to trap common signals
 1639: while the plugin functions are run.
 1640: The following signals are trapped by default before the command is
 1641: executed:
 1642: .Pp
 1643: .Bl -bullet -compact
 1644: .It
 1645: .Dv SIGALRM
 1646: .It
 1647: .Dv SIGHUP
 1648: .It
 1649: .Dv SIGINT
 1650: .It
 1651: .Dv SIGQUIT
 1652: .It
 1653: .Dv SIGTERM
 1654: .It
 1655: .Dv SIGTSTP
 1656: .It
 1657: .Dv SIGUSR1
 1658: .It
 1659: .Dv SIGUSR2
 1660: .El
 1661: .Pp
 1662: If a fatal signal is received before the command is executed,
 1663: .Nm sudo
 1664: will call the plugin's
 1665: .Fn close
 1666: function with an exit status of 128 plus the value of the signal
 1667: that was received.
 1668: This allows for consistent logging of commands killed by a signal
 1669: for plugins that log such information in their
 1670: .Fn close
 1671: function.
 1672: .Pp
 1673: A plugin may temporarily install its own signal handlers but must
 1674: restore the original handler before the plugin function returns.
 1675: .Ss Hook function API
 1676: Beginning with plugin API version 1.2, it is possible to install
 1677: hooks for certain functions called by the
 1678: .Nm sudo
 1679: front end.
 1680: .Pp
 1681: Currently, the only supported hooks relate to the handling of
 1682: environment variables.
 1683: Hooks can be used to intercept attempts to get, set, or remove
 1684: environment variables so that these changes can be reflected in
 1685: the version of the environment that is used to execute a command.
 1686: A future version of the API will support hooking internal
 1687: .Nm sudo
 1688: front end functions as well.
 1689: .Pp
 1690: .Em Hook structure
 1691: .Pp
 1692: Hooks in
 1693: .Nm sudo
 1694: are described by the following structure:
 1695: .Bd -literal
 1696: typedef int (*sudo_hook_fn_t)();
 1697: 
 1698: struct sudo_hook {
 1699:     int hook_version;
 1700:     int hook_type;
 1701:     sudo_hook_fn_t hook_fn;
 1702:     void *closure;
 1703: };
 1704: .Ed
 1705: .Pp
 1706: The
 1707: .Li sudo_hook
 1708: structure has the following fields:
 1709: .Bl -tag -width 4n
 1710: .It hook_version
 1711: The
 1712: .Li hook_version
 1713: field should be set to
 1714: .Dv SUDO_HOOK_VERSION .
 1715: .It hook_type
 1716: The
 1717: .Li hook_type
 1718: field may be one of the following supported hook types:
 1719: .Bl -tag -width 4n
 1720: .It Dv SUDO_HOOK_SETENV
 1721: The C library
 1722: .Xr setenv 3
 1723: function.
 1724: Any registered hooks will run before the C library implementation.
 1725: The
 1726: .Li hook_fn
 1727: field should
 1728: be a function that matches the following typedef:
 1729: .Bd -literal
 1730: typedef int (*sudo_hook_fn_setenv_t)(const char *name,
 1731:    const char *value, int overwrite, void *closure);
 1732: .Ed
 1733: .Pp
 1734: If the registered hook does not match the typedef the results are
 1735: unspecified.
 1736: .It Dv SUDO_HOOK_UNSETENV
 1737: The C library
 1738: .Xr unsetenv 3
 1739: function.
 1740: Any registered hooks will run before the C library implementation.
 1741: The
 1742: .Li hook_fn
 1743: field should
 1744: be a function that matches the following typedef:
 1745: .Bd -literal
 1746: typedef int (*sudo_hook_fn_unsetenv_t)(const char *name,
 1747:    void *closure);
 1748: .Ed
 1749: .It Dv SUDO_HOOK_GETENV
 1750: The C library
 1751: .Xr getenv 3
 1752: function.
 1753: Any registered hooks will run before the C library implementation.
 1754: The
 1755: .Li hook_fn
 1756: field should
 1757: be a function that matches the following typedef:
 1758: .Bd -literal
 1759: typedef int (*sudo_hook_fn_getenv_t)(const char *name,
 1760:    char **value, void *closure);
 1761: .Ed
 1762: .Pp
 1763: If the registered hook does not match the typedef the results are
 1764: unspecified.
 1765: .It Dv SUDO_HOOK_PUTENV
 1766: The C library
 1767: .Xr putenv 3
 1768: function.
 1769: Any registered hooks will run before the C library implementation.
 1770: The
 1771: .Li hook_fn
 1772: field should
 1773: be a function that matches the following typedef:
 1774: .Bd -literal
 1775: typedef int (*sudo_hook_fn_putenv_t)(char *string,
 1776:    void *closure);
 1777: .Ed
 1778: .Pp
 1779: If the registered hook does not match the typedef the results are
 1780: unspecified.
 1781: .El
 1782: .It hook_fn
 1783: sudo_hook_fn_t hook_fn;
 1784: .Pp
 1785: The
 1786: .Li hook_fn
 1787: field should be set to the plugin's hook implementation.
 1788: The actual function arguments will vary depending on the
 1789: .Li hook_type
 1790: (see
 1791: .Li hook_type
 1792: above).
 1793: In all cases, the
 1794: .Li closure
 1795: field of
 1796: .Li struct sudo_hook
 1797: is passed as the last function parameter.
 1798: This can be used to pass arbitrary data to the plugin's hook implementation.
 1799: .Pp
 1800: The function return value may be one of the following:
 1801: .Bl -tag -width 4n
 1802: .It Dv SUDO_HOOK_RET_ERROR
 1803: The hook function encountered an error.
 1804: .It Dv SUDO_HOOK_RET_NEXT
 1805: The hook completed without error, go on to the next hook (including
 1806: the native implementation if applicable).
 1807: For example, a
 1808: .Xr getenv 3
 1809: hook might return
 1810: .Dv SUDO_HOOK_RET_NEXT
 1811: if the specified variable was not found in the private copy of the environment.
 1812: .It Dv SUDO_HOOK_RET_STOP
 1813: The hook completed without error, stop processing hooks for this invocation.
 1814: This can be used to replace the native implementation.
 1815: For example, a
 1816: .Li setenv
 1817: hook that operates on a private copy of
 1818: the environment but leaves
 1819: .Li environ
 1820: unchanged.
 1821: .El
 1822: .El
 1823: .Pp
 1824: Note that it is very easy to create an infinite loop when hooking
 1825: C library functions.
 1826: For example, a
 1827: .Xr getenv 3
 1828: hook that calls the
 1829: .Xr snprintf 3
 1830: function may create a loop if the
 1831: .Xr snprintf 3
 1832: implementation calls
 1833: .Xr getenv 3
 1834: to check the locale.
 1835: To prevent this, you may wish to use a static variable in the hook
 1836: function to guard against nested calls.
 1837: For example:
 1838: .Bd -literal
 1839: static int in_progress = 0; /* avoid recursion */
 1840: if (in_progress)
 1841:     return SUDO_HOOK_RET_NEXT;
 1842: in_progress = 1;
 1843: \&...
 1844: in_progress = 0;
 1845: return SUDO_HOOK_RET_STOP;
 1846: .Ed
 1847: .Pp
 1848: .Em Hook API Version Macros
 1849: .Bd -literal
 1850: /* Hook API version major/minor */
 1851: #define SUDO_HOOK_VERSION_MAJOR 1
 1852: #define SUDO_HOOK_VERSION_MINOR 0
 1853: #define SUDO_HOOK_MKVERSION(x, y) ((x << 16) | y)
 1854: #define SUDO_HOOK_VERSION SUDO_HOOK_MKVERSION(SUDO_HOOK_VERSION_MAJOR,\e
 1855:                                               SUDO_HOOK_VERSION_MINOR)
 1856: 
 1857: /* Getters and setters for hook API version */
 1858: #define SUDO_HOOK_VERSION_GET_MAJOR(v) ((v) >> 16)
 1859: #define SUDO_HOOK_VERSION_GET_MINOR(v) ((v) & 0xffff)
 1860: #define SUDO_HOOK_VERSION_SET_MAJOR(vp, n) do { \e
 1861:     *(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \e
 1862: } while(0)
 1863: #define SUDO_HOOK_VERSION_SET_MINOR(vp, n) do { \e
 1864:     *(vp) = (*(vp) & 0xffff0000) | (n); \e
 1865: } while(0)
 1866: .Ed
 1867: .Ss Remote command execution
 1868: The
 1869: .Nm sudo
 1870: front end does not have native support for running remote commands.
 1871: However, starting with
 1872: .Nm sudo
 1873: 1.8.8, the
 1874: .Fl h
 1875: option may be used to specify a remote host that is passed
 1876: to the policy plugin.
 1877: A plugin may also accept a
 1878: .Em runas_user
 1879: in the form of
 1880: .Dq user@hostname
 1881: which will work with older versions of
 1882: .Nm sudo .
 1883: It is anticipated that remote commands will be supported by executing a
 1884: .Dq helper
 1885: program.
 1886: The policy plugin should setup the execution environment such that the
 1887: .Nm sudo
 1888: front end will run the helper which, in turn, will connect to the
 1889: remote host and run the command.
 1890: .Pp
 1891: For example, the policy plugin could utilize
 1892: .Nm ssh
 1893: to perform remote command execution.
 1894: The helper program would be responsible for running
 1895: .Nm ssh
 1896: with the proper options to use a private key or certificate
 1897: that the remote host will accept and run a program
 1898: on the remote host that would setup the execution environment
 1899: accordingly.
 1900: .Pp
 1901: Note that remote
 1902: .Nm sudoedit
 1903: functionality must be handled by the policy plugin, not
 1904: .Nm sudo
 1905: itself as the front end has no knowledge that a remote command is
 1906: being executed.
 1907: This may be addressed in a future revision of the plugin API.
 1908: .Ss Conversation API
 1909: If the plugin needs to interact with the user, it may do so via the
 1910: .Fn conversation
 1911: function.
 1912: A plugin should not attempt to read directly from the standard input
 1913: or the user's tty (neither of which are guaranteed to exist).
 1914: The caller must include a trailing newline in
 1915: .Li msg
 1916: if one is to be printed.
 1917: .Pp
 1918: A
 1919: .Fn printf Ns No -style
 1920: function is also available that can be used to display informational
 1921: or error messages to the user, which is usually more convenient for
 1922: simple messages where no use input is required.
 1923: .Bd -literal
 1924: struct sudo_conv_message {
 1925: #define SUDO_CONV_PROMPT_ECHO_OFF  0x0001 /* do not echo user input */
 1926: #define SUDO_CONV_PROMPT_ECHO_ON   0x0002 /* echo user input */
 1927: #define SUDO_CONV_ERROR_MSG        0x0003 /* error message */
 1928: #define SUDO_CONV_INFO_MSG         0x0004 /* informational message */
 1929: #define SUDO_CONV_PROMPT_MASK      0x0005 /* mask user input */
 1930: #define SUDO_CONV_DEBUG_MSG        0x0006 /* debugging message */
 1931: #define SUDO_CONV_PROMPT_ECHO_OK   0x1000 /* flag: allow echo if no tty */
 1932:     int msg_type;
 1933:     int timeout;
 1934:     const char *msg;
 1935: };
 1936: 
 1937: #define SUDO_CONV_REPL_MAX      255
 1938: 
 1939: struct sudo_conv_reply {
 1940:     char *reply;
 1941: };
 1942: 
 1943: typedef int (*sudo_conv_t)(int num_msgs,
 1944:              const struct sudo_conv_message msgs[],
 1945:              struct sudo_conv_reply replies[]);
 1946: 
 1947: typedef int (*sudo_printf_t)(int msg_type, const char *fmt, ...);
 1948: .Ed
 1949: .Pp
 1950: Pointers to the
 1951: .Fn conversation
 1952: and
 1953: .Fn printf Ns No -style
 1954: functions are passed
 1955: in to the plugin's
 1956: .Fn open
 1957: function when the plugin is initialized.
 1958: .Pp
 1959: To use the
 1960: .Fn conversation
 1961: function, the plugin must pass an array of
 1962: .Li sudo_conv_message
 1963: and
 1964: .Li sudo_conv_reply
 1965: structures.
 1966: There must be a
 1967: .Li struct sudo_conv_message
 1968: and
 1969: .Li struct sudo_conv_reply
 1970: for
 1971: each message in the conversation.
 1972: The plugin is responsible for freeing the reply buffer located in each
 1973: .Li struct sudo_conv_reply ,
 1974: if it is not
 1975: .Dv NULL .
 1976: .Dv SUDO_CONV_REPL_MAX
 1977: represents the maximum length of the reply buffer (not including
 1978: the trailing NUL character).
 1979: In practical terms, this is the longest password
 1980: .Nm sudo
 1981: will support.
 1982: It is also useful as a maximum value for the
 1983: .Fn memset_s
 1984: function when clearing passwords filled in by the conversation function.
 1985: .Pp
 1986: The
 1987: .Fn printf Ns No -style
 1988: function uses the same underlying mechanism as the
 1989: .Fn conversation
 1990: function but only supports
 1991: .Dv SUDO_CONV_INFO_MSG ,
 1992: .Dv SUDO_CONV_ERROR_MSG
 1993: and
 1994: .Dv SUDO_CONV_DEBUG_MSG
 1995: for the
 1996: .Em msg_type
 1997: parameter.
 1998: It can be more convenient than using the
 1999: .Fn conversation
 2000: function if no user reply is needed and supports standard
 2001: .Fn printf
 2002: escape sequences.
 2003: .Pp
 2004: Unlike,
 2005: .Dv SUDO_CONV_INFO_MSG
 2006: and
 2007: Dv SUDO_CONV_ERROR_MSG ,
 2008: messages
 2009: sent with the
 2010: .Dv SUDO_CONV_DEBUG_MSG
 2011: .Em msg_type
 2012: are not directly
 2013: user-visible.
 2014: Instead, they are logged to the file specified in the
 2015: .Li Debug
 2016: statement (if any) in the
 2017: .Xr sudo.conf @mansectform@ .
 2018: file.
 2019: This allows a plugin to log debugging information and is intended
 2020: to be used in conjunction with the
 2021: .Em debug_flags
 2022: setting.
 2023: .Pp
 2024: See the sample plugin for an example of the
 2025: .Fn conversation
 2026: function usage.
 2027: .Ss Sudoers group plugin API
 2028: The
 2029: .Nm sudoers
 2030: plugin supports its own plugin interface to allow non-Unix
 2031: group lookups.
 2032: This can be used to query a group source other than the standard Unix
 2033: group database.
 2034: Two sample group plugins are bundled with
 2035: .Nm sudo ,
 2036: .Em group_file
 2037: and
 2038: .Em system_group ,
 2039: are detailed in
 2040: .Xr sudoers @mansectform@ .
 2041: Third party group plugins include a QAS AD plugin available from Quest Software.
 2042: .Pp
 2043: A group plugin must declare and populate a
 2044: .Li sudoers_group_plugin
 2045: struct in the global scope.
 2046: This structure contains pointers to the functions that implement plugin
 2047: initialization, cleanup and group lookup.
 2048: .Bd -literal
 2049: struct sudoers_group_plugin {
 2050:    unsigned int version;
 2051:    int (*init)(int version, sudo_printf_t sudo_printf,
 2052:                char *const argv[]);
 2053:    void (*cleanup)(void);
 2054:    int (*query)(const char *user, const char *group,
 2055:                 const struct passwd *pwd);
 2056: };
 2057: .Ed
 2058: .Pp
 2059: The
 2060: .Li sudoers_group_plugin
 2061: struct has the following fields:
 2062: .Bl -tag -width 4n
 2063: .It version
 2064: The
 2065: .Li version
 2066: field should be set to GROUP_API_VERSION.
 2067: .Pp
 2068: This allows
 2069: .Nm sudoers
 2070: to determine the API version the group plugin
 2071: was built against.
 2072: .It init
 2073: .Bd -literal -compact
 2074: int (*init)(int version, sudo_printf_t plugin_printf,
 2075:             char *const argv[]);
 2076: .Ed
 2077: .Pp
 2078: The
 2079: .Fn init
 2080: function is called after
 2081: .Em sudoers
 2082: has been parsed but
 2083: before any policy checks.
 2084: It returns 1 on success, 0 on failure (or if the plugin is not configured),
 2085: and \-1 if a error occurred.
 2086: If an error occurs, the plugin may call the
 2087: .Fn plugin_printf
 2088: function with
 2089: .Dv SUDO_CONF_ERROR_MSG
 2090: to present additional error information
 2091: to the user.
 2092: .Pp
 2093: The function arguments are as follows:
 2094: .Bl -tag -width 4n
 2095: .It version
 2096: The version passed in by
 2097: .Nm sudoers
 2098: allows the plugin to determine the
 2099: major and minor version number of the group plugin API supported by
 2100: .Nm sudoers .
 2101: .It plugin_printf
 2102: A pointer to a
 2103: .Fn printf Ns No -style
 2104: function that may be used to display informational or error message to the user.
 2105: Returns the number of characters printed on success and \-1 on failure.
 2106: .It argv
 2107: A
 2108: .Dv NULL Ns No -terminated
 2109: array of arguments generated from the
 2110: .Em group_plugin
 2111: option in
 2112: .Em sudoers .
 2113: If no arguments were given,
 2114: .Em argv
 2115: will be
 2116: .Dv NULL .
 2117: .El
 2118: .It cleanup
 2119: .Bd -literal -compact
 2120: void (*cleanup)();
 2121: .Ed
 2122: .Pp
 2123: The
 2124: .Fn cleanup
 2125: function is called when
 2126: .Nm sudoers
 2127: has finished its
 2128: group checks.
 2129: The plugin should free any memory it has allocated and close open file handles.
 2130: .It query
 2131: .Bd -literal -compact
 2132: int (*query)(const char *user, const char *group,
 2133:              const struct passwd *pwd);
 2134: .Ed
 2135: .Pp
 2136: The
 2137: .Fn query
 2138: function is used to ask the group plugin whether
 2139: .Em user
 2140: is a member of
 2141: .Em group .
 2142: .Pp
 2143: The function arguments are as follows:
 2144: .Bl -tag -width 4n
 2145: .It user
 2146: The name of the user being looked up in the external group database.
 2147: .It group
 2148: The name of the group being queried.
 2149: .It pwd
 2150: The password database entry for
 2151: .Em user ,
 2152: if any.
 2153: If
 2154: .Em user
 2155: is not
 2156: present in the password database,
 2157: .Em pwd
 2158: will be
 2159: .Dv NULL .
 2160: .El
 2161: .El
 2162: .Pp
 2163: .Em Group API Version Macros
 2164: .Bd -literal
 2165: /* Sudoers group plugin version major/minor */
 2166: #define GROUP_API_VERSION_MAJOR 1
 2167: #define GROUP_API_VERSION_MINOR 0
 2168: #define GROUP_API_VERSION ((GROUP_API_VERSION_MAJOR << 16) | \e
 2169:                            GROUP_API_VERSION_MINOR)
 2170: 
 2171: /* Getters and setters for group version */
 2172: #define GROUP_API_VERSION_GET_MAJOR(v) ((v) >> 16)
 2173: #define GROUP_API_VERSION_GET_MINOR(v) ((v) & 0xffff)
 2174: #define GROUP_API_VERSION_SET_MAJOR(vp, n) do { \e
 2175:     *(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \e
 2176: } while(0)
 2177: #define GROUP_API_VERSION_SET_MINOR(vp, n) do { \e
 2178:     *(vp) = (*(vp) & 0xffff0000) | (n); \e
 2179: } while(0)
 2180: .Ed
 2181: .Sh PLUGIN API CHANGELOG
 2182: The following revisions have been made to the Sudo Plugin API.
 2183: .Bl -tag -width 4n
 2184: .It Version 1.0
 2185: Initial API version.
 2186: .It Version 1.1 (sudo 1.8.0)
 2187: The I/O logging plugin's
 2188: .Fn open
 2189: function was modified to take the
 2190: .Li command_info
 2191: list as an argument.
 2192: .It Version 1.2 (sudo 1.8.5)
 2193: The Policy and I/O logging plugins'
 2194: .Fn open
 2195: functions are now passed
 2196: a list of plugin parameters if any are specified in
 2197: .Xr sudo.conf @mansectform@ .
 2198: .Pp
 2199: A simple hooks API has been introduced to allow plugins to hook in to the
 2200: system's environment handling functions.
 2201: .Pp
 2202: The
 2203: .Li init_session
 2204: Policy plugin function is now passed a pointer
 2205: to the user environment which can be updated as needed.
 2206: This can be used to merge in environment variables stored in the PAM
 2207: handle before a command is run.
 2208: .It Version 1.3 (sudo 1.8.7)
 2209: Support for the
 2210: .Em exec_background
 2211: entry has been added to the
 2212: .Li command_info
 2213: list.
 2214: .Pp
 2215: The
 2216: .Em max_groups
 2217: and
 2218: .Em plugin_dir
 2219: entries were added to the
 2220: .Li settings
 2221: list.
 2222: .Pp
 2223: The
 2224: .Fn version
 2225: and
 2226: .Fn close
 2227: functions are now optional.
 2228: Previously, a missing
 2229: .Fn version
 2230: or
 2231: .Fn close
 2232: function would result in a crash.
 2233: If no policy plugin
 2234: .Fn close
 2235: function is defined, a default
 2236: .Fn close
 2237: function will be provided by the
 2238: .Nm sudo
 2239: front end that displays a warning if the command could not be
 2240: executed.
 2241: .Pp
 2242: The
 2243: .Nm sudo
 2244: front end now installs default signal handlers to trap common signals
 2245: while the plugin functions are run.
 2246: .It Version 1.4 (sudo 1.8.8)
 2247: The
 2248: .Em remote_host
 2249: entry was added to the
 2250: .Li settings
 2251: list.
 2252: .El
 2253: .Sh SEE ALSO
 2254: .Xr sudo.conf @mansectform@ ,
 2255: .Xr sudoers @mansectform@ ,
 2256: .Xr sudo @mansectsu@
 2257: .Sh BUGS
 2258: If you feel you have found a bug in
 2259: .Nm sudo ,
 2260: please submit a bug report at http://www.sudo.ws/sudo/bugs/
 2261: .Sh SUPPORT
 2262: Limited free support is available via the sudo-users mailing list,
 2263: see http://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or
 2264: search the archives.
 2265: .Sh DISCLAIMER
 2266: .Nm sudo
 2267: is provided
 2268: .Dq AS IS
 2269: and any express or implied warranties, including, but not limited
 2270: to, the implied warranties of merchantability and fitness for a
 2271: particular purpose are disclaimed.
 2272: See the LICENSE file distributed with
 2273: .Nm sudo
 2274: or http://www.sudo.ws/sudo/license.html for complete details.

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