DACLやSACLの情報を表示します。
#include <stdio.h>
#include <tchar.h>
#include <iostream>
#include <string>
#include <windows.h>
#include <aclapi.h>
#include <sddl.h>
#include <Iads.h>
#include <WinBase.h>
// lib
#pragma comment( lib, "advapi32.lib" )
#pragma comment( lib, "Rpcrt4.lib" )
/*
ACE情報の表示
*/
void DispAceInfo
(
PACE_HEADER pAceHeader
)
{
// 処理結果
BOOL bRet= FALSE;
// ACEのタイプを取得
BYTE bAceType = pAceHeader->AceType;
printf( "¥tAceSize = %d¥n", pAceHeader->AceSize );
printf( "¥tAceType = %d¥n", bAceType );
printf( "¥tAceFlag = %d¥n", pAceHeader->AceFlags );
// AccessMaskMaping
const static struct {
// アクセスマスク
ACCESS_MASK dwAccessMask;
// 名称
TCHAR* wpName;
} taAccessMaskMaping[]= {
{ DELETE , L"DELETE" }
, { READ_CONTROL , L"READ_CONTROL" }
, { WRITE_DAC , L"WRITE_DAC" }
, { WRITE_OWNER , L"WRITE_OWNER" }
, { SYNCHRONIZE , L"SYNCHRONIZE" }
, { ACCESS_SYSTEM_SECURITY , L"ACCESS_SYSTEM_SECURITY" }
, { MAXIMUM_ALLOWED , L"MAXIMUM_ALLOWED" }
, { GENERIC_ALL , L"GENERIC_ALL" }
, { GENERIC_EXECUTE , L"GENERIC_EXECUTE" }
, { GENERIC_WRITE , L"GENERIC_WRITE" }
, { GENERIC_READ , L"GENERIC_READ" }
};
// SysMandatoryMapping
const static struct {
// アクセスマスク
ACCESS_MASK dwAccessMask;
// 名称
TCHAR* wpName;
} taSysMandatoryMapping[]= {
{ SYSTEM_MANDATORY_LABEL_NO_WRITE_UP , L"SYSTEM_MANDATORY_LABEL_NO_WRITE_UP" }
, { SYSTEM_MANDATORY_LABEL_NO_READ_UP , L"SYSTEM_MANDATORY_LABEL_NO_READ_UP" }
, { SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP, L"SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP" }
};
// AdsRightMapping
const static struct {
// アクセスマスク
ACCESS_MASK dwAccessMask;
// 名称
TCHAR* wpName;
} taAdsRightMapping[]= {
{ ADS_RIGHT_DS_CREATE_CHILD , L"ADS_RIGHT_DS_CREATE_CHILD" }
, { ADS_RIGHT_DS_DELETE_CHILD , L"ADS_RIGHT_DS_DELETE_CHILD" }
, { ADS_RIGHT_ACTRL_DS_LIST , L"ADS_RIGHT_ACTRL_DS_LIST" }
, { ADS_RIGHT_DS_SELF , L"ADS_RIGHT_DS_SELF" }
, { ADS_RIGHT_DS_READ_PROP , L"ADS_RIGHT_DS_READ_PROP" }
, { ADS_RIGHT_DS_WRITE_PROP , L"ADS_RIGHT_DS_WRITE_PROP" }
, { ADS_RIGHT_DS_LIST_OBJECT , L"ADS_RIGHT_DS_LIST_OBJECT" }
, { ADS_RIGHT_DS_CONTROL_ACCESS , L"ADS_RIGHT_DS_CONTROL_ACCESS" }
};
// ObjectTypeMapping
const TCHAR* taObjectTypeMapping[]= {
L"",
L"ACE_OBJECT_TYPE_PRESENT",
L"ACE_INHERITED_OBJECT_TYPE_PRESENT",
L"ACE_OBJECT_TYPE_PRESENT | ACE_INHERITED_OBJECT_TYPE_PRESENT",
};
switch ( bAceType ) {
case ACCESS_ALLOWED_ACE_TYPE:
case ACCESS_ALLOWED_CALLBACK_ACE_TYPE:
case ACCESS_DENIED_ACE_TYPE:
case ACCESS_DENIED_CALLBACK_ACE_TYPE:
case SYSTEM_ALARM_ACE_TYPE:
case SYSTEM_ALARM_CALLBACK_ACE_TYPE:
case SYSTEM_AUDIT_ACE_TYPE:
case SYSTEM_AUDIT_CALLBACK_ACE_TYPE:
case SYSTEM_MANDATORY_LABEL_ACE_TYPE:
{
ACCESS_ALLOWED_ACE* pAccessAllowedAce = (ACCESS_ALLOWED_ACE*)pAceHeader;
// アクセスマスクの取得
ACCESS_MASK dwMask = pAccessAllowedAce->Mask;
printf( "¥tAccessMask = 0x%08x¥n", dwMask );
/*
AccessMaskMapingの表示
*/
for ( UINT nI = 0; nI < _countof( taAccessMaskMaping ); nI++ ) {
// マスクの取得
DWORD dwMaskTmp = taAccessMaskMaping[ nI ].dwAccessMask;
if ( 0 != ( dwMask & dwMaskTmp ) ) {
printf( "¥t ->0x%08x : %ls¥n", dwMaskTmp, taAccessMaskMaping[ nI ].wpName );
dwMask &= ~dwMaskTmp;
}
}
/*
SysMandatoryMappingの表示
*/
if ( SYSTEM_MANDATORY_LABEL_ACE_TYPE == bAceType ) {
for ( UINT nI = 0; nI < _countof( taSysMandatoryMapping ); nI++ ) {
// マスクの取得
DWORD dwMaskTmp = taSysMandatoryMapping[ nI ].dwAccessMask;
if ( 0 != ( dwMask & dwMaskTmp ) ) {
printf( "¥t ->0x%08x : %ls¥n", dwMaskTmp, taSysMandatoryMapping[ nI ].wpName );
dwMask &= ~dwMaskTmp;
}
}
}
/*
その他の表示
*/
if ( 0 != dwMask ) {
printf( "¥t ->0x%08x : Others¥n", dwMask );
}
LPWSTR wpSid = NULL;
// SIDを文字列SIDに変換する
BOOL bRet = ::ConvertSidToStringSid( (SID*)&pAccessAllowedAce->SidStart, &wpSid );
if ( FALSE == bRet ) {
printf( "ConvertSidToStringSid failed err = %d¥n", GetLastError() );
}
printf( "¥tSID = %ls¥n", ( NULL == wpSid )? L"Unknown" : wpSid );
// SIDの解放
if ( NULL != wpSid ) {
LocalFree( wpSid );
}
}
break;
case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE:
case ACCESS_DENIED_OBJECT_ACE_TYPE:
case ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE:
case SYSTEM_ALARM_OBJECT_ACE_TYPE:
case SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE:
case SYSTEM_AUDIT_OBJECT_ACE_TYPE:
case SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE:
{
ACCESS_ALLOWED_OBJECT_ACE* pAccessAllowedObjectAce = (ACCESS_ALLOWED_OBJECT_ACE*)pAceHeader;
RPC_STATUS RpcRet = RPC_S_OK;
// アクセスマスクの取得
ACCESS_MASK dwMask= pAccessAllowedObjectAce->Mask;
// SIDを文字列SIDの変換
printf( "¥tAccessMask = 0x%08x¥n", dwMask );
/*
AccessMaskMapingの表示
*/
for ( UINT nI = 0; nI < _countof( taAccessMaskMaping ); nI++ ) {
// マスクの取得
DWORD dwMaskTmp = taAccessMaskMaping[ nI ].dwAccessMask;
if ( 0 != ( dwMask & dwMaskTmp ) ) {
printf( "¥t ->0x%08x : %ls¥n", dwMaskTmp, taAccessMaskMaping[ nI ].wpName );
dwMask &= ~dwMaskTmp;
}
}
/*
AdsRightMappingの表示
*/
if ( 0 != ( ACE_OBJECT_TYPE_PRESENT & pAccessAllowedObjectAce->Flags ) ) {
for ( UINT nI = 0; nI < _countof( taAdsRightMapping ); nI++ ) {
// マスクの取得
DWORD dwMaskTmp = taAdsRightMapping[ nI ].dwAccessMask;
if ( 0 != ( dwMask & dwMaskTmp ) ) {
printf( "¥t ->0x%08x : %ls¥n", dwMaskTmp, taAdsRightMapping[ nI ].wpName );
dwMask &= ~dwMaskTmp;
}
}
}
/*
その他の表示
*/
if ( 0 != dwMask ) {
printf( "¥t ->0x%08x : Others¥n", dwMask );
}
// tAccessFlagsの文字列化
TCHAR* wpAccessFlags = ( pAccessAllowedObjectAce->Flags < _countof( taObjectTypeMapping ) )? taObjectTypeMapping[ pAccessAllowedObjectAce->Flags ] : L"Unknown";
printf( "¥tAccessFlags = 0x%08x : %ls¥n", pAccessAllowedObjectAce->Flags, wpAccessFlags );
GUID* pGuidObj = NULL;
GUID* pGuidInheritedObj = NULL;
PSID pSidOffset = NULL;
switch ( pAccessAllowedObjectAce->Flags ) {
case 0:
{
pGuidObj = NULL;
pGuidInheritedObj = NULL;
pSidOffset = (PSID)&pAccessAllowedObjectAce->ObjectType;
}
break;
case ACE_OBJECT_TYPE_PRESENT:
{
pGuidObj = &pAccessAllowedObjectAce->ObjectType;
pGuidInheritedObj = NULL;
pSidOffset = (PSID)&pAccessAllowedObjectAce->InheritedObjectType;
}
break;
case ACE_INHERITED_OBJECT_TYPE_PRESENT:
{
pGuidObj = NULL;
pGuidInheritedObj = &pAccessAllowedObjectAce->ObjectType;
pSidOffset = (PSID)&pAccessAllowedObjectAce->InheritedObjectType;
}
break;
case ACE_OBJECT_TYPE_PRESENT | ACE_INHERITED_OBJECT_TYPE_PRESENT:
{
pGuidObj = &pAccessAllowedObjectAce->ObjectType;
pGuidInheritedObj = &pAccessAllowedObjectAce->InheritedObjectType;
pSidOffset = (PSID)&pAccessAllowedObjectAce->SidStart;
}
break;
default:
{
pGuidObj = NULL;
pGuidInheritedObj = NULL;
pSidOffset = NULL;
}
break;
}
LPWSTR wpSid = NULL;
// SIDを文字列に変換
bRet= ::ConvertSidToStringSid( pSidOffset, &wpSid );
if ( FALSE == bRet ) {
printf( "ConvertSidToStringSid failed err = %d¥n", GetLastError() );
}
printf( "¥tSID = %ls¥n", ( NULL == wpSid )? L"Unknown" : wpSid );
// SID文字列の解放
if ( NULL != wpSid ) {
LocalFree( wpSid );
}
// GUID文字列
RPC_WSTR wpGuidString = NULL;
if ( NULL != pGuidObj ) {
// GUIDを文字列に変換
RpcRet = ::UuidToString( pGuidObj, &wpGuidString );
if ( RPC_S_OK == RpcRet ) {
printf( "¥tObjectType = %ls¥n", wpGuidString );
}
else {
printf( "UuidToString failed (%d)¥n", RpcRet );
}
}
else {
printf( "¥tObjectType = Not defined¥n" );
}
// GUID文字列の解放
if ( wpGuidString ) {
RpcStringFree( &wpGuidString );
}
if ( NULL != pGuidInheritedObj ) {
// GUIDを文字列に変換
RpcRet= ::UuidToString( pGuidObj, &wpGuidString );
if ( RPC_S_OK == RpcRet ) {
printf( "¥tInheritedObjectType = %ls¥n", wpGuidString );
}
else {
printf( "UuidToString failed (%d)¥n", RpcRet );
}
}
else {
printf( "¥tInheritedObjectType = Not defined¥n" );
}
// GUID文字列の解放
if ( wpGuidString ) {
RpcStringFree( &wpGuidString );
}
}
break;
case ACCESS_ALLOWED_COMPOUND_ACE_TYPE: // reserved
default:
break;
}
}
/*
ACL情報の表示
*/
void DispAclInfo
(
ACL* pAcl
)
{
if ( NULL == pAcl ) {
std::wcout << L"ACLがNUULLでした。" << std::endl;
return;
}
BOOL bRet = FALSE;
// ACEの数を取得
DWORD dwAceCount = pAcl->AceCount;
printf( "AceCount = %d¥n", dwAceCount );
/*
ACEの数だけループ
*/
for ( UINT nI = 0; nI < dwAceCount; nI++ ) {
// ACEヘッダ
ACE_HEADER* pAceHeader = NULL;
// ACEの取得
bRet = ::GetAce( pAcl, nI, (LPVOID*)&pAceHeader );
if ( FALSE == bRet ) {
// ACEが取得できなかった。
continue;
}
printf( "-- ACE[ %d ] --¥n", nI );
// Ace情報の取得
DispAceInfo( pAceHeader );
printf( "¥n" );
}
}
/*
ACL情報を表示する
*/
int _tmain
(
int argc
, _TCHAR* argv[]
)
{
// std::wcoutのロケールを設定
std::wcout.imbue( std::locale( "", std::locale::ctype ) );
// エラーコード
HRESULT hResult = S_OK;
// SecurityDescriptorを取得するファイル
std::wstring strFilePath = L".¥¥TestData¥¥test.txt";
// ACL
PSECURITY_DESCRIPTOR pSecurityDescriptor = NULL;
PSID pSidOwner = NULL; // 所有者SID
PSID pSidGroup = NULL; // プライマリグループSID
ACL* pDacl = NULL; // DACL
GUID oGUID = { 0 };
/*
名前を指定されたオブジェクトのセキュリティ記述子のコピーを取得します。
*/
DWORD dwResult = ::GetNamedSecurityInfo(
strFilePath.c_str()
, SE_FILE_OBJECT
, 0
| OWNER_SECURITY_INFORMATION
| GROUP_SECURITY_INFORMATION
| DACL_SECURITY_INFORMATION
// | SACL_SECURITY_INFORMATION // SE_SECURITY_NAMEアクセス権が必要
| LABEL_SECURITY_INFORMATION
, &pSidOwner // 所有者SID
, &pSidGroup // プライマリグループSID
, &pDacl // DACL
, NULL // SACL
, &pSecurityDescriptor // SECURITY_DESCRIPTOR
);
if ( ERROR_SUCCESS != dwResult ) {
// エラー
hResult = ::HRESULT_FROM_WIN32( dwResult );
goto err;
}
// ACL情報の表示
DispAclInfo( pDacl );
err:
// セキュリティ記述子を解放する
if ( NULL != pSecurityDescriptor ) {
LocalFree( pSecurityDescriptor );
}
// 処理結果を返す
return( 0 );
}
AceCount = 6
-- ACE[ 0 ] --
AceSize = 20
AceType = 1
AceFlag = 0
AccessMask = 0x000301bf
->0x00010000 : DELETE
->0x00020000 : READ_CONTROL
->0x000001bf : Others
SID = S-1-1-0
-- ACE[ 1 ] --
AceSize = 20
AceType = 0
AceFlag = 0
AccessMask = 0x00100116
->0x00100000 : SYNCHRONIZE
->0x00000116 : Others
SID = S-1-1-0
-- ACE[ 2 ] --
AceSize = 24
AceType = 0
AceFlag = 16
AccessMask = 0x001f01ff
->0x00010000 : DELETE
->0x00020000 : READ_CONTROL
->0x00040000 : WRITE_DAC
->0x00080000 : WRITE_OWNER
->0x00100000 : SYNCHRONIZE
->0x000001ff : Others
SID = S-1-5-32-544
-- ACE[ 3 ] --
AceSize = 20
AceType = 0
AceFlag = 16
AccessMask = 0x001f01ff
->0x00010000 : DELETE
->0x00020000 : READ_CONTROL
->0x00040000 : WRITE_DAC
->0x00080000 : WRITE_OWNER
->0x00100000 : SYNCHRONIZE
->0x000001ff : Others
SID = S-1-5-18
-- ACE[ 4 ] --
AceSize = 20
AceType = 0
AceFlag = 16
AccessMask = 0x001301bf
->0x00010000 : DELETE
->0x00020000 : READ_CONTROL
->0x00100000 : SYNCHRONIZE
->0x000001bf : Others
SID = S-1-5-11
-- ACE[ 5 ] --
AceSize = 24
AceType = 0
AceFlag = 16
AccessMask = 0x001200a9
->0x00020000 : READ_CONTROL
->0x00100000 : SYNCHRONIZE
->0x000000a9 : Others
SID = S-1-5-32-545