mirror of
https://github.com/sudo-project/sudo.git
synced 2025-08-22 01:49:11 +00:00
Do not follow symbolic links in sudoedit by default. This behavior
can be controlled by the sudoedit_follow Defaults flag as well as the FOLLOW/NOFOLLOW tags.
This commit is contained in:
parent
079167d2c4
commit
3354d27a17
@ -1,6 +1,13 @@
|
||||
Notes on upgrading from an older release
|
||||
========================================
|
||||
|
||||
o Upgrading from a version prior to 1.8.15:
|
||||
|
||||
When editing files with sudoedit, symbolic links will no longer
|
||||
be followed by default. The old behavior can be restored by
|
||||
enabling the sudoedit_follow option in sudoers or on a per-command
|
||||
basis with the FOLLOW and NOFOLLOW tags.
|
||||
|
||||
o Upgrading from a version prior to 1.8.14:
|
||||
|
||||
On HP-UX, sudo will no longer check for "plugin.sl" if "plugin.so"
|
||||
|
@ -124,6 +124,13 @@ DDEESSCCRRIIPPTTIIOONN
|
||||
copied back to their original location and the
|
||||
temporary versions are removed.
|
||||
|
||||
Unless explicitly allowed by the security policy, symbolic
|
||||
links will not be opened. This helps prevent the editing of
|
||||
unauthorized files when the file is located in a user-
|
||||
writable directory. Versions of ssuuddoo prior to 1.8.15 do not
|
||||
have this restriction. Users are never allowed to edit
|
||||
device special files.
|
||||
|
||||
If the specified file does not exist, it will be created.
|
||||
Note that unlike most commands run by _s_u_d_o, the editor is run
|
||||
with the invoking user's environment unmodified. If, for
|
||||
@ -585,4 +592,4 @@ DDIISSCCLLAAIIMMEERR
|
||||
file distributed with ssuuddoo or http://www.sudo.ws/license.html for
|
||||
complete details.
|
||||
|
||||
Sudo 1.8.14 July 10, 2015 Sudo 1.8.14
|
||||
Sudo 1.8.15 August 6, 2015 Sudo 1.8.15
|
||||
|
@ -21,7 +21,7 @@
|
||||
.\" Agency (DARPA) and Air Force Research Laboratory, Air Force
|
||||
.\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
|
||||
.\"
|
||||
.TH "SUDO" "8" "July 10, 2015" "Sudo @PACKAGE_VERSION@" "System Manager's Manual"
|
||||
.TH "SUDO" "8" "August 6, 2015" "Sudo @PACKAGE_VERSION@" "System Manager's Manual"
|
||||
.nh
|
||||
.if n .ad l
|
||||
.SH "NAME"
|
||||
@ -292,6 +292,15 @@ their original location and the temporary versions are removed.
|
||||
.RE
|
||||
.RS 12n
|
||||
.sp
|
||||
Unless explicitly allowed by the security policy, symbolic links
|
||||
will not be opened.
|
||||
This helps prevent the editing of unauthorized files when the file
|
||||
is located in a user-writable directory.
|
||||
Versions of
|
||||
\fBsudo\fR
|
||||
prior to 1.8.15 do not have this restriction.
|
||||
Users are never allowed to edit device special files.
|
||||
.sp
|
||||
If the specified file does not exist, it will be created.
|
||||
Note that unlike most commands run by
|
||||
\fIsudo\fR,
|
||||
|
@ -19,7 +19,7 @@
|
||||
.\" Agency (DARPA) and Air Force Research Laboratory, Air Force
|
||||
.\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
|
||||
.\"
|
||||
.Dd July 10, 2015
|
||||
.Dd August 6, 2015
|
||||
.Dt SUDO @mansectsu@
|
||||
.Os Sudo @PACKAGE_VERSION@
|
||||
.Sh NAME
|
||||
@ -265,6 +265,15 @@ If they have been modified, the temporary files are copied back to
|
||||
their original location and the temporary versions are removed.
|
||||
.El
|
||||
.Pp
|
||||
Unless explicitly allowed by the security policy, symbolic links
|
||||
will not be opened.
|
||||
This helps prevent the editing of unauthorized files when the file
|
||||
is located in a user-writable directory.
|
||||
Versions of
|
||||
.Nm
|
||||
prior to 1.8.15 do not have this restriction.
|
||||
Users are never allowed to edit device special files.
|
||||
.Pp
|
||||
If the specified file does not exist, it will be created.
|
||||
Note that unlike most commands run by
|
||||
.Em sudo ,
|
||||
|
@ -606,6 +606,14 @@ DDEESSCCRRIIPPTTIIOONN
|
||||
substitution and transparently enable _s_u_d_o_e_d_i_t when the
|
||||
user attempts to run an editor.
|
||||
|
||||
sudoedit_follow=bool
|
||||
Set to true to allow ssuuddooeeddiitt to edit files that are
|
||||
symbolic links. By default, ssuuddooeeddiitt 1.8.15 and higher
|
||||
will refuse to open a symbolic link. The
|
||||
_s_u_d_o_e_d_i_t___f_o_l_l_o_w option can be used to restore the older
|
||||
behavior and allow ssuuddooeeddiitt to open symbolic links.
|
||||
Only available starting with API version 1.8.
|
||||
|
||||
timeout=int
|
||||
Command timeout. If non-zero then when the timeout
|
||||
expires the command will be killed.
|
||||
@ -1479,6 +1487,9 @@ PPLLUUGGIINN AAPPII CCHHAANNGGEELLOOGG
|
||||
may occur multiple times if there are multiple plugin-specific
|
||||
Debug lines in the sudo.conf(4) file.
|
||||
|
||||
Version 1.8 (sudo 1.8.15)
|
||||
The _s_u_d_o_e_d_i_t___f_o_l_l_o_w entry was added to the command_info list.
|
||||
|
||||
SSEEEE AALLSSOO
|
||||
sudo.conf(4), sudoers(4), sudo(1m)
|
||||
|
||||
@ -1508,4 +1519,4 @@ DDIISSCCLLAAIIMMEERR
|
||||
file distributed with ssuuddoo or http://www.sudo.ws/license.html for
|
||||
complete details.
|
||||
|
||||
Sudo 1.8.14 December 4, 2014 Sudo 1.8.14
|
||||
Sudo 1.8.15 August 6, 2015 Sudo 1.8.15
|
||||
|
@ -16,7 +16,7 @@
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.TH "SUDO_PLUGIN" "5" "December 4, 2014" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
|
||||
.TH "SUDO_PLUGIN" "5" "August 6, 2015" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
|
||||
.nh
|
||||
.if n .ad l
|
||||
.SH "NAME"
|
||||
@ -999,6 +999,20 @@ enable
|
||||
\fIsudoedit\fR
|
||||
when the user attempts to run an editor.
|
||||
.TP 6n
|
||||
sudoedit_follow=bool
|
||||
Set to true to allow
|
||||
\fBsudoedit\fR
|
||||
to edit files that are symbolic links.
|
||||
By default,
|
||||
\fBsudoedit\fR
|
||||
1.8.15 and higher will refuse to open a symbolic link.
|
||||
The
|
||||
\fIsudoedit_follow\fR
|
||||
option can be used to restore the older behavior and allow
|
||||
\fBsudoedit\fR
|
||||
to open symbolic links.
|
||||
Only available starting with API version 1.8.
|
||||
.TP 6n
|
||||
timeout=int
|
||||
Command timeout.
|
||||
If non-zero then when the timeout expires the command will be killed.
|
||||
@ -2641,6 +2655,13 @@ The
|
||||
entry now starts with a debug file path name and may occur multiple
|
||||
times if there are multiple plugin-specific Debug lines in the
|
||||
sudo.conf(@mansectform@) file.
|
||||
.TP 6n
|
||||
Version 1.8 (sudo 1.8.15)
|
||||
The
|
||||
\fIsudoedit_follow\fR
|
||||
entry was added to the
|
||||
\fRcommand_info\fR
|
||||
list.
|
||||
.SH "SEE ALSO"
|
||||
sudo.conf(@mansectform@),
|
||||
sudoers(@mansectform@),
|
||||
|
@ -14,7 +14,7 @@
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd December 4, 2014
|
||||
.Dd August 6, 2015
|
||||
.Dt SUDO_PLUGIN @mansectform@
|
||||
.Os Sudo @PACKAGE_VERSION@
|
||||
.Sh NAME
|
||||
@ -881,6 +881,19 @@ This allows the plugin to perform command substitution and transparently
|
||||
enable
|
||||
.Em sudoedit
|
||||
when the user attempts to run an editor.
|
||||
.It sudoedit_follow=bool
|
||||
Set to true to allow
|
||||
.Nm sudoedit
|
||||
to edit files that are symbolic links.
|
||||
By default,
|
||||
.Nm sudoedit
|
||||
1.8.15 and higher will refuse to open a symbolic link.
|
||||
The
|
||||
.Em sudoedit_follow
|
||||
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 timeout=int
|
||||
Command timeout.
|
||||
If non-zero then when the timeout expires the command will be killed.
|
||||
@ -2310,6 +2323,12 @@ The
|
||||
entry now starts with a debug file path name and may occur multiple
|
||||
times if there are multiple plugin-specific Debug lines in the
|
||||
.Xr sudo.conf @mansectform@ file.
|
||||
.It Version 1.8 (sudo 1.8.15)
|
||||
The
|
||||
.Em sudoedit_follow
|
||||
entry was added to the
|
||||
.Li command_info
|
||||
list.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr sudo.conf @mansectform@ ,
|
||||
|
@ -465,9 +465,10 @@ SSUUDDOOEERRSS FFIILLEE FFOORRMMAATT
|
||||
|
||||
Solaris_Priv_Spec ::= ('PRIVS=privset' | 'LIMITPRIVS=privset')
|
||||
|
||||
Tag_Spec ::= ('NOEXEC:' | 'EXEC:' | 'LOG_INPUT:' | 'NOLOG_INPUT:' |
|
||||
'LOG_OUTPUT:' | 'NOLOG_OUTPUT:' | 'MAIL:' | 'NOMAIL:' |
|
||||
'NOPASSWD:' | 'PASSWD:' | 'SETENV:' | 'NOSETENV:')
|
||||
Tag_Spec ::= ('EXEC:' | 'NOEXEC:' | 'FOLLOW:' | 'NOFOLLOW' |
|
||||
'LOG_INPUT:' | 'NOLOG_INPUT:' | 'LOG_OUTPUT:' |
|
||||
'NOLOG_OUTPUT:' | 'MAIL:' | 'NOMAIL:' | 'PASSWD:' |
|
||||
'NOPASSWD:' | 'SETENV:' | 'NOSETENV:')
|
||||
|
||||
A uusseerr ssppeecciiffiiccaattiioonn determines which commands a user may run (and as
|
||||
what user) on specified hosts. By default, commands are run as rroooott, but
|
||||
@ -581,13 +582,14 @@ SSUUDDOOEERRSS FFIILLEE FFOORRMMAATT
|
||||
|
||||
TTaagg__SSppeecc
|
||||
A command may have zero or more tags associated with it. There are ten
|
||||
possible tag values: NOEXEC, EXEC, LOG_INPUT, NOLOG_INPUT, LOG_OUTPUT,
|
||||
NOLOG_OUTPUT, MAIL, NOMAIL, NOPASSWD, PASSWD, SETENV, and NOSETENV. Once
|
||||
a tag is set on a Cmnd, subsequent Cmnds in the Cmnd_Spec_List, inherit
|
||||
the tag unless it is overridden by the opposite tag (in other words,
|
||||
PASSWD overrides NOPASSWD and NOEXEC overrides EXEC).
|
||||
possible tag values: EXEC, NOEXEC, FOLLOW, NOFOLLOW, LOG_INPUT,
|
||||
NOLOG_INPUT, LOG_OUTPUT, NOLOG_OUTPUT, MAIL, NOMAIL, PASSWD, NOPASSWD,
|
||||
SETENV, and NOSETENV. Once a tag is set on a Cmnd, subsequent Cmnds in
|
||||
the Cmnd_Spec_List, inherit the tag unless it is overridden by the
|
||||
opposite tag (in other words, PASSWD overrides NOPASSWD and NOEXEC
|
||||
overrides EXEC).
|
||||
|
||||
_N_O_E_X_E_C and _E_X_E_C
|
||||
_E_X_E_C and _N_O_E_X_E_C
|
||||
|
||||
If ssuuddoo has been compiled with _n_o_e_x_e_c support and the underlying
|
||||
operating system supports it, the NOEXEC tag can be used to prevent a
|
||||
@ -601,6 +603,13 @@ SSUUDDOOEERRSS FFIILLEE FFOORRMMAATT
|
||||
See the _P_r_e_v_e_n_t_i_n_g _s_h_e_l_l _e_s_c_a_p_e_s section below for more details on how
|
||||
NOEXEC works and whether or not it will work on your system.
|
||||
|
||||
_F_O_L_L_O_W and _N_O_F_O_L_L_O_W Starting with version 1.8.15, ssuuddooeeddiitt will not
|
||||
follow symbolic links when opening files unless the _s_u_d_o_e_d_i_t___f_o_l_l_o_w
|
||||
option is enabled. The _F_O_L_L_O_W and _N_O_F_O_L_L_O_W tags override the value of
|
||||
_s_u_d_o_e_d_i_t___f_o_l_l_o_w and can be used to permit (or deny) the editing of
|
||||
symbolic links on a per-command basis. These tags are only effective
|
||||
for the _s_u_d_o_e_d_i_t command and are ignored for all other commands.
|
||||
|
||||
_L_O_G___I_N_P_U_T and _N_O_L_O_G___I_N_P_U_T
|
||||
|
||||
These tags override the value of the _l_o_g___i_n_p_u_t option on a per-command
|
||||
@ -623,7 +632,7 @@ SSUUDDOOEERRSS FFIILLEE FFOORRMMAATT
|
||||
the descriptions of _m_a_i_l___a_l_l___c_m_n_d_s, _m_a_i_l___a_l_w_a_y_s, and _m_a_i_l___n_o___p_e_r_m_s in
|
||||
the _S_U_D_O_E_R_S _O_P_T_I_O_N_S section below.
|
||||
|
||||
_N_O_P_A_S_S_W_D and _P_A_S_S_W_D
|
||||
_P_A_S_S_W_D and _N_O_P_A_S_S_W_D
|
||||
|
||||
By default, ssuuddoo requires that a user authenticate him or herself
|
||||
before running a command. This behavior can be modified via the
|
||||
@ -1248,6 +1257,15 @@ SSUUDDOOEERRSS OOPPTTIIOONNSS
|
||||
that support either the setreuid(2) or setresuid(2)
|
||||
system call. This flag is _o_f_f by default.
|
||||
|
||||
sudoedit_follow By default, ssuuddooeeddiitt will not follow symbolic links
|
||||
when opening files. The _s_u_d_o_e_d_i_t___f_o_l_l_o_w option can be
|
||||
enabled to allow ssuuddooeeddiitt to open symbolic links. It
|
||||
may be overridden on a per-command basis by the _F_O_L_L_O_W
|
||||
and _N_O_F_O_L_L_O_W tags. This flag is _o_f_f by default.
|
||||
|
||||
This setting is only supported by version 1.8.15 or
|
||||
higher.
|
||||
|
||||
targetpw If set, ssuuddoo will prompt for the password of the user
|
||||
specified by the --uu option (defaults to root) instead
|
||||
of the password of the invoking user when running a
|
||||
@ -2417,4 +2435,4 @@ DDIISSCCLLAAIIMMEERR
|
||||
file distributed with ssuuddoo or http://www.sudo.ws/license.html for
|
||||
complete details.
|
||||
|
||||
Sudo 1.8.14 August 4, 2015 Sudo 1.8.14
|
||||
Sudo 1.8.15 August 6, 2015 Sudo 1.8.15
|
||||
|
@ -21,7 +21,7 @@
|
||||
.\" Agency (DARPA) and Air Force Research Laboratory, Air Force
|
||||
.\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
|
||||
.\"
|
||||
.TH "SUDOERS" "5" "August 4, 2015" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
|
||||
.TH "SUDOERS" "5" "August 6, 2015" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
|
||||
.nh
|
||||
.if n .ad l
|
||||
.SH "NAME"
|
||||
@ -961,9 +961,10 @@ SELinux_Spec ::= ('ROLE=role' | 'TYPE=type')
|
||||
|
||||
Solaris_Priv_Spec ::= ('PRIVS=privset' | 'LIMITPRIVS=privset')
|
||||
|
||||
Tag_Spec ::= ('NOEXEC:' | 'EXEC:' | 'LOG_INPUT:' | 'NOLOG_INPUT:' |
|
||||
'LOG_OUTPUT:' | 'NOLOG_OUTPUT:' | 'MAIL:' | 'NOMAIL:' |
|
||||
'NOPASSWD:' | 'PASSWD:' | 'SETENV:' | 'NOSETENV:')
|
||||
Tag_Spec ::= ('EXEC:' | 'NOEXEC:' | 'FOLLOW:' | 'NOFOLLOW' |
|
||||
'LOG_INPUT:' | 'NOLOG_INPUT:' | 'LOG_OUTPUT:' |
|
||||
'NOLOG_OUTPUT:' | 'MAIL:' | 'NOMAIL:' | 'PASSWD:' |
|
||||
'NOPASSWD:' | 'SETENV:' | 'NOSETENV:')
|
||||
.RE
|
||||
.fi
|
||||
.PP
|
||||
@ -1214,16 +1215,18 @@ character.
|
||||
A command may have zero or more tags associated with it.
|
||||
There are
|
||||
ten possible tag values:
|
||||
\fRNOEXEC\fR,
|
||||
\fREXEC\fR,
|
||||
\fRNOEXEC\fR,
|
||||
\fRFOLLOW\fR,
|
||||
\fRNOFOLLOW\fR,
|
||||
\fRLOG_INPUT\fR,
|
||||
\fRNOLOG_INPUT\fR,
|
||||
\fRLOG_OUTPUT\fR,
|
||||
\fRNOLOG_OUTPUT\fR,
|
||||
\fRMAIL\fR,
|
||||
\fRNOMAIL\fR,
|
||||
\fRNOPASSWD\fR,
|
||||
\fRPASSWD\fR,
|
||||
\fRNOPASSWD\fR,
|
||||
\fRSETENV\fR,
|
||||
and
|
||||
\fRNOSETENV\fR.
|
||||
@ -1242,7 +1245,7 @@ and
|
||||
overrides
|
||||
\fREXEC\fR).
|
||||
.TP 2n
|
||||
\fINOEXEC\fR and \fIEXEC\fR
|
||||
\fIEXEC\fR and \fINOEXEC\fR
|
||||
.sp
|
||||
If
|
||||
\fBsudo\fR
|
||||
@ -1275,6 +1278,24 @@ section below for more details on how
|
||||
works and whether or not it will work on your system.
|
||||
.RE
|
||||
.TP 2n
|
||||
\fIFOLLOW\fR and \fINOFOLLOW\fR
|
||||
Starting with version 1.8.15,
|
||||
\fBsudoedit\fR
|
||||
will not follow symbolic links when opening files unless the
|
||||
\fIsudoedit_follow\fR
|
||||
option is enabled.
|
||||
The
|
||||
\fIFOLLOW\fR
|
||||
and
|
||||
\fINOFOLLOW\fR
|
||||
tags override the value of
|
||||
\fIsudoedit_follow\fR
|
||||
and can be used to permit (or deny) the editing of symbolic links
|
||||
on a per-command basis.
|
||||
These tags are only effective for the
|
||||
\fIsudoedit\fR
|
||||
command and are ignored for all other commands.
|
||||
.TP 2n
|
||||
\fILOG_INPUT\fR and \fINOLOG_INPUT\fR
|
||||
.sp
|
||||
These tags override the value of the
|
||||
@ -1327,7 +1348,7 @@ in the
|
||||
\fISUDOERS OPTIONS\fR
|
||||
section below.
|
||||
.TP 2n
|
||||
\fINOPASSWD\fR and \fIPASSWD\fR
|
||||
\fIPASSWD\fR and \fINOPASSWD\fR
|
||||
.sp
|
||||
By default,
|
||||
\fBsudo\fR
|
||||
@ -2660,6 +2681,26 @@ This flag is
|
||||
\fIoff\fR
|
||||
by default.
|
||||
.TP 18n
|
||||
sudoedit_follow
|
||||
By default,
|
||||
\fBsudoedit\fR
|
||||
will not follow symbolic links when opening files.
|
||||
The
|
||||
\fIsudoedit_follow\fR
|
||||
option can be enabled to allow
|
||||
\fBsudoedit\fR
|
||||
to open symbolic links.
|
||||
It may be overridden on a per-command basis by the
|
||||
\fIFOLLOW\fR
|
||||
and
|
||||
\fINOFOLLOW\fR
|
||||
tags.
|
||||
This flag is
|
||||
\fIoff\fR
|
||||
by default.
|
||||
.sp
|
||||
This setting is only supported by version 1.8.15 or higher.
|
||||
.TP 18n
|
||||
targetpw
|
||||
If set,
|
||||
\fBsudo\fR
|
||||
|
@ -19,7 +19,7 @@
|
||||
.\" Agency (DARPA) and Air Force Research Laboratory, Air Force
|
||||
.\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
|
||||
.\"
|
||||
.Dd August 4, 2015
|
||||
.Dd August 6, 2015
|
||||
.Dt SUDOERS @mansectform@
|
||||
.Os Sudo @PACKAGE_VERSION@
|
||||
.Sh NAME
|
||||
@ -914,9 +914,10 @@ SELinux_Spec ::= ('ROLE=role' | 'TYPE=type')
|
||||
|
||||
Solaris_Priv_Spec ::= ('PRIVS=privset' | 'LIMITPRIVS=privset')
|
||||
|
||||
Tag_Spec ::= ('NOEXEC:' | 'EXEC:' | 'LOG_INPUT:' | 'NOLOG_INPUT:' |
|
||||
'LOG_OUTPUT:' | 'NOLOG_OUTPUT:' | 'MAIL:' | 'NOMAIL:' |
|
||||
'NOPASSWD:' | 'PASSWD:' | 'SETENV:' | 'NOSETENV:')
|
||||
Tag_Spec ::= ('EXEC:' | 'NOEXEC:' | 'FOLLOW:' | 'NOFOLLOW' |
|
||||
'LOG_INPUT:' | 'NOLOG_INPUT:' | 'LOG_OUTPUT:' |
|
||||
'NOLOG_OUTPUT:' | 'MAIL:' | 'NOMAIL:' | 'PASSWD:' |
|
||||
'NOPASSWD:' | 'SETENV:' | 'NOSETENV:')
|
||||
.Ed
|
||||
.Pp
|
||||
A
|
||||
@ -1137,16 +1138,18 @@ character.
|
||||
A command may have zero or more tags associated with it.
|
||||
There are
|
||||
ten possible tag values:
|
||||
.Li NOEXEC ,
|
||||
.Li EXEC ,
|
||||
.Li NOEXEC ,
|
||||
.Li FOLLOW ,
|
||||
.Li NOFOLLOW ,
|
||||
.Li LOG_INPUT ,
|
||||
.Li NOLOG_INPUT ,
|
||||
.Li LOG_OUTPUT ,
|
||||
.Li NOLOG_OUTPUT ,
|
||||
.Li MAIL ,
|
||||
.Li NOMAIL ,
|
||||
.Li NOPASSWD ,
|
||||
.Li PASSWD ,
|
||||
.Li NOPASSWD ,
|
||||
.Li SETENV ,
|
||||
and
|
||||
.Li NOSETENV .
|
||||
@ -1165,7 +1168,7 @@ and
|
||||
overrides
|
||||
.Li EXEC ) .
|
||||
.Bl -hang -width 0n
|
||||
.It Em NOEXEC No and Em EXEC
|
||||
.It Em EXEC No and Em NOEXEC
|
||||
.sp
|
||||
If
|
||||
.Nm sudo
|
||||
@ -1192,6 +1195,23 @@ See the
|
||||
section below for more details on how
|
||||
.Li NOEXEC
|
||||
works and whether or not it will work on your system.
|
||||
.It Em FOLLOW No and Em NOFOLLOW
|
||||
Starting with version 1.8.15,
|
||||
.Nm sudoedit
|
||||
will not follow symbolic links when opening files unless the
|
||||
.Em sudoedit_follow
|
||||
option is enabled.
|
||||
The
|
||||
.Em FOLLOW
|
||||
and
|
||||
.Em NOFOLLOW
|
||||
tags override the value of
|
||||
.Em sudoedit_follow
|
||||
and can be used to permit (or deny) the editing of symbolic links
|
||||
on a per-command basis.
|
||||
These tags are only effective for the
|
||||
.Em sudoedit
|
||||
command and are ignored for all other commands.
|
||||
.It Em LOG_INPUT No and Em NOLOG_INPUT
|
||||
.sp
|
||||
These tags override the value of the
|
||||
@ -1241,7 +1261,7 @@ and
|
||||
in the
|
||||
.Sx SUDOERS OPTIONS
|
||||
section below.
|
||||
.It Em NOPASSWD No and Em PASSWD
|
||||
.It Em PASSWD No and Em NOPASSWD
|
||||
.sp
|
||||
By default,
|
||||
.Nm sudo
|
||||
@ -2493,6 +2513,25 @@ system call.
|
||||
This flag is
|
||||
.Em off
|
||||
by default.
|
||||
.It sudoedit_follow
|
||||
By default,
|
||||
.Nm sudoedit
|
||||
will not follow symbolic links when opening files.
|
||||
The
|
||||
.Em sudoedit_follow
|
||||
option can be enabled to allow
|
||||
.Nm sudoedit
|
||||
to open symbolic links.
|
||||
It may be overridden on a per-command basis by the
|
||||
.Em FOLLOW
|
||||
and
|
||||
.Em NOFOLLOW
|
||||
tags.
|
||||
This flag is
|
||||
.Em off
|
||||
by default.
|
||||
.Pp
|
||||
This setting is only supported by version 1.8.15 or higher.
|
||||
.It targetpw
|
||||
If set,
|
||||
.Nm sudo
|
||||
|
@ -170,6 +170,9 @@
|
||||
#ifndef S_ISDIR
|
||||
# define S_ISDIR(m) (((m) & _S_IFMT) == _S_IFDIR)
|
||||
#endif /* S_ISDIR */
|
||||
#ifndef S_ISLNK
|
||||
# define S_ISLNK(m) (((m) & _S_IFMT) == _S_IFLNK)
|
||||
#endif /* S_ISLNK */
|
||||
|
||||
/* For futimens() and utimensat() emulation. */
|
||||
#if !defined(HAVE_FUTIMENS) && !defined(HAVE_UTIMENSAT)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2014 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
* Copyright (c) 2009-2015 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -19,7 +19,7 @@
|
||||
|
||||
/* API version major/minor */
|
||||
#define SUDO_API_VERSION_MAJOR 1
|
||||
#define SUDO_API_VERSION_MINOR 7
|
||||
#define SUDO_API_VERSION_MINOR 8
|
||||
#define SUDO_API_MKVERSION(x, y) ((x << 16) | y)
|
||||
#define SUDO_API_VERSION SUDO_API_MKVERSION(SUDO_API_VERSION_MAJOR, SUDO_API_VERSION_MINOR)
|
||||
|
||||
|
@ -386,6 +386,10 @@ struct sudo_defs_types sudo_defs_table[] = {
|
||||
"use_netgroups", T_FLAG,
|
||||
N_("Enable sudoers netgroup support"),
|
||||
NULL,
|
||||
}, {
|
||||
"sudoedit_follow", T_FLAG,
|
||||
N_("Follow symbolic links when editing files with sudoedit"),
|
||||
NULL,
|
||||
}, {
|
||||
NULL, 0, NULL
|
||||
}
|
||||
|
@ -180,6 +180,8 @@
|
||||
#define I_MAXSEQ 89
|
||||
#define def_use_netgroups (sudo_defs_table[90].sd_un.flag)
|
||||
#define I_USE_NETGROUPS 90
|
||||
#define def_sudoedit_follow (sudo_defs_table[91].sd_un.flag)
|
||||
#define I_SUDOEDIT_FOLLOW 91
|
||||
|
||||
enum def_tuple {
|
||||
never,
|
||||
|
@ -286,3 +286,6 @@ maxseq
|
||||
use_netgroups
|
||||
T_FLAG
|
||||
"Enable sudoers netgroup support"
|
||||
sudoedit_follow
|
||||
T_FLAG
|
||||
"Follow symbolic links when editing files with sudoedit"
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -23,22 +23,24 @@
|
||||
#define NOLOG_OUTPUT 279
|
||||
#define MAIL 280
|
||||
#define NOMAIL 281
|
||||
#define ALL 282
|
||||
#define COMMENT 283
|
||||
#define HOSTALIAS 284
|
||||
#define CMNDALIAS 285
|
||||
#define USERALIAS 286
|
||||
#define RUNASALIAS 287
|
||||
#define ERROR 288
|
||||
#define TYPE 289
|
||||
#define ROLE 290
|
||||
#define PRIVS 291
|
||||
#define LIMITPRIVS 292
|
||||
#define MYSELF 293
|
||||
#define SHA224_TOK 294
|
||||
#define SHA256_TOK 295
|
||||
#define SHA384_TOK 296
|
||||
#define SHA512_TOK 297
|
||||
#define FOLLOW 282
|
||||
#define NOFOLLOW 283
|
||||
#define ALL 284
|
||||
#define COMMENT 285
|
||||
#define HOSTALIAS 286
|
||||
#define CMNDALIAS 287
|
||||
#define USERALIAS 288
|
||||
#define RUNASALIAS 289
|
||||
#define ERROR 290
|
||||
#define TYPE 291
|
||||
#define ROLE 292
|
||||
#define PRIVS 293
|
||||
#define LIMITPRIVS 294
|
||||
#define MYSELF 295
|
||||
#define SHA224_TOK 296
|
||||
#define SHA256_TOK 297
|
||||
#define SHA384_TOK 298
|
||||
#define SHA512_TOK 299
|
||||
#ifndef YYSTYPE_DEFINED
|
||||
#define YYSTYPE_DEFINED
|
||||
typedef union {
|
||||
|
@ -111,6 +111,8 @@ static struct sudo_digest *new_digest(int, const char *);
|
||||
%token <tok> NOLOG_OUTPUT /* don't log cmnd output */
|
||||
%token <tok> MAIL /* mail log message */
|
||||
%token <tok> NOMAIL /* don't mail log message */
|
||||
%token <tok> FOLLOW /* follow symbolic links */
|
||||
%token <tok> NOFOLLOW /* don't follow symbolic links */
|
||||
%token <tok> ALL /* ALL keyword */
|
||||
%token <tok> COMMENT /* comment and/or carriage return */
|
||||
%token <tok> HOSTALIAS /* Host_Alias keyword */
|
||||
@ -370,6 +372,8 @@ cmndspeclist : cmndspec
|
||||
$3->tags.log_output = prev->tags.log_output;
|
||||
if ($3->tags.send_mail == UNSPEC)
|
||||
$3->tags.send_mail = prev->tags.send_mail;
|
||||
if ($3->tags.follow == UNSPEC)
|
||||
$3->tags.follow = prev->tags.follow;
|
||||
if (($3->runasuserlist == NULL &&
|
||||
$3->runasgrouplist == NULL) &&
|
||||
(prev->runasuserlist != NULL ||
|
||||
@ -614,8 +618,7 @@ runaslist : /* empty */ {
|
||||
;
|
||||
|
||||
cmndtag : /* empty */ {
|
||||
$$.log_input = $$.log_output = $$.noexec =
|
||||
$$.nopasswd = $$.send_mail = $$.setenv = UNSPEC;
|
||||
TAGS_INIT($$);
|
||||
}
|
||||
| cmndtag NOPASSWD {
|
||||
$$.nopasswd = true;
|
||||
@ -647,6 +650,12 @@ cmndtag : /* empty */ {
|
||||
| cmndtag NOLOG_OUTPUT {
|
||||
$$.log_output = false;
|
||||
}
|
||||
| cmndtag FOLLOW {
|
||||
$$.follow = true;
|
||||
}
|
||||
| cmndtag NOFOLLOW {
|
||||
$$.follow = false;
|
||||
}
|
||||
| cmndtag MAIL {
|
||||
$$.send_mail = true;
|
||||
}
|
||||
|
@ -2325,6 +2325,9 @@ sudo_ldap_display_entry_short(LDAP *ld, LDAPMessage *entry, struct sudo_lbuf *lb
|
||||
if (strcmp(cp, "authenticate") == 0)
|
||||
sudo_lbuf_append(lbuf, (*p)->bv_val[0] == '!' ?
|
||||
"NOPASSWD: " : "PASSWD: ");
|
||||
else if (strcmp(cp, "sudoedit_follow") == 0)
|
||||
sudo_lbuf_append(lbuf, (*p)->bv_val[0] == '!' ?
|
||||
"FOLLOW: " : "NOFOLLOW: ");
|
||||
else if (strcmp(cp, "noexec") == 0)
|
||||
sudo_lbuf_append(lbuf, (*p)->bv_val[0] == '!' ?
|
||||
"EXEC: " : "NOEXEC: ");
|
||||
|
@ -320,6 +320,8 @@ sudo_file_lookup(struct sudo_nss *nss, int validated, int pwflag)
|
||||
def_mail_no_perms = false;
|
||||
}
|
||||
}
|
||||
if (tags->follow != UNSPEC)
|
||||
def_sudoedit_follow = tags->follow;
|
||||
}
|
||||
} else if (match == DENY) {
|
||||
SET(validated, VALIDATE_FAILURE);
|
||||
@ -346,9 +348,6 @@ done:
|
||||
debug_return_int(validated);
|
||||
}
|
||||
|
||||
#define TAG_SET(tt) \
|
||||
((tt) != UNSPEC && (tt) != IMPLIED)
|
||||
|
||||
#define TAG_CHANGED(t) \
|
||||
(TAG_SET(cs->tags.t) && cs->tags.t != tags->t)
|
||||
|
||||
@ -394,14 +393,14 @@ sudo_file_append_cmnd(struct cmndspec *cs, struct cmndtag *tags,
|
||||
tags->send_mail = cs->tags.send_mail;
|
||||
sudo_lbuf_append(lbuf, tags->send_mail ? "MAIL: " : "NOMAIL: ");
|
||||
}
|
||||
if (TAG_CHANGED(follow)) {
|
||||
tags->follow = cs->tags.follow;
|
||||
sudo_lbuf_append(lbuf, tags->follow ? "FOLLOW: " : "NOFOLLOW: ");
|
||||
}
|
||||
print_member(lbuf, cs->cmnd, CMNDALIAS);
|
||||
debug_return_bool(!sudo_lbuf_error(lbuf));
|
||||
}
|
||||
|
||||
#define RUNAS_CHANGED(cs1, cs2) \
|
||||
(cs1->runasuserlist != cs2->runasuserlist || \
|
||||
cs1->runasgrouplist != cs2->runasgrouplist)
|
||||
|
||||
static int
|
||||
sudo_file_display_priv_short(struct passwd *pw, struct userspec *us,
|
||||
struct sudo_lbuf *lbuf)
|
||||
@ -414,12 +413,7 @@ sudo_file_display_priv_short(struct passwd *pw, struct userspec *us,
|
||||
debug_decl(sudo_file_display_priv_short, SUDOERS_DEBUG_NSS)
|
||||
|
||||
/* gcc -Wuninitialized false positive */
|
||||
tags.log_input = UNSPEC;
|
||||
tags.log_output = UNSPEC;
|
||||
tags.noexec = UNSPEC;
|
||||
tags.nopasswd = UNSPEC;
|
||||
tags.send_mail = UNSPEC;
|
||||
tags.setenv = UNSPEC;
|
||||
TAGS_INIT(tags);
|
||||
TAILQ_FOREACH(priv, &us->privileges, entries) {
|
||||
if (hostlist_matches(&priv->hostlist) != ALLOW)
|
||||
continue;
|
||||
@ -449,12 +443,7 @@ sudo_file_display_priv_short(struct passwd *pw, struct userspec *us,
|
||||
}
|
||||
}
|
||||
sudo_lbuf_append(lbuf, ") ");
|
||||
tags.log_input = UNSPEC;
|
||||
tags.log_output = UNSPEC;
|
||||
tags.noexec = UNSPEC;
|
||||
tags.nopasswd = UNSPEC;
|
||||
tags.send_mail = UNSPEC;
|
||||
tags.setenv = UNSPEC;
|
||||
TAGS_INIT(tags);
|
||||
} else if (cs != TAILQ_FIRST(&priv->cmndlist)) {
|
||||
sudo_lbuf_append(lbuf, ", ");
|
||||
}
|
||||
@ -467,13 +456,6 @@ sudo_file_display_priv_short(struct passwd *pw, struct userspec *us,
|
||||
debug_return_int(nfound);
|
||||
}
|
||||
|
||||
#define TAGS_CHANGED(ot, nt) \
|
||||
((TAG_SET((nt).setenv) && (nt).setenv != (ot).setenv) || \
|
||||
(TAG_SET((nt).noexec) && (nt).noexec != (ot).noexec) || \
|
||||
(TAG_SET((nt).nopasswd) && (nt).nopasswd != (ot).nopasswd) || \
|
||||
(TAG_SET((nt).log_input) && (nt).log_input != (ot).log_input) || \
|
||||
(TAG_SET((nt).log_output) && (nt).log_output != (ot).log_output))
|
||||
|
||||
/*
|
||||
* Compare the current cmndspec with the previous one to determine
|
||||
* whether we need to start a new long entry for "sudo -ll".
|
||||
|
@ -27,6 +27,54 @@
|
||||
#undef IMPLIED
|
||||
#define IMPLIED 2
|
||||
|
||||
/*
|
||||
* Initialize all tags to UNSPEC.
|
||||
*/
|
||||
#define TAGS_INIT(t) do { \
|
||||
(t).follow = UNSPEC; \
|
||||
(t).log_input = UNSPEC; \
|
||||
(t).log_output = UNSPEC; \
|
||||
(t).noexec = UNSPEC; \
|
||||
(t).nopasswd = UNSPEC; \
|
||||
(t).send_mail = UNSPEC; \
|
||||
(t).setenv = UNSPEC; \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Returns true if any tag are not UNSPEC, else false.
|
||||
*/
|
||||
#define TAGS_SET(t) \
|
||||
((t).follow != UNSPEC || (t).log_input != UNSPEC || \
|
||||
(t).log_output != UNSPEC || (t).noexec != UNSPEC || \
|
||||
(t).nopasswd != UNSPEC || (t).send_mail != UNSPEC || \
|
||||
(t).setenv != UNSPEC)
|
||||
|
||||
/*
|
||||
* Returns true if the specified tag is not UNSPEC or IMPLIED, else false.
|
||||
*/
|
||||
#define TAG_SET(tt) \
|
||||
((tt) != UNSPEC && (tt) != IMPLIED)
|
||||
|
||||
/*
|
||||
* Returns true if any tags set in nt differ between ot and nt, else false.
|
||||
*/
|
||||
#define TAGS_CHANGED(ot, nt) \
|
||||
((TAG_SET((nt).follow) && (nt).follow != (ot).follow) || \
|
||||
(TAG_SET((nt).log_input) && (nt).log_input != (ot).log_input) || \
|
||||
(TAG_SET((nt).log_output) && (nt).log_output != (ot).log_output) || \
|
||||
(TAG_SET((nt).noexec) && (nt).noexec != (ot).noexec) || \
|
||||
(TAG_SET((nt).nopasswd) && (nt).nopasswd != (ot).nopasswd) || \
|
||||
(TAG_SET((nt).setenv) && (nt).setenv != (ot).setenv) || \
|
||||
(TAG_SET((nt).send_mail) && (nt).send_mail != (ot).send_mail))
|
||||
|
||||
/*
|
||||
* Returns true if the runas user and group lists match, else false.
|
||||
*/
|
||||
#define RUNAS_CHANGED(cs1, cs2) \
|
||||
((cs1) == NULL || (cs2) == NULL || \
|
||||
(cs1)->runasuserlist != (cs2)->runasuserlist || \
|
||||
(cs1)->runasgrouplist != (cs2)->runasgrouplist)
|
||||
|
||||
#define SUDO_DIGEST_SHA224 0
|
||||
#define SUDO_DIGEST_SHA256 1
|
||||
#define SUDO_DIGEST_SHA384 2
|
||||
@ -59,6 +107,7 @@ struct cmndtag {
|
||||
signed int log_input: 3;
|
||||
signed int log_output: 3;
|
||||
signed int send_mail: 3;
|
||||
signed int follow: 3;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -438,6 +438,10 @@ sudoers_policy_exec_setup(char *argv[], char *envp[], mode_t cmnd_umask,
|
||||
if (ISSET(sudo_mode, MODE_EDIT)) {
|
||||
if ((command_info[info_len++] = strdup("sudoedit=true")) == NULL)
|
||||
goto oom;
|
||||
if (def_sudoedit_follow) {
|
||||
if ((command_info[info_len++] = strdup("sudoedit_follow=true")) == NULL)
|
||||
goto oom;
|
||||
}
|
||||
}
|
||||
if (ISSET(sudo_mode, MODE_LOGIN_SHELL)) {
|
||||
/* Set cwd to run user's homedir. */
|
||||
|
@ -8,3 +8,5 @@ user2 ALL = NOPASSWD: NOEXEC: SETENV: /usr/bin/vi:\
|
||||
ALL = PASSWD: EXEC: NOSETENV: /usr/bin/echo
|
||||
user3 ALL = MAIL: /bin/sh:\
|
||||
ALL = NOMAIL: /usr/bin/id
|
||||
user4 ALL = FOLLOW: sudoedit /etc/motd:\
|
||||
ALL = NOFOLLOW: sudoedit /home/*/*
|
||||
|
@ -113,6 +113,42 @@
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"User_List": [
|
||||
{ "username": "user4" }
|
||||
],
|
||||
"Host_List": [
|
||||
{ "hostalias": "ALL" }
|
||||
],
|
||||
"Cmnd_Specs": [
|
||||
{
|
||||
"Options": [
|
||||
{ "sudoedit_follow": true }
|
||||
],
|
||||
"Commands": [
|
||||
{ "command": "sudoedit \/etc\/motd" }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"User_List": [
|
||||
{ "username": "user4" }
|
||||
],
|
||||
"Host_List": [
|
||||
{ "hostalias": "ALL" }
|
||||
],
|
||||
"Cmnd_Specs": [
|
||||
{
|
||||
"Options": [
|
||||
{ "sudoedit_follow": false }
|
||||
],
|
||||
"Commands": [
|
||||
{ "command": "sudoedit \/home\/*\/*" }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -5,3 +5,4 @@ Parses OK.
|
||||
user1 ALL = LOG_INPUT: LOG_OUTPUT: /usr/bin/su - : ALL = NOLOG_INPUT: NOLOG_OUTPUT: /usr/bin/id
|
||||
user2 ALL = NOEXEC: NOPASSWD: SETENV: /usr/bin/vi : ALL = EXEC: PASSWD: NOSETENV: /usr/bin/echo
|
||||
user3 ALL = MAIL: /bin/sh : ALL = NOMAIL: /usr/bin/id
|
||||
user4 ALL = FOLLOW: sudoedit /etc/motd : ALL = NOFOLLOW: sudoedit /home/*/*
|
||||
|
@ -5,3 +5,4 @@
|
||||
WORD(5) ALL = LOG_INPUT LOG_OUTPUT COMMAND ARG : ALL = NOLOG_INPUT NOLOG_OUTPUT COMMAND
|
||||
WORD(5) ALL = NOPASSWD NOEXEC SETENV COMMAND : ALL = PASSWD EXEC NOSETENV COMMAND
|
||||
WORD(5) ALL = MAIL COMMAND : ALL = NOMAIL COMMAND
|
||||
WORD(5) ALL = FOLLOW COMMAND ARG : ALL = NOFOLLOW COMMAND ARG
|
||||
|
@ -63,11 +63,12 @@
|
||||
* 42 sudo 1.8.6, Support for empty Runas_List (with or without a colon) to mean the invoking user. Support for Solaris Privilege Sets (PRIVS= and LIMITPRIVS=).
|
||||
* 43 sudo 1.8.7, Support for specifying a digest along with the command.
|
||||
* 44 sudo 1.8.13, added MAIL/NOMAIL tags.
|
||||
* 45 sudo 1.8.15, added FOLLOW/NOFOLLOW tags and sudoedit_follow Default.
|
||||
*/
|
||||
|
||||
#ifndef SUDOERS_VERSION_H
|
||||
#define SUDOERS_VERSION_H
|
||||
|
||||
#define SUDOERS_GRAMMAR_VERSION 44
|
||||
#define SUDOERS_GRAMMAR_VERSION 45
|
||||
|
||||
#endif /* SUDOERS_VERSION_H */
|
||||
|
@ -591,12 +591,7 @@ print_privilege(struct privilege *priv)
|
||||
print_member(m);
|
||||
}
|
||||
fputs(" = ", stdout);
|
||||
tags.log_input = UNSPEC;
|
||||
tags.log_output = UNSPEC;
|
||||
tags.noexec = UNSPEC;
|
||||
tags.nopasswd = UNSPEC;
|
||||
tags.send_mail = UNSPEC;
|
||||
tags.setenv = UNSPEC;
|
||||
TAGS_INIT(tags);
|
||||
TAILQ_FOREACH(cs, &priv->cmndlist, entries) {
|
||||
if (cs != TAILQ_FIRST(&priv->cmndlist))
|
||||
fputs(", ", stdout);
|
||||
@ -635,6 +630,8 @@ print_privilege(struct privilege *priv)
|
||||
if (cs->limitprivs)
|
||||
printf("LIMITPRIVS=%s ", cs->limitprivs);
|
||||
#endif /* HAVE_PRIV_SET */
|
||||
if (TAG_CHANGED(follow))
|
||||
printf("%sFOLLOW: ", cs->tags.follow ? "" : "NO");
|
||||
if (TAG_CHANGED(log_input))
|
||||
printf("%sLOG_INPUT: ", cs->tags.log_input ? "" : "NO");
|
||||
if (TAG_CHANGED(log_output))
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -454,6 +454,16 @@ NOMAIL[[:blank:]]*: {
|
||||
LEXRETURN(NOMAIL);
|
||||
}
|
||||
|
||||
FOLLOW[[:blank:]]*: {
|
||||
LEXTRACE("FOLLOW ");
|
||||
LEXRETURN(FOLLOW);
|
||||
}
|
||||
|
||||
NOFOLLOW[[:blank:]]*: {
|
||||
LEXTRACE("NOFOLLOW ");
|
||||
LEXRETURN(NOFOLLOW);
|
||||
}
|
||||
|
||||
<INITIAL,GOTDEFS>(\+|\%|\%:) {
|
||||
/* empty group or netgroup */
|
||||
LEXTRACE("ERROR ");
|
||||
|
@ -667,7 +667,7 @@ print_defaults_json(FILE *fp, int indent, bool need_comma)
|
||||
if (type == -1) {
|
||||
sudo_warnx(U_("unknown defaults entry `%s'"), def->var);
|
||||
/* XXX - just pass it through as a string anyway? */
|
||||
break;;
|
||||
break;
|
||||
}
|
||||
fputs(",\n", fp);
|
||||
}
|
||||
@ -738,23 +738,6 @@ print_aliases_json(FILE *fp, int indent, bool need_comma)
|
||||
debug_return_bool(need_comma);
|
||||
}
|
||||
|
||||
/* XXX these are all duplicated w/ parse.c */
|
||||
#define RUNAS_CHANGED(cs1, cs2) \
|
||||
(cs1 == NULL || cs2 == NULL || \
|
||||
cs1->runasuserlist != cs2->runasuserlist || \
|
||||
cs1->runasgrouplist != cs2->runasgrouplist)
|
||||
|
||||
#define TAG_SET(tt) \
|
||||
((tt) != UNSPEC && (tt) != IMPLIED)
|
||||
|
||||
#define TAGS_CHANGED(ot, nt) \
|
||||
((TAG_SET((nt).log_input) && (nt).log_input != (ot).log_input) || \
|
||||
(TAG_SET((nt).log_output) && (nt).log_output != (ot).log_output) || \
|
||||
(TAG_SET((nt).noexec) && (nt).noexec != (ot).noexec) || \
|
||||
(TAG_SET((nt).nopasswd) && (nt).nopasswd != (ot).nopasswd) || \
|
||||
(TAG_SET((nt).setenv) && (nt).setenv != (ot).setenv) || \
|
||||
(TAG_SET((nt).send_mail) && (nt).send_mail != (ot).send_mail))
|
||||
|
||||
/*
|
||||
* Print a Cmnd_Spec in JSON format at the specified indent level.
|
||||
* A pointer to the next Cmnd_Spec is passed in to make it possible to
|
||||
@ -799,56 +782,59 @@ print_cmndspec_json(FILE *fp, struct cmndspec *cs, struct cmndspec **nextp,
|
||||
}
|
||||
|
||||
/* Print tags */
|
||||
if (cs->tags.log_input != UNSPEC || cs->tags.log_output != UNSPEC ||
|
||||
cs->tags.noexec != UNSPEC || cs->tags.nopasswd != UNSPEC ||
|
||||
cs->tags.send_mail != UNSPEC || cs->tags.setenv != UNSPEC) {
|
||||
if (TAGS_SET(cs->tags)) {
|
||||
struct cmndtag tag = cs->tags;
|
||||
|
||||
fprintf(fp, "%*s\"Options\": [\n", indent, "");
|
||||
indent += 4;
|
||||
if (cs->tags.nopasswd != UNSPEC) {
|
||||
if (tag.nopasswd != UNSPEC) {
|
||||
value.type = JSON_BOOL;
|
||||
value.u.boolean = !cs->tags.nopasswd;
|
||||
last_one = cs->tags.noexec == UNSPEC &&
|
||||
cs->tags.send_mail == UNSPEC && cs->tags.setenv == UNSPEC &&
|
||||
cs->tags.log_input == UNSPEC && cs->tags.log_output == UNSPEC;
|
||||
value.u.boolean = !tag.nopasswd;
|
||||
tag.nopasswd = UNSPEC;
|
||||
print_pair_json(fp, "{ ", "authenticate", &value,
|
||||
last_one ? " }\n" : " },\n", indent);
|
||||
TAGS_SET(tag) ? " },\n" : " }\n", indent);
|
||||
}
|
||||
if (cs->tags.noexec != UNSPEC) {
|
||||
if (tag.noexec != UNSPEC) {
|
||||
value.type = JSON_BOOL;
|
||||
value.u.boolean = cs->tags.noexec;
|
||||
last_one = cs->tags.send_mail == UNSPEC &&
|
||||
cs->tags.setenv == UNSPEC && cs->tags.log_input == UNSPEC &&
|
||||
cs->tags.log_output == UNSPEC;
|
||||
value.u.boolean = tag.noexec;
|
||||
tag.noexec = UNSPEC;
|
||||
print_pair_json(fp, "{ ", "noexec", &value,
|
||||
last_one ? " }\n" : " },\n", indent);
|
||||
TAGS_SET(tag) ? " },\n" : " }\n", indent);
|
||||
}
|
||||
if (cs->tags.send_mail != UNSPEC) {
|
||||
if (tag.send_mail != UNSPEC) {
|
||||
value.type = JSON_BOOL;
|
||||
value.u.boolean = cs->tags.send_mail;
|
||||
last_one = cs->tags.setenv == UNSPEC &&
|
||||
cs->tags.log_input == UNSPEC && cs->tags.log_output == UNSPEC;
|
||||
value.u.boolean = tag.send_mail;
|
||||
tag.send_mail = UNSPEC;
|
||||
print_pair_json(fp, "{ ", "send_mail", &value,
|
||||
last_one ? " }\n" : " },\n", indent);
|
||||
TAGS_SET(tag) ? " },\n" : " }\n", indent);
|
||||
}
|
||||
if (cs->tags.setenv != UNSPEC) {
|
||||
if (tag.setenv != UNSPEC) {
|
||||
value.type = JSON_BOOL;
|
||||
value.u.boolean = cs->tags.setenv;
|
||||
last_one = cs->tags.log_input == UNSPEC &&
|
||||
cs->tags.log_output == UNSPEC;
|
||||
value.u.boolean = tag.setenv;
|
||||
tag.setenv = UNSPEC;
|
||||
print_pair_json(fp, "{ ", "setenv", &value,
|
||||
last_one ? " }\n" : " },\n", indent);
|
||||
TAGS_SET(tag) ? " },\n" : " }\n", indent);
|
||||
}
|
||||
if (cs->tags.log_input != UNSPEC) {
|
||||
if (tag.follow != UNSPEC) {
|
||||
value.type = JSON_BOOL;
|
||||
value.u.boolean = cs->tags.log_input;
|
||||
last_one = cs->tags.log_output == UNSPEC;
|
||||
value.u.boolean = tag.follow;
|
||||
tag.follow = UNSPEC;
|
||||
print_pair_json(fp, "{ ", "sudoedit_follow", &value,
|
||||
TAGS_SET(tag) ? " },\n" : " }\n", indent);
|
||||
}
|
||||
if (tag.log_input != UNSPEC) {
|
||||
value.type = JSON_BOOL;
|
||||
value.u.boolean = tag.log_input;
|
||||
tag.log_input = UNSPEC;
|
||||
print_pair_json(fp, "{ ", "log_input", &value,
|
||||
last_one ? " }\n" : " },\n", indent);
|
||||
TAGS_SET(tag) ? " },\n" : " }\n", indent);
|
||||
}
|
||||
if (cs->tags.log_output != UNSPEC) {
|
||||
if (tag.log_output != UNSPEC) {
|
||||
value.type = JSON_BOOL;
|
||||
value.u.boolean = cs->tags.log_output;
|
||||
print_pair_json(fp, "{ ", "log_output", &value, " }\n", indent);
|
||||
value.u.boolean = tag.log_output;
|
||||
tag.log_output = UNSPEC;
|
||||
print_pair_json(fp, "{ ", "log_output", &value,
|
||||
TAGS_SET(tag) ? " },\n" : " }\n", indent);
|
||||
}
|
||||
indent -= 4;
|
||||
fprintf(fp, "%*s],\n", indent, "");
|
||||
|
13
src/sesh.c
13
src/sesh.c
@ -120,13 +120,20 @@ static int
|
||||
sesh_sudoedit(int argc, char *argv[])
|
||||
{
|
||||
int i, oflags_dst, post, ret = SESH_ERR_FAILURE;
|
||||
int fd_src = -1, fd_dst = -1;
|
||||
int fd_src = -1, fd_dst = -1, follow = 0;
|
||||
ssize_t nread, nwritten;
|
||||
struct stat sb;
|
||||
struct timespec times[2];
|
||||
char buf[BUFSIZ];
|
||||
debug_decl(sesh_sudoedit, SUDO_DEBUG_EDIT)
|
||||
|
||||
/* Check for -h flag (don't follow links). */
|
||||
if (strcmp(argv[2], "-h") == 0) {
|
||||
argv++;
|
||||
argc--;
|
||||
follow = O_NOFOLLOW;
|
||||
}
|
||||
|
||||
if (argc < 3)
|
||||
debug_return_int(SESH_ERR_FAILURE);
|
||||
|
||||
@ -160,7 +167,7 @@ sesh_sudoedit(int argc, char *argv[])
|
||||
* so that it's ensured that the temporary files are
|
||||
* created by us and that we are not opening any symlinks.
|
||||
*/
|
||||
oflags_dst = O_WRONLY|O_TRUNC|O_CREAT|(post ? 0 : O_EXCL);
|
||||
oflags_dst = O_WRONLY|O_TRUNC|O_CREAT|(post ? follow : O_EXCL);
|
||||
for (i = 0; i < argc - 1; i += 2) {
|
||||
const char *path_src = argv[i];
|
||||
const char *path_dst = argv[i + 1];
|
||||
@ -169,7 +176,7 @@ sesh_sudoedit(int argc, char *argv[])
|
||||
* doesn't exist, that's OK, we'll create an empty
|
||||
* destination file.
|
||||
*/
|
||||
if ((fd_src = open(path_src, O_RDONLY, 0600)) < 0) {
|
||||
if ((fd_src = open(path_src, O_RDONLY|follow, 0600)) < 0) {
|
||||
if (errno != ENOENT) {
|
||||
sudo_warn("%s", path_src);
|
||||
if (post) {
|
||||
|
@ -715,6 +715,11 @@ command_info_to_details(char * const info[], struct command_details *details)
|
||||
SET(details->flags, CD_SUDOEDIT);
|
||||
break;
|
||||
}
|
||||
if (strncmp("sudoedit_follow=", info[i], sizeof("sudoedit_follow=") - 1) == 0) {
|
||||
if (sudo_strtobool(info[i] + sizeof("sudoedit_follow=") - 1) == true)
|
||||
SET(details->flags, CD_SUDOEDIT_FOLLOW);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 't':
|
||||
if (strncmp("timeout=", info[i], sizeof("timeout=") - 1) == 0) {
|
||||
|
33
src/sudo.h
33
src/sudo.h
@ -111,22 +111,23 @@ struct user_details {
|
||||
int ts_lines;
|
||||
};
|
||||
|
||||
#define CD_SET_UID 0x0001
|
||||
#define CD_SET_EUID 0x0002
|
||||
#define CD_SET_GID 0x0004
|
||||
#define CD_SET_EGID 0x0008
|
||||
#define CD_PRESERVE_GROUPS 0x0010
|
||||
#define CD_NOEXEC 0x0020
|
||||
#define CD_SET_PRIORITY 0x0040
|
||||
#define CD_SET_UMASK 0x0080
|
||||
#define CD_SET_TIMEOUT 0x0100
|
||||
#define CD_SUDOEDIT 0x0200
|
||||
#define CD_BACKGROUND 0x0400
|
||||
#define CD_RBAC_ENABLED 0x0800
|
||||
#define CD_USE_PTY 0x1000
|
||||
#define CD_SET_UTMP 0x2000
|
||||
#define CD_EXEC_BG 0x4000
|
||||
#define CD_SUDOEDIT_COPY 0x8000
|
||||
#define CD_SET_UID 0x00001
|
||||
#define CD_SET_EUID 0x00002
|
||||
#define CD_SET_GID 0x00004
|
||||
#define CD_SET_EGID 0x00008
|
||||
#define CD_PRESERVE_GROUPS 0x00010
|
||||
#define CD_NOEXEC 0x00020
|
||||
#define CD_SET_PRIORITY 0x00040
|
||||
#define CD_SET_UMASK 0x00080
|
||||
#define CD_SET_TIMEOUT 0x00100
|
||||
#define CD_SUDOEDIT 0x00200
|
||||
#define CD_BACKGROUND 0x00400
|
||||
#define CD_RBAC_ENABLED 0x00800
|
||||
#define CD_USE_PTY 0x01000
|
||||
#define CD_SET_UTMP 0x02000
|
||||
#define CD_EXEC_BG 0x04000
|
||||
#define CD_SUDOEDIT_COPY 0x08000
|
||||
#define CD_SUDOEDIT_FOLLOW 0x10000
|
||||
|
||||
struct preserved_fd {
|
||||
TAILQ_ENTRY(preserved_fd) entries;
|
||||
|
@ -57,8 +57,8 @@
|
||||
struct tempfile {
|
||||
char *tfile;
|
||||
char *ofile;
|
||||
struct timespec omtim;
|
||||
off_t osize;
|
||||
struct timespec omtim;
|
||||
};
|
||||
|
||||
static char edit_tmpdir[MAX(sizeof(_PATH_VARTMP), sizeof(_PATH_TMP))];
|
||||
@ -157,6 +157,50 @@ sudo_edit_mktemp(const char *ofile, char **tfile)
|
||||
debug_return_int(tfd);
|
||||
}
|
||||
|
||||
#ifdef O_NOFOLLOW
|
||||
static int
|
||||
sudo_edit_open(const char *path, int oflags, mode_t mode, int sflags)
|
||||
{
|
||||
if (!ISSET(sflags, CD_SUDOEDIT_FOLLOW))
|
||||
oflags |= O_NOFOLLOW;
|
||||
return open(path, oflags, mode);
|
||||
}
|
||||
#else
|
||||
static int
|
||||
sudo_edit_open(const char *path, int oflags, mode_t mode, int sflags)
|
||||
{
|
||||
struct stat sb1, sb2;
|
||||
int fd;
|
||||
|
||||
fd = open(path, oflags, mode);
|
||||
if (fd == -1 || ISSET(sflags, CD_SUDOEDIT_FOLLOW))
|
||||
return fd;
|
||||
|
||||
/*
|
||||
* Treat [fl]stat() failure like an open() failure.
|
||||
*/
|
||||
if (fstat(fd, &sb1) == -1 || lstat(path, &sb2) == -1) {
|
||||
const int serrno = errno;
|
||||
close(fd);
|
||||
errno = serrno;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure we did not open a link and that what we opened
|
||||
* matches what is currently on the file system.
|
||||
*/
|
||||
if (S_ISLNK(sb2.st_mode) ||
|
||||
sb1.st_dev != sb2.st_dev || sb1.st_ino != sb2.st_ino) {
|
||||
close(fd);
|
||||
errno = ELOOP;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
#endif /* O_NOFOLLOW */
|
||||
|
||||
/*
|
||||
* Create temporary copies of files[] and store the temporary path name
|
||||
* along with the original name, size and mtime in tf.
|
||||
@ -182,7 +226,8 @@ sudo_edit_create_tfiles(struct command_details *command_details,
|
||||
rc = -1;
|
||||
switch_user(command_details->euid, command_details->egid,
|
||||
command_details->ngroups, command_details->groups);
|
||||
if ((ofd = open(files[i], O_RDONLY, 0644)) != -1 || errno == ENOENT) {
|
||||
ofd = sudo_edit_open(files[i], O_RDONLY, 0644, command_details->flags);
|
||||
if (ofd != -1 || errno == ENOENT) {
|
||||
if (ofd == -1) {
|
||||
memset(&sb, 0, sizeof(sb)); /* new file */
|
||||
rc = 0;
|
||||
@ -192,11 +237,17 @@ sudo_edit_create_tfiles(struct command_details *command_details,
|
||||
}
|
||||
switch_user(ROOT_UID, user_details.egid,
|
||||
user_details.ngroups, user_details.groups);
|
||||
if (rc || (ofd != -1 && !S_ISREG(sb.st_mode))) {
|
||||
if (rc)
|
||||
sudo_warn("%s", files[i]);
|
||||
if (ofd != -1 && !S_ISREG(sb.st_mode)) {
|
||||
sudo_warnx(U_("%s: not a regular file"), files[i]);
|
||||
close(ofd);
|
||||
continue;
|
||||
}
|
||||
if (rc == -1) {
|
||||
/* open() or fstat() error. */
|
||||
if (ofd == -1 && errno == ELOOP)
|
||||
sudo_warnx(U_("%s: is a symbolic link"), files[i]);
|
||||
else
|
||||
sudo_warnx(U_("%s: not a regular file"), files[i]);
|
||||
sudo_warn("%s", files[i]);
|
||||
if (ofd != -1)
|
||||
close(ofd);
|
||||
continue;
|
||||
@ -275,9 +326,9 @@ sudo_edit_copy_tfiles(struct command_details *command_details,
|
||||
"seteuid(%u)", user_details.uid);
|
||||
if (seteuid(user_details.uid) != 0)
|
||||
sudo_fatal("seteuid(%d)", (int)user_details.uid);
|
||||
if ((tfd = open(tf[i].tfile, O_RDONLY, 0644)) != -1) {
|
||||
tfd = sudo_edit_open(tf[i].tfile, O_RDONLY, 0644, 0);
|
||||
if (tfd != -1)
|
||||
rc = fstat(tfd, &sb);
|
||||
}
|
||||
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
|
||||
"seteuid(%u)", ROOT_UID);
|
||||
if (seteuid(ROOT_UID) != 0)
|
||||
@ -309,7 +360,8 @@ sudo_edit_copy_tfiles(struct command_details *command_details,
|
||||
}
|
||||
switch_user(command_details->euid, command_details->egid,
|
||||
command_details->ngroups, command_details->groups);
|
||||
ofd = open(tf[i].ofile, O_WRONLY|O_TRUNC|O_CREAT, 0644);
|
||||
ofd = sudo_edit_open(tf[i].ofile, O_WRONLY|O_TRUNC|O_CREAT, 0644,
|
||||
command_details->flags);
|
||||
switch_user(ROOT_UID, user_details.egid,
|
||||
user_details.ngroups, user_details.groups);
|
||||
if (ofd == -1) {
|
||||
@ -368,7 +420,7 @@ selinux_edit_create_tfiles(struct command_details *command_details,
|
||||
command_details->command = _PATH_SUDO_SESH;
|
||||
command_details->flags |= CD_SUDOEDIT_COPY;
|
||||
|
||||
sesh_nargs = 3 + (nfiles * 2) + 1;
|
||||
sesh_nargs = 4 + (nfiles * 2) + 1;
|
||||
sesh_args = sesh_ap = reallocarray(NULL, sesh_nargs, sizeof(char *));
|
||||
if (sesh_args == NULL) {
|
||||
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
||||
@ -376,6 +428,8 @@ selinux_edit_create_tfiles(struct command_details *command_details,
|
||||
}
|
||||
*sesh_ap++ = "sesh";
|
||||
*sesh_ap++ = "-e";
|
||||
if (!ISSET(command_details->flags, CD_SUDOEDIT_FOLLOW))
|
||||
*sesh_ap++ = "-h";
|
||||
*sesh_ap++ = "0";
|
||||
|
||||
for (i = 0; i < nfiles; i++) {
|
||||
@ -406,7 +460,7 @@ selinux_edit_create_tfiles(struct command_details *command_details,
|
||||
}
|
||||
*sesh_ap = NULL;
|
||||
|
||||
/* Run sesh -e 0 <o1> <t1> ... <on> <tn> */
|
||||
/* Run sesh -e [-h] 0 <o1> <t1> ... <on> <tn> */
|
||||
command_details->argv = sesh_args;
|
||||
rc = run_command(command_details);
|
||||
switch (rc) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user