⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 accessenum.cpp

📁 查看文件可被那些用户使用,然后列出清单。进行查询。
💻 CPP
📖 第 1 页 / 共 4 页
字号:
#define _WIN32_WINNT 0x0400		// WM_MOUSEWHEEL support
#include <windows.h>
#include <stdio.h>
#include <commctrl.h>
#include <tchar.h>
#include <ctype.h>
#include <Aclapi.h>
#include <crtdbg.h>		// ASSERT
#include <comdef.h>		// bstr_t support
#include <lm.h>
#include <ShlObj.h>


#include "AccessEnum.h"
#include "resource.h"
#include "resizer.h"
#include "listview.h"
#include "Enumeration.h"


PSID DomainAdminSid();
bool IsDomainAdmin();
int GetAccountName( TCHAR * buf, const TCHAR * host, PSID sid );


const TCHAR ALL_DOMAINS[] = _T("<All domains>");

struct _globals {
	HINSTANCE			hInst;
	HWND				Abort;		// 'abort in progress' window
	bool				ShowAllFiles;
	CShare			*	ShareList;
	long				ThreadCount;
	HWND				hMainDlg;
	_bstr_t				Exclude;
} g;


const DWORD CFileEnumeration::READ_MASK		=	GENERIC_ALL|GENERIC_READ|GENERIC_EXECUTE|READ_CONTROL|FILE_READ_ATTRIBUTES|FILE_READ_DATA|FILE_READ_EA;
const DWORD CFileEnumeration::WRITE_MASK	=	GENERIC_ALL|GENERIC_WRITE|DELETE|WRITE_DAC|WRITE_OWNER|FILE_APPEND_DATA|FILE_WRITE_ATTRIBUTES|FILE_WRITE_DATA|FILE_WRITE_EA;

const DWORD	CRegEnumeration::READ_MASK		=	GENERIC_ALL|GENERIC_READ|GENERIC_EXECUTE|READ_CONTROL|KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS|KEY_NOTIFY;
const DWORD	CRegEnumeration::WRITE_MASK		=	GENERIC_ALL|GENERIC_WRITE|DELETE|WRITE_DAC|WRITE_OWNER|KEY_SET_VALUE|KEY_CREATE_SUB_KEY|KEY_CREATE_LINK;


// Everyone
static const SID	SID_EVERYONE			= { 1, 1, SECURITY_WORLD_SID_AUTHORITY,		SECURITY_NULL_RID					};
// creator owner
static const SID	SID_CREATOR_OWNER		= { 1, 1, SECURITY_CREATOR_SID_AUTHORITY,	SECURITY_CREATOR_OWNER_RID			};
static const SID	SID_CREATOR_GROUP		= { 1, 1, SECURITY_CREATOR_SID_AUTHORITY,	SECURITY_CREATOR_GROUP_RID			};
static const SID	SID_CREATOR_OWNERSERVER	= { 1, 1, SECURITY_CREATOR_SID_AUTHORITY,	SECURITY_CREATOR_OWNER_SERVER_RID 	};
static const SID	SID_CREATOR_GROUPSERVER	= { 1, 1, SECURITY_CREATOR_SID_AUTHORITY,	SECURITY_CREATOR_GROUP_SERVER_RID	};
// local system
static const SID	SID_NTAUTHORITY_SYSTEM	= { 1, 1, SECURITY_NT_AUTHORITY,			SECURITY_LOCAL_SYSTEM_RID			};
// alias sids
#if 0
static const SID	SID_BUILTIN_ADMIN		= { 1, 1, SECURITY_BUILTIN_DOMAIN_RID,		DOMAIN_ALIAS_RID_ADMINS				};
static const SID	SID_BUILTIN_POWERUSERS	= { 1, 1, SECURITY_BUILTIN_DOMAIN_RID,		DOMAIN_ALIAS_RID_POWER_USERS		};
static const SID	SID_BUILTIN_GUESTS		= { 1, 1, SECURITY_BUILTIN_DOMAIN_RID,		DOMAIN_ALIAS_RID_GUESTS				};
static const SID	SID_BUILTIN_USERS		= { 1, 1, SECURITY_BUILTIN_DOMAIN_RID,		DOMAIN_ALIAS_RID_USERS				};
#endif



static struct LISTVIEW_COLUMN Columns[] = 
{
	{ TEXT("Path"),			240,	DATATYPE_TEXT	},
	{ TEXT("Read"),			120,	DATATYPE_TEXT	},
	{ TEXT("Write"),		120,	DATATYPE_TEXT	},
	{ TEXT("Deny"),			80,		DATATYPE_TEXT	},
	{ NULL,					0,		(DATATYPE)-1	}
};



// Power Users
PSID SidLocalPowerUserAlias()
{
	static PSID sid = NULL;
	if ( sid == NULL )  {
		SID_IDENTIFIER_AUTHORITY	SystemSidAuthority = SECURITY_NT_AUTHORITY;
		AllocateAndInitializeSid( &SystemSidAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS,
									0, 0, 0, 0, 0, 0, &sid );
	}
	return sid;
}

// None
PSID SidNone()
{
	static PSID sid = NULL;
	if ( sid == NULL )  {
		SID_IDENTIFIER_AUTHORITY	SystemSidAuthority = SECURITY_NT_AUTHORITY;
		AllocateAndInitializeSid( &SystemSidAuthority, 5, SECURITY_NT_NON_UNIQUE, 0x56252AE1, 0xAEF28A35, 0x7D8EE907, 0x00000201, 0, 0, 0, &sid );
	}
	return sid;
}

// Local Administrators
PSID SidLocalAdminAlias()
{
	static PSID sid = NULL;
	if ( sid == NULL )  {
		SID_IDENTIFIER_AUTHORITY ntauth = SECURITY_NT_AUTHORITY;
		AllocateAndInitializeSid( &ntauth, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 
									0, 0, 0, 0, 0, 0, &sid );
	}
	return sid;
}


const TCHAR * FormattedMessage( DWORD status )
{
	static TCHAR msg[ 1024 ];
	msg[0] = 0;
	FormatMessage( FORMAT_MESSAGE_IGNORE_INSERTS|FORMAT_MESSAGE_FROM_SYSTEM, NULL,
					status, 0, msg, sizeof msg/sizeof msg[0], NULL );
	if ( msg[0] != 0 )  {
		TCHAR * ptr = _tcschr( msg, 0 );
		while ( ptr > msg  &&  isspace( *--ptr ) )
			*ptr = 0;
	} else {
		_stprintf( msg, _T("Error %d"), status );
	}
	return msg;
}


bool ShowFileProperties( HWND hDlg, const TCHAR * Path )
{
	SHELLEXECUTEINFO	shellExecuteInfo = { 0 };

	shellExecuteInfo.cbSize	= sizeof shellExecuteInfo;
	shellExecuteInfo.fMask	= SEE_MASK_INVOKEIDLIST;
	shellExecuteInfo.hwnd	= hDlg;
	shellExecuteInfo.lpVerb = _T("properties");
    shellExecuteInfo.lpFile = Path;

	return ShellExecuteEx( &shellExecuteInfo ) != FALSE;
}

bool ExploreFile( HWND hDlg, const TCHAR * Path )
{
	if ( _tcsnicmp( Path, _T("HK"), 2 ) == 0 )  {
		// registry key
		
		RegeditJump( hDlg, Path );
		return true;

	} else {
		// file
		SHELLEXECUTEINFO	shellExecuteInfo = { 0 };

		shellExecuteInfo.cbSize	= sizeof shellExecuteInfo;
		shellExecuteInfo.fMask	= SEE_MASK_INVOKEIDLIST;
		shellExecuteInfo.hwnd	= hDlg;
		shellExecuteInfo.lpVerb = _T("explore");
		shellExecuteInfo.lpFile = Path;

		return ShellExecuteEx( &shellExecuteInfo ) != FALSE;
	}
}




TCHAR * GetTextualSid( PSID pSid )
{
	PSID_IDENTIFIER_AUTHORITY psia;
	DWORD dwSubAuthorities;
	DWORD dwSidRev=SID_REVISION;
	DWORD dwCounter;
	DWORD dwSidSize;

	// Validate the binary SID.
	if ( ! IsValidSid( pSid ) )
		return NULL;

	// Get the identifier authority value from the SID.
	psia = GetSidIdentifierAuthority( pSid );

	// Get the number of subauthorities in the SID.
	dwSubAuthorities = *GetSidSubAuthorityCount(pSid);

	// Compute the buffer length.
	// S-SID_REVISION- + IdentifierAuthority- + subauthorities- + NULL
	dwSidSize = (15 + 12 + (12 * dwSubAuthorities) + 1) * sizeof(TCHAR);

	// Check input buffer length.
	// If too small, indicate the proper size and set last error.
	TCHAR	*	TextualSid = new TCHAR[ dwSidSize ];

	// Add 'S' prefix and revision number to the string.
	dwSidSize = wsprintf( TextualSid, TEXT("S-%lu-"), dwSidRev );

	// Add SID identifier authority to the string.
	if ( (psia->Value[0] != 0) || (psia->Value[1] != 0) )  {
		dwSidSize += wsprintf( TextualSid + dwSidSize,
								TEXT("0x%02hx%02hx%02hx%02hx%02hx%02hx"),
								(USHORT)psia->Value[0],
								(USHORT)psia->Value[1],
								(USHORT)psia->Value[2],
								(USHORT)psia->Value[3],
								(USHORT)psia->Value[4],
								(USHORT)psia->Value[5]);
	} else {
		dwSidSize += wsprintf( TextualSid + dwSidSize,
								TEXT("%lu"),
								(ULONG)(psia->Value[5]      )   +
								(ULONG)(psia->Value[4] <<  8)   +
								(ULONG)(psia->Value[3] << 16)   +
								(ULONG)(psia->Value[2] << 24)   );
	}

	// Add SID subauthorities to the string.
	//
	for ( dwCounter = 0; dwCounter < dwSubAuthorities; dwCounter++ )  {
		dwSidSize += wsprintf( TextualSid + dwSidSize, TEXT("-%lu"), *GetSidSubAuthority(pSid, dwCounter) );
	}

	return TextualSid;
}




