Записать в файл без перенаправления?

12

Я пишу обычное скомпилированное приложение, которое должно создать специальный файл и записать в него волшебный файл cookie. Я не могу записать файл напрямую из приложения, модель безопасности системы требует от меня запуска вспомогательного инструмента с повышенными привилегиями, чтобы сделать свое дело. Я могу предоставить любое количество аргументов вспомогательному инструменту. Теперь я хотел бы выбрать очень простую системную команду, которая будет служить вспомогательным инструментом, и создать файл для меня. Что-то вроде этого:

/bin/sh -c "/bin/echo -n 'magic' > /some/where/file"

Simple touchне обрезает его, так как мне нужно записать cookie в файл, simple echoбез оболочки не работает, так как для записи файла требуется перенаправление. Мне неудобно вызывать оболочку с правами root для выполнения такой тривиальной задачи. Есть ли какая-нибудь действительно простая системная команда с ограничениями, которую я мог бы вызвать, чтобы написать файл для меня?

Zoul
источник
Есть ли причина, почему /bin/sh -c 'echo magic > /path/to/magic/file'не работает? Это будет исполняемый файл и два аргумента. Вам нужно будет построить последний аргумент в виде строки (со sprintf или эквивалентным). Есть ли причина, по которой это не сработает для вас? По твоему вопросу это звучит так, как будто doCommandAsRoot () не принимает ввод в поток в команду, правильно? В противном случае вы можете заменить последний аргумент 'cat > /path/to/magic/file'и передать данные вместо создания строки.
Arcege
Пример оболочки работает, но я бы не хотел вызывать оболочку с привилегиями root только для создания простого файла. Библиотека принимает аргумент канала связи (это AuthorizationExecuteWithPrivileges ), который можно использовать для записи cookie с помощью tee. Спасибо!
zoul
См. Также stackoverflow.com/a/18146890/2032064
Mifeet

Ответы:

11

Как насчет этого:

echo -n 'magic' | sudo tee /some/where/file > /dev/null

Конечно, в этом есть перенаправления, но только тройник работает как root, а не как оболочка. Работает с dd of=...тоже.

stribika
источник
2
Извините, у меня явно есть проблемы с объяснением в последнее время. Проблема в том, что когда я хочу запустить что-то с повышенными привилегиями, мне нужно пройти специальный библиотечный вызов (что-то вроде doCommandAsRoot). И эта функция принимает только путь к команде и ее аргументам, поэтому я не могу сразу использовать перенаправление вывода. Я мог бы пройти через оболочку (как показано в вопросе), но мне это не нравится в плане безопасности.
Zoul
@zoul: Я думал, что вы пишете сценарий оболочки. Можно ли записать магический файл cookie в файл, доступный для непривилегированных процессов? Если это так, запишите его в такой файл и позвоните doCommandAsRoot("dd", "if=/tmp/unprotected_file", "of=/some/where/file").
стрибика
Нет, это обычное скомпилированное приложение (вопрос обновлен). Я просто ищу команды «shell», которые будут служить помощником, чтобы мне не пришлось писать их самому. Да, в куки нет ничего деликатного. ddПример довольно близко к тому, что я хочу, спасибо. Не могли бы вы придумать что-нибудь еще проще?
zoul
Конечно - вы можете использовать cpили mvвместо dd.
Mattdm
Я имею в виду проще, как без необходимости копировать :)
zoul
9

Без перенаправления вывода, без канала, но с «здесь строкой»:

dd of=/some/where/file <<<'magic'
Райнер Перске
источник
Недостатком этого подхода является то, что dd записывает некоторую статистику в стандартный вывод. Вы можете использовать> / dev / null, чтобы скрыть их, но в этот момент вы также можете использовать tee.
Studgeek
1
Это сработало для меня в необычной ситуации, когда я не мог использовать перенаправление вывода или каналы. status=noneбудет подавлять все остальные выходные данные из современных версий GNU coreutils dd.
Майкл Хэмптон
5

Есть еще одно соображение, которое заключается в том, что вы не хотите помещать значение волшебного куки-файла в командную строку, так как это могут наблюдать другие пользователи. Даже если программа недолговечна (в том числе, если программа обнуляет строку командной строки), существует возможность для атаки. Итак, теоретический:

writestringtofile 'magic' /some/where/file

это опасный подход. Поэтому я поддерживаю предложение @ stribika: записать значение во временный файл и скопировать его на место. Убедитесь, что вы используете безопасную функцию для создания временного файла ( mkstemp()), чтобы не было и условия гонки.

mattdm
источник
Спасибо, это полезное обсуждение. К счастью, «волшебное печенье» не является защитным устройством, оно может быть ясно видно любому.
zoul
0

Губка из moreutils - впитать стандартный ввод и записать в файл:

echo -n 'magic' | sponge /some/where/file

В отличие от перенаправления оболочки, губка впитывает весь свой ввод перед записью выходного файла. По возможности sponge создает или обновляет выходной файл атомарно, переименовывая временный файл на место.

Увидеть больше

Илья Муравьев
источник