From: Todd C. Miller Date: Mon, 22 Feb 2010 02:24:20 +0000 (-0500) Subject: Rename plugin.pod -> sudo_plugin.pod and wire into Makefile X-Git-Tag: SUDO_1_8_0~870 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bcd021da5e3399d9c686ed231695245dbc371ecc;p=sudo Rename plugin.pod -> sudo_plugin.pod and wire into Makefile --- diff --git a/doc/Makefile.in b/doc/Makefile.in index 7ecc08f18..37fa1d7f0 100644 --- a/doc/Makefile.in +++ b/doc/Makefile.in @@ -50,7 +50,7 @@ install_gid = 0 SHELL = /bin/sh DOCS = sudo.man visudo.man sudoers.man sudoers.ldap.man sudoers.man \ - sudoreplay.man + sudoreplay.man sudo_plugin.man VERSION = @PACKAGE_VERSION@ @@ -106,7 +106,16 @@ sudoreplay.man.in: $(srcdir)/sudoreplay.pod sudoreplay.man:: sudoreplay.man.in CONFIG_FILES=$@ CONFIG_HEADERS= sh $(top_builddir)/config.status -sudoers.cat: sudoers.man +sudoreplay.cat: sudoreplay.man + +sudo_plugin.man.in: $(srcdir)/sudo_plugin.pod + @rm -f $(srcdir)/$@ + ( cd $(srcdir); mansectsu=`echo @MANSECTSU@|tr A-Z a-z`; mansectform=`echo @MANSECTFORM@|tr A-Z a-z`; sed -n -e '/^=pod/q' -e 's/^/.\\" /p' sudo_plugin.pod > $@; pod2man --quotes=none --date="`date '+%B %e, %Y'`" --section=$$mansectsu --release=$(VERSION) --center="MAINTENANCE COMMANDS" sudo_plugin.pod | sed -e "s/(5)/($$mansectform)/" -e "s/(8)/($$mansectsu)/" -e 's|\\fI\\f\((CW*\)*I@\([^@]*\)\\fI@|\\fI@\2@|g' >> $@ ) + +sudo_plugin.man:: sudo_plugin.man.in + CONFIG_FILES=$@ CONFIG_HEADERS= sh $(top_builddir)/config.status + +sudo_plugin.cat: sudo_plugin.man @DEV@HISTORY: history.pod @DEV@ pod2text -l -i0 $> > $@ diff --git a/doc/sudo_plugin.cat b/doc/sudo_plugin.cat new file mode 100644 index 000000000..092be6ebf --- /dev/null +++ b/doc/sudo_plugin.cat @@ -0,0 +1,792 @@ + + + +SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m) + + +SSuuddoo PPlluuggiinn AAPPII + Starting with version 1.8, ssuuddoo supports a plugin API for policy and + session logging. By default, the _s_u_d_o_e_r_s policy plugin and an + associated I/O logging plugin are used. Via the plugin API, ssuuddoo can + be configured to use alternate policy and/or I/O logging plugins + provided by third parties. The plugins to be used are specified via + the _/_e_t_c_/_s_u_d_o_._c_o_n_f file. + + The API is versioned with a major and minor number. The minor version + number is incremented when additions are made. The major number is + incremented when incompatible changes are made. A plugin should be + check the version passed to it and make sure that the major version + matches. + + The plugin API is defined by the sudo_plugin.h header file. + + TThhee ssuuddoo..ccoonnff FFiillee + The _/_e_t_c_/_s_u_d_o_._c_o_n_f file contains plugin configuration directives. + Currently, the only supported keyword is the Plugin directive, which + causes a plugin plugin to be loaded. + + A Plugin line consists of the Plugin keyword, followed by the + _s_y_m_b_o_l___n_a_m_e and the _p_a_t_h to the shared object containing the plugin. + The _s_y_m_b_o_l___n_a_m_e is the name of the struct policy_plugin or struct + io_plugin in the plugin shared object. The _p_a_t_h may be fully qualified + or relative. If not fully qualified it is relative to the + $prefix/libexec directory where the prefix is specified at build time + (/usr/local by default). + + The same shared object may contain multiple plugins, each with a + different symbol name. The shared object file must be owned by uid 0 + and only writable by its owner. Because of ambiguities that arise from + composite policies, only a single policy plugin may be specified. This + limitation does not apply to I/O plugins. + + # + # Default /etc/sudo.conf file + # + # Format: + # Plugin plugin_name plugin_path + # + # The plugin_path relative to prefix/libexec unless fully qualified + # The plugin_name corresponds to a global symbol in the plugin + # that contains the plugin interface. + # + Plugin policy_plugin sudoers.so + Plugin io_plugin sudoers.so + + PPoolliiccyy PPlluuggiinn AAPPII + A policy plugin must declare and populate a policy_plugin struct in the + global scope. This structure contains pointers to the functions that + implement the ssuuddoo policy checks. The name of the symbol should be + specified in _/_e_t_c_/_s_u_d_o_._c_o_n_f along with a path to the plugin so that + ssuuddoo can load it. + + + +1.8.0a1 February 21, 2010 1 + + + + + +SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m) + + + struct policy_plugin { + #define SUDO_POLICY_PLUGIN 1 + unsigned int type; /* always SUDO_POLICY_PLUGIN */ + unsigned int version; /* always SUDO_API_VERSION */ + int (*open)(unsigned int version, sudo_conv_t conversation, + char * const settings[], char * const user_info[], + char * const user_env[]); + void (*close)(int exit_status, int error); + int (*show_version)(int verbose); + int (*check_policy)(int agrc, char * const argv[], + char *env_add[], char **command_info[], + char **argv_out[], char **user_env_out[]); + int (*list)(int argc, char * const argv[], int verbose, + const char *list_user); + int (*validate)(void); + void (*invalidate)(int remove); + }; + + The policy_plugin struct has the following fields: + + type + The type field should always be set to SUDO_POLICY_PLUGIN + + version + The version field should be set to SUDO_API_VERSION. + + This allows ssuuddoo to determine the API version the plugin was built + against. + + open + int (*open)(unsigned int version, sudo_conv_t conversation, + char * const settings[], char * const user_info[], + char * const user_env[]); + + Returns 1 on success, 0 on failure and -1 on error. On error, the + plugin may optionally call the conversation function with + SUDO_CONF_ERROR_MSG to present additional error information to the + user. + + The function arguments are as follows: + + version + The version passed in by ssuuddoo allows the plugin to determine + the major and minor version number of the plugin API supported + by ssuuddoo. + + conversation + A pointer to the conversation function that can be used by the + plugin to interact with the user (see below). + + settings + A vector of user-supplied ssuuddoo settings in the form of + "name=value" strings. The vector is terminated by a NULL + pointer. These settings correspond to flags the user specified + + + +1.8.0a1 February 21, 2010 2 + + + + + +SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m) + + + when running ssuuddoo. As such, they will only be present when the + corresponding flag has been specified on the command line. + + When parsing _s_e_t_t_i_n_g_s, the plugin should split on the ffiirrsstt + equal sign ('=') since the _n_a_m_e field will never include one + itself but the _v_a_l_u_e might. + + runas_user=string + The user name or uid to to run the command as, if specified + via the -u flag. + + runas_group=string + The group name or gid to to run the command as, if + specified via the -g flag. + + prompt=string + The prompt to use when requesting a password, if specified + via the -p flag. + + set_home=bool + Set to true if the user specified the -H flag. If true, + set the HOME environment variable to the target user's home + directory. + + preserve_environment=bool + Set to true if the user specified the -E flag, indicating + that the user wishes to preserve the environment. + + login_shell=bool + Set to true if the user specified the -i flag, indicating + that the user wishes to run a login shell. + + preserve_groups=bool + Set to true if the user specified the -P flag, indicating + that the user wishes to preserve the group vector instead + of setting it based on the runas user. + + ignore_ticket=bool + Set to true if the user specified the -k flag along with a + command, indicating that the user wishes to ignore any + cached authentication credentials. + + login_class=string + BSD login class to use when setting resource limits and + nice value, if specified by the -c flag. + + selinux_role=string + SELinux role to use when executing the command, if + specified by the -r flag. + + selinux_type=string + SELinux type to use when executing the command, if + specified by the -t flag. + + + + +1.8.0a1 February 21, 2010 3 + + + + + +SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m) + + + bsdauth_type=string + Authentication type, if specified by the -a flag, to use on + systems where BSD authentication is supported. + + Additional settings may be added in the future so the plugin + should silently ignore settings that it does not recognize. + + user_info + A vector of information about the user running the command in + the form of "name=value" strings. The vector is terminated by + a NULL pointer. + + When parsing _u_s_e_r___i_n_f_o, the plugin should split on the ffiirrsstt + equal sign ('=') since the _n_a_m_e field will never include one + itself but the _v_a_l_u_e might. + + user=string + The name of the user invoking ssuuddoo. + + uid=uid_t + The real user ID of the user invoking ssuuddoo. + + gid=gid_t + The real group ID of the user invoking ssuuddoo. + + groups=list + The user's supplementary group list formatted as a string + of comma-separated group IDs. + + cwd=string + The user's current working directory. + + tty=string + The path to the user's terminal device. If the user has no + terminal device associated with the session, the value will + be empty, as in tty=. + + host=string + The local machine's hostname as returned by the + gethostname() system call. + + user_env + The user's environment in the form of a NULL-terminated vector + of "name=value" strings. + + When parsing _u_s_e_r___e_n_v, the plugin should split on the ffiirrsstt + equal sign ('=') since the _n_a_m_e field will never include one + itself but the _v_a_l_u_e might. + + close + void (*close)(int exit_status, int error); + + The close function is called when the command being run by ssuuddoo + finishes. + + + +1.8.0a1 February 21, 2010 4 + + + + + +SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m) + + + The function arguments are as follows: + + exit_status + The command's exit status, as returned by the _w_a_i_t(2) system + call. The value of exit_status is undefined if error is non- + zero. + + error + If the command could not be executed, this is set to the value + of errno set by the _e_x_e_c_v_e(2) system call. The plugin is + responsible for displaying error information via the + conversation function. If the command was successfully + executed, the value of error is 0. + + show_version + int (*show_version)(int verbose); + + The show_version function is called by ssuuddoo when the user specifies + the -V option. The plugin may display its version information to + the user via the conversation function using SUDO_CONV_INFO_MSG. + If the user requests detailed version information, the verbose flag + will be set. + + check_policy + int (*check_policy)(int argc, char * const argv[] + char *env_add[], char **command_info[], + char **argv_out[], char **user_env_out[]); + + The _c_h_e_c_k___p_o_l_i_c_y function is called by ssuuddoo to determine whether + the user is allowed to run the specified commands. Returns 1 if + the command is allowed, 0 if not and -1 on error. On error, the + plugin may optionally call the conversation function with + SUDO_CONF_ERROR_MSG to present additional error information to the + user. + + The function arguments are as follows: + + argc + The number of elements in _a_r_g_v, not counting the final NULL + pointer. + + argv + The argument vector describing the command the user wishes to + run, in the same form as what would be passed to the _e_x_e_c_v_e_(_) + system call. The vector is terminated by a NULL pointer. + + env_add + Additional environment variables specified by the user on the + command line in the form of a NULL-terminated vector of + "name=value" strings. The plugin may reject the command if one + or more variables are not allowed to be set, or it may silently + ignore such variables. + + When parsing _e_n_v___a_d_d, the plugin should split on the ffiirrsstt + + + +1.8.0a1 February 21, 2010 5 + + + + + +SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m) + + + equal sign ('=') since the _n_a_m_e field will never include one + itself but the _v_a_l_u_e might. + + command_info + Information about the command being run in the form of + "name=value" strings. These values are used by ssuuddoo to set the + execution environment when running a command. The plugin is + responsible for creating and populating the vector, which must + be terminated with a NULL pointer. The following values are + recognized by ssuuddoo: + + command=string + Fully qualified path to the command to be executed. + + runas_uid=uid + User ID to run the command as. + + runas_euid=uid + Effective user ID to run the command as. If not specified, + the value of _r_u_n_a_s___u_i_d is used. + + runas_gid=gid + Group ID to run the command as. + + runas_egid=gid + Effective group ID to run the command as. If not + specified, the value of _r_u_n_a_s___g_i_d is used. + + runas_groups=list + The supplementary group vector to use for the command in + the form of a comma-separated list of group IDs. If + _p_r_e_s_e_r_v_e___g_r_o_u_p_s is set, this option is ignored. + + login_class=login_class + BSD login class to use when setting resource limits and + nice value (optional). This option is only set on systems + that support login classes. + + preserve_groups=bool + If set, ssuuddoo will preserve the user's group vector instead + of initializing the group vector based on runas_user. + + cwd=string + The current working directory to change to when executing + the command. + + noexec=bool + If set, prevent the command from executing other programs. + + chroot=string + The root directory to use when running the command. + + nice=int + Nice value (priority) to use when executing the command. + + + +1.8.0a1 February 21, 2010 6 + + + + + +SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m) + + + The nice value, if specified, overrides the priority + associated with the _l_o_g_i_n___c_l_a_s_s on BSD systems. + + umask=octal + The file creation mask to use when executing the command. + + selinux_role=string + SELinux role to use when executing the command. + + selinux_type=string + SELinux type to use when executing the command. + + timeout=int + Command timeout. If non-zero then when the timeout expires + the command will be killed. + + Unsupported values will be ignored. + + argv_out + The NULL-terminated argument vector to pass to the _e_x_e_c_v_e_(_) + system call when executing the command. The plugin is + responsible for allocating and populating the vector. + + user_env_out + The NULL-terminated environment vector to use when executing + the command. The plugin is responsible for allocating and + populating the vector. + + list + int (*list)(int verbose, const char *list_user, + int argc, char * const argv[]); + + List available privileges for the invoking user. Returns 1 on + success, 0 on failure and -1 on error. On error, the plugin may + optionally call the conversation function with SUDO_CONF_ERROR_MSG + to present additional error information to the user. + + Privileges should be output via the conversation function using + SUDO_CONV_INFO_MSG. + + verbose + Flag indicating whether to list in verbose mode or not. + + list_user + The name of a different user to list privileges for if the + policy allows it. If NULL, the plugin should list the + privileges of the invoking user. + + argc + The number of elements in _a_r_g_v, not counting the final NULL + pointer. + + argv + If non-NULL, an argument vector describing a command the user + + + +1.8.0a1 February 21, 2010 7 + + + + + +SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m) + + + wishes to check against the policy in the same form as what + would be passed to the _e_x_e_c_v_e_(_) system call. If the command is + permitted by the policy, the fully-qualified path to the + command should be displayed along with any command line + arguments. + + validate + int (*validate)(void); + + The validate function is called when ssuuddoo is run with the -v flag. + For policy plugins such as _s_u_d_o_e_r_s that cache authentication + credentials, this function will validate and cache the credentials. + + The validate function should be NULL if the plugin does not support + credential caching. + + Returns 1 on success, 0 on failure and -1 on error. On error, the + plugin may optionally call the conversation function with + SUDO_CONF_ERROR_MSG to present additional error information to the + user. + + invalidate + void (*invalidate)(int remove); + + The invalidate function is called when ssuuddoo is called with the -k + or -K flag. For policy plugins such as _s_u_d_o_e_r_s that cache + authentication credentials, this function will invalidate the + credentials. If the _r_e_m_o_v_e flag is set, the plugin may remove the + credentials instead of simply invalidating them. + + The invalidate function should be NULL if the plugin does not + support credential caching. + + _C_o_n_v_e_r_s_a_t_i_o_n _A_P_I + + If the plugin needs to interact with the user or display informational + or error messages, it may do so via the conversation function. A + plugin should not attempt to read directly from the standard input or + the user's tty. + + struct sudo_conv_message { + #define SUDO_CONV_PROMPT_ECHO_OFF 1 + #define SUDO_CONV_PROMPT_ECHO_ON 2 + #define SUDO_CONV_ERROR_MSG 3 + #define SUDO_CONV_INFO_MSG 4 + int msg_type; + int timeout; + const char *msg; + }; + + struct sudo_conv_reply { + char *reply; + }; + + + + +1.8.0a1 February 21, 2010 8 + + + + + +SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m) + + + typedef int (*sudo_conv_t)(int num_msgs, + const struct sudo_conv_message msgs[], + struct sudo_conv_reply replies[]); + + A conversation function is passed in to the plugin's open function when + the plugin is initialized. The plugin passes in a struct + sudo_conv_message and struct sudo_conv_reply for each message in the + conversation. The plugin is responsible for freeing the actual reply + buffer in struct sudo_conv_reply. + + See the sample plugin for an example of the conversation function + usage. + + II//OO PPlluuggiinn AAPPII + struct io_plugin { + #define SUDO_IO_PLUGIN 2 + unsigned int type; /* always SUDO_IO_PLUGIN */ + unsigned int version; /* always SUDO_API_VERSION */ + int (*open)(unsigned int version, sudo_conv_t conversation + char * const settings[], char * const user_info[], + char * const user_env[]); + void (*close)(int exit_status, int error); /* wait status or error */ + int (*show_version)(int verbose); + int (*log_input)(const char *buf, unsigned int len); + int (*log_output)(const char *buf, unsigned int len); + }; + + When an I/O plugin is loaded, ssuuddoo runs the command in a pseudo-tty. + This makes it possible to log the input and output from the user's + session. If the log_input function is defined, it will receive the raw + user input (note that this will include input even when echo is + disabled, such as passwords). The log_output function receives output + from the pseudo-tty that is suitable for replaying the user's session + at a later time. Either log_input or log_output may be NULL. If the + open function returns 0, no I/O will be sent to the plugin. + + The io_plugin struct has the following fields: + + type + The type field should always be set to SUDO_IO_PLUGIN + + version + The version field should be set to SUDO_API_VERSION. + + This allows ssuuddoo to determine the API version the plugin was built + against. + + open + int (*open)(unsigned int version, sudo_conv_t conversation + char * const settings[], char * const user_info[], + char * const user_env[]); + + Returns 1 on success, 0 if the command should not be logged and -1 + on error. On error, the plugin may optionally call the + + + +1.8.0a1 February 21, 2010 9 + + + + + +SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m) + + + conversation function with SUDO_CONF_ERROR_MSG to present + additional error information to the user. + + The function arguments are as follows: + + version + The version passed in by ssuuddoo allows the plugin to determine + the major and minor version number of the plugin API supported + by ssuuddoo. + + conversation + A pointer to the conversation function that may be used by the + _s_h_o_w___v_e_r_s_i_o_n function to display version information (see + show_version below). The conversation function may also be + used to display additional error message to the user. + + settings + A vector of user-supplied ssuuddoo settings in the form of + "name=value" strings. The vector is terminated by a NULL + pointer. These settings correspond to flags the user specified + when running ssuuddoo. As such, they will only be present when the + corresponding flag has been specified on the command line. + + When parsing _s_e_t_t_i_n_g_s, the plugin should split on the ffiirrsstt + equal sign ('=') since the _n_a_m_e field will never include one + itself but the _v_a_l_u_e might. + + See the "Policy Plugin API" section for a list of all possible + settings. + + user_info + A vector of information about the user running the command in + the form of "name=value" strings. The vector is terminated by + a NULL pointer. + + When parsing _u_s_e_r___i_n_f_o, the plugin should split on the ffiirrsstt + equal sign ('=') since the _n_a_m_e field will never include one + itself but the _v_a_l_u_e might. + + See the "Policy Plugin API" section for a list of all possible + strings. + + user_env + The user's environment in the form of a NULL-terminated vector + of "name=value" strings. + + When parsing _u_s_e_r___e_n_v, the plugin should split on the ffiirrsstt + equal sign ('=') since the _n_a_m_e field will never include one + itself but the _v_a_l_u_e might. + + close + void (*close)(int exit_status, int error); + + The close function is called when the command being run by ssuuddoo + + + +1.8.0a1 February 21, 2010 10 + + + + + +SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m) + + + finishes. + + The function arguments are as follows: + + exit_status + The command's exit status, as returned by the _w_a_i_t(2) system + call. The value of exit_status is undefined if error is non- + zero. + + error + If the command could not be executed, this is set to the value + of errno set by the _e_x_e_c_v_e(2) system call. If the command was + successfully executed, the value of error is 0. + + show_version + int (*show_version)(int verbose); + + The show_version function is called by ssuuddoo when the user specifies + the -V option. The plugin may display its version information to + the user via the conversation function using SUDO_CONV_INFO_MSG. + If the user requests detailed version information, the verbose flag + will be set. + + log_input + int (*log_input)(const char *buf, unsigned int len); + + The _l_o_g___i_n_p_u_t function is called whenever data can be read from the + user but before it is passed to the running command. This allows + the plugin to reject data if it chooses to (for instance if the + input contains banned content). Returns 1 if the data should be + passed to the command, 0 if the data is rejected (which will + terminate the command) or -1 if an error occurred. + + The function arguments are as follows: + + buf The buffer containing user input. + + len The length of _b_u_f in bytes. + + log_output + int (*log_output)(const char *buf, unsigned int len); + + The _l_o_g___o_u_t_p_u_t function is called whenever data can be read from + the command but before it is written to the user's terminal. This + allows the plugin to reject data if it chooses to (for instance if + the input contains banned content). Returns 1 if the data should + be passed to the user, 0 if the data is rejected (which will + terminate the command) or -1 if an error occurred. + + The function arguments are as follows: + + buf The buffer containing command output. + + len The length of _b_u_f in bytes. + + + +1.8.0a1 February 21, 2010 11 + + + + + +SUDO_PLUGIN(1m) MAINTENANCE COMMANDS SUDO_PLUGIN(1m) + + + UUnnhhaannddlleedd ccoommmmaanndd lliinnee ooppttiioonnss + The -L command line option has been deprecated as its output is covered + by the _s_u_d_o_e_r_s manual page. + + SSuuddoo iimmpplleemmeennttaattiioonn ddeettaaiillss + Version macros: + + #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) & 0x0000ffff) | ((n) << 16); \ + } while(0) + #define SUDO_VERSION_SET_MINOR(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) + + Sudo will cast the plugin symbol to the following when determining the + plugin type. + + union sudo_plugin { + struct policy_plugin policy; + struct io_plugin io; + }; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +1.8.0a1 February 21, 2010 12 + + diff --git a/doc/sudo_plugin.man.in b/doc/sudo_plugin.man.in new file mode 100644 index 000000000..10c17831c --- /dev/null +++ b/doc/sudo_plugin.man.in @@ -0,0 +1,831 @@ +.\" Automatically generated by Pod::Man 2.22 (Pod::Simple 3.07) +.\" +.\" Standard preamble: +.\" ======================================================================== +.de Sp \" Vertical space (when we can't use .PP) +.if t .sp .5v +.if n .sp +.. +.de Vb \" Begin verbatim text +.ft CW +.nf +.ne \\$1 +.. +.de Ve \" End verbatim text +.ft R +.fi +.. +.\" Set up some character translations and predefined strings. \*(-- will +.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left +.\" double quote, and \*(R" will give a right double quote. \*(C+ will +.\" give a nicer C++. Capital omega is used to do unbreakable dashes and +.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, +.\" nothing in troff, for use with C<>. +.tr \(*W- +.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' +.ie n \{\ +. ds -- \(*W- +. ds PI pi +. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch +. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch +. ds L" "" +. ds R" "" +. ds C` +. ds C' +'br\} +.el\{\ +. ds -- \|\(em\| +. ds PI \(*p +. ds L" `` +. ds R" '' +'br\} +.\" +.\" Escape single quotes in literal strings from groff's Unicode transform. +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" +.\" If the F register is turned on, we'll generate index entries on stderr for +.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index +.\" entries marked with X<> in POD. Of course, you'll have to process the +.\" output yourself in some meaningful fashion. +.ie \nF \{\ +. de IX +. tm Index:\\$1\t\\n%\t"\\$2" +.. +. nr % 0 +. rr F +.\} +.el \{\ +. de IX +.. +.\} +.\" +.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). +.\" Fear. Run. Save yourself. No user-serviceable parts. +. \" fudge factors for nroff and troff +.if n \{\ +. ds #H 0 +. ds #V .8m +. ds #F .3m +. ds #[ \f1 +. ds #] \fP +.\} +.if t \{\ +. ds #H ((1u-(\\\\n(.fu%2u))*.13m) +. ds #V .6m +. ds #F 0 +. ds #[ \& +. ds #] \& +.\} +. \" simple accents for nroff and troff +.if n \{\ +. ds ' \& +. ds ` \& +. ds ^ \& +. ds , \& +. ds ~ ~ +. ds / +.\} +.if t \{\ +. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" +. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' +. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' +. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' +. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' +. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' +.\} +. \" troff and (daisy-wheel) nroff accents +.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' +.ds 8 \h'\*(#H'\(*b\h'-\*(#H' +.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] +.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' +.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' +.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] +.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] +.ds ae a\h'-(\w'a'u*4/10)'e +.ds Ae A\h'-(\w'A'u*4/10)'E +. \" corrections for vroff +.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' +.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' +. \" for low resolution devices (crt and lpr) +.if \n(.H>23 .if \n(.V>19 \ +\{\ +. ds : e +. ds 8 ss +. ds o a +. ds d- d\h'-1'\(ga +. ds D- D\h'-1'\(hy +. ds th \o'bp' +. ds Th \o'LP' +. ds ae ae +. ds Ae AE +.\} +.rm #[ #] #H #V #F C +.\" ======================================================================== +.\" +.IX Title "SUDO_PLUGIN @mansectsu@" +.TH SUDO_PLUGIN @mansectsu@ "February 21, 2010" "1.8.0a1" "MAINTENANCE COMMANDS" +.\" For nroff, turn off justification. Always turn off hyphenation; it makes +.\" way too many mistakes in technical documents. +.if n .ad l +.nh +.SH "Sudo Plugin API" +.IX Header "Sudo Plugin API" +Starting with version 1.8, \fBsudo\fR supports a plugin \s-1API\s0 +for policy and session logging. By default, the \fIsudoers\fR policy +plugin and an associated I/O logging plugin are used. Via the plugin +\&\s-1API\s0, \fBsudo\fR can be configured to use alternate policy and/or I/O +logging plugins provided by third parties. The plugins to be used +are specified via the \fI/etc/sudo.conf\fR file. +.PP +The \s-1API\s0 is versioned with a major and minor number. The minor +version number is incremented when additions are made. The major +number is incremented when incompatible changes are made. A plugin +should be check the version passed to it and make sure that the +major version matches. +.PP +The plugin \s-1API\s0 is defined by the \f(CW\*(C`sudo_plugin.h\*(C'\fR header file. +.SS "The sudo.conf File" +.IX Subsection "The sudo.conf File" +The \fI/etc/sudo.conf\fR file contains plugin configuration directives. +Currently, the only supported keyword is the \f(CW\*(C`Plugin\*(C'\fR directive, +which causes a plugin plugin to be loaded. +.PP +A \f(CW\*(C`Plugin\*(C'\fR line consists of the \f(CW\*(C`Plugin\*(C'\fR keyword, followed by the +\&\fIsymbol_name\fR and the \fIpath\fR to the shared object containing the +plugin. The \fIsymbol_name\fR is the name of the \f(CW\*(C`struct policy_plugin\*(C'\fR +or \f(CW\*(C`struct io_plugin\*(C'\fR in the plugin shared object. The \fIpath\fR +may be fully qualified or relative. If not fully qualified it is +relative to the \f(CW$prefix\fR/libexec directory where the prefix is +specified at build time (/usr/local by default). +.PP +The same shared object may contain multiple plugins, each with a +different symbol name. The shared object file must be owned by uid +0 and only writable by its owner. Because of ambiguities that arise +from composite policies, only a single policy plugin may be specified. +This limitation does not apply to I/O plugins. +.PP +.Vb 12 +\& # +\& # Default /etc/sudo.conf file +\& # +\& # Format: +\& # Plugin plugin_name plugin_path +\& # +\& # The plugin_path relative to prefix/libexec unless fully qualified +\& # The plugin_name corresponds to a global symbol in the plugin +\& # that contains the plugin interface. +\& # +\& Plugin policy_plugin sudoers.so +\& Plugin io_plugin sudoers.so +.Ve +.SS "Policy Plugin \s-1API\s0" +.IX Subsection "Policy Plugin API" +A policy plugin must declare and populate a \f(CW\*(C`policy_plugin\*(C'\fR struct +in the global scope. This structure contains pointers to the functions +that implement the \fBsudo\fR policy checks. The name of the symbol should +be specified in \fI/etc/sudo.conf\fR along with a path to the plugin +so that \fBsudo\fR can load it. +.PP +.Vb 10 +\& struct policy_plugin { +\& #define SUDO_POLICY_PLUGIN 1 +\& unsigned int type; /* always SUDO_POLICY_PLUGIN */ +\& unsigned int version; /* always SUDO_API_VERSION */ +\& int (*open)(unsigned int version, sudo_conv_t conversation, +\& char * const settings[], char * const user_info[], +\& char * const user_env[]); +\& void (*close)(int exit_status, int error); +\& int (*show_version)(int verbose); +\& int (*check_policy)(int agrc, char * const argv[], +\& char *env_add[], char **command_info[], +\& char **argv_out[], char **user_env_out[]); +\& int (*list)(int argc, char * const argv[], int verbose, +\& const char *list_user); +\& int (*validate)(void); +\& void (*invalidate)(int remove); +\& }; +.Ve +.PP +The policy_plugin struct has the following fields: +.IP "type" 4 +.IX Item "type" +The \f(CW\*(C`type\*(C'\fR field should always be set to \s-1SUDO_POLICY_PLUGIN\s0 +.IP "version" 4 +.IX Item "version" +The \f(CW\*(C`version\*(C'\fR field should be set to \s-1SUDO_API_VERSION\s0. +.Sp +This allows \fBsudo\fR to determine the \s-1API\s0 version the plugin was +built against. +.IP "open" 4 +.IX Item "open" +.Vb 3 +\& int (*open)(unsigned int version, sudo_conv_t conversation, +\& char * const settings[], char * const user_info[], +\& char * const user_env[]); +.Ve +.Sp +Returns 1 on success, 0 on failure and \-1 on error. +On error, the plugin may optionally call the conversation function with +\&\f(CW\*(C`SUDO_CONF_ERROR_MSG\*(C'\fR to present additional error information to the +user. +.Sp +The function arguments are as follows: +.RS 4 +.IP "version" 4 +.IX Item "version" +The version passed in by \fBsudo\fR allows the plugin to determine the +major and minor version number of the plugin \s-1API\s0 supported by +\&\fBsudo\fR. +.IP "conversation" 4 +.IX Item "conversation" +A pointer to the conversation function that can be used by the +plugin to interact with the user (see below). +.IP "settings" 4 +.IX Item "settings" +A vector of user-supplied \fBsudo\fR settings in the form of \*(L"name=value\*(R" +strings. The vector is terminated by a \f(CW\*(C`NULL\*(C'\fR pointer. These +settings correspond to flags the user specified when running \fBsudo\fR. +As such, they will only be present when the corresponding flag has +been specified on the command line. +.Sp +When parsing \fIsettings\fR, the plugin should split on the \fBfirst\fR +equal sign ('=') since the \fIname\fR field will never include one +itself but the \fIvalue\fR might. +.RS 4 +.IP "runas_user=string" 4 +.IX Item "runas_user=string" +The user name or uid to to run the command as, if specified via the +\&\f(CW\*(C`\-u\*(C'\fR flag. +.IP "runas_group=string" 4 +.IX Item "runas_group=string" +The group name or gid to to run the command as, if specified via +the \f(CW\*(C`\-g\*(C'\fR flag. +.IP "prompt=string" 4 +.IX Item "prompt=string" +The prompt to use when requesting a password, if specified via +the \f(CW\*(C`\-p\*(C'\fR flag. +.IP "set_home=bool" 4 +.IX Item "set_home=bool" +Set to true if the user specified the \f(CW\*(C`\-H\*(C'\fR flag. If true, set the +\&\f(CW\*(C`HOME\*(C'\fR environment variable to the target user's home directory. +.IP "preserve_environment=bool" 4 +.IX Item "preserve_environment=bool" +Set to true if the user specified the \f(CW\*(C`\-E\*(C'\fR flag, indicating that +the user wishes to preserve the environment. +.IP "login_shell=bool" 4 +.IX Item "login_shell=bool" +Set to true if the user specified the \f(CW\*(C`\-i\*(C'\fR flag, indicating that +the user wishes to run a login shell. +.IP "preserve_groups=bool" 4 +.IX Item "preserve_groups=bool" +Set to true if the user specified the \f(CW\*(C`\-P\*(C'\fR flag, indicating that +the user wishes to preserve the group vector instead of setting it +based on the runas user. +.IP "ignore_ticket=bool" 4 +.IX Item "ignore_ticket=bool" +Set to true if the user specified the \f(CW\*(C`\-k\*(C'\fR flag along with a +command, indicating that the user wishes to ignore any cached +authentication credentials. +.IP "login_class=string" 4 +.IX Item "login_class=string" +\&\s-1BSD\s0 login class to use when setting resource limits and nice value, +if specified by the \f(CW\*(C`\-c\*(C'\fR flag. +.IP "selinux_role=string" 4 +.IX Item "selinux_role=string" +SELinux role to use when executing the command, if specified by +the \f(CW\*(C`\-r\*(C'\fR flag. +.IP "selinux_type=string" 4 +.IX Item "selinux_type=string" +SELinux type to use when executing the command, if specified by +the \f(CW\*(C`\-t\*(C'\fR flag. +.IP "bsdauth_type=string" 4 +.IX Item "bsdauth_type=string" +Authentication type, if specified by the \f(CW\*(C`\-a\*(C'\fR flag, to use on +systems where \s-1BSD\s0 authentication is supported. +.RE +.RS 4 +.Sp +Additional settings may be added in the future so the plugin should +silently ignore settings that it does not recognize. +.RE +.IP "user_info" 4 +.IX Item "user_info" +A vector of information about the user running the command in the form of +\&\*(L"name=value\*(R" strings. The vector is terminated by a \f(CW\*(C`NULL\*(C'\fR pointer. +.Sp +When parsing \fIuser_info\fR, the plugin should split on the \fBfirst\fR +equal sign ('=') since the \fIname\fR field will never include one +itself but the \fIvalue\fR might. +.RS 4 +.IP "user=string" 4 +.IX Item "user=string" +The name of the user invoking \fBsudo\fR. +.IP "uid=uid_t" 4 +.IX Item "uid=uid_t" +The real user \s-1ID\s0 of the user invoking \fBsudo\fR. +.IP "gid=gid_t" 4 +.IX Item "gid=gid_t" +The real group \s-1ID\s0 of the user invoking \fBsudo\fR. +.IP "groups=list" 4 +.IX Item "groups=list" +The user's supplementary group list formatted as a string of +comma-separated group IDs. +.IP "cwd=string" 4 +.IX Item "cwd=string" +The user's current working directory. +.IP "tty=string" 4 +.IX Item "tty=string" +The path to the user's terminal device. If the user has no terminal +device associated with the session, the value will be empty, as in +\&\f(CW\*(C`tty=\*(C'\fR. +.IP "host=string" 4 +.IX Item "host=string" +The local machine's hostname as returned by the \f(CW\*(C`gethostname()\*(C'\fR +system call. +.RE +.RS 4 +.RE +.IP "user_env" 4 +.IX Item "user_env" +The user's environment in the form of a \f(CW\*(C`NULL\*(C'\fR\-terminated vector of +\&\*(L"name=value\*(R" strings. +.Sp +When parsing \fIuser_env\fR, the plugin should split on the \fBfirst\fR +equal sign ('=') since the \fIname\fR field will never include one +itself but the \fIvalue\fR might. +.RE +.RS 4 +.RE +.IP "close" 4 +.IX Item "close" +.Vb 1 +\& void (*close)(int exit_status, int error); +.Ve +.Sp +The \f(CW\*(C`close\*(C'\fR function is called when the command being run by \fBsudo\fR +finishes. +.Sp +The function arguments are as follows: +.RS 4 +.IP "exit_status" 4 +.IX Item "exit_status" +The command's exit status, as returned by the \fIwait\fR\|(2) system call. +The value of \f(CW\*(C`exit_status\*(C'\fR is undefined if \f(CW\*(C`error\*(C'\fR is non-zero. +.IP "error" 4 +.IX Item "error" +If the command could not be executed, this is set to the value of +\&\f(CW\*(C`errno\*(C'\fR set by the \fIexecve\fR\|(2) system call. The plugin is responsible +for displaying error information via the conversation function. If +the command was successfully executed, the value of \f(CW\*(C`error\*(C'\fR is 0. +.RE +.RS 4 +.RE +.IP "show_version" 4 +.IX Item "show_version" +.Vb 1 +\& int (*show_version)(int verbose); +.Ve +.Sp +The \f(CW\*(C`show_version\*(C'\fR function is called by \fBsudo\fR when the user specifies +the \f(CW\*(C`\-V\*(C'\fR option. The plugin may display its version information +to the user via the conversation function using \f(CW\*(C`SUDO_CONV_INFO_MSG\*(C'\fR. +If the user requests detailed version information, the verbose flag +will be set. +.IP "check_policy" 4 +.IX Item "check_policy" +.Vb 3 +\& int (*check_policy)(int argc, char * const argv[] +\& char *env_add[], char **command_info[], +\& char **argv_out[], char **user_env_out[]); +.Ve +.Sp +The \fIcheck_policy\fR function is called by \fBsudo\fR to determine +whether the user is allowed to run the specified commands. +Returns 1 if the command is allowed, 0 if not and \-1 on error. +On error, the plugin may optionally call the conversation function with +\&\f(CW\*(C`SUDO_CONF_ERROR_MSG\*(C'\fR to present additional error information to the +user. +.Sp +The function arguments are as follows: +.RS 4 +.IP "argc" 4 +.IX Item "argc" +The number of elements in \fIargv\fR, not counting the final \f(CW\*(C`NULL\*(C'\fR +pointer. +.IP "argv" 4 +.IX Item "argv" +The argument vector describing the command the user wishes to run, +in the same form as what would be passed to the \fIexecve()\fR system +call. The vector is terminated by a \f(CW\*(C`NULL\*(C'\fR pointer. +.IP "env_add" 4 +.IX Item "env_add" +Additional environment variables specified by the user on the command +line in the form of a \f(CW\*(C`NULL\*(C'\fR\-terminated vector of \*(L"name=value\*(R" +strings. The plugin may reject the command if one or more variables +are not allowed to be set, or it may silently ignore such variables. +.Sp +When parsing \fIenv_add\fR, the plugin should split on the \fBfirst\fR +equal sign ('=') since the \fIname\fR field will never include one +itself but the \fIvalue\fR might. +.IP "command_info" 4 +.IX Item "command_info" +Information about the command being run in the form of \*(L"name=value\*(R" +strings. These values are used by \fBsudo\fR to set the execution +environment when running a command. The plugin is responsible for +creating and populating the vector, which must be terminated with +a \f(CW\*(C`NULL\*(C'\fR pointer. The following values are recognized by \fBsudo\fR: +.RS 4 +.IP "command=string" 4 +.IX Item "command=string" +Fully qualified path to the command to be executed. +.IP "runas_uid=uid" 4 +.IX Item "runas_uid=uid" +User \s-1ID\s0 to run the command as. +.IP "runas_euid=uid" 4 +.IX Item "runas_euid=uid" +Effective user \s-1ID\s0 to run the command as. +If not specified, the value of \fIrunas_uid\fR is used. +.IP "runas_gid=gid" 4 +.IX Item "runas_gid=gid" +Group \s-1ID\s0 to run the command as. +.IP "runas_egid=gid" 4 +.IX Item "runas_egid=gid" +Effective group \s-1ID\s0 to run the command as. +If not specified, the value of \fIrunas_gid\fR is used. +.IP "runas_groups=list" 4 +.IX Item "runas_groups=list" +The supplementary group vector to use for the command in the form +of a comma-separated list of group IDs. If \fIpreserve_groups\fR +is set, this option is ignored. +.IP "login_class=login_class" 4 +.IX Item "login_class=login_class" +\&\s-1BSD\s0 login class to use when setting resource limits and nice value +(optional). This option is only set on systems that support login +classes. +.IP "preserve_groups=bool" 4 +.IX Item "preserve_groups=bool" +If set, \fBsudo\fR will preserve the user's group vector instead of +initializing the group vector based on \f(CW\*(C`runas_user\*(C'\fR. +.IP "cwd=string" 4 +.IX Item "cwd=string" +The current working directory to change to when executing the command. +.IP "noexec=bool" 4 +.IX Item "noexec=bool" +If set, prevent the command from executing other programs. +.IP "chroot=string" 4 +.IX Item "chroot=string" +The root directory to use when running the command. +.IP "nice=int" 4 +.IX Item "nice=int" +Nice value (priority) to use when executing the command. The nice +value, if specified, overrides the priority associated with the +\&\fIlogin_class\fR on \s-1BSD\s0 systems. +.IP "umask=octal" 4 +.IX Item "umask=octal" +The file creation mask to use when executing the command. +.IP "selinux_role=string" 4 +.IX Item "selinux_role=string" +SELinux role to use when executing the command. +.IP "selinux_type=string" 4 +.IX Item "selinux_type=string" +SELinux type to use when executing the command. +.IP "timeout=int" 4 +.IX Item "timeout=int" +Command timeout. If non-zero then when the timeout expires the +command will be killed. +.RE +.RS 4 +.Sp +Unsupported values will be ignored. +.RE +.IP "argv_out" 4 +.IX Item "argv_out" +The \f(CW\*(C`NULL\*(C'\fR\-terminated argument vector to pass to the \fIexecve()\fR +system call when executing the command. The plugin is responsible +for allocating and populating the vector. +.IP "user_env_out" 4 +.IX Item "user_env_out" +The \f(CW\*(C`NULL\*(C'\fR\-terminated environment vector to use when executing the +command. The plugin is responsible for allocating and populating +the vector. +.RE +.RS 4 +.RE +.IP "list" 4 +.IX Item "list" +.Vb 2 +\& int (*list)(int verbose, const char *list_user, +\& int argc, char * const argv[]); +.Ve +.Sp +List available privileges for the invoking user. Returns 1 on +success, 0 on failure and \-1 on error. +On error, the plugin may optionally call the conversation function with +\&\f(CW\*(C`SUDO_CONF_ERROR_MSG\*(C'\fR to present additional error information to the +user. +.Sp +Privileges should be output via the conversation function using +\&\f(CW\*(C`SUDO_CONV_INFO_MSG\*(C'\fR. +.RS 4 +.IP "verbose" 4 +.IX Item "verbose" +Flag indicating whether to list in verbose mode or not. +.IP "list_user" 4 +.IX Item "list_user" +The name of a different user to list privileges for if the policy +allows it. If \f(CW\*(C`NULL\*(C'\fR, the plugin should list the privileges of +the invoking user. +.IP "argc" 4 +.IX Item "argc" +The number of elements in \fIargv\fR, not counting the final \f(CW\*(C`NULL\*(C'\fR +pointer. +.IP "argv" 4 +.IX Item "argv" +If non\-\f(CW\*(C`NULL\*(C'\fR, an argument vector describing a command the user +wishes to check against the policy in the same form as what would +be passed to the \fIexecve()\fR system call. If the command is permitted +by the policy, the fully-qualified path to the command should be +displayed along with any command line arguments. +.RE +.RS 4 +.RE +.IP "validate" 4 +.IX Item "validate" +.Vb 1 +\& int (*validate)(void); +.Ve +.Sp +The \f(CW\*(C`validate\*(C'\fR function is called when \fBsudo\fR is run with the +\&\f(CW\*(C`\-v\*(C'\fR flag. For policy plugins such as \fIsudoers\fR that cache +authentication credentials, this function will validate and cache +the credentials. +.Sp +The \f(CW\*(C`validate\*(C'\fR function should be \f(CW\*(C`NULL\*(C'\fR if the plugin does not +support credential caching. +.Sp +Returns 1 on success, 0 on failure and \-1 on error. +On error, the plugin may optionally call the conversation function with +\&\f(CW\*(C`SUDO_CONF_ERROR_MSG\*(C'\fR to present additional error information to the +user. +.IP "invalidate" 4 +.IX Item "invalidate" +.Vb 1 +\& void (*invalidate)(int remove); +.Ve +.Sp +The \f(CW\*(C`invalidate\*(C'\fR function is called when \fBsudo\fR is called with +the \f(CW\*(C`\-k\*(C'\fR or \f(CW\*(C`\-K\*(C'\fR flag. For policy plugins such as \fIsudoers\fR that +cache authentication credentials, this function will invalidate the +credentials. If the \fIremove\fR flag is set, the plugin may remove +the credentials instead of simply invalidating them. +.Sp +The \f(CW\*(C`invalidate\*(C'\fR function should be \f(CW\*(C`NULL\*(C'\fR if the plugin does not +support credential caching. +.PP +\fIConversation \s-1API\s0\fR +.IX Subsection "Conversation API" +.PP +If the plugin needs to interact with the user or display informational +or error messages, it may do so via the conversation function. A +plugin should not attempt to read directly from the standard input +or the user's tty. +.PP +.Vb 9 +\& struct sudo_conv_message { +\& #define SUDO_CONV_PROMPT_ECHO_OFF 1 +\& #define SUDO_CONV_PROMPT_ECHO_ON 2 +\& #define SUDO_CONV_ERROR_MSG 3 +\& #define SUDO_CONV_INFO_MSG 4 +\& int msg_type; +\& int timeout; +\& const char *msg; +\& }; +\& +\& struct sudo_conv_reply { +\& char *reply; +\& }; +\& +\& typedef int (*sudo_conv_t)(int num_msgs, +\& const struct sudo_conv_message msgs[], +\& struct sudo_conv_reply replies[]); +.Ve +.PP +A conversation function is passed in to the plugin's \f(CW\*(C`open\*(C'\fR function +when the plugin is initialized. The plugin passes in a \f(CW\*(C`struct +sudo_conv_message\*(C'\fR and \f(CW\*(C`struct sudo_conv_reply\*(C'\fR for each message +in the conversation. The plugin is responsible for freeing the +actual reply buffer in \f(CW\*(C`struct sudo_conv_reply\*(C'\fR. +.PP +See the sample plugin for an example of the conversation function usage. +.SS "I/O Plugin \s-1API\s0" +.IX Subsection "I/O Plugin API" +.Vb 12 +\& struct io_plugin { +\& #define SUDO_IO_PLUGIN 2 +\& unsigned int type; /* always SUDO_IO_PLUGIN */ +\& unsigned int version; /* always SUDO_API_VERSION */ +\& int (*open)(unsigned int version, sudo_conv_t conversation +\& char * const settings[], char * const user_info[], +\& char * const user_env[]); +\& void (*close)(int exit_status, int error); /* wait status or error */ +\& int (*show_version)(int verbose); +\& int (*log_input)(const char *buf, unsigned int len); +\& int (*log_output)(const char *buf, unsigned int len); +\& }; +.Ve +.PP +When an I/O plugin is loaded, \fBsudo\fR runs the command in a pseudo-tty. +This makes it possible to log the input and output from the user's +session. If the log_input function is defined, it will receive the +raw user input (note that this will include input even when echo +is disabled, such as passwords). The log_output function receives +output from the pseudo-tty that is suitable for replaying the user's +session at a later time. Either log_input or log_output may be +\&\s-1NULL\s0. If the open function returns \f(CW0\fR, no I/O will be sent to +the plugin. +.PP +The io_plugin struct has the following fields: +.IP "type" 4 +.IX Item "type" +The \f(CW\*(C`type\*(C'\fR field should always be set to \s-1SUDO_IO_PLUGIN\s0 +.IP "version" 4 +.IX Item "version" +The \f(CW\*(C`version\*(C'\fR field should be set to \s-1SUDO_API_VERSION\s0. +.Sp +This allows \fBsudo\fR to determine the \s-1API\s0 version the plugin was +built against. +.IP "open" 4 +.IX Item "open" +.Vb 3 +\& int (*open)(unsigned int version, sudo_conv_t conversation +\& char * const settings[], char * const user_info[], +\& char * const user_env[]); +.Ve +.Sp +Returns 1 on success, 0 if the command should not be logged and \-1 on error. +On error, the plugin may optionally call the conversation function with +\&\f(CW\*(C`SUDO_CONF_ERROR_MSG\*(C'\fR to present additional error information to the +user. +.Sp +The function arguments are as follows: +.RS 4 +.IP "version" 4 +.IX Item "version" +The version passed in by \fBsudo\fR allows the plugin to determine the +major and minor version number of the plugin \s-1API\s0 supported by +\&\fBsudo\fR. +.IP "conversation" 4 +.IX Item "conversation" +A pointer to the conversation function that may be used by the +\&\fIshow_version\fR function to display version information (see +show_version below). The conversation function may also be used +to display additional error message to the user. +.IP "settings" 4 +.IX Item "settings" +A vector of user-supplied \fBsudo\fR settings in the form of \*(L"name=value\*(R" +strings. The vector is terminated by a \f(CW\*(C`NULL\*(C'\fR pointer. These +settings correspond to flags the user specified when running \fBsudo\fR. +As such, they will only be present when the corresponding flag has +been specified on the command line. +.Sp +When parsing \fIsettings\fR, the plugin should split on the \fBfirst\fR +equal sign ('=') since the \fIname\fR field will never include one +itself but the \fIvalue\fR might. +.Sp +See the \*(L"Policy Plugin \s-1API\s0\*(R" section for a list of all possible settings. +.IP "user_info" 4 +.IX Item "user_info" +A vector of information about the user running the command in the form of +\&\*(L"name=value\*(R" strings. The vector is terminated by a \f(CW\*(C`NULL\*(C'\fR pointer. +.Sp +When parsing \fIuser_info\fR, the plugin should split on the \fBfirst\fR +equal sign ('=') since the \fIname\fR field will never include one +itself but the \fIvalue\fR might. +.Sp +See the \*(L"Policy Plugin \s-1API\s0\*(R" section for a list of all possible strings. +.IP "user_env" 4 +.IX Item "user_env" +The user's environment in the form of a \f(CW\*(C`NULL\*(C'\fR\-terminated vector of +\&\*(L"name=value\*(R" strings. +.Sp +When parsing \fIuser_env\fR, the plugin should split on the \fBfirst\fR +equal sign ('=') since the \fIname\fR field will never include one +itself but the \fIvalue\fR might. +.RE +.RS 4 +.RE +.IP "close" 4 +.IX Item "close" +.Vb 1 +\& void (*close)(int exit_status, int error); +.Ve +.Sp +The \f(CW\*(C`close\*(C'\fR function is called when the command being run by \fBsudo\fR +finishes. +.Sp +The function arguments are as follows: +.RS 4 +.IP "exit_status" 4 +.IX Item "exit_status" +The command's exit status, as returned by the \fIwait\fR\|(2) system call. +The value of \f(CW\*(C`exit_status\*(C'\fR is undefined if \f(CW\*(C`error\*(C'\fR is non-zero. +.IP "error" 4 +.IX Item "error" +If the command could not be executed, this is set to the value of +\&\f(CW\*(C`errno\*(C'\fR set by the \fIexecve\fR\|(2) system call. If the command was +successfully executed, the value of \f(CW\*(C`error\*(C'\fR is 0. +.RE +.RS 4 +.RE +.IP "show_version" 4 +.IX Item "show_version" +.Vb 1 +\& int (*show_version)(int verbose); +.Ve +.Sp +The \f(CW\*(C`show_version\*(C'\fR function is called by \fBsudo\fR when the user specifies +the \f(CW\*(C`\-V\*(C'\fR option. The plugin may display its version information +to the user via the conversation function using \f(CW\*(C`SUDO_CONV_INFO_MSG\*(C'\fR. +If the user requests detailed version information, the verbose flag +will be set. +.IP "log_input" 4 +.IX Item "log_input" +.Vb 1 +\& int (*log_input)(const char *buf, unsigned int len); +.Ve +.Sp +The \fIlog_input\fR function is called whenever data can be read from +the user but before it is passed to the running command. This +allows the plugin to reject data if it chooses to (for instance +if the input contains banned content). Returns \f(CW1\fR if the data +should be passed to the command, \f(CW0\fR if the data is rejected +(which will terminate the command) or \f(CW\*(C`\-1\*(C'\fR if an error occurred. +.Sp +The function arguments are as follows: +.RS 4 +.IP "buf" 4 +.IX Item "buf" +The buffer containing user input. +.IP "len" 4 +.IX Item "len" +The length of \fIbuf\fR in bytes. +.RE +.RS 4 +.RE +.IP "log_output" 4 +.IX Item "log_output" +.Vb 1 +\& int (*log_output)(const char *buf, unsigned int len); +.Ve +.Sp +The \fIlog_output\fR function is called whenever data can be read from +the command but before it is written to the user's terminal. This +allows the plugin to reject data if it chooses to (for instance +if the input contains banned content). Returns \f(CW1\fR if the data +should be passed to the user, \f(CW0\fR if the data is rejected +(which will terminate the command) or \f(CW\*(C`\-1\*(C'\fR if an error occurred. +.Sp +The function arguments are as follows: +.RS 4 +.IP "buf" 4 +.IX Item "buf" +The buffer containing command output. +.IP "len" 4 +.IX Item "len" +The length of \fIbuf\fR in bytes. +.RE +.RS 4 +.RE +.SS "Unhandled command line options" +.IX Subsection "Unhandled command line options" +The \f(CW\*(C`\-L\*(C'\fR command line option has been deprecated as its output is +covered by the \fIsudoers\fR manual page. +.SS "Sudo implementation details" +.IX Subsection "Sudo implementation details" +Version macros: +.PP +.Vb 8 +\& #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 { \e +\& *(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \e +\& } while(0) +\& #define SUDO_VERSION_SET_MINOR(vp, n) do { \e +\& *(vp) = (*(vp) & 0xffff0000) | (n); \e +\& } 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) +.Ve +.PP +Sudo will cast the plugin symbol to the following when determining +the plugin type. +.PP +.Vb 4 +\& union sudo_plugin { +\& struct policy_plugin policy; +\& struct io_plugin io; +\& }; +.Ve diff --git a/doc/plugin.pod b/doc/sudo_plugin.pod similarity index 100% rename from doc/plugin.pod rename to doc/sudo_plugin.pod