File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / sudo / doc / sudo_plugin.cat
Revision 1.1.1.4 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Jul 22 10:46:12 2013 UTC (11 years ago) by misho
Branches: sudo, MAIN
CVS tags: v1_8_7p0, v1_8_7, HEAD
1.8.7

    1: SUDO_PLUGIN(4)                Programmer's Manual               SUDO_PLUGIN(4)
    2: 
    3: NNAAMMEE
    4:      ssuuddoo__pplluuggiinn - Sudo Plugin API
    5: 
    6: DDEESSCCRRIIPPTTIIOONN
    7:      Starting with version 1.8, ssuuddoo supports a plugin API for policy and
    8:      session logging.  By default, the ssuuddooeerrss policy plugin and an associated
    9:      I/O logging plugin are used.  Via the plugin API, ssuuddoo can be configured
   10:      to use alternate policy and/or I/O logging plugins provided by third
   11:      parties.  The plugins to be used are specified in the sudo.conf(4) file.
   12: 
   13:      The API is versioned with a major and minor number.  The minor version
   14:      number is incremented when additions are made.  The major number is
   15:      incremented when incompatible changes are made.  A plugin should be check
   16:      the version passed to it and make sure that the major version matches.
   17: 
   18:      The plugin API is defined by the sudo_plugin.h header file.
   19: 
   20:    PPoolliiccyy pplluuggiinn AAPPII
   21:      A policy plugin must declare and populate a policy_plugin struct in the
   22:      global scope.  This structure contains pointers to the functions that
   23:      implement the ssuuddoo policy checks.  The name of the symbol should be
   24:      specified in sudo.conf(4) along with a path to the plugin so that ssuuddoo
   25:      can load it.
   26: 
   27:      struct policy_plugin {
   28:      #define SUDO_POLICY_PLUGIN     1
   29:          unsigned int type; /* always SUDO_POLICY_PLUGIN */
   30:          unsigned int version; /* always SUDO_API_VERSION */
   31:          int (*open)(unsigned int version, sudo_conv_t conversation,
   32:                      sudo_printf_t plugin_printf, char * const settings[],
   33:                      char * const user_info[], char * const user_env[],
   34:                      char * const plugin_options[]);
   35:          void (*close)(int exit_status, int error);
   36:          int (*show_version)(int verbose);
   37:          int (*check_policy)(int argc, char * const argv[],
   38:                              char *env_add[], char **command_info[],
   39:                              char **argv_out[], char **user_env_out[]);
   40:          int (*list)(int argc, char * const argv[], int verbose,
   41:                      const char *list_user);
   42:          int (*validate)(void);
   43:          void (*invalidate)(int remove);
   44:          int (*init_session)(struct passwd *pwd, char **user_env[]);
   45:          void (*register_hooks)(int version,
   46:             int (*register_hook)(struct sudo_hook *hook));
   47:          void (*deregister_hooks)(int version,
   48:             int (*deregister_hook)(struct sudo_hook *hook));
   49:      };
   50: 
   51:      The policy_plugin struct has the following fields:
   52: 
   53:      type  The type field should always be set to SUDO_POLICY_PLUGIN.
   54: 
   55:      version
   56:            The version field should be set to SUDO_API_VERSION.
   57: 
   58:            This allows ssuuddoo to determine the API version the plugin was built
   59:            against.
   60: 
   61:      open
   62:            int (*open)(unsigned int version, sudo_conv_t conversation,
   63:                        sudo_printf_t plugin_printf, char * const settings[],
   64:                        char * const user_info[], char * const user_env[],
   65:                        char * const plugin_options[]);
   66: 
   67:            Returns 1 on success, 0 on failure, -1 if a general error occurred,
   68:            or -2 if there was a usage error.  In the latter case, ssuuddoo will
   69:            print a usage message before it exits.  If an error occurs, the
   70:            plugin may optionally call the ccoonnvveerrssaattiioonn() or pplluuggiinn__pprriinnttff()
   71:            function with SUDO_CONF_ERROR_MSG to present additional error
   72:            information to the user.
   73: 
   74:            The function arguments are as follows:
   75: 
   76:            version
   77:                  The version passed in by ssuuddoo allows the plugin to determine
   78:                  the major and minor version number of the plugin API
   79:                  supported by ssuuddoo.
   80: 
   81:            conversation
   82:                  A pointer to the ccoonnvveerrssaattiioonn() function that can be used by
   83:                  the plugin to interact with the user (see below).  Returns 0
   84:                  on success and -1 on failure.
   85: 
   86:            plugin_printf
   87:                  A pointer to a pprriinnttff()-style function that may be used to
   88:                  display informational or error messages (see below).  Returns
   89:                  the number of characters printed on success and -1 on
   90:                  failure.
   91: 
   92:            settings
   93:                  A vector of user-supplied ssuuddoo settings in the form of
   94:                  ``name=value'' strings.  The vector is terminated by a NULL
   95:                  pointer.  These settings correspond to flags the user
   96:                  specified when running ssuuddoo.  As such, they will only be
   97:                  present when the corresponding flag has been specified on the
   98:                  command line.
   99: 
  100:                  When parsing _s_e_t_t_i_n_g_s, the plugin should split on the ffiirrsstt
  101:                  equal sign (`=') since the _n_a_m_e field will never include one
  102:                  itself but the _v_a_l_u_e might.
  103: 
  104:                  bsdauth_type=string
  105:                        Authentication type, if specified by the --aa flag, to
  106:                        use on systems where BSD authentication is supported.
  107: 
  108:                  closefrom=number
  109:                        If specified, the user has requested via the --CC flag
  110:                        that ssuuddoo close all files descriptors with a value of
  111:                        _n_u_m_b_e_r or higher.  The plugin may optionally pass this,
  112:                        or another value, back in the _c_o_m_m_a_n_d___i_n_f_o list.
  113: 
  114:                  debug_flags=string
  115:                        A comma-separated list of debug flags that correspond
  116:                        to ssuuddoo's Debug entry in sudo.conf(4), if there is one.
  117:                        The flags are passed to the plugin as they appear in
  118:                        sudo.conf(4).  The syntax used by ssuuddoo and the ssuuddooeerrss
  119:                        plugin is _s_u_b_s_y_s_t_e_m@_p_r_i_o_r_i_t_y but the plugin is free to
  120:                        use a different format so long as it does not include a
  121:                        comma (`,').  There is not currently a way to specify a
  122:                        set of debug flags specific to the plugin--the flags
  123:                        are shared by ssuuddoo and the plugin.
  124: 
  125:                  debug_level=number
  126:                        This setting has been deprecated in favor of
  127:                        _d_e_b_u_g___f_l_a_g_s.
  128: 
  129:                  ignore_ticket=bool
  130:                        Set to true if the user specified the --kk flag along
  131:                        with a command, indicating that the user wishes to
  132:                        ignore any cached authentication credentials.
  133:                        _i_m_p_l_i_e_d___s_h_e_l_l to true.  This allows ssuuddoo with no
  134:                        arguments to be used similarly to su(1).  If the plugin
  135:                        does not to support this usage, it may return a value
  136:                        of -2 from the cchheecckk__ppoolliiccyy() function, which will
  137:                        cause ssuuddoo to print a usage message and exit.
  138: 
  139:                  implied_shell=bool
  140:                        If the user does not specify a program on the command
  141:                        line, ssuuddoo will pass the plugin the path to the user's
  142:                        shell and set
  143: 
  144:                  login_class=string
  145:                        BSD login class to use when setting resource limits and
  146:                        nice value, if specified by the --cc flag.
  147: 
  148:                  login_shell=bool
  149:                        Set to true if the user specified the --ii flag,
  150:                        indicating that the user wishes to run a login shell.
  151: 
  152:                  max_groups=int
  153:                        The maximum number of groups a user may belong to.
  154:                        This will only be present if there is a corresponding
  155:                        setting in sudo.conf(4).
  156: 
  157:                  network_addrs=list
  158:                        A space-separated list of IP network addresses and
  159:                        netmasks in the form ``addr/netmask'', e.g.
  160:                        ``192.168.1.2/255.255.255.0''.  The address and netmask
  161:                        pairs may be either IPv4 or IPv6, depending on what the
  162:                        operating system supports.  If the address contains a
  163:                        colon (`:'), it is an IPv6 address, else it is IPv4.
  164: 
  165:                  noninteractive=bool
  166:                        Set to true if the user specified the --nn flag,
  167:                        indicating that ssuuddoo should operate in non-interactive
  168:                        mode.  The plugin may reject a command run in non-
  169:                        interactive mode if user interaction is required.
  170: 
  171:                  plugin_dir=string
  172:                        The default plugin directory used by the ssuuddoo front
  173:                        end.  This is the default directory set at compile time
  174:                        and may not correspond to the directory the running
  175:                        plugin was loaded from.  It may be used by a plugin to
  176:                        locate support files.
  177: 
  178:                  preserve_environment=bool
  179:                        Set to true if the user specified the --EE flag,
  180:                        indicating that the user wishes to preserve the
  181:                        environment.
  182: 
  183:                  preserve_groups=bool
  184:                        Set to true if the user specified the --PP flag,
  185:                        indicating that the user wishes to preserve the group
  186:                        vector instead of setting it based on the runas user.
  187: 
  188:                  progname=string
  189:                        The command name that sudo was run as, typically
  190:                        ``sudo'' or ``sudoedit''.
  191: 
  192:                  prompt=string
  193:                        The prompt to use when requesting a password, if
  194:                        specified via the --pp flag.
  195: 
  196:                  run_shell=bool
  197:                        Set to true if the user specified the --ss flag,
  198:                        indicating that the user wishes to run a shell.
  199: 
  200:                  runas_group=string
  201:                        The group name or gid to to run the command as, if
  202:                        specified via the --gg flag.
  203: 
  204:                  runas_user=string
  205:                        The user name or uid to to run the command as, if
  206:                        specified via the --uu flag.
  207: 
  208:                  selinux_role=string
  209:                        SELinux role to use when executing the command, if
  210:                        specified by the --rr flag.
  211: 
  212:                  selinux_type=string
  213:                        SELinux type to use when executing the command, if
  214:                        specified by the --tt flag.
  215: 
  216:                  set_home=bool
  217:                        Set to true if the user specified the --HH flag.  If
  218:                        true, set the HOME environment variable to the target
  219:                        user's home directory.
  220: 
  221:                  sudoedit=bool
  222:                        Set to true when the --ee flag is is specified or if
  223:                        invoked as ssuuddooeeddiitt.  The plugin shall substitute an
  224:                        editor into _a_r_g_v in the cchheecckk__ppoolliiccyy() function or
  225:                        return -2 with a usage error if the plugin does not
  226:                        support _s_u_d_o_e_d_i_t.  For more information, see the
  227:                        _c_h_e_c_k___p_o_l_i_c_y section.
  228: 
  229:                  Additional settings may be added in the future so the plugin
  230:                  should silently ignore settings that it does not recognize.
  231: 
  232:            user_info
  233:                  A vector of information about the user running the command in
  234:                  the form of ``name=value'' strings.  The vector is terminated
  235:                  by a NULL pointer.
  236: 
  237:                  When parsing _u_s_e_r___i_n_f_o, the plugin should split on the ffiirrsstt
  238:                  equal sign (`=') since the _n_a_m_e field will never include one
  239:                  itself but the _v_a_l_u_e might.
  240: 
  241:                  cols=int
  242:                        The number of columns the user's terminal supports.  If
  243:                        there is no terminal device available, a default value
  244:                        of 80 is used.
  245: 
  246:                  cwd=string
  247:                        The user's current working directory.
  248: 
  249:                  egid=gid_t
  250:                        The effective group ID of the user invoking ssuuddoo.
  251: 
  252:                  euid=uid_t
  253:                        The effective user ID of the user invoking ssuuddoo.
  254: 
  255:                  gid=gid_t
  256:                        The real group ID of the user invoking ssuuddoo.
  257: 
  258:                  groups=list
  259:                        The user's supplementary group list formatted as a
  260:                        string of comma-separated group IDs.
  261: 
  262:                  host=string
  263:                        The local machine's hostname as returned by the
  264:                        gethostname(2) system call.
  265: 
  266:                  lines=int
  267:                        The number of lines the user's terminal supports.  If
  268:                        there is no terminal device available, a default value
  269:                        of 24 is used.
  270: 
  271:                  pgid=int
  272:                        The ID of the process group that the running ssuuddoo
  273:                        process is a member of.  Only available starting with
  274:                        API version 1.2
  275: 
  276:                  pid=int
  277:                        The process ID of the running ssuuddoo process.  Only
  278:                        available starting with API version 1.2
  279: 
  280:                  plugin_options
  281:                        Any (non-comment) strings immediately after the plugin
  282:                        path are passed as arguments to the plugin.  These
  283:                        arguments are split on a white space boundary and are
  284:                        passed to the plugin in the form of a NULL-terminated
  285:                        array of strings.  If no arguments were specified,
  286:                        _p_l_u_g_i_n___o_p_t_i_o_n_s will be the NULL pointer.
  287: 
  288:                        NOTE: the _p_l_u_g_i_n___o_p_t_i_o_n_s parameter is only available
  289:                        starting with API version 1.2.  A plugin mmuusstt check the
  290:                        API version specified by the ssuuddoo front end before
  291:                        using _p_l_u_g_i_n___o_p_t_i_o_n_s.  Failure to do so may result in a
  292:                        crash.
  293: 
  294:                  ppid=int
  295:                        The parent process ID of the running ssuuddoo process.
  296:                        Only available starting with API version 1.2
  297: 
  298:                  sid=int
  299:                        The session ID of the running ssuuddoo process or 0 if ssuuddoo
  300:                        is not part of a POSIX job control session.  Only
  301:                        available starting with API version 1.2
  302: 
  303:                  tcpgid=int
  304:                        The ID of the foreground process group associated with
  305:                        the terminal device associated with the ssuuddoo process or
  306:                        -1 if there is no terminal present.  Only available
  307:                        starting with API version 1.2
  308: 
  309:                  tty=string
  310:                        The path to the user's terminal device.  If the user
  311:                        has no terminal device associated with the session, the
  312:                        value will be empty, as in ``tty=''.
  313: 
  314:                  uid=uid_t
  315:                        The real user ID of the user invoking ssuuddoo.
  316: 
  317:                  user=string
  318:                        The name of the user invoking ssuuddoo.
  319: 
  320:            user_env
  321:                  The user's environment in the form of a NULL-terminated
  322:                  vector of ``name=value'' strings.
  323: 
  324:                  When parsing _u_s_e_r___e_n_v, the plugin should split on the ffiirrsstt
  325:                  equal sign (`=') since the _n_a_m_e field will never include one
  326:                  itself but the _v_a_l_u_e might.
  327: 
  328:      close
  329:            void (*close)(int exit_status, int error);
  330: 
  331:            The cclloossee() function is called when the command being run by ssuuddoo
  332:            finishes.
  333: 
  334:            The function arguments are as follows:
  335: 
  336:            exit_status
  337:                  The command's exit status, as returned by the wait(2) system
  338:                  call.  The value of exit_status is undefined if error is non-
  339:                  zero.
  340: 
  341:            error
  342:                  If the command could not be executed, this is set to the
  343:                  value of errno set by the execve(2) system call.  The plugin
  344:                  is responsible for displaying error information via the
  345:                  ccoonnvveerrssaattiioonn() or pplluuggiinn__pprriinnttff() function.  If the command
  346:                  was successfully executed, the value of error is 0.
  347: 
  348:            If no cclloossee() function is defined, no I/O logging plugins are
  349:            loaded, and neither the _t_i_m_e_o_u_t not _u_s_e___p_t_y options are set in the
  350:            command_info list, the ssuuddoo front end may execute the command
  351:            directly instead of running it as a child process.
  352: 
  353:      show_version
  354:            int (*show_version)(int verbose);
  355: 
  356:            The sshhooww__vveerrssiioonn() function is called by ssuuddoo when the user
  357:            specifies the --VV option.  The plugin may display its version
  358:            information to the user via the ccoonnvveerrssaattiioonn() or pplluuggiinn__pprriinnttff()
  359:            function using SUDO_CONV_INFO_MSG.  If the user requests detailed
  360:            version information, the verbose flag will be set.
  361: 
  362:      check_policy
  363:            int (*check_policy)(int argc, char * const argv[]
  364:                                char *env_add[], char **command_info[],
  365:                                char **argv_out[], char **user_env_out[]);
  366: 
  367:            The cchheecckk__ppoolliiccyy() function is called by ssuuddoo to determine whether
  368:            the user is allowed to run the specified commands.
  369: 
  370:            If the _s_u_d_o_e_d_i_t option was enabled in the _s_e_t_t_i_n_g_s array passed to
  371:            the ooppeenn() function, the user has requested _s_u_d_o_e_d_i_t mode.
  372:            _s_u_d_o_e_d_i_t is a mechanism for editing one or more files where an
  373:            editor is run with the user's credentials instead of with elevated
  374:            privileges.  ssuuddoo achieves this by creating user-writable temporary
  375:            copies of the files to be edited and then overwriting the originals
  376:            with the temporary copies after editing is complete.  If the plugin
  377:            supports _s_u_d_o_e_d_i_t, it should choose the editor to be used,
  378:            potentially from a variable in the user's environment, such as
  379:            EDITOR, and include it in _a_r_g_v___o_u_t (note that environment variables
  380:            may include command line flags).  The files to be edited should be
  381:            copied from _a_r_g_v into _a_r_g_v___o_u_t, separated from the editor and its
  382:            arguments by a ``--'' element.  The ``--'' will be removed by ssuuddoo
  383:            before the editor is executed.  The plugin should also set
  384:            _s_u_d_o_e_d_i_t_=_t_r_u_e in the _c_o_m_m_a_n_d___i_n_f_o list.
  385: 
  386:            The cchheecckk__ppoolliiccyy() function returns 1 if the command is allowed, 0
  387:            if not allowed, -1 for a general error, or -2 for a usage error or
  388:            if _s_u_d_o_e_d_i_t was specified but is unsupported by the plugin.  In the
  389:            latter case, ssuuddoo will print a usage message before it exits.  If
  390:            an error occurs, the plugin may optionally call the ccoonnvveerrssaattiioonn()
  391:            or pplluuggiinn__pprriinnttff() function with SUDO_CONF_ERROR_MSG to present
  392:            additional error information to the user.
  393: 
  394:            The function arguments are as follows:
  395: 
  396:            argc  The number of elements in _a_r_g_v, not counting the final NULL
  397:                  pointer.
  398: 
  399:            argv  The argument vector describing the command the user wishes to
  400:                  run, in the same form as what would be passed to the
  401:                  execve(2) system call.  The vector is terminated by a NULL
  402:                  pointer.
  403: 
  404:            env_add
  405:                  Additional environment variables specified by the user on the
  406:                  command line in the form of a NULL-terminated vector of
  407:                  ``name=value'' strings.  The plugin may reject the command if
  408:                  one or more variables are not allowed to be set, or it may
  409:                  silently ignore such variables.
  410: 
  411:                  When parsing _e_n_v___a_d_d, the plugin should split on the ffiirrsstt
  412:                  equal sign (`=') since the _n_a_m_e field will never include one
  413:                  itself but the _v_a_l_u_e might.
  414: 
  415:            command_info
  416:                  Information about the command being run in the form of
  417:                  ``name=value'' strings.  These values are used by ssuuddoo to set
  418:                  the execution environment when running a command.  The plugin
  419:                  is responsible for creating and populating the vector, which
  420:                  must be terminated with a NULL pointer.  The following values
  421:                  are recognized by ssuuddoo:
  422: 
  423:                  chroot=string
  424:                        The root directory to use when running the command.
  425: 
  426:                  closefrom=number
  427:                        If specified, ssuuddoo will close all files descriptors
  428:                        with a value of _n_u_m_b_e_r or higher.
  429: 
  430:                  command=string
  431:                        Fully qualified path to the command to be executed.
  432: 
  433:                  cwd=string
  434:                        The current working directory to change to when
  435:                        executing the command.
  436: 
  437:                  exec_background=bool
  438:                        By default, ssuuddoo runs a command as the foreground
  439:                        process as long as ssuuddoo itself is running in the
  440:                        foreground.  When _e_x_e_c___b_a_c_k_g_r_o_u_n_d is enabled and the
  441:                        command is being run in a pty (due to I/O logging or
  442:                        the _u_s_e___p_t_y setting), the command will be run as a
  443:                        background process.  Attempts to read from the
  444:                        controlling terminal (or to change terminal settings)
  445:                        will result in the command being suspended with the
  446:                        SIGTTIN signal (or SIGTTOU in the case of terminal
  447:                        settings).  If this happens when ssuuddoo is a foreground
  448:                        process, the command will be granted the controlling
  449:                        terminal and resumed in the foreground with no user
  450:                        intervention required.  The advantage of initially
  451:                        running the command in the background is that ssuuddoo need
  452:                        not read from the terminal unless the command
  453:                        explicitly requests it.  Otherwise, any terminal input
  454:                        must be passed to the command, whether it has required
  455:                        it or not (the kernel buffers terminals so it is not
  456:                        possible to tell whether the command really wants the
  457:                        input).  This is different from historic _s_u_d_o behavior
  458:                        or when the command is not being run in a pty.
  459: 
  460:                        For this to work seamlessly, the operating system must
  461:                        support the automatic restarting of system calls.
  462:                        Unfortunately, not all operating systems do this by
  463:                        default, and even those that do may have bugs.  For
  464:                        example, Mac OS X fails to restart the ttccggeettaattttrr() and
  465:                        ttccsseettaattttrr() system calls (this is a bug in Mac OS X).
  466:                        Furthermore, because this behavior depends on the
  467:                        command stopping with the SIGTTIN or SIGTTOU signals,
  468:                        programs that catch these signals and suspend
  469:                        themselves with a different signal (usually SIGTOP)
  470:                        will not be automatically foregrounded.  Some versions
  471:                        of the linux su(1) command behave this way.  Because of
  472:                        this, a plugin should not set _e_x_e_c___b_a_c_k_g_r_o_u_n_d unless it
  473:                        is explicitly enabled by the administrator and there
  474:                        should be a way to enabled or disable it on a per-
  475:                        command basis.
  476: 
  477:                        This setting has no effect unless I/O logging is
  478:                        enabled or _u_s_e___p_t_y is enabled.
  479: 
  480:                  iolog_compress=bool
  481:                        Set to true if the I/O logging plugins, if any, should
  482:                        compress the log data.  This is a hint to the I/O
  483:                        logging plugin which may choose to ignore it.
  484: 
  485:                  iolog_path=string
  486:                        Fully qualified path to the file or directory in which
  487:                        I/O log is to be stored.  This is a hint to the I/O
  488:                        logging plugin which may choose to ignore it.  If no
  489:                        I/O logging plugin is loaded, this setting has no
  490:                        effect.
  491: 
  492:                  iolog_stdin=bool
  493:                        Set to true if the I/O logging plugins, if any, should
  494:                        log the standard input if it is not connected to a
  495:                        terminal device.  This is a hint to the I/O logging
  496:                        plugin which may choose to ignore it.
  497: 
  498:                  iolog_stdout=bool
  499:                        Set to true if the I/O logging plugins, if any, should
  500:                        log the standard output if it is not connected to a
  501:                        terminal device.  This is a hint to the I/O logging
  502:                        plugin which may choose to ignore it.
  503: 
  504:                  iolog_stderr=bool
  505:                        Set to true if the I/O logging plugins, if any, should
  506:                        log the standard error if it is not connected to a
  507:                        terminal device.  This is a hint to the I/O logging
  508:                        plugin which may choose to ignore it.
  509: 
  510:                  iolog_ttyin=bool
  511:                        Set to true if the I/O logging plugins, if any, should
  512:                        log all terminal input.  This only includes input typed
  513:                        by the user and not from a pipe or redirected from a
  514:                        file.  This is a hint to the I/O logging plugin which
  515:                        may choose to ignore it.
  516: 
  517:                  iolog_ttyout=bool
  518:                        Set to true if the I/O logging plugins, if any, should
  519:                        log all terminal output.  This only includes output to
  520:                        the screen, not output to a pipe or file.  This is a
  521:                        hint to the I/O logging plugin which may choose to
  522:                        ignore it.
  523: 
  524:                  login_class=string
  525:                        BSD login class to use when setting resource limits and
  526:                        nice value (optional).  This option is only set on
  527:                        systems that support login classes.
  528: 
  529:                  nice=int
  530:                        Nice value (priority) to use when executing the
  531:                        command.  The nice value, if specified, overrides the
  532:                        priority associated with the _l_o_g_i_n___c_l_a_s_s on BSD
  533:                        systems.
  534: 
  535:                  noexec=bool
  536:                        If set, prevent the command from executing other
  537:                        programs.
  538: 
  539:                  preserve_groups=bool
  540:                        If set, ssuuddoo will preserve the user's group vector
  541:                        instead of initializing the group vector based on
  542:                        runas_user.
  543: 
  544:                  runas_egid=gid
  545:                        Effective group ID to run the command as.  If not
  546:                        specified, the value of _r_u_n_a_s___g_i_d is used.
  547: 
  548:                  runas_euid=uid
  549:                        Effective user ID to run the command as.  If not
  550:                        specified, the value of _r_u_n_a_s___u_i_d is used.
  551: 
  552:                  runas_gid=gid
  553:                        Group ID to run the command as.
  554: 
  555:                  runas_groups=list
  556:                        The supplementary group vector to use for the command
  557:                        in the form of a comma-separated list of group IDs.  If
  558:                        _p_r_e_s_e_r_v_e___g_r_o_u_p_s is set, this option is ignored.
  559: 
  560:                  runas_uid=uid
  561:                        User ID to run the command as.
  562: 
  563:                  selinux_role=string
  564:                        SELinux role to use when executing the command.
  565: 
  566:                  selinux_type=string
  567:                        SELinux type to use when executing the command.
  568: 
  569:                  set_utmp=bool
  570:                        Create a utmp (or utmpx) entry when a pseudo-tty is
  571:                        allocated.  By default, the new entry will be a copy of
  572:                        the user's existing utmp entry (if any), with the tty,
  573:                        time, type and pid fields updated.
  574: 
  575:                  sudoedit=bool
  576:                        Set to true when in _s_u_d_o_e_d_i_t mode.  The plugin may
  577:                        enable _s_u_d_o_e_d_i_t mode even if ssuuddoo was not invoked as
  578:                        ssuuddooeeddiitt.  This allows the plugin to perform command
  579:                        substitution and transparently enable _s_u_d_o_e_d_i_t when the
  580:                        user attempts to run an editor.
  581: 
  582:                  timeout=int
  583:                        Command timeout.  If non-zero then when the timeout
  584:                        expires the command will be killed.
  585: 
  586:                  umask=octal
  587:                        The file creation mask to use when executing the
  588:                        command.
  589: 
  590:                  use_pty=bool
  591:                        Allocate a pseudo-tty to run the command in, regardless
  592:                        of whether or not I/O logging is in use.  By default,
  593:                        ssuuddoo will only run the command in a pty when an I/O log
  594:                        plugin is loaded.
  595: 
  596:                  utmp_user=string
  597:                        User name to use when constructing a new utmp (or
  598:                        utmpx) entry when _s_e_t___u_t_m_p is enabled.  This option can
  599:                        be used to set the user field in the utmp entry to the
  600:                        user the command runs as rather than the invoking user.
  601:                        If not set, ssuuddoo will base the new entry on the
  602:                        invoking user's existing entry.
  603: 
  604:                  Unsupported values will be ignored.
  605: 
  606:            argv_out
  607:                  The NULL-terminated argument vector to pass to the execve(2)
  608:                  system call when executing the command.  The plugin is
  609:                  responsible for allocating and populating the vector.
  610: 
  611:            user_env_out
  612:                  The NULL-terminated environment vector to use when executing
  613:                  the command.  The plugin is responsible for allocating and
  614:                  populating the vector.
  615: 
  616:      list
  617:            int (*list)(int verbose, const char *list_user,
  618:                        int argc, char * const argv[]);
  619: 
  620:            List available privileges for the invoking user.  Returns 1 on
  621:            success, 0 on failure and -1 on error.  On error, the plugin may
  622:            optionally call the ccoonnvveerrssaattiioonn() or pplluuggiinn__pprriinnttff() function with
  623:            SUDO_CONF_ERROR_MSG to present additional error information to the
  624:            user.
  625: 
  626:            Privileges should be output via the ccoonnvveerrssaattiioonn() or
  627:            pplluuggiinn__pprriinnttff() function using SUDO_CONV_INFO_MSG,
  628: 
  629:            verbose
  630:                  Flag indicating whether to list in verbose mode or not.
  631: 
  632:            list_user
  633:                  The name of a different user to list privileges for if the
  634:                  policy allows it.  If NULL, the plugin should list the
  635:                  privileges of the invoking user.
  636: 
  637:            argc  The number of elements in _a_r_g_v, not counting the final NULL
  638:                  pointer.
  639: 
  640:            argv  If non-NULL, an argument vector describing a command the user
  641:                  wishes to check against the policy in the same form as what
  642:                  would be passed to the execve(2) system call.  If the command
  643:                  is permitted by the policy, the fully-qualified path to the
  644:                  command should be displayed along with any command line
  645:                  arguments.
  646: 
  647:      validate
  648:            int (*validate)(void);
  649: 
  650:            The vvaalliiddaattee() function is called when ssuuddoo is run with the --vv
  651:            flag.  For policy plugins such as ssuuddooeerrss that cache authentication
  652:            credentials, this function will validate and cache the credentials.
  653: 
  654:            The vvaalliiddaattee() function should be NULL if the plugin does not
  655:            support credential caching.
  656: 
  657:            Returns 1 on success, 0 on failure and -1 on error.  On error, the
  658:            plugin may optionally call the ccoonnvveerrssaattiioonn() or pplluuggiinn__pprriinnttff()
  659:            function with SUDO_CONF_ERROR_MSG to present additional error
  660:            information to the user.
  661: 
  662:      invalidate
  663:            void (*invalidate)(int remove);
  664: 
  665:            The iinnvvaalliiddaattee() function is called when ssuuddoo is called with the --kk
  666:            or --KK flag.  For policy plugins such as ssuuddooeerrss that cache
  667:            authentication credentials, this function will invalidate the
  668:            credentials.  If the _r_e_m_o_v_e flag is set, the plugin may remove the
  669:            credentials instead of simply invalidating them.
  670: 
  671:            The iinnvvaalliiddaattee() function should be NULL if the plugin does not
  672:            support credential caching.
  673: 
  674:      init_session
  675:            int (*init_session)(struct passwd *pwd, char **user_envp[);
  676: 
  677:            The iinniitt__sseessssiioonn() function is called before ssuuddoo sets up the
  678:            execution environment for the command.  It is run in the parent
  679:            ssuuddoo process and before any uid or gid changes.  This can be used
  680:            to perform session setup that is not supported by _c_o_m_m_a_n_d___i_n_f_o,
  681:            such as opening the PAM session.  The cclloossee() function can be used
  682:            to tear down the session that was opened by init_session.
  683: 
  684:            The _p_w_d argument points to a passwd struct for the user the command
  685:            will be run as if the uid the command will run as was found in the
  686:            password database, otherwise it will be NULL.
  687: 
  688:            The _u_s_e_r___e_n_v argument points to the environment the command will
  689:            run in, in the form of a NULL-terminated vector of ``name=value''
  690:            strings.  This is the same string passed back to the front end via
  691:            the Policy Plugin's _u_s_e_r___e_n_v___o_u_t parameter.  If the iinniitt__sseessssiioonn()
  692:            function needs to modify the user environment, it should update the
  693:            pointer stored in _u_s_e_r___e_n_v.  The expected use case is to merge the
  694:            contents of the PAM environment (if any) with the contents of
  695:            _u_s_e_r___e_n_v.  NOTE: the _u_s_e_r___e_n_v parameter is only available starting
  696:            with API version 1.2.  A plugin mmuusstt check the API version
  697:            specified by the ssuuddoo front end before using _u_s_e_r___e_n_v.  Failure to
  698:            do so may result in a crash.
  699: 
  700:            Returns 1 on success, 0 on failure and -1 on error.  On error, the
  701:            plugin may optionally call the ccoonnvveerrssaattiioonn() or pplluuggiinn__pprriinnttff()
  702:            function with SUDO_CONF_ERROR_MSG to present additional error
  703:            information to the user.
  704: 
  705:      register_hooks
  706:            void (*register_hooks)(int version,
  707:               int (*register_hook)(struct sudo_hook *hook));
  708: 
  709:            The rreeggiisstteerr__hhooookkss() function is called by the sudo front end to
  710:            register any hooks the plugin needs.  If the plugin does not
  711:            support hooks, register_hooks should be set to the NULL pointer.
  712: 
  713:            The _v_e_r_s_i_o_n argument describes the version of the hooks API
  714:            supported by the ssuuddoo front end.
  715: 
  716:            The rreeggiisstteerr__hhooookk() function should be used to register any
  717:            supported hooks the plugin needs.  It returns 0 on success, 1 if
  718:            the hook type is not supported and -1 if the major version in
  719:            struct hook does not match the front end's major hook API version.
  720: 
  721:            See the _H_o_o_k _f_u_n_c_t_i_o_n _A_P_I section below for more information about
  722:            hooks.
  723: 
  724:            NOTE: the rreeggiisstteerr__hhooookkss() function is only available starting with
  725:            API version 1.2.  If the ssuuddoo front end doesn't support API version
  726:            1.2 or higher, register_hooks will not be called.
  727: 
  728:      deregister_hooks
  729:            void (*deregister_hooks)(int version,
  730:               int (*deregister_hook)(struct sudo_hook *hook));
  731: 
  732:            The ddeerreeggiisstteerr__hhooookkss() function is called by the sudo front end to
  733:            deregister any hooks the plugin has registered.  If the plugin does
  734:            not support hooks, deregister_hooks should be set to the NULL
  735:            pointer.
  736: 
  737:            The _v_e_r_s_i_o_n argument describes the version of the hooks API
  738:            supported by the ssuuddoo front end.
  739: 
  740:            The ddeerreeggiisstteerr__hhooookk() function should be used to deregister any
  741:            hooks that were put in place by the rreeggiisstteerr__hhooookk() function.  If
  742:            the plugin tries to deregister a hook that the front end does not
  743:            support, deregister_hook will return an error.
  744: 
  745:            See the _H_o_o_k _f_u_n_c_t_i_o_n _A_P_I section below for more information about
  746:            hooks.
  747: 
  748:            NOTE: the ddeerreeggiisstteerr__hhooookkss() function is only available starting
  749:            with API version 1.2.  If the ssuuddoo front end doesn't support API
  750:            version 1.2 or higher, deregister_hooks will not be called.
  751: 
  752:      _P_o_l_i_c_y _P_l_u_g_i_n _V_e_r_s_i_o_n _M_a_c_r_o_s
  753: 
  754:      /* Plugin API version major/minor. */
  755:      #define SUDO_API_VERSION_MAJOR 1
  756:      #define SUDO_API_VERSION_MINOR 2
  757:      #define SUDO_API_MKVERSION(x, y) ((x << 16) | y)
  758:      #define SUDO_API_VERSION SUDO_API_MKVERSION(SUDO_API_VERSION_MAJOR,\
  759:                                                  SUDO_API_VERSION_MINOR)
  760: 
  761:      /* Getters and setters for API version */
  762:      #define SUDO_API_VERSION_GET_MAJOR(v) ((v) >> 16)
  763:      #define SUDO_API_VERSION_GET_MINOR(v) ((v) & 0xffff)
  764:      #define SUDO_API_VERSION_SET_MAJOR(vp, n) do { \
  765:          *(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \
  766:      } while(0)
  767:      #define SUDO_VERSION_SET_MINOR(vp, n) do { \
  768:          *(vp) = (*(vp) & 0xffff0000) | (n); \
  769:      } while(0)
  770: 
  771:    II//OO pplluuggiinn AAPPII
  772:      struct io_plugin {
  773:      #define SUDO_IO_PLUGIN 2
  774:          unsigned int type; /* always SUDO_IO_PLUGIN */
  775:          unsigned int version; /* always SUDO_API_VERSION */
  776:          int (*open)(unsigned int version, sudo_conv_t conversation,
  777:                      sudo_printf_t plugin_printf, char * const settings[],
  778:                      char * const user_info[], char * const command_info[],
  779:                      int argc, char * const argv[], char * const user_env[],
  780:                      char * const plugin_options[]);
  781:          void (*close)(int exit_status, int error); /* wait status or error */
  782:          int (*show_version)(int verbose);
  783:          int (*log_ttyin)(const char *buf, unsigned int len);
  784:          int (*log_ttyout)(const char *buf, unsigned int len);
  785:          int (*log_stdin)(const char *buf, unsigned int len);
  786:          int (*log_stdout)(const char *buf, unsigned int len);
  787:          int (*log_stderr)(const char *buf, unsigned int len);
  788:          void (*register_hooks)(int version,
  789:             int (*register_hook)(struct sudo_hook *hook));
  790:          void (*deregister_hooks)(int version,
  791:             int (*deregister_hook)(struct sudo_hook *hook));
  792:      };
  793: 
  794:      When an I/O plugin is loaded, ssuuddoo runs the command in a pseudo-tty.
  795:      This makes it possible to log the input and output from the user's
  796:      session.  If any of the standard input, standard output or standard error
  797:      do not correspond to a tty, ssuuddoo will open a pipe to capture the I/O for
  798:      logging before passing it on.
  799: 
  800:      The log_ttyin function receives the raw user input from the terminal
  801:      device (note that this will include input even when echo is disabled,
  802:      such as when a password is read).  The log_ttyout function receives
  803:      output from the pseudo-tty that is suitable for replaying the user's
  804:      session at a later time.  The lloogg__ssttddiinn(), lloogg__ssttddoouutt() and lloogg__ssttddeerrrr()
  805:      functions are only called if the standard input, standard output or
  806:      standard error respectively correspond to something other than a tty.
  807: 
  808:      Any of the logging functions may be set to the NULL pointer if no logging
  809:      is to be performed.  If the open function returns 0, no I/O will be sent
  810:      to the plugin.
  811: 
  812:      The io_plugin struct has the following fields:
  813: 
  814:      type  The type field should always be set to SUDO_IO_PLUGIN.
  815: 
  816:      version
  817:            The version field should be set to SUDO_API_VERSION.
  818: 
  819:            This allows ssuuddoo to determine the API version the plugin was built
  820:            against.
  821: 
  822:      open
  823:            int (*open)(unsigned int version, sudo_conv_t conversation,
  824:                        sudo_printf_t plugin_printf, char * const settings[],
  825:                        char * const user_info[], int argc, char * const argv[],
  826:                        char * const user_env[], char * const plugin_options[]);
  827: 
  828:            The ooppeenn() function is run before the lloogg__iinnppuutt(), lloogg__oouuttppuutt() or
  829:            sshhooww__vveerrssiioonn() functions are called.  It is only called if the
  830:            version is being requested or the cchheecckk__ppoolliiccyy() function has
  831:            returned successfully.  It returns 1 on success, 0 on failure, -1
  832:            if a general error occurred, or -2 if there was a usage error.  In
  833:            the latter case, ssuuddoo will print a usage message before it exits.
  834:            If an error occurs, the plugin may optionally call the
  835:            ccoonnvveerrssaattiioonn() or pplluuggiinn__pprriinnttff() function with SUDO_CONF_ERROR_MSG
  836:            to present additional error information to the user.
  837: 
  838:            The function arguments are as follows:
  839: 
  840:            version
  841:                  The version passed in by ssuuddoo allows the plugin to determine
  842:                  the major and minor version number of the plugin API
  843:                  supported by ssuuddoo.
  844: 
  845:            conversation
  846:                  A pointer to the ccoonnvveerrssaattiioonn() function that may be used by
  847:                  the sshhooww__vveerrssiioonn() function to display version information
  848:                  (see sshhooww__vveerrssiioonn() below).  The ccoonnvveerrssaattiioonn() function may
  849:                  also be used to display additional error message to the user.
  850:                  The ccoonnvveerrssaattiioonn() function returns 0 on success and -1 on
  851:                  failure.
  852: 
  853:            plugin_printf
  854:                  A pointer to a pprriinnttff()-style function that may be used by
  855:                  the sshhooww__vveerrssiioonn() function to display version information
  856:                  (see show_version below).  The pplluuggiinn__pprriinnttff() function may
  857:                  also be used to display additional error message to the user.
  858:                  The pplluuggiinn__pprriinnttff() function returns number of characters
  859:                  printed on success and -1 on failure.
  860: 
  861:            settings
  862:                  A vector of user-supplied ssuuddoo settings in the form of
  863:                  ``name=value'' strings.  The vector is terminated by a NULL
  864:                  pointer.  These settings correspond to flags the user
  865:                  specified when running ssuuddoo.  As such, they will only be
  866:                  present when the corresponding flag has been specified on the
  867:                  command line.
  868: 
  869:                  When parsing _s_e_t_t_i_n_g_s, the plugin should split on the ffiirrsstt
  870:                  equal sign (`=') since the _n_a_m_e field will never include one
  871:                  itself but the _v_a_l_u_e might.
  872: 
  873:                  See the _P_o_l_i_c_y _p_l_u_g_i_n _A_P_I section for a list of all possible
  874:                  settings.
  875: 
  876:            user_info
  877:                  A vector of information about the user running the command in
  878:                  the form of ``name=value'' strings.  The vector is terminated
  879:                  by a NULL pointer.
  880: 
  881:                  When parsing _u_s_e_r___i_n_f_o, the plugin should split on the ffiirrsstt
  882:                  equal sign (`=') since the _n_a_m_e field will never include one
  883:                  itself but the _v_a_l_u_e might.
  884: 
  885:                  See the _P_o_l_i_c_y _p_l_u_g_i_n _A_P_I section for a list of all possible
  886:                  strings.
  887: 
  888:            argc  The number of elements in _a_r_g_v, not counting the final NULL
  889:                  pointer.
  890: 
  891:            argv  If non-NULL, an argument vector describing a command the user
  892:                  wishes to run in the same form as what would be passed to the
  893:                  execve(2) system call.
  894: 
  895:            user_env
  896:                  The user's environment in the form of a NULL-terminated
  897:                  vector of ``name=value'' strings.
  898: 
  899:                  When parsing _u_s_e_r___e_n_v, the plugin should split on the ffiirrsstt
  900:                  equal sign (`=') since the _n_a_m_e field will never include one
  901:                  itself but the _v_a_l_u_e might.
  902: 
  903:            plugin_options
  904:                  Any (non-comment) strings immediately after the plugin path
  905:                  are treated as arguments to the plugin.  These arguments are
  906:                  split on a white space boundary and are passed to the plugin
  907:                  in the form of a NULL-terminated array of strings.  If no
  908:                  arguments were specified, _p_l_u_g_i_n___o_p_t_i_o_n_s will be the NULL
  909:                  pointer.
  910: 
  911:                  NOTE: the _p_l_u_g_i_n___o_p_t_i_o_n_s parameter is only available starting
  912:                  with API version 1.2.  A plugin mmuusstt check the API version
  913:                  specified by the ssuuddoo front end before using _p_l_u_g_i_n___o_p_t_i_o_n_s.
  914:                  Failure to do so may result in a crash.
  915: 
  916:      close
  917:            void (*close)(int exit_status, int error);
  918: 
  919:            The cclloossee() function is called when the command being run by ssuuddoo
  920:            finishes.
  921: 
  922:            The function arguments are as follows:
  923: 
  924:            exit_status
  925:                  The command's exit status, as returned by the wait(2) system
  926:                  call.  The value of exit_status is undefined if error is non-
  927:                  zero.
  928: 
  929:            error
  930:                  If the command could not be executed, this is set to the
  931:                  value of errno set by the execve(2) system call.  If the
  932:                  command was successfully executed, the value of error is 0.
  933: 
  934:      show_version
  935:            int (*show_version)(int verbose);
  936: 
  937:            The sshhooww__vveerrssiioonn() function is called by ssuuddoo when the user
  938:            specifies the --VV option.  The plugin may display its version
  939:            information to the user via the ccoonnvveerrssaattiioonn() or pplluuggiinn__pprriinnttff()
  940:            function using SUDO_CONV_INFO_MSG.  If the user requests detailed
  941:            version information, the verbose flag will be set.
  942: 
  943:      log_ttyin
  944:            int (*log_ttyin)(const char *buf, unsigned int len);
  945: 
  946:            The lloogg__ttttyyiinn() function is called whenever data can be read from
  947:            the user but before it is passed to the running command.  This
  948:            allows the plugin to reject data if it chooses to (for instance if
  949:            the input contains banned content).  Returns 1 if the data should
  950:            be passed to the command, 0 if the data is rejected (which will
  951:            terminate the command) or -1 if an error occurred.
  952: 
  953:            The function arguments are as follows:
  954: 
  955:            buf   The buffer containing user input.
  956: 
  957:            len   The length of _b_u_f in bytes.
  958: 
  959:      log_ttyout
  960:            int (*log_ttyout)(const char *buf, unsigned int len);
  961: 
  962:            The lloogg__ttttyyoouutt() function is called whenever data can be read from
  963:            the command but before it is written to the user's terminal.  This
  964:            allows the plugin to reject data if it chooses to (for instance if
  965:            the output contains banned content).  Returns 1 if the data should
  966:            be passed to the user, 0 if the data is rejected (which will
  967:            terminate the command) or -1 if an error occurred.
  968: 
  969:            The function arguments are as follows:
  970: 
  971:            buf   The buffer containing command output.
  972: 
  973:            len   The length of _b_u_f in bytes.
  974: 
  975:      log_stdin
  976:            int (*log_stdin)(const char *buf, unsigned int len);
  977: 
  978:            The lloogg__ssttddiinn() function is only used if the standard input does
  979:            not correspond to a tty device.  It is called whenever data can be
  980:            read from the standard input but before it is passed to the running
  981:            command.  This allows the plugin to reject data if it chooses to
  982:            (for instance if the input contains banned content).  Returns 1 if
  983:            the data should be passed to the command, 0 if the data is rejected
  984:            (which will terminate the command) or -1 if an error occurred.
  985: 
  986:            The function arguments are as follows:
  987: 
  988:            buf   The buffer containing user input.
  989: 
  990:            len   The length of _b_u_f in bytes.
  991: 
  992:      log_stdout
  993:            int (*log_stdout)(const char *buf, unsigned int len);
  994: 
  995:            The lloogg__ssttddoouutt() function is only used if the standard output does
  996:            not correspond to a tty device.  It is called whenever data can be
  997:            read from the command but before it is written to the standard
  998:            output.  This allows the plugin to reject data if it chooses to
  999:            (for instance if the output contains banned content).  Returns 1 if
 1000:            the data should be passed to the user, 0 if the data is rejected
 1001:            (which will terminate the command) or -1 if an error occurred.
 1002: 
 1003:            The function arguments are as follows:
 1004: 
 1005:            buf   The buffer containing command output.
 1006: 
 1007:            len   The length of _b_u_f in bytes.
 1008: 
 1009:      log_stderr
 1010:            int (*log_stderr)(const char *buf, unsigned int len);
 1011: 
 1012:            The lloogg__ssttddeerrrr() function is only used if the standard error does
 1013:            not correspond to a tty device.  It is called whenever data can be
 1014:            read from the command but before it is written to the standard
 1015:            error.  This allows the plugin to reject data if it chooses to (for
 1016:            instance if the output contains banned content).  Returns 1 if the
 1017:            data should be passed to the user, 0 if the data is rejected (which
 1018:            will terminate the command) or -1 if an error occurred.
 1019: 
 1020:            The function arguments are as follows:
 1021: 
 1022:            buf   The buffer containing command output.
 1023: 
 1024:            len   The length of _b_u_f in bytes.
 1025: 
 1026:      register_hooks
 1027:            See the _P_o_l_i_c_y _p_l_u_g_i_n _A_P_I section for a description of
 1028:            register_hooks.
 1029: 
 1030:      deregister_hooks
 1031:            See the _P_o_l_i_c_y _p_l_u_g_i_n _A_P_I section for a description of
 1032:            deregister_hooks.
 1033: 
 1034:      _I_/_O _P_l_u_g_i_n _V_e_r_s_i_o_n _M_a_c_r_o_s
 1035: 
 1036:      Same as for the _P_o_l_i_c_y _p_l_u_g_i_n _A_P_I.
 1037: 
 1038:    SSiiggnnaall hhaannddlleerrss
 1039:      The ssuuddoo front end installs default signal handlers to trap common
 1040:      signals while the plugin functions are run.  The following signals are
 1041:      trapped by default before the command is executed:
 1042: 
 1043:      oo   SIGALRM
 1044:      oo   SIGHUP
 1045:      oo   SIGINT
 1046:      oo   SIGQUIT
 1047:      oo   SIGTERM
 1048:      oo   SIGTSTP
 1049:      oo   SIGUSR1
 1050:      oo   SIGUSR2
 1051: 
 1052:      If a fatal signal is received before the command is executed, ssuuddoo will
 1053:      call the plugin's cclloossee() function with an exit status of 128 plus the
 1054:      value of the signal that was received.  This allows for consistent
 1055:      logging of commands killed by a signal for plugins that log such
 1056:      information in their cclloossee() function.
 1057: 
 1058:      A plugin may temporarily install its own signal handlers but must restore
 1059:      the original handler before the plugin function returns.
 1060: 
 1061:    HHooookk ffuunnccttiioonn AAPPII
 1062:      Beginning with plugin API version 1.2, it is possible to install hooks
 1063:      for certain functions called by the ssuuddoo front end.
 1064: 
 1065:      Currently, the only supported hooks relate to the handling of environment
 1066:      variables.  Hooks can be used to intercept attempts to get, set, or
 1067:      remove environment variables so that these changes can be reflected in
 1068:      the version of the environment that is used to execute a command.  A
 1069:      future version of the API will support hooking internal ssuuddoo front end
 1070:      functions as well.
 1071: 
 1072:      _H_o_o_k _s_t_r_u_c_t_u_r_e
 1073: 
 1074:      Hooks in ssuuddoo are described by the following structure:
 1075: 
 1076:      typedef int (*sudo_hook_fn_t)();
 1077: 
 1078:      struct sudo_hook {
 1079:          int hook_version;
 1080:          int hook_type;
 1081:          sudo_hook_fn_t hook_fn;
 1082:          void *closure;
 1083:      };
 1084: 
 1085:      The sudo_hook structure has the following fields:
 1086: 
 1087:      hook_version
 1088:            The hook_version field should be set to SUDO_HOOK_VERSION.
 1089: 
 1090:      hook_type
 1091:            The hook_type field may be one of the following supported hook
 1092:            types:
 1093: 
 1094:            SUDO_HOOK_SETENV
 1095:                  The C library setenv(3) function.  Any registered hooks will
 1096:                  run before the C library implementation.  The hook_fn field
 1097:                  should be a function that matches the following typedef:
 1098: 
 1099:                  typedef int (*sudo_hook_fn_setenv_t)(const char *name,
 1100:                     const char *value, int overwrite, void *closure);
 1101: 
 1102:                  If the registered hook does not match the typedef the results
 1103:                  are unspecified.
 1104: 
 1105:            SUDO_HOOK_UNSETENV
 1106:                  The C library unsetenv(3) function.  Any registered hooks
 1107:                  will run before the C library implementation.  The hook_fn
 1108:                  field should be a function that matches the following
 1109:                  typedef:
 1110: 
 1111:                  typedef int (*sudo_hook_fn_unsetenv_t)(const char *name,
 1112:                     void *closure);
 1113: 
 1114:            SUDO_HOOK_GETENV
 1115:                  The C library getenv(3) function.  Any registered hooks will
 1116:                  run before the C library implementation.  The hook_fn field
 1117:                  should be a function that matches the following typedef:
 1118: 
 1119:                  typedef int (*sudo_hook_fn_getenv_t)(const char *name,
 1120:                     char **value, void *closure);
 1121: 
 1122:                  If the registered hook does not match the typedef the results
 1123:                  are unspecified.
 1124: 
 1125:            SUDO_HOOK_PUTENV
 1126:                  The C library putenv(3) function.  Any registered hooks will
 1127:                  run before the C library implementation.  The hook_fn field
 1128:                  should be a function that matches the following typedef:
 1129: 
 1130:                  typedef int (*sudo_hook_fn_putenv_t)(char *string,
 1131:                     void *closure);
 1132: 
 1133:                  If the registered hook does not match the typedef the results
 1134:                  are unspecified.
 1135: 
 1136:      hook_fn
 1137:            sudo_hook_fn_t hook_fn;
 1138: 
 1139:            The hook_fn field should be set to the plugin's hook
 1140:            implementation.  The actual function arguments will vary depending
 1141:            on the hook_type (see hook_type above).  In all cases, the closure
 1142:            field of struct sudo_hook is passed as the last function parameter.
 1143:            This can be used to pass arbitrary data to the plugin's hook
 1144:            implementation.
 1145: 
 1146:            The function return value may be one of the following:
 1147: 
 1148:            SUDO_HOOK_RET_ERROR
 1149:                  The hook function encountered an error.
 1150: 
 1151:            SUDO_HOOK_RET_NEXT
 1152:                  The hook completed without error, go on to the next hook
 1153:                  (including the native implementation if applicable).  For
 1154:                  example, a getenv(3) hook might return SUDO_HOOK_RET_NEXT if
 1155:                  the specified variable was not found in the private copy of
 1156:                  the environment.
 1157: 
 1158:            SUDO_HOOK_RET_STOP
 1159:                  The hook completed without error, stop processing hooks for
 1160:                  this invocation.  This can be used to replace the native
 1161:                  implementation.  For example, a setenv hook that operates on
 1162:                  a private copy of the environment but leaves environ
 1163:                  unchanged.
 1164: 
 1165:      Note that it is very easy to create an infinite loop when hooking C
 1166:      library functions.  For example, a getenv(3) hook that calls the
 1167:      snprintf(3) function may create a loop if the snprintf(3) implementation
 1168:      calls getenv(3) to check the locale.  To prevent this, you may wish to
 1169:      use a static variable in the hook function to guard against nested calls.
 1170:      For example:
 1171: 
 1172:      static int in_progress = 0; /* avoid recursion */
 1173:      if (in_progress)
 1174:          return SUDO_HOOK_RET_NEXT;
 1175:      in_progress = 1;
 1176:      ...
 1177:      in_progress = 0;
 1178:      return SUDO_HOOK_RET_STOP;
 1179: 
 1180:      _H_o_o_k _A_P_I _V_e_r_s_i_o_n _M_a_c_r_o_s
 1181: 
 1182:      /* Hook API version major/minor */
 1183:      #define SUDO_HOOK_VERSION_MAJOR 1
 1184:      #define SUDO_HOOK_VERSION_MINOR 0
 1185:      #define SUDO_HOOK_MKVERSION(x, y) ((x << 16) | y)
 1186:      #define SUDO_HOOK_VERSION SUDO_HOOK_MKVERSION(SUDO_HOOK_VERSION_MAJOR,\
 1187:                                                    SUDO_HOOK_VERSION_MINOR)
 1188: 
 1189:      /* Getters and setters for hook API version */
 1190:      #define SUDO_HOOK_VERSION_GET_MAJOR(v) ((v) >> 16)
 1191:      #define SUDO_HOOK_VERSION_GET_MINOR(v) ((v) & 0xffff)
 1192:      #define SUDO_HOOK_VERSION_SET_MAJOR(vp, n) do { \
 1193:          *(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \
 1194:      } while(0)
 1195:      #define SUDO_HOOK_VERSION_SET_MINOR(vp, n) do { \
 1196:          *(vp) = (*(vp) & 0xffff0000) | (n); \
 1197:      } while(0)
 1198: 
 1199:    CCoonnvveerrssaattiioonn AAPPII
 1200:      If the plugin needs to interact with the user, it may do so via the
 1201:      ccoonnvveerrssaattiioonn() function.  A plugin should not attempt to read directly
 1202:      from the standard input or the user's tty (neither of which are
 1203:      guaranteed to exist).  The caller must include a trailing newline in msg
 1204:      if one is to be printed.
 1205: 
 1206:      A pprriinnttff()-style function is also available that can be used to display
 1207:      informational or error messages to the user, which is usually more
 1208:      convenient for simple messages where no use input is required.
 1209: 
 1210:      struct sudo_conv_message {
 1211:      #define SUDO_CONV_PROMPT_ECHO_OFF  0x0001 /* do not echo user input */
 1212:      #define SUDO_CONV_PROMPT_ECHO_ON   0x0002 /* echo user input */
 1213:      #define SUDO_CONV_ERROR_MSG        0x0003 /* error message */
 1214:      #define SUDO_CONV_INFO_MSG         0x0004 /* informational message */
 1215:      #define SUDO_CONV_PROMPT_MASK      0x0005 /* mask user input */
 1216:      #define SUDO_CONV_DEBUG_MSG        0x0006 /* debugging message */
 1217:      #define SUDO_CONV_PROMPT_ECHO_OK   0x1000 /* flag: allow echo if no tty */
 1218:          int msg_type;
 1219:          int timeout;
 1220:          const char *msg;
 1221:      };
 1222: 
 1223:      struct sudo_conv_reply {
 1224:          char *reply;
 1225:      };
 1226: 
 1227:      typedef int (*sudo_conv_t)(int num_msgs,
 1228:                   const struct sudo_conv_message msgs[],
 1229:                   struct sudo_conv_reply replies[]);
 1230: 
 1231:      typedef int (*sudo_printf_t)(int msg_type, const char *fmt, ...);
 1232: 
 1233:      Pointers to the ccoonnvveerrssaattiioonn() and pprriinnttff()-style functions are passed in
 1234:      to the plugin's ooppeenn() function when the plugin is initialized.
 1235: 
 1236:      To use the ccoonnvveerrssaattiioonn() function, the plugin must pass an array of
 1237:      sudo_conv_message and sudo_conv_reply structures.  There must be a struct
 1238:      sudo_conv_message and struct sudo_conv_reply for each message in the
 1239:      conversation.  The plugin is responsible for freeing the reply buffer
 1240:      filled in to the struct sudo_conv_reply, if any.
 1241: 
 1242:      The pprriinnttff()-style function uses the same underlying mechanism as the
 1243:      ccoonnvveerrssaattiioonn() function but only supports SUDO_CONV_INFO_MSG,
 1244:      SUDO_CONV_ERROR_MSG and SUDO_CONV_DEBUG_MSG for the _m_s_g___t_y_p_e parameter.
 1245:      It can be more convenient than using the ccoonnvveerrssaattiioonn() function if no
 1246:      user reply is needed and supports standard pprriinnttff() escape sequences.
 1247: 
 1248:      Unlike, SUDO_CONV_INFO_MSG and Dv SUDO_CONV_ERROR_MSG , messages sent
 1249:      with the SUDO_CONV_DEBUG_MSG _m_s_g___t_y_p_e are not directly user-visible.
 1250:      Instead, they are logged to the file specified in the Debug statement (if
 1251:      any) in the sudo.conf(4).  file.  This allows a plugin to log debugging
 1252:      information and is intended to be used in conjunction with the
 1253:      _d_e_b_u_g___f_l_a_g_s setting.
 1254: 
 1255:      See the sample plugin for an example of the ccoonnvveerrssaattiioonn() function
 1256:      usage.
 1257: 
 1258:    SSuuddooeerrss ggrroouupp pplluuggiinn AAPPII
 1259:      The ssuuddooeerrss plugin supports its own plugin interface to allow non-Unix
 1260:      group lookups.  This can be used to query a group source other than the
 1261:      standard Unix group database.  Two sample group plugins are bundled with
 1262:      ssuuddoo, _g_r_o_u_p___f_i_l_e and _s_y_s_t_e_m___g_r_o_u_p, are detailed in sudoers(4).  Third
 1263:      party group plugins include a QAS AD plugin available from Quest
 1264:      Software.
 1265: 
 1266:      A group plugin must declare and populate a sudoers_group_plugin struct in
 1267:      the global scope.  This structure contains pointers to the functions that
 1268:      implement plugin initialization, cleanup and group lookup.
 1269: 
 1270:      struct sudoers_group_plugin {
 1271:         unsigned int version;
 1272:         int (*init)(int version, sudo_printf_t sudo_printf,
 1273:                     char *const argv[]);
 1274:         void (*cleanup)(void);
 1275:         int (*query)(const char *user, const char *group,
 1276:                      const struct passwd *pwd);
 1277:      };
 1278: 
 1279:      The sudoers_group_plugin struct has the following fields:
 1280: 
 1281:      version
 1282:            The version field should be set to GROUP_API_VERSION.
 1283: 
 1284:            This allows ssuuddooeerrss to determine the API version the group plugin
 1285:            was built against.
 1286: 
 1287:      init
 1288:            int (*init)(int version, sudo_printf_t plugin_printf,
 1289:                        char *const argv[]);
 1290: 
 1291:            The iinniitt() function is called after _s_u_d_o_e_r_s has been parsed but
 1292:            before any policy checks.  It returns 1 on success, 0 on failure
 1293:            (or if the plugin is not configured), and -1 if a error occurred.
 1294:            If an error occurs, the plugin may call the pplluuggiinn__pprriinnttff()
 1295:            function with SUDO_CONF_ERROR_MSG to present additional error
 1296:            information to the user.
 1297: 
 1298:            The function arguments are as follows:
 1299: 
 1300:            version
 1301:                  The version passed in by ssuuddooeerrss allows the plugin to
 1302:                  determine the major and minor version number of the group
 1303:                  plugin API supported by ssuuddooeerrss.
 1304: 
 1305:            plugin_printf
 1306:                  A pointer to a pprriinnttff()-style function that may be used to
 1307:                  display informational or error message to the user.  Returns
 1308:                  the number of characters printed on success and -1 on
 1309:                  failure.
 1310: 
 1311:            argv  A NULL-terminated array of arguments generated from the
 1312:                  _g_r_o_u_p___p_l_u_g_i_n option in _s_u_d_o_e_r_s.  If no arguments were given,
 1313:                  _a_r_g_v will be NULL.
 1314: 
 1315:      cleanup
 1316:            void (*cleanup)();
 1317: 
 1318:            The cclleeaannuupp() function is called when ssuuddooeerrss has finished its
 1319:            group checks.  The plugin should free any memory it has allocated
 1320:            and close open file handles.
 1321: 
 1322:      query
 1323:            int (*query)(const char *user, const char *group,
 1324:                         const struct passwd *pwd);
 1325: 
 1326:            The qquueerryy() function is used to ask the group plugin whether _u_s_e_r
 1327:            is a member of _g_r_o_u_p.
 1328: 
 1329:            The function arguments are as follows:
 1330: 
 1331:            user  The name of the user being looked up in the external group
 1332:                  database.
 1333: 
 1334:            group
 1335:                  The name of the group being queried.
 1336: 
 1337:            pwd   The password database entry for _u_s_e_r, if any.  If _u_s_e_r is not
 1338:                  present in the password database, _p_w_d will be NULL.
 1339: 
 1340:      _G_r_o_u_p _A_P_I _V_e_r_s_i_o_n _M_a_c_r_o_s
 1341: 
 1342:      /* Sudoers group plugin version major/minor */
 1343:      #define GROUP_API_VERSION_MAJOR 1
 1344:      #define GROUP_API_VERSION_MINOR 0
 1345:      #define GROUP_API_VERSION ((GROUP_API_VERSION_MAJOR << 16) | \
 1346:                                 GROUP_API_VERSION_MINOR)
 1347: 
 1348:      /* Getters and setters for group version */
 1349:      #define GROUP_API_VERSION_GET_MAJOR(v) ((v) >> 16)
 1350:      #define GROUP_API_VERSION_GET_MINOR(v) ((v) & 0xffff)
 1351:      #define GROUP_API_VERSION_SET_MAJOR(vp, n) do { \
 1352:          *(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \
 1353:      } while(0)
 1354:      #define GROUP_API_VERSION_SET_MINOR(vp, n) do { \
 1355:          *(vp) = (*(vp) & 0xffff0000) | (n); \
 1356:      } while(0)
 1357: 
 1358: PPLLUUGGIINN AAPPII CCHHAANNGGEELLOOGG
 1359:      The following revisions have been made to the Sudo Plugin API.
 1360: 
 1361:      Version 1.0
 1362:            Initial API version.
 1363: 
 1364:      Version 1.1 (sudo 1.8.0)
 1365:            The I/O logging plugin's ooppeenn() function was modified to take the
 1366:            command_info list as an argument.
 1367: 
 1368:      Version 1.2 (sudo 1.8.5)
 1369:            The Policy and I/O logging plugins' ooppeenn() functions are now passed
 1370:            a list of plugin parameters if any are specified in sudo.conf(4).
 1371: 
 1372:            A simple hooks API has been introduced to allow plugins to hook in
 1373:            to the system's environment handling functions.
 1374: 
 1375:            The init_session Policy plugin function is now passed a pointer to
 1376:            the user environment which can be updated as needed.  This can be
 1377:            used to merge in environment variables stored in the PAM handle
 1378:            before a command is run.
 1379: 
 1380:      Version 1.3 (sudo 1.8.7)
 1381:            Support for the _e_x_e_c___b_a_c_k_g_r_o_u_n_d entry has been added to the
 1382:            command_info list.
 1383: 
 1384:            The _m_a_x___g_r_o_u_p_s and _p_l_u_g_i_n___d_i_r entries were added to the settings
 1385:            list.
 1386: 
 1387:            The vveerrssiioonn() and cclloossee() functions are now optional.  Previously,
 1388:            a missing vveerrssiioonn() or cclloossee() function would result in a crash.
 1389:            If no policy plugin cclloossee() function is defined, a default cclloossee()
 1390:            function will be provided by the ssuuddoo front end that displays a
 1391:            warning if the command could not be executed.
 1392: 
 1393:            The ssuuddoo front end now installs default signal handlers to trap
 1394:            common signals while the plugin functions are run.
 1395: 
 1396: SSEEEE AALLSSOO
 1397:      sudo.conf(4), sudoers(4), sudo(1m)
 1398: 
 1399: BBUUGGSS
 1400:      If you feel you have found a bug in ssuuddoo, please submit a bug report at
 1401:      http://www.sudo.ws/sudo/bugs/
 1402: 
 1403: SSUUPPPPOORRTT
 1404:      Limited free support is available via the sudo-users mailing list, see
 1405:      http://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or search the
 1406:      archives.
 1407: 
 1408: DDIISSCCLLAAIIMMEERR
 1409:      ssuuddoo is provided ``AS IS'' and any express or implied warranties,
 1410:      including, but not limited to, the implied warranties of merchantability
 1411:      and fitness for a particular purpose are disclaimed.  See the LICENSE
 1412:      file distributed with ssuuddoo or http://www.sudo.ws/sudo/license.html for
 1413:      complete details.
 1414: 
 1415: Sudo 1.8.7                       March 5, 2013                      Sudo 1.8.7

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