Is this safe?
echo "Defaults insults" >> /etc/sudoers
If yes, can I do this?
echo "## First line" >> /etc/sudoers
echo "### Second line" >> /etc/sudoers
echo "Defaults insults" >> /etc/sudoers
echo "### Totally the last line" >> /etc/sudoers
Is there a better way to do this incorporating visudo
?
I'm making a bash script, this bit needs to turn insults on and off.
Best Answer
There are at least 3 ways in which it can be dangerous:
If
/etc/sudoers
doesn't end in a newline character (whichsudo
andvisudo
allow), for instance, if it ends in a non-terminated#includedir /etc/sudoers.d
line, your command will make it:which will break it and render
sudo
unusable.echo
may fail to write the full string, for instance if the file system is full. For instance, it may just be able to writeDefaults in
. Which again will break yoursudoers
file./etc/sudoers
at the same time, the data they write may be interlaced.visudo
avoids these problems because it lets you edit a temporary file instead (/etc/sudoers.tmp
), detects if the file was modified (unfortunately not if the file was successfully modified as it doesn't seem to be checking the editor's exit status), checks the syntax, and does arename
(an atomic operation) to move the new file in place. So it will either successfully update the file (provided your editor also leaves the file unmodified if it fails to write the new one) or fail if it can't or the syntax is invalid.visudo
also guards against several persons editing thesudoers
files at the same time.Now, reliably using
visudo
in an automatic fashion is tricky as well. There are several problems with that:visudo
with theVISUAL
environment variable (takes precedence overEDITOR
), but only if theenv_editor
option has not been disabled.visudo
at least, under some conditions, edits all of/etc/sudoers
and all the files it includes (runs$VISUAL
for all of them). So you have to make sure your$VISUAL
only modifies/etc/sudoers
.Addressing all those is a bit tricky. Here is how you could do it:
Won't work if
env_editor
is unset.On a GNU system, a better alternative would be to use
sed -i
which should leavesudoers.tmp
unmodified if it fails to write the newer version:Add
insults
:Remove insults: