web-dev-qa-db-ja.com

400の権限を持つファイルがrootからは書き込み可能であるのに、ユーザーからは読み取り専用であるのはなぜですか?

非特権ユーザーとしてファイルを作成し、アクセス許可モードを400に変更すると、そのユーザーには正しく読み取り専用として表示されます。

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

すべては順調です。

しかし、その後ルートがやって来ます:

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

一体何ですか?確かに、rootは読み取り専用ファイルに書き込むことができますが、それを習慣にするべきではありません。ベストプラクティスでは、書き込み許可ビットをテストできるはずであると指示する傾向があり、そうでない場合は設定されています。理由のためにその方法。

なぜこれが起こっているのか、そして方法の両方を理解したいと思う書き込みビットが設定されていないファイルをテストするときにfalse戻りコードを取得できますか?

10
Rich

_test -w_別名_[ -w_はファイルモードをチェックしません。書き込み可能かどうかをチェックします。ルートについては、そうです。

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

私がテストする方法は、stat(1)( "_%a_ 8進数のアクセス権")の出力に対してビットごとの比較を行うことです。

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

statの出力が_0_によって8進数として解釈されるように、サブシェル$(...)には接頭辞_(( ... ))_が必要であることに注意してください。

26
Patrick

_-w_の機能を誤解していると思います。ファイルに「書き込み権限」があるかどうかはチェックせず、ファイルがinvokingユーザーによって書き込み可能かどうかをチェックします。

具体的には、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であるという理由だけで、ファイルが書き込み可能であることを停止しません...

30
Stephen Harris

Rootユーザーは好きなように実行できますが、「通常の」ファイル権限は制限されません。これは、足のターゲットの練習に対する少しの保険のために、eXecute権限なしでプレーンファイルを直接実行しません。

1
vonbrand