487 lines
13 KiB
C++
487 lines
13 KiB
C++
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Microsoft Windows
|
||
|
// Copyright (C) Microsoft Corporation, 1992 - 1998.
|
||
|
//
|
||
|
// File: Main.cxx
|
||
|
//
|
||
|
// Contents: Main file for CI security dump utility
|
||
|
//
|
||
|
// History: 29-Jul-1998 KyleP Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <windows.h>
|
||
|
#include <aclapi.h>
|
||
|
|
||
|
typedef ULONG SDID;
|
||
|
|
||
|
//
|
||
|
// Copied from SecCache.hxx (NtCiUtil directory)
|
||
|
//
|
||
|
|
||
|
const USHORT SECSTORE_REC_SIZE = 64;
|
||
|
const ULONG SECSTORE_HASH_SIZE = 199;
|
||
|
|
||
|
struct SSdHeaderRecord
|
||
|
{
|
||
|
ULONG cbSD; // size in bytes of the security descriptor
|
||
|
ULONG ulHash; // the hash of the security descriptor
|
||
|
SDID iHashChain; // index to previous entry for hash bucket
|
||
|
};
|
||
|
|
||
|
//
|
||
|
// Used for mapping bitmasks to text.
|
||
|
//
|
||
|
|
||
|
struct SPermDisplay
|
||
|
{
|
||
|
DWORD Perm;
|
||
|
char * Display;
|
||
|
};
|
||
|
|
||
|
//
|
||
|
// Local constants and function prototypes
|
||
|
//
|
||
|
|
||
|
unsigned const SixtyFourK = 1024 * 64;
|
||
|
|
||
|
void DisplayTrustee( TRUSTEE const & Trustee );
|
||
|
void DisplayACE( char const * pszPreface, unsigned cACE, EXPLICIT_ACCESS * pACE );
|
||
|
void DisplayMode( DWORD mode );
|
||
|
void DisplayInheritance( DWORD Inherit );
|
||
|
void DisplayPerms( DWORD grfAccess );
|
||
|
void Display( DWORD grfAccess, SPermDisplay aPerm[], unsigned cPerm, unsigned cDisplay = 0 );
|
||
|
void Usage();
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: wmain, public
|
||
|
//
|
||
|
// Synopsis: Program entry point. Iterates and displays SDID mapping.
|
||
|
//
|
||
|
// Arguments: [argc] -- Argument count
|
||
|
// [argv] -- Program arguments
|
||
|
//
|
||
|
// History: 29-Jul-1998 KyleP Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
extern "C" int __cdecl wmain( int argc, WCHAR * argv[] )
|
||
|
{
|
||
|
if ( argc != 2 )
|
||
|
{
|
||
|
Usage();
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Open handle
|
||
|
//
|
||
|
|
||
|
WCHAR wszSecFile[MAX_PATH];
|
||
|
wcscpy( wszSecFile, argv[1] );
|
||
|
wcscat( wszSecFile, L"\\CiST0000.001" );
|
||
|
|
||
|
HANDLE h = CreateFile( wszSecFile,
|
||
|
GENERIC_READ,
|
||
|
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||
|
0,
|
||
|
OPEN_EXISTING,
|
||
|
0,
|
||
|
0 );
|
||
|
|
||
|
if ( INVALID_HANDLE_VALUE == h )
|
||
|
{
|
||
|
printf( "Can't open file %ws. Error %u\n", wszSecFile, GetLastError() );
|
||
|
return GetLastError();
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Read until done.
|
||
|
//
|
||
|
|
||
|
BYTE abTemp[SixtyFourK];
|
||
|
DWORD cbRead;
|
||
|
int i = 0;
|
||
|
|
||
|
SSdHeaderRecord Header;
|
||
|
|
||
|
while ( ReadFile( h,
|
||
|
&Header,
|
||
|
sizeof(Header),
|
||
|
&cbRead,
|
||
|
0 ) )
|
||
|
{
|
||
|
if ( 0 == Header.cbSD )
|
||
|
break;
|
||
|
|
||
|
i++;
|
||
|
printf( "SDID %u / 0x%x (cbSD = %u bytes)\n", i, i, Header.cbSD );
|
||
|
|
||
|
//
|
||
|
// Read rest of first record.
|
||
|
//
|
||
|
|
||
|
if ( !ReadFile( h,
|
||
|
abTemp,
|
||
|
SECSTORE_REC_SIZE - sizeof(Header) + 4,
|
||
|
&cbRead,
|
||
|
0 ) )
|
||
|
{
|
||
|
printf( "Error %u reading file\n", GetLastError() );
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Read additional records, which together create one security descriptor
|
||
|
//
|
||
|
|
||
|
if ( Header.cbSD > (SECSTORE_REC_SIZE - sizeof(Header)) )
|
||
|
{
|
||
|
unsigned iCurrent = SECSTORE_REC_SIZE - sizeof(Header);
|
||
|
|
||
|
for ( unsigned cLeft = (Header.cbSD - SECSTORE_REC_SIZE + sizeof(Header) - 1) / SECSTORE_REC_SIZE + 1;
|
||
|
cLeft > 0;
|
||
|
cLeft-- )
|
||
|
{
|
||
|
if ( !ReadFile( h,
|
||
|
abTemp + iCurrent,
|
||
|
SECSTORE_REC_SIZE + 4,
|
||
|
&cbRead,
|
||
|
0 ) )
|
||
|
{
|
||
|
printf( "Error %u reading file\n", GetLastError() );
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
i++;
|
||
|
iCurrent += SECSTORE_REC_SIZE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
SECURITY_DESCRIPTOR * pSD = (SECURITY_DESCRIPTOR *)abTemp;
|
||
|
|
||
|
//
|
||
|
// Create a human-readable descriptor
|
||
|
//
|
||
|
|
||
|
TRUSTEE * pOwner;
|
||
|
TRUSTEE * pGroup;
|
||
|
DWORD cACE;
|
||
|
EXPLICIT_ACCESS * pACE;
|
||
|
|
||
|
DWORD dwError = LookupSecurityDescriptorParts( &pOwner,
|
||
|
&pGroup,
|
||
|
&cACE,
|
||
|
&pACE,
|
||
|
0,
|
||
|
0,
|
||
|
pSD );
|
||
|
|
||
|
//
|
||
|
// And display it.
|
||
|
//
|
||
|
|
||
|
if ( ERROR_SUCCESS == dwError )
|
||
|
{
|
||
|
if ( 0 != pOwner )
|
||
|
{
|
||
|
printf( "Owner: " );
|
||
|
DisplayTrustee( *pOwner );
|
||
|
LocalFree( pOwner );
|
||
|
}
|
||
|
|
||
|
if ( 0 != pGroup )
|
||
|
{
|
||
|
printf( "Group: " );
|
||
|
DisplayTrustee( *pGroup );
|
||
|
LocalFree( pGroup );
|
||
|
}
|
||
|
|
||
|
if ( cACE > 0 )
|
||
|
{
|
||
|
printf( "Access: " );
|
||
|
DisplayACE( " ", cACE, pACE );
|
||
|
LocalFree( pACE );
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
printf( "LookupSecurityDescriptorParts returned %u\n", dwError );
|
||
|
|
||
|
printf( "\n\n" );
|
||
|
}
|
||
|
|
||
|
CloseHandle( h );
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: DisplayTrustee
|
||
|
//
|
||
|
// Synopsis: Prints out trustee (user, group, etc.)
|
||
|
//
|
||
|
// Arguments: [Trustee] -- Trustee description
|
||
|
//
|
||
|
// History: 29-Jul-1998 KyleP Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
char * aszTrusteeType[] = { "Unknown", // TRUSTEE_IS_UNKNOWN
|
||
|
"User", // TRUSTEE_IS_USER,
|
||
|
"Group", // TRUSTEE_IS_GROUP,
|
||
|
"Domain", // TRUSTEE_IS_DOMAIN,
|
||
|
"Alias", // TRUSTEE_IS_ALIAS,
|
||
|
"Group", // TRUSTEE_IS_WELL_KNOWN_GROUP,
|
||
|
"Deleted", // TRUSTEE_IS_DELETED,
|
||
|
"Invalid" }; // TRUSTEE_IS_INVALID
|
||
|
|
||
|
void DisplayTrustee( TRUSTEE const & Trustee )
|
||
|
{
|
||
|
if ( TRUSTEE_IS_NAME == Trustee.TrusteeForm )
|
||
|
{
|
||
|
printf( "%ws (%s)", Trustee.ptstrName, aszTrusteeType[Trustee.TrusteeType] );
|
||
|
}
|
||
|
else if ( TRUSTEE_IS_SID == Trustee.TrusteeForm )
|
||
|
{
|
||
|
}
|
||
|
else
|
||
|
printf( "Invalid Trustee form\n" );
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: DisplayACE
|
||
|
//
|
||
|
// Synopsis: Prints out Access Control Entry(ies)
|
||
|
//
|
||
|
// Arguments: [pszPreface] -- String to append at beginning of each line.
|
||
|
// [cACE] -- Count of entries
|
||
|
// [pACE] -- Array of entries
|
||
|
//
|
||
|
// History: 29-Jul-1998 KyleP Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
void DisplayACE( char const * pszPreface, unsigned cACE, EXPLICIT_ACCESS * pACE )
|
||
|
{
|
||
|
for ( unsigned i = 0; i < cACE; i++ )
|
||
|
{
|
||
|
if ( 0 != i )
|
||
|
printf( "%s", pszPreface );
|
||
|
|
||
|
DisplayTrustee( pACE[i].Trustee );
|
||
|
|
||
|
printf( " : " );
|
||
|
|
||
|
DisplayMode( pACE[i].grfAccessMode );
|
||
|
|
||
|
printf( " /" );
|
||
|
|
||
|
DisplayInheritance( pACE[i].grfInheritance );
|
||
|
|
||
|
printf( " /" );
|
||
|
|
||
|
DisplayPerms( pACE[i].grfAccessPermissions );
|
||
|
|
||
|
printf( "\n" );
|
||
|
}
|
||
|
//ACCESS_MODE grfAccessMode; DWORD grfInheritance;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: DisplayMode, private
|
||
|
//
|
||
|
// Synopsis: Prints out access mode (Set or Deny access)
|
||
|
//
|
||
|
// Arguments: [mode] -- Access mode
|
||
|
//
|
||
|
// History: 29-Jul-1998 KyleP Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
char * aszAccessDisplay[] = { "NOT_USED",
|
||
|
"GRANT_ACCESS",
|
||
|
"SET_ACCESS",
|
||
|
"DENY_ACCESS",
|
||
|
"REVOKE_ACCESS",
|
||
|
"SET_AUDIT_SUCCESS",
|
||
|
"SET_AUDIT_FAILURE" };
|
||
|
|
||
|
void DisplayMode( DWORD mode )
|
||
|
{
|
||
|
printf( "%s", aszAccessDisplay[mode] );
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: DisplayInheritance, private
|
||
|
//
|
||
|
// Synopsis: Prints out inheritance, both up (to parent) and down (to children)
|
||
|
//
|
||
|
// Arguments: [Inherit] -- Inheritance bitmask
|
||
|
//
|
||
|
// History: 29-Jul-1998 KyleP Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
SPermDisplay aInheritDisplay[] = {
|
||
|
//{ INHERITED_ACCESS_ENTRY, "(inherited)" },
|
||
|
{ INHERITED_PARENT, "(inherited from parent)" },
|
||
|
{ INHERITED_GRANDPARENT, "(inherited from grandparent)" },
|
||
|
{ SUB_OBJECTS_ONLY_INHERIT, "SUB_OBJECTS_ONLY" },
|
||
|
{ SUB_CONTAINERS_ONLY_INHERIT, "SUB_CONTAINERS_ONLY" },
|
||
|
{ SUB_CONTAINERS_AND_OBJECTS_INHERIT, "SUB_CONTAINERS_AND_OBJECTS" },
|
||
|
{ INHERIT_NO_PROPAGATE, "INHERIT_NO_PROPAGATE" },
|
||
|
{ INHERIT_ONLY, "INHERIT_ONLY" } };
|
||
|
|
||
|
void DisplayInheritance( DWORD Inherit )
|
||
|
{
|
||
|
if ( NO_INHERITANCE == Inherit )
|
||
|
printf( "\n\t\t(not inherited)" );
|
||
|
else
|
||
|
Display( Inherit, aInheritDisplay, sizeof(aInheritDisplay)/sizeof(aInheritDisplay[0]) );
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: DisplayPerms
|
||
|
//
|
||
|
// Synopsis: Displays file permissions
|
||
|
//
|
||
|
// Arguments: [grfAccess] -- Access permission bitmask
|
||
|
//
|
||
|
// History: 29-Jul-1998 KyleP Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
SPermDisplay aPermDisplay[] = {
|
||
|
{ FILE_READ_DATA, "READ_DATA" },
|
||
|
{ FILE_WRITE_DATA, "WRITE_DATA" },
|
||
|
{ FILE_ADD_FILE, "ADD_FILE" },
|
||
|
{ FILE_APPEND_DATA, "APPEND_DATA" },
|
||
|
{ FILE_ADD_SUBDIRECTORY, "ADD_SUBDIRECTORY" },
|
||
|
{ FILE_CREATE_PIPE_INSTANCE, "CREATE_PIPE_INSTANCE" },
|
||
|
{ FILE_READ_EA, "READ_EA" },
|
||
|
{ FILE_WRITE_EA, "WRITE_EA" },
|
||
|
{ FILE_EXECUTE, "EXECUTE" },
|
||
|
{ FILE_TRAVERSE, "TRAVERSE" },
|
||
|
{ FILE_DELETE_CHILD, "DELETE_CHILD" },
|
||
|
{ FILE_READ_ATTRIBUTES, "READ_ATTRIBUTES" },
|
||
|
{ FILE_WRITE_ATTRIBUTES, "WRITE_ATTRIBUTES" },
|
||
|
{ DELETE, "DELETE" },
|
||
|
{ READ_CONTROL, "READ_CONTROL" },
|
||
|
{ WRITE_DAC, "WRITE_DAC" },
|
||
|
{ WRITE_OWNER, "WRITE_OWNER" },
|
||
|
{ SYNCHRONIZE, "SYNCHRONIZE" },
|
||
|
{ GENERIC_READ, "GENERIC_READ" },
|
||
|
{ GENERIC_WRITE, "GENERIC_WRITE" },
|
||
|
{ GENERIC_EXECUTE, "GENERIC_EXECUTE" } };
|
||
|
|
||
|
|
||
|
void DisplayPerms( DWORD grfAccess )
|
||
|
{
|
||
|
BOOL cDisplay = 0;
|
||
|
DWORD grfRemove = 0;
|
||
|
|
||
|
printf( "\n\t\t" );
|
||
|
|
||
|
//
|
||
|
// First, get rid of the basics...
|
||
|
//
|
||
|
|
||
|
if ( (grfAccess & FILE_GENERIC_READ) == FILE_GENERIC_READ )
|
||
|
{
|
||
|
printf( "GENERIC_READ" );
|
||
|
grfRemove = FILE_GENERIC_READ;
|
||
|
cDisplay++;
|
||
|
}
|
||
|
|
||
|
if ( (grfAccess & FILE_GENERIC_WRITE) == FILE_GENERIC_WRITE )
|
||
|
{
|
||
|
if ( 0 != cDisplay )
|
||
|
printf( " | " );
|
||
|
|
||
|
printf( "GENERIC_WRITE" );
|
||
|
grfRemove = grfRemove | FILE_GENERIC_WRITE;
|
||
|
cDisplay++;
|
||
|
}
|
||
|
|
||
|
if ( (grfAccess & FILE_GENERIC_EXECUTE) == FILE_GENERIC_EXECUTE )
|
||
|
{
|
||
|
if ( 0 != cDisplay )
|
||
|
printf( " | " );
|
||
|
|
||
|
if ( 0 == (cDisplay % 2) )
|
||
|
printf( " \n\t\t" );
|
||
|
|
||
|
printf( "GENERIC_EXECUTE" );
|
||
|
grfRemove = grfRemove | FILE_GENERIC_EXECUTE;
|
||
|
cDisplay++;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Now, individual permissions.
|
||
|
//
|
||
|
|
||
|
DWORD grfRemainder = grfAccess & ~grfRemove;
|
||
|
|
||
|
Display( grfRemainder, aPermDisplay, sizeof(aPermDisplay)/sizeof(aPermDisplay[0]), cDisplay );
|
||
|
|
||
|
printf( " (0x%x)", grfAccess );
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: Display, private
|
||
|
//
|
||
|
// Synopsis: Print bit masks
|
||
|
//
|
||
|
// Arguments: [grfAccess] -- Bit mask
|
||
|
// [aPerm] -- Description of bits
|
||
|
// [cPerm] -- Count of entries in [aPerm]
|
||
|
// [cDisplay] -- Number of entries already displayed on
|
||
|
// current line by caller.
|
||
|
//
|
||
|
// History: 29-Jul-1998 KyleP Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
void Display( DWORD grfAccess, SPermDisplay aPerm[], unsigned cPerm, unsigned cDisplay )
|
||
|
{
|
||
|
for ( unsigned i = 0; i < cPerm ; i++ )
|
||
|
{
|
||
|
if ( grfAccess & aPerm[i].Perm )
|
||
|
{
|
||
|
if ( 0 != cDisplay )
|
||
|
printf( " | " );
|
||
|
|
||
|
if ( 0 == (cDisplay % 2) )
|
||
|
printf( " \n\t\t" );
|
||
|
|
||
|
printf( "%s", aPerm[i].Display );
|
||
|
|
||
|
cDisplay++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: Usage
|
||
|
//
|
||
|
// Synopsis: Displays program usage
|
||
|
//
|
||
|
// History: 29-Jul-1998 KyleP Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
void Usage()
|
||
|
{
|
||
|
printf( "Usage: DumpSec <Path to catalog>\n" );
|
||
|
}
|