struct ACCOUNT {
	PSID								Sid;
	const TCHAR						*	Name;
	const GROUP_USERS_INFO_0		*	GroupNetList;
	DWORD								GroupNetCnt;
	const LOCALGROUP_USERS_INFO_0	*	GroupLocalList;
	DWORD								GroupLocalCnt;
	SID_NAME_USE						Use;
};
#define UNDEFINED_ACCOUNT	((ACCOUNT *)-1)


const ACCOUNT * LookupSid( PSID pSid, const TCHAR * host )
{
	static	ACCOUNT **	AccountList = NULL;
	static	DWORD		AccountCnt	= 0;
	static	DWORD		AccountMax	= 0;

	for ( DWORD idx = 0; idx < AccountCnt; ++idx )
		if ( EqualSid( pSid, AccountList[idx]->Sid ) )
			return AccountList[idx];

	ACCOUNT	*	act = new ACCOUNT;

	// get copy of sid
	DWORD	sidlen = GetLengthSid( pSid );
	act->Sid = new BYTE[ sidlen ];
	memcpy( act->Sid, pSid, sidlen );

	// Get account name for sid.
	TCHAR		domainName[MAX_PATH+1+2] = _T("\\\\");
	TCHAR		userName[MAX_PATH+1];
	DWORD		userLength = MAX_PATH;
	DWORD		domainLength = MAX_PATH;
	TCHAR		fullName[ 2 * MAX_PATH ];

	if ( LookupAccountSid( host, pSid, userName, &userLength, domainName+2, &domainLength, &act->Use ) )  {
		// found account on remote system
		switch ( act->Use )  {
		case SidTypeAlias:
			_stprintf( fullName, _T("%s"), userName );
			break;
		case SidTypeUser:
			_stprintf( fullName, _T("%s\\%s"), domainName+2, userName );
			break;
		case SidTypeDeletedAccount:
			_stprintf( fullName, _T("%s\\%s(Deleted)"), domainName+2, userName );
			break;
		default:
			_ASSERT(false);
			// fall through
		case SidTypeGroup:
		case SidTypeWellKnownGroup:
			if ( domainName[2] )
				_stprintf( fullName, _T("%s\\%s"), domainName+2, userName );
			else
				_stprintf( fullName, _T("%s"), userName );
			break;
		}
		act->Name = _tcsdup( fullName );
	} else if ( host  &&  LookupAccountSid( NULL, pSid, userName, &userLength, domainName+2, &domainLength, &act->Use ) )  {
		_ASSERT(false);
		// found account on local system
		switch ( act->Use )  {
		case SidTypeAlias:
			_stprintf( fullName, _T("%s"), userName );
			break;
		case SidTypeUser:
			_stprintf( fullName, _T("%s\\%s"), domainName+2, userName );
			break;
		case SidTypeDeletedAccount:
			_stprintf( fullName, _T("%s\\%s(Deleted)"), domainName+2, userName );
			break;
		default:
			_ASSERT(false);
			// fall through
		case SidTypeGroup:
		case SidTypeWellKnownGroup:
			if ( domainName[2] )
				_stprintf( fullName, _T("%s\\%s"), domainName+2, userName );
			else
				_stprintf( fullName, _T("%s"), userName );
			break;
		}
		act->Name = _tcsdup( fullName );
	} else {
		if ( EqualSid( pSid, SidLocalPowerUserAlias() ) )  {
			_tcscpy( fullName, _T("Power Users") );
			act->Name = _tcsdup( fullName );
		} else {
			// Use plain SID
			act->Name	= GetTextualSid( pSid );
			act->Use	= SidTypeUnknown;
			fullName[0]	= 0;
		}
	}

	act->GroupNetList	= NULL;
	act->GroupLocalList	= NULL;
	act->GroupNetCnt	= 0;
	act->GroupLocalCnt	= 0;

	if ( act->Use == SidTypeUser )  {
		NET_API_STATUS	status;

		// see what groups account belongs to
		DWORD	total = 0;
		status = NetUserGetGroups( domainName, userName, 0, (BYTE **)&act->GroupNetList, MAX_PREFERRED_LENGTH, &act->GroupNetCnt, &total );
		_ASSERT( status == 0 || status == ERROR_ACCESS_DENIED );	// ERROR_INVALID_FUNCTION, NERR_InvalidComputer

		total = 0;
		TCHAR server[ MAX_PATH ];
		if ( host )  {
			_stprintf( server, _T("\\\\%s"), host );
			host = server;
		}
		status = NetUserGetLocalGroups( host, fullName, 0, LG_INCLUDE_INDIRECT, (BYTE **)&act->GroupLocalList, MAX_PREFERRED_LENGTH, &act->GroupLocalCnt, &total );
		_ASSERT( status == 0 || status == ERROR_ACCESS_DENIED );	// ERROR_INVALID_FUNCTION, NERR_InvalidComputer
	}

	// add account to list
	if ( AccountCnt >= AccountMax )  {
		AccountMax = AccountMax ? 2*AccountMax : 1024;
		AccountList = (ACCOUNT **)realloc( AccountList, AccountMax * sizeof AccountList[0] );
	}
	AccountList[ AccountCnt++ ] = act;

	return act;
}


