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