io_plugin in the plugin shared object. The _\bp_\ba_\bt_\bh may be fully qualified
or relative. If not fully qualified it is relative to the
_\b/_\bu_\bs_\br_\b/_\bl_\bo_\bc_\ba_\bl_\b/_\bl_\bi_\bb_\be_\bx_\be_\bc directory. Any additional parameters after the _\bp_\ba_\bt_\bh
- are ignored. Lines that don't begin with Plugin or Path are silently
- ignored.
+ are passed as options to the plugin's _\bo_\bp_\be_\bn function. Lines that don't
+ begin with Plugin, Path, Debug or Set are silently ignored.
The same shared object may contain multiple plugins, each with a
different symbol name. The shared object file must be owned by uid 0
# Default /etc/sudo.conf file
#
# Format:
- # Plugin plugin_name plugin_path
+ # Plugin plugin_name plugin_path plugin_options ...
# Path askpass /path/to/askpass
+ # Path noexec /path/to/sudo_noexec.so
+ # Debug sudo /var/log/sudo_debug all@warn
+ # Set disable_coredump true
#
# The plugin_path is relative to /usr/local/libexec unless
# fully qualified.
# The plugin_name corresponds to a global symbol in the plugin
# that contains the plugin interface structure.
+ # The plugin_options are optional.
#
Plugin sudoers_policy sudoers.so
Plugin sudoers_io sudoers.so
unsigned int version; /* always SUDO_API_VERSION */
int (*open)(unsigned int version, sudo_conv_t conversation,
sudo_printf_t plugin_printf, char * const settings[],
- char * const user_info[], char * const user_env[]);
+ char * const user_info[], char * const user_env[],
+ char * const plugin_options[]);
void (*close)(int exit_status, int error);
int (*show_version)(int verbose);
int (*check_policy)(int argc, char * const argv[],
const char *list_user);
int (*validate)(void);
void (*invalidate)(int remove);
- int (*init_session)(struct passwd *pwd);
+ int (*init_session)(struct passwd *pwd, char **user_env[]);
+ void (*register_hooks)(int version,
+ int (*register_hook)(struct sudo_hook *hook));
+ void (*deregister_hooks)(int version,
+ int (*deregister_hook)(struct sudo_hook *hook));
};
The policy_plugin struct has the following fields:
open
int (*open)(unsigned int version, sudo_conv_t conversation,
sudo_printf_t plugin_printf, char * const settings[],
- char * const user_info[], char * const user_env[]);
+ char * const user_info[], char * const user_env[],
+ char * const plugin_options[]);
Returns 1 on success, 0 on failure, -1 if a general error occurred,
or -2 if there was a usage error. In the latter case, s\bsu\bud\bdo\bo will
equal sign ('=') since the _\bn_\ba_\bm_\be field will never include one
itself but the _\bv_\ba_\bl_\bu_\be might.
+ debug_flags=string
+ A comma-separated list of debug flags that correspond to
+ s\bsu\bud\bdo\bo's Debug entry in _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\b._\bc_\bo_\bn_\bf, if there is one. The
+ flags are passed to the plugin as they appear in
+ _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\b._\bc_\bo_\bn_\bf. The syntax used by s\bsu\bud\bdo\bo and the _\bs_\bu_\bd_\bo_\be_\br_\bs
+ plugin is _\bs_\bu_\bb_\bs_\by_\bs_\bt_\be_\bm@_\bp_\br_\bi_\bo_\br_\bi_\bt_\by but the plugin is free to use
+ a different format so long as it does not include a command
+ ,.
+
+ For reference, the priorities supported by the s\bsu\bud\bdo\bo front
+ end and _\bs_\bu_\bd_\bo_\be_\br_\bs are: _\bc_\br_\bi_\bt, _\be_\br_\br, _\bw_\ba_\br_\bn, _\bn_\bo_\bt_\bi_\bc_\be, _\bd_\bi_\ba_\bg, _\bi_\bn_\bf_\bo,
+ _\bt_\br_\ba_\bc_\be and _\bd_\be_\bb_\bu_\bg.
+
+ The following subsystems are defined: _\bm_\ba_\bi_\bn, _\bm_\be_\bm_\bo_\br_\by, _\ba_\br_\bg_\bs,
+ _\be_\bx_\be_\bc, _\bp_\bt_\by, _\bu_\bt_\bm_\bp, _\bc_\bo_\bn_\bv, _\bp_\bc_\bo_\bm_\bm, _\bu_\bt_\bi_\bl, _\bl_\bi_\bs_\bt, _\bn_\be_\bt_\bi_\bf, _\ba_\bu_\bd_\bi_\bt,
+ _\be_\bd_\bi_\bt, _\bs_\be_\bl_\bi_\bn_\bu_\bx, _\bl_\bd_\ba_\bp, _\bm_\ba_\bt_\bc_\bh, _\bp_\ba_\br_\bs_\be_\br, _\ba_\bl_\bi_\ba_\bs, _\bd_\be_\bf_\ba_\bu_\bl_\bt_\bs, _\ba_\bu_\bt_\bh,
+ _\be_\bn_\bv, _\bl_\bo_\bg_\bg_\bi_\bn_\bg, _\bn_\bs_\bs, _\br_\bb_\bt_\br_\be_\be, _\bp_\be_\br_\bm_\bs, _\bp_\bl_\bu_\bg_\bi_\bn. The subsystem
+ _\ba_\bl_\bl includes every subsystem.
+
+ There is not currently a way to specify a set of debug
+ flags specific to the plugin--the flags are shared by s\bsu\bud\bdo\bo
+ and the plugin.
+
debug_level=number
- A numeric debug level, from 1-9, if specified via the -D
- flag.
+ This setting has been deprecated in favor of _\bd_\be_\bb_\bu_\bg_\b__\bf_\bl_\ba_\bg_\bs.
runas_user=string
The user name or uid to to run the command as, if specified
equal sign ('=') since the _\bn_\ba_\bm_\be field will never include one
itself but the _\bv_\ba_\bl_\bu_\be might.
+ pid=int
+ The process ID of the running s\bsu\bud\bdo\bo process. Only available
+ starting with API version 1.2
+
+ ppid=int
+ The parent process ID of the running s\bsu\bud\bdo\bo process. Only
+ available starting with API version 1.2
+
+ sid=int
+ The session ID of the running s\bsu\bud\bdo\bo process or 0 if s\bsu\bud\bdo\bo is
+ not part of a POSIX job control session. Only available
+ starting with API version 1.2
+
+ pgid=int
+ The ID of the process group that the running s\bsu\bud\bdo\bo process
+ belongs to. Only available starting with API version 1.2
+
+ tcpgid=int
+ The ID of the forground process group associated with the
+ terminal device associcated with the s\bsu\bud\bdo\bo process or -1 if
+ there is no terminal present. Only available starting with
+ API version 1.2
+
user=string
The name of the user invoking s\bsu\bud\bdo\bo.
+ euid=uid_t
+ The effective user ID of the user invoking s\bsu\bud\bdo\bo.
+
uid=uid_t
The real user ID of the user invoking s\bsu\bud\bdo\bo.
+ egid=gid_t
+ The effective group ID of the user invoking s\bsu\bud\bdo\bo.
+
gid=gid_t
The real group ID of the user invoking s\bsu\bud\bdo\bo.
equal sign ('=') since the _\bn_\ba_\bm_\be field will never include one
itself but the _\bv_\ba_\bl_\bu_\be might.
+ plugin_options
+ Any (non-comment) strings immediately after the plugin path are
+ treated as arguments to the plugin. These arguments are split
+ on a white space boundary and are passed to the plugin in the
+ form of a NULL-terminated array of strings. If no arguments
+ were specified, _\bp_\bl_\bu_\bg_\bi_\bn_\b__\bo_\bp_\bt_\bi_\bo_\bn_\bs will be the NULL pointer.
+
+ NOTE: the _\bp_\bl_\bu_\bg_\bi_\bn_\b__\bo_\bp_\bt_\bi_\bo_\bn_\bs parameter is only available starting
+ with API version 1.2. A plugin m\bmu\bus\bst\bt check the API version
+ specified by the s\bsu\bud\bdo\bo front end before using _\bp_\bl_\bu_\bg_\bi_\bn_\b__\bo_\bp_\bt_\bi_\bo_\bn_\bs.
+ Failure to do so may result in a crash.
+
close
void (*close)(int exit_status, int error);
support credential caching.
init_session
- int (*init_session)(struct passwd *pwd);
+ int (*init_session)(struct passwd *pwd, char **user_envp[);
- The init_session function is called when s\bsu\bud\bdo\bo sets up the execution
- environment for the command, immediately before the contents of the
- _\bc_\bo_\bm_\bm_\ba_\bn_\bd_\b__\bi_\bn_\bf_\bo list are applied (before the uid changes). This can
- be used to do session setup that is not supported by _\bc_\bo_\bm_\bm_\ba_\bn_\bd_\b__\bi_\bn_\bf_\bo,
- such as opening the PAM session.
+ The init_session function is called before s\bsu\bud\bdo\bo sets up the
+ execution environment for the command. It is run in the parent
+ s\bsu\bud\bdo\bo process and before any uid or gid changes. This can be used
+ to perform session setup that is not supported by _\bc_\bo_\bm_\bm_\ba_\bn_\bd_\b__\bi_\bn_\bf_\bo,
+ such as opening the PAM session. The close function can be used to
+ tear down the session that was opened by init_session.
The _\bp_\bw_\bd argument points to a passwd struct for the user the command
will be run as if the uid the command will run as was found in the
password database, otherwise it will be NULL.
+ The _\bu_\bs_\be_\br_\b__\be_\bn_\bv argument points to the environment the command will
+ run in, in the form of a NULL-terminated vector of "name=value"
+ strings. This is the same string passed back to the front end via
+ the Policy Plugin's _\bu_\bs_\be_\br_\b__\be_\bn_\bv_\b__\bo_\bu_\bt parameter. If the init_session
+ function needs to modify the user environment, it should update the
+ pointer stored in _\bu_\bs_\be_\br_\b__\be_\bn_\bv. The expected use case is to merge the
+ contents of the PAM environment (if any) with the contents of
+ _\bu_\bs_\be_\br_\b__\be_\bn_\bv. NOTE: the _\bu_\bs_\be_\br_\b__\be_\bn_\bv parameter is only available starting
+ with API version 1.2. A plugin m\bmu\bus\bst\bt check the API version
+ specified by the s\bsu\bud\bdo\bo front end before using _\bu_\bs_\be_\br_\b__\be_\bn_\bv. Failure to
+ do so may result in a crash.
+
Returns 1 on success, 0 on failure and -1 on error. On error, the
plugin may optionally call the conversation or plugin_printf
function with SUDO_CONF_ERROR_MSG to present additional error
information to the user.
- _\bV_\be_\br_\bs_\bi_\bo_\bn _\bm_\ba_\bc_\br_\bo_\bs
+ register_hooks
+ void (*register_hooks)(int version,
+ int (*register_hook)(struct sudo_hook *hook));
+
+ The register_hooks function is called by the sudo front end to
+ register any hooks the plugin needs. If the plugin does not
+ support hooks, register_hooks should be set to the NULL pointer.
+
+ The _\bv_\be_\br_\bs_\bi_\bo_\bn argument describes the version of the hooks API
+ supported by the s\bsu\bud\bdo\bo front end.
+
+ The register_hook function should be used to register any supported
+ hooks the plugin needs. It returns 0 on success, 1 if the hook
+ type is not supported and -1 if the major version in struct hook
+ does not match the front end's major hook API version.
+
+ See the "Hook Function API" section below for more information
+ about hooks.
+
+ NOTE: the register_hooks function is only available starting with
+ API version 1.2. If the s\bsu\bud\bdo\bo front end doesn't support API version
+ 1.2 or higher, register_hooks will not be called.
+
+ deregister_hooks
+ void (*deregister_hooks)(int version,
+ int (*deregister_hook)(struct sudo_hook *hook));
+
+ The deregister_hooks function is called by the sudo front end to
+ deregister any hooks the plugin has registered. If the plugin does
+ not support hooks, deregister_hooks should be set to the NULL
+ pointer.
+
+ The _\bv_\be_\br_\bs_\bi_\bo_\bn argument describes the version of the hooks API
+ supported by the s\bsu\bud\bdo\bo front end.
+
+ The deregister_hook function should be used to deregister any hooks
+ that were put in place by the register_hook function. If the
+ plugin tries to deregister a hook that the front end does not
+ support, deregister_hook will return an error.
+
+ See the "Hook Function API" section below for more information
+ about hooks.
+
+ NOTE: the deregister_hooks function is only available starting with
+ API version 1.2. If the s\bsu\bud\bdo\bo front end doesn't support API version
+ 1.2 or higher, deregister_hooks will not be called.
+
+ _\bP_\bo_\bl_\bi_\bc_\by _\bP_\bl_\bu_\bg_\bi_\bn _\bV_\be_\br_\bs_\bi_\bo_\bn _\bM_\ba_\bc_\br_\bo_\bs
+
+ /* Plugin API version major/minor. */
+ #define SUDO_API_VERSION_MAJOR 1
+ #define SUDO_API_VERSION_MINOR 2
+ #define SUDO_API_MKVERSION(x, y) ((x << 16) | y)
+ #define SUDO_API_VERSION SUDO_API_MKVERSION(SUDO_API_VERSION_MAJOR,\
+ SUDO_API_VERSION_MINOR)
+ /* Getters and setters for API version */
#define SUDO_API_VERSION_GET_MAJOR(v) ((v) >> 16)
#define SUDO_API_VERSION_GET_MINOR(v) ((v) & 0xffff)
#define SUDO_API_VERSION_SET_MAJOR(vp, n) do { \
*(vp) = (*(vp) & 0xffff0000) | (n); \
} while(0)
- #define SUDO_API_VERSION_MAJOR 1
- #define SUDO_API_VERSION_MINOR 0
- #define SUDO_API_VERSION ((SUDO_API_VERSION_MAJOR << 16) | \
- SUDO_API_VERSION_MINOR)
-
I\bI/\b/O\bO P\bPl\blu\bug\bgi\bin\bn A\bAP\bPI\bI
struct io_plugin {
#define SUDO_IO_PLUGIN 2
int (*open)(unsigned int version, sudo_conv_t conversation
sudo_printf_t plugin_printf, char * const settings[],
char * const user_info[], int argc, char * const argv[],
- char * const user_env[]);
+ char * const user_env[], char * const plugin_options[]);
void (*close)(int exit_status, int error); /* wait status or error */
int (*show_version)(int verbose);
int (*log_ttyin)(const char *buf, unsigned int len);
int (*log_stdin)(const char *buf, unsigned int len);
int (*log_stdout)(const char *buf, unsigned int len);
int (*log_stderr)(const char *buf, unsigned int len);
+ void (*register_hooks)(int version,
+ int (*register_hook)(struct sudo_hook *hook));
+ void (*deregister_hooks)(int version,
+ int (*deregister_hook)(struct sudo_hook *hook));
};
When an I/O plugin is loaded, s\bsu\bud\bdo\bo runs the command in a pseudo-tty.
int (*open)(unsigned int version, sudo_conv_t conversation
sudo_printf_t plugin_printf, char * const settings[],
char * const user_info[], int argc, char * const argv[],
- char * const user_env[]);
+ char * const user_env[], char * const plugin_options[]);
The _\bo_\bp_\be_\bn function is run before the _\bl_\bo_\bg_\b__\bi_\bn_\bp_\bu_\bt, _\bl_\bo_\bg_\b__\bo_\bu_\bt_\bp_\bu_\bt or
_\bs_\bh_\bo_\bw_\b__\bv_\be_\br_\bs_\bi_\bo_\bn functions are called. It is only called if the
equal sign ('=') since the _\bn_\ba_\bm_\be field will never include one
itself but the _\bv_\ba_\bl_\bu_\be might.
+ plugin_options
+ Any (non-comment) strings immediately after the plugin path are
+ treated as arguments to the plugin. These arguments are split
+ on a white space boundary and are passed to the plugin in the
+ form of a NULL-terminated array of strings. If no arguments
+ were specified, _\bp_\bl_\bu_\bg_\bi_\bn_\b__\bo_\bp_\bt_\bi_\bo_\bn_\bs will be the NULL pointer.
+
+ NOTE: the _\bp_\bl_\bu_\bg_\bi_\bn_\b__\bo_\bp_\bt_\bi_\bo_\bn_\bs parameter is only available starting
+ with API version 1.2. A plugin m\bmu\bus\bst\bt check the API version
+ specified by the s\bsu\bud\bdo\bo front end before using _\bp_\bl_\bu_\bg_\bi_\bn_\b__\bo_\bp_\bt_\bi_\bo_\bn_\bs.
+ Failure to do so may result in a crash.
+
close
void (*close)(int exit_status, int error);
len The length of _\bb_\bu_\bf in bytes.
- _\bV_\be_\br_\bs_\bi_\bo_\bn _\bm_\ba_\bc_\br_\bo_\bs
+ register_hooks
+ See the "Policy Plugin API" section for a description of
+ register_hooks.
+
+ deregister_hooks
+ See the "Policy Plugin API" section for a description of
+ deregister_hooks.
+
+ _\bI_\b/_\bO _\bP_\bl_\bu_\bg_\bi_\bn _\bV_\be_\br_\bs_\bi_\bo_\bn _\bM_\ba_\bc_\br_\bo_\bs
Same as for the "Policy Plugin API".
+ H\bHo\boo\bok\bk F\bFu\bun\bnc\bct\bti\bio\bon\bn A\bAP\bPI\bI
+ Beginning with plugin API version 1.2, it is possible to install hooks
+ for certain functions called by the s\bsu\bud\bdo\bo front end.
+
+ Currently, the only supported hooks relate to the handling of
+ environment variables. Hooks can be used to intercept attempts to get,
+ set, or remove environment variables so that these changes can be
+ reflected in the version of the environment that is used to execute a
+ command. A future version of the API will support hooking internal
+ s\bsu\bud\bdo\bo front end functions as well.
+
+ _\bH_\bo_\bo_\bk _\bs_\bt_\br_\bu_\bc_\bt_\bu_\br_\be
+
+ Hooks in s\bsu\bud\bdo\bo are described by the following structure:
+
+ typedef int (*sudo_hook_fn_t)();
+
+ struct sudo_hook {
+ int hook_version;
+ int hook_type;
+ sudo_hook_fn_t hook_fn;
+ void *closure;
+ };
+
+ The sudo_hook structure has the following fields:
+
+ hook_version
+ The hook_version field should be set to SUDO_HOOK_VERSION.
+
+ hook_type
+ The hook_type field may be one of the following supported hook
+ types:
+
+ SUDO_HOOK_SETENV
+ The C library setenv() function. Any registered hooks will run
+ before the C library implementation. The hook_fn field should
+ be a function that matches the following typedef:
+
+ typedef int (*sudo_hook_fn_setenv_t)(const char *name,
+ const char *value, int overwrite, void *closure);
+
+ If the registered hook does not match the typedef the results
+ are unspecified.
+
+ SUDO_HOOK_UNSETENV
+ The C library unsetenv() function. Any registered hooks will
+ run before the C library implementation. The hook_fn field
+ should be a function that matches the following typedef:
+
+ typedef int (*sudo_hook_fn_unsetenv_t)(const char *name,
+ void *closure);
+
+ SUDO_HOOK_GETENV
+ The C library getenv() function. Any registered hooks will run
+ before the C library implementation. The hook_fn field should
+ be a function that matches the following typedef:
+
+ typedef int (*sudo_hook_fn_getenv_t)(const char *name,
+ char **value, void *closure);
+
+ If the registered hook does not match the typedef the results
+ are unspecified.
+
+ SUDO_HOOK_PUTENV
+ The C library putenv() function. Any registered hooks will run
+ before the C library implementation. The hook_fn field should
+ be a function that matches the following typedef:
+
+ typedef int (*sudo_hook_fn_putenv_t)(char *string,
+ void *closure);
+
+ If the registered hook does not match the typedef the results
+ are unspecified.
+
+ hook_fn
+ sudo_hook_fn_t hook_fn;
+
+ The hook_fn field should be set to the plugin's hook
+ implementation. The actual function arguments will vary depending
+ on the hook_type (see hook_type above). In all cases, the closure
+ field of struct sudo_hook is passed as the last function parameter.
+ This can be used to pass arbitrary data to the plugin's hook
+ implementation.
+
+ The function return value may be one of the following:
+
+ SUDO_HOOK_RET_ERROR
+ The hook function encountered an error.
+
+ SUDO_HOOK_RET_NEXT
+ The hook completed without error, go on to the next hook
+ (including the native implementation if applicable). For
+ example, a getenv hook might return SUDO_HOOK_RET_NEXT if the
+ specified variable was not found in the private copy of the
+ environment.
+
+ SUDO_HOOK_RET_STOP
+ The hook completed without error, stop processing hooks for
+ this invocation. This can be used to replace the native
+ implementation. For example, a setenv hook that operates on a
+ private copy of the environment but leaves environ unchanged.
+
+ Note that it is very easy to create an infinite loop when hooking C
+ library functions. For example, a getenv hook that calls the snprintf
+ function may create a loop if the snprintf implementation calls getenv
+ to check the locale. To prevent this, you may wish to use a static
+ variable in the hook function to guard against nested calls. E.g.
+
+ static int in_progress = 0; /* avoid recursion */
+ if (in_progress)
+ return SUDO_HOOK_RET_NEXT;
+ in_progress = 1;
+ ...
+ in_progress = 0;
+ return SUDO_HOOK_RET_STOP;
+
+ _\bH_\bo_\bo_\bk _\bA_\bP_\bI _\bV_\be_\br_\bs_\bi_\bo_\bn _\bM_\ba_\bc_\br_\bo_\bs
+
+ /* Hook API version major/minor */
+ #define SUDO_HOOK_VERSION_MAJOR 1
+ #define SUDO_HOOK_VERSION_MINOR 0
+ #define SUDO_HOOK_MKVERSION(x, y) ((x << 16) | y)
+ #define SUDO_HOOK_VERSION SUDO_HOOK_MKVERSION(SUDO_HOOK_VERSION_MAJOR,\
+ SUDO_HOOK_VERSION_MINOR)
+
+ /* Getters and setters for hook API version */
+ #define SUDO_HOOK_VERSION_GET_MAJOR(v) ((v) >> 16)
+ #define SUDO_HOOK_VERSION_GET_MINOR(v) ((v) & 0xffff)
+ #define SUDO_HOOK_VERSION_SET_MAJOR(vp, n) do { \
+ *(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \
+ } while(0)
+ #define SUDO_HOOK_VERSION_SET_MINOR(vp, n) do { \
+ *(vp) = (*(vp) & 0xffff0000) | (n); \
+ } while(0)
+
C\bCo\bon\bnv\bve\ber\brs\bsa\bat\bti\bio\bon\bn A\bAP\bPI\bI
If the plugin needs to interact with the user, it may do so via the
conversation function. A plugin should not attempt to read directly
#define SUDO_CONV_ERROR_MSG 0x0003 /* error message */
#define SUDO_CONV_INFO_MSG 0x0004 /* informational message */
#define SUDO_CONV_PROMPT_MASK 0x0005 /* mask user input */
+ #define SUDO_CONV_DEBUG_MSG 0x0006 /* debugging message */
#define SUDO_CONV_PROMPT_ECHO_OK 0x1000 /* flag: allow echo if no tty */
int msg_type;
int timeout;
buffer filled in to the struct sudo_conv_reply, if any.
The printf-style function uses the same underlying mechanism as the
- conversation function but only supports SUDO_CONV_INFO_MSG and
- SUDO_CONV_ERROR_MSG for the _\bm_\bs_\bg_\b__\bt_\by_\bp_\be parameter. It can be more
- convenient than using the conversation function if no user reply is
- needed and supports standard _\bp_\br_\bi_\bn_\bt_\bf_\b(_\b) escape sequences.
+ conversation function but only supports SUDO_CONV_INFO_MSG,
+ SUDO_CONV_ERROR_MSG and SUDO_CONV_DEBUG_MSG for the _\bm_\bs_\bg_\b__\bt_\by_\bp_\be parameter.
+ It can be more convenient than using the conversation function if no
+ user reply is needed and supports standard _\bp_\br_\bi_\bn_\bt_\bf_\b(_\b) escape sequences.
+
+ Unlike, SUDO_CONV_INFO_MSG and SUDO_CONV_ERROR_MSG, messages sent with
+ the <SUDO_CONV_DEBUG_MSG> _\bm_\bs_\bg_\b__\bt_\by_\bp_\be are not directly user-visible.
+ Instead, they are logged to the file specified in the Debug statement
+ (if any) in the _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\b._\bc_\bo_\bn_\bf file. This allows a plugin to log
+ debugging information and is intended to be used in conjunction with
+ the _\bd_\be_\bb_\bu_\bg_\b__\bf_\bl_\ba_\bg_\bs setting.
See the sample plugin for an example of the conversation function
usage.
pwd The password database entry for _\bu_\bs_\be_\br, if any. If _\bu_\bs_\be_\br is not
present in the password database, _\bp_\bw_\bd will be NULL.
- _\bV_\be_\br_\bs_\bi_\bo_\bn _\bM_\ba_\bc_\br_\bo_\bs
+ _\bG_\br_\bo_\bu_\bp _\bA_\bP_\bI _\bV_\be_\br_\bs_\bi_\bo_\bn _\bM_\ba_\bc_\br_\bo_\bs
/* Sudoers group plugin version major/minor */
#define GROUP_API_VERSION_MAJOR 1
*(vp) = (*(vp) & 0xffff0000) | (n); \
} while(0)
+P\bPL\bLU\bUG\bGI\bIN\bN A\bAP\bPI\bI C\bCH\bHA\bAN\bNG\bGE\bEL\bLO\bOG\bG
+ The following revisions have been made to the Sudo Plugin API.
+
+ Version 1.0
+ Initial API version.
+
+ Version 1.1
+ The I/O logging plugin's open function was modified to take the
+ command_info list as an argument.
+
+ Version 1.2
+ The Policy and I/O logging plugins' open functions are now passed a
+ list of plugin options if any are specified in _\b/_\be_\bt_\bc_\b/_\bs_\bu_\bd_\bo_\b._\bc_\bo_\bn_\bf.
+
+ A simple hooks API has been introduced to allow plugins to hook in
+ to the system's environment handling functions.
+
+ The init_session Policy plugin function is now passed a pointer to
+ the user environment which can be updated as needed. This can be
+ used to merge in environment variables stored in the PAM handle
+ before a command is run.
+
S\bSE\bEE\bE A\bAL\bLS\bSO\bO
_\bs_\bu_\bd_\bo_\be_\br_\bs(4), _\bs_\bu_\bd_\bo(1m)
-1.8.2 May 22, 2011 SUDO_PLUGIN(1m)
+1.8.5 April 23, 2012 SUDO_PLUGIN(1m)