web-dev-qa-db-ja.com

最小限のプロセス作成でユーザーが効率的に書き込むことができるファイルを見つける

私は根です。非rootユーザーがいくつかのファイル(数千)への書き込みアクセス権を持っているかどうかを知りたいです。プロセスの作成を回避しながら効率的に行うにはどうすればよいですか?

20
Howard

おそらくこのように:

_#! /bin/bash

writable()
{
    local uid="$1"
    local gids="$2"
    local ids
    local perms

    ids=($( stat -L -c '%u %g %a' -- "$3" ))
    perms="0${ids[2]}"

    if [[ ${ids[0]} -eq $uid ]]; then
        return $(( ( perms & 0200 ) == 0 ))
    Elif [[ $gids =~ (^|[[:space:]])"${ids[1]}"($|[[:space:]]) ]]; then
        return $(( ( perms & 020 ) == 0 ))
    else
        return $(( ( perms & 2 ) == 0 ))
    fi
}

user=foo
uid="$( id -u "$user" )"
gids="$( id -G "$user" )"

while IFS= read -r f; do
    writable "$uid" "$gids" "$f" && printf '%s writable\n' "$f"
done
_

上記はファイルごとに単一の外部プログラム、つまりstat(1)を実行します。

注:これはbash(1)、およびLinuxのstat(1)の実装を前提としています。

注2:このアプローチの過去、現在、将来、および潜在的な危険と制限については、以下のステファンシャゼラスからのコメントをお読みください。

2
lcd047

オプションをfindコマンドと組み合わせて、指定したモードと所有者のファイルを見つけることができます。例えば:

$ find / \( -group staff -o -group users \) -and -perm -g+w

上記のコマンドは、「staff」または「users」グループに属し、そのグループへの書き込み権限を持つすべてのエントリをリストします。

また、自分のユーザーが所有しているエントリと、誰でも書き込み可能なファイルを確認する必要があります。

$ find / \( -user yourusername -or \
             \(  \( -group staff -o -group users \) -and -perm -g+w \
             \) -or \
            -perm -o+w \
         \)

ただし、このコマンドは拡張ACLのあるエントリとは一致しません。したがって、suを実行すると、書き込み可能なすべてのエントリを見つけることができます。

# su - yourusername
$ find / -writable
2
apaul

アプローチは、実際にテストしているものに依存します。

  1. 確認書き込みアクセスが可能ですか?
  2. ensure書き込みアクセスの欠如をしたいですか?

これは、2)に到達する方法が非常に多いためであり、Stéphaneの答えはこれらをうまくカバーしており(不変は覚えておくべきものです)、ドライブをアンマウントしたり、読み取り専用にするなどの物理的な手段もあることを思い出してください。ハードウェアレベル(フロッピータブ)。何千ものファイルが異なるディレクトリにあり、レポートが必要か、マスターリストをチェックしていると思います。 (別の人形の乱用が起こるのを待っているだけです)。

StéphaneのPerlツリートラバーサルを必要とし、必要に応じて出力をリストに「結合」します(suは、親ディレクトリで欠落している実行もキャッチしますか?)。代理出産がパフォーマンスの問題である場合、「多数」のユーザーに対してこれを行っていますか?それともオンラインクエリですか?これが永続的な継続的な要件である場合は、サードパーティ製品を検討するときかもしれません。

1
mckenzm

できるよ...

_find / ! -type d -exec tee -a {} + </dev/null
_

...ユーザーがで書き込めないすべてのファイルのリストについては、次の形式でstderrに書き込まれたように...

_"tee: cannot access %s\n", <pathname>" 
_

...または類似。

このアプローチで発生する可能性のある問題に関する注記については、以下のコメントを参照してください。また、この方法が機能する理由については、以下の説明を参照してください。しかし、より正気に、おそらくonlyfind 次のような通常のファイルを使用する必要があります。

_find / -type f -exec tee -a {} + </dev/null
_

つまり、teeは、2つのフラグのいずれかを持つファイル open() を試行するとエラーを出力します...

O_WRONLY

書き込み専用です。

O_RDWR

読み取りおよび書き込み用に開きます。このフラグがFIFOに適用される場合、結果は不定です。

...そして出会い...

[EACCES]

パスプレフィックスのコンポーネントで検索権限が拒否されている、またはファイルが存在し、oflagで指定された権限が拒否されている、またはファイルが存在せず、作成するファイルの親ディレクトリに対する書き込み権限が拒否されている、またはO_TRUNCが指定され、書き込み権限が拒否されました。

...指定どおり ここ

teeユーティリティは、標準入力を標準出力にコピーし、0個以上のファイルにコピーを作成します。 teeユーティリティは出力をバッファリングしません。

_-a_オプションが指定されていない場合、出力ファイルが書き込まれます( ファイルの読み取り、書き込み、および作成 を参照)...

... POSIX.1-2008には、O_APPEND...を使用することと同等の機能が必要です。

同じ方法でチェックする必要があるため _test -w_ は...

_-w_パス名

pathnameFile Read、Write、and Creationで定義されているように、ファイルへの書き込み権限が付与されるファイルの既存のディレクトリエントリに解決される場合はtruepathnameを解決できない場合、またはpathnameが、ファイルへの書き込み権限があるファイルの既存のディレクトリエントリを解決する場合はfalseファイルは許可されません。

どちらも[〜#〜] eaccess [〜#〜]をチェックします。

0
mikeserv