Почему файл с 400 правами доступа доступен для записи пользователю root, но только для чтения пользователем?

10

Если я создаю файл как непривилегированный пользователь и изменяю режим разрешений на него 400, он корректно воспринимается этим пользователем как доступный только для чтения:

$ touch somefile
$ chmod 400 somefile
$ [ -w somefile ] && echo rw || echo ro
ro

Все хорошо.

Но потом приходит root:

# [ -w somefile ] && echo rw || echo ro
rw

Какого черта? Конечно, root может писать в файлы, доступные только для чтения, но это не должно вызывать у него привычки: передовой опыт будет склонен диктовать, что я должен иметь возможность проверять бит разрешения на запись, а если нет, то он был установлен таким образом, по причине.

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

Богатый
источник
Кстати, я использую оба RHEL6 ( 4.1.2(1)-release) и RHEL7 ( 4.2.46(2)-release).
Богатый
16
«Передовой опыт, как правило, диктует, что я должен быть в состоянии проверить бит разрешения на запись, а если нет, то это было установлено именно так». - На самом деле, лучшая практика - «не запускать вещи как root». Если вы работаете от имени пользователя root, вы уже решили обойти проверку прав доступа. Повторная реализация этих проверок разрешений в пользовательском пространстве вручную - это путь к катастрофе .
Кевин
@Kevin Хорошо, если вы можете работать непривилегированным. Это для манипулирования /etc/dhcp/dhcpd.conf, которым владеет root. Я использую поставляемую поставщиком dhcpd. Полная катастрофа, а? Файл проверен в RCS, я автоматизирую использование rcsdiff, ciи coпотому что у нас есть операторы, которые должны ... работать. Проверка бита разрешения ( -wкак подробно описано test(1)) должна была стать первой строкой сбоя, работающей на основе, которая ci -uоставляет файл доступным только для чтения. Я бросаю это и иду прямо к rcsdiff -qпроверке $?. Невероятно dhcpd? Это будет в собственности dhcpd.
Богатый
1
Это потенциальная катастрофа, потому что теперь у вас есть две разные реализации проверки разрешений: одна в ядре и одна в пользовательском пространстве. Хуже того, эти реализации даже не предназначены для получения идентичных результатов, поэтому вы не можете просто проверить их друг против друга. Итак, теперь у вас есть два пути доступа, которые должны быть заблокированы и защищены независимо друг от друга.
Кевин
@Kevin Конечно, они не дают идентичных результатов и не были предназначены (несмотря на недостаток подробностей в man-страницах), но я явно хочу проверить бит разрешения записи ; и руководство для bashи testпривело меня к мысли, что это то, что [ -wдля.
Богатый

Ответы:

26

test -wака [ -wне проверяет режим файла. Это проверяет, если это доступно для записи. Для root это так.

$ help test | grep '\-w'
  -w FILE        True if the file is writable by you.

Я бы проверил способ побитового сравнения с выводом stat(1)%a Права доступа в восьмеричном виде»).

(( 0$(stat -c %a somefile) & 0200 )) && echo rw || echo ro

Обратите внимание, что для подоболочки $(...)необходим 0префикс, так что вывод statинтерпретируется как восьмеричный (( ... )).

Патрик
источник
Спасибо за краткость. Хорошее использование (( ... & ... )). Исправлена ​​одна опечатка :-)
Rich
Сделайте это 3 ... Нет ifнеобходимости, восьмеричные выходные данные разрешений %aне являются %d, и (( ... ))нуждаются в префиксе, 0чтобы интерпретировать выходные данные statкак восьмеричные.
Богатый
@ Патрик мой man statговорит: «% d номер устройства в десятичном виде», но нам нужны «права доступа», нет? Ваша точка зрения о необходимости префикса 0 хорошо сделана, но я думаю, что мы просто должны ее там ввести :).
sourcejedi
2
stat -c 0%a...
sourcejedi
@ sourcejedi ack, ты прав. По какой-то причине я думал, что% d - это права доступа в десятичном формате. Восстановил редактирование. спасибо :-)
Патрик
30

Я думаю, что вы неправильно поняли, что -wделает. Он не проверяет, есть ли у файла «Права на запись», он проверяет, доступен ли файл для записи вызывающему пользователю.

Точнее, звонки access(2)или аналогичные.

например, если скрипт имеет, if [ -w /etc/shadow ]то если вы запустите straceскрипт, вы можете увидеть строку, аналогичную

faccessat(AT_FDCWD, "/etc/shadow", W_OK)

Так как rootможет записать в файл, то он возвращает 0.

например, как обычный пользователь:

faccessat(AT_FDCWD, "/etc/shadow", W_OK) = -1 EACCES (Permission denied)

Как корень

faccessat(AT_FDCWD, "/etc/shadow", W_OK) = 0

Это, несмотря на то, что /etc/shadowимеет разрешение 000на мою машину.

---------- 1 root root 4599 Jan 29 20:08 /etc/shadow

Теперь то, что вы хотите сделать, становится интересным и не так просто.

Если вы хотите проверить простые разрешения, то проверьте lsвывод, или позвоните statили подобное. Но поймите, что списки ACL могут переопределить эти разрешения. То, что файл 400 является разрешением, не мешает его записи ...

Стивен Харрис
источник
Нет, «недоразумение» означает неправильное чтение man-страниц -w: test(1)явно: «ФАЙЛ существует и разрешение на запись предоставлено», а не « файл может быть записан текущим пользователем ». Ничего о переопределении разрешений, ни ACL. bash(1)is cagey: "Истина, если файл существует и доступен для записи ." ksh(1)делает тонкий намек на махинации: «-w file // True, если файл существует и доступен для записи текущим процессомzsh(1)Относится к test(1), zshmisc(1)сформулирован как ksh(1), и zshexpn(1)подробно описывает некоторые интересные глобализации на основе разрешений. csh(1)смешно кратко: «Доступ для записи».
Кстати: я принял ответ Патрика, 1. потому что вы не ответили адекватно на начальный вопрос: как я могу получить ложный код возврата при тестировании файла, для которого не установлен бит записи? и 2. из-за странного вводного предположения, что я неправильно понял manpages.
Богатый
3
@Rich Как я читаю это, я думаю, что ваши комментарии выглядят немного странными. Я не говорю, что все, что вы написали, было неверным, просто, вероятно, оно было бы лучше, если выразить это более вежливо.
Дэвид З
3
«Я думаю, что вы неправильно поняли ...» - это не выдумка. Ваш ответ, однако, 100% вялый.
барбекю
@Rich Кроме того, хотя справочные страницы, возможно, не были кристально чистыми, Стивен заявил, что вы, возможно, «неправильно поняли, что делает -w », а не то, что говорят справочные страницы , где первое выглядит так, поэтому возникает вопрос
Себи
1

Пользователь root может делать все, что ему угодно, «нормальные» права доступа к файлам не имеют ограничений. Он не будет напрямую выполнять простой файл без каких-либо разрешений eXecute, просто для того, чтобы немного застраховаться от практических целей.

vonbrand
источник