我在/ 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后跟多个命令?
答案 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
不是可以用来利用您的计算机)。