2

Using /etc/sudoers I gave a non-root user (anyuser below) permission to sudo-execute a root-owned script (test-script below) with the NOPASSWD: tag set.
The script's permission octal value is 0550. Its execution is possible only with one predefined argument (cache_bak below) and when the script file was not tampered with. The latter is possible based on a SHA256 digest-conditioned execution (relevant info in sudoers man page).

Things work well , ... until I test-modify the script to get a different SHA digest and see how sudoers handles it.

What I did was:

$ cat /home/anyuser/Scripts/test-script
#!/bin/bash
/bin/mkdir -p /var/"$1"
/bin/cp -R /var/cache/* /var/"$1" # copies content of /var/cache/ 
                                  # to /var/$1, defined by script's lone arg 
exit $?
# End of test-script

$ sudo chmod 0550 /home/anyuser/Scripts/test-script
$ sudo chown root:admin /home/anyuser/Scripts/test-script
$ ls -lsAF test-*   # check
4 -r-xr-x--- 1 root admin   75 Apr 25 18:23 test-script*

$ cat /etc/group | grep sudo   # check
sudo:x:27:anyuser

$ sudo cat /etc/sudoers         # check
Defaults    env_reset
Defaults    mail_badpass
Defaults    secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
Defaults    insults
root    ALL = (ALL:ALL) ALL
%sudo   ALL = (root:ALL) ALL
%admin  ALL = (ALL:ALL) ALL
%wheel Somehost = (ALL:ALL) ALL
#includedir /etc/sudoers.d

I then populated /etc/sudoers.d with 10_user, whose content is:

$ cat /etc/sudoers.d/10_user
Cmnd_Alias CPVARCACHE = sha256:48805bae82834f323xxxxxxxxxxxxx10145c7bbf80bae183b7de3ea52ef90637 /home/anyuser/Scripts/test-script cache_bak

# GROUP SPECS
%admin Somehost = NOPASSWD: /usr/bin/rsync

# USER SPECS
anyuser Somehost = (root) NOPASSWD: CPVARCACHE

Everything works well, i.e. no passwd is requested and the copy-job gets done, until I simulate having tampered with test-script. I did so by adding a line to it, e.g. if [ "$1" ] ;then :; fi and running: sudo /home/anyuser/Scripts/test-script cache_bak again.

The sudo shell does not abort as I expected. Instead it checks that the SHA digest has become different and requests a password for anyuser to carry out the job. However, in that case, I want the line cmd to abort unattended (quietly).

Attempting to redirect stdout and stderr to /dev/null:

# after modifying the script so its SHA digest is different from
#+ that in '/etc/sudoers.d/10_user'

$ sudo /home/anyuser/Scripts/test-script cache_bak > /dev/null 2>&1
[sudo] password for anyuser: _^C

The above only redirects output of the subshell process, not that of the sudo process.

If the script is tampered with I need the sudo process to abort, presumably even before it launches the script... I saw interesting stuff (e.g. this), but nothing really relevant...

Cbhihe
  • 2,801
  • 3
  • 27
  • 47

1 Answers1

1

My solution directly adapted from MarcoS' answer on StackOverflow is:

$ sudo -n /home/anyuser/Scripts/test-script cache_bak -- 2> sudo-stderr_"$(date+\%Y\%m\&d-\%H\%M\%S)".log

EXPLANATION:
The -n flag suppresses' sudo's passwd request. So nothing is displayed on stdout.
If a passwd is nevertheless required, sudo dies gracefully after sending an error message to stdderr. For example:

$ sudo -n ls
sudo: a password is required

is immediately followed by sudo process death.

To redirect sudo's stderr, first add -- after the sudo'd cmd to signify that sudo stops interpreting what comes afterwards as cmd line arguments. Redirection of stderr is as usual denoted by 2> followed by ad-hoc log-filename.

Cbhihe
  • 2,801
  • 3
  • 27
  • 47