For plugin API 1.15 and up, always call the plugin close function.

Previously, it was only called when a command was run (including
sudoedit).  Now, plugin operations list, validate, invalidate, and
show_version are also closed.
This commit is contained in:
Todd C. Miller
2019-11-20 10:57:47 -07:00
parent 2143746370
commit f976a5d866
4 changed files with 103 additions and 22 deletions

View File

@@ -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" "November 12, 2019" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
.TH "SUDO_PLUGIN" "5" "November 18, 2019" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
.nh
.if n .ad l
.SH "NAME"
@@ -601,16 +601,29 @@ void (*close)(int exit_status, int error);
.sp
The
\fBclose\fR()
function is called when the command being run by
function is called when
\fBsudo\fR
finishes.
is finished, shortly before it exits.
Starting with API version 1.15,
\fBclose\fR()
is called regardless of whether or not a command was actually executed.
This makes it possible for plugins to perform cleanup even when a
command was not run.
It is not possible to tell whether a command was run based solely
on the arguments passed to the
\fBclose\fR()
function.
To determine if a command was actually run,
the plugin must keep track of whether or not the
\fBcheck_policy\fR()
function returned successfully.
.sp
The function arguments are as follows:
.TP 6n
exit_status
The command's exit status, as returned by the
wait(2)
system call.
system call, or zero if no command was run.
The value of
\fRexit_status\fR
is undefined if
@@ -631,7 +644,7 @@ or
function.
If the command was successfully executed, the value of
\fRerror\fR
is 0.
is zero.
.PP
If no
\fBclose\fR()
@@ -1815,16 +1828,21 @@ void (*close)(int exit_status, int error);
.sp
The
\fBclose\fR()
function is called when the command being run by
function is called when
\fBsudo\fR
finishes.
is finished, shortly before it exits.
Starting with API version 1.15,
\fBclose\fR()
is called regardless of whether or not a command was actually executed.
This makes it possible for plugins to perform cleanup even when a
command was not run.
.sp
The function arguments are as follows:
.TP 6n
exit_status
The command's exit status, as returned by the
wait(2)
system call.
system call, or zero if no command was run.
The value of
\fRexit_status\fR
is undefined if
@@ -1840,7 +1858,7 @@ execve(2)
system call.
If the command was successfully executed, the value of
\fRerror\fR
is 0.
is zero.
.PD 0
.PP
.RE
@@ -3339,6 +3357,13 @@ Version 1.15 (sudo 1.9.0)
The
\fIevent_alloc\fR
field was added to the policy_plugin and io_plugin structs.
.sp
The
\fBclose\fR()
function is now is called regardless of whether or not a command
was actually executed.
This makes it possible for plugins to perform cleanup even when a
command was not run.
.SH "SEE ALSO"
sudo.conf(@mansectform@),
sudoers(@mansectform@),

View File

@@ -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 November 12, 2019
.Dd November 18, 2019
.Dt SUDO_PLUGIN @mansectform@
.Os Sudo @PACKAGE_VERSION@
.Sh NAME
@@ -526,16 +526,29 @@ void (*close)(int exit_status, int error);
.Pp
The
.Fn close
function is called when the command being run by
function is called when
.Nm sudo
finishes.
is finished, shortly before it exits.
Starting with API version 1.15,
.Fn close
is called regardless of whether or not a command was actually executed.
This makes it possible for plugins to perform cleanup even when a
command was not run.
It is not possible to tell whether a command was run based solely
on the arguments passed to the
.Fn close
function.
To determine if a command was actually run,
the plugin must keep track of whether or not the
.Fn check_policy
function returned successfully.
.Pp
The function arguments are as follows:
.Bl -tag -width 4n
.It exit_status
The command's exit status, as returned by the
.Xr wait 2
system call.
system call, or zero if no command was run.
The value of
.Li exit_status
is undefined if
@@ -554,7 +567,7 @@ or
function.
If the command was successfully executed, the value of
.Li error
is 0.
is zero.
.El
.Pp
If no
@@ -1616,16 +1629,21 @@ void (*close)(int exit_status, int error);
.Pp
The
.Fn close
function is called when the command being run by
function is called when
.Nm sudo
finishes.
is finished, shortly before it exits.
Starting with API version 1.15,
.Fn close
is called regardless of whether or not a command was actually executed.
This makes it possible for plugins to perform cleanup even when a
command was not run.
.Pp
The function arguments are as follows:
.Bl -tag -width 4n
.It exit_status
The command's exit status, as returned by the
.Xr wait 2
system call.
system call, or zero if no command was run.
The value of
.Li exit_status
is undefined if
@@ -1639,7 +1657,7 @@ set by the
system call.
If the command was successfully executed, the value of
.Li error
is 0.
is zero.
.El
.It show_version
.Bd -literal -compact
@@ -2904,6 +2922,13 @@ list.
The
.Em event_alloc
field was added to the policy_plugin and io_plugin structs.
.Pp
The
.Fn close
function is now is called regardless of whether or not a command
was actually executed.
This makes it possible for plugins to perform cleanup even when a
command was not run.
.El
.Sh SEE ALSO
.Xr sudo.conf @mansectform@ ,

