📄 vncexportacl.cpp
字号:
/////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2004 Martin Scharpf. All Rights Reserved.
// Based on Felix Kasza's DumpACL (http://win32.mvps.org/security/dumpacl.html).
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
//
// If the source code for the program is not available from the place from
// which you received this file, check
// http://ultravnc.sourceforge.net/
#include "vncExportACL.h"
// Get ACL from regkey HKLM\Software\ORL\WinVNC3\ACL
bool vncExportACL::GetACL(PACL *pACL){
HKEY hk = NULL;
DWORD dwValueLength = SECURITY_DESCRIPTOR_MIN_LENGTH;
fprintf(stderr, "== Entering GetACL\n");
__try{
if (ERROR_SUCCESS != RegOpenKeyEx( HKEY_LOCAL_MACHINE,
"Software\\ORL\\WinVNC3",
0, KEY_QUERY_VALUE, &hk )){
fprintf(stderr, "== Error %d: RegOpenKeyEx\n", GetLastError());
__leave;
}
// Read the ACL value from the VNC registry key
// First call to RegQueryValueEx just gets the buffer length.
if (ERROR_SUCCESS != RegQueryValueEx(hk, // subkey handle
"ACL", // value name
0, // must be zero
0, // value type , not needed here
NULL, //
&dwValueLength)){ // length of value data
fprintf(stderr, "== Error %d: RegQueryValueEx 1\tValueLength = %d\n",
GetLastError(), dwValueLength);
__leave;
}
*pACL = (PACL) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwValueLength);
if (ERROR_SUCCESS != RegQueryValueEx(hk, // subkey handle
"ACL", // value name
0, // must be zero
0, // value type
(LPBYTE) *pACL,
&dwValueLength)){ // length of value data
fprintf(stderr, "== Error %d: RegQueryValueEx 2\n", GetLastError());
__leave;
}
fprintf(stderr, "== RegQueryValueEx passed\tdwValueLength = %d\n", dwValueLength);
} __finally {
if (hk)
RegCloseKey(hk);
}
return true;
}
const char *vncExportACL::SidToText( PSID psid )
{
// S-rev- + SIA + subauthlen*maxsubauth + terminator
static char buf[15 + 12 + 12*SID_MAX_SUB_AUTHORITIES + 1];
char *p = &buf[0];
PSID_IDENTIFIER_AUTHORITY psia;
DWORD numSubAuths, i;
// Validate the binary SID.
if (!IsValidSid(psid))
return FALSE;
psia = GetSidIdentifierAuthority(psid);
p = buf;
p += _snprintf(p, &buf[sizeof buf] - p, "S-%lu-", 0x0f & *((byte *)psid));
if ((psia->Value[0] != 0) || (psia->Value[1] != 0))
p += _snprintf( p, &buf[sizeof buf] - p, "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
p += _snprintf(p, &buf[sizeof buf] - p, "%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.
numSubAuths = *GetSidSubAuthorityCount(psid);
for (i = 0; i < numSubAuths; ++ i)
p += _snprintf(p, &buf[sizeof buf] - p, "-%lu", *GetSidSubAuthority(psid, i));
return buf;
}
void vncExportACL::PrintSid(PSID psid)
{
char name[256], domain[256];
DWORD cbname = sizeof name, cbdomain = sizeof domain, rc;
SID_NAME_USE sidUse;
//!! next line has hardcoded server name !!
// NULL server name is usually appropriate, though.
if (LookupAccountSid(NULL, psid, name, &cbname, domain, &cbdomain, &sidUse))
{
//Todo: Check if WellKnownSID and reserve special names for them.
/* switch ( sidUse )
{
case SidTypeWellKnownGroup: type = "well-known group"; break;
default: type = "bad sidUse value"; break;
}
*/
LPWKSTA_INFO_100 wkstainfo = NULL;
NET_API_STATUS nStatus;
char langroup[MAXLEN];
char computername[MAXLEN];
nStatus = NetWkstaGetInfo( 0 , 100 , (LPBYTE *) &wkstainfo);
if (nStatus == NERR_Success){
wcstombs(langroup, wkstainfo->wki100_langroup, MAXLEN);
wcstombs(computername, wkstainfo->wki100_computername, MAXLEN);
langroup[MAXLEN - 1] = '\0';
computername[MAXLEN - 1] = '\0';
// replace computername with a dot
if (_stricmp(computername, domain) == 0)
strcpy(domain,".");
else if (_stricmp(langroup, domain) == 0)
strcpy(domain, "..");
}
else
printf("NetWkstaGetInfo() returned %lu \n", wkstainfo);
NetApiBufferFree(wkstainfo);
wkstainfo = NULL;
// If domain or username contains whitespace, print enclosing quotes
if (strchr(domain, ' ') || strchr(name, ' '))
printf("\"%s%s%s\"\n", domain, (domain == 0 || *domain == '\0')? "": "\\", name);
else
printf("%s%s%s\n", domain, (domain == 0 || *domain == '\0')? "": "\\", name);
}
else
{
rc = GetLastError();
printf( "[%s] *** error %lu\n", SidToText( psid ), rc );
}
}
void vncExportACL::PrintAce(int index, PACL acl){
ACE_HEADER *ace;
char *type;
PSID psid;
if (!GetAce(acl, index, (void **) &ace)) {
printf("DACL, entry %d: GetAce() failed, gle == %lu\n",
index, GetLastError());
return;
}
switch ( ace->AceType ) {
case ACCESS_ALLOWED_ACE_TYPE:
type = "allow";
psid = &((ACCESS_ALLOWED_ACE *) ace)->SidStart;
break;
case ACCESS_DENIED_ACE_TYPE:
type = "deny";
psid = &((ACCESS_DENIED_ACE *) ace)->SidStart;
break;
default:
type = "invalid";
psid = &((ACCESS_ALLOWED_ACE *) ace)->SidStart;
break;
}
printf( "%s\t", type);
printf("0x%08lX\t", ((ACCESS_ALLOWED_ACE *) ace)->Mask);
PrintSid( psid );
}
void vncExportACL::PrintAcl(PACL acl)
{
DWORD i;
ACL_SIZE_INFORMATION aci;
if ( acl == 0 )
return;
if (!GetAclInformation( acl, &aci, sizeof aci, AclSizeInformation)) {
printf("GAI(): gle == %lu\n", GetLastError());
return;
}
for ( i = 0; i < aci.AceCount; ++ i )
PrintAce(i, acl);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -