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

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

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