如何允许sudoers使用bash -c(跟随多个命令)?

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


1
一个明显的解决方法:将其称为/usr/local/bin中的脚本,并在/etc/sudoers中引用该脚本 :) - user3159253
@user3159253 这是我目前的方法 - 我想要摆脱它 :) - user569825
嗯,最明显的解决方案通常是最好的 :) sudoers手册提到应该对传递给shell的特殊符号进行反斜杠保护,但我在你的命令中没有看到任何这样的符号。 - user3159253
额外的文件会使我的设置变得复杂,因为有多个脚本受到影响 - 而且涉及多台机器。我也尝试过使用 sudo /bin/bash -c \"echo foo && echo bar\" 进行测试 - 但没有成功。 - user569825
你试过使用 \&\& 吗? - BeniBela
显示剩余2条评论
2个回答

5

问题在于你的shell如何解释参数。如果我使用bash(大多数其他shell也是同样的工作方式),并输入以下命令:

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

sudo 命令会将其后面的所有内容作为参数调用。但在传递到 sudo 前,shell 会处理每个参数。其中一件事情是移除带引号的参数周围的引号。因此,sudo 得到的参数数组(每行一个参数)如下:

/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
非常好的解释。谢谢! - user569825

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的说法,唯一必须转义的字符是',', ':', '='和'\'

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


谢谢。我把赏金给了@Austin作为他的解释,并接受了你的答案,因为它对于其他寻找解决方案的人来说是“更快速的阅读”。 - user569825

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接