2

I have a bash script (x11docker) that needs to run some commands as root (docker), and some commands as unprivileged user (X servers like Xephyr). The script prompts for password at some point. It should run on arbitrary linux systems without configuring the system first.

Some systems use su, some use sudo to get root privileges. How can I recognize which one will work? I tried sudo -l docker. That should tell me if sudo dockeris allowed. Unfortunately, it needs a password even for this information.

The point is, root may or may not have a password (that is needed to use su -c), and sudo may or may not be allowed to run docker. How to decide which one will do the job (=executing a command with root privileges)?

Checking for group sudo may be a good guess, but is not reliable, as it does not tell me if /etc/sudoers is configured to allow group sudo arbitrary root access. Also, docker can be allowed in /etc/sudoers without the user being member of group sudo.

pkexec should be a solution, but is not reliable. The password prompt fails on console, fails on X servers different from DISPLAY=:0, and fails on OpenSuse at all.

Currently, the script defaults to use su, and a switch --sudo allows to use sudo. Possible, but not nifty.

I am working on an update allowing to run the script as root at all and checking for the "real" unprivileged user with logname, SUDO_USER and PKEXEC_UID. Not nifty, too.

Is there a way to know if I should use su or sudo?

mviereck
  • 2,377
  • 1
  • 18
  • 18
  • `su` switches to a user with an interactive shell (switch user). `sudo` just executes a command as that user (switch user & do). If no user is specified root will be used. – jesse_b Aug 04 '17 at 12:23
  • 1
    Basically you probably shouldn't use either in a script, but it would probably be best to execute the script as root (or `sudo script`) and then within the script `su - docker` before executing the commands needed for it. – jesse_b Aug 04 '17 at 12:30
  • The point is, root may or may not have a password (that is needed to use `su -c`), and `sudo` may or may not be allowed to run docker. How to decide which one will do the job (=executing a command with root privileges)? – mviereck Aug 04 '17 at 14:19
  • @Jesse_b: Not sure what you mean with `su - docker`, I have no user called docker. Do you mean `su -c docker`? Starting the script with root privileges and than switching back to unprivileged user is possible, if I can rely on `logname`, `SUDO_USER` and `PKEXEC_USER`, as I said. But that is not a good way, I think. – mviereck Aug 04 '17 at 14:26
  • if you want to `run as` use `sudo`. If you want to log into the shell interactively as another user use `su -` – jesse_b Aug 04 '17 at 14:32
  • 2
    @Jesse_b You can use `su` to run a single command with the `-c` option. The big difference between `sudo` and `su` is that `sudo` has a configuration file listing what's allowed, and `sudo` asks for the user's own password rather than the target user's password, and can be configured to not ask for a password. – Barmar Aug 05 '17 at 00:33
  • @Jesse_b And you can get an interactive shell with `sudo -s`. – Barmar Aug 05 '17 at 00:34
  • If you can split the script into privileged vs unprivileged, then you tell the system administrator to run the privileged part as $(local root mechanism) and the rest as another user. Or tell them to run the whole thing as root and 'su otheruser' to run the non-privileged commands. – Jeff Schaller Aug 06 '17 at 00:38
  • @Jeff Schaller: I also try to run the script as root and to use `su otheruser -c` for unprivileged commands. But I don't see a reliable way to find out the right unprivileged user. `logname` is part of [POSIX](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/logname.html), but fails for example in gnome-terminal in Ubuntu 16.04. Same problem with `/proc/self/loginuid`. Then I fall back to `$SUDO_USER` and `$PKEXEC_UID`. About `logname` issue: [A proper replacement for the `logname` utility?](https://unix.stackexchange.com/questions/347889/a-proper-replacement-for-the-logname-utility) – mviereck Aug 06 '17 at 15:16

2 Answers2

0

You can at least test whether root has a password. In that case you probably want to try sudo:

if [ foo = "$(echo | su -c "echo foo")" ]; then
  su -c whatever
else
  sudo whatever
fi
Hauke Laging
  • 88,146
  • 18
  • 125
  • 174
  • Thanks, but this fails at least on debian 9 and fedora 25, although root has a password. I always get error code 1, and "else ..sudo" comes up. – mviereck Aug 06 '17 at 10:53
  • @mviereck The idea is that `sudo` does get executed if there is a password for `root`... – Hauke Laging Aug 06 '17 at 12:15
  • Your example always defaults to sudo, regardless of root having a password or not. The check if root has a password does not work. (now checked on Ubuntu 16.04, too) – mviereck Aug 06 '17 at 13:30
  • @mviereck OK, that's bad. I tested it with a non-root account on openSUSE Tumbleweed. Would it be possible to make sure that certain software (like `expect`) is installed on all affected systems? – Hauke Laging Aug 06 '17 at 13:43
  • As I provide just a bash script, I want to avoid dependencies that are not commonly already installed. Looking at debian 9, `expect` is not installed by default. Software that is common for all main distributions may be expectable. I try to avoid hard dependencies. The script uses for instance xrandr and xdpyinfo, but does not fail if they are missing. – mviereck Aug 06 '17 at 14:42
0

The su command switches to the super user – or root user – when you execute it with no additional options. You’ll have to enter the root account’s password. This isn’t all the su command does, though – you can use it to switch to any user account. If you execute the su bob command, you’ll be prompted to enter Bob’s password and the shell will switch to Bob’s user account.

Once you’re done running commands in the root shell, you should type exit to leave the root shell and go back to limited-privileges mode.

Sudo runs a single command with root privileges. When you execute sudo command, the system prompts you for your current user account’s password before running command as the root user. By default, Ubuntu remembers the password for fifteen minutes and won’t ask for a password again until the fifteen minutes are up.

Shiva
  • 1
  • 2
  • 1
    Thanks, but that does not answer my question, whether a system provides either su or sudo to get root privileges. Apart from that, both su and sudo can be used for single commands or for interactive sessions. (`su -c` or `sudo -s` to change default behaviour). – mviereck Aug 06 '17 at 16:16