How can I allow bash -c for sudoers (followed by multiple commands)?
Asked Answered
P

2

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?

Posh answered 2/9, 2014 at 12:42 Comment(7)
One obvious work-around: call it a script in /usr/local/bin and refer to that script in /etc/sudoers :)Cankerous
@Cankerous that's my current approach - which I want to get away from :)Posh
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.Cankerous
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.Posh
Did you try \&\& ?Incontrollable
@Incontrollable Yes :) Been at it for (felt) hours.Posh
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.Ishii
A
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).

Adamson answered 13/9, 2014 at 15:31 Comment(1)
Thanks. I gave the bounty to @Hairy for for his explanation and accepted your answer, as it's the "quicker read" for others looking for a solution.Posh
H
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.

Hairy answered 13/9, 2014 at 7:41 Comment(0)
A
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).

Adamson answered 13/9, 2014 at 15:31 Comment(1)
Thanks. I gave the bounty to @Hairy for for his explanation and accepted your answer, as it's the "quicker read" for others looking for a solution.Posh

© 2022 - 2024 — McMap. All rights reserved.