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

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

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