8

ユーザーがディレクトリへの読み取りアクセス権または読み取り/書き込みアクセス権を持っているかどうかを判断するために、 両方stat()と個別に使用することに成功しました。access()

私の質問は:-好ましい方法はありますか?を使用した例はたくさんありますstatが、私の目的では、アクセスはより軽量で目的を果たしているようです。
-どちらか一方の問題(例:セキュリティ)はありますか?-私のアプローチに関する問題はありますか?

ここにいくつかの擬似コードがあります(コンパイルせずにメモリから再作成します):

       // Using access():
    bool readAccessPermission = false; 
    bool writeAccessPermission = false;

    if (mode == 'r'){
            if (access(directory, R_OK) == 0)
                    readAccessPermission = true;                        
    }
    else{
            if (access(directory, R_OK && W_OK) == 0)
                    readAccessPermission = true;
                    writeAccessPermission = true;
    }


    // vs. using stat function
    // assume I already called stat(directory) and have the object


    bool readAccessPermission = false; 
    bool writeAccessPermission = false;

    var retmode = ((stats.mode) & (0777));

    if (modeString == 'r'){ 
        if ((retmode) & (consts.S_IRUSR)){
            readAccessPermission = false; 
        }    
    } 
    else{ 
        if ((retmode) & (consts.S_IRUSR)){
            readAccessPermission = true; 

            if ((retmode) & consts.S_IWUSR)){               
                writeAccessPermission = true; 
            }
        }
    }
4

3 に答える 3

9

どちらもあなたのニーズに相当します。access()入力した統計構造で何もしない場合は、よりクリーンなラッパーです。

これを行うときは、レースを作成していることに注意してください。権限は、呼び出しstat()/access()と実際にディレクトリを使用しようとするときとの間で変わる可能性があります。地獄、その時にディレクトリを削除して再作成することさえできました。

必要なものを開いて確認することをお勧めしますEPERM。チェックするstat()access()、後続の操作でEPERMが返されないことを保証しません。

于 2011-08-17T05:04:21.083 に答える
4

単純なケースでは、両方とも機能的に同等です。また、access()同じデータ構造(iノード)が多くフェッチされるため、それほど高速ではありません。

ただし、システムでアクセス制御リスト(ACL)が使用されている場合、データを使用してACLを確認する方法がない間、アクセスはこれらを処理しstatます。

于 2011-08-17T09:13:20.003 に答える
1

これらの2つのコードスニペットは同一ではなく、実質的に異なる結果を生成します。

まず、統計呼び出しは所有者の許可ビットのみをチェックします。このコードを実行しているユーザーが問題のファイルを所有していない場合、これはチェックする適切なビットのセットではありません。

次に、呼び出し元のユーザーが所有者であると想定した場合でも、「呼び出し側のユーザー」が何を意味するのかを理解する必要があります。とその友人に関する限りopen(2)、呼び出し元のユーザーは、によって返される番号geteuid(2)、つまり有効なユーザーIDです。これは、openがファイルのオープンを許可するかどうかを決定するために使用するものです。呼び出しaccess(2)元のユーザーは、によって返される番号getuid(2)、つまり実際のユーザーIDです。これは、アクセスが成功を報告するかどうかを決定するために使用するものです。実際のUIDと有効なUIDは異なる場合があります。特に、setuidビットを有効にしてバイナリを実行する場合、またはプログラマーが特に賢いことをしている場合(そしておそらく不適切なIMHO)です。

(一方、stat()呼び出し元のユーザーは、そのジョブを実行するために含まれているディレクトリに対する実行権限が必要な場合を除いて、どちらの方法でも気にしません。そのために、EUIDをチェックします)。

最後に、複数の回答で指摘されているように、結果をどのように処理するかによっては、両方のコードスニペットがTOCTTOUバグに対して脆弱である可能性があります。全体として、アクションが許可されているかどうかを判断する最も安全な方法は、そのアクションを試行し、失敗したかどうかを確認することです。

于 2016-11-11T00:31:36.300 に答える