Pass back the number of files to edit when using sudoedit.
The sudo front-end can use this to determine where the list of files to edit begins.
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
.\"
|
||||
.\" SPDX-License-Identifier: ISC
|
||||
.\"
|
||||
.\" Copyright (c) 2009-2022 Todd C. Miller <Todd.Miller@sudo.ws>
|
||||
.\" Copyright (c) 2009-2023 Todd C. Miller <Todd.Miller@sudo.ws>
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and distribute this software for any
|
||||
.\" purpose with or without fee is hereby granted, provided that the above
|
||||
@@ -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" "October 7, 2022" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
|
||||
.TH "SUDO_PLUGIN" "5" "January 18, 2023" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
|
||||
.nh
|
||||
.if n .ad l
|
||||
.SH "NAME"
|
||||
@@ -909,15 +909,20 @@ temporary copies of the files to be edited and then overwriting the
|
||||
originals with the temporary copies after editing is complete.
|
||||
If the plugin supports
|
||||
\fIsudoedit\fR,
|
||||
it should choose the editor to be used, potentially from a variable
|
||||
in the user's environment, such as
|
||||
it must set
|
||||
\fIsudoedit=true\fR
|
||||
in the
|
||||
\fIcommand_info\fR
|
||||
list.
|
||||
The plugin is responsible for choosing the editor to be used,
|
||||
potentially from a variable in the user's environment, such as
|
||||
\fREDITOR\fR,
|
||||
and include it in
|
||||
and should be stored in
|
||||
\fIargv_out\fR
|
||||
(environment variables may include command line options).
|
||||
The files to be edited should be copied from
|
||||
\fIargv\fR
|
||||
into
|
||||
to
|
||||
\fIargv_out\fR,
|
||||
separated from the
|
||||
editor and its arguments by a
|
||||
@@ -928,11 +933,13 @@ The
|
||||
will be removed by
|
||||
\fBsudo\fR
|
||||
before the editor is executed.
|
||||
The plugin should also set
|
||||
\fIsudoedit=true\fR
|
||||
in the
|
||||
The plugin may also set
|
||||
\fIsudoedit_nfiles\fR
|
||||
to the number of files to be edited in the
|
||||
\fIcommand_info\fR
|
||||
list.
|
||||
list; this will only be used by the
|
||||
\fBsudo\fR
|
||||
front-end starting with API version 1.21.
|
||||
.sp
|
||||
The
|
||||
\fBcheck_policy\fR()
|
||||
@@ -1536,6 +1543,25 @@ option can be used to restore the older behavior and allow
|
||||
to open symbolic links.
|
||||
Only available starting with API version 1.8.
|
||||
.TP 6n
|
||||
sudoedit_nfiles=number
|
||||
The number of files to be edited by the user.
|
||||
If present, this is will be used by the
|
||||
\fBsudo\fR
|
||||
front-end to determine which elements of the
|
||||
\fIargv_out\fR
|
||||
vector are files to be edited.
|
||||
The
|
||||
\(oq--\(cq
|
||||
element must immediately precede the first file to be editied.
|
||||
If
|
||||
\fIsudoedit_nfiles\fR
|
||||
is not specified, the
|
||||
\fBsudo\fR
|
||||
front-end will use the position of the
|
||||
\(oq--\(cq
|
||||
element to determine where the file list begins.
|
||||
Only available starting with API version 1.21.
|
||||
.TP 6n
|
||||
timeout=int
|
||||
Command timeout.
|
||||
If non-zero then when the timeout expires the command will be killed.
|
||||
@@ -5441,6 +5467,13 @@ The
|
||||
entry was added to the
|
||||
\fIcommand_info\fR
|
||||
list.
|
||||
.TP 6n
|
||||
Version 1.21 (sudo 1.9.13)
|
||||
The
|
||||
\fIsudoedit_nfiles\fR
|
||||
entry was added to the
|
||||
\fIcommand_info\fR
|
||||
list.
|
||||
.SH "SEE ALSO"
|
||||
sudo.conf(@mansectform@),
|
||||
sudoers(@mansectform@),
|
||||
|
@@ -1,7 +1,7 @@
|
||||
.\"
|
||||
.\" SPDX-License-Identifier: ISC
|
||||
.\"
|
||||
.\" Copyright (c) 2009-2022 Todd C. Miller <Todd.Miller@sudo.ws>
|
||||
.\" Copyright (c) 2009-2023 Todd C. Miller <Todd.Miller@sudo.ws>
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and distribute this software for any
|
||||
.\" purpose with or without fee is hereby granted, provided that the above
|
||||
@@ -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 October 7, 2022
|
||||
.Dd January 18, 2023
|
||||
.Dt SUDO_PLUGIN @mansectform@
|
||||
.Os Sudo @PACKAGE_VERSION@
|
||||
.Sh NAME
|
||||
@@ -807,15 +807,20 @@ temporary copies of the files to be edited and then overwriting the
|
||||
originals with the temporary copies after editing is complete.
|
||||
If the plugin supports
|
||||
.Em sudoedit ,
|
||||
it should choose the editor to be used, potentially from a variable
|
||||
in the user's environment, such as
|
||||
it must set
|
||||
.Em sudoedit=true
|
||||
in the
|
||||
.Fa command_info
|
||||
list.
|
||||
The plugin is responsible for choosing the editor to be used,
|
||||
potentially from a variable in the user's environment, such as
|
||||
.Ev EDITOR ,
|
||||
and include it in
|
||||
and should be stored in
|
||||
.Fa argv_out
|
||||
(environment variables may include command line options).
|
||||
The files to be edited should be copied from
|
||||
.Fa argv
|
||||
into
|
||||
to
|
||||
.Fa argv_out ,
|
||||
separated from the
|
||||
editor and its arguments by a
|
||||
@@ -826,11 +831,13 @@ The
|
||||
will be removed by
|
||||
.Nm sudo
|
||||
before the editor is executed.
|
||||
The plugin should also set
|
||||
.Em sudoedit=true
|
||||
in the
|
||||
The plugin may also set
|
||||
.Em sudoedit_nfiles
|
||||
to the number of files to be edited in the
|
||||
.Fa command_info
|
||||
list.
|
||||
list; this will only be used by the
|
||||
.Nm sudo
|
||||
front-end starting with API version 1.21.
|
||||
.Pp
|
||||
The
|
||||
.Fn check_policy
|
||||
@@ -1377,6 +1384,24 @@ option can be used to restore the older behavior and allow
|
||||
.Nm sudoedit
|
||||
to open symbolic links.
|
||||
Only available starting with API version 1.8.
|
||||
.It sudoedit_nfiles=number
|
||||
The number of files to be edited by the user.
|
||||
If present, this is will be used by the
|
||||
.Nm sudo
|
||||
front-end to determine which elements of the
|
||||
.Fa argv_out
|
||||
vector are files to be edited.
|
||||
The
|
||||
.Ql --
|
||||
element must immediately precede the first file to be editied.
|
||||
If
|
||||
.Em sudoedit_nfiles
|
||||
is not specified, the
|
||||
.Nm sudo
|
||||
front-end will use the position of the
|
||||
.Ql --
|
||||
element to determine where the file list begins.
|
||||
Only available starting with API version 1.21.
|
||||
.It timeout=int
|
||||
Command timeout.
|
||||
If non-zero then when the timeout expires the command will be killed.
|
||||
@@ -4826,6 +4851,12 @@ The
|
||||
entry was added to the
|
||||
.Fa command_info
|
||||
list.
|
||||
.It Version 1.21 (sudo 1.9.13)
|
||||
The
|
||||
.Em sudoedit_nfiles
|
||||
entry was added to the
|
||||
.Fa command_info
|
||||
list.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr sudo.conf @mansectform@ ,
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: ISC
|
||||
*
|
||||
* Copyright (c) 2009-2022 Todd C. Miller <Todd.Miller@sudo.ws>
|
||||
* Copyright (c) 2009-2023 Todd C. Miller <Todd.Miller@sudo.ws>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
/* API version major/minor */
|
||||
#define SUDO_API_VERSION_MAJOR 1
|
||||
#define SUDO_API_VERSION_MINOR 20
|
||||
#define SUDO_API_VERSION_MINOR 21
|
||||
#define SUDO_API_MKVERSION(x, y) (((x) << 16) | (y))
|
||||
#define SUDO_API_VERSION SUDO_API_MKVERSION(SUDO_API_VERSION_MAJOR, SUDO_API_VERSION_MINOR)
|
||||
|
||||
|
@@ -58,6 +58,7 @@ struct sudo_plugin_event * (*plugin_event_alloc)(void);
|
||||
const char *path_ldap_conf = _PATH_LDAP_CONF;
|
||||
const char *path_ldap_secret = _PATH_LDAP_SECRET;
|
||||
static bool session_opened;
|
||||
int sudoedit_nfiles;
|
||||
|
||||
extern sudo_dso_public struct policy_plugin sudoers_policy;
|
||||
|
||||
@@ -189,6 +190,7 @@ sudoers_policy_deserialize_info(void *v, struct defaults_list *defaults)
|
||||
/* Parse command line settings. */
|
||||
sudo_user.flags = 0;
|
||||
user_closefrom = -1;
|
||||
sudoedit_nfiles = 0;
|
||||
sudo_mode = 0;
|
||||
for (cur = info->settings; *cur != NULL; cur++) {
|
||||
if (MATCHES(*cur, "closefrom=")) {
|
||||
@@ -653,7 +655,7 @@ sudoers_policy_store_result(bool accepted, char *argv[], char *envp[],
|
||||
}
|
||||
|
||||
/* Increase the length of command_info as needed, it is *not* checked. */
|
||||
command_info = calloc(72, sizeof(char *));
|
||||
command_info = calloc(73, sizeof(char *));
|
||||
if (command_info == NULL)
|
||||
goto oom;
|
||||
|
||||
@@ -715,6 +717,11 @@ sudoers_policy_store_result(bool accepted, char *argv[], char *envp[],
|
||||
if (ISSET(sudo_mode, MODE_EDIT)) {
|
||||
if ((command_info[info_len++] = strdup("sudoedit=true")) == NULL)
|
||||
goto oom;
|
||||
if (sudoedit_nfiles > 0) {
|
||||
if (asprintf(&command_info[info_len++], "sudoedit_nfiles=%d",
|
||||
sudoedit_nfiles) == -1)
|
||||
goto oom;
|
||||
}
|
||||
if (!def_sudoedit_checkdir) {
|
||||
if ((command_info[info_len++] = strdup("sudoedit_checkdir=false")) == NULL)
|
||||
goto oom;
|
||||
|
@@ -806,8 +806,9 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
|
||||
char **edit_argv;
|
||||
int edit_argc;
|
||||
|
||||
sudoedit_nfiles = NewArgc - 1;
|
||||
free(safe_cmnd);
|
||||
safe_cmnd = find_editor(NewArgc - 1, NewArgv + 1, &edit_argc,
|
||||
safe_cmnd = find_editor(sudoedit_nfiles, NewArgv + 1, &edit_argc,
|
||||
&edit_argv, NULL, &env_editor);
|
||||
if (safe_cmnd == NULL) {
|
||||
switch (errno) {
|
||||
|
@@ -433,6 +433,7 @@ extern struct sudo_user sudo_user;
|
||||
extern struct passwd *list_pw;
|
||||
extern bool force_umask;
|
||||
extern int sudo_mode;
|
||||
extern int sudoedit_nfiles;
|
||||
extern uid_t timestamp_uid;
|
||||
extern gid_t timestamp_gid;
|
||||
extern sudo_conv_t sudo_conv;
|
||||
|
11
src/sudo.c
11
src/sudo.c
@@ -287,7 +287,8 @@ main(int argc, char *argv[], char *envp[])
|
||||
/* Setup command details and run command/edit. */
|
||||
command_info_to_details(command_info, &command_details);
|
||||
command_details.tty = user_details.tty;
|
||||
command_details.argv = argv_out;
|
||||
command_details.argv = nargv;
|
||||
command_details.argc = nargc;
|
||||
command_details.envp = run_envp;
|
||||
command_details.evbase = sudo_event_base;
|
||||
if (ISSET(sudo_mode, MODE_LOGIN_SHELL))
|
||||
@@ -833,6 +834,14 @@ command_info_to_details(char * const info[], struct command_details *details)
|
||||
SET_FLAG("sudoedit=", CD_SUDOEDIT)
|
||||
SET_FLAG("sudoedit_checkdir=", CD_SUDOEDIT_CHECKDIR)
|
||||
SET_FLAG("sudoedit_follow=", CD_SUDOEDIT_FOLLOW)
|
||||
if (strncmp("sudoedit_nfiles=", info[i], sizeof("sudoedit_nfiles=") - 1) == 0) {
|
||||
cp = info[i] + sizeof("sudoedit_nfiles=") - 1;
|
||||
details->nfiles = sudo_strtonum(cp, 1, INT_MAX,
|
||||
&errstr);
|
||||
if (errstr != NULL)
|
||||
sudo_fatalx(U_("%s: %s"), info[i], U_(errstr));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 't':
|
||||
if (strncmp("timeout=", info[i], sizeof("timeout=") - 1) == 0) {
|
||||
|
@@ -189,11 +189,13 @@ TAILQ_HEAD(preserved_fd_list, preserved_fd);
|
||||
struct command_details {
|
||||
struct sudo_cred cred;
|
||||
mode_t umask;
|
||||
int argc;
|
||||
int priority;
|
||||
int timeout;
|
||||
int closefrom;
|
||||
int flags;
|
||||
int execfd;
|
||||
int nfiles;
|
||||
struct preserved_fd_list preserved_fds;
|
||||
struct passwd *pw;
|
||||
const char *command;
|
||||
|
@@ -628,9 +628,10 @@ int
|
||||
sudo_edit(struct command_details *command_details)
|
||||
{
|
||||
struct command_details saved_command_details;
|
||||
char **nargv = NULL, **ap, **files = NULL;
|
||||
char **nargv = NULL, **files = NULL;
|
||||
int nfiles = command_details->nfiles;
|
||||
int errors, i, ac, nargc, ret;
|
||||
int editor_argc = 0, nfiles = 0;
|
||||
int editor_argc = 0;
|
||||
struct timespec times[2];
|
||||
struct tempfile *tf = NULL;
|
||||
debug_decl(sudo_edit, SUDO_DEBUG_EDIT);
|
||||
@@ -650,17 +651,31 @@ sudo_edit(struct command_details *command_details)
|
||||
if (!set_tmpdir(&user_details.cred))
|
||||
goto cleanup;
|
||||
|
||||
if (nfiles > 0) {
|
||||
/*
|
||||
* The user's editor must be separated from the files to be
|
||||
* edited by a "--" option.
|
||||
* The plugin specified the number of files to edit, use it.
|
||||
*/
|
||||
for (ap = command_details->argv; *ap != NULL; ap++) {
|
||||
if (files)
|
||||
nfiles++;
|
||||
else if (strcmp(*ap, "--") == 0)
|
||||
files = ap + 1;
|
||||
else
|
||||
editor_argc++;
|
||||
editor_argc = command_details->argc - nfiles;
|
||||
if (editor_argc < 2 || strcmp(command_details->argv[editor_argc - 1], "--") != 0) {
|
||||
sudo_warnx("%s", U_("plugin error: invalid file list for sudoedit"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* We don't include the "--" when running the user's editor. */
|
||||
files = &command_details->argv[editor_argc--];
|
||||
} else {
|
||||
/*
|
||||
* Compute the number of files to edit by looking for the "--"
|
||||
* option which separate the editor from the files.
|
||||
*/
|
||||
for (i = 0; command_details->argv[i] != NULL; i++) {
|
||||
if (strcmp(command_details->argv[i], "--") == 0) {
|
||||
editor_argc = i;
|
||||
files = &command_details->argv[i + 1];
|
||||
nfiles = command_details->argc - (i + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nfiles == 0) {
|
||||
sudo_warnx("%s", U_("plugin error: missing file list for sudoedit"));
|
||||
@@ -717,6 +732,7 @@ sudo_edit(struct command_details *command_details)
|
||||
command_details->cred = user_details.cred;
|
||||
command_details->cred.euid = user_details.cred.uid;
|
||||
command_details->cred.egid = user_details.cred.gid;
|
||||
command_details->argc = nargc;
|
||||
command_details->argv = nargv;
|
||||
ret = run_command(command_details);
|
||||
if (sudo_gettime_real(×[1]) == -1) {
|
||||
@@ -726,6 +742,7 @@ sudo_edit(struct command_details *command_details)
|
||||
|
||||
/* Restore saved command_details. */
|
||||
command_details->cred = saved_command_details.cred;
|
||||
command_details->argc = saved_command_details.argc;
|
||||
command_details->argv = saved_command_details.argv;
|
||||
|
||||
/* Copy contents of temp files to real ones. */
|
||||
|
Reference in New Issue
Block a user