File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / sudo / doc / sudo_plugin.pod
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue May 29 12:26:49 2012 UTC (12 years, 1 month ago) by misho
Branches: sudo, MAIN
CVS tags: v1_8_5p1, HEAD
sudo 1.8.5p1

    1: Copyright (c) 2009-2012 Todd C. Miller <Todd.Miller@courtesan.com>
    2: 
    3: Permission to use, copy, modify, and distribute this software for any
    4: purpose with or without fee is hereby granted, provided that the above
    5: copyright notice and this permission notice appear in all copies.
    6: 
    7: THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
    8: WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
    9: MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   10: ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   11: WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   12: ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   13: OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   14: ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   15: 
   16: =pod
   17: 
   18: =head1 NAME
   19: 
   20: sudo_plugin - Sudo Plugin API
   21: 
   22: =head1 DESCRIPTION
   23: 
   24: Starting with version 1.8, B<sudo> supports a plugin API
   25: for policy and session logging.  By default, the I<sudoers> policy
   26: plugin and an associated I/O logging plugin are used.  Via the plugin
   27: API, B<sudo> can be configured to use alternate policy and/or I/O
   28: logging plugins provided by third parties.  The plugins to be used
   29: are specified via the F<@sysconfdir@/sudo.conf> file.
   30: 
   31: The API is versioned with a major and minor number.  The minor
   32: version number is incremented when additions are made.  The major
   33: number is incremented when incompatible changes are made.  A plugin
   34: should be check the version passed to it and make sure that the
   35: major version matches.
   36: 
   37: The plugin API is defined by the C<sudo_plugin.h> header file.
   38: 
   39: =head2 The sudo.conf File
   40: 
   41: The F<@sysconfdir@/sudo.conf> file contains plugin configuration directives.
   42: Currently, the only supported keyword is the C<Plugin> directive,
   43: which causes a plugin plugin to be loaded.
   44: 
   45: A C<Plugin> line consists of the C<Plugin> keyword, followed by the
   46: I<symbol_name> and the I<path> to the shared object containing the
   47: plugin.  The I<symbol_name> is the name of the C<struct policy_plugin>
   48: or C<struct io_plugin> in the plugin shared object.  The I<path>
   49: may be fully qualified or relative.  If not fully qualified it is
   50: relative to the F<@prefix@/libexec> directory.  Any additional
   51: parameters after the I<path> are passed as options to the plugin's
   52: I<open> function.  Lines that don't begin with C<Plugin>, C<Path>,
   53: C<Debug> or C<Set> are silently ignored.
   54: 
   55: The same shared object may contain multiple plugins, each with a
   56: different symbol name.  The shared object file must be owned by uid
   57: 0 and only writable by its owner.  Because of ambiguities that arise
   58: from composite policies, only a single policy plugin may be specified.
   59: This limitation does not apply to I/O plugins.
   60: 
   61:  #
   62:  # Default @sysconfdir@/sudo.conf file
   63:  #
   64:  # Format:
   65:  #   Plugin plugin_name plugin_path plugin_options ...
   66:  #   Path askpass /path/to/askpass
   67:  #   Path noexec /path/to/sudo_noexec.so
   68:  #   Debug sudo /var/log/sudo_debug all@warn
   69:  #   Set disable_coredump true
   70:  #
   71:  # The plugin_path is relative to @prefix@/libexec unless
   72:  #   fully qualified.
   73:  # The plugin_name corresponds to a global symbol in the plugin
   74:  #   that contains the plugin interface structure.
   75:  # The plugin_options are optional.
   76:  #
   77:  Plugin sudoers_policy sudoers.so
   78:  Plugin sudoers_io sudoers.so
   79: 
   80: =head2 Policy Plugin API
   81: 
   82: A policy plugin must declare and populate a C<policy_plugin> struct
   83: in the global scope.  This structure contains pointers to the functions
   84: that implement the B<sudo> policy checks.  The name of the symbol should
   85: be specified in F<@sysconfdir@/sudo.conf> along with a path to the plugin
   86: so that B<sudo> can load it.
   87: 
   88:  struct policy_plugin {
   89:  #define SUDO_POLICY_PLUGIN	1
   90:      unsigned int type; /* always SUDO_POLICY_PLUGIN */
   91:      unsigned int version; /* always SUDO_API_VERSION */
   92:      int (*open)(unsigned int version, sudo_conv_t conversation,
   93:                  sudo_printf_t plugin_printf, char * const settings[],
   94:                  char * const user_info[], char * const user_env[],
   95:                  char * const plugin_options[]);
   96:      void (*close)(int exit_status, int error);
   97:      int (*show_version)(int verbose);
   98:      int (*check_policy)(int argc, char * const argv[],
   99:                          char *env_add[], char **command_info[],
  100:                          char **argv_out[], char **user_env_out[]);
  101:      int (*list)(int argc, char * const argv[], int verbose,
  102:                  const char *list_user);
  103:      int (*validate)(void);
  104:      void (*invalidate)(int remove);
  105:      int (*init_session)(struct passwd *pwd, char **user_env[]);
  106:      void (*register_hooks)(int version,
  107: 	int (*register_hook)(struct sudo_hook *hook));
  108:      void (*deregister_hooks)(int version,
  109: 	int (*deregister_hook)(struct sudo_hook *hook));
  110:  };
  111: 
  112: The policy_plugin struct has the following fields:
  113: 
  114: =over 4
  115: 
  116: =item type
  117: 
  118: The C<type> field should always be set to SUDO_POLICY_PLUGIN.
  119: 
  120: =item version
  121: 
  122: The C<version> field should be set to SUDO_API_VERSION.
  123: 
  124: This allows B<sudo> to determine the API version the plugin was
  125: built against.
  126: 
  127: =item open
  128: 
  129:  int (*open)(unsigned int version, sudo_conv_t conversation,
  130:              sudo_printf_t plugin_printf, char * const settings[],
  131:              char * const user_info[], char * const user_env[],
  132:              char * const plugin_options[]);
  133: 
  134: Returns 1 on success, 0 on failure, -1 if a general error occurred,
  135: or -2 if there was a usage error.  In the latter case, B<sudo> will
  136: print a usage message before it exits.  If an error occurs, the
  137: plugin may optionally call the conversation or plugin_printf function
  138: with C<SUDO_CONF_ERROR_MSG> to present additional error information
  139: to the user.
  140: 
  141: The function arguments are as follows:
  142: 
  143: =over 4
  144: 
  145: =item version
  146: 
  147: The version passed in by B<sudo> allows the plugin to determine the
  148: major and minor version number of the plugin API supported by
  149: B<sudo>.
  150: 
  151: =item conversation
  152: 
  153: A pointer to the conversation function that can be used by the
  154: plugin to interact with the user (see below).
  155: Returns 0 on success and -1 on failure.
  156: 
  157: =item plugin_printf
  158: 
  159: A pointer to a printf-style function that may be used to display
  160: informational or error messages (see below).
  161: Returns the number of characters printed on success and -1 on failure.
  162: 
  163: =item settings
  164: 
  165: A vector of user-supplied B<sudo> settings in the form of "name=value"
  166: strings.  The vector is terminated by a C<NULL> pointer.  These
  167: settings correspond to flags the user specified when running B<sudo>.
  168: As such, they will only be present when the corresponding flag has
  169: been specified on the command line.
  170: 
  171: When parsing I<settings>, the plugin should split on the B<first>
  172: equal sign ('=') since the I<name> field will never include one
  173: itself but the I<value> might.
  174: 
  175: =over 4
  176: 
  177: =item debug_flags=string
  178: 
  179: A comma-separated list of debug flags that correspond to B<sudo>'s
  180: C<Debug> entry in F<@sysconfdir@/sudo.conf>, if there is one.  The
  181: flags are passed to the plugin as they appear in F<@sysconfdir@/sudo.conf>.
  182: The syntax used by B<sudo> and the I<sudoers> plugin is
  183: I<subsystem>@I<priority> but the plugin is free to use a different
  184: format so long as it does not include a command C<,>.
  185: 
  186: For reference, the priorities supported by the B<sudo> front end and
  187: I<sudoers> are: I<crit>, I<err>, I<warn>, I<notice>, I<diag>,
  188: I<info>, I<trace> and I<debug>.
  189: 
  190: The following subsystems are defined: I<main>, I<memory>, I<args>,
  191: I<exec>, I<pty>, I<utmp>, I<conv>, I<pcomm>, I<util>, I<list>,
  192: I<netif>, I<audit>, I<edit>, I<selinux>, I<ldap>, I<match>, I<parser>,
  193: I<alias>, I<defaults>, I<auth>, I<env>, I<logging>, I<nss>, I<rbtree>,
  194: I<perms>, I<plugin>.  The subsystem I<all> includes every subsystem.
  195: 
  196: There is not currently a way to specify a set of debug flags specific
  197: to the plugin--the flags are shared by B<sudo> and the plugin.
  198: 
  199: =item debug_level=number
  200: 
  201: This setting has been deprecated in favor of I<debug_flags>.
  202: 
  203: =item runas_user=string
  204: 
  205: The user name or uid to to run the command as, if specified via the
  206: C<-u> flag.
  207: 
  208: =item runas_group=string
  209: 
  210: The group name or gid to to run the command as, if specified via
  211: the C<-g> flag.
  212: 
  213: =item prompt=string
  214: 
  215: The prompt to use when requesting a password, if specified via
  216: the C<-p> flag.
  217: 
  218: =item set_home=bool
  219: 
  220: Set to true if the user specified the C<-H> flag.  If true, set the
  221: C<HOME> environment variable to the target user's home directory.
  222: 
  223: =item preserve_environment=bool
  224: 
  225: Set to true if the user specified the C<-E> flag, indicating that
  226: the user wishes to preserve the environment.
  227: 
  228: =item run_shell=bool
  229: 
  230: Set to true if the user specified the C<-s> flag, indicating that
  231: the user wishes to run a shell.
  232: 
  233: =item login_shell=bool
  234: 
  235: Set to true if the user specified the C<-i> flag, indicating that
  236: the user wishes to run a login shell.
  237: 
  238: =item implied_shell=bool
  239: 
  240: If the user does not specify a program on the command line, B<sudo>
  241: will pass the plugin the path to the user's shell and set
  242: I<implied_shell> to true.  This allows B<sudo> with no arguments
  243: to be used similarly to L<su(1)>.  If the plugin does not to support
  244: this usage, it may return a value of -2 from the C<check_policy>
  245: function, which will cause B<sudo> to print a usage message and
  246: exit.
  247: 
  248: =item preserve_groups=bool
  249: 
  250: Set to true if the user specified the C<-P> flag, indicating that
  251: the user wishes to preserve the group vector instead of setting it
  252: based on the runas user.
  253: 
  254: =item ignore_ticket=bool
  255: 
  256: Set to true if the user specified the C<-k> flag along with a
  257: command, indicating that the user wishes to ignore any cached
  258: authentication credentials.
  259: 
  260: =item noninteractive=bool
  261: 
  262: Set to true if the user specified the C<-n> flag, indicating that
  263: B<sudo> should operate in non-interactive mode.  The plugin may
  264: reject a command run in non-interactive mode if user interaction
  265: is required.
  266: 
  267: =item login_class=string
  268: 
  269: BSD login class to use when setting resource limits and nice value,
  270: if specified by the C<-c> flag.
  271: 
  272: =item selinux_role=string
  273: 
  274: SELinux role to use when executing the command, if specified by
  275: the C<-r> flag.
  276: 
  277: =item selinux_type=string
  278: 
  279: SELinux type to use when executing the command, if specified by
  280: the C<-t> flag.
  281: 
  282: =item bsdauth_type=string
  283: 
  284: Authentication type, if specified by the C<-a> flag, to use on
  285: systems where BSD authentication is supported.
  286: 
  287: =item network_addrs=list
  288: 
  289: A space-separated list of IP network addresses and netmasks in the
  290: form "addr/netmask", e.g. "192.168.1.2/255.255.255.0".  The address
  291: and netmask pairs may be either IPv4 or IPv6, depending on what the
  292: operating system supports.  If the address contains a colon (':'),
  293: it is an IPv6 address, else it is IPv4.
  294: 
  295: =item progname=string
  296: 
  297: The command name that sudo was run as, typically "sudo" or "sudoedit".
  298: 
  299: =item sudoedit=bool
  300: 
  301: Set to true when the C<-e> flag is is specified or if invoked as
  302: B<sudoedit>.  The plugin shall substitute an editor into I<argv>
  303: in the I<check_policy> function or return C<-2> with a usage error
  304: if the plugin does not support I<sudoedit>.  For more information,
  305: see the I<check_policy> section.
  306: 
  307: =item closefrom=number
  308: 
  309: If specified, the user has requested via the C<-C> flag that B<sudo>
  310: close all files descriptors with a value of I<number> or higher.
  311: The plugin may optionally pass this, or another value, back in the
  312: I<command_info> list.
  313: 
  314: =back
  315: 
  316: Additional settings may be added in the future so the plugin should
  317: silently ignore settings that it does not recognize.
  318: 
  319: =item user_info
  320: 
  321: A vector of information about the user running the command in the form of
  322: "name=value" strings.  The vector is terminated by a C<NULL> pointer.
  323: 
  324: When parsing I<user_info>, the plugin should split on the B<first>
  325: equal sign ('=') since the I<name> field will never include one
  326: itself but the I<value> might.
  327: 
  328: =over 4
  329: 
  330: =item pid=int
  331: 
  332: The process ID of the running B<sudo> process.
  333: Only available starting with API version 1.2
  334: 
  335: =item ppid=int
  336: 
  337: The parent process ID of the running B<sudo> process.
  338: Only available starting with API version 1.2
  339: 
  340: =item sid=int
  341: 
  342: The session ID of the running B<sudo> process or 0 if B<sudo> is
  343: not part of a POSIX job control session.
  344: Only available starting with API version 1.2
  345: 
  346: =item pgid=int
  347: 
  348: The ID of the process group that the running B<sudo> process belongs
  349: to.
  350: Only available starting with API version 1.2
  351: 
  352: =item tcpgid=int
  353: 
  354: The ID of the forground process group associated with the terminal
  355: device associcated with the B<sudo> process or -1 if there is no
  356: terminal present.
  357: Only available starting with API version 1.2
  358: 
  359: =item user=string
  360: 
  361: The name of the user invoking B<sudo>.
  362: 
  363: =item euid=uid_t
  364: 
  365: The effective user ID of the user invoking B<sudo>.
  366: 
  367: =item uid=uid_t
  368: 
  369: The real user ID of the user invoking B<sudo>.
  370: 
  371: =item egid=gid_t
  372: 
  373: The effective group ID of the user invoking B<sudo>.
  374: 
  375: =item gid=gid_t
  376: 
  377: The real group ID of the user invoking B<sudo>.
  378: 
  379: =item groups=list
  380: 
  381: The user's supplementary group list formatted as a string of
  382: comma-separated group IDs.
  383: 
  384: =item cwd=string
  385: 
  386: The user's current working directory.
  387: 
  388: =item tty=string
  389: 
  390: The path to the user's terminal device.  If the user has no terminal
  391: device associated with the session, the value will be empty, as in
  392: C<tty=>.
  393: 
  394: =item host=string
  395: 
  396: The local machine's hostname as returned by the C<gethostname()>
  397: system call.
  398: 
  399: =item lines=int
  400: 
  401: The number of lines the user's terminal supports.  If there is
  402: no terminal device available, a default value of 24 is used.
  403: 
  404: =item cols=int
  405: 
  406: The number of columns the user's terminal supports.  If there is
  407: no terminal device available, a default value of 80 is used.
  408: 
  409: =back
  410: 
  411: =item user_env
  412: 
  413: The user's environment in the form of a C<NULL>-terminated vector of
  414: "name=value" strings.
  415: 
  416: When parsing I<user_env>, the plugin should split on the B<first>
  417: equal sign ('=') since the I<name> field will never include one
  418: itself but the I<value> might.
  419: 
  420: =item plugin_options
  421: 
  422: Any (non-comment) strings immediately after the plugin path are
  423: treated as arguments to the plugin.  These arguments are split on
  424: a white space boundary and are passed to the plugin in the form of
  425: a C<NULL>-terminated array of strings.  If no arguments were
  426: specified, I<plugin_options> will be the NULL pointer.
  427: 
  428: NOTE: the I<plugin_options> parameter is only available starting with
  429: API version 1.2.  A plugin B<must> check the API version specified
  430: by the B<sudo> front end before using I<plugin_options>.  Failure to
  431: do so may result in a crash.
  432: 
  433: =back
  434: 
  435: =item close
  436: 
  437:  void (*close)(int exit_status, int error);
  438: 
  439: The C<close> function is called when the command being run by B<sudo>
  440: finishes.
  441: 
  442: The function arguments are as follows:
  443: 
  444: =over 4
  445: 
  446: =item exit_status
  447: 
  448: The command's exit status, as returned by the wait(2) system call.
  449: The value of C<exit_status> is undefined if C<error> is non-zero.
  450: 
  451: =item error
  452: 
  453: If the command could not be executed, this is set to the value of
  454: C<errno> set by the execve(2) system call.  The plugin is responsible
  455: for displaying error information via the conversation or plugin_printf
  456: function.  If the command was successfully executed, the value of
  457: C<error> is 0.
  458: 
  459: =back
  460: 
  461: =item show_version
  462: 
  463:  int (*show_version)(int verbose);
  464: 
  465: The C<show_version> function is called by B<sudo> when the user specifies
  466: the C<-V> option.  The plugin may display its version information
  467: to the user via the conversation or plugin_printf function using
  468: C<SUDO_CONV_INFO_MSG>.  If the user requests detailed version
  469: information, the verbose flag will be set.
  470: 
  471: =item check_policy
  472: 
  473:  int (*check_policy)(int argc, char * const argv[]
  474:                      char *env_add[], char **command_info[],
  475:                      char **argv_out[], char **user_env_out[]);
  476: 
  477: The I<check_policy> function is called by B<sudo> to determine
  478: whether the user is allowed to run the specified commands.
  479: 
  480: If the I<sudoedit> option was enabled in the I<settings> array
  481: passed to the I<open> function, the user has requested I<sudoedit>
  482: mode.  I<sudoedit> is a mechanism for editing one or more files
  483: where an editor is run with the user's credentials instead of with
  484: elevated privileges.  B<sudo> achieves this by creating user-writable
  485: temporary copies of the files to be edited and then overwriting the
  486: originals with the temporary copies after editing is complete.  If
  487: the plugin supports B<sudoedit>, it should choose the editor to be
  488: used, potentially from a variable in the user's environment, such
  489: as C<EDITOR>, and include it in I<argv_out> (note that environment
  490: variables may include command line flags).  The files to be edited
  491: should be copied from I<argv> into I<argv_out>, separated from the
  492: editor and its arguments by a C<"--"> element.  The C<"--"> will
  493: be removed by B<sudo> before the editor is executed.  The plugin
  494: should also set I<sudoedit=true> in the I<command_info> list.
  495: 
  496: The I<check_policy> function returns 1 if the command is allowed,
  497: 0 if not allowed, -1 for a general error, or -2 for a usage error
  498: or if B<sudoedit> was specified but is unsupported by the plugin.
  499: In the latter case, B<sudo> will print a usage message before it
  500: exits.  If an error occurs, the plugin may optionally call the
  501: conversation or plugin_printf function with C<SUDO_CONF_ERROR_MSG>
  502: to present additional error information to the user.
  503: 
  504: The function arguments are as follows:
  505: 
  506: =over 4
  507: 
  508: =item argc
  509: 
  510: The number of elements in I<argv>, not counting the final C<NULL>
  511: pointer.
  512: 
  513: =item argv
  514: 
  515: The argument vector describing the command the user wishes to run,
  516: in the same form as what would be passed to the execve() system
  517: call.  The vector is terminated by a C<NULL> pointer.
  518: 
  519: =item env_add
  520: 
  521: Additional environment variables specified by the user on the command
  522: line in the form of a C<NULL>-terminated vector of "name=value"
  523: strings.  The plugin may reject the command if one or more variables
  524: are not allowed to be set, or it may silently ignore such variables.
  525: 
  526: When parsing I<env_add>, the plugin should split on the B<first>
  527: equal sign ('=') since the I<name> field will never include one
  528: itself but the I<value> might.
  529: 
  530: =item command_info
  531: 
  532: Information about the command being run in the form of "name=value"
  533: strings.  These values are used by B<sudo> to set the execution
  534: environment when running a command.  The plugin is responsible for
  535: creating and populating the vector, which must be terminated with
  536: a C<NULL> pointer.  The following values are recognized by B<sudo>:
  537: 
  538: =over 4
  539: 
  540: =item command=string
  541: 
  542: Fully qualified path to the command to be executed.
  543: 
  544: =item runas_uid=uid
  545: 
  546: User ID to run the command as.
  547: 
  548: =item runas_euid=uid
  549: 
  550: Effective user ID to run the command as.
  551: If not specified, the value of I<runas_uid> is used.
  552: 
  553: =item runas_gid=gid
  554: 
  555: Group ID to run the command as.
  556: 
  557: =item runas_egid=gid
  558: 
  559: Effective group ID to run the command as.
  560: If not specified, the value of I<runas_gid> is used.
  561: 
  562: =item runas_groups=list
  563: 
  564: The supplementary group vector to use for the command in the form
  565: of a comma-separated list of group IDs.  If I<preserve_groups>
  566: is set, this option is ignored.
  567: 
  568: =item login_class=string
  569: 
  570: BSD login class to use when setting resource limits and nice value
  571: (optional).  This option is only set on systems that support login
  572: classes.
  573: 
  574: =item preserve_groups=bool
  575: 
  576: If set, B<sudo> will preserve the user's group vector instead of
  577: initializing the group vector based on C<runas_user>.
  578: 
  579: =item cwd=string
  580: 
  581: The current working directory to change to when executing the command.
  582: 
  583: =item noexec=bool
  584: 
  585: If set, prevent the command from executing other programs.
  586: 
  587: =item chroot=string
  588: 
  589: The root directory to use when running the command.
  590: 
  591: =item nice=int
  592: 
  593: Nice value (priority) to use when executing the command.  The nice
  594: value, if specified, overrides the priority associated with the
  595: I<login_class> on BSD systems.
  596: 
  597: =item umask=octal
  598: 
  599: The file creation mask to use when executing the command.
  600: 
  601: =item selinux_role=string
  602: 
  603: SELinux role to use when executing the command.
  604: 
  605: =item selinux_type=string
  606: 
  607: SELinux type to use when executing the command.
  608: 
  609: =item timeout=int
  610: 
  611: Command timeout.  If non-zero then when the timeout expires the
  612: command will be killed.
  613: 
  614: =item sudoedit=bool
  615: 
  616: Set to true when in I<sudoedit> mode.  The plugin may enable
  617: I<sudoedit> mode even if B<sudo> was not invoked as B<sudoedit>.
  618: This allows the plugin to perform command substitution and transparently
  619: enable I<sudoedit> when the user attempts to run an editor.
  620: 
  621: =item closefrom=number
  622: 
  623: If specified, B<sudo> will close all files descriptors with a value
  624: of I<number> or higher.
  625: 
  626: =item iolog_compress=bool
  627: 
  628: Set to true if the I/O logging plugins, if any, should compress the
  629: log data.  This is a hint to the I/O logging plugin which may choose
  630: to ignore it.
  631: 
  632: =item iolog_path=string
  633: 
  634: Fully qualified path to the file or directory in which I/O log is
  635: to be stored.  This is a hint to the I/O logging plugin which may
  636: choose to ignore it.  If no I/O logging plugin is loaded, this
  637: setting has no effect.
  638: 
  639: =item iolog_stdin=bool
  640: 
  641: Set to true if the I/O logging plugins, if any, should log the
  642: standard input if it is not connected to a terminal device.  This
  643: is a hint to the I/O logging plugin which may choose to ignore it.
  644: 
  645: =item iolog_stdout=bool
  646: 
  647: Set to true if the I/O logging plugins, if any, should log the
  648: standard output if it is not connected to a terminal device.  This
  649: is a hint to the I/O logging plugin which may choose to ignore it.
  650: 
  651: =item iolog_stderr=bool
  652: 
  653: Set to true if the I/O logging plugins, if any, should log the
  654: standard error if it is not connected to a terminal device.  This
  655: is a hint to the I/O logging plugin which may choose to ignore it.
  656: 
  657: =item iolog_ttyin=bool
  658: 
  659: Set to true if the I/O logging plugins, if any, should log all
  660: terminal input.  This only includes input typed by the user and not
  661: from a pipe or redirected from a file.  This is a hint to the I/O
  662: logging plugin which may choose to ignore it.
  663: 
  664: =item iolog_ttyout=bool
  665: 
  666: Set to true if the I/O logging plugins, if any, should log all
  667: terminal output.  This only includes output to the screen, not
  668: output to a pipe or file.  This is a hint to the I/O logging plugin
  669: which may choose to ignore it.
  670: 
  671: =item use_pty=bool
  672: 
  673: Allocate a pseudo-tty to run the command in, regardless of whether
  674: or not I/O logging is in use.  By default, B<sudo> will only run
  675: the command in a pty when an I/O log plugin is loaded.
  676: 
  677: =item set_utmp=bool
  678: 
  679: Create a utmp (or utmpx) entry when a pseudo-tty is allocated.  By
  680: default, the new entry will be a copy of the user's existing utmp
  681: entry (if any), with the tty, time, type and pid fields updated.
  682: 
  683: =item utmp_user=string
  684: 
  685: User name to use when constructing a new utmp (or utmpx) entry when
  686: I<set_utmp> is enabled.  This option can be used to set the user
  687: field in the utmp entry to the user the command runs as rather than
  688: the invoking user.  If not set, B<sudo> will base the new entry on
  689: the invoking user's existing entry.
  690: 
  691: =back
  692: 
  693: Unsupported values will be ignored.
  694: 
  695: =item argv_out
  696: 
  697: The C<NULL>-terminated argument vector to pass to the execve()
  698: system call when executing the command.  The plugin is responsible
  699: for allocating and populating the vector.
  700: 
  701: =item user_env_out
  702: 
  703: The C<NULL>-terminated environment vector to use when executing the
  704: command.  The plugin is responsible for allocating and populating
  705: the vector.
  706: 
  707: =back
  708: 
  709: =item list
  710: 
  711:  int (*list)(int verbose, const char *list_user,
  712:              int argc, char * const argv[]);
  713: 
  714: List available privileges for the invoking user.  Returns 1 on
  715: success, 0 on failure and -1 on error.  On error, the plugin may
  716: optionally call the conversation or plugin_printf function with
  717: C<SUDO_CONF_ERROR_MSG> to present additional error information to
  718: the user.
  719: 
  720: Privileges should be output via the conversation or plugin_printf
  721: function using C<SUDO_CONV_INFO_MSG>.
  722: 
  723: =over 4
  724: 
  725: =item verbose
  726: 
  727: Flag indicating whether to list in verbose mode or not.
  728: 
  729: =item list_user
  730: 
  731: The name of a different user to list privileges for if the policy
  732: allows it.  If C<NULL>, the plugin should list the privileges of
  733: the invoking user.
  734: 
  735: =item argc
  736: 
  737: The number of elements in I<argv>, not counting the final C<NULL>
  738: pointer.
  739: 
  740: =item argv
  741: 
  742: If non-C<NULL>, an argument vector describing a command the user
  743: wishes to check against the policy in the same form as what would
  744: be passed to the execve() system call.  If the command is permitted
  745: by the policy, the fully-qualified path to the command should be
  746: displayed along with any command line arguments.
  747: 
  748: =back
  749: 
  750: =item validate
  751: 
  752:  int (*validate)(void);
  753: 
  754: The C<validate> function is called when B<sudo> is run with the
  755: C<-v> flag.  For policy plugins such as I<sudoers> that cache
  756: authentication credentials, this function will validate and cache
  757: the credentials.
  758: 
  759: The C<validate> function should be C<NULL> if the plugin does not
  760: support credential caching.
  761: 
  762: Returns 1 on success, 0 on failure and -1 on error.
  763: On error, the plugin may optionally call the conversation or plugin_printf
  764: function with C<SUDO_CONF_ERROR_MSG> to present additional
  765: error information to the user.
  766: 
  767: =item invalidate
  768: 
  769:  void (*invalidate)(int remove);
  770: 
  771: The C<invalidate> function is called when B<sudo> is called with
  772: the C<-k> or C<-K> flag.  For policy plugins such as I<sudoers> that
  773: cache authentication credentials, this function will invalidate the
  774: credentials.  If the I<remove> flag is set, the plugin may remove
  775: the credentials instead of simply invalidating them.
  776: 
  777: The C<invalidate> function should be C<NULL> if the plugin does not
  778: support credential caching.
  779: 
  780: =item init_session
  781: 
  782:  int (*init_session)(struct passwd *pwd, char **user_envp[);
  783: 
  784: The C<init_session> function is called before B<sudo> sets up the
  785: execution environment for the command.  It is run in the parent
  786: B<sudo> process and before any uid or gid changes.  This can be used
  787: to perform session setup that is not supported by I<command_info>,
  788: such as opening the PAM session.  The C<close> function can be
  789: used to tear down the session that was opened by C<init_session>.
  790: 
  791: The I<pwd> argument points to a passwd struct for the user the
  792: command will be run as if the uid the command will run as was found
  793: in the password database, otherwise it will be NULL.
  794: 
  795: The I<user_env> argument points to the environment the command will
  796: run in, in the form of a C<NULL>-terminated vector of "name=value"
  797: strings.  This is the same string passed back to the front end via
  798: the Policy Plugin's I<user_env_out> parameter.  If the C<init_session>
  799: function needs to modify the user environment, it should update the
  800: pointer stored in I<user_env>.  The expected use case is to merge
  801: the contents of the PAM environment (if any) with the contents of
  802: I<user_env>.  NOTE: the I<user_env> parameter is only available
  803: starting with API version 1.2.  A plugin B<must> check the API
  804: version specified by the B<sudo> front end before using I<user_env>.
  805: Failure to do so may result in a crash.
  806: 
  807: Returns 1 on success, 0 on failure and -1 on error.
  808: On error, the plugin may optionally call the conversation or plugin_printf
  809: function with C<SUDO_CONF_ERROR_MSG> to present additional
  810: error information to the user.
  811: 
  812: =item register_hooks
  813: 
  814:  void (*register_hooks)(int version,
  815:     int (*register_hook)(struct sudo_hook *hook));
  816: 
  817: The C<register_hooks> function is called by the sudo front end to
  818: register any hooks the plugin needs.  If the plugin does not support
  819: hooks, C<register_hooks> should be set to the NULL pointer.
  820: 
  821: The I<version> argument describes the version of the hooks API
  822: supported by the B<sudo> front end.
  823: 
  824: The C<register_hook> function should be used to register any supported
  825: hooks the plugin needs.  It returns 0 on success, 1 if the hook
  826: type is not supported and -1 if the major version in C<struct hook>
  827: does not match the front end's major hook API version.
  828: 
  829: See the L<Hook Function API> section below for more information
  830: about hooks.
  831: 
  832: NOTE: the C<register_hooks> function is only available starting
  833: with API version 1.2.  If the B<sudo> front end doesn't support API
  834: version 1.2 or higher, C<register_hooks> will not be called.
  835: 
  836: =item deregister_hooks
  837: 
  838:  void (*deregister_hooks)(int version,
  839:     int (*deregister_hook)(struct sudo_hook *hook));
  840: 
  841: The C<deregister_hooks> function is called by the sudo front end
  842: to deregister any hooks the plugin has registered.  If the plugin
  843: does not support hooks, C<deregister_hooks> should be set to the
  844: NULL pointer.
  845: 
  846: The I<version> argument describes the version of the hooks API
  847: supported by the B<sudo> front end.
  848: 
  849: The C<deregister_hook> function should be used to deregister any
  850: hooks that were put in place by the C<register_hook> function.  If
  851: the plugin tries to deregister a hook that the front end does not
  852: support, C<deregister_hook> will return an error.
  853: 
  854: See the L<Hook Function API> section below for more information
  855: about hooks.
  856: 
  857: NOTE: the C<deregister_hooks> function is only available starting
  858: with API version 1.2.  If the B<sudo> front end doesn't support API
  859: version 1.2 or higher, C<deregister_hooks> will not be called.
  860: 
  861: =back
  862: 
  863: =head3 Policy Plugin Version Macros
  864: 
  865:  /* Plugin API version major/minor. */
  866:  #define SUDO_API_VERSION_MAJOR 1
  867:  #define SUDO_API_VERSION_MINOR 2
  868:  #define SUDO_API_MKVERSION(x, y) ((x << 16) | y)
  869:  #define SUDO_API_VERSION SUDO_API_MKVERSION(SUDO_API_VERSION_MAJOR,\
  870: 					     SUDO_API_VERSION_MINOR)
  871: 
  872:  /* Getters and setters for API version */
  873:  #define SUDO_API_VERSION_GET_MAJOR(v) ((v) >> 16)
  874:  #define SUDO_API_VERSION_GET_MINOR(v) ((v) & 0xffff)
  875:  #define SUDO_API_VERSION_SET_MAJOR(vp, n) do { \
  876:      *(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \
  877:  } while(0)
  878:  #define SUDO_VERSION_SET_MINOR(vp, n) do { \
  879:      *(vp) = (*(vp) & 0xffff0000) | (n); \
  880:  } while(0)
  881: 
  882: =head2 I/O Plugin API
  883: 
  884:  struct io_plugin {
  885:  #define SUDO_IO_PLUGIN		2
  886:      unsigned int type; /* always SUDO_IO_PLUGIN */
  887:      unsigned int version; /* always SUDO_API_VERSION */
  888:      int (*open)(unsigned int version, sudo_conv_t conversation
  889:                  sudo_printf_t plugin_printf, char * const settings[],
  890:                  char * const user_info[], int argc, char * const argv[],
  891:                  char * const user_env[], char * const plugin_options[]);
  892:      void (*close)(int exit_status, int error); /* wait status or error */
  893:      int (*show_version)(int verbose);
  894:      int (*log_ttyin)(const char *buf, unsigned int len);
  895:      int (*log_ttyout)(const char *buf, unsigned int len);
  896:      int (*log_stdin)(const char *buf, unsigned int len);
  897:      int (*log_stdout)(const char *buf, unsigned int len);
  898:      int (*log_stderr)(const char *buf, unsigned int len);
  899:      void (*register_hooks)(int version,
  900: 	int (*register_hook)(struct sudo_hook *hook));
  901:      void (*deregister_hooks)(int version,
  902: 	int (*deregister_hook)(struct sudo_hook *hook));
  903:  };
  904: 
  905: When an I/O plugin is loaded, B<sudo> runs the command in a pseudo-tty.
  906: This makes it possible to log the input and output from the user's
  907: session.  If any of the standard input, standard output or standard
  908: error do not correspond to a tty, B<sudo> will open a pipe to capture
  909: the I/O for logging before passing it on.
  910: 
  911: The log_ttyin function receives the raw user input from the terminal
  912: device (note that this will include input even when echo is disabled,
  913: such as when a password is read). The log_ttyout function receives
  914: output from the pseudo-tty that is suitable for replaying the user's
  915: session at a later time.  The log_stdin, log_stdout and log_stderr
  916: functions are only called if the standard input, standard output
  917: or standard error respectively correspond to something other than
  918: a tty.
  919: 
  920: Any of the logging functions may be set to the NULL
  921: pointer if no logging is to be performed.  If the open function
  922: returns C<0>, no I/O will be sent to the plugin.
  923: 
  924: The io_plugin struct has the following fields:
  925: 
  926: =over 4
  927: 
  928: =item type
  929: 
  930: The C<type> field should always be set to SUDO_IO_PLUGIN
  931: 
  932: =item version
  933: 
  934: The C<version> field should be set to SUDO_API_VERSION.
  935: 
  936: This allows B<sudo> to determine the API version the plugin was
  937: built against.
  938: 
  939: =item open
  940: 
  941:  int (*open)(unsigned int version, sudo_conv_t conversation
  942:              sudo_printf_t plugin_printf, char * const settings[],
  943:              char * const user_info[], int argc, char * const argv[],
  944:              char * const user_env[], char * const plugin_options[]);
  945: 
  946: The I<open> function is run before the I<log_input>, I<log_output>
  947: or I<show_version> functions are called.  It is only called if the
  948: version is being requested or the I<check_policy> function has
  949: returned successfully.  It returns 1 on success, 0 on failure, -1
  950: if a general error occurred, or -2 if there was a usage error.  In
  951: the latter case, B<sudo> will print a usage message before it exits.
  952: If an error occurs, the plugin may optionally call the conversation
  953: or plugin_printf function with C<SUDO_CONF_ERROR_MSG> to present
  954: additional error information to the user.
  955: 
  956: The function arguments are as follows:
  957: 
  958: =over 4
  959: 
  960: =item version
  961: 
  962: The version passed in by B<sudo> allows the plugin to determine the
  963: major and minor version number of the plugin API supported by
  964: B<sudo>.
  965: 
  966: =item conversation
  967: 
  968: A pointer to the conversation function that may be used by the
  969: I<show_version> function to display version information (see
  970: show_version below).  The conversation function may also be used
  971: to display additional error message to the user.
  972: The conversation function returns 0 on success and -1 on failure.
  973: 
  974: =item plugin_printf
  975: 
  976: A pointer to a printf-style function that may be used by the
  977: I<show_version> function to display version information (see
  978: show_version below).  The plugin_printf function may also be used
  979: to display additional error message to the user.
  980: The plugin_printf function returns number of characters printed on
  981: success and -1 on failure.
  982: 
  983: =item settings
  984: 
  985: A vector of user-supplied B<sudo> settings in the form of "name=value"
  986: strings.  The vector is terminated by a C<NULL> pointer.  These
  987: settings correspond to flags the user specified when running B<sudo>.
  988: As such, they will only be present when the corresponding flag has
  989: been specified on the command line.
  990: 
  991: When parsing I<settings>, the plugin should split on the B<first>
  992: equal sign ('=') since the I<name> field will never include one
  993: itself but the I<value> might.
  994: 
  995: See the L<Policy Plugin API> section for a list of all possible settings.
  996: 
  997: =item user_info
  998: 
  999: A vector of information about the user running the command in the form of
 1000: "name=value" strings.  The vector is terminated by a C<NULL> pointer.
 1001: 
 1002: When parsing I<user_info>, the plugin should split on the B<first>
 1003: equal sign ('=') since the I<name> field will never include one
 1004: itself but the I<value> might.
 1005: 
 1006: See the L<Policy Plugin API> section for a list of all possible strings.
 1007: 
 1008: =item argc
 1009: 
 1010: The number of elements in I<argv>, not counting the final C<NULL>
 1011: pointer.
 1012: 
 1013: =item argv
 1014: 
 1015: If non-C<NULL>, an argument vector describing a command the user
 1016: wishes to run in the same form as what would be passed to the
 1017: execve() system call.
 1018: 
 1019: =item user_env
 1020: 
 1021: The user's environment in the form of a C<NULL>-terminated vector of
 1022: "name=value" strings.
 1023: 
 1024: When parsing I<user_env>, the plugin should split on the B<first>
 1025: equal sign ('=') since the I<name> field will never include one
 1026: itself but the I<value> might.
 1027: 
 1028: =item plugin_options
 1029: 
 1030: Any (non-comment) strings immediately after the plugin path are
 1031: treated as arguments to the plugin.  These arguments are split on
 1032: a white space boundary and are passed to the plugin in the form of
 1033: a C<NULL>-terminated array of strings.  If no arguments were
 1034: specified, I<plugin_options> will be the NULL pointer.
 1035: 
 1036: NOTE: the I<plugin_options> parameter is only available starting with
 1037: API version 1.2.  A plugin B<must> check the API version specified
 1038: by the B<sudo> front end before using I<plugin_options>.  Failure to
 1039: do so may result in a crash.
 1040: 
 1041: =back
 1042: 
 1043: =item close
 1044: 
 1045:  void (*close)(int exit_status, int error);
 1046: 
 1047: The C<close> function is called when the command being run by B<sudo>
 1048: finishes.
 1049: 
 1050: The function arguments are as follows:
 1051: 
 1052: =over 4
 1053: 
 1054: =item exit_status
 1055: 
 1056: The command's exit status, as returned by the wait(2) system call.
 1057: The value of C<exit_status> is undefined if C<error> is non-zero.
 1058: 
 1059: =item error
 1060: 
 1061: If the command could not be executed, this is set to the value of
 1062: C<errno> set by the execve(2) system call.  If the command was
 1063: successfully executed, the value of C<error> is 0.
 1064: 
 1065: =back
 1066: 
 1067: =item show_version
 1068: 
 1069:  int (*show_version)(int verbose);
 1070: 
 1071: The C<show_version> function is called by B<sudo> when the user specifies
 1072: the C<-V> option.  The plugin may display its version information
 1073: to the user via the conversation or plugin_printf function using
 1074: C<SUDO_CONV_INFO_MSG>.  If the user requests detailed version
 1075: information, the verbose flag will be set.
 1076: 
 1077: =item log_ttyin
 1078: 
 1079:  int (*log_ttyin)(const char *buf, unsigned int len);
 1080: 
 1081: The I<log_ttyin> function is called whenever data can be read from
 1082: the user but before it is passed to the running command.  This
 1083: allows the plugin to reject data if it chooses to (for instance
 1084: if the input contains banned content).  Returns C<1> if the data
 1085: should be passed to the command, C<0> if the data is rejected
 1086: (which will terminate the command) or C<-1> if an error occurred.
 1087: 
 1088: The function arguments are as follows:
 1089: 
 1090: =over 4
 1091: 
 1092: =item buf
 1093: 
 1094: The buffer containing user input.
 1095: 
 1096: =item len
 1097: 
 1098: The length of I<buf> in bytes.
 1099: 
 1100: =back
 1101: 
 1102: =item log_ttyout
 1103: 
 1104:  int (*log_ttyout)(const char *buf, unsigned int len);
 1105: 
 1106: The I<log_ttyout> function is called whenever data can be read from
 1107: the command but before it is written to the user's terminal.  This
 1108: allows the plugin to reject data if it chooses to (for instance
 1109: if the output contains banned content).  Returns C<1> if the data
 1110: should be passed to the user, C<0> if the data is rejected
 1111: (which will terminate the command) or C<-1> if an error occurred.
 1112: 
 1113: The function arguments are as follows:
 1114: 
 1115: =over 4
 1116: 
 1117: =item buf
 1118: 
 1119: The buffer containing command output.
 1120: 
 1121: =item len
 1122: 
 1123: The length of I<buf> in bytes.
 1124: 
 1125: =back
 1126: 
 1127: =item log_stdin
 1128: 
 1129:  int (*log_stdin)(const char *buf, unsigned int len);
 1130: 
 1131: The I<log_stdin> function is only used if the standard input does
 1132: not correspond to a tty device.  It is called whenever data can be
 1133: read from the standard input but before it is passed to the running
 1134: command.  This allows the plugin to reject data if it chooses to
 1135: (for instance if the input contains banned content).  Returns C<1>
 1136: if the data should be passed to the command, C<0> if the data is
 1137: rejected (which will terminate the command) or C<-1> if an error
 1138: occurred.
 1139: 
 1140: The function arguments are as follows:
 1141: 
 1142: =over 4
 1143: 
 1144: =item buf
 1145: 
 1146: The buffer containing user input.
 1147: 
 1148: =item len
 1149: 
 1150: The length of I<buf> in bytes.
 1151: 
 1152: =back
 1153: 
 1154: =item log_stdout
 1155: 
 1156:  int (*log_stdout)(const char *buf, unsigned int len);
 1157: 
 1158: The I<log_stdout> function is only used if the standard output does
 1159: not correspond to a tty device.  It is called whenever data can be
 1160: read from the command but before it is written to the standard
 1161: output.  This allows the plugin to reject data if it chooses to
 1162: (for instance if the output contains banned content).  Returns C<1>
 1163: if the data should be passed to the user, C<0> if the data is
 1164: rejected (which will terminate the command) or C<-1> if an error
 1165: occurred.
 1166: 
 1167: The function arguments are as follows:
 1168: 
 1169: =over 4
 1170: 
 1171: =item buf
 1172: 
 1173: The buffer containing command output.
 1174: 
 1175: =item len
 1176: 
 1177: The length of I<buf> in bytes.
 1178: 
 1179: =back
 1180: 
 1181: =item log_stderr
 1182: 
 1183:  int (*log_stderr)(const char *buf, unsigned int len);
 1184: 
 1185: The I<log_stderr> function is only used if the standard error does
 1186: not correspond to a tty device.  It is called whenever data can be
 1187: read from the command but before it is written to the standard
 1188: error.  This allows the plugin to reject data if it chooses to
 1189: (for instance if the output contains banned content).  Returns C<1>
 1190: if the data should be passed to the user, C<0> if the data is
 1191: rejected (which will terminate the command) or C<-1> if an error
 1192: occurred.
 1193: 
 1194: The function arguments are as follows:
 1195: 
 1196: =over 4
 1197: 
 1198: =item buf
 1199: 
 1200: The buffer containing command output.
 1201: 
 1202: =item len
 1203: 
 1204: The length of I<buf> in bytes.
 1205: 
 1206: =back
 1207: 
 1208: =item register_hooks
 1209: 
 1210: See the L<Policy Plugin API> section for a description of
 1211: C<register_hooks>.
 1212: 
 1213: =item deregister_hooks
 1214: 
 1215: See the L<Policy Plugin API> section for a description of
 1216: C<deregister_hooks>.
 1217: 
 1218: =back
 1219: 
 1220: =head3 I/O Plugin Version Macros
 1221: 
 1222: Same as for the L<Policy Plugin API>.
 1223: 
 1224: =head2 Hook Function API
 1225: 
 1226: Beginning with plugin API version 1.2, it is possible to install
 1227: hooks for certain functions called by the B<sudo> front end.
 1228: 
 1229: Currently, the only supported hooks relate to the handling of
 1230: environment variables.  Hooks can be used to intercept attempts to
 1231: get, set, or remove environment variables so that these changes can
 1232: be reflected in the version of the environment that is used to
 1233: execute a command.  A future version of the API will support
 1234: hooking internal B<sudo> front end functions as well.
 1235: 
 1236: =head3 Hook structure
 1237: 
 1238: Hooks in B<sudo> are described by the following structure:
 1239: 
 1240:  typedef int (*sudo_hook_fn_t)();
 1241: 
 1242:  struct sudo_hook {
 1243:      int hook_version;
 1244:      int hook_type;
 1245:      sudo_hook_fn_t hook_fn;
 1246:      void *closure;
 1247:  };
 1248: 
 1249: The C<sudo_hook> structure has the following fields:
 1250: 
 1251: =over 4
 1252: 
 1253: =item hook_version
 1254: 
 1255: The C<hook_version> field should be set to SUDO_HOOK_VERSION.
 1256: 
 1257: =item hook_type
 1258: 
 1259: The C<hook_type> field may be one of the following supported hook types:
 1260: 
 1261: =over 4
 1262: 
 1263: =item SUDO_HOOK_SETENV
 1264: 
 1265: The C library C<setenv()> function.  Any registered hooks will run
 1266: before the C library implementation.  The C<hook_fn> field should
 1267: be a function that matches the following typedef:
 1268: 
 1269:  typedef int (*sudo_hook_fn_setenv_t)(const char *name,
 1270:     const char *value, int overwrite, void *closure);
 1271: 
 1272: If the registered hook does not match the typedef the results are
 1273: unspecified.
 1274: 
 1275: =item SUDO_HOOK_UNSETENV
 1276: 
 1277: The C library C<unsetenv()> function.  Any registered hooks will run
 1278: before the C library implementation.  The C<hook_fn> field should
 1279: be a function that matches the following typedef:
 1280: 
 1281:  typedef int (*sudo_hook_fn_unsetenv_t)(const char *name,
 1282:     void *closure);
 1283: 
 1284: =item SUDO_HOOK_GETENV
 1285: 
 1286: The C library C<getenv()> function.  Any registered hooks will run
 1287: before the C library implementation.  The C<hook_fn> field should
 1288: be a function that matches the following typedef:
 1289: 
 1290:  typedef int (*sudo_hook_fn_getenv_t)(const char *name,
 1291:     char **value, void *closure);
 1292: 
 1293: If the registered hook does not match the typedef the results are
 1294: unspecified.
 1295: 
 1296: =item SUDO_HOOK_PUTENV
 1297: 
 1298: The C library C<putenv()> function.  Any registered hooks will run
 1299: before the C library implementation.  The C<hook_fn> field should
 1300: be a function that matches the following typedef:
 1301: 
 1302:  typedef int (*sudo_hook_fn_putenv_t)(char *string,
 1303:     void *closure);
 1304: 
 1305: If the registered hook does not match the typedef the results are
 1306: unspecified.
 1307: 
 1308: =back
 1309: 
 1310: =item hook_fn
 1311: 
 1312:  sudo_hook_fn_t hook_fn;
 1313: 
 1314: The C<hook_fn> field should be set to the plugin's hook implementation.
 1315: The actual function arguments will vary depending on the C<hook_type>
 1316: (see C<hook_type> above).  In all cases, the C<closure> field of
 1317: C<struct sudo_hook> is passed as the last function parameter.  This
 1318: can be used to pass arbitrary data to the plugin's hook implementation.
 1319: 
 1320: The function return value may be one of the following:
 1321: 
 1322: =over 4
 1323: 
 1324: =item SUDO_HOOK_RET_ERROR
 1325: 
 1326: The hook function encountered an error.
 1327: 
 1328: =item SUDO_HOOK_RET_NEXT
 1329: 
 1330: The hook completed without error, go on to the next hook (including
 1331: the native implementation if applicable).  For example, a C<getenv>
 1332: hook might return C<SUDO_HOOK_RET_NEXT> if the specified variable
 1333: was not found in the private copy of the environment.
 1334: 
 1335: =item SUDO_HOOK_RET_STOP
 1336: 
 1337: The hook completed without error, stop processing hooks for this
 1338: invocation.  This can be used to replace the native implementation.
 1339: For example, a C<setenv> hook that operates on a private copy of
 1340: the environment but leaves C<environ> unchanged.
 1341: 
 1342: =back
 1343: 
 1344: =back
 1345: 
 1346: Note that it is very easy to create an infinite loop when hooking
 1347: C library functions.  For example, a C<getenv> hook that calls the
 1348: C<snprintf> function may create a loop if the C<snprintf> implementation
 1349: calls C<getenv> to check the locale.  To prevent this, you may wish
 1350: to use a static variable in the hook function to guard against
 1351: nested calls.  E.g.
 1352: 
 1353:  static int in_progress = 0; /* avoid recursion */
 1354:  if (in_progress)
 1355:      return SUDO_HOOK_RET_NEXT;
 1356:  in_progress = 1;
 1357:  ...
 1358:  in_progress = 0;
 1359:  return SUDO_HOOK_RET_STOP;
 1360: 
 1361: =head3 Hook API Version Macros
 1362: 
 1363:  /* Hook API version major/minor */
 1364:  #define SUDO_HOOK_VERSION_MAJOR 1
 1365:  #define SUDO_HOOK_VERSION_MINOR 0
 1366:  #define SUDO_HOOK_MKVERSION(x, y) ((x << 16) | y)
 1367:  #define SUDO_HOOK_VERSION SUDO_HOOK_MKVERSION(SUDO_HOOK_VERSION_MAJOR,\
 1368: 					       SUDO_HOOK_VERSION_MINOR)
 1369: 
 1370:  /* Getters and setters for hook API version */
 1371:  #define SUDO_HOOK_VERSION_GET_MAJOR(v) ((v) >> 16)
 1372:  #define SUDO_HOOK_VERSION_GET_MINOR(v) ((v) & 0xffff)
 1373:  #define SUDO_HOOK_VERSION_SET_MAJOR(vp, n) do { \
 1374:      *(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \
 1375:  } while(0)
 1376:  #define SUDO_HOOK_VERSION_SET_MINOR(vp, n) do { \
 1377:      *(vp) = (*(vp) & 0xffff0000) | (n); \
 1378:  } while(0)
 1379: 
 1380: =head2 Conversation API
 1381: 
 1382: If the plugin needs to interact with the user, it may do so via the
 1383: conversation function.  A plugin should not attempt to read directly
 1384: from the standard input or the user's tty (neither of which are
 1385: guaranteed to exist).  The caller must include a trailing newline
 1386: in C<msg> if one is to be printed.
 1387: 
 1388: A printf-style function is also available that can be used to display
 1389: informational or error messages to the user, which is usually more
 1390: convenient for simple messages where no use input is required.
 1391: 
 1392:  struct sudo_conv_message {
 1393:  #define SUDO_CONV_PROMPT_ECHO_OFF  0x0001 /* do not echo user input */
 1394:  #define SUDO_CONV_PROMPT_ECHO_ON   0x0002 /* echo user input */
 1395:  #define SUDO_CONV_ERROR_MSG	    0x0003 /* error message */
 1396:  #define SUDO_CONV_INFO_MSG	    0x0004 /* informational message */
 1397:  #define SUDO_CONV_PROMPT_MASK	    0x0005 /* mask user input */
 1398:  #define SUDO_CONV_DEBUG_MSG	    0x0006 /* debugging message */
 1399:  #define SUDO_CONV_PROMPT_ECHO_OK   0x1000 /* flag: allow echo if no tty */
 1400:      int msg_type;
 1401:      int timeout;
 1402:      const char *msg;
 1403:  };
 1404: 
 1405:  struct sudo_conv_reply {
 1406:      char *reply;
 1407:  };
 1408: 
 1409:  typedef int (*sudo_conv_t)(int num_msgs,
 1410: 	      const struct sudo_conv_message msgs[],
 1411:               struct sudo_conv_reply replies[]);
 1412: 
 1413:  typedef int (*sudo_printf_t)(int msg_type, const char *fmt, ...);
 1414: 
 1415: Pointers to the conversation and printf-style functions are passed
 1416: in to the plugin's C<open> function when the plugin is initialized.
 1417: 
 1418: To use the conversation function, the plugin must pass an array of
 1419: C<sudo_conv_message> and C<sudo_conv_reply> structures.  There must
 1420: be a C<struct sudo_conv_message> and C<struct sudo_conv_reply> for
 1421: each message in the conversation.  The plugin is responsible for
 1422: freeing the reply buffer filled in to the C<struct sudo_conv_reply>,
 1423: if any.
 1424: 
 1425: The printf-style function uses the same underlying mechanism as the
 1426: conversation function but only supports C<SUDO_CONV_INFO_MSG>,
 1427: C<SUDO_CONV_ERROR_MSG> and C<SUDO_CONV_DEBUG_MSG> for the I<msg_type>
 1428: parameter.  It can be more convenient than using the conversation
 1429: function if no user reply is needed and supports standard printf()
 1430: escape sequences.
 1431: 
 1432: Unlike, C<SUDO_CONV_INFO_MSG> and C<SUDO_CONV_ERROR_MSG>, messages
 1433: sent with the <SUDO_CONV_DEBUG_MSG> I<msg_type> are not directly
 1434: user-visible.  Instead, they are logged to the file specified in
 1435: the C<Debug> statement (if any) in the F<@sysconfdir@/sudo.conf>
 1436: file.  This allows a plugin to log debugging information and is
 1437: intended to be used in conjunction with the I<debug_flags> setting.
 1438: 
 1439: See the sample plugin for an example of the conversation function usage.
 1440: 
 1441: =head2 Sudoers Group Plugin API
 1442: 
 1443: The I<sudoers> module supports a plugin interface to allow non-Unix
 1444: group lookups.  This can be used to query a group source other than
 1445: the standard Unix group database.  A sample group plugin is bundled
 1446: with B<sudo> that implements file-based lookups.  Third party group
 1447: plugins include a QAS AD plugin available from Quest Software.
 1448: 
 1449: A group plugin must declare and populate a C<sudoers_group_plugin>
 1450: struct in the global scope.  This structure contains pointers to
 1451: the functions that implement plugin initialization, cleanup and
 1452: group lookup.
 1453: 
 1454:  struct sudoers_group_plugin {
 1455:     unsigned int version;
 1456:     int (*init)(int version, sudo_printf_t sudo_printf,
 1457:                 char *const argv[]);
 1458:     void (*cleanup)(void);
 1459:     int (*query)(const char *user, const char *group,
 1460:                  const struct passwd *pwd);
 1461: };
 1462: 
 1463: The C<sudoers_group_plugin> struct has the following fields:
 1464: 
 1465: =over 4
 1466: 
 1467: =item version
 1468: 
 1469: The C<version> field should be set to GROUP_API_VERSION.
 1470: 
 1471: This allows I<sudoers> to determine the API version the group plugin
 1472: was built against.
 1473: 
 1474: =item init
 1475: 
 1476:  int (*init)(int version, sudo_printf_t plugin_printf,
 1477:              char *const argv[]);
 1478: 
 1479: The I<init> function is called after I<sudoers> has been parsed but
 1480: before any policy checks.  It returns 1 on success, 0 on failure
 1481: (or if the plugin is not configured), and -1 if a error occurred.
 1482: If an error occurs, the plugin may call the plugin_printf function
 1483: with C<SUDO_CONF_ERROR_MSG> to present additional error information
 1484: to the user.
 1485: 
 1486: The function arguments are as follows:
 1487: 
 1488: =over 4
 1489: 
 1490: =item version
 1491: 
 1492: The version passed in by I<sudoers> allows the plugin to determine the
 1493: major and minor version number of the group plugin API supported by
 1494: I<sudoers>.
 1495: 
 1496: =item plugin_printf
 1497: 
 1498: A pointer to a printf-style function that may be used to display
 1499: informational or error message to the user.
 1500: Returns the number of characters printed on success and -1 on failure.
 1501: 
 1502: =item argv
 1503: 
 1504: A NULL-terminated array of arguments generated from the I<group_plugin>
 1505: option in I<sudoers>.  If no arguments were given, I<argv> will be
 1506: NULL.
 1507: 
 1508: =back
 1509: 
 1510: =item cleanup
 1511: 
 1512:  void (*cleanup)();
 1513: 
 1514: The I<cleanup> function is called when I<sudoers> has finished its
 1515: group checks.  The plugin should free any memory it has allocated
 1516: and close open file handles.
 1517: 
 1518: =item query
 1519: 
 1520:  int (*query)(const char *user, const char *group,
 1521:               const struct passwd *pwd);
 1522: 
 1523: The I<query> function is used to ask the group plugin whether I<user>
 1524: is a member of I<group>.
 1525: 
 1526: The function arguments are as follows:
 1527: 
 1528: =over 4
 1529: 
 1530: =item user
 1531: 
 1532: The name of the user being looked up in the external group database.
 1533: 
 1534: =item group
 1535: 
 1536: The name of the group being queried.
 1537: 
 1538: =item pwd
 1539: 
 1540: The password database entry for I<user>, if any.  If I<user> is not
 1541: present in the password database, I<pwd> will be C<NULL>.
 1542: 
 1543: =back
 1544: 
 1545: =back
 1546: 
 1547: =head3 Group API Version Macros
 1548: 
 1549:  /* Sudoers group plugin version major/minor */
 1550:  #define GROUP_API_VERSION_MAJOR 1
 1551:  #define GROUP_API_VERSION_MINOR 0
 1552:  #define GROUP_API_VERSION ((GROUP_API_VERSION_MAJOR << 16) | \
 1553:                             GROUP_API_VERSION_MINOR)
 1554: 
 1555:  /* Getters and setters for group version */
 1556:  #define GROUP_API_VERSION_GET_MAJOR(v) ((v) >> 16)
 1557:  #define GROUP_API_VERSION_GET_MINOR(v) ((v) & 0xffff)
 1558:  #define GROUP_API_VERSION_SET_MAJOR(vp, n) do { \
 1559:      *(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \
 1560:  } while(0)
 1561:  #define GROUP_API_VERSION_SET_MINOR(vp, n) do { \
 1562:      *(vp) = (*(vp) & 0xffff0000) | (n); \
 1563:  } while(0)
 1564: 
 1565: =head1 PLUGIN API CHANGELOG
 1566: 
 1567: The following revisions have been made to the Sudo Plugin API.
 1568: 
 1569: =over 4
 1570: 
 1571: =item Version 1.0
 1572: 
 1573: Initial API version.
 1574: 
 1575: =item Version 1.1
 1576: 
 1577: The I/O logging plugin's C<open> function was modified to take the
 1578: C<command_info> list as an argument.
 1579: 
 1580: =item Version 1.2
 1581: 
 1582: The Policy and I/O logging plugins' C<open> functions are now passed
 1583: a list of plugin options if any are specified in F<@sysconfdir@/sudo.conf>.
 1584: 
 1585: A simple hooks API has been introduced to allow plugins to hook in to the
 1586: system's environment handling functions.
 1587: 
 1588: The C<init_session> Policy plugin function is now passed a pointer
 1589: to the user environment which can be updated as needed.  This can
 1590: be used to merge in environment variables stored in the PAM handle
 1591: before a command is run.
 1592: 
 1593: =back
 1594: 
 1595: 
 1596: =head1 SEE ALSO
 1597: 
 1598: L<sudoers(5)>, L<sudo(8)>
 1599: 
 1600: =head1 BUGS
 1601: 
 1602: If you feel you have found a bug in B<sudo>, please submit a bug report
 1603: at http://www.sudo.ws/sudo/bugs/
 1604: 
 1605: =head1 SUPPORT
 1606: 
 1607: Limited free support is available via the sudo-workers mailing list,
 1608: see http://www.sudo.ws/mailman/listinfo/sudo-workers to subscribe or
 1609: search the archives.
 1610: 
 1611: =head1 DISCLAIMER
 1612: 
 1613: B<sudo> is provided ``AS IS'' and any express or implied warranties,
 1614: including, but not limited to, the implied warranties of merchantability
 1615: and fitness for a particular purpose are disclaimed.  See the LICENSE
 1616: file distributed with B<sudo> or http://www.sudo.ws/sudo/license.html
 1617: for complete details.

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