// Include NT headers #include #include #include #include #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