View File

@@ -869,10 +869,14 @@ sudoers_policy_close(int exit_status, int error_code)
/* Free remaining references to password and group entries. */
/* XXX - move cleanup to function in sudoers.c */
sudo_pw_delref(sudo_user.pw);
sudo_user.pw = NULL;
sudo_pw_delref(runas_pw);
runas_pw = NULL;
if (sudo_user.pw != NULL) {
sudo_pw_delref(sudo_user.pw);
sudo_user.pw = NULL;
}
if (runas_pw != NULL) {
sudo_pw_delref(runas_pw);
runas_pw = NULL;
}
if (runas_gr != NULL) {
sudo_gr_delref(runas_gr);
runas_gr = NULL;

View File

@@ -1120,6 +1120,10 @@ policy_show_version(struct plugin_container *plugin, int verbose)
debug_return_int(true);
sudo_debug_set_active_instance(plugin->debug_instance);
ret = plugin->u.policy->show_version(verbose);
if (plugin->u.policy->version >= SUDO_API_MKVERSION(1, 15)) {
if (plugin->u.policy->close != NULL)
plugin->u.policy->close(0, 0);
}
sudo_debug_set_active_instance(sudo_debug_instance);
debug_return_int(ret);
}
@@ -1139,6 +1143,13 @@ policy_check(struct plugin_container *plugin, int argc, char * const argv[],
sudo_debug_set_active_instance(plugin->debug_instance);
ret = plugin->u.policy->check_policy(argc, argv, env_add, command_info,
argv_out, user_env_out);
/* On success, the close method will be called by sudo_edit/run_command. */
if (ret != 1) {
if (plugin->u.policy->version >= SUDO_API_MKVERSION(1, 15)) {
if (plugin->u.policy->close != NULL)
plugin->u.policy->close(0, 0);
}
}
sudo_debug_set_active_instance(sudo_debug_instance);
debug_return_int(ret);
}
@@ -1157,6 +1168,10 @@ policy_list(struct plugin_container *plugin, int argc, char * const argv[],
}
sudo_debug_set_active_instance(plugin->debug_instance);
ret = plugin->u.policy->list(argc, argv, verbose, list_user);
if (plugin->u.policy->version >= SUDO_API_MKVERSION(1, 15)) {
if (plugin->u.policy->close != NULL)
plugin->u.policy->close(0, 0);
}
sudo_debug_set_active_instance(sudo_debug_instance);
debug_return_int(ret);
}
@@ -1174,6 +1189,10 @@ policy_validate(struct plugin_container *plugin)
}
sudo_debug_set_active_instance(plugin->debug_instance);
ret = plugin->u.policy->validate();
if (plugin->u.policy->version >= SUDO_API_MKVERSION(1, 15)) {
if (plugin->u.policy->close != NULL)
plugin->u.policy->close(0, 0);
}
sudo_debug_set_active_instance(sudo_debug_instance);
debug_return_int(ret);
}
@@ -1188,6 +1207,10 @@ policy_invalidate(struct plugin_container *plugin, int remove)
}
sudo_debug_set_active_instance(plugin->debug_instance);
plugin->u.policy->invalidate(remove);
if (plugin->u.policy->version >= SUDO_API_MKVERSION(1, 15)) {
if (plugin->u.policy->close != NULL)
plugin->u.policy->close(0, 0);
}
sudo_debug_set_active_instance(sudo_debug_instance);
debug_return;
}
@@ -1301,6 +1324,10 @@ iolog_show_version(struct plugin_container *plugin, int verbose)
sudo_debug_set_active_instance(plugin->debug_instance);
ret = plugin->u.io->show_version(verbose);
if (plugin->u.io->version >= SUDO_API_MKVERSION(1, 15)) {
if (plugin->u.io->close != NULL)
plugin->u.io->close(0, 0);
}
sudo_debug_set_active_instance(sudo_debug_instance);
debug_return_int(ret);
}