web-dev-qa-db-ja.com

ターミナル:ユーザーまたはグループが書き込み許可を持つすべてのディレクトリを一覧表示します

ユーザーまたはグループが書き込み権限を持っているすべてのディレクトリを一覧表示します。

ServerFaultのこの質問 が見つかりましたが、Windows Serverに対応しているので、Linuxコミュニティにはもっと良いものがあると楽観しています。同時に、この質問には再帰的なひねりがあり、長時間実行するスクリプトなしでは不可能になる可能性があることに気付きました。

私は次の便利なコマンドを知っています:

  • すべてのグループをリストします:cut -d : -f 1 /etc/group
  • すべてのユーザーのリスト:cut -d : -f 1 /etc/passwd
  • ユーザーのホームディレクトリを取得します:getent passwd user-name| cut -d: -f 6
  • 各ユーザーとそのグループの割り当てをリストする
  • フォルダーの内容に関する権限とユーザー/グループの詳細を取得します:ls -la

ただし、ユーザーの目的がわからない場合は、書き込み許可を持っているすべてのディレクトリのリストを取得して、そこから見て回るといいでしょう。他に何もなければ、それは非常に有用な監査です。

私の目的を理解するのに役立つ場合、私たちのシステム管理者が新しい地位に就いた後、私はいくつかのシステムを継承しました(または少なくともベビーシッターですか?)。だから、私はこれらの2つのシステムの進化を理解しようとしました。たとえば、どのソフトウェアがインストールされ、どこ(..ugh)、さまざまな構成ファイルがどこにあるのか、そして今、さまざまなグループとユーザーがどのように作成されたのか、書き込みが許可されているディレクトリ。通常、私はaskubuntuでこのような便利な端末コマンドを見つけることができますが、これを見つけられないので、先に進んで尋ねると思いました。

正確なシステムはUbuntu 10.04.2ですが、Ubuntu 12.04.5もサポートしているため、最もバージョンに依存しないソリューションが最適です。助けてくれてありがとう。


[更新:2つのクイックアンサーの初期結果]

これらのルートとしてログインしていることに注意してください。/は私の作業ディレクトリでした。また、それらは実行するのに同等の時間を要しました。

@Rinzwindの結合コマンドは、約5.5分で次の出力を取得しました。

root@tatooine:/# Sudo find -type d \( \( -user ftpgisdata -perm /u=w \) -o \( -group ftpgisdata -perm /g=w \) -o -perm /o=w \)
./tmp
./tmp/.ICE-unix
./tmp/.X11-unix
find: `./proc/6594/task/6594/fd/5': No such file or directory
find: `./proc/6594/task/6594/fdinfo/5': No such file or directory
find: `./proc/6594/fd/5': No such file or directory
find: `./proc/6594/fdinfo/5': No such file or directory
./var/tmp
./var/lib/php5
./var/crash
./var/lock
./home/ftpgisdata
./home/ftpgisdata/.ssh
./home/ftpgisdata/.cache
./home/sitename-i-changed.com/wp-content/profile-pics
./dev/shm

@Oliの改訂されたコマンドは、約5.5分で非常によく似たものになります。

root@tatooine:/# Sudo find / -type d -print0 | Sudo -u ftpgisdata xargs -0 sh -c 'for p; do [ -w "$p" ] && echo "$p"; done' -
/tmp
/tmp/.ICE-unix
/tmp/.X11-unix
find: `/proc/15541': No such file or directory
find: `/proc/15542': No such file or directory
find: `/proc/15543': No such file or directory
find: `/proc/15567': No such file or directory
find: `/proc/15568/task/15568/fd/5': No such file or directory
find: `/proc/15568/task/15568/fdinfo/5': No such file or directory
find: `/proc/15568/fd/5': No such file or directory
find: `/proc/15568/fdinfo/5': No such file or directory
/var/tmp
/var/lib/php5
/var/crash
/var/lock
/home/ftpgisdata
/home/ftpgisdata/.ssh
/home/ftpgisdata/.cache
/home/sitename-i-changed.com/wp-content/profile-pics
/dev/shm

@PeterCordesの回答も、約5.5分で同様の結果を返しました。

root@tatooine:~# username_to_check=ftpgisdata base_dir=/   # for example
root@tatooine:~# Sudo -u "$username_to_check" find "$base_dir" -type d -writable  2>/dev/null ## GNU find, not POSIX
/tmp
/tmp/.ICE-unix
/tmp/.X11-unix
/proc/7159/task/7159/fd
/proc/7159/fd
/proc/7159/map_files
/var/tmp
/var/lib/php5
/var/crash
/var/lock
/home/ftpgisdata
/home/ftpgisdata/.ssh
/home/ftpgisdata/.cache
/home/sitename-i-changed.com/wp-content/profile-pics
/dev/shm
7
elrobis

あなたがそのユーザーでない場合、ユーザーができることを解決するのは難しいです。さまざまなもの(所有者、同じグループなど)をテストできますが、ACLが適用される可能性があり、マウントに権限がない可能性があります。それは難しい。

turn intoそのユーザーができる場合は、test -w <path>を使用して、書き込みが可能かどうかを確認できます。これは、inodeを見るだけでは速くありませんが、Sudoで可能です。

Sudo -u oli test -w <path> && echo "HOORAY"

次に、それをfindのバックエンドに絞り込みます。 -execを使用してoliユーザーに何度も何度も変更するのではなく(過去のリビジョンを参照)、oliとして実行されているxargsインスタンスにすべてをパイプします。これははるかに高速です。

