0

厄介な問題があり、それがどこから来たのか本質的にわかりません:(したがって、件名は次のとおりです:ローカルホスト(実際のファイルシステムから)からフォルダのパーミッションをチェックしようとすると、それ(以下に添付されたコード)は正常に機能しますが、アプリケーションがネットワーク(例:\ * machinename *)はそうではありません。アクセス許可を要求すると、常にネットワーク経由で承認を取得しますが、たとえば、十分なアクセス許可がないため、ファイルを作成できません。

iccFile_Security =
    class
        const
            FILE_READ_DATA        = $0001;
            FILE_WRITE_DATA       = $0002;
            FILE_APPEND_DATA      = $0004;
            FILE_READ_EA          = $0008;
            FILE_WRITE_EA         = $0010;
            FILE_EXECUTE          = $0020;
            FILE_READ_ATTRIBUTES  = $0080;
            FILE_WRITE_ATTRIBUTES = $0100;
            FILE_GENERIC_READ     = (    STANDARD_RIGHTS_READ
                                      or FILE_READ_DATA
                                      or FILE_READ_ATTRIBUTES
                                      or FILE_READ_EA
                                      or SYNCHRONIZE
                                    );
            FILE_GENERIC_WRITE    = (    STANDARD_RIGHTS_WRITE
                                      or FILE_WRITE_DATA
                                      or FILE_WRITE_ATTRIBUTES
                                      or FILE_WRITE_EA
                                      or FILE_APPEND_DATA
                                      or SYNCHRONIZE
                                    );
            FILE_GENERIC_EXECUTE  = (    STANDARD_RIGHTS_EXECUTE
                                      or FILE_READ_ATTRIBUTES
                                      or FILE_EXECUTE
                                      or SYNCHRONIZE
                                    );
            FILE_ALL_ACCESS       = (    STANDARD_RIGHTS_REQUIRED
                                      or SYNCHRONIZE
                                      or $1FF
                                    );
        strict private
        public
            class function check( _filename : String; _desiredAccess : DWORD                       ) : Boolean; overload;
            class function check( _filename : String; _desiredAccess : DWORD; out _failed : Boolean) : Boolean; overload;
    end;

implementation

{ iccFile_Security }

class function iccFile_Security.check( _filename: String; _desiredAccess: DWORD) :    Boolean;
var _failed : Boolean;
begin
    result := check( _filename, _desiredAccess, _failed) and not _failed;
end;

class function iccFile_Security.check( _filename : String; _desiredAccess : DWORD; out _failed : Boolean) : Boolean;
var Token       : DWORD;
    Status      : LongBool;
    Access      : DWORD;
    SecDescSize : DWORD;
    PrivSetSize : DWORD;
    PrivSet     : PRIVILEGE_SET;
    Mapping     : GENERIC_MAPPING;
    SecDesc     : PSECURITY_DESCRIPTOR;
begin
    Result := False;

    SecDesc     := nil;
    SecDescSize := 0;

    try
       GetFileSecurity( pchar( _filename),
                            OWNER_SECURITY_INFORMATION
                         or GROUP_SECURITY_INFORMATION
                         or DACL_SECURITY_INFORMATION,
                         nil,
                         0,
                         SecDescSize
                       );

        SecDesc := GetMemory( SecDescSize);

        if not GetFileSecurity( pchar( _filename),
                                   OWNER_SECURITY_INFORMATION
                                or GROUP_SECURITY_INFORMATION
                                or DACL_SECURITY_INFORMATION,
                                SecDesc,
                                SecDescSize,
                                SecDescSize
                              )
            then begin
                     _failed := true;
                     exit;
                 end;


        ImpersonateSelf( SecurityImpersonation);
        OpenThreadToken( GetCurrentThread, TOKEN_QUERY, False, Token);

        if Token = 0
            then begin
                     _failed := true;
                     exit;
                 end;

        Mapping.GenericRead    := FILE_GENERIC_READ;
        Mapping.GenericWrite   := FILE_GENERIC_WRITE;
        Mapping.GenericExecute := FILE_GENERIC_EXECUTE;
        Mapping.GenericAll     := FILE_ALL_ACCESS;

        MapGenericMask( Access, Mapping);
        PrivSetSize := SizeOf( PrivSet);
        AccessCheck( SecDesc, Token, _desiredAccess, Mapping, PrivSet, PrivSetSize,         Access, Status);
        CloseHandle( Token);

        if _desiredAccess = Access
            then result := Status;
    finally
        FreeMem( SecDesc, SecDescSize);
    end;
end;

正しく機能します:

if not iccFile_Security.check( 'C:\temp\',     iccFile_Security.FILE_ALL_ACCESS)
        then ...

動作しません:

if not iccFile_Security.check( '\\testmachine\temp\',         iccFile_Security.FILE_ALL_ACCESS)
        then ...

コメント\提案はありますか?どんな助けでも大歓迎です。

4

1 に答える 1

4

ああ。私は前にこれに答えました-ネットワークファイルのセキュリティは信頼できないがらくたです。(ディレクトリにファイルを書き込めるかどうかを確認するために、すべてのコードをダンプしました。)

Cf、http: //www.ureader.com/msg/16591730.aspx

AccessCheck()に関する説明を読んでください。具体的には:

AccessCheck()を実行する場合でも、オブジェクトに関連付けられたセキュリティ記述子を使用して、「ローカル」で生成されたアクセストークンに対してアクセスチェックを実行しています。リモートシステム上のオブジェクトに直接アクセスすると、ネットワークアクセストークンがリモートシステム上に生成されます。このネットワークアクセストークンは、オブジェクトに対してアクセスチェックを実行して、アクセスを許可するか拒否するかを決定するために使用されます。オブジェクトは、ファイル、名前付きパイプ、またはADオブジェクトのいずれかです。

たとえば、ユーザーがリモートシステムのAdministratorsグループのメンバーである場合、リモートシステムのオブジェクトに直接アクセスすると、リモートシステムで生成されるネットワークアクセストークンにAdministratorsグループが含まれ、アクセスが許可されます。一方、ローカルアクセストークンを使用してAccessCheck()を呼び出すと、異なる結果が得られます。

于 2012-06-22T15:47:38.450 に答える