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 .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" 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 .nh
.if n .ad l .if n .ad l
.SH "NAME" .SH "NAME"
@@ -601,16 +601,29 @@ void (*close)(int exit_status, int error);
.sp .sp
The The
\fBclose\fR() \fBclose\fR()
function is called when the command being run by function is called when
\fBsudo\fR \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 .sp
The function arguments are as follows: The function arguments are as follows:
.TP 6n .TP 6n
exit_status exit_status
The command's exit status, as returned by the The command's exit status, as returned by the
wait(2) wait(2)
system call. system call, or zero if no command was run.
The value of The value of
\fRexit_status\fR \fRexit_status\fR
is undefined if is undefined if
@@ -631,7 +644,7 @@ or
function. function.
If the command was successfully executed, the value of If the command was successfully executed, the value of
\fRerror\fR \fRerror\fR
is 0. is zero.
.PP .PP
If no If no
\fBclose\fR() \fBclose\fR()
@@ -1815,16 +1828,21 @@ void (*close)(int exit_status, int error);
.sp .sp
The The
\fBclose\fR() \fBclose\fR()
function is called when the command being run by function is called when
\fBsudo\fR \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 .sp
The function arguments are as follows: The function arguments are as follows:
.TP 6n .TP 6n
exit_status exit_status
The command's exit status, as returned by the The command's exit status, as returned by the
wait(2) wait(2)
system call. system call, or zero if no command was run.
The value of The value of
\fRexit_status\fR \fRexit_status\fR
is undefined if is undefined if
@@ -1840,7 +1858,7 @@ execve(2)
system call. system call.
If the command was successfully executed, the value of If the command was successfully executed, the value of
\fRerror\fR \fRerror\fR
is 0. is zero.
.PD 0 .PD 0
.PP .PP
.RE .RE
@@ -3339,6 +3357,13 @@ Version 1.15 (sudo 1.9.0)
The The
\fIevent_alloc\fR \fIevent_alloc\fR
field was added to the policy_plugin and io_plugin structs. 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" .SH "SEE ALSO"
sudo.conf(@mansectform@), sudo.conf(@mansectform@),
sudoers(@mansectform@), sudoers(@mansectform@),

View File

@@ -15,7 +15,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\" .\"
.Dd November 12, 2019 .Dd November 18, 2019
.Dt SUDO_PLUGIN @mansectform@ .Dt SUDO_PLUGIN @mansectform@
.Os Sudo @PACKAGE_VERSION@ .Os Sudo @PACKAGE_VERSION@
.Sh NAME .Sh NAME
@@ -526,16 +526,29 @@ void (*close)(int exit_status, int error);
.Pp .Pp
The The
.Fn close .Fn close
function is called when the command being run by function is called when
.Nm sudo .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 .Pp
The function arguments are as follows: The function arguments are as follows:
.Bl -tag -width 4n .Bl -tag -width 4n
.It exit_status .It exit_status
The command's exit status, as returned by the The command's exit status, as returned by the
.Xr wait 2 .Xr wait 2
system call. system call, or zero if no command was run.
The value of The value of
.Li exit_status .Li exit_status
is undefined if is undefined if
@@ -554,7 +567,7 @@ or
function. function.
If the command was successfully executed, the value of If the command was successfully executed, the value of
.Li error .Li error
is 0. is zero.
.El .El
.Pp .Pp
If no If no
@@ -1616,16 +1629,21 @@ void (*close)(int exit_status, int error);
.Pp .Pp
The The
.Fn close .Fn close
function is called when the command being run by function is called when
.Nm sudo .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 .Pp
The function arguments are as follows: The function arguments are as follows:
.Bl -tag -width 4n .Bl -tag -width 4n
.It exit_status .It exit_status
The command's exit status, as returned by the The command's exit status, as returned by the
.Xr wait 2 .Xr wait 2
system call. system call, or zero if no command was run.
The value of The value of
.Li exit_status .Li exit_status
is undefined if is undefined if
@@ -1639,7 +1657,7 @@ set by the
system call. system call.
If the command was successfully executed, the value of If the command was successfully executed, the value of
.Li error .Li error
is 0. is zero.
.El .El
.It show_version .It show_version
.Bd -literal -compact .Bd -literal -compact
@@ -2904,6 +2922,13 @@ list.
The The
.Em event_alloc .Em event_alloc
field was added to the policy_plugin and io_plugin structs. 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 .El
.Sh SEE ALSO .Sh SEE ALSO
.Xr sudo.conf @mansectform@ , .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. */ /* Free remaining references to password and group entries. */
/* XXX - move cleanup to function in sudoers.c */ /* XXX - move cleanup to function in sudoers.c */
if (sudo_user.pw != NULL) {
sudo_pw_delref(sudo_user.pw); sudo_pw_delref(sudo_user.pw);
sudo_user.pw = NULL; sudo_user.pw = NULL;
}
if (runas_pw != NULL) {
sudo_pw_delref(runas_pw); sudo_pw_delref(runas_pw);
runas_pw = NULL; runas_pw = NULL;
}
if (runas_gr != NULL) { if (runas_gr != NULL) {
sudo_gr_delref(runas_gr); sudo_gr_delref(runas_gr);
runas_gr = NULL; runas_gr = NULL;

View File

@@ -1120,6 +1120,10 @@ policy_show_version(struct plugin_container *plugin, int verbose)
debug_return_int(true); debug_return_int(true);
sudo_debug_set_active_instance(plugin->debug_instance); sudo_debug_set_active_instance(plugin->debug_instance);
ret = plugin->u.policy->show_version(verbose); 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); sudo_debug_set_active_instance(sudo_debug_instance);
debug_return_int(ret); 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); sudo_debug_set_active_instance(plugin->debug_instance);
ret = plugin->u.policy->check_policy(argc, argv, env_add, command_info, ret = plugin->u.policy->check_policy(argc, argv, env_add, command_info,
argv_out, user_env_out); 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); sudo_debug_set_active_instance(sudo_debug_instance);
debug_return_int(ret); 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); sudo_debug_set_active_instance(plugin->debug_instance);
ret = plugin->u.policy->list(argc, argv, verbose, list_user); 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); sudo_debug_set_active_instance(sudo_debug_instance);
debug_return_int(ret); debug_return_int(ret);
} }
@@ -1174,6 +1189,10 @@ policy_validate(struct plugin_container *plugin)
} }
sudo_debug_set_active_instance(plugin->debug_instance); sudo_debug_set_active_instance(plugin->debug_instance);
ret = plugin->u.policy->validate(); 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); sudo_debug_set_active_instance(sudo_debug_instance);
debug_return_int(ret); debug_return_int(ret);
} }
@@ -1188,6 +1207,10 @@ policy_invalidate(struct plugin_container *plugin, int remove)
} }
sudo_debug_set_active_instance(plugin->debug_instance); sudo_debug_set_active_instance(plugin->debug_instance);
plugin->u.policy->invalidate(remove); 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); sudo_debug_set_active_instance(sudo_debug_instance);
debug_return; debug_return;
} }
@@ -1301,6 +1324,10 @@ iolog_show_version(struct plugin_container *plugin, int verbose)
sudo_debug_set_active_instance(plugin->debug_instance); sudo_debug_set_active_instance(plugin->debug_instance);
ret = plugin->u.io->show_version(verbose); 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); sudo_debug_set_active_instance(sudo_debug_instance);
debug_return_int(ret); debug_return_int(ret);
} }