333 lines
7.9 KiB
C
333 lines
7.9 KiB
C
|
||
// Include NT headers
|
||
#include <nt.h>
|
||
#include <ntrtl.h>
|
||
#include <nturtl.h>
|
||
#include <ntseapi.h>
|
||
|
||
#include "windows.h"
|
||
|
||
void CtxDumpSid( PSID, PCHAR, PULONG );
|
||
void DumpAcl( PACL, PCHAR, PULONG );
|
||
void DumpAce( PACE_HEADER, PCHAR, PULONG );
|
||
|
||
#if DBG
|
||
void
|
||
DumpSecurityDescriptor(
|
||
PSECURITY_DESCRIPTOR pSD
|
||
)
|
||
{
|
||
PISECURITY_DESCRIPTOR p = (PISECURITY_DESCRIPTOR)pSD;
|
||
PSID pSid;
|
||
PACL pAcl;
|
||
PCHAR pTmp;
|
||
ULONG Size;
|
||
|
||
//
|
||
// This is done under an exception handler in case someone passes in
|
||
// a totally bogus security descriptor
|
||
//
|
||
try {
|
||
|
||
DbgPrint("DUMP_SECURITY_DESCRIPTOR: Revision %d, Sbz1 %d, Control 0x%x\n",
|
||
p->Revision, p->Sbz1, p->Control );
|
||
|
||
if ( p->Control & SE_SELF_RELATIVE ) {
|
||
DbgPrint("Self Relative\n");
|
||
}
|
||
|
||
DbgPrint("PSID Owner 0x%x\n",p->Owner);
|
||
|
||
// If this is self relative, must offset the pointers
|
||
if( p->Owner != NULL ) {
|
||
if( p->Control & SE_SELF_RELATIVE ) {
|
||
pTmp = (PCHAR)pSD;
|
||
pTmp += (UINT_PTR)p->Owner;
|
||
CtxDumpSid( (PSID)pTmp, (PCHAR)p, &Size );
|
||
}
|
||
else {
|
||
// can reference it directly
|
||
CtxDumpSid( p->Owner, (PCHAR)p, &Size );
|
||
}
|
||
}
|
||
|
||
|
||
DbgPrint("PSID Group 0x%x\n",p->Group);
|
||
|
||
// If this is self relative, must offset the pointers
|
||
if( p->Group != NULL ) {
|
||
if( p->Control & SE_SELF_RELATIVE ) {
|
||
pTmp = (PCHAR)pSD;
|
||
pTmp += (UINT_PTR)p->Group;
|
||
CtxDumpSid( (PSID)pTmp, (PCHAR)p, &Size );
|
||
}
|
||
else {
|
||
// can reference it directly
|
||
CtxDumpSid( p->Group, (PCHAR)p, &Size );
|
||
}
|
||
}
|
||
|
||
DbgPrint("\n");
|
||
|
||
DbgPrint("PACL Sacl 0x%x\n",p->Sacl);
|
||
|
||
// If this is self relative, must offset the pointers
|
||
if( p->Sacl != NULL ) {
|
||
if( p->Control & SE_SELF_RELATIVE ) {
|
||
pTmp = (PCHAR)pSD;
|
||
pTmp += (UINT_PTR)p->Sacl;
|
||
DumpAcl( (PSID)pTmp, (PCHAR)p, &Size );
|
||
}
|
||
else {
|
||
// can reference it directly
|
||
DumpAcl( p->Sacl, (PCHAR)p, &Size );
|
||
}
|
||
}
|
||
|
||
DbgPrint("\n");
|
||
|
||
DbgPrint("PACL Dacl 0x%x\n",p->Dacl);
|
||
|
||
// If this is self relative, must offset the pointers
|
||
if( p->Dacl != NULL ) {
|
||
if( p->Control & SE_SELF_RELATIVE ) {
|
||
pTmp = (PCHAR)pSD;
|
||
pTmp += (UINT_PTR)p->Dacl;
|
||
DumpAcl( (PSID)pTmp, (PCHAR)p, &Size );
|
||
}
|
||
else {
|
||
// can reference it directly
|
||
DumpAcl( p->Dacl, (PCHAR)p, &Size );
|
||
}
|
||
}
|
||
|
||
|
||
} except( EXCEPTION_EXECUTE_HANDLER) {
|
||
DbgPrint("DUMP_SECURITY_DESCRIPTOR: Exception %d accessing descriptor\n",GetExceptionCode());
|
||
return;
|
||
}
|
||
}
|
||
#endif
|
||
|
||
#if DBG
|
||
void
|
||
CtxDumpSid(
|
||
PSID pSid,
|
||
PCHAR pBase,
|
||
PULONG pSize
|
||
)
|
||
{
|
||
PISID p;
|
||
ULONG i;
|
||
BOOL OK;
|
||
DWORD szUserName;
|
||
DWORD szDomain;
|
||
SID_NAME_USE UserSidType;
|
||
WCHAR UserName[256];
|
||
WCHAR Domain[256];
|
||
ULONG Size = 0;
|
||
|
||
p = (PISID)pSid;
|
||
|
||
DbgPrint("Revision %d, SubAuthorityCount %d\n", p->Revision, p->SubAuthorityCount);
|
||
|
||
Size += 2; // Revision, SubAuthorityCount
|
||
|
||
DbgPrint("IdentifierAuthority: %x %x %x %x %x %x\n",
|
||
p->IdentifierAuthority.Value[0],
|
||
p->IdentifierAuthority.Value[1],
|
||
p->IdentifierAuthority.Value[2],
|
||
p->IdentifierAuthority.Value[3],
|
||
p->IdentifierAuthority.Value[4],
|
||
p->IdentifierAuthority.Value[5] );
|
||
|
||
Size += 6; // IdentifierAuthority
|
||
|
||
for( i=0; i < p->SubAuthorityCount; i++ ) {
|
||
|
||
DbgPrint("SubAuthority[%d] 0x%x\n", i, p->SubAuthority[i]);
|
||
|
||
Size += sizeof(ULONG);
|
||
}
|
||
|
||
if( pSize ) {
|
||
*pSize = Size;
|
||
}
|
||
|
||
szUserName = sizeof(UserName);
|
||
szDomain = sizeof(Domain);
|
||
|
||
// Now print its account
|
||
OK = LookupAccountSidW(
|
||
NULL, // Computer Name
|
||
pSid,
|
||
UserName,
|
||
&szUserName,
|
||
Domain,
|
||
&szDomain,
|
||
&UserSidType
|
||
);
|
||
|
||
if( OK ) {
|
||
DbgPrint("Account Name %ws, Domain %ws, Type %d, SidSize %d\n",UserName,Domain,UserSidType,Size);
|
||
}
|
||
else {
|
||
DbgPrint("Error looking up account name %d, SizeSid %d\n",GetLastError(),Size);
|
||
}
|
||
|
||
}
|
||
#endif
|
||
|
||
#if DBG
|
||
void
|
||
DumpAcl(
|
||
PACL pAcl,
|
||
PCHAR pBase,
|
||
PULONG pSize
|
||
)
|
||
{
|
||
USHORT i;
|
||
PCHAR pTmp;
|
||
ULONG Size, MySize;
|
||
PACL p = pAcl;
|
||
PCHAR pCur = (PCHAR)pAcl;
|
||
|
||
MySize = 0;
|
||
|
||
DbgPrint("AclRevision %d, Sbz1 %d, AclSize %d, AceCount %d, Sbz2 %d\n",
|
||
p->AclRevision, p->Sbz1, p->AclSize, p->AceCount, p->Sbz2 );
|
||
|
||
// bump over the ACL header to point to the first ACE
|
||
pCur += sizeof( ACL );
|
||
|
||
MySize += sizeof( ACL );
|
||
|
||
for( i=0; i < p->AceCount; i++ ) {
|
||
|
||
DumpAce( (PACE_HEADER)pCur, pBase, &Size );
|
||
|
||
pCur += Size;
|
||
MySize += Size;
|
||
}
|
||
|
||
// ACL consistency check
|
||
if( p->AclSize != MySize ) {
|
||
DbgPrint("Inconsistent ACL Entry! p->AclSize %d, RealSize %d\n",p->AclSize,MySize);
|
||
}
|
||
|
||
// return the size of this ACL
|
||
*pSize = MySize;
|
||
return;
|
||
}
|
||
#endif
|
||
|
||
#if DBG
|
||
void
|
||
DumpAce(
|
||
PACE_HEADER pAce,
|
||
PCHAR pBase,
|
||
PULONG pSize
|
||
)
|
||
{
|
||
PACE_HEADER p = pAce;
|
||
PACCESS_ALLOWED_ACE pAl;
|
||
PACCESS_DENIED_ACE pAd;
|
||
PSYSTEM_AUDIT_ACE pSa;
|
||
PSYSTEM_ALARM_ACE pSl;
|
||
PCHAR pTmp;
|
||
ULONG MySize, Size;
|
||
|
||
|
||
DbgPrint("ACE_HEADER: Type %d, Flags 0x%x, Size %d\n",
|
||
p->AceType, p->AceFlags, p->AceSize );
|
||
|
||
|
||
switch( p->AceType ) {
|
||
|
||
case ACCESS_ALLOWED_ACE_TYPE:
|
||
pAl = (PACCESS_ALLOWED_ACE)p;
|
||
DbgPrint("ACCESS_ALLOWED_ACE: AccessMask 0x%x, Sid 0x%x\n",pAl->Mask,pAl->SidStart);
|
||
|
||
MySize = sizeof(ACCESS_ALLOWED_ACE);
|
||
|
||
if( pAl->SidStart ) {
|
||
pTmp = (PCHAR)&pAl->SidStart;
|
||
CtxDumpSid( (PSID)pTmp, pBase, &Size );
|
||
MySize += Size;
|
||
// Adjust for the first ULONG of the ACE
|
||
// being part of the Sid
|
||
MySize -= sizeof(ULONG);
|
||
}
|
||
|
||
break;
|
||
|
||
case ACCESS_DENIED_ACE_TYPE:
|
||
pAd = (PACCESS_DENIED_ACE)p;
|
||
DbgPrint("ACCESS_DENIED_ACE: AccessMask 0x%x, Sid 0x%x\n",pAd->Mask,pAd->SidStart);
|
||
|
||
MySize = sizeof(ACCESS_DENIED_ACE);
|
||
|
||
if( pAd->SidStart ) {
|
||
pTmp = (PCHAR)&pAd->SidStart;
|
||
CtxDumpSid( (PSID)pTmp, pBase, &Size );
|
||
MySize += Size;
|
||
// Adjust for the first ULONG of the ACE
|
||
// being part of the Sid
|
||
MySize -= sizeof(ULONG);
|
||
}
|
||
|
||
break;
|
||
|
||
case SYSTEM_AUDIT_ACE_TYPE:
|
||
pSa = (PSYSTEM_AUDIT_ACE)p;
|
||
DbgPrint("SYSTEM_AUDIT_ACE: AccessMask 0x%x, Sid 0x%x\n",pSa->Mask,pSa->SidStart);
|
||
|
||
MySize = sizeof(SYSTEM_AUDIT_ACE);
|
||
|
||
if( pSa->SidStart ) {
|
||
pTmp = (PCHAR)&pSa->SidStart;
|
||
CtxDumpSid( (PSID)pTmp, pBase, &Size );
|
||
MySize += Size;
|
||
// Adjust for the first ULONG of the ACE
|
||
// being part of the Sid
|
||
MySize -= sizeof(ULONG);
|
||
}
|
||
|
||
break;
|
||
|
||
case SYSTEM_ALARM_ACE_TYPE:
|
||
pSl = (PSYSTEM_ALARM_ACE)p;
|
||
DbgPrint("SYSTEM_ALARM_ACE: AccessMask 0x%x, Sid 0x%x\n",pSl->Mask,pSl->SidStart);
|
||
|
||
MySize = sizeof(SYSTEM_ALARM_ACE);
|
||
|
||
if( pSl->SidStart ) {
|
||
pTmp = (PCHAR)&pSl->SidStart;
|
||
CtxDumpSid( (PSID)pTmp, pBase, &Size );
|
||
MySize += Size;
|
||
// Adjust for the first ULONG of the ACE
|
||
// being part of the Sid
|
||
MySize -= sizeof(ULONG);
|
||
}
|
||
|
||
break;
|
||
|
||
default:
|
||
DbgPrint("Unknown ACE type %d\n", p->AceType);
|
||
}
|
||
|
||
// Check its consistency
|
||
if( p->AceSize != MySize ) {
|
||
DbgPrint("Inconsistent ACE Entry! p->AceSize %d, RealSize %d\n",p->AceSize,MySize);
|
||
}
|
||
|
||
// return the size so the caller can update the pointer
|
||
*pSize = p->AceSize;
|
||
|
||
DbgPrint("\n");
|
||
|
||
return;
|
||
}
|
||
#endif
|
||
|
||
|