7

I have this in /etc/sudoers:

%wheel myhostname =NOPASSWD: /bin/bash -c "echo foo && echo bar", \
                             /bin/bash -c echo foo

Executing sudo /bin/bash -c echo foo works without being prompted for a password.

However, sudo /bin/bash -c "echo foo && echo bar" still asks for a password.

I've tried many variations to this, but nothing is being accepted.

Where's the error? / How can I allow -c followed by multiple commands?

user569825
  • 2,369
  • 1
  • 25
  • 45
  • 1
    One obvious work-around: call it a script in /usr/local/bin and refer to that script in /etc/sudoers :) – user3159253 Sep 02 '14 at 12:52
  • @user3159253 that's my current approach - which I want to get away from :) – user569825 Sep 02 '14 at 12:57
  • Ehhm, the most obvious solutions are often the best :) The sudoers manpage mentiones that special symbols which to be passed to shell should be backslash-protected, but I don't see any of them in your command. – user3159253 Sep 02 '14 at 12:59
  • Additional files would complicate my setup, as there is more than one script affected - and multiple machines. I also had tested with `sudo /bin/bash -c \"echo foo && echo bar\"` - without success. – user569825 Sep 02 '14 at 13:07
  • Did you try `\&\&` ? – BeniBela Sep 02 '14 at 13:33
  • @BeniBela Yes :) Been at it for (felt) hours. – user569825 Sep 02 '14 at 14:10
  • I can't reproduce your problem. `%wheel myhostname =NOPASSWD: /bin/bash -c "echo foo && echo bar"` works well with Ubuntu 11.04. `sudo /bin/bash -c echo foo` without quotation marks won't work. – Cyrus Sep 13 '14 at 07:45

2 Answers2

5

The problem is in how your shell interprets arguments. If I am in bash (most other shells work the same way), and I type the command

sudo /bin/bash -c "echo foo && echo bar"

sudo is invoked with everything after it as arguments. However, the shell processes each argument before passing it in to sudo. One of the things it does is remove quotes around quoted arguments. Therefore, the arguments that sudo gets as its argv value are an array that looks like this (one argument per line):

/bin/bash
-c
echo foo && echo bar

sudo combines these with spaces and compares that to the commands in the sudoers file (it is actually a bit more complicated than this since it does wildcard replacement, etc.). Thus, the command it actually sees you executing, for the purposes of checking permissions is

/bin/bash -c echo foo && echo bar

When I put that command in my sudoers file, I am not prompted for a password when I enter

sudo /bin/bash -c "echo foo && echo bar"

However I am also not prompted for a password when I enter any of these commands or other like them.

sudo /bin/bash "-c echo foo && echo bar"
sudo /bin/bash "-c echo" foo "&& echo" bar
sudo /bin/bash -c echo "foo && echo" bar

In general, as far as I know, there is no way for sudo (or any program) to know exactly what command got entered, only what it gets converted to by the shell for execution purposes.

Austin
  • 2,982
  • 2
  • 28
  • 36
3

At least with my sudo (OS X 10.9, sudo 1.7.10p7), quote marks in the /etc/sudoers are matched literally. That is, specifying

/bin/bash -c "echo foo && echo bar"

means that the users literally have to run

sudo /bin/bash -c '"echo foo && echo bar"'

i.e. the quote marks have to be passed to the program.

Therefore, all you have to do is just drop the quote marks in /etc/sudoers:

%wheel myhostname =NOPASSWD: /bin/bash -c echo foo && echo bar

While this looks kind of weird, it completely works on my machine: users can execute /bin/bash -c "echo foo && echo bar" without a password. This works because, according to man sudoers, the only characters that must be escaped are ',', ':', '=' and '\'.

Note that this implies that sudo is basically concatenating all the command-line args together with only spaces to determine a match: users can also execute /bin/bash -c "echo foo" "&&" "echo bar". Therefore, you must take care that none of the arguments could individually be a security risk (e.g. that foo, && and bar aren't things that could be used to exploit your computer).

nneonneo
  • 171,345
  • 36
  • 312
  • 383
  • Thanks. I gave the bounty to @Austin for for his explanation and accepted your answer, as it's the "quicker read" for others looking for a solution. – user569825 Sep 15 '14 at 07:48