4

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

#!/bin/sh

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

但是,当在运行 10.7 的 Mac 上运行时,它不会将该行添加到 sudoers 文件中,而是“以交互方式”启动 visudo。它似乎在任何时候都没有进入“else”子句。我怀疑第 4 行(“export ...”)的适当语法已经改变,但我似乎不知道如何。任何指针?

既然有人会问:我们有一个精心设计的(诚然,有些愚蠢,但必然如此)强制重启的修补时间表。如果用户在截止日期前没有故意重启,应用程序将在 5 分钟倒计时启动(或立即重启的选项),此时发出“sudo shutdown -r now”命令。为了我的理智,请不要让我为这种安排的性质辩护。这是我无法控制的。

4

2 回答 2

2

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

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

要解决此问题,请调整 sudoers 文件以保留 EDITOR,并通过设置允许任何程序作为编辑器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
于 2012-07-19T14:15:41.070 回答
1

visudo(8)有话要说:

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

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

于 2012-07-19T15:25:31.103 回答