Sudo find / -type d -print0 | Sudo -u oli xargs -0 -I{} sh -c 'test -w "$0" && echo "$0"' {}

多少最適化された(ただし視覚的にはゆるい)バージョンでは、パスのストリームを少数のbashサブシェルにパイプすることにより、xargsが実行するサブシェルの量を最小限に抑えます。これは、大きな検索では間違いなく高速です。

Sudo find / -type d -print0 | Sudo -u oli xargs -0 sh -c 'for p; do [ -w "$p" ] && echo "$p"; done' -
7
Oli

チャットで、ユーザーとグループに関する次の指示に行きました。

Sudo find / -type d -user rinzwind -perm /u=w
Sudo find / -type d -group rinzwind -perm /g=w
Sudo find / -type d -perm /o=w

または、3つすべてを1つに結合します。

Sudo find -type d \( \( -user rinzwind -perm /u=w \) -o \( -group rinzwind -perm /g=w \) -o -perm /o=w \)

/がなければ、現在のディレクトリを検索します。

私のシステムの67Gbのデータで2秒未満かかりました;)

4
Rinzwind

回答中、しばらくお待ちください

自分自身のテスト

次のコードを使用して、自分の書き込み権限をテストできます。

[ -w /home/$USER ] && echo yes # using home directory as example

Testに-dフラグを使用すると、何かがディレクトリかどうかをテストできます。

すべてを知っていて、findできること

find /home/ -print0 2> /dev/null | while IFS=""  read -r -d "" file ; do [ -d "$file"  ] &&  [ -w "$file" ]  && echo "$file" is writeable ; done

サイドノート:明らかに、findで許可エラーが発生した場合、そのファイルを読み取ることができないため、これらのエラーを出力する理由がないため、dev nullにリダイレクトされます。自分以外のユーザーのアクセス許可を確認する場合、これは明らかに機能しません。/homeはここの例にすぎません。 /varなどのフォルダーには、複数のユーザー間で共有されるフォルダーがあります

他の人のためのテスト

statが検出した各ファイルごとにfindを使用し、awkでそれをフィルタリングすることができます。

 find /var -type d -exec stat --format '%g %n'  {} \; 2> /dev/null | awk '$1=='1000'{print}' 

ここでは、自分のユーザー1000の数値IDをフィルタリングしていますが、どのユーザーのIDでもかまいません。もちろん、オプションを使用して、数値IDの代わりにグループ名を使用できます。それはあなたが必要とする目的に非常に柔軟で適応可能なものです

微調整

そのため、ルートとしてログインしていることに言及していることに気付きました。コマンドの出力は次のとおりです。ファイルを統計し、グループとファイル名を出力し、適切なグループ名でAWKを使用して除外します。

$ find /proc -type d -exec stat --format '%G %n'  {} \; 2> /dev/null  | awk '$1=="syslog"{print}'
syslog /proc/560
syslog /proc/560/task
syslog /proc/560/task/560
syslog /proc/560/task/560/net
syslog /proc/560/task/560/attr
syslog /proc/560/task/562
syslog /proc/560/task/562/net
syslog /proc/560/task/562/attr
syslog /proc/560/task/563
syslog /proc/560/task/563/net
syslog /proc/560/task/563/attr
syslog /proc/560/task/564
syslog /proc/560/task/564/net
syslog /proc/560/task/564/attr
syslog /proc/560/net
syslog /proc/560/attr
^C
2

GNUが見つかった場合、-writableテストを使用できます(スペルに注意してください。writeableではありません)。これは、アクセス許可を調べるだけではなくaccess(2)システムコールを使用するため、ACLで正しく動作します。 (ただし、NFSではIDマッピングを使用すると破損する場合があります)。

また、セカンダリグループのメンバーであるため、ユーザーが書き込み可能なディレクトリも検索します。 (例:adminグループのユーザーが書き込み可能な/usr/localのディレクトリ、またはchown root:users /data/share && chmod 2775 /data/shareのようなもの。一部のアカウントはusersグループのメンバーです。)

username_to_check=peter base_dir=/   # for example
Sudo -u "$username_to_check" find "$base_dir" -type d -writable  2>/dev/null ## GNU find, not POSIX

findがユーザーが降りることのできないディレクトリに遭遇するとエラーが発生するため、エラーを/dev/nullにリダイレクトします。

これはnot書き込み可能なディレクトリを検出しますが、ユーザーとして実行されるfindは上位のディレクトリを横断できないため、実行許可のないディレクトリ内にあります。ただし、所有するプロセスがそのようなディレクトリ内で開始された場合、それらは相対パスを使用してそれに書き込むことができます。 (または、そのようなディレクトリへの開いているファイル記述子を取得し、openat(2)を使用できます)。 pwdは、フルパスのディレクトリコンポーネントの1つに対するexec権限がない場合は機能しないため、一般的な設定ではありません。

これは、実行可能ファイル内にあるが読み取り可能なディレクトリではない書き込み可能なディレクトリも見逃します。これらの制限を回避するには、おそらくfind -type dをルートとして実行し、ユーザーとしてfind -writableを使用して、結果のパスを確認します。 [ -w "$f" ]を使用したシェルループよりも効率的です。

POSIX find(1) には、GNU findよりもはるかに少ないオプションがあります。スクリプトをPOSIXに移植可能にする必要がある場合は、[ -w "$f" ]を持つシェルのように、アクセス許可をチェックする他の何かにパイプするのがおそらく最も簡単です(これを示唆する他の回答を参照してください)。

2
Peter Cordes