Add open and close functions to the approval plugin API.
We need a close function to be able to to free memory allocated for errstr. Unlike the other plugins, the close function is called immediately after the plugin's check or show_version function. The plugin does not remain open until the command completes.
This commit is contained in:
@@ -16,7 +16,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.TH "SUDO_PLUGIN" "5" "February 5, 2020" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
|
||||
.TH "SUDO_PLUGIN" "5" "February 10, 2020" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
|
||||
.nh
|
||||
.if n .ad l
|
||||
.SH "NAME"
|
||||
@@ -605,6 +605,11 @@ store a message describing the failure or error in
|
||||
The
|
||||
\fBsudo\fR
|
||||
front end will then pass this value to any registered audit plugins.
|
||||
The string stored in
|
||||
\fIerrstr\fR
|
||||
must remain valid until the plugin's
|
||||
\fBclose\fR()
|
||||
function is called.
|
||||
.sp
|
||||
NOTE: the
|
||||
\fIerrstr\fR
|
||||
@@ -1208,6 +1213,11 @@ store a message describing the failure or error in
|
||||
The
|
||||
\fBsudo\fR
|
||||
front end will then pass this value to any registered audit plugins.
|
||||
The string stored in
|
||||
\fIerrstr\fR
|
||||
must remain valid until the plugin's
|
||||
\fBclose\fR()
|
||||
function is called.
|
||||
.sp
|
||||
NOTE: the
|
||||
\fIerrstr\fR
|
||||
@@ -1291,6 +1301,11 @@ store a message describing the failure or error in
|
||||
The
|
||||
\fBsudo\fR
|
||||
front end will then pass this value to any registered audit plugins.
|
||||
The string stored in
|
||||
\fIerrstr\fR
|
||||
must remain valid until the plugin's
|
||||
\fBclose\fR()
|
||||
function is called.
|
||||
.sp
|
||||
NOTE: the
|
||||
\fIerrstr\fR
|
||||
@@ -1356,6 +1371,11 @@ store a message describing the failure or error in
|
||||
The
|
||||
\fBsudo\fR
|
||||
front end will then pass this value to any registered audit plugins.
|
||||
The string stored in
|
||||
\fIerrstr\fR
|
||||
must remain valid until the plugin's
|
||||
\fBclose\fR()
|
||||
function is called.
|
||||
.sp
|
||||
NOTE: the
|
||||
\fIerrstr\fR
|
||||
@@ -1636,6 +1656,11 @@ store a message describing the failure or error in
|
||||
The
|
||||
\fBsudo\fR
|
||||
front end will then pass this value to any registered audit plugins.
|
||||
The string stored in
|
||||
\fIerrstr\fR
|
||||
must remain valid until the plugin's
|
||||
\fBclose\fR()
|
||||
function is called.
|
||||
.sp
|
||||
NOTE: the
|
||||
\fIerrstr\fR
|
||||
@@ -2005,6 +2030,11 @@ store a message describing the failure or error in
|
||||
The
|
||||
\fBsudo\fR
|
||||
front end will then pass this value to any registered audit plugins.
|
||||
The string stored in
|
||||
\fIerrstr\fR
|
||||
must remain valid until the plugin's
|
||||
\fBclose\fR()
|
||||
function is called.
|
||||
.sp
|
||||
NOTE: the
|
||||
\fIerrstr\fR
|
||||
@@ -2130,6 +2160,11 @@ store a message describing the failure or error in
|
||||
The
|
||||
\fBsudo\fR
|
||||
front end will then pass this value to any registered audit plugins.
|
||||
The string stored in
|
||||
\fIerrstr\fR
|
||||
must remain valid until the plugin's
|
||||
\fBclose\fR()
|
||||
function is called.
|
||||
.sp
|
||||
NOTE: the
|
||||
\fIerrstr\fR
|
||||
@@ -2184,6 +2219,11 @@ store a message describing the failure or error in
|
||||
The
|
||||
\fBsudo\fR
|
||||
front end will then pass this value to any registered audit plugins.
|
||||
The string stored in
|
||||
\fIerrstr\fR
|
||||
must remain valid until the plugin's
|
||||
\fBclose\fR()
|
||||
function is called.
|
||||
.sp
|
||||
NOTE: the
|
||||
\fIerrstr\fR
|
||||
@@ -2240,6 +2280,11 @@ store a message describing the failure or error in
|
||||
The
|
||||
\fBsudo\fR
|
||||
front end will then pass this value to any registered audit plugins.
|
||||
The string stored in
|
||||
\fIerrstr\fR
|
||||
must remain valid until the plugin's
|
||||
\fBclose\fR()
|
||||
function is called.
|
||||
.sp
|
||||
NOTE: the
|
||||
\fIerrstr\fR
|
||||
@@ -2296,6 +2341,11 @@ store a message describing the failure or error in
|
||||
The
|
||||
\fBsudo\fR
|
||||
front end will then pass this value to any registered audit plugins.
|
||||
The string stored in
|
||||
\fIerrstr\fR
|
||||
must remain valid until the plugin's
|
||||
\fBclose\fR()
|
||||
function is called.
|
||||
.sp
|
||||
NOTE: the
|
||||
\fIerrstr\fR
|
||||
@@ -2352,6 +2402,11 @@ store a message describing the failure or error in
|
||||
The
|
||||
\fBsudo\fR
|
||||
front end will then pass this value to any registered audit plugins.
|
||||
The string stored in
|
||||
\fIerrstr\fR
|
||||
must remain valid until the plugin's
|
||||
\fBclose\fR()
|
||||
function is called.
|
||||
.sp
|
||||
NOTE: the
|
||||
\fIerrstr\fR
|
||||
@@ -2418,6 +2473,11 @@ store a message describing the failure or error in
|
||||
The
|
||||
\fBsudo\fR
|
||||
front end will then pass this value to any registered audit plugins.
|
||||
The string stored in
|
||||
\fIerrstr\fR
|
||||
must remain valid until the plugin's
|
||||
\fBclose\fR()
|
||||
function is called.
|
||||
.sp
|
||||
NOTE: the
|
||||
\fIerrstr\fR
|
||||
@@ -2469,6 +2529,11 @@ store a message describing the failure or error in
|
||||
The
|
||||
\fBsudo\fR
|
||||
front end will then pass this value to any registered audit plugins.
|
||||
The string stored in
|
||||
\fIerrstr\fR
|
||||
must remain valid until the plugin's
|
||||
\fBclose\fR()
|
||||
function is called.
|
||||
.sp
|
||||
NOTE: the
|
||||
\fIerrstr\fR
|
||||
@@ -2778,6 +2843,11 @@ store a message describing the failure or error in
|
||||
The
|
||||
\fBsudo\fR
|
||||
front end will then pass this value to any registered audit plugins.
|
||||
The string stored in
|
||||
\fIerrstr\fR
|
||||
must remain valid until the plugin's
|
||||
\fBclose\fR()
|
||||
function is called.
|
||||
.PD 0
|
||||
.PP
|
||||
.RE
|
||||
@@ -2914,6 +2984,11 @@ store a message describing the failure or error in
|
||||
The
|
||||
\fBsudo\fR
|
||||
front end will then pass this value to any registered audit plugins.
|
||||
The string stored in
|
||||
\fIerrstr\fR
|
||||
must remain valid until the plugin's
|
||||
\fBclose\fR()
|
||||
function is called.
|
||||
.PD 0
|
||||
.PP
|
||||
.RE
|
||||
@@ -2986,6 +3061,11 @@ store a message describing the failure or error in
|
||||
The
|
||||
\fBsudo\fR
|
||||
front end will then pass this value to any registered audit plugins.
|
||||
The string stored in
|
||||
\fIerrstr\fR
|
||||
must remain valid until the plugin's
|
||||
\fBclose\fR()
|
||||
function is called.
|
||||
.PD 0
|
||||
.PP
|
||||
.RE
|
||||
@@ -3058,6 +3138,11 @@ store a message describing the failure or error in
|
||||
The
|
||||
\fBsudo\fR
|
||||
front end will then pass this value to any registered audit plugins.
|
||||
The string stored in
|
||||
\fIerrstr\fR
|
||||
must remain valid until the plugin's
|
||||
\fBclose\fR()
|
||||
function is called.
|
||||
.PD 0
|
||||
.PP
|
||||
.RE
|
||||
@@ -3110,26 +3195,28 @@ struct approval_plugin {
|
||||
#define SUDO_APPROVAL_PLUGIN 4
|
||||
unsigned int type; /* always SUDO_APPROVAL_PLUGIN */
|
||||
unsigned int version; /* always SUDO_API_VERSION */
|
||||
int (*check)(unsigned int version, sudo_conv_t conversation,
|
||||
int (*open)(unsigned int version, sudo_conv_t conversation,
|
||||
sudo_printf_t sudo_printf, char * const settings[],
|
||||
char * const user_info[], int submit_optind,
|
||||
char * const submit_argv[], char * const submit_envp[],
|
||||
char * const command_info[], char * const run_argv[],
|
||||
char * const run_envp[], char * const plugin_options[],
|
||||
const char **errstr);
|
||||
int (*show_version)(unsigned int version, sudo_conv_t conversation,
|
||||
sudo_printf_t sudo_printf, int verbose);
|
||||
char * const plugin_options[], const char **errstr);
|
||||
void (*close)(void);
|
||||
int (*check)(char * const command_info[], char * const run_argv[],
|
||||
char * const run_envp[], const char **errstr);
|
||||
int (*show_version)(int verbose);
|
||||
};
|
||||
.RE
|
||||
.fi
|
||||
.PP
|
||||
An approval plugin can be used to apply extra constraints after a
|
||||
command has been accepted by the policy plugin.
|
||||
Unlike the other plugin types, there are no
|
||||
\fBopen\fR()
|
||||
Unlike the other plugin types, it does not remain open until the command
|
||||
completes.
|
||||
The plugin is opened before a call to
|
||||
\fBcheck\fR()
|
||||
or
|
||||
\fBclose\fR()
|
||||
functions; functions in an approval function are stand-alone.
|
||||
\fBshow_version\fR()
|
||||
and closed immediately after.
|
||||
Multiple approval plugins may be specified in
|
||||
sudo.conf(@mansectform@).
|
||||
.PP
|
||||
@@ -3152,28 +3239,29 @@ This allows
|
||||
to determine the API version the plugin was
|
||||
built against.
|
||||
.TP 6n
|
||||
check
|
||||
.br
|
||||
open
|
||||
.nf
|
||||
.RS 6n
|
||||
int (*check)(unsigned int version, sudo_conv_t conversation,
|
||||
int (*open)(unsigned int version, sudo_conv_t conversation,
|
||||
sudo_printf_t sudo_printf, char * const settings[],
|
||||
char * const user_info[], int submit_optind,
|
||||
char * const submit_argv[], char * const submit_envp[],
|
||||
char * const command_info[], char * const run_argv[],
|
||||
char * const run_envp[], char * const plugin_options[],
|
||||
const char **errstr);
|
||||
char * const plugin_options[], const char **errstr);
|
||||
.RE
|
||||
.fi
|
||||
.RS 6n
|
||||
.sp
|
||||
The approval
|
||||
\fBopen\fR()
|
||||
function is run immediately before a call to the plugin's
|
||||
\fBcheck\fR()
|
||||
function is run after the policy plugin
|
||||
\fBcheck\fR()
|
||||
function and before any I/O logging plugins.
|
||||
If multiple approval plugins are loaded, they must all succeeed for
|
||||
the command to be allowed.
|
||||
or
|
||||
\fBshow_version\fR()
|
||||
functions.
|
||||
It is only called if the version is being requested or if the
|
||||
policy plugin's
|
||||
\fBcheck_policy\fR()
|
||||
function has returned successfully.
|
||||
It 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,
|
||||
@@ -3310,6 +3398,98 @@ itself but the
|
||||
\fIvalue\fR
|
||||
might.
|
||||
.TP 6n
|
||||
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
|
||||
\fRNULL\fR-terminated
|
||||
array of strings.
|
||||
If no arguments were specified,
|
||||
\fIplugin_options\fR
|
||||
will be the
|
||||
\fRNULL\fR
|
||||
pointer.
|
||||
.TP 6n
|
||||
errstr
|
||||
If the
|
||||
\fBopen\fR()
|
||||
function returns a value other than 1, the plugin may
|
||||
store a message describing the failure or error in
|
||||
\fIerrstr\fR.
|
||||
The
|
||||
\fBsudo\fR
|
||||
front end will then pass this value to any registered audit plugins.
|
||||
The string stored in
|
||||
\fIerrstr\fR
|
||||
must remain valid until the plugin's
|
||||
\fBclose\fR()
|
||||
function is called.
|
||||
.PD 0
|
||||
.PP
|
||||
.RE
|
||||
.PD
|
||||
.TP 6n
|
||||
close
|
||||
.br
|
||||
.nf
|
||||
.RS 6n
|
||||
void (*close)(void);
|
||||
.RE
|
||||
.fi
|
||||
.RS 6n
|
||||
.sp
|
||||
The
|
||||
\fBclose\fR()
|
||||
function is called after the approval plugin's
|
||||
\fBcheck\fR()
|
||||
or
|
||||
\fBshow_version\fR()
|
||||
functions have been called.
|
||||
It takes no arguments.
|
||||
The
|
||||
\fBclose\fR()
|
||||
function is typically used to perform plugin-specific cleanup,
|
||||
such as the freeing of memory objects allocated by the plugin.
|
||||
If the plugin does not need to perform any cleanup,
|
||||
\fBclose\fR()
|
||||
may be set to the
|
||||
\fRNULL\fR
|
||||
pointer.
|
||||
.RE
|
||||
.TP 6n
|
||||
check
|
||||
.br
|
||||
.nf
|
||||
.RS 6n
|
||||
int (*check)(char * const command_info[], char * const run_argv[],
|
||||
char * const run_envp[], const char **errstr);
|
||||
.RE
|
||||
.fi
|
||||
.RS 6n
|
||||
.sp
|
||||
The approval
|
||||
\fBcheck\fR()
|
||||
function is run after the policy plugin
|
||||
\fBcheck_policy\fR()
|
||||
function and before any I/O logging plugins.
|
||||
If multiple approval plugins are loaded, they must all succeeed for
|
||||
the command to be allowed.
|
||||
It 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,
|
||||
\fBsudo\fR
|
||||
will print a usage message before it exits.
|
||||
If an error occurs, the plugin may optionally call the
|
||||
\fBconversation\fR()
|
||||
or
|
||||
\fBplugin_printf\fR()
|
||||
function with
|
||||
\fRSUDO_CONF_ERROR_MSG\fR
|
||||
to present additional error information to the user.
|
||||
.sp
|
||||
The function arguments are as follows:
|
||||
.TP 6n
|
||||
command_info
|
||||
A vector of information describing the command being run in the form of
|
||||
\(lqname=value\(rq
|
||||
@@ -3363,19 +3543,6 @@ itself but the
|
||||
\fIvalue\fR
|
||||
might.
|
||||
.TP 6n
|
||||
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
|
||||
\fRNULL\fR-terminated
|
||||
array of strings.
|
||||
If no arguments were specified,
|
||||
\fIplugin_options\fR
|
||||
will be the
|
||||
\fRNULL\fR
|
||||
pointer.
|
||||
.TP 6n
|
||||
errstr
|
||||
If the
|
||||
\fBopen\fR()
|
||||
@@ -3385,6 +3552,11 @@ store a message describing the failure or error in
|
||||
The
|
||||
\fBsudo\fR
|
||||
front end will then pass this value to any registered audit plugins.
|
||||
The string stored in
|
||||
\fIerrstr\fR
|
||||
must remain valid until the plugin's
|
||||
\fBclose\fR()
|
||||
function is called.
|
||||
.PD 0
|
||||
.PP
|
||||
.RE
|
||||
|
@@ -15,7 +15,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd February 5, 2020
|
||||
.Dd February 10, 2020
|
||||
.Dt SUDO_PLUGIN @mansectform@
|
||||
.Os Sudo @PACKAGE_VERSION@
|
||||
.Sh NAME
|
||||
@@ -533,13 +533,18 @@ If the
|
||||
.Fn open
|
||||
function returns a value other than 1, the plugin may
|
||||
store a message describing the failure or error in
|
||||
.Em errstr .
|
||||
.Fa errstr .
|
||||
The
|
||||
.Nm sudo
|
||||
front end will then pass this value to any registered audit plugins.
|
||||
The string stored in
|
||||
.Fa errstr
|
||||
must remain valid until the plugin's
|
||||
.Fn close
|
||||
function is called.
|
||||
.Pp
|
||||
NOTE: the
|
||||
.Em errstr
|
||||
.Fa errstr
|
||||
parameter is only available starting with
|
||||
API version 1.15.
|
||||
A plugin
|
||||
@@ -547,7 +552,7 @@ A plugin
|
||||
check the API version specified by the
|
||||
.Nm sudo
|
||||
front end before using
|
||||
.Em errstr .
|
||||
.Fa errstr .
|
||||
Failure to do so may result in a crash.
|
||||
.El
|
||||
.It close
|
||||
@@ -1069,13 +1074,18 @@ If the
|
||||
.Fn check_policy
|
||||
function returns a value other than 1, the plugin may
|
||||
store a message describing the failure or error in
|
||||
.Em errstr .
|
||||
.Fa errstr .
|
||||
The
|
||||
.Nm sudo
|
||||
front end will then pass this value to any registered audit plugins.
|
||||
The string stored in
|
||||
.Fa errstr
|
||||
must remain valid until the plugin's
|
||||
.Fn close
|
||||
function is called.
|
||||
.Pp
|
||||
NOTE: the
|
||||
.Em errstr
|
||||
.Fa errstr
|
||||
parameter is only available starting with
|
||||
API version 1.15.
|
||||
A plugin
|
||||
@@ -1083,7 +1093,7 @@ A plugin
|
||||
check the API version specified by the
|
||||
.Nm sudo
|
||||
front end before using
|
||||
.Em errstr .
|
||||
.Fa errstr .
|
||||
Failure to do so may result in a crash.
|
||||
.El
|
||||
.It list
|
||||
@@ -1141,13 +1151,18 @@ If the
|
||||
.Fn list
|
||||
function returns a value other than 1, the plugin may
|
||||
store a message describing the failure or error in
|
||||
.Em errstr .
|
||||
.Fa errstr .
|
||||
The
|
||||
.Nm sudo
|
||||
front end will then pass this value to any registered audit plugins.
|
||||
The string stored in
|
||||
.Fa errstr
|
||||
must remain valid until the plugin's
|
||||
.Fn close
|
||||
function is called.
|
||||
.Pp
|
||||
NOTE: the
|
||||
.Em errstr
|
||||
.Fa errstr
|
||||
parameter is only available starting with
|
||||
API version 1.15.
|
||||
A plugin
|
||||
@@ -1155,7 +1170,7 @@ A plugin
|
||||
check the API version specified by the
|
||||
.Nm sudo
|
||||
front end before using
|
||||
.Em errstr .
|
||||
.Fa errstr .
|
||||
Failure to do so may result in a crash.
|
||||
.El
|
||||
.It validate
|
||||
@@ -1199,13 +1214,18 @@ If the
|
||||
.Fn validate
|
||||
function returns a value other than 1, the plugin may
|
||||
store a message describing the failure or error in
|
||||
.Em errstr .
|
||||
.Fa errstr .
|
||||
The
|
||||
.Nm sudo
|
||||
front end will then pass this value to any registered audit plugins.
|
||||
The string stored in
|
||||
.Fa errstr
|
||||
must remain valid until the plugin's
|
||||
.Fn close
|
||||
function is called.
|
||||
.Pp
|
||||
NOTE: the
|
||||
.Em errstr
|
||||
.Fa errstr
|
||||
parameter is only available starting with
|
||||
API version 1.15.
|
||||
A plugin
|
||||
@@ -1213,7 +1233,7 @@ A plugin
|
||||
check the API version specified by the
|
||||
.Nm sudo
|
||||
front end before using
|
||||
.Em errstr .
|
||||
.Fa errstr .
|
||||
Failure to do so may result in a crash.
|
||||
.El
|
||||
.It invalidate
|
||||
@@ -1450,13 +1470,18 @@ If the
|
||||
.Fn init_session
|
||||
function returns a value other than 1, the plugin may
|
||||
store a message describing the failure or error in
|
||||
.Em errstr .
|
||||
.Fa errstr .
|
||||
The
|
||||
.Nm sudo
|
||||
front end will then pass this value to any registered audit plugins.
|
||||
The string stored in
|
||||
.Fa errstr
|
||||
must remain valid until the plugin's
|
||||
.Fn close
|
||||
function is called.
|
||||
.Pp
|
||||
NOTE: the
|
||||
.Em errstr
|
||||
.Fa errstr
|
||||
parameter is only available starting with
|
||||
API version 1.15.
|
||||
A plugin
|
||||
@@ -1464,7 +1489,7 @@ A plugin
|
||||
check the API version specified by the
|
||||
.Nm sudo
|
||||
front end before using
|
||||
.Em errstr .
|
||||
.Fa errstr .
|
||||
Failure to do so may result in a crash.
|
||||
.El
|
||||
.Pp
|
||||
@@ -1800,13 +1825,18 @@ If the
|
||||
.Fn open
|
||||
function returns a value other than 1, the plugin may
|
||||
store a message describing the failure or error in
|
||||
.Em errstr .
|
||||
.Fa errstr .
|
||||
The
|
||||
.Nm sudo
|
||||
front end will then pass this value to any registered audit plugins.
|
||||
The string stored in
|
||||
.Fa errstr
|
||||
must remain valid until the plugin's
|
||||
.Fn close
|
||||
function is called.
|
||||
.Pp
|
||||
NOTE: the
|
||||
.Em errstr
|
||||
.Fa errstr
|
||||
parameter is only available starting with
|
||||
API version 1.15.
|
||||
A plugin
|
||||
@@ -1814,7 +1844,7 @@ A plugin
|
||||
check the API version specified by the
|
||||
.Nm sudo
|
||||
front end before using
|
||||
.Em errstr .
|
||||
.Fa errstr .
|
||||
Failure to do so may result in a crash.
|
||||
.El
|
||||
.It close
|
||||
@@ -1901,13 +1931,18 @@ If the
|
||||
.Fn log_ttyin
|
||||
function returns a value other than 1, the plugin may
|
||||
store a message describing the failure or error in
|
||||
.Em errstr .
|
||||
.Fa errstr .
|
||||
The
|
||||
.Nm sudo
|
||||
front end will then pass this value to any registered audit plugins.
|
||||
The string stored in
|
||||
.Fa errstr
|
||||
must remain valid until the plugin's
|
||||
.Fn close
|
||||
function is called.
|
||||
.Pp
|
||||
NOTE: the
|
||||
.Em errstr
|
||||
.Fa errstr
|
||||
parameter is only available starting with
|
||||
API version 1.15.
|
||||
A plugin
|
||||
@@ -1915,7 +1950,7 @@ A plugin
|
||||
check the API version specified by the
|
||||
.Nm sudo
|
||||
front end before using
|
||||
.Em errstr .
|
||||
.Fa errstr .
|
||||
Failure to do so may result in a crash.
|
||||
.El
|
||||
.It log_ttyout
|
||||
@@ -1946,13 +1981,18 @@ If the
|
||||
.Fn log_ttyout
|
||||
function returns a value other than 1, the plugin may
|
||||
store a message describing the failure or error in
|
||||
.Em errstr .
|
||||
.Fa errstr .
|
||||
The
|
||||
.Nm sudo
|
||||
front end will then pass this value to any registered audit plugins.
|
||||
The string stored in
|
||||
.Fa errstr
|
||||
must remain valid until the plugin's
|
||||
.Fn close
|
||||
function is called.
|
||||
.Pp
|
||||
NOTE: the
|
||||
.Em errstr
|
||||
.Fa errstr
|
||||
parameter is only available starting with
|
||||
API version 1.15.
|
||||
A plugin
|
||||
@@ -1960,7 +2000,7 @@ A plugin
|
||||
check the API version specified by the
|
||||
.Nm sudo
|
||||
front end before using
|
||||
.Em errstr .
|
||||
.Fa errstr .
|
||||
Failure to do so may result in a crash.
|
||||
.El
|
||||
.It log_stdin
|
||||
@@ -1993,13 +2033,18 @@ If the
|
||||
.Fn log_stdin
|
||||
function returns a value other than 1, the plugin may
|
||||
store a message describing the failure or error in
|
||||
.Em errstr .
|
||||
.Fa errstr .
|
||||
The
|
||||
.Nm sudo
|
||||
front end will then pass this value to any registered audit plugins.
|
||||
The string stored in
|
||||
.Fa errstr
|
||||
must remain valid until the plugin's
|
||||
.Fn close
|
||||
function is called.
|
||||
.Pp
|
||||
NOTE: the
|
||||
.Em errstr
|
||||
.Fa errstr
|
||||
parameter is only available starting with
|
||||
API version 1.15.
|
||||
A plugin
|
||||
@@ -2007,7 +2052,7 @@ A plugin
|
||||
check the API version specified by the
|
||||
.Nm sudo
|
||||
front end before using
|
||||
.Em errstr .
|
||||
.Fa errstr .
|
||||
Failure to do so may result in a crash.
|
||||
.El
|
||||
.It log_stdout
|
||||
@@ -2040,13 +2085,18 @@ If the
|
||||
.Fn log_stdout
|
||||
function returns a value other than 1, the plugin may
|
||||
store a message describing the failure or error in
|
||||
.Em errstr .
|
||||
.Fa errstr .
|
||||
The
|
||||
.Nm sudo
|
||||
front end will then pass this value to any registered audit plugins.
|
||||
The string stored in
|
||||
.Fa errstr
|
||||
must remain valid until the plugin's
|
||||
.Fn close
|
||||
function is called.
|
||||
.Pp
|
||||
NOTE: the
|
||||
.Em errstr
|
||||
.Fa errstr
|
||||
parameter is only available starting with
|
||||
API version 1.15.
|
||||
A plugin
|
||||
@@ -2054,7 +2104,7 @@ A plugin
|
||||
check the API version specified by the
|
||||
.Nm sudo
|
||||
front end before using
|
||||
.Em errstr .
|
||||
.Fa errstr .
|
||||
Failure to do so may result in a crash.
|
||||
.El
|
||||
.It log_stderr
|
||||
@@ -2087,13 +2137,18 @@ If the
|
||||
.Fn log_stderr
|
||||
function returns a value other than 1, the plugin may
|
||||
store a message describing the failure or error in
|
||||
.Em errstr .
|
||||
.Fa errstr .
|
||||
The
|
||||
.Nm sudo
|
||||
front end will then pass this value to any registered audit plugins.
|
||||
The string stored in
|
||||
.Fa errstr
|
||||
must remain valid until the plugin's
|
||||
.Fn close
|
||||
function is called.
|
||||
.Pp
|
||||
NOTE: the
|
||||
.Em errstr
|
||||
.Fa errstr
|
||||
parameter is only available starting with
|
||||
API version 1.15.
|
||||
A plugin
|
||||
@@ -2101,7 +2156,7 @@ A plugin
|
||||
check the API version specified by the
|
||||
.Nm sudo
|
||||
front end before using
|
||||
.Em errstr .
|
||||
.Fa errstr .
|
||||
Failure to do so may result in a crash.
|
||||
.El
|
||||
.It register_hooks
|
||||
@@ -2141,13 +2196,18 @@ If the
|
||||
.Fn change_winsize
|
||||
function returns a value other than 1, the plugin may
|
||||
store a message describing the failure or error in
|
||||
.Em errstr .
|
||||
.Fa errstr .
|
||||
The
|
||||
.Nm sudo
|
||||
front end will then pass this value to any registered audit plugins.
|
||||
The string stored in
|
||||
.Fa errstr
|
||||
must remain valid until the plugin's
|
||||
.Fn close
|
||||
function is called.
|
||||
.Pp
|
||||
NOTE: the
|
||||
.Em errstr
|
||||
.Fa errstr
|
||||
parameter is only available starting with
|
||||
API version 1.15.
|
||||
A plugin
|
||||
@@ -2155,7 +2215,7 @@ A plugin
|
||||
check the API version specified by the
|
||||
.Nm sudo
|
||||
front end before using
|
||||
.Em errstr .
|
||||
.Fa errstr .
|
||||
Failure to do so may result in a crash.
|
||||
.El
|
||||
.It log_suspend
|
||||
@@ -2183,13 +2243,18 @@ If the
|
||||
.Fn log_suspend
|
||||
function returns a value other than 1, the plugin may
|
||||
store a message describing the failure or error in
|
||||
.Em errstr .
|
||||
.Fa errstr .
|
||||
The
|
||||
.Nm sudo
|
||||
front end will then pass this value to any registered audit plugins.
|
||||
The string stored in
|
||||
.Fa errstr
|
||||
must remain valid until the plugin's
|
||||
.Fn close
|
||||
function is called.
|
||||
.Pp
|
||||
NOTE: the
|
||||
.Em errstr
|
||||
.Fa errstr
|
||||
parameter is only available starting with
|
||||
API version 1.15.
|
||||
A plugin
|
||||
@@ -2197,7 +2262,7 @@ A plugin
|
||||
check the API version specified by the
|
||||
.Nm sudo
|
||||
front end before using
|
||||
.Em errstr .
|
||||
.Fa errstr .
|
||||
Failure to do so may result in a crash.
|
||||
.It event_alloc
|
||||
.Bd -literal -compact
|
||||
@@ -2472,10 +2537,15 @@ If the
|
||||
.Fn open
|
||||
function returns a value other than 1, the plugin may
|
||||
store a message describing the failure or error in
|
||||
.Em errstr .
|
||||
.Fa errstr .
|
||||
The
|
||||
.Nm sudo
|
||||
front end will then pass this value to any registered audit plugins.
|
||||
The string stored in
|
||||
.Fa errstr
|
||||
must remain valid until the plugin's
|
||||
.Fn close
|
||||
function is called.
|
||||
.El
|
||||
.It close
|
||||
.Bd -literal -compact
|
||||
@@ -2587,10 +2657,15 @@ If the
|
||||
.Fn accept
|
||||
function returns a value other than 1, the plugin may
|
||||
store a message describing the failure or error in
|
||||
.Em errstr .
|
||||
.Fa errstr .
|
||||
The
|
||||
.Nm sudo
|
||||
front end will then pass this value to any registered audit plugins.
|
||||
The string stored in
|
||||
.Fa errstr
|
||||
must remain valid until the plugin's
|
||||
.Fn close
|
||||
function is called.
|
||||
.El
|
||||
.It reject
|
||||
.Bd -literal -compact
|
||||
@@ -2648,10 +2723,15 @@ If the
|
||||
.Fn reject
|
||||
function returns a value other than 1, the plugin may
|
||||
store a message describing the failure or error in
|
||||
.Em errstr .
|
||||
.Fa errstr .
|
||||
The
|
||||
.Nm sudo
|
||||
front end will then pass this value to any registered audit plugins.
|
||||
The string stored in
|
||||
.Fa errstr
|
||||
must remain valid until the plugin's
|
||||
.Fn close
|
||||
function is called.
|
||||
.El
|
||||
.It error
|
||||
.Bd -literal -compact
|
||||
@@ -2708,10 +2788,15 @@ If the
|
||||
.Fn error
|
||||
function returns a value other than 1, the plugin may
|
||||
store a message describing the failure or error in
|
||||
.Em errstr .
|
||||
.Fa errstr .
|
||||
The
|
||||
.Nm sudo
|
||||
front end will then pass this value to any registered audit plugins.
|
||||
The string stored in
|
||||
.Fa errstr
|
||||
must remain valid until the plugin's
|
||||
.Fn close
|
||||
function is called.
|
||||
.El
|
||||
.It show_version
|
||||
.Bd -literal -compact
|
||||
@@ -2754,25 +2839,27 @@ struct approval_plugin {
|
||||
#define SUDO_APPROVAL_PLUGIN 4
|
||||
unsigned int type; /* always SUDO_APPROVAL_PLUGIN */
|
||||
unsigned int version; /* always SUDO_API_VERSION */
|
||||
int (*check)(unsigned int version, sudo_conv_t conversation,
|
||||
int (*open)(unsigned int version, sudo_conv_t conversation,
|
||||
sudo_printf_t sudo_printf, char * const settings[],
|
||||
char * const user_info[], int submit_optind,
|
||||
char * const submit_argv[], char * const submit_envp[],
|
||||
char * const command_info[], char * const run_argv[],
|
||||
char * const run_envp[], char * const plugin_options[],
|
||||
const char **errstr);
|
||||
int (*show_version)(unsigned int version, sudo_conv_t conversation,
|
||||
sudo_printf_t sudo_printf, int verbose);
|
||||
char * const plugin_options[], const char **errstr);
|
||||
void (*close)(void);
|
||||
int (*check)(char * const command_info[], char * const run_argv[],
|
||||
char * const run_envp[], const char **errstr);
|
||||
int (*show_version)(int verbose);
|
||||
};
|
||||
.Ed
|
||||
.Pp
|
||||
An approval plugin can be used to apply extra constraints after a
|
||||
command has been accepted by the policy plugin.
|
||||
Unlike the other plugin types, there are no
|
||||
.Fn open
|
||||
Unlike the other plugin types, it does not remain open until the command
|
||||
completes.
|
||||
The plugin is opened before a call to
|
||||
.Fn check
|
||||
or
|
||||
.Fn close
|
||||
functions; functions in an approval function are stand-alone.
|
||||
.Fn show_version
|
||||
and closed immediately after.
|
||||
Multiple approval plugins may be specified in
|
||||
.Xr sudo.conf @mansectform@ .
|
||||
.Pp
|
||||
@@ -2793,24 +2880,26 @@ This allows
|
||||
.Nm sudo
|
||||
to determine the API version the plugin was
|
||||
built against.
|
||||
.It check
|
||||
.It open
|
||||
.Bd -literal -compact
|
||||
int (*check)(unsigned int version, sudo_conv_t conversation,
|
||||
int (*open)(unsigned int version, sudo_conv_t conversation,
|
||||
sudo_printf_t sudo_printf, char * const settings[],
|
||||
char * const user_info[], int submit_optind,
|
||||
char * const submit_argv[], char * const submit_envp[],
|
||||
char * const command_info[], char * const run_argv[],
|
||||
char * const run_envp[], char * const plugin_options[],
|
||||
const char **errstr);
|
||||
char * const plugin_options[], const char **errstr);
|
||||
.Ed
|
||||
.Pp
|
||||
The approval
|
||||
.Fn open
|
||||
function is run immediately before a call to the plugin's
|
||||
.Fn check
|
||||
function is run after the policy plugin
|
||||
.Fn check
|
||||
function and before any I/O logging plugins.
|
||||
If multiple approval plugins are loaded, they must all succeeed for
|
||||
the command to be allowed.
|
||||
or
|
||||
.Fn show_version
|
||||
functions.
|
||||
It is only called if the version is being requested or if the
|
||||
policy plugin's
|
||||
.Fn check_policy
|
||||
function has returned successfully.
|
||||
It 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,
|
||||
@@ -2939,6 +3028,83 @@ field will never include one
|
||||
itself but the
|
||||
.Em value
|
||||
might.
|
||||
.It 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
|
||||
.Dv NULL Ns -terminated
|
||||
array of strings.
|
||||
If no arguments were specified,
|
||||
.Em plugin_options
|
||||
will be the
|
||||
.Dv NULL
|
||||
pointer.
|
||||
.It errstr
|
||||
If the
|
||||
.Fn open
|
||||
function returns a value other than 1, the plugin may
|
||||
store a message describing the failure or error in
|
||||
.Fa errstr .
|
||||
The
|
||||
.Nm sudo
|
||||
front end will then pass this value to any registered audit plugins.
|
||||
The string stored in
|
||||
.Fa errstr
|
||||
must remain valid until the plugin's
|
||||
.Fn close
|
||||
function is called.
|
||||
.El
|
||||
.It close
|
||||
.Bd -literal -compact
|
||||
void (*close)(void);
|
||||
.Ed
|
||||
.Pp
|
||||
The
|
||||
.Fn close
|
||||
function is called after the approval plugin's
|
||||
.Fn check
|
||||
or
|
||||
.Fn show_version
|
||||
functions have been called.
|
||||
It takes no arguments.
|
||||
The
|
||||
.Fn close
|
||||
function is typically used to perform plugin-specific cleanup,
|
||||
such as the freeing of memory objects allocated by the plugin.
|
||||
If the plugin does not need to perform any cleanup,
|
||||
.Fn close
|
||||
may be set to the
|
||||
.Dv NULL
|
||||
pointer.
|
||||
.It check
|
||||
.Bd -literal -compact
|
||||
int (*check)(char * const command_info[], char * const run_argv[],
|
||||
char * const run_envp[], const char **errstr);
|
||||
.Ed
|
||||
.Pp
|
||||
The approval
|
||||
.Fn check
|
||||
function is run after the policy plugin
|
||||
.Fn check_policy
|
||||
function and before any I/O logging plugins.
|
||||
If multiple approval plugins are loaded, they must all succeeed for
|
||||
the command to be allowed.
|
||||
It 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,
|
||||
.Nm sudo
|
||||
will print a usage message before it exits.
|
||||
If an error occurs, the plugin may optionally call the
|
||||
.Fn conversation
|
||||
or
|
||||
.Fn plugin_printf
|
||||
function with
|
||||
.Dv SUDO_CONF_ERROR_MSG
|
||||
to present additional error information to the user.
|
||||
.Pp
|
||||
The function arguments are as follows:
|
||||
.Bl -tag -width 4n
|
||||
.It command_info
|
||||
A vector of information describing the command being run in the form of
|
||||
.Dq name=value
|
||||
@@ -2989,27 +3155,20 @@ field will never include one
|
||||
itself but the
|
||||
.Em value
|
||||
might.
|
||||
.It 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
|
||||
.Dv NULL Ns -terminated
|
||||
array of strings.
|
||||
If no arguments were specified,
|
||||
.Em plugin_options
|
||||
will be the
|
||||
.Dv NULL
|
||||
pointer.
|
||||
.It errstr
|
||||
If the
|
||||
.Fn open
|
||||
function returns a value other than 1, the plugin may
|
||||
store a message describing the failure or error in
|
||||
.Em errstr .
|
||||
.Fa errstr .
|
||||
The
|
||||
.Nm sudo
|
||||
front end will then pass this value to any registered audit plugins.
|
||||
The string stored in
|
||||
.Fa errstr
|
||||
must remain valid until the plugin's
|
||||
.Fn close
|
||||
function is called.
|
||||
.El
|
||||
.It show_version
|
||||
.Bd -literal -compact
|
||||
|
@@ -242,15 +242,15 @@ struct approval_plugin {
|
||||
#define SUDO_APPROVAL_PLUGIN 4
|
||||
unsigned int type; /* always SUDO_APPROVAL_PLUGIN */
|
||||
unsigned int version; /* always SUDO_API_VERSION */
|
||||
int (*check)(unsigned int version, sudo_conv_t conversation,
|
||||
int (*open)(unsigned int version, sudo_conv_t conversation,
|
||||
sudo_printf_t sudo_printf, char * const settings[],
|
||||
char * const user_info[], int submit_optind,
|
||||
char * const submit_argv[], char * const submit_envp[],
|
||||
char * const command_info[], char * const run_argv[],
|
||||
char * const run_envp[], char * const plugin_options[],
|
||||
const char **errstr);
|
||||
int (*show_version)(unsigned int version, sudo_conv_t conversation,
|
||||
sudo_printf_t sudo_printf, int verbose);
|
||||
char * const plugin_options[], const char **errstr);
|
||||
void (*close)(void);
|
||||
int (*check)(char * const command_info[], char * const run_argv[],
|
||||
char * const run_envp[], const char **errstr);
|
||||
int (*show_version)(int verbose);
|
||||
};
|
||||
|
||||
/* Sudoers group plugin version major/minor */
|
||||
|
@@ -52,6 +52,7 @@
|
||||
#include "sudo_util.h"
|
||||
|
||||
static int approval_debug_instance = SUDO_DEBUG_INSTANCE_INITIALIZER;
|
||||
sudo_printf_t sudo_printf;
|
||||
|
||||
/*
|
||||
* Parse the "filename flags,..." debug_flags entry and insert a new
|
||||
@@ -93,22 +94,21 @@ oom:
|
||||
}
|
||||
|
||||
static int
|
||||
approval_check(unsigned int version, sudo_conv_t conversation,
|
||||
sample_approval_open(unsigned int version, sudo_conv_t conversation,
|
||||
sudo_printf_t plugin_printf, char * const settings[],
|
||||
char * const user_info[], int submit_optind, char * const submit_argv[],
|
||||
char * const submit_envp[], char * const command_info[],
|
||||
char * const run_argv[], char * const run_envp[],
|
||||
char * const plugin_options[], const char **errstr)
|
||||
char * const submit_envp[], char * const plugin_options[],
|
||||
const char **errstr)
|
||||
{
|
||||
struct sudo_conf_debug_file_list debug_files =
|
||||
TAILQ_HEAD_INITIALIZER(debug_files);
|
||||
struct sudo_debug_file *debug_file;
|
||||
const char *cp, *plugin_path = NULL;
|
||||
char * const *cur;
|
||||
struct tm *tm;
|
||||
time_t now;
|
||||
int ret = -1;
|
||||
debug_decl(approval_check, SUDO_DEBUG_PLUGIN);
|
||||
debug_decl_vars(sample_approval_open, SUDO_DEBUG_PLUGIN);
|
||||
|
||||
sudo_printf = plugin_printf;
|
||||
|
||||
/* Initialize the debug subsystem. */
|
||||
for (cur = settings; (cp = *cur) != NULL; cur++) {
|
||||
@@ -129,25 +129,9 @@ approval_check(unsigned int version, sudo_conv_t conversation,
|
||||
sudo_debug_register(plugin_path, NULL, NULL, &debug_files);
|
||||
if (approval_debug_instance == SUDO_DEBUG_INSTANCE_ERROR) {
|
||||
*errstr = U_("unable to initialize debugging");
|
||||
goto bad;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Only approve requests that are within business hours,
|
||||
* which are 9am - 5pm local time. Does not check holidays.
|
||||
*/
|
||||
ret = 0;
|
||||
if (time(&now) == -1 || (tm = localtime(&now)) == NULL)
|
||||
goto bad;
|
||||
if (tm->tm_wday < 1 || tm->tm_wday > 5) {
|
||||
/* bad weekday */
|
||||
goto bad;
|
||||
}
|
||||
if (tm->tm_hour < 9 || tm->tm_hour > 17 ||
|
||||
(tm->tm_hour == 17 && tm->tm_min > 0)) {
|
||||
/* bad hour */
|
||||
goto bad;
|
||||
sudo_debug_enter(__func__, __FILE__, __LINE__, sudo_debug_subsys);
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
@@ -157,12 +141,6 @@ oom:
|
||||
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
||||
*errstr = U_("unable to allocate memory");
|
||||
|
||||
bad:
|
||||
if (ret == 0) {
|
||||
*errstr = U_("You are not allowed to use sudo outside business hours");
|
||||
plugin_printf(SUDO_CONV_ERROR_MSG, "%s\n", *errstr);
|
||||
}
|
||||
|
||||
done:
|
||||
while ((debug_file = TAILQ_FIRST(&debug_files)) != NULL) {
|
||||
TAILQ_REMOVE(&debug_files, debug_file, entries);
|
||||
@@ -174,13 +152,57 @@ done:
|
||||
debug_return_int(ret);
|
||||
}
|
||||
|
||||
static void
|
||||
sample_approval_close(void)
|
||||
{
|
||||
debug_decl(sample_approval_close, SUDO_DEBUG_PLUGIN);
|
||||
|
||||
/* Nothing here, we could store a NULL pointer instead. */
|
||||
|
||||
debug_return;
|
||||
}
|
||||
|
||||
static int
|
||||
approval_show_version(unsigned int version, sudo_conv_t conversation,
|
||||
sudo_printf_t plugin_printf, int verbose)
|
||||
sample_approval_check(char * const command_info[], char * const run_argv[],
|
||||
char * const run_envp[], const char **errstr)
|
||||
{
|
||||
struct tm *tm;
|
||||
time_t now;
|
||||
int ret = 0;
|
||||
debug_decl(sample_approval_check, SUDO_DEBUG_PLUGIN);
|
||||
|
||||
/*
|
||||
* Only approve requests that are within business hours,
|
||||
* which are 9am - 5pm local time. Does not check holidays.
|
||||
*/
|
||||
if (time(&now) == -1 || (tm = localtime(&now)) == NULL)
|
||||
goto done;
|
||||
if (tm->tm_wday < 1 || tm->tm_wday > 5) {
|
||||
/* bad weekday */
|
||||
goto done;
|
||||
}
|
||||
if (tm->tm_hour < 9 || tm->tm_hour > 17 ||
|
||||
(tm->tm_hour == 17 && tm->tm_min > 0)) {
|
||||
/* bad hour */
|
||||
goto done;
|
||||
}
|
||||
ret = 1;
|
||||
|
||||
done:
|
||||
if (ret == 0) {
|
||||
*errstr = U_("You are not allowed to use sudo outside business hours");
|
||||
sudo_printf(SUDO_CONV_ERROR_MSG, "%s\n", *errstr);
|
||||
}
|
||||
|
||||
debug_return_int(ret);
|
||||
}
|
||||
|
||||
static int
|
||||
sample_approval_show_version(int verbose)
|
||||
{
|
||||
debug_decl(approval_show_version, SUDO_DEBUG_PLUGIN);
|
||||
|
||||
plugin_printf(SUDO_CONV_INFO_MSG, "sample approval plugin version %s\n",
|
||||
sudo_printf(SUDO_CONV_INFO_MSG, "sample approval plugin version %s\n",
|
||||
PACKAGE_VERSION);
|
||||
|
||||
debug_return_int(true);
|
||||
@@ -189,6 +211,8 @@ approval_show_version(unsigned int version, sudo_conv_t conversation,
|
||||
__dso_public struct approval_plugin sample_approval = {
|
||||
SUDO_APPROVAL_PLUGIN,
|
||||
SUDO_API_VERSION,
|
||||
approval_check,
|
||||
approval_show_version
|
||||
sample_approval_open,
|
||||
sample_approval_close,
|
||||
sample_approval_check,
|
||||
sample_approval_show_version
|
||||
};
|
||||
|
136
src/sudo.c
136
src/sudo.c
@@ -144,7 +144,9 @@ static void approval_check(struct sudo_settings *settings,
|
||||
char * const user_info[], int submit_optind, char * const submit_argv[],
|
||||
char * const submit_envp[], char * const command_info[],
|
||||
char * const run_argv[], char * const run_envp[]);
|
||||
static void approval_show_version(int verbose);
|
||||
static void approval_show_version(int verbose, struct sudo_settings *settings,
|
||||
char * const user_info[], int submit_optind, char * const submit_argv[],
|
||||
char * const submit_envp[]);
|
||||
|
||||
__dso_public int main(int argc, char *argv[], char *envp[]);
|
||||
|
||||
@@ -246,7 +248,8 @@ main(int argc, char *argv[], char *envp[])
|
||||
policy_show_version(!user_details.uid);
|
||||
iolog_show_version(!user_details.uid, settings, user_info,
|
||||
nargc, nargv, envp);
|
||||
approval_show_version(!user_details.uid);
|
||||
approval_show_version(!user_details.uid, settings, user_info,
|
||||
submit_optind, argv, envp);
|
||||
audit_show_version(!user_details.uid);
|
||||
break;
|
||||
case MODE_VALIDATE:
|
||||
@@ -1704,36 +1707,79 @@ audit_error(const char *plugin_name, unsigned int plugin_type,
|
||||
}
|
||||
|
||||
static int
|
||||
approval_check_int(struct plugin_container *plugin,
|
||||
approval_open_int(struct plugin_container *plugin,
|
||||
struct sudo_settings *settings, char * const user_info[],
|
||||
int submit_optind, char * const submit_argv[], char * const submit_envp[],
|
||||
char * const command_info[], char * const run_argv[],
|
||||
char * const run_envp[], const char **errstr)
|
||||
int submit_optind, char * const submit_argv[], char * const submit_envp[])
|
||||
{
|
||||
char **plugin_settings;
|
||||
const char *errstr = NULL;
|
||||
int ret;
|
||||
debug_decl(approval_check_int, SUDO_DEBUG_PCOMM);
|
||||
debug_decl(approval_open_int, SUDO_DEBUG_PCOMM);
|
||||
|
||||
/* Convert struct sudo_settings to plugin_settings[] */
|
||||
plugin_settings = format_plugin_settings(plugin, settings);
|
||||
if (plugin_settings == NULL) {
|
||||
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
||||
debug_return_int(-1);
|
||||
}
|
||||
if (plugin_settings == NULL)
|
||||
sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
||||
|
||||
sudo_debug_set_active_instance(plugin->debug_instance);
|
||||
ret = plugin->u.approval->check(SUDO_API_VERSION, sudo_conversation,
|
||||
sudo_conversation_printf, plugin_settings, user_info,
|
||||
submit_optind, submit_argv, submit_envp, command_info, run_argv,
|
||||
run_envp, plugin->options, errstr);
|
||||
sudo_debug_set_active_instance(SUDO_DEBUG_INSTANCE_INITIALIZER);
|
||||
ret = plugin->u.approval->open(SUDO_API_VERSION, sudo_conversation,
|
||||
sudo_conversation_printf, plugin_settings, user_info, submit_optind,
|
||||
submit_argv, submit_envp, plugin->options, &errstr);
|
||||
|
||||
/* Stash plugin debug instance ID if set in open() function. */
|
||||
plugin->debug_instance = sudo_debug_get_active_instance();
|
||||
sudo_debug_set_active_instance(sudo_debug_instance);
|
||||
|
||||
sudo_debug_printf(SUDO_DEBUG_INFO, "approval plugin %s returns %d (%s)",
|
||||
plugin->name, ret, *errstr ? *errstr : "");
|
||||
switch (ret) {
|
||||
case 1:
|
||||
break;
|
||||
case 0:
|
||||
/* approval plugin asked to be disabled, remove and free. */
|
||||
unlink_plugin(&approval_plugins, plugin);
|
||||
break;
|
||||
case -2:
|
||||
usage();
|
||||
break;
|
||||
default:
|
||||
/* XXX - audit */
|
||||
sudo_fatalx(U_("error initializing approval plugin %s"),
|
||||
plugin->name);
|
||||
}
|
||||
|
||||
debug_return_int(ret);
|
||||
}
|
||||
|
||||
static void
|
||||
approval_show_version(int verbose, struct sudo_settings *settings,
|
||||
char * const user_info[], int submit_optind, char * const submit_argv[],
|
||||
char * const submit_envp[])
|
||||
{
|
||||
struct plugin_container *plugin, *next;
|
||||
int ok;
|
||||
debug_decl(approval_show_version, SUDO_DEBUG_PCOMM);
|
||||
|
||||
/*
|
||||
* Approval plugin us only open for the life of the show_version() call.
|
||||
*/
|
||||
TAILQ_FOREACH_SAFE(plugin, &approval_plugins, entries, next) {
|
||||
if (plugin->u.approval->show_version == NULL)
|
||||
continue;
|
||||
|
||||
ok = approval_open_int(plugin, settings, user_info, submit_optind,
|
||||
submit_argv, submit_envp);
|
||||
if (ok == 1) {
|
||||
/* Return value of show_version currently ignored. */
|
||||
sudo_debug_set_active_instance(plugin->debug_instance);
|
||||
plugin->u.approval->show_version(verbose);
|
||||
if (plugin->u.approval->close != NULL)
|
||||
plugin->u.approval->close();
|
||||
sudo_debug_set_active_instance(sudo_debug_instance);
|
||||
}
|
||||
}
|
||||
|
||||
debug_return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Run approval checks (there may be more than one).
|
||||
* This is a "one-shot" plugin that has no open/close and is only
|
||||
@@ -1747,12 +1793,27 @@ approval_check(struct sudo_settings *settings, char * const user_info[],
|
||||
{
|
||||
struct plugin_container *plugin, *next;
|
||||
const char *errstr = NULL;
|
||||
int ok;
|
||||
debug_decl(approval_check, SUDO_DEBUG_PCOMM);
|
||||
|
||||
/*
|
||||
* Approval plugin us only open for the life of the check() call.
|
||||
*/
|
||||
TAILQ_FOREACH_SAFE(plugin, &approval_plugins, entries, next) {
|
||||
int ok = approval_check_int(plugin, settings, user_info,
|
||||
submit_optind, submit_argv, submit_envp, command_info, run_argv,
|
||||
run_envp, &errstr);
|
||||
if (plugin->u.approval->check == NULL)
|
||||
continue;
|
||||
|
||||
ok = approval_open_int(plugin, settings, user_info, submit_optind,
|
||||
submit_argv, submit_envp);
|
||||
if (ok != 1)
|
||||
continue;
|
||||
|
||||
sudo_debug_set_active_instance(plugin->debug_instance);
|
||||
ok = plugin->u.approval->check(command_info, run_argv, run_envp,
|
||||
&errstr);
|
||||
sudo_debug_set_active_instance(sudo_debug_instance);
|
||||
sudo_debug_printf(SUDO_DEBUG_INFO, "approval plugin %s returns %d (%s)",
|
||||
plugin->name, ok, errstr ? errstr : "");
|
||||
|
||||
switch (ok) {
|
||||
case 0:
|
||||
@@ -1763,7 +1824,7 @@ approval_check(struct sudo_settings *settings, char * const user_info[],
|
||||
case 1:
|
||||
audit_accept(plugin->name, SUDO_APPROVAL_PLUGIN, command_info,
|
||||
run_argv, run_envp);
|
||||
continue;
|
||||
break;
|
||||
case -1:
|
||||
audit_error(plugin->name, SUDO_APPROVAL_PLUGIN,
|
||||
errstr ? errstr : _("approval plugin error"),
|
||||
@@ -1774,29 +1835,20 @@ approval_check(struct sudo_settings *settings, char * const user_info[],
|
||||
break;
|
||||
}
|
||||
|
||||
if (policy_plugin.u.policy->version >= SUDO_API_MKVERSION(1, 15))
|
||||
policy_close(0, EPERM);
|
||||
audit_close(SUDO_PLUGIN_NO_STATUS, 0);
|
||||
exit(EXIT_FAILURE); /* approval plugin printed error message */
|
||||
}
|
||||
|
||||
debug_return;
|
||||
}
|
||||
|
||||
static void
|
||||
approval_show_version(int verbose)
|
||||
{
|
||||
struct plugin_container *plugin;
|
||||
debug_decl(approval_show_version, SUDO_DEBUG_PCOMM);
|
||||
|
||||
TAILQ_FOREACH(plugin, &approval_plugins, entries) {
|
||||
if (plugin->u.approval->show_version != NULL) {
|
||||
/* Return value of show_version currently ignored. */
|
||||
/* Close approval plugin now that errstr has been consumed. */
|
||||
if (plugin->u.approval->close != NULL) {
|
||||
sudo_debug_set_active_instance(plugin->debug_instance);
|
||||
plugin->u.approval->show_version(SUDO_API_VERSION,
|
||||
sudo_conversation, sudo_conversation_printf, verbose);
|
||||
plugin->u.approval->close();
|
||||
sudo_debug_set_active_instance(sudo_debug_instance);
|
||||
}
|
||||
|
||||
/* On error, close policy and audit plugins then exit. */
|
||||
if (ok != 1) {
|
||||
if (policy_plugin.u.policy->version >= SUDO_API_MKVERSION(1, 15))
|
||||
policy_close(0, EPERM);
|
||||
audit_close(SUDO_PLUGIN_NO_STATUS, 0);
|
||||
exit(EXIT_FAILURE); /* approval plugin printed error message */
|
||||
}
|
||||
}
|
||||
|
||||
debug_return;
|
||||
|
Reference in New Issue
Block a user