わびさびサンプルソース

WindowsやHTML5などのプログラムのサンプルコードやフリーソフトを提供します。

ACL情報の表示

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






わびさびサンプルソース

WindowsやHTML5などのプログラムのサンプルコードやフリーソフトを提供します。