Чому файл із 400 дозволами бачиться корінним файлом, але лише для читання користувачем?


10

Якщо я створюю файл як непривілейований користувач і змінюю режим дозволів на такий 400, він вважає, що цей користувач є правильним лише для читання:

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

Все добре.

Але потім з'являється корінь:

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

Якого біса? Звичайно, root може писати файли лише для читання, але це не має звички: найкраща практика може диктувати, що я маю змогу перевірити біт дозволу на запис, а якщо це не так, тоді він був встановлений таким чином з причини.

Я думаю, я хочу зрозуміти і те, чому це відбувається, і як я можу отримати помилковий код повернення при тестуванні файлу, на якому не встановлено біт запису?


btw Я використовую і RHEL6 ( 4.1.2(1)-release), і RHEL7 ( 4.2.46(2)-release).
Багатий

16
"Найкраща практика схильна диктувати, що я повинен мати можливість перевірити біт дозволу на запис, а якщо це не так, то він був встановлений таким чином з причини". - Насправді найкраща практика - «не запускати матеріали як корінь». Якщо ви працюєте як root, ви вже вирішили обійти перевірки дозволів. Повторна реалізація цих перевірок дозволів у просторі користувачів є рецептом катастрофи .
Кевін

@Kevin Добре для вас, якщо ви можете вести матеріали непривілейовано. Це для маніпулювання /etc/dhcp/dhcpd.conf, яким належить root. Я використовую постачальника dhcpd. Загальна катастрофа, так? Файл перевіряється в RCS, я автоматизую використання rcsdiff, ciі coтому, що у нас є оператори, яким потрібно ... працювати. Перевірка бітів дозволів ( -wяк детально описано test(1)) мала бути першим рядком відмови, працюючи на основі, що ci -uзалишає файл лише для читання. Я кидаю це і пряму до rcsdiff -qта перевіряю $?. Нечесно dhcpd? Це було б у власності dhcpd.
Багатий

1
Це потенційна катастрофа, оскільки тепер у вас є дві різні реалізації перевірок дозволів: одна в ядрі та одна в просторі користувачів. Гірше, що ці реалізації навіть не приводять до отримання однакових результатів, тому ви не можете просто перевірити їх незрозуміло. Отже, у вас є два шляхи до доступу, які потрібно заблокувати та захистити незалежно один від одного.
Кевін

@Kevin Sure, вони не дають однакових результатів і не збиралися (незважаючи на нечисленні деталі в Manpages), але я явно хочу перевірити біт дозволу на запис ; і керівництво для мене bashі testзмусило мене повірити, що це і [ -wє.
Багатий

Відповіді:


26

test -wака [ -wне перевіряє режим файлу. Він перевіряє, чи це можливо для запису. Для кореня це так.

$ 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інтерпретувався як вісімковий знак (( ... )).


Дякуємо, що ви були лаконічними. Гарне використання (( ... & ... )). Одним типом виправлено :-)
Багатий

Зробіть так, щоб 3 ... Не ifпотрібно, октальних дозволів %aне є %d, і (( ... ))потрібен префікс, 0щоб інтерпретувати вихід statяк восьмеричний.
Багатий

@Patrick моє 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, це не перешкоджає його запису ...


Ні, "непорозуміння" було б читанням невідповідних сторінок -w: test(1)явно: "ФАЙЛ існує і дозвіл на запис надається", а не " файл може бути записаний поточним користувачем ". Нічого про переважні дозволи, а також ACL. bash(1)є cagey: "Дійсно, якщо файл існує і піддається запису ." ksh(1)робить тонкий натяк на shenanigans: "-w файл // Правда, якщо файл існує і його можна записати поточним процесом ." zsh(1)відкладає test(1), zshmisc(1)формулюється як ksh(1), і zshexpn(1)деталізує деякі цікаві дозволи на основі глобалізації. csh(1)весело коротко: "Пишіть доступ".

btw: Я прийняв відповідь Патріка, 1. оскільки ви не відповіли належним чином на головне запитання: як я можу отримати помилковий код повернення під час тестування файлу, у якому не встановлено біт запису? і 2. через хиткий привід, припускаючи, що я неправильно зрозумів підручники.
Багатий

3
@Rich Як я читаю це, я думаю, що ваші коментарі також трапляються як трохи хиткі. Я не кажу, що все, що ви написали, було неправильним, просто, що, ймовірно, піде краще, якщо висловитись більш ввічливо.
David Z

3
"Я думаю, ви зрозуміли неправильно ..." - це не хитро. Ваша відповідь, проте, 100% химерна.
мангал

@Rich Крім того, хоча керівництво не може бути кришталево чистим, Стівен заявив, що ви, можливо, "неправильно зрозуміли, що робить -w ", а не те, що кажуть manpages , де виглядає колишній випадок, звідси питання
Sebi

1

Користувач root може робити, як їй заманеться, "нормальні" дозволи на файли не обмежуються. Він не буде безпосередньо виконувати звичайний файл без будь-яких дозволів eXecute, лише для трохи страхування від практичної цільової практики.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.