mirror of
https://github.com/sudo-project/sudo.git
synced 2025-08-30 13:58:05 +00:00
Also honor SUDO_EDITOR in visudo. Previously is was only used
by sudoedit.
This commit is contained in:
parent
fa2ab63da9
commit
23ac62cfb5
@ -1001,19 +1001,19 @@ SSUUDDOOEERRSS OOPPTTIIOONNSS
|
|||||||
higher. It has no effect unless I/O logging is enabled
|
higher. It has no effect unless I/O logging is enabled
|
||||||
or the _u_s_e___p_t_y flag is enabled.
|
or the _u_s_e___p_t_y flag is enabled.
|
||||||
|
|
||||||
env_editor If set, vviissuuddoo will use the value of the EDITOR or
|
env_editor If set, vviissuuddoo will use the value of the SUDO_EDITOR,
|
||||||
VISUAL environment variables before falling back on the
|
VISUAL or EDITOR environment variables before falling
|
||||||
default editor list. Note that this may create a
|
back on the default editor list. Note that this may
|
||||||
security hole as it allows the user to run any
|
create a security hole as it allows the user to run any
|
||||||
arbitrary command as root without logging. A safer
|
arbitrary command as root without logging. A safer
|
||||||
alternative is to place a colon-separated list of
|
alternative is to place a colon-separated list of
|
||||||
editors in the editor variable. vviissuuddoo will then only
|
editors in the _e_d_i_t_o_r variable. vviissuuddoo will then only
|
||||||
use the EDITOR or VISUAL if they match a value
|
use SUDO_EDITOR, VISUAL or EDITOR if they match a value
|
||||||
specified in editor. If the _e_n_v___r_e_s_e_t flag is enabled,
|
specified in _e_d_i_t_o_r. If the _e_n_v___r_e_s_e_t flag is enabled,
|
||||||
the EDITOR and/or VISUAL environment variables must be
|
the SUDO_EDITOR, VISUAL and/or EDITOR environment
|
||||||
present in the _e_n_v___k_e_e_p list for the _e_n_v___e_d_i_t_o_r flag to
|
variables must be present in the _e_n_v___k_e_e_p list for the
|
||||||
function when vviissuuddoo is invoked via ssuuddoo. This flag is
|
_e_n_v___e_d_i_t_o_r flag to function when vviissuuddoo is invoked via
|
||||||
_o_f_f by default.
|
ssuuddoo. This flag is _o_f_f by default.
|
||||||
|
|
||||||
env_reset If set, ssuuddoo will run the command in a minimal
|
env_reset If set, ssuuddoo will run the command in a minimal
|
||||||
environment containing the TERM, PATH, HOME, MAIL,
|
environment containing the TERM, PATH, HOME, MAIL,
|
||||||
@ -1613,12 +1613,12 @@ SSUUDDOOEERRSS OOPPTTIIOONNSS
|
|||||||
|
|
||||||
editor A colon (`:') separated list of editors allowed to be
|
editor A colon (`:') separated list of editors allowed to be
|
||||||
used with vviissuuddoo. vviissuuddoo will choose the editor that
|
used with vviissuuddoo. vviissuuddoo will choose the editor that
|
||||||
matches the user's EDITOR or VISUAL environment
|
matches the user's SUDO_EDITOR, VISUAL or EDITOR
|
||||||
variable if possible, or the first editor in the list
|
environment variable if possible, or the first editor
|
||||||
that exists and is executable. Note that the EDITOR
|
in the list that exists and is executable. Note that
|
||||||
and VISUAL environment variables are not preserved by
|
the SUDO_EDITOR, VISUAL and EDITOR environment
|
||||||
default when the _e_n_v___r_e_s_e_t option is enabled. The
|
variables are not preserved by default when the
|
||||||
default is _v_i.
|
_e_n_v___r_e_s_e_t option is enabled. The default is _v_i.
|
||||||
|
|
||||||
iolog_dir The top-level directory to use when constructing the
|
iolog_dir The top-level directory to use when constructing the
|
||||||
path name for the input/output log directory. Only
|
path name for the input/output log directory. Only
|
||||||
|
@ -2132,29 +2132,32 @@ env_editor
|
|||||||
If set,
|
If set,
|
||||||
\fBvisudo\fR
|
\fBvisudo\fR
|
||||||
will use the value of the
|
will use the value of the
|
||||||
\fREDITOR\fR
|
\fRSUDO_EDITOR\fR,
|
||||||
or
|
|
||||||
\fRVISUAL\fR
|
\fRVISUAL\fR
|
||||||
|
or
|
||||||
|
\fREDITOR\fR
|
||||||
environment variables before falling back on the default editor list.
|
environment variables before falling back on the default editor list.
|
||||||
Note that this may create a security hole as it allows the user to
|
Note that this may create a security hole as it allows the user to
|
||||||
run any arbitrary command as root without logging.
|
run any arbitrary command as root without logging.
|
||||||
A safer alternative is to place a colon-separated list of editors
|
A safer alternative is to place a colon-separated list of editors
|
||||||
in the
|
in the
|
||||||
\fReditor\fR
|
\fIeditor\fR
|
||||||
variable.
|
variable.
|
||||||
\fBvisudo\fR
|
\fBvisudo\fR
|
||||||
will then only use the
|
will then only use
|
||||||
\fREDITOR\fR
|
\fRSUDO_EDITOR\fR,
|
||||||
or
|
|
||||||
\fRVISUAL\fR
|
\fRVISUAL\fR
|
||||||
|
or
|
||||||
|
\fREDITOR\fR
|
||||||
if they match a value specified in
|
if they match a value specified in
|
||||||
\fReditor\fR.
|
\fIeditor\fR.
|
||||||
If the
|
If the
|
||||||
\fIenv_reset\fR
|
\fIenv_reset\fR
|
||||||
flag is enabled, the
|
flag is enabled, the
|
||||||
\fREDITOR\fR
|
\fRSUDO_EDITOR\fR,
|
||||||
and/or
|
|
||||||
\fRVISUAL\fR
|
\fRVISUAL\fR
|
||||||
|
and/or
|
||||||
|
\fREDITOR\fR
|
||||||
environment variables must be present in the
|
environment variables must be present in the
|
||||||
\fIenv_keep\fR
|
\fIenv_keep\fR
|
||||||
list for the
|
list for the
|
||||||
@ -3310,15 +3313,17 @@ separated list of editors allowed to be used with
|
|||||||
\fBvisudo\fR.
|
\fBvisudo\fR.
|
||||||
\fBvisudo\fR
|
\fBvisudo\fR
|
||||||
will choose the editor that matches the user's
|
will choose the editor that matches the user's
|
||||||
\fREDITOR\fR
|
\fRSUDO_EDITOR\fR,
|
||||||
or
|
|
||||||
\fRVISUAL\fR
|
\fRVISUAL\fR
|
||||||
|
or
|
||||||
|
\fREDITOR\fR
|
||||||
environment variable if possible, or the first editor in the
|
environment variable if possible, or the first editor in the
|
||||||
list that exists and is executable.
|
list that exists and is executable.
|
||||||
Note that the
|
Note that the
|
||||||
\fREDITOR\fR
|
\fRSUDO_EDITOR\fR,
|
||||||
and
|
|
||||||
\fRVISUAL\fR
|
\fRVISUAL\fR
|
||||||
|
and
|
||||||
|
\fREDITOR\fR
|
||||||
environment variables are not preserved by default when the
|
environment variables are not preserved by default when the
|
||||||
\fIenv_reset\fR
|
\fIenv_reset\fR
|
||||||
option is enabled.
|
option is enabled.
|
||||||
|
@ -1998,29 +1998,32 @@ flag is enabled.
|
|||||||
If set,
|
If set,
|
||||||
.Nm visudo
|
.Nm visudo
|
||||||
will use the value of the
|
will use the value of the
|
||||||
.Ev EDITOR
|
.Ev SUDO_EDITOR ,
|
||||||
or
|
|
||||||
.Ev VISUAL
|
.Ev VISUAL
|
||||||
|
or
|
||||||
|
.Ev EDITOR
|
||||||
environment variables before falling back on the default editor list.
|
environment variables before falling back on the default editor list.
|
||||||
Note that this may create a security hole as it allows the user to
|
Note that this may create a security hole as it allows the user to
|
||||||
run any arbitrary command as root without logging.
|
run any arbitrary command as root without logging.
|
||||||
A safer alternative is to place a colon-separated list of editors
|
A safer alternative is to place a colon-separated list of editors
|
||||||
in the
|
in the
|
||||||
.Li editor
|
.Em editor
|
||||||
variable.
|
variable.
|
||||||
.Nm visudo
|
.Nm visudo
|
||||||
will then only use the
|
will then only use
|
||||||
.Ev EDITOR
|
.Ev SUDO_EDITOR ,
|
||||||
or
|
|
||||||
.Ev VISUAL
|
.Ev VISUAL
|
||||||
|
or
|
||||||
|
.Ev EDITOR
|
||||||
if they match a value specified in
|
if they match a value specified in
|
||||||
.Li editor .
|
.Em editor .
|
||||||
If the
|
If the
|
||||||
.Em env_reset
|
.Em env_reset
|
||||||
flag is enabled, the
|
flag is enabled, the
|
||||||
.Ev EDITOR
|
.Ev SUDO_EDITOR ,
|
||||||
and/or
|
|
||||||
.Ev VISUAL
|
.Ev VISUAL
|
||||||
|
and/or
|
||||||
|
.Ev EDITOR
|
||||||
environment variables must be present in the
|
environment variables must be present in the
|
||||||
.Em env_keep
|
.Em env_keep
|
||||||
list for the
|
list for the
|
||||||
@ -3114,15 +3117,17 @@ separated list of editors allowed to be used with
|
|||||||
.Nm visudo .
|
.Nm visudo .
|
||||||
.Nm visudo
|
.Nm visudo
|
||||||
will choose the editor that matches the user's
|
will choose the editor that matches the user's
|
||||||
.Ev EDITOR
|
.Ev SUDO_EDITOR ,
|
||||||
or
|
|
||||||
.Ev VISUAL
|
.Ev VISUAL
|
||||||
|
or
|
||||||
|
.Ev EDITOR
|
||||||
environment variable if possible, or the first editor in the
|
environment variable if possible, or the first editor in the
|
||||||
list that exists and is executable.
|
list that exists and is executable.
|
||||||
Note that the
|
Note that the
|
||||||
.Ev EDITOR
|
.Ev SUDO_EDITOR ,
|
||||||
and
|
|
||||||
.Ev VISUAL
|
.Ev VISUAL
|
||||||
|
and
|
||||||
|
.Ev EDITOR
|
||||||
environment variables are not preserved by default when the
|
environment variables are not preserved by default when the
|
||||||
.Em env_reset
|
.Em env_reset
|
||||||
option is enabled.
|
option is enabled.
|
||||||
|
@ -13,27 +13,45 @@ DDEESSCCRRIIPPTTIIOONN
|
|||||||
_s_u_d_o_e_r_s file is currently being edited you will receive a message to try
|
_s_u_d_o_e_r_s file is currently being edited you will receive a message to try
|
||||||
again later.
|
again later.
|
||||||
|
|
||||||
There is a hard-coded list of one or more editors that vviissuuddoo will use
|
vviissuuddoo parses the _s_u_d_o_e_r_s file after editing and will not save the
|
||||||
set at compile-time that may be overridden via the _e_d_i_t_o_r _s_u_d_o_e_r_s Default
|
|
||||||
variable. This list defaults to vi. Normally, vviissuuddoo does not honor the
|
|
||||||
VISUAL or EDITOR environment variables unless they contain an editor in
|
|
||||||
the aforementioned editors list. However, if vviissuuddoo is configured with
|
|
||||||
the --with-env-editor option or the _e_n_v___e_d_i_t_o_r Default variable is set in
|
|
||||||
_s_u_d_o_e_r_s, vviissuuddoo will use any the editor defines by VISUAL or EDITOR.
|
|
||||||
Note that this can be a security hole since it allows the user to execute
|
|
||||||
any program they wish simply by setting VISUAL or EDITOR.
|
|
||||||
|
|
||||||
vviissuuddoo parses the _s_u_d_o_e_r_s file after the edit and will not save the
|
|
||||||
changes if there is a syntax error. Upon finding an error, vviissuuddoo will
|
changes if there is a syntax error. Upon finding an error, vviissuuddoo will
|
||||||
print a message stating the line number(s) where the error occurred and
|
print a message stating the line number(s) where the error occurred and
|
||||||
the user will receive the "What now?" prompt. At this point the user may
|
the user will receive the "What now?" prompt. At this point the user may
|
||||||
enter `e' to re-edit the _s_u_d_o_e_r_s file, `x' to exit without saving the
|
enter `e' to re-edit the _s_u_d_o_e_r_s file, `x' to exit without saving the
|
||||||
changes, or `Q' to quit and save changes. The `Q' option should be used
|
changes, or `Q' to quit and save changes. The `Q' option should be used
|
||||||
with extreme care because if vviissuuddoo believes there to be a parse error,
|
with extreme caution because if vviissuuddoo believes there to be a parse
|
||||||
so will ssuuddoo and no one will be able to run ssuuddoo again until the error is
|
error, so will ssuuddoo and no one will be able to run ssuuddoo again until the
|
||||||
fixed. If `e' is typed to edit the _s_u_d_o_e_r_s file after a parse error has
|
error is fixed. If `e' is typed to edit the _s_u_d_o_e_r_s file after a parse
|
||||||
been detected, the cursor will be placed on the line where the error
|
error has been detected, the cursor will be placed on the line where the
|
||||||
occurred (if the editor supports this feature).
|
error occurred (if the editor supports this feature).
|
||||||
|
|
||||||
|
There are two _s_u_d_o_e_r_s settings that determine which editor vviissuuddoo will
|
||||||
|
run.
|
||||||
|
|
||||||
|
editor A colon (`:') separated list of editors allowed to be used with
|
||||||
|
vviissuuddoo. vviissuuddoo will choose the editor that matches the user's
|
||||||
|
SUDO_EDITOR, VISUAL or EDITOR environment variable if possible,
|
||||||
|
or the first editor in the list that exists and is executable.
|
||||||
|
Note that the SUDO_EDITOR, VISUAL and EDITOR environment
|
||||||
|
variables are not preserved by default when the _e_n_v___r_e_s_e_t
|
||||||
|
_s_u_d_o_e_r_s option is enabled. The default editor path is _v_i which
|
||||||
|
can be set at compile time via the --with-editor configure
|
||||||
|
option.
|
||||||
|
|
||||||
|
env_editor
|
||||||
|
If set, vviissuuddoo will use the value of the SUDO_EDITOR, VISUAL or
|
||||||
|
EDITOR environment variables before falling back on the default
|
||||||
|
editor list. Note that this may create a security hole as it
|
||||||
|
allows the user to run any arbitrary command as root without
|
||||||
|
logging. A safer alternative is to place a colon-separated
|
||||||
|
list of editors in the _e_d_i_t_o_r variable. vviissuuddoo will then only
|
||||||
|
use SUDO_EDITOR, VISUAL or EDITOR if they match a value
|
||||||
|
specified in _e_d_i_t_o_r. If the _e_n_v___r_e_s_e_t flag is enabled, the
|
||||||
|
SUDO_EDITOR, VISUAL and/or EDITOR environment variables must be
|
||||||
|
present in the _e_n_v___k_e_e_p list for the _e_n_v___e_d_i_t_o_r flag to
|
||||||
|
function when vviissuuddoo is invoked via ssuuddoo. The default value is
|
||||||
|
_o_f_f, which can be set at compile time via the --with-env-editor
|
||||||
|
configure option.
|
||||||
|
|
||||||
The options are as follows:
|
The options are as follows:
|
||||||
|
|
||||||
@ -128,9 +146,11 @@ EENNVVIIRROONNMMEENNTT
|
|||||||
The following environment variables may be consulted depending on the
|
The following environment variables may be consulted depending on the
|
||||||
value of the _e_d_i_t_o_r and _e_n_v___e_d_i_t_o_r _s_u_d_o_e_r_s settings:
|
value of the _e_d_i_t_o_r and _e_n_v___e_d_i_t_o_r _s_u_d_o_e_r_s settings:
|
||||||
|
|
||||||
VISUAL Invoked by vviissuuddoo as the editor to use
|
SUDO_EDITOR Invoked by vviissuuddoo as the editor to use
|
||||||
|
|
||||||
EDITOR Used by vviissuuddoo if VISUAL is not set
|
VISUAL Used by vviissuuddoo if SUDO_EDITOR is not set
|
||||||
|
|
||||||
|
EDITOR Used by vviissuuddoo if neither SUDO_EDITOR nor VISUAL is set
|
||||||
|
|
||||||
FFIILLEESS
|
FFIILLEESS
|
||||||
_/_e_t_c_/_s_u_d_o_._c_o_n_f Sudo front end configuration
|
_/_e_t_c_/_s_u_d_o_._c_o_n_f Sudo front end configuration
|
||||||
@ -217,4 +237,4 @@ DDIISSCCLLAAIIMMEERR
|
|||||||
file distributed with ssuuddoo or https://www.sudo.ws/license.html for
|
file distributed with ssuuddoo or https://www.sudo.ws/license.html for
|
||||||
complete details.
|
complete details.
|
||||||
|
|
||||||
Sudo 1.8.22 December 6, 2017 Sudo 1.8.22
|
Sudo 1.8.22 December 21, 2017 Sudo 1.8.22
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
.\" Agency (DARPA) and Air Force Research Laboratory, Air Force
|
.\" Agency (DARPA) and Air Force Research Laboratory, Air Force
|
||||||
.\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
|
.\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
|
||||||
.\"
|
.\"
|
||||||
.TH "VISUDO" "8" "December 6, 2017" "Sudo @PACKAGE_VERSION@" "System Manager's Manual"
|
.TH "VISUDO" "8" "December 21, 2017" "Sudo @PACKAGE_VERSION@" "System Manager's Manual"
|
||||||
.nh
|
.nh
|
||||||
.if n .ad l
|
.if n .ad l
|
||||||
.SH "NAME"
|
.SH "NAME"
|
||||||
@ -48,48 +48,10 @@ If the
|
|||||||
\fIsudoers\fR
|
\fIsudoers\fR
|
||||||
file is currently being edited you will receive a message to try again later.
|
file is currently being edited you will receive a message to try again later.
|
||||||
.PP
|
.PP
|
||||||
There is a hard-coded list of one or more editors that
|
|
||||||
\fBvisudo\fR
|
|
||||||
will use set at compile-time that may be overridden via the
|
|
||||||
\fIeditor\fR
|
|
||||||
\fIsudoers\fR
|
|
||||||
\fRDefault\fR
|
|
||||||
variable.
|
|
||||||
This list defaults to
|
|
||||||
\fR@editor@\fR.
|
|
||||||
Normally,
|
|
||||||
\fBvisudo\fR
|
|
||||||
does not honor the
|
|
||||||
\fRVISUAL\fR
|
|
||||||
or
|
|
||||||
\fREDITOR\fR
|
|
||||||
environment variables unless they contain an editor in the aforementioned
|
|
||||||
editors list.
|
|
||||||
However, if
|
|
||||||
\fBvisudo\fR
|
|
||||||
is configured with the
|
|
||||||
\fR--with-env-editor\fR
|
|
||||||
option or the
|
|
||||||
\fIenv_editor\fR
|
|
||||||
\fRDefault\fR
|
|
||||||
variable is set in
|
|
||||||
\fIsudoers\fR,
|
|
||||||
\fBvisudo\fR
|
|
||||||
will use any the editor defines by
|
|
||||||
\fRVISUAL\fR
|
|
||||||
or
|
|
||||||
\fREDITOR\fR.
|
|
||||||
Note that this can be a security hole since it allows the user to
|
|
||||||
execute any program they wish simply by setting
|
|
||||||
\fRVISUAL\fR
|
|
||||||
or
|
|
||||||
\fREDITOR\fR.
|
|
||||||
.PP
|
|
||||||
\fBvisudo\fR
|
\fBvisudo\fR
|
||||||
parses the
|
parses the
|
||||||
\fIsudoers\fR
|
\fIsudoers\fR
|
||||||
file after the edit and will
|
file after editing and will not save the changes if there is a syntax error.
|
||||||
not save the changes if there is a syntax error.
|
|
||||||
Upon finding an error,
|
Upon finding an error,
|
||||||
\fBvisudo\fR
|
\fBvisudo\fR
|
||||||
will print a message stating the line number(s)
|
will print a message stating the line number(s)
|
||||||
@ -107,7 +69,7 @@ to exit without saving the changes, or
|
|||||||
to quit and save changes.
|
to quit and save changes.
|
||||||
The
|
The
|
||||||
\(oqQ\(cq
|
\(oqQ\(cq
|
||||||
option should be used with extreme care because if
|
option should be used with extreme caution because if
|
||||||
\fBvisudo\fR
|
\fBvisudo\fR
|
||||||
believes there to be a parse error, so will
|
believes there to be a parse error, so will
|
||||||
\fBsudo\fR
|
\fBsudo\fR
|
||||||
@ -122,6 +84,84 @@ is typed to edit the
|
|||||||
file after a parse error has been detected, the cursor will be placed on
|
file after a parse error has been detected, the cursor will be placed on
|
||||||
the line where the error occurred (if the editor supports this feature).
|
the line where the error occurred (if the editor supports this feature).
|
||||||
.PP
|
.PP
|
||||||
|
There are two
|
||||||
|
\fIsudoers\fR
|
||||||
|
settings that determine which editor
|
||||||
|
\fBvisudo\fR
|
||||||
|
will run.
|
||||||
|
.TP 10n
|
||||||
|
editor
|
||||||
|
A colon
|
||||||
|
(\(oq:\&\(cq)
|
||||||
|
separated list of editors allowed to be used with
|
||||||
|
\fBvisudo\fR.
|
||||||
|
\fBvisudo\fR
|
||||||
|
will choose the editor that matches the user's
|
||||||
|
\fRSUDO_EDITOR\fR,
|
||||||
|
\fRVISUAL\fR
|
||||||
|
or
|
||||||
|
\fREDITOR\fR
|
||||||
|
environment variable if possible, or the first editor in the
|
||||||
|
list that exists and is executable.
|
||||||
|
Note that the
|
||||||
|
\fRSUDO_EDITOR\fR,
|
||||||
|
\fRVISUAL\fR
|
||||||
|
and
|
||||||
|
\fREDITOR\fR
|
||||||
|
environment variables are not preserved by default when the
|
||||||
|
\fIenv_reset\fR
|
||||||
|
\fIsudoers\fR
|
||||||
|
option is enabled.
|
||||||
|
The default editor path is
|
||||||
|
\fI@editor@\fR
|
||||||
|
which can be set at compile time via the
|
||||||
|
\fR--with-editor\fR
|
||||||
|
configure option.
|
||||||
|
.TP 10n
|
||||||
|
env_editor
|
||||||
|
If set,
|
||||||
|
\fBvisudo\fR
|
||||||
|
will use the value of the
|
||||||
|
\fRSUDO_EDITOR\fR,
|
||||||
|
\fRVISUAL\fR
|
||||||
|
or
|
||||||
|
\fREDITOR\fR
|
||||||
|
environment variables before falling back on the default editor list.
|
||||||
|
Note that this may create a security hole as it allows the user to
|
||||||
|
run any arbitrary command as root without logging.
|
||||||
|
A safer alternative is to place a colon-separated list of editors
|
||||||
|
in the
|
||||||
|
\fIeditor\fR
|
||||||
|
variable.
|
||||||
|
\fBvisudo\fR
|
||||||
|
will then only use
|
||||||
|
\fRSUDO_EDITOR\fR,
|
||||||
|
\fRVISUAL\fR
|
||||||
|
or
|
||||||
|
\fREDITOR\fR
|
||||||
|
if they match a value specified in
|
||||||
|
\fIeditor\fR.
|
||||||
|
If the
|
||||||
|
\fIenv_reset\fR
|
||||||
|
flag is enabled, the
|
||||||
|
\fRSUDO_EDITOR\fR,
|
||||||
|
\fRVISUAL\fR
|
||||||
|
and/or
|
||||||
|
\fREDITOR\fR
|
||||||
|
environment variables must be present in the
|
||||||
|
\fIenv_keep\fR
|
||||||
|
list for the
|
||||||
|
\fIenv_editor\fR
|
||||||
|
flag to function when
|
||||||
|
\fBvisudo\fR
|
||||||
|
is invoked via
|
||||||
|
\fBsudo\fR.
|
||||||
|
The default value is
|
||||||
|
\fI@env_editor@\fR,
|
||||||
|
which can be set at compile time via the
|
||||||
|
\fR--with-env-editor\fR
|
||||||
|
configure option.
|
||||||
|
.PP
|
||||||
The options are as follows:
|
The options are as follows:
|
||||||
.TP 12n
|
.TP 12n
|
||||||
\fB\-c\fR, \fB\--check\fR
|
\fB\-c\fR, \fB\--check\fR
|
||||||
@ -314,17 +354,26 @@ and
|
|||||||
\fIsudoers\fR
|
\fIsudoers\fR
|
||||||
settings:
|
settings:
|
||||||
.TP 17n
|
.TP 17n
|
||||||
\fRVISUAL\fR
|
\fRSUDO_EDITOR\fR
|
||||||
Invoked by
|
Invoked by
|
||||||
\fBvisudo\fR
|
\fBvisudo\fR
|
||||||
as the editor to use
|
as the editor to use
|
||||||
.TP 17n
|
.TP 17n
|
||||||
\fREDITOR\fR
|
\fRVISUAL\fR
|
||||||
Used by
|
Used by
|
||||||
\fBvisudo\fR
|
\fBvisudo\fR
|
||||||
if
|
if
|
||||||
\fRVISUAL\fR
|
\fRSUDO_EDITOR\fR
|
||||||
is not set
|
is not set
|
||||||
|
.TP 17n
|
||||||
|
\fREDITOR\fR
|
||||||
|
Used by
|
||||||
|
\fBvisudo\fR
|
||||||
|
if neither
|
||||||
|
\fRSUDO_EDITOR\fR
|
||||||
|
nor
|
||||||
|
\fRVISUAL\fR
|
||||||
|
is set
|
||||||
.SH "FILES"
|
.SH "FILES"
|
||||||
.TP 26n
|
.TP 26n
|
||||||
\fI@sysconfdir@/sudo.conf\fR
|
\fI@sysconfdir@/sudo.conf\fR
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
.\" Agency (DARPA) and Air Force Research Laboratory, Air Force
|
.\" Agency (DARPA) and Air Force Research Laboratory, Air Force
|
||||||
.\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
|
.\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
|
||||||
.\"
|
.\"
|
||||||
.Dd December 6, 2017
|
.Dd December 21, 2017
|
||||||
.Dt VISUDO @mansectsu@
|
.Dt VISUDO @mansectsu@
|
||||||
.Os Sudo @PACKAGE_VERSION@
|
.Os Sudo @PACKAGE_VERSION@
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -45,48 +45,10 @@ If the
|
|||||||
.Em sudoers
|
.Em sudoers
|
||||||
file is currently being edited you will receive a message to try again later.
|
file is currently being edited you will receive a message to try again later.
|
||||||
.Pp
|
.Pp
|
||||||
There is a hard-coded list of one or more editors that
|
|
||||||
.Nm
|
|
||||||
will use set at compile-time that may be overridden via the
|
|
||||||
.Em editor
|
|
||||||
.Em sudoers
|
|
||||||
.Li Default
|
|
||||||
variable.
|
|
||||||
This list defaults to
|
|
||||||
.Li "@editor@" .
|
|
||||||
Normally,
|
|
||||||
.Nm
|
|
||||||
does not honor the
|
|
||||||
.Ev VISUAL
|
|
||||||
or
|
|
||||||
.Ev EDITOR
|
|
||||||
environment variables unless they contain an editor in the aforementioned
|
|
||||||
editors list.
|
|
||||||
However, if
|
|
||||||
.Nm
|
|
||||||
is configured with the
|
|
||||||
.Li --with-env-editor
|
|
||||||
option or the
|
|
||||||
.Em env_editor
|
|
||||||
.Li Default
|
|
||||||
variable is set in
|
|
||||||
.Em sudoers ,
|
|
||||||
.Nm
|
|
||||||
will use any the editor defines by
|
|
||||||
.Ev VISUAL
|
|
||||||
or
|
|
||||||
.Ev EDITOR .
|
|
||||||
Note that this can be a security hole since it allows the user to
|
|
||||||
execute any program they wish simply by setting
|
|
||||||
.Ev VISUAL
|
|
||||||
or
|
|
||||||
.Ev EDITOR .
|
|
||||||
.Pp
|
|
||||||
.Nm
|
.Nm
|
||||||
parses the
|
parses the
|
||||||
.Em sudoers
|
.Em sudoers
|
||||||
file after the edit and will
|
file after editing and will not save the changes if there is a syntax error.
|
||||||
not save the changes if there is a syntax error.
|
|
||||||
Upon finding an error,
|
Upon finding an error,
|
||||||
.Nm
|
.Nm
|
||||||
will print a message stating the line number(s)
|
will print a message stating the line number(s)
|
||||||
@ -104,7 +66,7 @@ to exit without saving the changes, or
|
|||||||
to quit and save changes.
|
to quit and save changes.
|
||||||
The
|
The
|
||||||
.Ql Q
|
.Ql Q
|
||||||
option should be used with extreme care because if
|
option should be used with extreme caution because if
|
||||||
.Nm
|
.Nm
|
||||||
believes there to be a parse error, so will
|
believes there to be a parse error, so will
|
||||||
.Nm sudo
|
.Nm sudo
|
||||||
@ -119,6 +81,84 @@ is typed to edit the
|
|||||||
file after a parse error has been detected, the cursor will be placed on
|
file after a parse error has been detected, the cursor will be placed on
|
||||||
the line where the error occurred (if the editor supports this feature).
|
the line where the error occurred (if the editor supports this feature).
|
||||||
.Pp
|
.Pp
|
||||||
|
There are two
|
||||||
|
.Em sudoers
|
||||||
|
settings that determine which editor
|
||||||
|
.Nm visudo
|
||||||
|
will run.
|
||||||
|
.Bl -tag -width 8n
|
||||||
|
.It editor
|
||||||
|
A colon
|
||||||
|
.Pq Ql :\&
|
||||||
|
separated list of editors allowed to be used with
|
||||||
|
.Nm .
|
||||||
|
.Nm
|
||||||
|
will choose the editor that matches the user's
|
||||||
|
.Ev SUDO_EDITOR ,
|
||||||
|
.Ev VISUAL
|
||||||
|
or
|
||||||
|
.Ev EDITOR
|
||||||
|
environment variable if possible, or the first editor in the
|
||||||
|
list that exists and is executable.
|
||||||
|
Note that the
|
||||||
|
.Ev SUDO_EDITOR ,
|
||||||
|
.Ev VISUAL
|
||||||
|
and
|
||||||
|
.Ev EDITOR
|
||||||
|
environment variables are not preserved by default when the
|
||||||
|
.Em env_reset
|
||||||
|
.Em sudoers
|
||||||
|
option is enabled.
|
||||||
|
The default editor path is
|
||||||
|
.Pa @editor@
|
||||||
|
which can be set at compile time via the
|
||||||
|
.Li --with-editor
|
||||||
|
configure option.
|
||||||
|
.It env_editor
|
||||||
|
If set,
|
||||||
|
.Nm
|
||||||
|
will use the value of the
|
||||||
|
.Ev SUDO_EDITOR ,
|
||||||
|
.Ev VISUAL
|
||||||
|
or
|
||||||
|
.Ev EDITOR
|
||||||
|
environment variables before falling back on the default editor list.
|
||||||
|
Note that this may create a security hole as it allows the user to
|
||||||
|
run any arbitrary command as root without logging.
|
||||||
|
A safer alternative is to place a colon-separated list of editors
|
||||||
|
in the
|
||||||
|
.Em editor
|
||||||
|
variable.
|
||||||
|
.Nm
|
||||||
|
will then only use
|
||||||
|
.Ev SUDO_EDITOR ,
|
||||||
|
.Ev VISUAL
|
||||||
|
or
|
||||||
|
.Ev EDITOR
|
||||||
|
if they match a value specified in
|
||||||
|
.Em editor .
|
||||||
|
If the
|
||||||
|
.Em env_reset
|
||||||
|
flag is enabled, the
|
||||||
|
.Ev SUDO_EDITOR ,
|
||||||
|
.Ev VISUAL
|
||||||
|
and/or
|
||||||
|
.Ev EDITOR
|
||||||
|
environment variables must be present in the
|
||||||
|
.Em env_keep
|
||||||
|
list for the
|
||||||
|
.Em env_editor
|
||||||
|
flag to function when
|
||||||
|
.Nm
|
||||||
|
is invoked via
|
||||||
|
.Nm sudo .
|
||||||
|
The default value is
|
||||||
|
.Em @env_editor@ ,
|
||||||
|
which can be set at compile time via the
|
||||||
|
.Li --with-env-editor
|
||||||
|
configure option.
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
The options are as follows:
|
The options are as follows:
|
||||||
.Bl -tag -width Fl
|
.Bl -tag -width Fl
|
||||||
.It Fl c , -check
|
.It Fl c , -check
|
||||||
@ -301,16 +341,24 @@ and
|
|||||||
.Em sudoers
|
.Em sudoers
|
||||||
settings:
|
settings:
|
||||||
.Bl -tag -width 15n
|
.Bl -tag -width 15n
|
||||||
.It Ev VISUAL
|
.It Ev SUDO_EDITOR
|
||||||
Invoked by
|
Invoked by
|
||||||
.Nm
|
.Nm
|
||||||
as the editor to use
|
as the editor to use
|
||||||
.It Ev EDITOR
|
.It Ev VISUAL
|
||||||
Used by
|
Used by
|
||||||
.Nm
|
.Nm
|
||||||
if
|
if
|
||||||
.Ev VISUAL
|
.Ev SUDO_EDITOR
|
||||||
is not set
|
is not set
|
||||||
|
.It Ev EDITOR
|
||||||
|
Used by
|
||||||
|
.Nm
|
||||||
|
if neither
|
||||||
|
.Ev SUDO_EDITOR
|
||||||
|
nor
|
||||||
|
.Ev VISUAL
|
||||||
|
is set
|
||||||
.El
|
.El
|
||||||
.Sh FILES
|
.Sh FILES
|
||||||
.Bl -tag -width 24n
|
.Bl -tag -width 24n
|
||||||
|
@ -36,11 +36,12 @@
|
|||||||
* the result against whitelist if non-NULL. An argument vector
|
* the result against whitelist if non-NULL. An argument vector
|
||||||
* suitable for execve() is allocated and stored in argv_out.
|
* suitable for execve() is allocated and stored in argv_out.
|
||||||
* If nfiles is non-zero, files[] is added to the end of argv_out.
|
* If nfiles is non-zero, files[] is added to the end of argv_out.
|
||||||
|
*
|
||||||
* Returns the path to be executed on success, else NULL.
|
* Returns the path to be executed on success, else NULL.
|
||||||
* The caller is responsible for freeing the returned editor path
|
* The caller is responsible for freeing the returned editor path
|
||||||
* as well as the argument vector.
|
* as well as the argument vector.
|
||||||
*/
|
*/
|
||||||
char *
|
static char *
|
||||||
resolve_editor(const char *ed, size_t edlen, int nfiles, char **files,
|
resolve_editor(const char *ed, size_t edlen, int nfiles, char **files,
|
||||||
int *argc_out, char ***argv_out, char * const *whitelist)
|
int *argc_out, char ***argv_out, char * const *whitelist)
|
||||||
{
|
{
|
||||||
@ -109,3 +110,65 @@ resolve_editor(const char *ed, size_t edlen, int nfiles, char **files,
|
|||||||
*argv_out = nargv;
|
*argv_out = nargv;
|
||||||
debug_return_str(editor_path);
|
debug_return_str(editor_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Determine which editor to use based on the SUDO_EDITOR, VISUAL and
|
||||||
|
* EDITOR environment variables as well as the editor path in sudoers.
|
||||||
|
* If env_error is true, an editor environment variable that cannot be
|
||||||
|
* resolved is an error.
|
||||||
|
*
|
||||||
|
* Returns the path to be executed on success, else NULL.
|
||||||
|
* The caller is responsible for freeing the returned editor path
|
||||||
|
* as well as the argument vector.
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
find_editor(int nfiles, char **files, int *argc_out, char ***argv_out,
|
||||||
|
char * const *whitelist, const char **env_editor, bool env_error)
|
||||||
|
{
|
||||||
|
char *ev[3], *editor_path = NULL;
|
||||||
|
unsigned int i;
|
||||||
|
debug_decl(find_editor, SUDOERS_DEBUG_UTIL)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If any of SUDO_EDITOR, VISUAL or EDITOR are set, choose the first one.
|
||||||
|
*/
|
||||||
|
*env_editor = NULL;
|
||||||
|
ev[0] = "SUDO_EDITOR";
|
||||||
|
ev[1] = "VISUAL";
|
||||||
|
ev[2] = "EDITOR";
|
||||||
|
for (i = 0; i < nitems(ev); i++) {
|
||||||
|
char *editor = getenv(ev[i]);
|
||||||
|
|
||||||
|
if (editor != NULL && *editor != '\0') {
|
||||||
|
*env_editor = editor;
|
||||||
|
editor_path = resolve_editor(editor, strlen(editor),
|
||||||
|
nfiles, files, argc_out, argv_out, whitelist);
|
||||||
|
if (editor_path != NULL)
|
||||||
|
break;
|
||||||
|
if (errno != ENOENT)
|
||||||
|
debug_return_str(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (editor_path == NULL) {
|
||||||
|
const char *def_editor_end = def_editor + strlen(def_editor);
|
||||||
|
const char *cp, *ep;
|
||||||
|
|
||||||
|
if (env_error && *env_editor != NULL) {
|
||||||
|
/* User-specified editor could not be found. */
|
||||||
|
debug_return_str(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* def_editor could be a path, split it up, avoiding strtok() */
|
||||||
|
for (cp = sudo_strsplit(def_editor, def_editor_end, ":", &ep);
|
||||||
|
cp != NULL; cp = sudo_strsplit(NULL, def_editor_end, ":", &ep)) {
|
||||||
|
editor_path = resolve_editor(cp, (size_t)(ep - cp), nfiles,
|
||||||
|
files, argc_out, argv_out, whitelist);
|
||||||
|
if (editor_path != NULL)
|
||||||
|
break;
|
||||||
|
if (errno != ENOENT)
|
||||||
|
debug_return_str(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
debug_return_str(editor_path);
|
||||||
|
}
|
||||||
|
@ -68,7 +68,6 @@
|
|||||||
/*
|
/*
|
||||||
* Prototypes
|
* Prototypes
|
||||||
*/
|
*/
|
||||||
static char *find_editor(int nfiles, char **files, int *argc_out, char ***argv_out);
|
|
||||||
static bool cb_fqdn(const union sudo_defs_val *);
|
static bool cb_fqdn(const union sudo_defs_val *);
|
||||||
static bool cb_runas_default(const union sudo_defs_val *);
|
static bool cb_runas_default(const union sudo_defs_val *);
|
||||||
static bool cb_tty_tickets(const union sudo_defs_val *);
|
static bool cb_tty_tickets(const union sudo_defs_val *);
|
||||||
@ -622,13 +621,18 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
|
|||||||
/* Note: must call audit before uid change. */
|
/* Note: must call audit before uid change. */
|
||||||
if (ISSET(sudo_mode, MODE_EDIT)) {
|
if (ISSET(sudo_mode, MODE_EDIT)) {
|
||||||
int edit_argc;
|
int edit_argc;
|
||||||
|
const char *env_editor;
|
||||||
|
|
||||||
free(safe_cmnd);
|
free(safe_cmnd);
|
||||||
safe_cmnd = find_editor(NewArgc - 1, NewArgv + 1, &edit_argc,
|
safe_cmnd = find_editor(NewArgc - 1, NewArgv + 1, &edit_argc,
|
||||||
&edit_argv);
|
&edit_argv, NULL, &env_editor, false);
|
||||||
if (safe_cmnd == NULL) {
|
if (safe_cmnd == NULL) {
|
||||||
if (errno != ENOENT)
|
if (errno != ENOENT)
|
||||||
goto done;
|
goto done;
|
||||||
|
audit_failure(NewArgc, NewArgv, N_("%s: command not found"),
|
||||||
|
env_editor ? env_editor : def_editor);
|
||||||
|
sudo_warnx(U_("%s: command not found"),
|
||||||
|
env_editor ? env_editor : def_editor);
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
if (audit_success(edit_argc, edit_argv) != 0 && !def_ignore_audit_errors)
|
if (audit_success(edit_argc, edit_argv) != 0 && !def_ignore_audit_errors)
|
||||||
@ -1252,58 +1256,6 @@ sudoers_cleanup(void)
|
|||||||
debug_return;
|
debug_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Determine which editor to use. We don't need to worry about restricting
|
|
||||||
* this to a "safe" editor since it runs with the uid of the invoking user,
|
|
||||||
* not the runas (privileged) user.
|
|
||||||
* Returns a fully-qualified path to the editor on success and fills
|
|
||||||
* in argc_out and argv_out accordingly. Returns NULL on failure.
|
|
||||||
*/
|
|
||||||
static char *
|
|
||||||
find_editor(int nfiles, char **files, int *argc_out, char ***argv_out)
|
|
||||||
{
|
|
||||||
const char *cp, *ep, *editor = NULL;
|
|
||||||
char *editor_path = NULL, **ev, *ev0[4];
|
|
||||||
debug_decl(find_editor, SUDOERS_DEBUG_PLUGIN)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If any of SUDO_EDITOR, VISUAL or EDITOR are set, choose the first one.
|
|
||||||
*/
|
|
||||||
ev0[0] = "SUDO_EDITOR";
|
|
||||||
ev0[1] = "VISUAL";
|
|
||||||
ev0[2] = "EDITOR";
|
|
||||||
ev0[3] = NULL;
|
|
||||||
for (ev = ev0; editor_path == NULL && *ev != NULL; ev++) {
|
|
||||||
if ((editor = getenv(*ev)) != NULL && *editor != '\0') {
|
|
||||||
editor_path = resolve_editor(editor, strlen(editor),
|
|
||||||
nfiles, files, argc_out, argv_out, NULL);
|
|
||||||
if (editor_path != NULL)
|
|
||||||
break;
|
|
||||||
if (errno != ENOENT)
|
|
||||||
debug_return_str(NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (editor_path == NULL) {
|
|
||||||
/* def_editor could be a path, split it up, avoiding strtok() */
|
|
||||||
const char *def_editor_end = def_editor + strlen(def_editor);
|
|
||||||
for (cp = sudo_strsplit(def_editor, def_editor_end, ":", &ep);
|
|
||||||
cp != NULL; cp = sudo_strsplit(NULL, def_editor_end, ":", &ep)) {
|
|
||||||
editor_path = resolve_editor(cp, (size_t)(ep - cp), nfiles,
|
|
||||||
files, argc_out, argv_out, NULL);
|
|
||||||
if (editor_path != NULL)
|
|
||||||
break;
|
|
||||||
if (errno != ENOENT)
|
|
||||||
debug_return_str(NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!editor_path) {
|
|
||||||
audit_failure(NewArgc, NewArgv, N_("%s: command not found"),
|
|
||||||
editor ? editor : def_editor);
|
|
||||||
sudo_warnx(U_("%s: command not found"), editor ? editor : def_editor);
|
|
||||||
}
|
|
||||||
debug_return_str(editor_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef USE_ADMIN_FLAG
|
#ifdef USE_ADMIN_FLAG
|
||||||
static int
|
static int
|
||||||
create_admin_success_flag(void)
|
create_admin_success_flag(void)
|
||||||
|
@ -403,8 +403,8 @@ bool cb_group_plugin(const union sudo_defs_val *sd_un);
|
|||||||
extern const char *path_plugin_dir;
|
extern const char *path_plugin_dir;
|
||||||
|
|
||||||
/* editor.c */
|
/* editor.c */
|
||||||
char *resolve_editor(const char *ed, size_t edlen, int nfiles, char **files,
|
char *find_editor(int nfiles, char **files, int *argc_out, char ***argv_out,
|
||||||
int *argc_out, char ***argv_out, char * const *whitelist);
|
char * const *whitelist, const char **env_editor, bool env_error);
|
||||||
|
|
||||||
/* mkdir_parents.c */
|
/* mkdir_parents.c */
|
||||||
bool sudo_mkdir_parents(char *path, uid_t uid, gid_t gid, mode_t mode, bool quiet);
|
bool sudo_mkdir_parents(char *path, uid_t uid, gid_t gid, mode_t mode, bool quiet);
|
||||||
|
@ -289,7 +289,8 @@ done:
|
|||||||
static char *
|
static char *
|
||||||
get_editor(int *editor_argc, char ***editor_argv)
|
get_editor(int *editor_argc, char ***editor_argv)
|
||||||
{
|
{
|
||||||
char *editor, *editor_path = NULL, **whitelist = NULL;
|
char *editor_path = NULL, **whitelist = NULL;
|
||||||
|
const char *env_editor;
|
||||||
static char *files[] = { "+1", "sudoers" };
|
static char *files[] = { "+1", "sudoers" };
|
||||||
unsigned int whitelist_len = 0;
|
unsigned int whitelist_len = 0;
|
||||||
debug_decl(get_editor, SUDOERS_DEBUG_UTIL)
|
debug_decl(get_editor, SUDOERS_DEBUG_UTIL)
|
||||||
@ -318,37 +319,16 @@ get_editor(int *editor_argc, char ***editor_argv)
|
|||||||
whitelist[whitelist_len] = NULL;
|
whitelist[whitelist_len] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* First try to use user's VISUAL or EDITOR environment vars. */
|
editor_path = find_editor(2, files, editor_argc, editor_argv, whitelist,
|
||||||
if ((editor = getenv("VISUAL")) == NULL || *editor == '\0')
|
&env_editor, true);
|
||||||
editor = getenv("EDITOR");
|
|
||||||
if (editor && *editor == '\0')
|
|
||||||
editor = NULL;
|
|
||||||
if (editor != NULL) {
|
|
||||||
editor_path = resolve_editor(editor, strlen(editor), 2, files,
|
|
||||||
editor_argc, editor_argv, whitelist);
|
|
||||||
if (def_env_editor && editor_path == NULL) {
|
|
||||||
/* If we are honoring $EDITOR this is a fatal error. */
|
|
||||||
sudo_fatalx(U_("specified editor (%s) doesn't exist"), editor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (editor_path == NULL) {
|
if (editor_path == NULL) {
|
||||||
/* def_editor could be a path, split it up, avoiding strtok() */
|
if (def_env_editor && env_editor != NULL) {
|
||||||
const char *def_editor_end = def_editor + strlen(def_editor);
|
/* We are honoring $EDITOR so this is a fatal error. */
|
||||||
const char *cp, *ep;
|
sudo_fatalx(U_("specified editor (%s) doesn't exist"), env_editor);
|
||||||
for (cp = sudo_strsplit(def_editor, def_editor_end, ":", &ep);
|
|
||||||
cp != NULL; cp = sudo_strsplit(NULL, def_editor_end, ":", &ep)) {
|
|
||||||
editor_path = resolve_editor(cp, (size_t)(ep - cp), 2, files,
|
|
||||||
editor_argc, editor_argv, whitelist);
|
|
||||||
if (editor_path != NULL)
|
|
||||||
break;
|
|
||||||
if (errno != ENOENT)
|
|
||||||
goto done;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (editor_path == NULL)
|
|
||||||
sudo_fatalx(U_("no editor found (editor path = %s)"), def_editor);
|
sudo_fatalx(U_("no editor found (editor path = %s)"), def_editor);
|
||||||
|
}
|
||||||
|
|
||||||
done:
|
|
||||||
if (whitelist != NULL) {
|
if (whitelist != NULL) {
|
||||||
while (whitelist_len--)
|
while (whitelist_len--)
|
||||||
free(whitelist[whitelist_len]);
|
free(whitelist[whitelist_len]);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user