Annotation of embedaddon/sudo/doc/sudo_plugin.mdoc.in, revision 1.1.1.4

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

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