# Prevent script from sudoing

I have a script that runs an utility every two days. This utility does some stuff on my system. It is a very known, widely used piece of open source software.

#!/usr/bin/env bash

#...do stuff here
utility


Sometimes, but not always, utility will need me to enter my password so it can do its thing. I'm not watching utility run, and I'm not looking at any output either, 1>/dev/null. So I'd like for any attempt utility makes to sudo to automatically fail. Later I can run it manually and see what it needs superuser access for.

The problem is that it's not my script sudoing, it's utility. utility updates regularly so I don't want to edit it. Setting SUDO_ASKPASS to something useless looked promising but it requires sudo to have been caled with -A from utility. utility man page and online docs also don't have a way to "prevent sudo", neither did I have any luck googling "prevent system wide sudo."

I'm thinking of using this fake-sudo-test.bash:

#!/usr/bin/env bash

FAKE_SUDO="/usr/local/bin/sudo"
echo "echo 'no sudo for you $0' && exit 1" >$FAKE_SUDO
chmod u+x $FAKE_SUDO sudo echo "I got superuser access" \rm$FAKE_SUDO


This works because my $PATH has /usr/local/bin in front of /usr/bin. Do you know a better way to do it? PS: utility is brew, from the homebrew package manager for macOS, and I'm using brew upgrade in question. I thought making the question more generic would make it more useful. $ sudo -V
Sudo version 1.8.17p1
Sudoers policy plugin version 1.8.17p1
Sudoers file grammar version 45
Sudoers I/O plugin version 1.8.17p1

• You could create a function named sudo that exits if called – Jesse_b Jul 4 '18 at 16:04
• That's true. :) – Thomazella Jul 4 '18 at 16:40
• @Jesse_b A shell function would not be callable from within the utility. – Kusalananda Jul 4 '18 at 16:45
• brew practically never calls sudo (and if it does it calls /usr/bin/sudo so your false sudo won't work), maybe one of the formulae does? Anyway, can't you allow sudo brew in /etc/sudoers for the user in question? And then run the whole brew update with sudo? – nohillside Jul 4 '18 at 17:32
• Are you sure it’s calling sudo? You could set the sudo prompt to something unique to confirm. – Jeff Schaller Jul 4 '18 at 17:37

It cannot ask for a password if it is not associated with a terminal:

setsid brew < /dev/null &> /dev/null


Or, if you want to capture its output:

setsid brew < /dev/null |& cat


That is, supposing you have setsid, which apparently may not be available on MacOS. If you want it and don't have it there are implementations available.

If you don't have sedsid but you have at:

[ -e ~/brew_$$.log ] && rm ~/brew_$$.log
at now << eof
brew > ~/brew_$$.lo_ 2>& 1 || true mv ~/brew_$$.lo_ ~/brew_$$.log eof while ! [ -e ~/brew_$$.log ]; do sleep 1; done
cat ~/brew_$$.log && rm ~/brew_$$.log


will run brew now-ish detached from the terminal, capture the output and copy it into the output stream of the script.

1. Take yourself out of /etc/sudoers. This will make all sudo attempts fail.

You may need to comment out this line:

%sudo   ALL=(ALL:ALL) ALL


Make sure you have an alternate way of gaining root (e.g. root password) so that you can undo this.

2. Modify this line in /etc/sudoers:

Defaults        env_reset


into

Defaults        env_reset,timestamp_timeout=-1


3. All failed sudo attempts are logged to /var/log/auth.log. Run utility, and look for a line like this in auth.log:

Jul  4 12:23:07 host sudo: test_perm : user NOT in sudoers ; TTY=pts/1 ; PWD=/home/nick ; USER=root ; COMMAND=/bin/echo


(This might be logged to somewhere else on macOS; I'm not sure.)

• I think on my sudoers setting the timeout to -1 is making the timestamp never expire. I'll test it on linux and I think it'll work as we expect... I edited the post with sudo -V info. I still need to test taking myself out of the sudoers though. – Thomazella Jul 5 '18 at 14:42

On Linux, you can disable the effect of the setuid bit for the process and all other processes launched from it by enabling the no_new_privs flag (see prctl(2)). In shell scripts, you can do this with the setpriv utility from the util-linux package:

\$ setpriv --no-new-privs sudo -v
sudo: effective uid is not 0, is /usr/bin/sudo on a file system with the 'nosuid' option set or an NFS file system without root privileges?


So modifying your script to run setpriv --no-new-privs utility instead of utility should do the job, as long as you can live with the noisy error message above.

(Unfortunately, you mention brew, and this probably doesn’t work on macOS… but perhaps it still helps someone else.)

• I didn't know about this, thanks, I'll try it. – Thomazella Jul 5 '18 at 17:17
• As far as I can tell, setpriv doesn't seem to have an implementation for macOS. But yeah, nice you added it to the thread anyway. – Thomazella Jul 6 '18 at 6:08