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
RtlxAddAuditAccessAceEx(_Inout_ PACL Acl,_In_ ULONG Revision,_In_ ULONG Flags,_In_ ACCESS_MASK AccessMask,_In_ PSID Sid,_In_ BOOLEAN Success,_In_ BOOLEAN Failure)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
RtlxAddMandatoryLabelAceEx(_Inout_ PACL Acl,_In_ ULONG Revision,_In_ ULONG Flags,_In_ ACCESS_MASK AccessMask,_In_ PSID Sid)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
CheckSid__(_In_ PSID Sid,_In_ ULONG SidSize,_In_ PISID ExpectedSid,_In_ PCSTR FileAndLine)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
VCheckAcl__(_In_ PACL Acl,_In_ ULONG AceCount,_In_ PCSTR FileAndLine,_In_ va_list Arguments)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
CheckAcl__(_In_ PACL Acl,_In_ ULONG AceCount,_In_ PCSTR FileAndLine,...)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