1 /* 2 * PROJECT: ReactOS kernel-mode tests 3 * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory 4 * PURPOSE: Kernel-Mode Test Suite Helper functions for Se tests 5 * PROGRAMMER: Thomas Faber <thomas.faber@reactos.org> 6 */ 7 8 #include <kmt_test.h> 9 #include "se.h" 10 11 NTSTATUS 12 RtlxAddAuditAccessAceEx( 13 _Inout_ PACL Acl, 14 _In_ ULONG Revision, 15 _In_ ULONG Flags, 16 _In_ ACCESS_MASK AccessMask, 17 _In_ PSID Sid, 18 _In_ BOOLEAN Success, 19 _In_ BOOLEAN Failure) 20 { 21 NTSTATUS Status; 22 USHORT AceSize; 23 PSYSTEM_AUDIT_ACE Ace; 24 25 if (Success) Flags |= SUCCESSFUL_ACCESS_ACE_FLAG; 26 if (Failure) Flags |= FAILED_ACCESS_ACE_FLAG; 27 28 AceSize = FIELD_OFFSET(SYSTEM_AUDIT_ACE, SidStart) + RtlLengthSid(Sid); 29 Ace = ExAllocatePoolWithTag(PagedPool, AceSize, 'cAmK'); 30 if (!Ace) 31 return STATUS_INSUFFICIENT_RESOURCES; 32 Ace->Header.AceType = SYSTEM_AUDIT_ACE_TYPE; 33 Ace->Header.AceFlags = Flags; 34 Ace->Header.AceSize = AceSize; 35 Ace->Mask = AccessMask; 36 Status = RtlCopySid(AceSize - FIELD_OFFSET(SYSTEM_AUDIT_ACE, SidStart), 37 (PSID)&Ace->SidStart, 38 Sid); 39 ASSERT(NT_SUCCESS(Status)); 40 if (NT_SUCCESS(Status)) 41 { 42 Status = RtlAddAce(Acl, 43 Revision, 44 MAXULONG, 45 Ace, 46 AceSize); 47 } 48 ExFreePoolWithTag(Ace, 'cAmK'); 49 return Status; 50 } 51 52 NTSTATUS 53 RtlxAddMandatoryLabelAceEx( 54 _Inout_ PACL Acl, 55 _In_ ULONG Revision, 56 _In_ ULONG Flags, 57 _In_ ACCESS_MASK AccessMask, 58 _In_ PSID Sid) 59 { 60 NTSTATUS Status; 61 USHORT AceSize; 62 PSYSTEM_MANDATORY_LABEL_ACE Ace; 63 64 AceSize = FIELD_OFFSET(SYSTEM_MANDATORY_LABEL_ACE, SidStart) + RtlLengthSid(Sid); 65 Ace = ExAllocatePoolWithTag(PagedPool, AceSize, 'cAmK'); 66 if (!Ace) 67 return STATUS_INSUFFICIENT_RESOURCES; 68 Ace->Header.AceType = SYSTEM_MANDATORY_LABEL_ACE_TYPE; 69 Ace->Header.AceFlags = Flags; 70 Ace->Header.AceSize = AceSize; 71 Ace->Mask = AccessMask; 72 Status = RtlCopySid(AceSize - FIELD_OFFSET(SYSTEM_MANDATORY_LABEL_ACE, SidStart), 73 (PSID)&Ace->SidStart, 74 Sid); 75 ASSERT(NT_SUCCESS(Status)); 76 if (NT_SUCCESS(Status)) 77 { 78 Status = RtlAddAce(Acl, 79 Revision, 80 MAXULONG, 81 Ace, 82 AceSize); 83 } 84 ExFreePoolWithTag(Ace, 'cAmK'); 85 return Status; 86 } 87 88 VOID 89 CheckSid__( 90 _In_ PSID Sid, 91 _In_ ULONG SidSize, 92 _In_ PISID ExpectedSid, 93 _In_ PCSTR FileAndLine) 94 { 95 BOOLEAN Okay; 96 ULONG Length; 97 98 KmtOk(Sid != NULL, FileAndLine, "Sid is NULL\n"); 99 if (KmtSkip(Sid != NULL, FileAndLine, "No Sid\n")) 100 return; 101 if (KmtSkip(SidSize >= sizeof(ULONG), FileAndLine, "Sid too small: %lu\n", SidSize)) 102 return; 103 Okay = RtlValidSid(Sid); 104 KmtOk(Okay == TRUE, FileAndLine, "Invalid Sid\n"); 105 if (KmtSkip(Okay, FileAndLine, "Invalid Sid\n")) 106 return; 107 108 Length = RtlLengthSid(Sid); 109 KmtOk(SidSize >= Length, FileAndLine, "SidSize %lu too small, need %lu\n", SidSize, Length); 110 if (KmtSkip(SidSize >= Length, FileAndLine, "Sid too small\n")) 111 return; 112 Okay = RtlEqualSid(Sid, ExpectedSid); 113 KmtOk(Okay, FileAndLine, "Sids %p and %p not equal\n", Sid, ExpectedSid); 114 if (!Okay) 115 { 116 WCHAR Buffer1[128]; 117 WCHAR Buffer2[128]; 118 UNICODE_STRING SidString1, SidString2; 119 RtlInitEmptyUnicodeString(&SidString1, Buffer1, sizeof(Buffer1)); 120 RtlInitEmptyUnicodeString(&SidString2, Buffer2, sizeof(Buffer2)); 121 (void)RtlConvertSidToUnicodeString(&SidString1, Sid, FALSE); 122 (void)RtlConvertSidToUnicodeString(&SidString2, ExpectedSid, FALSE); 123 KmtOk(0, FileAndLine, "Got %wZ, expected %wZ\n", &SidString1, &SidString2); 124 } 125 } 126 127 VOID 128 VCheckAcl__( 129 _In_ PACL Acl, 130 _In_ ULONG AceCount, 131 _In_ PCSTR FileAndLine, 132 _In_ va_list Arguments) 133 { 134 ULONG i; 135 ULONG Offset; 136 PACE_HEADER AceHeader; 137 INT AceType; 138 INT AceFlags; 139 ACCESS_MASK Mask; 140 PISID Sid; 141 PACCESS_ALLOWED_ACE AllowedAce; 142 PACCESS_DENIED_ACE DeniedAce; 143 PSYSTEM_AUDIT_ACE AuditAce; 144 145 KmtOk(Acl != NULL, FileAndLine, "Acl is NULL\n"); 146 if (KmtSkip(Acl != NULL, FileAndLine, "No ACL\n")) 147 return; 148 KmtOk((ULONG_PTR)Acl % sizeof(ULONG) == 0, FileAndLine, "Unaligned ACL %p\n", Acl); 149 KmtOk(Acl->AclRevision == ACL_REVISION, FileAndLine, "AclRevision is %u\n", Acl->AclRevision); 150 KmtOk(Acl->Sbz1 == 0, FileAndLine, "Sbz1 is %u\n", Acl->Sbz1); 151 KmtOk(Acl->Sbz2 == 0, FileAndLine, "Sbz2 is %u\n", Acl->Sbz2); 152 KmtOk(Acl->AclSize >= sizeof(*Acl), FileAndLine, "AclSize too small: %u\n", Acl->AclSize); 153 KmtOk(Acl->AceCount == AceCount, FileAndLine, "AceCount is %u, expected %lu\n", Acl->AceCount, AceCount); 154 Offset = sizeof(*Acl); 155 for (i = 0; i < Acl->AceCount; i++) 156 { 157 KmtOk(Acl->AclSize >= Offset + sizeof(*AceHeader), FileAndLine, "AclSize too small (%u) at Offset %lu, ACE #%lu\n", Acl->AclSize, Offset, i); 158 if (Acl->AclSize < Offset + sizeof(*AceHeader)) 159 break; 160 AceHeader = (PACE_HEADER)((PUCHAR)Acl + Offset); 161 KmtOk((ULONG_PTR)AceHeader % sizeof(ULONG) == 0, FileAndLine, "[%lu] Unaligned ACE %p\n", i, AceHeader); 162 KmtOk(AceHeader->AceSize % sizeof(ULONG) == 0, FileAndLine, "[%lu] Unaligned ACE size %u\n", i, AceHeader->AceSize); 163 KmtOk(Acl->AclSize >= Offset + AceHeader->AceSize, FileAndLine, "[%lu] AclSize too small (%u) at Offset %lu\n", i, Acl->AclSize, Offset); 164 if (Acl->AclSize < Offset + AceHeader->AceSize) 165 break; 166 Offset += AceHeader->AceSize; 167 if (i >= AceCount) 168 continue; 169 AceType = va_arg(Arguments, INT); 170 AceFlags = va_arg(Arguments, INT); 171 KmtOk(AceHeader->AceType == AceType, FileAndLine, "[%lu] AceType is %u, expected %u\n", i, AceHeader->AceType, AceType); 172 KmtOk(AceHeader->AceFlags == AceFlags, FileAndLine, "[%lu] AceFlags is 0x%x, expected 0x%x\n", i, AceHeader->AceFlags, AceFlags); 173 if (AceType == ACCESS_ALLOWED_ACE_TYPE) 174 { 175 Sid = va_arg(Arguments, PSID); 176 Mask = va_arg(Arguments, INT); 177 KmtOk(AceHeader->AceSize >= sizeof(*AllowedAce), FileAndLine, "[%lu] AllowedAce AceSize too small: %u\n", i, AceHeader->AceSize); 178 if (AceHeader->AceSize < sizeof(*AllowedAce)) 179 continue; 180 AllowedAce = (PACCESS_ALLOWED_ACE)AceHeader; 181 KmtOk(AllowedAce->Mask == Mask, FileAndLine, "[%lu] AllowedAce Mask is 0x%lx, expected 0x%lx\n", i, AllowedAce->Mask, Mask); 182 CheckSid__((PSID)&AllowedAce->SidStart, 183 AceHeader->AceSize - FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart), 184 Sid, 185 FileAndLine); 186 } 187 else if (AceType == ACCESS_DENIED_ACE_TYPE) 188 { 189 Sid = va_arg(Arguments, PSID); 190 Mask = va_arg(Arguments, INT); 191 KmtOk(AceHeader->AceSize >= sizeof(*DeniedAce), FileAndLine, "[%lu] DeniedAce AceSize too small: %u\n", i, AceHeader->AceSize); 192 if (AceHeader->AceSize < sizeof(*DeniedAce)) 193 continue; 194 DeniedAce = (PACCESS_DENIED_ACE)AceHeader; 195 KmtOk(DeniedAce->Mask == Mask, FileAndLine, "[%lu] DeniedAce Mask is 0x%lx, expected 0x%lx\n", i, DeniedAce->Mask, Mask); 196 CheckSid__((PSID)&DeniedAce->SidStart, 197 AceHeader->AceSize - FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart), 198 Sid, 199 FileAndLine); 200 } 201 else if (AceType == SYSTEM_AUDIT_ACE_TYPE) 202 { 203 Sid = va_arg(Arguments, PSID); 204 Mask = va_arg(Arguments, INT); 205 KmtOk(AceHeader->AceSize >= sizeof(*AuditAce), FileAndLine, "[%lu] AuditAce AceSize too small: %u\n", i, AceHeader->AceSize); 206 if (AceHeader->AceSize < sizeof(*AuditAce)) 207 continue; 208 AuditAce = (PSYSTEM_AUDIT_ACE)AceHeader; 209 KmtOk(AuditAce->Mask == Mask, FileAndLine, "[%lu] AuditAce Mask is 0x%lx, expected 0x%lx\n", i, AuditAce->Mask, Mask); 210 CheckSid__((PSID)&AuditAce->SidStart, 211 AceHeader->AceSize - FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart), 212 Sid, 213 FileAndLine); 214 } 215 } 216 } 217 218 VOID 219 CheckAcl__( 220 _In_ PACL Acl, 221 _In_ ULONG AceCount, 222 _In_ PCSTR FileAndLine, 223 ...) 224 { 225 va_list Arguments; 226 227 va_start(Arguments, FileAndLine); 228 VCheckAcl__(Acl, AceCount, FileAndLine, Arguments); 229 va_end(Arguments); 230 } 231