Редактирование sudoers в OS X (10.7)

У меня есть скрипт (написанный моим предшественником), который успешно редактирует файл sudoers на Mac под управлением OS X 10.6; это выглядит так:

#!/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 "в интерактивном режиме". Кажется, он не вводит предложение "else" в любой момент. Я подозреваю, что соответствующий синтаксис строки 4 ("экспорт...") изменился, но я не могу понять, как. Есть указатели?

Так как кто-то спросит: у нас есть сложный (и по общему признанию, несколько глупый, но обязательно такой) график принудительной перезагрузки для установки исправлений. Если пользователь не перезагружен преднамеренно до крайнего срока, приложение запустится с 5-минутным обратным отсчетом (или с возможностью немедленной перезагрузки), после чего выдается команда "sudo shutdown -r now". Ради моего здравомыслия, пожалуйста, не просите меня защищать природу этого соглашения. Это вне моего контроля.

2 ответа

Решение

visudo(8) имеет это сказать:

Существует жестко запрограммированный список одного или нескольких редакторов, которые visudo будет использовать set во время компиляции, который может быть переопределен с помощью переменной sudoers editor Default. Этот список по умолчанию равен "/bin/vi". Обычно visudo не учитывает переменные среды VISUAL или EDITOR, если они не содержат редактора в вышеупомянутом списке редакторов. Однако, если visudo настроен с параметром --with-env-editor или переменная env_editor Default установлена ​​в sudoers, visudo будет использовать любой редактор, определенный VISUAL или EDITOR. Обратите внимание, что это может быть дырой в безопасности, поскольку она позволяет пользователю выполнять любую программу, которую он пожелает, просто установив VISUAL или EDITOR.

Я подозреваю, что это то, что вы сталкиваетесь здесь.

if [ -z "$1" ]; это распространенная идиома, проверяющая, не заданы ли в скрипте аргументы. При вызове без аргументов ваш сценарий выберет первый путь, запустив редактор (в данном случае это должен быть сам скрипт). Учитывая имя файла в качестве аргумента, else-branch берется и строка добавляется в файл неинтерактивно (в 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
Другие вопросы по тегам