1

Windows APIを正しく使用してファイルのアクセス許可を決定する方法について、私は本当に頭を悩ませています。これについて非常に多くの投稿を見てきましたが、正しく理解できないようです。具体的には、ユーザーが特定のファイルに対して読み取りまたは書き込みのアクセス許可を持っているかどうかを調べたいと思います。これらは私のステップです:

(1) GetUserNameEx を使用して、呼び出し元クライアントの完全修飾ユーザー名 (ドメイン名を含む) にアクセスします。(0 エラーを返します。ユーザー名は、cout デバッグ メッセージを使用して正しく出力されているように見えます)。

(2) LookupAccountName を使用してユーザーの SID にアクセスします。(これを 2 回行います。最初は SID とドメインのバッファー サイズを設定するためです。最初の呼び出しでは 122 エラーが返され、2 回目の呼び出しでは 0 エラーが返されます (予想される))。SID バッファが正しく設定されていると仮定します。

(3) 取得した sid でトラスティを構築します。

        TRUSTEE t;
        PTRUSTEE tptr = &t;
        BuildTrusteeWithSid(tptr,&sid[0]);

(4) DACL を取得します。

 // following are freed up later using LocalFree (maybe I should use delete?)
 PACL ppDacl = new ACL;
 PSECURITY_DESCRIPTOR ppSecurityDescriptor = new SECURITY_DESCRIPTOR;
 std::vector<TCHAR> v(pathString.begin(), pathString.end());
 GetNamedSecurityInfo(&v[0],
                      SE_FILE_OBJECT,
                      READ_CONTROL,
                      NULL,
                      NULL,
                      &ppDacl,
                      NULL,
                      &ppSecurityDescriptor);

簡単な呼び出し

 std::cout<<"ACE count: "<<ppDacl->AceCount<<std::endl;

次に、DACL構造体が正しくインスタンス化されていると仮定するように導く58個のACEがあることを示します(これを手動で確認する方法がわかりませんが、58個のACEがあるとさらに仮定しています;私は本当にWindowsの人ではありません) . ただし、GetNamedSecurityInfo 呼び出しの後に GetLastError() を出力すると 122 (つまり、ERROR_INSUFFICIENT_BUFFER) が返されるため、このステップで何か問題が発生しているように見えます。

次のように PACL と PSECURITY_DESCRIPTOR を初期化することに注意してください。

 ACL dacl;
 PACL ppDacl = &dacl;
 SECURITY_DESCRIPTOR sd;
 PSECURITY_DESCRIPTO = &sd;

それらを新しくするのではなく、DACLを正しく埋めていないようです(少なくとも呼び出し

  std::cout<<"ACE count: "<<ppDacl->AceCount<<std::endl;

58 ではなく 0 を報告します)。理由はわかりません。

(5) 最後に、作成されたトラスティと dacl を指定して、ファイルのアクセス マスクを取得しようとします。

 ACCESS_MASK access;
 GetEffectiveRightsFromAcl(ppDacl, tptr, &access);

私が行うとき、これはアクセス権がないことを示します:

 ((access & GENERIC_WRITE)==GENERIC_WRITE)

また

 ((access & GENERIC_READ)==GENERIC_READ)

あなたの一人がこれについていくつかの光を当てることができることを願っています

乾杯、

ベン。

4

1 に答える 1

2

toの呼び出しは、3番目のパラメーターとして渡されるフラグのセットに設定されてGetNamedSecurityInfo()いる必要があります。DACL_SECURITY_INFORMATIONその場合にのみ、6番目のパラメーターで返された値によって参照されているデータは、呼び出しが返された後に有効になります。

GetNamedSecurityInfo()MSDNのドキュメントからの逐語的:

ppDacl [出力、オプション]

...返されたポインタは、DACL_SECURITY_INFORMATIONフラグを設定した場合にのみ有効です。


補足として:初期化する必要はありませんppDaclppSecurityDescriptorこれは。によって行われGetNamedSecurityInfo()ます。GetNamedSecurityInfo()それらに動的にメモリを割り当てると、割り当てたものへの参照が失われるため、呼び出しによってメモリリークが発生します。

于 2012-11-12T11:02:18.297 に答える