如何允许bash -c为sudoers(后跟多个命令)?

时间:2014-09-02 12:42:17

标签: bash sudo sudoers

我在/ etc / sudoers中有这个:

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

执行sudo /bin/bash -c echo foo无需提示输入密码即可运行。

但是,sudo /bin/bash -c "echo foo && echo bar"仍然要求输入密码。

我已尝试许多变体,但没有接受任何内容。

哪里出错? /如何允许-c后跟多个命令?

2 个答案:

答案 0 :(得分:4)

问题在于shell如何解释参数。如果我在bash中(大多数其他shell以相同的方式工作),我输入命令

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

sudo后面的所有内容作为参数。但是,shell会在将每个参数传递给sudo之前对其进行处理。它所做的一件事是删除引用参数周围的引号。因此,sudo得到的argv值的参数是一个看起来像这样的数组(每行一个参数):

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

sudo将这些与空格结合起来,并将其与sudoers文件中的命令进行比较(实际上它比这更复杂,因为它会进行通配符替换等)。因此,为了检查权限,它实际看到您执行的命令是

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

当我将该命令放在我的sudoers文件中时,当我输入

时,系统不会提示我输入密码
sudo /bin/bash -c "echo foo && echo bar"

但是,当我输入任何这些命令或其他命令时,我也不会提示输入密码。

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

一般来说,据我所知,sudo(或任何程序)无法知道完全输入了什么命令,只知道它被转换为什么命令shell用于执行目的。

答案 1 :(得分:2)

至少在我的sudo(OS X 10.9,sudo 1.7.10p7)中,/etc/sudoers中的引号与字面匹配。也就是说,指定

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

意味着用户必须运行

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

即。引号必须传递给程序。

因此,您只需在/ etc / sudoers中删除引号:

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

虽然这看起来很奇怪,但它完全适用于我的机器:用户可以在没有密码的情况下执行/bin/bash -c "echo foo && echo bar"。这是有效的,因为根据man sudoers,必须转义的唯一字符是',', ':', '=' and '\'

请注意,这意味着sudo基本上将所有命令行参数连接在一起,只用空格来确定匹配:用户也可以执行/bin/bash -c "echo foo" "&&" "echo bar"。因此,您必须注意,任何参数都不能单独成为安全风险(例如,foo&&bar不是可以用来利用您的计算机)。