|
|
//+---------------------------------------------------------------------------
//
// 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
//
if ( wcslen( argv[1] ) > ( MAX_PATH - 20 ) ) { Usage(); return 1; }
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 = 0; TRUSTEE * pGroup = 0; DWORD cACE; EXPLICIT_ACCESS * pACE; DWORD cAudit = 0; EXPLICIT_ACCESS * pAudit = 0;
DWORD dwError = LookupSecurityDescriptorParts( &pOwner, &pGroup, &cACE, &pACE, &cAudit, &pAudit, pSD );
//
// And display it.
//
if ( ERROR_SUCCESS == dwError ) { if ( 0 != pOwner ) { printf( "Owner: " ); DisplayTrustee( *pOwner ); printf( "\n" ); LocalFree( pOwner ); }
if ( 0 != pGroup ) { printf( "Group: " ); DisplayTrustee( *pGroup ); printf( "\n" ); LocalFree( pGroup ); }
if ( cACE > 0 ) { printf( "Access: " ); DisplayACE( " ", cACE, pACE ); printf( "\n" ); LocalFree( pACE ); }
#if 0 // comes out the same as the access
if ( cAudit > 0 ) { printf( "Audit: " ); DisplayACE( " ", cAudit, pAudit ); printf( "\n" ); LocalFree( pAudit ); }
#endif
} 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
"Unknown", "Computer" };
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 ) { WCHAR wszName[100]; DWORD ccName = sizeof(wszName)/sizeof(wszName[0]);
WCHAR wszDomain[100]; DWORD ccDomain = sizeof(wszDomain)/sizeof(wszDomain[0]);
SID_NAME_USE snu;
BOOL fOk = LookupAccountSid( 0, // local system
(PSID)Trustee.ptstrName, // address of security identifier
wszName, // address of string for account name
&ccName, // address of size account string
wszDomain, // address of string for referenced domain
&ccDomain, // address of size domain string
&snu ); // address of structure for SID type
if ( fOk ) { if ( 0 == wszDomain[0] ) printf( "%ws (%s)", wszName, aszTrusteeType[snu] ); else printf( "%ws\\%ws (%s)", wszDomain, wszName, aszTrusteeType[snu] ); } else printf( "<SID>" ); } else printf( "Invalid Trustee form: %d\n", Trustee.TrusteeForm ); }
//+---------------------------------------------------------------------------
//
// 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" ); }
|