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

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

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