struct ACCOUNT_RIGHTS {
	const ACCOUNT	*	Account;
	DWORD				AllowMask;
	DWORD				DenyMask;
};

inline int CompareAccount( const ACCOUNT * pa, const ACCOUNT * pb )
{
	if ( pa == pb )
		return 0;
	return _tcsicmp( pa->Name, pb->Name );
}
int __cdecl CompareAccountRights( const void * pa, const void * pb )
{
	return CompareAccount( ((const ACCOUNT_RIGHTS *)pa)->Account, ((const ACCOUNT_RIGHTS *)pb)->Account );
}

class CEnumeration;
bool GetCannonicalRights( const TCHAR * host, const PSECURITY_DESCRIPTOR sd, const CEnumeration * root, const ACCOUNT * Read[], const ACCOUNT * Write[], const ACCOUNT * Deny[] )
{
	BOOL	present, defaulted;
	PACL	acl = NULL;

	if ( host  &&  host[0] == 0 )
		host = NULL;

	// Get DACL 
	if ( !IsValidSecurityDescriptor( sd )  ||  
		 !GetSecurityDescriptorDacl( sd, &present, &acl, &defaulted )  ||  
		 !present )
	{
		// can't say anything about the rights
		Read[0]		= UNDEFINED_ACCOUNT;
		Write[0]	= UNDEFINED_ACCOUNT;
		Deny[0]		= UNDEFINED_ACCOUNT;
		Read[1]		= NULL;
		Write[1]	= NULL;
		Deny[1]		= NULL;
		return false;
	}

	if ( acl == NULL )  {
		// NULL dacl grants full access to everyone
		Read[0]		= LookupSid( (PSID)&SID_EVERYONE, host );
		Write[0]	= Read[0];
		Deny[0]		= Read[0];
		Read[1]		= NULL;
		Write[1]	= NULL;
		Deny[1]		= NULL;
		return true;
	}

	// First we'll get a list of all accounts and the rights each has.
	ACCOUNT_RIGHTS	AccountList[ MAX_ACCOUNTS_PER_ACL ];
	DWORD			AccountCnt = 0;

	// Iterate over aces and acculate a list of accounts
	for ( int idx = 0; idx < acl->AceCount; ++idx )  {

		ACCESS_ALLOWED_ACE * ace;

		// Get the ace
		GetAce( acl, idx, (void **)&ace );
		if ( ace->Header.AceType != ACCESS_ALLOWED_ACE_TYPE	&&
			 ace->Header.AceType != ACCESS_DENIED_ACE_TYPE )
		{
            continue;
		}

		// Get SID for ace
		PSID pSid = &ace->SidStart;
		if ( ! IsValidSid( pSid ) )
			continue;

		// translate CREATOR_OWNER sid to owner sid
		if ( EqualSid( pSid, (PSID)&SID_CREATOR_OWNER ) )  {
			PSID	pOwner = NULL;
			BOOL	defaulted;
			if ( ! GetSecurityDescriptorOwner( sd, &pOwner, &defaulted ) )
				continue;
			if ( pOwner == NULL )
				continue;	// no owner, therefore no permissions to report
			pSid = pOwner;
		} else if ( EqualSid( pSid, (PSID)&SID_CREATOR_GROUP ) )  {
			PSID	pOwner = NULL;
			BOOL	defaulted;
			if ( ! GetSecurityDescriptorGroup( sd, &pOwner, &defaulted ) )
				continue;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -