File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / sudo / doc / sudo_plugin.mdoc.in
Revision 1.1.1.4 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jun 15 16:12:54 2014 UTC (10 years ago) by misho
Branches: sudo, MAIN
CVS tags: v1_8_10p3_0, v1_8_10p3, HEAD
sudo v 1.8.10p3

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

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