掲示板システム
ホーム
アクセス解析
カテゴリ
ログアウト
フォルダアクセス権取得について (ID:36022)
名前
ホームページ(ブログ、Twitterなど)のURL (省略可)
本文
フォルダのアクセス権について(2006/06/02) https://www.petitmonte.com/bbs/answers?question_id=4002 これの続きです( もう3年も前の話で、とても古いけど) ママんさんのコードがだめだったのは、参照したいフォルダに新たに設定された アクセス許可エントリしか取得できず、上位フォルダから継承されたもアクセス 許可エントリが取得できなかったため。 GetNamedSecurityInfo の引数を変えてやれば取得できたかもしれませんが、 今回Vista の UAC対策に、もうちょっと突っ込んでやってみました。 ※ 今回、特に参考にした資料 フォルダのアクセス権チェック方法について http://social.msdn.microsoft.com/forums/ja-JP/vcgeneralja/thread/a4225c57-ebc3-4808-8464-dc731548ab99/ アクセスコントロール / アクセスチェック http://eternalwindows.jp/security/accesscontrol/accesscontrol04.html 主な宣言 var hToken, hTokenImpersonatation:THandle; dwTokenUserLength: DWORD; pTokenUser: ^TSIDAndAttributes; pSecurityDescriptor: PSECURITY_DESCRIPTOR; pDACL: PACL; 細かいとこはSDKとか読んでください。 また、NT系のみ、2000以降のみとかAPIも使っているかもしれませんが、 それもSDKとかで確認してください。 1) GetVolumeInformationを使って NTFS か判定する。 これは、上記の質問内にコードが含まれています。 2) GetNamedSecurityInfo を使用して、セキュリティ記述子を取得する if GetNamedSecurityInfo(PChar("調査フォルダ"), SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION or GROUP_SECURITY_INFORMATION or DACL_SECURITY_INFORMATION, // 取得するセキュリティ情報のタイプ nil, nil, @pDACL, nil, pSecurityDescriptor) = 0 then //成功 3) 自プロセスのトークンを取得する NT, 2000, XP とかなら、フォルダのアクセス権がそのまま、自分のアクセス権に なりますが、VistaのUACの存在が、ユーザー権限で動作を行うため、アカウントの アクセス権では判定できないのです(たぶん)。 OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY or TOKEN_DUPLICATE, htoken) 4) トークン情報を取得する 「AccessCheckに指定するトークンは偽装トークンでなければならないため」 (By 参考資料に二つ目のリンクより一部抜粋) ということで、トークンを取得して、偽装トークンに複製する必要があります。 そのための準備 //1回目で情報のサイズを取得し GetTokenInformation(hToken, TokenUser, nil, 0, dwTokenUserLength); //メモリ確保 pTokenUser := GetMemory(dwTokenUserLength) //ここで本当にトークン情報を取得する GetTokenInformation(hToken, TokenUser, pTokenUser, dwTokenUserLength, dwTokenUserLength); 5) 偽装トークンに複製 DuplicateTokenEx(hToken, GENERIC_ALL, nil, SecurityImpersonation, TokenImpersonation, hTokenImpersonatation) 6) アクセス許可の判定 {アクセス権の調査} var genericMapping: TGenericMapping; dwDesiredAccess: Cardinal; dwSize: Cardinal; privilegeSet: TPrivilegeSet; dwGrantedAccess: DWORD; accessStatus: LongBool; begin {初期化} FillChar(genericMapping, SizeOf(TGenericMapping), 0); //この FILE_GENERIC_READ, FILE_GENERIC_WRITE 定数については //Delphiのユニットには含まれていない可能性が高いので //Googleさんなどで検索してくださいな //読み込み可能であるか調べる場合 //dwDesiredAccess := FILE_GENERIC_READ; //書き込み可能であるか調べる場合 dwDesiredAccess := FILE_GENERIC_WRITE; {調査するアクセス権のマッピングを用意} genericMapping.GenericRead := FILE_GENERIC_READ; genericMapping.GenericWrite := FILE_GENERIC_WRITE; genericMapping.GenericExecute := FILE_GENERIC_EXECUTE; genericMapping.GenericAll := FILE_ALL_ACCESS; {アクセスマスク内の汎用のアクセス権を、特定の標準的なアクセス権にマップする} MapGenericMask(dwDesiredAccess, genericMapping); {初期化} dwSize := SizeOf(PRIVILEGE_SET); privilegeSet.PrivilegeCount := 0; {アクセス トークンによって識別されたクライアントに対して、 指定されたアクセス権利セットを、セキュリティ記述子が許可しているか どうかを調べます。通常、サーバーアプリケーションはこの関数を使って、 プライベートオブジェクトへのアクセスを確認します。} if AccessCheck(pSecurityDescriptor, hTokenImpersonatation, dwDesiredAccess, genericMapping, privilegeSet, dwSize, dwGrantedAccess, accessStatus) then begin if accessStatus then //アクセス許可されています else //アクセス許可されていません end else begin //アクセス権の取得に失敗 end; end; 以上で、Vista,Sevenでも、UACが有効で、ユーザー権限で動作中のアクセス権と、 admin権限での動作のアクセス権が判定できると思います。 一応、XP SP2、Vista UAC オンの通常起動、Vista UAC オンのadmin権限起動で フォントフォルダのアクセス権の判定がうまくいっています。 ソースを完全掲載じゃないので、足りないトコは自分で調べてください m(v_v)m
←解決時は質問者本人がここをチェックしてください。
更新する
戻る
掲示板システム
Copyright 2021 Takeshi Okamoto All Rights Reserved.