2012-07-19 112 views
4

我有一个脚本(由我的前任编写),它成功编辑运行OS X 10.6的Mac上的sudoers文件;它是这样的:在OS X中编辑sudoers(10.7)

#!/bin/sh 

if [ -z "$1" ]; then 
    export EDITOR=$0 && sudo -E visudo 
else 
    echo "%staff ALL=NOPASSWD: /sbin/shutdown" >> $1 
fi 

然而,当在Mac上运行的运行10.7,而不是添加一行到sudoers文件,它会启动visudo命令,“交互”。在任何时候它似乎都没有进入“其他”条款。我怀疑第4行(“export ...”)的适当语法已经改变,但我似乎无法找出如何。任何指针?

由于有人会问:我们有一个详细的(并且有些愚蠢的,但必然如此)强制重新启动计划进行修补。如果用户在截止日期前没有重新启动,应用程序将启动5分钟倒计时(或立即重启选项),此时发出'sudo shutdown -r now'命令。为了我的理智,请不要要求我捍卫这种安排的性质。这是我无法控制的。

+0

- 删除了以前的评论;无视 - – jpdyson 2012-07-19 17:55:54

回答

1

visudo(8)有这样一段话:

有是visudo命令,将使用设置在编译时 可以通过编辑sudoers文件默认变量覆盖一个或多个编辑的硬编码列表。该列表默认为 “/ bin/vi”。通常情况下,visudo不会遵守VISUAL或EDITOR环境变量 ,除非它们在上述编辑器列表中包含编辑器。但是,如果使用--with-env-editor选项配置visudo为 ,或者在 sudoers中设置env_editor默认变量,visudo将使用由VISUAL或EDITOR定义的任何编辑器。请注意,这可能是一个安全漏洞,因为它允许用户通过设置 VISUAL或EDITOR来执行他们希望的任何程序。

我怀疑这就是你在这里遇到的情况。

+0

我同意。我会去看看这个;然而,为什么它在10.6而不是10.7工作是一个谜。 10.6在我们的环境中是一个全面的,单一的图像,而10.7更多地是一个汇总,这更加复杂。这可能是因为我们的10.6图像有一些其他的调整可以使用EDITOR。 – jpdyson 2012-07-19 17:29:50

+0

进一步测试 - 在我的10.6机器上,我能够导出EDITOR =/path/to/script,echo验证,然后运行sudo visudo - 所有操作都按预期进行(sudoers文件按预期进行了修改)。我在10.7上做了同样的事情,回声来验证,但是当我运行sudo visudo时,EDITOR env var绝对被忽略(它在vi中打开)。你的理论得到证实。 – jpdyson 2012-07-19 18:01:55

2

if [ -z "$1" ];是一种常见的习惯用法,用于检查是否没有给出脚本参数。当调用而没有参数时,脚本将采用第一个路径,启动编辑器(在这种情况下,应该是此脚本本身)。 以文件名作为参数,采用else分支,并且非交互式地在文件中附加一行(在visudo上下文中)。

假设脚本在没有参数的情况下被外部调用,sudo开始清除EDITOR环境变量,或者(如@twalberg指出的)visudo现在忽略EDITOR。

要修复,调整sudoers文件继续编辑,要么允许任何程序的编辑器通过设置env_editor,或脚本(以及任何其他脚本编辑sudoers文件)添加到editor变量。

Defaults env_keep += "EDITOR" 
# UNSAFE 
#Defaults env_editor 
# better 
Defaults editor = "/usr/bin/vi:/path/to/script" # ... possibly more 

如果你不希望这样做(或不能这样做,非交互),它是安全的假设,同步编辑不会发生,你可以这样做以下:

cp -p /etc/sudoers /etc/sudoers.tmp 
echo "%staff ALL=NOPASSWD: /sbin/shutdown" >> /etc/sudoers.tmp 
if visudo -cqf /etc/sudoers.tmp; then 
    mv /etc/sudoers.tmp /etc/sudoers 
else 
    rm /etc/sudoers.tmp 
    echo "update failed" 
fi 
+0

/etc已经(在10.6和10.7中)建立到/ private/etc的符号链接,这是sudoers所在的位置。我也试过指定/ private/etc/sudoers,但得到相同的结果 - 打开sudoers文件,而不是编辑。 – jpdyson 2012-07-19 14:45:18

+0

尝试直接运行'echo“%staff ALL = NOPASSWD:/ sbin/shutdown”>>/private/etc/sudoers'(当然,您可能需要root)。如果是这样的话,用这个单行代码替换对脚本的调用(即删除围绕该命令的'if',包括不需要的分支)。 – nobody 2012-07-19 14:48:59

+0

这很有效,但它可能不是超级明智的,因为它绕过visudo。我还没有提到我们使用Casper Suite来部署所有这些以root身份运行所有脚本的东西,所以这没有问题。 – jpdyson 2012-07-19 17:28:23