-1

What I'm aiming for:

I want to run:

  1. multiple lines at once
  2. under another user
  3. with access to the variables set by the user I'm running from

So from this:

ROOT_VAR='var-set-from-root'

cmd="
 echo $ROOT_VAR
 echo `whoami`
 echo $HOME
"

the DESIRED RESULT would be:

var-set-from-root
UserA
/home/UserA

What I've tried so far:

1 run with bash; commands contained in double quotes:

cmd="
 echo $ROOT_VAR
 echo `whoami`
 echo $HOME
"

sudo -u UserA bash -c "{$cmd}"

# result (has access to root var but still running as root):
var-set-from-root
root
/root

2 run with bash with commands in heredoc

sudo -u UserA bash -c<<EOF
 echo $ROOT_VAR
 echo `whoami`
 echo $HOME
EOF

# result (error):
bash: -c: option requires an argument

3 run with su and commands in heredoc with single quote

su UserA <<'EOF'
 echo $ROOT_VAR
 echo `whoami`
 echo $HOME
EOF

# result (no access to root var but running as correct user):

UserA
/home/UserA

4 run with su and commands in heredoc without quotes

su UserA <<EOF
 echo $ROOT_VAR
 echo `whoami`
 echo $HOME
EOF

# result (has access to root var but still running as root):
var-set-from-root
root
/root

5 run with bash; commands in double quotes; root var passed as param:

cmd="
 echo $1
 echo `whoami`
 echo $HOME
"

sudo -u UserA bash -c "{$cmd}" $ROOT_VAR

# result (no access to root variable parameter):

root
/root

None of them can access the variable set from the root user while at the same time running under the non-root user. Is it possible even by using parameters?

jww
  • 83,594
  • 69
  • 338
  • 732
jbobbins
  • 1,084
  • 1
  • 13
  • 23
  • Does [this](https://stackoverflow.com/q/8633461/589259) help? – Maarten Bodewes Jan 08 '19 at 23:53
  • Your first example actually works under Ubuntu 18.04. I tried this under root and it worked: `whoami && TEST="1" && sudo -u nav bash -c "echo $TEST && whoami && echo $HOME"` Output is `root 1 nav /home/nav` – TheNavigat Jan 08 '19 at 23:53
  • @TheNavigat strange....I copy/paste/modify-user/run your command under root and output is: `root 1 UserA /root` If I `su UserA` and `echo $HOME` I get `/home/UserA` This is in Ubuntu 18.04.1 LTS – jbobbins Jan 09 '19 at 00:11
  • Yep, you're correct. My bad. This fixes it: https://unix.stackexchange.com/a/177011/215614. It's basically because of a couple of things: you need `-i` to include the user's environment, and `\$HOME` to ensure that the dollar sign actually passes on to the command correctly instead of passing on root's own HOME. – TheNavigat Jan 09 '19 at 10:52

2 Answers2

3

A slight modification of your first example should work:

cmd="
 echo $ROOT_VAR
 echo \`whoami\`
 echo \$HOME
"

sudo -H -u UserA bash -c "{$cmd}"

-H is needed to set the $HOME variable of the user based on this.

Regarding the backslashes, the distinction here between \$HOME and $ROOT_VAR is quite tricky. When the command is parsed, $ROOT_VAR is actually expanded to it's real value. In other words, the value of cmd is the following:

cmd="
  echo var-set-from-root
  echo `whoami`
  echo $HOME
"

You need to use backslashes to avoid parsing of whoami and $HOME in the root's environment and instead pass on the execution of the command to the user's bash itself.

TheNavigat
  • 826
  • 10
  • 27
  • Did the sample in the first section run for you without errors? I get this: `mesg: cannot open /dev/pts/0: Permission denied bash: -c: line 1: syntax error: unexpected end of file ` – jbobbins Jan 09 '19 at 15:58
  • I wasn't able to get `-i` to work, as mentioned in my first comment. But this did output my desired result: `sudo -H -u zteed998 bash -c "{$cmd}"` So if you update your answer accordingly, I will accept your answer. – jbobbins Jan 09 '19 at 16:43
  • 1
    My bad. It looks like because of the way `-i` works, the commands have to be joined using `&&` or so in order to work. I didn't test it properly. `-H` works and is actually more specific than `-i`, so I modified the answer to reflect that. Thanks! – TheNavigat Jan 09 '19 at 18:08
2
# as root
var=1
export var
sudo -E -u kamil sh -c 'echo "$(whoami) var = $var"'
echo "$(whoami) var = $var"

will output:

kamil var = 1
root var = 1
  1. sudo let's you run as another user
  2. sueo -E allows to preserve environment, see man sudo
  3. After sudoing, you need to execute a program - typically sh or bash for a script, sometimes with <<'EOF' for unexpanded multiline commands

The folllwing:

export var=1
sudo -E -u kamil sh <<'EOF'
echo "I am $(whoami) and..."
echo "var = $var"
echo "Let's change it!"
var=2
echo "var = $var"
EOF
echo "$(whoami) var = $var"

will output:

I am kamil and...
var = 1
Let's change it!
var = 2
root var = 1

You can always be even more explicit with env:

sudo -u kamil env var="$var" sh -c 'echo "$var"'

where you exactly choose what you pass around.

KamilCuk
  • 69,546
  • 5
  • 27
  • 60
  • This had the same issue that @TheNavigat answer had, which is that `$HOME` was outputting `/root`. With the `-H` switch, it outputs correctly as `/home/UserA` – jbobbins Jan 09 '19 at 16:56