7

我在 /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 后跟多个命令?

4

2 回答 2

5

问题在于你的 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 转换成什么来执行。

于 2014-09-13T07:41:55.513 回答
3

至少对于我的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不是可以用来利用您的计算机的东西)。

于 2014-09-13T15:31:14.210 回答