Guys, this has been driving me crazy: As far as I know, sudo -u <user> can be used in a script that is being run as sudo in order to “cancel out” the sudo, hence run the line that follows as the regular user <user>. Only it doesn’t seem to me to be working like this, at least not in the context below: it’s as if sudo -u <user> doesn’t do anything!
Here’s the context: I got two small Bash scripts, a master.sh script, and a slave.sh script:
master.sh:
#!/bin/bash
# Run as root/sudo.
if [ ! $(id -u) == 0 ]
then
echo "This script should be run as root! Exiting ..."
exit
fi
sudo -u dad /home/dad/Downloads/slave.sh
slave.sh:
#!/bin/bash
if [[ ! -v DOTNET_ROOT ]] # If variable is not set ...
then
echo "DOTNET_ROOT needs to be set ..."
else
echo "No need to set DOTNET_ROOT."
fi
Here’s what happens:
dad@DadsGram~/Downloads $ echo $DOTNET_ROOT
/home/dad/.dotnet
dad@DadsGram~/Downloads $ ./slave.sh
No need to set DOTNET_ROOT.
dad@DadsGram~/Downloads $ sudo ./master.sh
DOTNET_ROOT needs to be set ...
dad@DadsGram~/Downloads $ sudo ./slave.sh
DOTNET_ROOT needs to be set ...
dad@DadsGram~/Downloads $ echo $DOTNET_ROOT
/home/dad/.dotnet
dad@DadsGram~/Downloads $ ./slave.sh
No need to set DOTNET_ROOT.
dad@DadsGram~/Downloads $ sudo ./master.sh
DOTNET_ROOT needs to be set …
dad@DadsGram~/Downloads $ sudo ./slave.sh
DOTNET_ROOT needs to be set …
There is the sudo --preserve-env option. I have seen the -E option used recently and checked the man page.
-E, -‐preserve‐env
Indicates to the security policy that the user wishes to pre‐
serve their existing environment variables. The security pol‐
icy may return an error if the user does not have permission to
preserve the environment.
--preserve‐env=list
Indicates to the security policy that the user wishes to add
the comma‐separated list of environment variables to those pre‐
served from the user’s environment. The security policy may
return an error if the user does not have permission to pre‐
serve the environment. This option may be specified multiple
times.
Testing:
$ export HI=there
$ sudo --preserve-env sh -c 'echo $HI'
there
$ sudo --preserve-env=HI sh -c 'echo $HI'
there
Something like this in the master script.
sudo --preserve-env=DOTNET_ROOT -u dad /home/dad/Downloads/slave.sh
dad@DadsGram~/Downloads $ cat master.sh
#!/bin/bash
# Run as root/sudo.
if [ ! $(id -u) == 0 ]
then
echo "This script should be run as root! Exiting ..."
exit
fi
sudo --preserve-env=DOTNET_ROOT -u dad /home/dad/Downloads/slave.sh
dad@DadsGram~/Downloads $ echo $DOTNET_ROOT
/home/dad/.dotnet
dad@DadsGram~/Downloads $ sudo ./master.sh
DOTNET_ROOT needs to be set ...
Try also, -E or --preserve-env=VAR option with the initial sudo command.
$ sudo -E /tmp/master.sh
No need to set DOTNET_ROOT.
master.sh
#!/bin/bash
# Run as root/sudo.
if [ ! $(id -u) == 0 ]
then
echo "This script should be run as root! Exiting ..."
exit
fi
sudo --preserve-env=DOTNET_ROOT -u dad /home/dad/Downloads/slave.sh
Thanks, that works. To recap, both changes need to be made: slave needs to be run with the --preserve-env=DOTNET_ROOT prefix, and master needs to be run with the -E option.
Otherwise, I am sure that @miguelinux’s solution works fine as well, but I was hoping to not have to mess with the sudoers.d file, as I am hoping to keep my interventions in the bowels of CL rather limited.
Concerning the sudoers file in /usr/share/defaults/sudo…
If you want, create the folder /etc/sudoers.d/ and just cp /usr/share/defaults/sudo/sudoers file to that new folder. Then you can make changes to sudoers in the /etc/ stage which is not part of the stateless Clear Linux stuff.
Just to be super clear, you need either -E or --preserve-env=DOTNET_ROOT, but for both. -E means “preserve all my environment variables” (potential security risk), while --preserve-env=DOTNET_ROOT means “only preserve $DOTNET_ROOT”, which is all you actually need to preserve. Just use the same option for both scripts.