Annotation of embedaddon/sudo/doc/sudo_plugin.cat, revision 1.1

1.1     ! misho       1: SUDO_PLUGIN(1m)              MAINTENANCE COMMANDS              SUDO_PLUGIN(1m)
        !             2: 
        !             3: 
        !             4: 
        !             5: NNAAMMEE
        !             6:        sudo_plugin - Sudo Plugin API
        !             7: 
        !             8: DDEESSCCRRIIPPTTIIOONN
        !             9:        Starting with version 1.8, ssuuddoo supports a plugin API for policy and
        !            10:        session logging.  By default, the _s_u_d_o_e_r_s policy plugin and an
        !            11:        associated I/O logging plugin are used.  Via the plugin API, ssuuddoo can
        !            12:        be configured to use alternate policy and/or I/O logging plugins
        !            13:        provided by third parties.  The plugins to be used are specified via
        !            14:        the _/_e_t_c_/_s_u_d_o_._c_o_n_f file.
        !            15: 
        !            16:        The API is versioned with a major and minor number.  The minor version
        !            17:        number is incremented when additions are made.  The major number is
        !            18:        incremented when incompatible changes are made.  A plugin should be
        !            19:        check the version passed to it and make sure that the major version
        !            20:        matches.
        !            21: 
        !            22:        The plugin API is defined by the sudo_plugin.h header file.
        !            23: 
        !            24:    TThhee ssuuddoo..ccoonnff FFiillee
        !            25:        The _/_e_t_c_/_s_u_d_o_._c_o_n_f file contains plugin configuration directives.
        !            26:        Currently, the only supported keyword is the Plugin directive, which
        !            27:        causes a plugin plugin to be loaded.
        !            28: 
        !            29:        A Plugin line consists of the Plugin keyword, followed by the
        !            30:        _s_y_m_b_o_l___n_a_m_e and the _p_a_t_h to the shared object containing the plugin.
        !            31:        The _s_y_m_b_o_l___n_a_m_e is the name of the struct policy_plugin or struct
        !            32:        io_plugin in the plugin shared object.  The _p_a_t_h may be fully qualified
        !            33:        or relative.  If not fully qualified it is relative to the
        !            34:        _/_u_s_r_/_l_o_c_a_l_/_l_i_b_e_x_e_c directory.  Any additional parameters after the _p_a_t_h
        !            35:        are ignored.  Lines that don't begin with Plugin or Path are silently
        !            36:        ignored.
        !            37: 
        !            38:        The same shared object may contain multiple plugins, each with a
        !            39:        different symbol name.  The shared object file must be owned by uid 0
        !            40:        and only writable by its owner.  Because of ambiguities that arise from
        !            41:        composite policies, only a single policy plugin may be specified.  This
        !            42:        limitation does not apply to I/O plugins.
        !            43: 
        !            44:         #
        !            45:         # Default /etc/sudo.conf file
        !            46:         #
        !            47:         # Format:
        !            48:         #   Plugin plugin_name plugin_path
        !            49:         #   Path askpass /path/to/askpass
        !            50:         #
        !            51:         # The plugin_path is relative to /usr/local/libexec unless
        !            52:         #   fully qualified.
        !            53:         # The plugin_name corresponds to a global symbol in the plugin
        !            54:         #   that contains the plugin interface structure.
        !            55:         #
        !            56:         Plugin sudoers_policy sudoers.so
        !            57:         Plugin sudoers_io sudoers.so
        !            58: 
        !            59:    PPoolliiccyy PPlluuggiinn AAPPII
        !            60:        A policy plugin must declare and populate a policy_plugin struct in the
        !            61:        global scope.  This structure contains pointers to the functions that
        !            62:        implement the ssuuddoo policy checks.  The name of the symbol should be
        !            63:        specified in _/_e_t_c_/_s_u_d_o_._c_o_n_f along with a path to the plugin so that
        !            64:        ssuuddoo can load it.
        !            65: 
        !            66:         struct policy_plugin {
        !            67:         #define SUDO_POLICY_PLUGIN     1
        !            68:             unsigned int type; /* always SUDO_POLICY_PLUGIN */
        !            69:             unsigned int version; /* always SUDO_API_VERSION */
        !            70:             int (*open)(unsigned int version, sudo_conv_t conversation,
        !            71:                         sudo_printf_t plugin_printf, char * const settings[],
        !            72:                         char * const user_info[], char * const user_env[]);
        !            73:             void (*close)(int exit_status, int error);
        !            74:             int (*show_version)(int verbose);
        !            75:             int (*check_policy)(int argc, char * const argv[],
        !            76:                                 char *env_add[], char **command_info[],
        !            77:                                 char **argv_out[], char **user_env_out[]);
        !            78:             int (*list)(int argc, char * const argv[], int verbose,
        !            79:                         const char *list_user);
        !            80:             int (*validate)(void);
        !            81:             void (*invalidate)(int remove);
        !            82:             int (*init_session)(struct passwd *pwd);
        !            83:         };
        !            84: 
        !            85:        The policy_plugin struct has the following fields:
        !            86: 
        !            87:        type
        !            88:            The type field should always be set to SUDO_POLICY_PLUGIN.
        !            89: 
        !            90:        version
        !            91:            The version field should be set to SUDO_API_VERSION.
        !            92: 
        !            93:            This allows ssuuddoo to determine the API version the plugin was built
        !            94:            against.
        !            95: 
        !            96:        open
        !            97:             int (*open)(unsigned int version, sudo_conv_t conversation,
        !            98:                         sudo_printf_t plugin_printf, char * const settings[],
        !            99:                         char * const user_info[], char * const user_env[]);
        !           100: 
        !           101:            Returns 1 on success, 0 on failure, -1 if a general error occurred,
        !           102:            or -2 if there was a usage error.  In the latter case, ssuuddoo will
        !           103:            print a usage message before it exits.  If an error occurs, the
        !           104:            plugin may optionally call the conversation or plugin_printf
        !           105:            function with SUDO_CONF_ERROR_MSG to present additional error
        !           106:            information to the user.
        !           107: 
        !           108:            The function arguments are as follows:
        !           109: 
        !           110:            version
        !           111:                The version passed in by ssuuddoo allows the plugin to determine
        !           112:                the major and minor version number of the plugin API supported
        !           113:                by ssuuddoo.
        !           114: 
        !           115:            conversation
        !           116:                A pointer to the conversation function that can be used by the
        !           117:                plugin to interact with the user (see below).  Returns 0 on
        !           118:                success and -1 on failure.
        !           119: 
        !           120:            plugin_printf
        !           121:                A pointer to a printf-style function that may be used to
        !           122:                display informational or error messages (see below).  Returns
        !           123:                the number of characters printed on success and -1 on failure.
        !           124: 
        !           125:            settings
        !           126:                A vector of user-supplied ssuuddoo settings in the form of
        !           127:                "name=value" strings.  The vector is terminated by a NULL
        !           128:                pointer.  These settings correspond to flags the user specified
        !           129:                when running ssuuddoo.  As such, they will only be present when the
        !           130:                corresponding flag has been specified on the command line.
        !           131: 
        !           132:                When parsing _s_e_t_t_i_n_g_s, the plugin should split on the ffiirrsstt
        !           133:                equal sign ('=') since the _n_a_m_e field will never include one
        !           134:                itself but the _v_a_l_u_e might.
        !           135: 
        !           136:                debug_level=number
        !           137:                    A numeric debug level, from 1-9, if specified via the -D
        !           138:                    flag.
        !           139: 
        !           140:                runas_user=string
        !           141:                    The user name or uid to to run the command as, if specified
        !           142:                    via the -u flag.
        !           143: 
        !           144:                runas_group=string
        !           145:                    The group name or gid to to run the command as, if
        !           146:                    specified via the -g flag.
        !           147: 
        !           148:                prompt=string
        !           149:                    The prompt to use when requesting a password, if specified
        !           150:                    via the -p flag.
        !           151: 
        !           152:                set_home=bool
        !           153:                    Set to true if the user specified the -H flag.  If true,
        !           154:                    set the HOME environment variable to the target user's home
        !           155:                    directory.
        !           156: 
        !           157:                preserve_environment=bool
        !           158:                    Set to true if the user specified the -E flag, indicating
        !           159:                    that the user wishes to preserve the environment.
        !           160: 
        !           161:                run_shell=bool
        !           162:                    Set to true if the user specified the -s flag, indicating
        !           163:                    that the user wishes to run a shell.
        !           164: 
        !           165:                login_shell=bool
        !           166:                    Set to true if the user specified the -i flag, indicating
        !           167:                    that the user wishes to run a login shell.
        !           168: 
        !           169:                implied_shell=bool
        !           170:                    If the user does not specify a program on the command line,
        !           171:                    ssuuddoo will pass the plugin the path to the user's shell and
        !           172:                    set _i_m_p_l_i_e_d___s_h_e_l_l to true.  This allows ssuuddoo with no
        !           173:                    arguments to be used similarly to _s_u(1).  If the plugin
        !           174:                    does not to support this usage, it may return a value of -2
        !           175:                    from the check_policy function, which will cause ssuuddoo to
        !           176:                    print a usage message and exit.
        !           177: 
        !           178:                preserve_groups=bool
        !           179:                    Set to true if the user specified the -P flag, indicating
        !           180:                    that the user wishes to preserve the group vector instead
        !           181:                    of setting it based on the runas user.
        !           182: 
        !           183:                ignore_ticket=bool
        !           184:                    Set to true if the user specified the -k flag along with a
        !           185:                    command, indicating that the user wishes to ignore any
        !           186:                    cached authentication credentials.
        !           187: 
        !           188:                noninteractive=bool
        !           189:                    Set to true if the user specified the -n flag, indicating
        !           190:                    that ssuuddoo should operate in non-interactive mode.  The
        !           191:                    plugin may reject a command run in non-interactive mode if
        !           192:                    user interaction is required.
        !           193: 
        !           194:                login_class=string
        !           195:                    BSD login class to use when setting resource limits and
        !           196:                    nice value, if specified by the -c flag.
        !           197: 
        !           198:                selinux_role=string
        !           199:                    SELinux role to use when executing the command, if
        !           200:                    specified by the -r flag.
        !           201: 
        !           202:                selinux_type=string
        !           203:                    SELinux type to use when executing the command, if
        !           204:                    specified by the -t flag.
        !           205: 
        !           206:                bsdauth_type=string
        !           207:                    Authentication type, if specified by the -a flag, to use on
        !           208:                    systems where BSD authentication is supported.
        !           209: 
        !           210:                network_addrs=list
        !           211:                    A space-separated list of IP network addresses and netmasks
        !           212:                    in the form "addr/netmask", e.g.
        !           213:                    "192.168.1.2/255.255.255.0".  The address and netmask pairs
        !           214:                    may be either IPv4 or IPv6, depending on what the operating
        !           215:                    system supports.  If the address contains a colon (':'), it
        !           216:                    is an IPv6 address, else it is IPv4.
        !           217: 
        !           218:                progname=string
        !           219:                    The command name that sudo was run as, typically "sudo" or
        !           220:                    "sudoedit".
        !           221: 
        !           222:                sudoedit=bool
        !           223:                    Set to true when the -e flag is is specified or if invoked
        !           224:                    as ssuuddooeeddiitt.  The plugin shall substitute an editor into
        !           225:                    _a_r_g_v in the _c_h_e_c_k___p_o_l_i_c_y function or return -2 with a usage
        !           226:                    error if the plugin does not support _s_u_d_o_e_d_i_t.  For more
        !           227:                    information, see the _c_h_e_c_k___p_o_l_i_c_y section.
        !           228: 
        !           229:                closefrom=number
        !           230:                    If specified, the user has requested via the -C flag that
        !           231:                    ssuuddoo close all files descriptors with a value of _n_u_m_b_e_r or
        !           232:                    higher.  The plugin may optionally pass this, or another
        !           233:                    value, back in the _c_o_m_m_a_n_d___i_n_f_o list.
        !           234: 
        !           235:                Additional settings may be added in the future so the plugin
        !           236:                should silently ignore settings that it does not recognize.
        !           237: 
        !           238:            user_info
        !           239:                A vector of information about the user running the command in
        !           240:                the form of "name=value" strings.  The vector is terminated by
        !           241:                a NULL pointer.
        !           242: 
        !           243:                When parsing _u_s_e_r___i_n_f_o, the plugin should split on the ffiirrsstt
        !           244:                equal sign ('=') since the _n_a_m_e field will never include one
        !           245:                itself but the _v_a_l_u_e might.
        !           246: 
        !           247:                user=string
        !           248:                    The name of the user invoking ssuuddoo.
        !           249: 
        !           250:                uid=uid_t
        !           251:                    The real user ID of the user invoking ssuuddoo.
        !           252: 
        !           253:                gid=gid_t
        !           254:                    The real group ID of the user invoking ssuuddoo.
        !           255: 
        !           256:                groups=list
        !           257:                    The user's supplementary group list formatted as a string
        !           258:                    of comma-separated group IDs.
        !           259: 
        !           260:                cwd=string
        !           261:                    The user's current working directory.
        !           262: 
        !           263:                tty=string
        !           264:                    The path to the user's terminal device.  If the user has no
        !           265:                    terminal device associated with the session, the value will
        !           266:                    be empty, as in tty=.
        !           267: 
        !           268:                host=string
        !           269:                    The local machine's hostname as returned by the
        !           270:                    gethostname() system call.
        !           271: 
        !           272:                lines=int
        !           273:                    The number of lines the user's terminal supports.  If there
        !           274:                    is no terminal device available, a default value of 24 is
        !           275:                    used.
        !           276: 
        !           277:                cols=int
        !           278:                    The number of columns the user's terminal supports.  If
        !           279:                    there is no terminal device available, a default value of
        !           280:                    80 is used.
        !           281: 
        !           282:            user_env
        !           283:                The user's environment in the form of a NULL-terminated vector
        !           284:                of "name=value" strings.
        !           285: 
        !           286:                When parsing _u_s_e_r___e_n_v, the plugin should split on the ffiirrsstt
        !           287:                equal sign ('=') since the _n_a_m_e field will never include one
        !           288:                itself but the _v_a_l_u_e might.
        !           289: 
        !           290:        close
        !           291:             void (*close)(int exit_status, int error);
        !           292: 
        !           293:            The close function is called when the command being run by ssuuddoo
        !           294:            finishes.
        !           295: 
        !           296:            The function arguments are as follows:
        !           297: 
        !           298:            exit_status
        !           299:                The command's exit status, as returned by the _w_a_i_t(2) system
        !           300:                call.  The value of exit_status is undefined if error is non-
        !           301:                zero.
        !           302: 
        !           303:            error
        !           304:                If the command could not be executed, this is set to the value
        !           305:                of errno set by the _e_x_e_c_v_e(2) system call.  The plugin is
        !           306:                responsible for displaying error information via the
        !           307:                conversation or plugin_printf function.  If the command was
        !           308:                successfully executed, the value of error is 0.
        !           309: 
        !           310:        show_version
        !           311:             int (*show_version)(int verbose);
        !           312: 
        !           313:            The show_version function is called by ssuuddoo when the user specifies
        !           314:            the -V option.  The plugin may display its version information to
        !           315:            the user via the conversation or plugin_printf function using
        !           316:            SUDO_CONV_INFO_MSG.  If the user requests detailed version
        !           317:            information, the verbose flag will be set.
        !           318: 
        !           319:        check_policy
        !           320:             int (*check_policy)(int argc, char * const argv[]
        !           321:                                 char *env_add[], char **command_info[],
        !           322:                                 char **argv_out[], char **user_env_out[]);
        !           323: 
        !           324:            The _c_h_e_c_k___p_o_l_i_c_y function is called by ssuuddoo to determine whether
        !           325:            the user is allowed to run the specified commands.
        !           326: 
        !           327:            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
        !           328:            the _o_p_e_n function, the user has requested _s_u_d_o_e_d_i_t mode.  _s_u_d_o_e_d_i_t
        !           329:            is a mechanism for editing one or more files where an editor is run
        !           330:            with the user's credentials instead of with elevated privileges.
        !           331:            ssuuddoo achieves this by creating user-writable temporary copies of
        !           332:            the files to be edited and then overwriting the originals with the
        !           333:            temporary copies after editing is complete.  If the plugin supports
        !           334:            ssuuddooeeddiitt, it should choose the editor to be used, potentially from
        !           335:            a variable in the user's environment, such as EDITOR, and include
        !           336:            it in _a_r_g_v___o_u_t (note that environment variables may include command
        !           337:            line flags).  The files to be edited should be copied from _a_r_g_v
        !           338:            into _a_r_g_v___o_u_t, separated from the editor and its arguments by a
        !           339:            "--" element.  The "--" will be removed by ssuuddoo before the editor
        !           340:            is executed.  The plugin should also set _s_u_d_o_e_d_i_t_=_t_r_u_e in the
        !           341:            _c_o_m_m_a_n_d___i_n_f_o list.
        !           342: 
        !           343:            The _c_h_e_c_k___p_o_l_i_c_y function returns 1 if the command is allowed, 0 if
        !           344:            not allowed, -1 for a general error, or -2 for a usage error or if
        !           345:            ssuuddooeeddiitt was specified but is unsupported by the plugin.  In the
        !           346:            latter case, ssuuddoo will print a usage message before it exits.  If
        !           347:            an error occurs, the plugin may optionally call the conversation or
        !           348:            plugin_printf function with SUDO_CONF_ERROR_MSG to present
        !           349:            additional error information to the user.
        !           350: 
        !           351:            The function arguments are as follows:
        !           352: 
        !           353:            argc
        !           354:                The number of elements in _a_r_g_v, not counting the final NULL
        !           355:                pointer.
        !           356: 
        !           357:            argv
        !           358:                The argument vector describing the command the user wishes to
        !           359:                run, in the same form as what would be passed to the _e_x_e_c_v_e_(_)
        !           360:                system call.  The vector is terminated by a NULL pointer.
        !           361: 
        !           362:            env_add
        !           363:                Additional environment variables specified by the user on the
        !           364:                command line in the form of a NULL-terminated vector of
        !           365:                "name=value" strings.  The plugin may reject the command if one
        !           366:                or more variables are not allowed to be set, or it may silently
        !           367:                ignore such variables.
        !           368: 
        !           369:                When parsing _e_n_v___a_d_d, the plugin should split on the ffiirrsstt
        !           370:                equal sign ('=') since the _n_a_m_e field will never include one
        !           371:                itself but the _v_a_l_u_e might.
        !           372: 
        !           373:            command_info
        !           374:                Information about the command being run in the form of
        !           375:                "name=value" strings.  These values are used by ssuuddoo to set the
        !           376:                execution environment when running a command.  The plugin is
        !           377:                responsible for creating and populating the vector, which must
        !           378:                be terminated with a NULL pointer.  The following values are
        !           379:                recognized by ssuuddoo:
        !           380: 
        !           381:                command=string
        !           382:                    Fully qualified path to the command to be executed.
        !           383: 
        !           384:                runas_uid=uid
        !           385:                    User ID to run the command as.
        !           386: 
        !           387:                runas_euid=uid
        !           388:                    Effective user ID to run the command as.  If not specified,
        !           389:                    the value of _r_u_n_a_s___u_i_d is used.
        !           390: 
        !           391:                runas_gid=gid
        !           392:                    Group ID to run the command as.
        !           393: 
        !           394:                runas_egid=gid
        !           395:                    Effective group ID to run the command as.  If not
        !           396:                    specified, the value of _r_u_n_a_s___g_i_d is used.
        !           397: 
        !           398:                runas_groups=list
        !           399:                    The supplementary group vector to use for the command in
        !           400:                    the form of a comma-separated list of group IDs.  If
        !           401:                    _p_r_e_s_e_r_v_e___g_r_o_u_p_s is set, this option is ignored.
        !           402: 
        !           403:                login_class=string
        !           404:                    BSD login class to use when setting resource limits and
        !           405:                    nice value (optional).  This option is only set on systems
        !           406:                    that support login classes.
        !           407: 
        !           408:                preserve_groups=bool
        !           409:                    If set, ssuuddoo will preserve the user's group vector instead
        !           410:                    of initializing the group vector based on runas_user.
        !           411: 
        !           412:                cwd=string
        !           413:                    The current working directory to change to when executing
        !           414:                    the command.
        !           415: 
        !           416:                noexec=bool
        !           417:                    If set, prevent the command from executing other programs.
        !           418: 
        !           419:                chroot=string
        !           420:                    The root directory to use when running the command.
        !           421: 
        !           422:                nice=int
        !           423:                    Nice value (priority) to use when executing the command.
        !           424:                    The nice value, if specified, overrides the priority
        !           425:                    associated with the _l_o_g_i_n___c_l_a_s_s on BSD systems.
        !           426: 
        !           427:                umask=octal
        !           428:                    The file creation mask to use when executing the command.
        !           429: 
        !           430:                selinux_role=string
        !           431:                    SELinux role to use when executing the command.
        !           432: 
        !           433:                selinux_type=string
        !           434:                    SELinux type to use when executing the command.
        !           435: 
        !           436:                timeout=int
        !           437:                    Command timeout.  If non-zero then when the timeout expires
        !           438:                    the command will be killed.
        !           439: 
        !           440:                sudoedit=bool
        !           441:                    Set to true when in _s_u_d_o_e_d_i_t mode.  The plugin may enable
        !           442:                    _s_u_d_o_e_d_i_t mode even if ssuuddoo was not invoked as ssuuddooeeddiitt.
        !           443:                    This allows the plugin to perform command substitution and
        !           444:                    transparently enable _s_u_d_o_e_d_i_t when the user attempts to run
        !           445:                    an editor.
        !           446: 
        !           447:                closefrom=number
        !           448:                    If specified, ssuuddoo will close all files descriptors with a
        !           449:                    value of _n_u_m_b_e_r or higher.
        !           450: 
        !           451:                iolog_compress=bool
        !           452:                    Set to true if the I/O logging plugins, if any, should
        !           453:                    compress the log data.  This is a hint to the I/O logging
        !           454:                    plugin which may choose to ignore it.
        !           455: 
        !           456:                iolog_path=string
        !           457:                    Fully qualified path to the file or directory in which I/O
        !           458:                    log is to be stored.  This is a hint to the I/O logging
        !           459:                    plugin which may choose to ignore it.  If no I/O logging
        !           460:                    plugin is loaded, this setting has no effect.
        !           461: 
        !           462:                iolog_stdin=bool
        !           463:                    Set to true if the I/O logging plugins, if any, should log
        !           464:                    the standard input if it is not connected to a terminal
        !           465:                    device.  This is a hint to the I/O logging plugin which may
        !           466:                    choose to ignore it.
        !           467: 
        !           468:                iolog_stdout=bool
        !           469:                    Set to true if the I/O logging plugins, if any, should log
        !           470:                    the standard output if it is not connected to a terminal
        !           471:                    device.  This is a hint to the I/O logging plugin which may
        !           472:                    choose to ignore it.
        !           473: 
        !           474:                iolog_stderr=bool
        !           475:                    Set to true if the I/O logging plugins, if any, should log
        !           476:                    the standard error if it is not connected to a terminal
        !           477:                    device.  This is a hint to the I/O logging plugin which may
        !           478:                    choose to ignore it.
        !           479: 
        !           480:                iolog_ttyin=bool
        !           481:                    Set to true if the I/O logging plugins, if any, should log
        !           482:                    all terminal input.  This only includes input typed by the
        !           483:                    user and not from a pipe or redirected from a file.  This
        !           484:                    is a hint to the I/O logging plugin which may choose to
        !           485:                    ignore it.
        !           486: 
        !           487:                iolog_ttyout=bool
        !           488:                    Set to true if the I/O logging plugins, if any, should log
        !           489:                    all terminal output.  This only includes output to the
        !           490:                    screen, not output to a pipe or file.  This is a hint to
        !           491:                    the I/O logging plugin which may choose to ignore it.
        !           492: 
        !           493:                use_pty=bool
        !           494:                    Allocate a pseudo-tty to run the command in, regardless of
        !           495:                    whether or not I/O logging is in use.  By default, ssuuddoo
        !           496:                    will only run the command in a pty when an I/O log plugin
        !           497:                    is loaded.
        !           498: 
        !           499:                set_utmp=bool
        !           500:                    Create a utmp (or utmpx) entry when a pseudo-tty is
        !           501:                    allocated.  By default, the new entry will be a copy of the
        !           502:                    user's existing utmp entry (if any), with the tty, time,
        !           503:                    type and pid fields updated.
        !           504: 
        !           505:                utmp_user=string
        !           506:                    User name to use when constructing a new utmp (or utmpx)
        !           507:                    entry when _s_e_t___u_t_m_p is enabled.  This option can be used to
        !           508:                    set the user field in the utmp entry to the user the
        !           509:                    command runs as rather than the invoking user.  If not set,
        !           510:                    ssuuddoo will base the new entry on the invoking user's
        !           511:                    existing entry.
        !           512: 
        !           513:                Unsupported values will be ignored.
        !           514: 
        !           515:            argv_out
        !           516:                The NULL-terminated argument vector to pass to the _e_x_e_c_v_e_(_)
        !           517:                system call when executing the command.  The plugin is
        !           518:                responsible for allocating and populating the vector.
        !           519: 
        !           520:            user_env_out
        !           521:                The NULL-terminated environment vector to use when executing
        !           522:                the command.  The plugin is responsible for allocating and
        !           523:                populating the vector.
        !           524: 
        !           525:        list
        !           526:             int (*list)(int verbose, const char *list_user,
        !           527:                         int argc, char * const argv[]);
        !           528: 
        !           529:            List available privileges for the invoking user.  Returns 1 on
        !           530:            success, 0 on failure and -1 on error.  On error, the plugin may
        !           531:            optionally call the conversation or plugin_printf function with
        !           532:            SUDO_CONF_ERROR_MSG to present additional error information to the
        !           533:            user.
        !           534: 
        !           535:            Privileges should be output via the conversation or plugin_printf
        !           536:            function using SUDO_CONV_INFO_MSG.
        !           537: 
        !           538:            verbose
        !           539:                Flag indicating whether to list in verbose mode or not.
        !           540: 
        !           541:            list_user
        !           542:                The name of a different user to list privileges for if the
        !           543:                policy allows it.  If NULL, the plugin should list the
        !           544:                privileges of the invoking user.
        !           545: 
        !           546:            argc
        !           547:                The number of elements in _a_r_g_v, not counting the final NULL
        !           548:                pointer.
        !           549: 
        !           550:            argv
        !           551:                If non-NULL, an argument vector describing a command the user
        !           552:                wishes to check against the policy in the same form as what
        !           553:                would be passed to the _e_x_e_c_v_e_(_) system call.  If the command is
        !           554:                permitted by the policy, the fully-qualified path to the
        !           555:                command should be displayed along with any command line
        !           556:                arguments.
        !           557: 
        !           558:        validate
        !           559:             int (*validate)(void);
        !           560: 
        !           561:            The validate function is called when ssuuddoo is run with the -v flag.
        !           562:            For policy plugins such as _s_u_d_o_e_r_s that cache authentication
        !           563:            credentials, this function will validate and cache the credentials.
        !           564: 
        !           565:            The validate function should be NULL if the plugin does not support
        !           566:            credential caching.
        !           567: 
        !           568:            Returns 1 on success, 0 on failure and -1 on error.  On error, the
        !           569:            plugin may optionally call the conversation or plugin_printf
        !           570:            function with SUDO_CONF_ERROR_MSG to present additional error
        !           571:            information to the user.
        !           572: 
        !           573:        invalidate
        !           574:             void (*invalidate)(int remove);
        !           575: 
        !           576:            The invalidate function is called when ssuuddoo is called with the -k
        !           577:            or -K flag.  For policy plugins such as _s_u_d_o_e_r_s that cache
        !           578:            authentication credentials, this function will invalidate the
        !           579:            credentials.  If the _r_e_m_o_v_e flag is set, the plugin may remove the
        !           580:            credentials instead of simply invalidating them.
        !           581: 
        !           582:            The invalidate function should be NULL if the plugin does not
        !           583:            support credential caching.
        !           584: 
        !           585:        init_session
        !           586:             int (*init_session)(struct passwd *pwd);
        !           587: 
        !           588:            The init_session function is called when ssuuddoo sets up the execution
        !           589:            environment for the command, immediately before the contents of the
        !           590:            _c_o_m_m_a_n_d___i_n_f_o list are applied (before the uid changes).  This can
        !           591:            be used to do session setup that is not supported by _c_o_m_m_a_n_d___i_n_f_o,
        !           592:            such as opening the PAM session.
        !           593: 
        !           594:            The _p_w_d argument points to a passwd struct for the user the command
        !           595:            will be run as if the uid the command will run as was found in the
        !           596:            password database, otherwise it will be NULL.
        !           597: 
        !           598:            Returns 1 on success, 0 on failure and -1 on error.  On error, the
        !           599:            plugin may optionally call the conversation or plugin_printf
        !           600:            function with SUDO_CONF_ERROR_MSG to present additional error
        !           601:            information to the user.
        !           602: 
        !           603:        _V_e_r_s_i_o_n _m_a_c_r_o_s
        !           604: 
        !           605:         #define SUDO_API_VERSION_GET_MAJOR(v) ((v) >> 16)
        !           606:         #define SUDO_API_VERSION_GET_MINOR(v) ((v) & 0xffff)
        !           607:         #define SUDO_API_VERSION_SET_MAJOR(vp, n) do { \
        !           608:             *(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \
        !           609:         } while(0)
        !           610:         #define SUDO_VERSION_SET_MINOR(vp, n) do { \
        !           611:             *(vp) = (*(vp) & 0xffff0000) | (n); \
        !           612:         } while(0)
        !           613: 
        !           614:         #define SUDO_API_VERSION_MAJOR 1
        !           615:         #define SUDO_API_VERSION_MINOR 0
        !           616:         #define SUDO_API_VERSION ((SUDO_API_VERSION_MAJOR << 16) | \
        !           617:                                   SUDO_API_VERSION_MINOR)
        !           618: 
        !           619:    II//OO PPlluuggiinn AAPPII
        !           620:         struct io_plugin {
        !           621:         #define SUDO_IO_PLUGIN         2
        !           622:             unsigned int type; /* always SUDO_IO_PLUGIN */
        !           623:             unsigned int version; /* always SUDO_API_VERSION */
        !           624:             int (*open)(unsigned int version, sudo_conv_t conversation
        !           625:                         sudo_printf_t plugin_printf, char * const settings[],
        !           626:                         char * const user_info[], int argc, char * const argv[],
        !           627:                         char * const user_env[]);
        !           628:             void (*close)(int exit_status, int error); /* wait status or error */
        !           629:             int (*show_version)(int verbose);
        !           630:             int (*log_ttyin)(const char *buf, unsigned int len);
        !           631:             int (*log_ttyout)(const char *buf, unsigned int len);
        !           632:             int (*log_stdin)(const char *buf, unsigned int len);
        !           633:             int (*log_stdout)(const char *buf, unsigned int len);
        !           634:             int (*log_stderr)(const char *buf, unsigned int len);
        !           635:         };
        !           636: 
        !           637:        When an I/O plugin is loaded, ssuuddoo runs the command in a pseudo-tty.
        !           638:        This makes it possible to log the input and output from the user's
        !           639:        session.  If any of the standard input, standard output or standard
        !           640:        error do not correspond to a tty, ssuuddoo will open a pipe to capture the
        !           641:        I/O for logging before passing it on.
        !           642: 
        !           643:        The log_ttyin function receives the raw user input from the terminal
        !           644:        device (note that this will include input even when echo is disabled,
        !           645:        such as when a password is read). The log_ttyout function receives
        !           646:        output from the pseudo-tty that is suitable for replaying the user's
        !           647:        session at a later time.  The log_stdin, log_stdout and log_stderr
        !           648:        functions are only called if the standard input, standard output or
        !           649:        standard error respectively correspond to something other than a tty.
        !           650: 
        !           651:        Any of the logging functions may be set to the NULL pointer if no
        !           652:        logging is to be performed.  If the open function returns 0, no I/O
        !           653:        will be sent to the plugin.
        !           654: 
        !           655:        The io_plugin struct has the following fields:
        !           656: 
        !           657:        type
        !           658:            The type field should always be set to SUDO_IO_PLUGIN
        !           659: 
        !           660:        version
        !           661:            The version field should be set to SUDO_API_VERSION.
        !           662: 
        !           663:            This allows ssuuddoo to determine the API version the plugin was built
        !           664:            against.
        !           665: 
        !           666:        open
        !           667:             int (*open)(unsigned int version, sudo_conv_t conversation
        !           668:                         sudo_printf_t plugin_printf, char * const settings[],
        !           669:                         char * const user_info[], int argc, char * const argv[],
        !           670:                         char * const user_env[]);
        !           671: 
        !           672:            The _o_p_e_n function is run before the _l_o_g___i_n_p_u_t, _l_o_g___o_u_t_p_u_t or
        !           673:            _s_h_o_w___v_e_r_s_i_o_n functions are called.  It is only called if the
        !           674:            version is being requested or the _c_h_e_c_k___p_o_l_i_c_y function has
        !           675:            returned successfully.  It returns 1 on success, 0 on failure, -1
        !           676:            if a general error occurred, or -2 if there was a usage error.  In
        !           677:            the latter case, ssuuddoo will print a usage message before it exits.
        !           678:            If an error occurs, the plugin may optionally call the conversation
        !           679:            or plugin_printf function with SUDO_CONF_ERROR_MSG to present
        !           680:            additional error information to the user.
        !           681: 
        !           682:            The function arguments are as follows:
        !           683: 
        !           684:            version
        !           685:                The version passed in by ssuuddoo allows the plugin to determine
        !           686:                the major and minor version number of the plugin API supported
        !           687:                by ssuuddoo.
        !           688: 
        !           689:            conversation
        !           690:                A pointer to the conversation function that may be used by the
        !           691:                _s_h_o_w___v_e_r_s_i_o_n function to display version information (see
        !           692:                show_version below).  The conversation function may also be
        !           693:                used to display additional error message to the user.  The
        !           694:                conversation function returns 0 on success and -1 on failure.
        !           695: 
        !           696:            plugin_printf
        !           697:                A pointer to a printf-style function that may be used by the
        !           698:                _s_h_o_w___v_e_r_s_i_o_n function to display version information (see
        !           699:                show_version below).  The plugin_printf function may also be
        !           700:                used to display additional error message to the user.  The
        !           701:                plugin_printf function returns number of characters printed on
        !           702:                success and -1 on failure.
        !           703: 
        !           704:            settings
        !           705:                A vector of user-supplied ssuuddoo settings in the form of
        !           706:                "name=value" strings.  The vector is terminated by a NULL
        !           707:                pointer.  These settings correspond to flags the user specified
        !           708:                when running ssuuddoo.  As such, they will only be present when the
        !           709:                corresponding flag has been specified on the command line.
        !           710: 
        !           711:                When parsing _s_e_t_t_i_n_g_s, the plugin should split on the ffiirrsstt
        !           712:                equal sign ('=') since the _n_a_m_e field will never include one
        !           713:                itself but the _v_a_l_u_e might.
        !           714: 
        !           715:                See the "Policy Plugin API" section for a list of all possible
        !           716:                settings.
        !           717: 
        !           718:            user_info
        !           719:                A vector of information about the user running the command in
        !           720:                the form of "name=value" strings.  The vector is terminated by
        !           721:                a NULL pointer.
        !           722: 
        !           723:                When parsing _u_s_e_r___i_n_f_o, the plugin should split on the ffiirrsstt
        !           724:                equal sign ('=') since the _n_a_m_e field will never include one
        !           725:                itself but the _v_a_l_u_e might.
        !           726: 
        !           727:                See the "Policy Plugin API" section for a list of all possible
        !           728:                strings.
        !           729: 
        !           730:            argc
        !           731:                The number of elements in _a_r_g_v, not counting the final NULL
        !           732:                pointer.
        !           733: 
        !           734:            argv
        !           735:                If non-NULL, an argument vector describing a command the user
        !           736:                wishes to run in the same form as what would be passed to the
        !           737:                _e_x_e_c_v_e_(_) system call.
        !           738: 
        !           739:            user_env
        !           740:                The user's environment in the form of a NULL-terminated vector
        !           741:                of "name=value" strings.
        !           742: 
        !           743:                When parsing _u_s_e_r___e_n_v, the plugin should split on the ffiirrsstt
        !           744:                equal sign ('=') since the _n_a_m_e field will never include one
        !           745:                itself but the _v_a_l_u_e might.
        !           746: 
        !           747:        close
        !           748:             void (*close)(int exit_status, int error);
        !           749: 
        !           750:            The close function is called when the command being run by ssuuddoo
        !           751:            finishes.
        !           752: 
        !           753:            The function arguments are as follows:
        !           754: 
        !           755:            exit_status
        !           756:                The command's exit status, as returned by the _w_a_i_t(2) system
        !           757:                call.  The value of exit_status is undefined if error is non-
        !           758:                zero.
        !           759: 
        !           760:            error
        !           761:                If the command could not be executed, this is set to the value
        !           762:                of errno set by the _e_x_e_c_v_e(2) system call.  If the command was
        !           763:                successfully executed, the value of error is 0.
        !           764: 
        !           765:        show_version
        !           766:             int (*show_version)(int verbose);
        !           767: 
        !           768:            The show_version function is called by ssuuddoo when the user specifies
        !           769:            the -V option.  The plugin may display its version information to
        !           770:            the user via the conversation or plugin_printf function using
        !           771:            SUDO_CONV_INFO_MSG.  If the user requests detailed version
        !           772:            information, the verbose flag will be set.
        !           773: 
        !           774:        log_ttyin
        !           775:             int (*log_ttyin)(const char *buf, unsigned int len);
        !           776: 
        !           777:            The _l_o_g___t_t_y_i_n function is called whenever data can be read from the
        !           778:            user but before it is passed to the running command.  This allows
        !           779:            the plugin to reject data if it chooses to (for instance if the
        !           780:            input contains banned content).  Returns 1 if the data should be
        !           781:            passed to the command, 0 if the data is rejected (which will
        !           782:            terminate the command) or -1 if an error occurred.
        !           783: 
        !           784:            The function arguments are as follows:
        !           785: 
        !           786:            buf The buffer containing user input.
        !           787: 
        !           788:            len The length of _b_u_f in bytes.
        !           789: 
        !           790:        log_ttyout
        !           791:             int (*log_ttyout)(const char *buf, unsigned int len);
        !           792: 
        !           793:            The _l_o_g___t_t_y_o_u_t function is called whenever data can be read from
        !           794:            the command but before it is written to the user's terminal.  This
        !           795:            allows the plugin to reject data if it chooses to (for instance if
        !           796:            the output contains banned content).  Returns 1 if the data should
        !           797:            be passed to the user, 0 if the data is rejected (which will
        !           798:            terminate the command) or -1 if an error occurred.
        !           799: 
        !           800:            The function arguments are as follows:
        !           801: 
        !           802:            buf The buffer containing command output.
        !           803: 
        !           804:            len The length of _b_u_f in bytes.
        !           805: 
        !           806:        log_stdin
        !           807:             int (*log_stdin)(const char *buf, unsigned int len);
        !           808: 
        !           809:            The _l_o_g___s_t_d_i_n function is only used if the standard input does not
        !           810:            correspond to a tty device.  It is called whenever data can be read
        !           811:            from the standard input but before it is passed to the running
        !           812:            command.  This allows the plugin to reject data if it chooses to
        !           813:            (for instance if the input contains banned content).  Returns 1 if
        !           814:            the data should be passed to the command, 0 if the data is rejected
        !           815:            (which will terminate the command) or -1 if an error occurred.
        !           816: 
        !           817:            The function arguments are as follows:
        !           818: 
        !           819:            buf The buffer containing user input.
        !           820: 
        !           821:            len The length of _b_u_f in bytes.
        !           822: 
        !           823:        log_stdout
        !           824:             int (*log_stdout)(const char *buf, unsigned int len);
        !           825: 
        !           826:            The _l_o_g___s_t_d_o_u_t function is only used if the standard output does
        !           827:            not correspond to a tty device.  It is called whenever data can be
        !           828:            read from the command but before it is written to the standard
        !           829:            output.  This allows the plugin to reject data if it chooses to
        !           830:            (for instance if the output contains banned content).  Returns 1 if
        !           831:            the data should be passed to the user, 0 if the data is rejected
        !           832:            (which will terminate the command) or -1 if an error occurred.
        !           833: 
        !           834:            The function arguments are as follows:
        !           835: 
        !           836:            buf The buffer containing command output.
        !           837: 
        !           838:            len The length of _b_u_f in bytes.
        !           839: 
        !           840:        log_stderr
        !           841:             int (*log_stderr)(const char *buf, unsigned int len);
        !           842: 
        !           843:            The _l_o_g___s_t_d_e_r_r function is only used if the standard error does not
        !           844:            correspond to a tty device.  It is called whenever data can be read
        !           845:            from the command but before it is written to the standard error.
        !           846:            This allows the plugin to reject data if it chooses to (for
        !           847:            instance if the output contains banned content).  Returns 1 if the
        !           848:            data should be passed to the user, 0 if the data is rejected (which
        !           849:            will terminate the command) or -1 if an error occurred.
        !           850: 
        !           851:            The function arguments are as follows:
        !           852: 
        !           853:            buf The buffer containing command output.
        !           854: 
        !           855:            len The length of _b_u_f in bytes.
        !           856: 
        !           857:        _V_e_r_s_i_o_n _m_a_c_r_o_s
        !           858: 
        !           859:        Same as for the "Policy Plugin API".
        !           860: 
        !           861:    CCoonnvveerrssaattiioonn AAPPII
        !           862:        If the plugin needs to interact with the user, it may do so via the
        !           863:        conversation function.  A plugin should not attempt to read directly
        !           864:        from the standard input or the user's tty (neither of which are
        !           865:        guaranteed to exist).  The caller must include a trailing newline in
        !           866:        msg if one is to be printed.
        !           867: 
        !           868:        A printf-style function is also available that can be used to display
        !           869:        informational or error messages to the user, which is usually more
        !           870:        convenient for simple messages where no use input is required.
        !           871: 
        !           872:         struct sudo_conv_message {
        !           873:         #define SUDO_CONV_PROMPT_ECHO_OFF  0x0001 /* do not echo user input */
        !           874:         #define SUDO_CONV_PROMPT_ECHO_ON   0x0002 /* echo user input */
        !           875:         #define SUDO_CONV_ERROR_MSG        0x0003 /* error message */
        !           876:         #define SUDO_CONV_INFO_MSG         0x0004 /* informational message */
        !           877:         #define SUDO_CONV_PROMPT_MASK      0x0005 /* mask user input */
        !           878:         #define SUDO_CONV_PROMPT_ECHO_OK   0x1000 /* flag: allow echo if no tty */
        !           879:             int msg_type;
        !           880:             int timeout;
        !           881:             const char *msg;
        !           882:         };
        !           883: 
        !           884:         struct sudo_conv_reply {
        !           885:             char *reply;
        !           886:         };
        !           887: 
        !           888:         typedef int (*sudo_conv_t)(int num_msgs,
        !           889:                      const struct sudo_conv_message msgs[],
        !           890:                      struct sudo_conv_reply replies[]);
        !           891: 
        !           892:         typedef int (*sudo_printf_t)(int msg_type, const char *fmt, ...);
        !           893: 
        !           894:        Pointers to the conversation and printf-style functions are passed in
        !           895:        to the plugin's open function when the plugin is initialized.
        !           896: 
        !           897:        To use the conversation function, the plugin must pass an array of
        !           898:        sudo_conv_message and sudo_conv_reply structures.  There must be a
        !           899:        struct sudo_conv_message and struct sudo_conv_reply for each message in
        !           900:        the conversation.  The plugin is responsible for freeing the reply
        !           901:        buffer filled in to the struct sudo_conv_reply, if any.
        !           902: 
        !           903:        The printf-style function uses the same underlying mechanism as the
        !           904:        conversation function but only supports SUDO_CONV_INFO_MSG and
        !           905:        SUDO_CONV_ERROR_MSG for the _m_s_g___t_y_p_e parameter.  It can be more
        !           906:        convenient than using the conversation function if no user reply is
        !           907:        needed and supports standard _p_r_i_n_t_f_(_) escape sequences.
        !           908: 
        !           909:        See the sample plugin for an example of the conversation function
        !           910:        usage.
        !           911: 
        !           912:    SSuuddooeerrss GGrroouupp PPlluuggiinn AAPPII
        !           913:        The _s_u_d_o_e_r_s module supports a plugin interface to allow non-Unix group
        !           914:        lookups.  This can be used to query a group source other than the
        !           915:        standard Unix group database.  A sample group plugin is bundled with
        !           916:        ssuuddoo that implements file-based lookups.  Third party group plugins
        !           917:        include a QAS AD plugin available from Quest Software.
        !           918: 
        !           919:        A group plugin must declare and populate a sudoers_group_plugin struct
        !           920:        in the global scope.  This structure contains pointers to the functions
        !           921:        that implement plugin initialization, cleanup and group lookup.
        !           922: 
        !           923:         struct sudoers_group_plugin {
        !           924:            unsigned int version;
        !           925:            int (*init)(int version, sudo_printf_t sudo_printf,
        !           926:                        char *const argv[]);
        !           927:            void (*cleanup)(void);
        !           928:            int (*query)(const char *user, const char *group,
        !           929:                         const struct passwd *pwd);
        !           930:        };
        !           931: 
        !           932:        The sudoers_group_plugin struct has the following fields:
        !           933: 
        !           934:        version
        !           935:            The version field should be set to GROUP_API_VERSION.
        !           936: 
        !           937:            This allows _s_u_d_o_e_r_s to determine the API version the group plugin
        !           938:            was built against.
        !           939: 
        !           940:        init
        !           941:             int (*init)(int version, sudo_printf_t plugin_printf,
        !           942:                         char *const argv[]);
        !           943: 
        !           944:            The _i_n_i_t function is called after _s_u_d_o_e_r_s has been parsed but
        !           945:            before any policy checks.  It returns 1 on success, 0 on failure
        !           946:            (or if the plugin is not configured), and -1 if a error occurred.
        !           947:            If an error occurs, the plugin may call the plugin_printf function
        !           948:            with SUDO_CONF_ERROR_MSG to present additional error information to
        !           949:            the user.
        !           950: 
        !           951:            The function arguments are as follows:
        !           952: 
        !           953:            version
        !           954:                The version passed in by _s_u_d_o_e_r_s allows the plugin to determine
        !           955:                the major and minor version number of the group plugin API
        !           956:                supported by _s_u_d_o_e_r_s.
        !           957: 
        !           958:            plugin_printf
        !           959:                A pointer to a printf-style function that may be used to
        !           960:                display informational or error message to the user.  Returns
        !           961:                the number of characters printed on success and -1 on failure.
        !           962: 
        !           963:            argv
        !           964:                A NULL-terminated array of arguments generated from the
        !           965:                _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,
        !           966:                _a_r_g_v will be NULL.
        !           967: 
        !           968:        cleanup
        !           969:             void (*cleanup)();
        !           970: 
        !           971:            The _c_l_e_a_n_u_p function is called when _s_u_d_o_e_r_s has finished its group
        !           972:            checks.  The plugin should free any memory it has allocated and
        !           973:            close open file handles.
        !           974: 
        !           975:        query
        !           976:             int (*query)(const char *user, const char *group,
        !           977:                          const struct passwd *pwd);
        !           978: 
        !           979:            The _q_u_e_r_y function is used to ask the group plugin whether _u_s_e_r is
        !           980:            a member of _g_r_o_u_p.
        !           981: 
        !           982:            The function arguments are as follows:
        !           983: 
        !           984:            user
        !           985:                The name of the user being looked up in the external group
        !           986:                database.
        !           987: 
        !           988:            group
        !           989:                The name of the group being queried.
        !           990: 
        !           991:            pwd The password database entry for _u_s_e_r, if any.  If _u_s_e_r is not
        !           992:                present in the password database, _p_w_d will be NULL.
        !           993: 
        !           994:        _V_e_r_s_i_o_n _M_a_c_r_o_s
        !           995: 
        !           996:         /* Sudoers group plugin version major/minor */
        !           997:         #define GROUP_API_VERSION_MAJOR 1
        !           998:         #define GROUP_API_VERSION_MINOR 0
        !           999:         #define GROUP_API_VERSION ((GROUP_API_VERSION_MAJOR << 16) | \
        !          1000:                                    GROUP_API_VERSION_MINOR)
        !          1001: 
        !          1002:         /* Getters and setters for group version */
        !          1003:         #define GROUP_API_VERSION_GET_MAJOR(v) ((v) >> 16)
        !          1004:         #define GROUP_API_VERSION_GET_MINOR(v) ((v) & 0xffff)
        !          1005:         #define GROUP_API_VERSION_SET_MAJOR(vp, n) do { \
        !          1006:             *(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \
        !          1007:         } while(0)
        !          1008:         #define GROUP_API_VERSION_SET_MINOR(vp, n) do { \
        !          1009:             *(vp) = (*(vp) & 0xffff0000) | (n); \
        !          1010:         } while(0)
        !          1011: 
        !          1012: SSEEEE AALLSSOO
        !          1013:        _s_u_d_o_e_r_s(4), _s_u_d_o(1m)
        !          1014: 
        !          1015: BBUUGGSS
        !          1016:        If you feel you have found a bug in ssuuddoo, please submit a bug report at
        !          1017:        http://www.sudo.ws/sudo/bugs/
        !          1018: 
        !          1019: SSUUPPPPOORRTT
        !          1020:        Limited free support is available via the sudo-workers mailing list,
        !          1021:        see http://www.sudo.ws/mailman/listinfo/sudo-workers to subscribe or
        !          1022:        search the archives.
        !          1023: 
        !          1024: DDIISSCCLLAAIIMMEERR
        !          1025:        ssuuddoo is provided ``AS IS'' and any express or implied warranties,
        !          1026:        including, but not limited to, the implied warranties of
        !          1027:        merchantability and fitness for a particular purpose are disclaimed.
        !          1028:        See the LICENSE file distributed with ssuuddoo or
        !          1029:        http://www.sudo.ws/sudo/license.html for complete details.
        !          1030: 
        !          1031: 
        !          1032: 
        !          1033: 1.8.3                         September 16, 2011               SUDO_PLUGIN(1m)

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