1c2c66affSColin Finck /*
2c2c66affSColin Finck * PROJECT: ReactOS kernel-mode tests
3c2c66affSColin Finck * LICENSE: GPLv2+ - See COPYING in the top level directory
4c2c66affSColin Finck * PURPOSE: Kernel-Mode Test Suite Process Notification Routines test
5c2c66affSColin Finck * PROGRAMMER: Constantine Belev (Moscow State Technical University)
6c2c66affSColin Finck * Denis Grishin (Moscow State Technical University)
7c2c66affSColin Finck * Egor Sinitsyn (Moscow State Technical University)
8c2c66affSColin Finck */
9c2c66affSColin Finck
10c2c66affSColin Finck #include <kmt_test.h>
11c2c66affSColin Finck #include <ntifs.h>
12c2c66affSColin Finck
13c2c66affSColin Finck #define NDEBUG
14c2c66affSColin Finck #include <debug.h>
15c2c66affSColin Finck
1664a6bd4cSThomas Faber // Copied from PspProcessMapping -- although the values don't matter much for
1764a6bd4cSThomas Faber // the most part.
1864a6bd4cSThomas Faber static GENERIC_MAPPING ProcessGenericMapping =
1964a6bd4cSThomas Faber {
2064a6bd4cSThomas Faber STANDARD_RIGHTS_READ | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
2164a6bd4cSThomas Faber STANDARD_RIGHTS_WRITE | PROCESS_CREATE_PROCESS | PROCESS_CREATE_THREAD |
2264a6bd4cSThomas Faber PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_DUP_HANDLE |
2364a6bd4cSThomas Faber PROCESS_TERMINATE | PROCESS_SET_QUOTA | PROCESS_SET_INFORMATION |
2464a6bd4cSThomas Faber PROCESS_SUSPEND_RESUME,
2564a6bd4cSThomas Faber STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE,
2664a6bd4cSThomas Faber PROCESS_ALL_ACCESS
2764a6bd4cSThomas Faber };
2864a6bd4cSThomas Faber
29c2c66affSColin Finck //------------------------------------------------------------------------------//
30c2c66affSColin Finck // Testing Functions //
31c2c66affSColin Finck //------------------------------------------------------------------------------//
32c2c66affSColin Finck
33c2c66affSColin Finck // Testing function for SQIT
34c2c66affSColin Finck
TestsSeQueryInformationToken(PACCESS_TOKEN Token)35c2c66affSColin Finck void TestsSeQueryInformationToken(PACCESS_TOKEN Token)
36c2c66affSColin Finck {
37c2c66affSColin Finck NTSTATUS Status;
38c2c66affSColin Finck PVOID Buffer = NULL;
39c2c66affSColin Finck PSID sid;
40c2c66affSColin Finck PTOKEN_OWNER Towner;
41c2c66affSColin Finck PTOKEN_DEFAULT_DACL TDefDacl;
42c2c66affSColin Finck PTOKEN_GROUPS TGroups;
43c2c66affSColin Finck ULONG GroupCount;
44c2c66affSColin Finck PACL acl;
45c2c66affSColin Finck PTOKEN_STATISTICS TStats;
46c2c66affSColin Finck PTOKEN_TYPE TType;
47c2c66affSColin Finck PTOKEN_USER TUser;
48c2c66affSColin Finck BOOLEAN Flag;
49c2c66affSColin Finck ULONG i;
50c2c66affSColin Finck
51c2c66affSColin Finck //----------------------------------------------------------------//
52c2c66affSColin Finck // Testing SeQueryInformationToken with various args //
53c2c66affSColin Finck //----------------------------------------------------------------//
54c2c66affSColin Finck
55c2c66affSColin Finck ok(Token != NULL, "Token is not captured. Testing SQIT interrupted\n\n");
56c2c66affSColin Finck
57c2c66affSColin Finck if (Token == NULL) return;
58c2c66affSColin Finck
59c2c66affSColin Finck Status = SeQueryInformationToken(Token, TokenOwner, &Buffer);
60c2c66affSColin Finck ok((Status == STATUS_SUCCESS), "SQIT with TokenOwner arg fails with status 0x%08X\n", Status);
61c2c66affSColin Finck if (Status == STATUS_SUCCESS)
62c2c66affSColin Finck {
63c2c66affSColin Finck ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenOwner arg. But Buffer == NULL\n");
64c2c66affSColin Finck
65c2c66affSColin Finck if (Buffer)
66c2c66affSColin Finck {
67c2c66affSColin Finck Towner = (TOKEN_OWNER *)Buffer;
68c2c66affSColin Finck sid = Towner->Owner;
69c2c66affSColin Finck ok((RtlValidSid(sid) == TRUE), "TokenOwner's SID is not a valid SID\n");
70c2c66affSColin Finck ExFreePool(Buffer);
71c2c66affSColin Finck }
72c2c66affSColin Finck }
73c2c66affSColin Finck
74c2c66affSColin Finck //----------------------------------------------------------------//
75c2c66affSColin Finck
76c2c66affSColin Finck Buffer = NULL;
77c2c66affSColin Finck Status = SeQueryInformationToken(Token, TokenDefaultDacl, &Buffer);
78c2c66affSColin Finck ok(Status == STATUS_SUCCESS, "SQIT with TokenDefaultDacl fails with status 0x%08X\n", Status);
79c2c66affSColin Finck if (Status == STATUS_SUCCESS)
80c2c66affSColin Finck {
81c2c66affSColin Finck ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenDefaultDacl arg. But Buffer == NULL\n");
82c2c66affSColin Finck if (Buffer)
83c2c66affSColin Finck {
84c2c66affSColin Finck TDefDacl = (PTOKEN_DEFAULT_DACL)Buffer;
85c2c66affSColin Finck acl = TDefDacl->DefaultDacl;
86c2c66affSColin Finck ok(((acl->AclRevision == ACL_REVISION || acl->AclRevision == ACL_REVISION_DS) == TRUE), "DACL is invalid\n");
87c2c66affSColin Finck ExFreePool(Buffer);
88c2c66affSColin Finck }
89c2c66affSColin Finck }
90c2c66affSColin Finck
91c2c66affSColin Finck //----------------------------------------------------------------//
92c2c66affSColin Finck
93c2c66affSColin Finck Buffer = NULL;
94c2c66affSColin Finck Status = SeQueryInformationToken(Token, TokenGroups, &Buffer);
95c2c66affSColin Finck ok(Status == STATUS_SUCCESS, "SQIT with TokenGroups fails with status 0x%08X\n", Status);
96c2c66affSColin Finck if (Status == STATUS_SUCCESS)
97c2c66affSColin Finck {
98c2c66affSColin Finck ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenGroups arg. But Buffer == NULL\n");
99c2c66affSColin Finck if (Buffer)
100c2c66affSColin Finck {
101c2c66affSColin Finck TGroups = (PTOKEN_GROUPS)Buffer;
102c2c66affSColin Finck GroupCount = TGroups->GroupCount;
103c2c66affSColin Finck Flag = TRUE;
104c2c66affSColin Finck for (i = 0; i < GroupCount; i++)
105c2c66affSColin Finck {
106c2c66affSColin Finck sid = TGroups->Groups[i].Sid;
107c2c66affSColin Finck if (!RtlValidSid(sid))
108c2c66affSColin Finck {
109c2c66affSColin Finck Flag = FALSE;
110c2c66affSColin Finck break;
111c2c66affSColin Finck }
112c2c66affSColin Finck }
113c2c66affSColin Finck ok((Flag == TRUE), "TokenGroup's SIDs are not valid\n");
114c2c66affSColin Finck ExFreePool(Buffer);
115c2c66affSColin Finck }
116c2c66affSColin Finck }
117c2c66affSColin Finck
118c2c66affSColin Finck //----------------------------------------------------------------//
119c2c66affSColin Finck
120ac976626SGeorge Bișoc // Call SQIT with TokenImpersonationLevel argument. Although our token
121ac976626SGeorge Bișoc // is not an impersonation token, the call will outright fail.
122c2c66affSColin Finck
123c2c66affSColin Finck Buffer = NULL;
124c2c66affSColin Finck Status = SeQueryInformationToken(Token, TokenImpersonationLevel, &Buffer);
125ac976626SGeorge Bișoc ok(Status == STATUS_INVALID_INFO_CLASS, "SQIT with TokenImpersonationLevel must return STATUS_INVALID_INFO_CLASS but got 0x%08X\n", Status);
126ac976626SGeorge Bișoc ok(Buffer == NULL, "SQIT has failed to query the impersonation level but buffer is not NULL!\n");
127c2c66affSColin Finck
128c2c66affSColin Finck //----------------------------------------------------------------//
129c2c66affSColin Finck
130c2c66affSColin Finck // Call SQIT with the 4 classes (TokenOrigin, TokenGroupsAndPrivileges,
131c2c66affSColin Finck // TokenRestrictedSids and TokenSandBoxInert) are not supported by
132c2c66affSColin Finck // SeQueryInformationToken (only NtQueryInformationToken supports them).
133c2c66affSColin Finck //
134c2c66affSColin Finck
135c2c66affSColin Finck Buffer = NULL;
136c2c66affSColin Finck Status = SeQueryInformationToken(Token, TokenOrigin, &Buffer);
137c2c66affSColin Finck ok(Status == STATUS_INVALID_INFO_CLASS, "SQIT with TokenOrigin failed with Status 0x%08X; expected STATUS_INVALID_INFO_CLASS\n", Status);
138c2c66affSColin Finck ok(Buffer == NULL, "Wrong. SQIT call failed. But Buffer != NULL\n");
139c2c66affSColin Finck
140c2c66affSColin Finck Buffer = NULL;
141c2c66affSColin Finck Status = SeQueryInformationToken(Token, TokenGroupsAndPrivileges, &Buffer);
142c2c66affSColin Finck ok(Status == STATUS_INVALID_INFO_CLASS, "SQIT with TokenGroupsAndPrivileges failed with Status 0x%08X; expected STATUS_INVALID_INFO_CLASS\n", Status);
143c2c66affSColin Finck ok(Buffer == NULL, "Wrong. SQIT call failed. But Buffer != NULL\n");
144c2c66affSColin Finck
145c2c66affSColin Finck Buffer = NULL;
146c2c66affSColin Finck Status = SeQueryInformationToken(Token, TokenRestrictedSids, &Buffer);
147c2c66affSColin Finck ok(Status == STATUS_INVALID_INFO_CLASS, "SQIT with TokenRestrictedSids failed with Status 0x%08X; expected STATUS_INVALID_INFO_CLASS\n", Status);
148c2c66affSColin Finck ok(Buffer == NULL, "Wrong. SQIT call failed. But Buffer != NULL\n");
149c2c66affSColin Finck
150c2c66affSColin Finck Buffer = NULL;
151c2c66affSColin Finck Status = SeQueryInformationToken(Token, TokenSandBoxInert, &Buffer);
152c2c66affSColin Finck ok(Status == STATUS_INVALID_INFO_CLASS, "SQIT with TokenSandBoxInert failed with Status 0x%08X; expected STATUS_INVALID_INFO_CLASS\n", Status);
153c2c66affSColin Finck ok(Buffer == NULL, "Wrong. SQIT call failed. But Buffer != NULL\n");
154c2c66affSColin Finck
155c2c66affSColin Finck //----------------------------------------------------------------//
156c2c66affSColin Finck
157c2c66affSColin Finck Buffer = NULL;
158c2c66affSColin Finck Status = SeQueryInformationToken(Token, TokenStatistics, &Buffer);
159c2c66affSColin Finck ok(Status == STATUS_SUCCESS, "SQIT with TokenStatistics fails with status 0x%08X\n", Status);
160c2c66affSColin Finck if (Status == STATUS_SUCCESS)
161c2c66affSColin Finck {
162c2c66affSColin Finck ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenStatistics arg. But Buffer == NULL\n");
163c2c66affSColin Finck if (Buffer)
164c2c66affSColin Finck {
165c2c66affSColin Finck TStats = (PTOKEN_STATISTICS)Buffer;
166c2c66affSColin Finck // just put 0 into 1st arg or use trace to print TokenStatistics
167c2c66affSColin Finck ok(1, "print statistics:\n\tTokenID = %u_%d\n\tSecurityImperLevel = %d\n\tPrivCount = %d\n\tGroupCount = %d\n\n", TStats->TokenId.LowPart,
168c2c66affSColin Finck TStats->TokenId.HighPart,
169c2c66affSColin Finck TStats->ImpersonationLevel,
170c2c66affSColin Finck TStats->PrivilegeCount,
171c2c66affSColin Finck TStats->GroupCount
172c2c66affSColin Finck );
173c2c66affSColin Finck ExFreePool(Buffer);
174c2c66affSColin Finck }
175c2c66affSColin Finck } else {
176c2c66affSColin Finck ok(Buffer == NULL, "Wrong. SQIT call failed. But Buffer != NULL\n");
177c2c66affSColin Finck }
178c2c66affSColin Finck
179c2c66affSColin Finck //----------------------------------------------------------------//
180c2c66affSColin Finck
181c2c66affSColin Finck Buffer = NULL;
182c2c66affSColin Finck Status = SeQueryInformationToken(Token, TokenType, &Buffer);
183c2c66affSColin Finck ok(Status == STATUS_SUCCESS, "SQIT with TokenType fails with status 0x%08X\n", Status);
184c2c66affSColin Finck if (Status == STATUS_SUCCESS)
185c2c66affSColin Finck {
186c2c66affSColin Finck ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenType arg. But Buffer == NULL\n");
187c2c66affSColin Finck if (Buffer)
188c2c66affSColin Finck {
189c2c66affSColin Finck TType = (PTOKEN_TYPE)Buffer;
190c2c66affSColin Finck ok((*TType == TokenPrimary || *TType == TokenImpersonation), "TokenType in not a primary nor impersonation. FAILED\n");
191c2c66affSColin Finck ExFreePool(Buffer);
192c2c66affSColin Finck }
193c2c66affSColin Finck }
194c2c66affSColin Finck
195c2c66affSColin Finck //----------------------------------------------------------------//
196c2c66affSColin Finck
197c2c66affSColin Finck Buffer = NULL;
198c2c66affSColin Finck Status = SeQueryInformationToken(Token, TokenUser, &Buffer);
199c2c66affSColin Finck ok(Status == STATUS_SUCCESS, "SQIT with TokenUser fails\n");
200c2c66affSColin Finck if (Status == STATUS_SUCCESS)
201c2c66affSColin Finck {
202c2c66affSColin Finck ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenUser arg. But Buffer == NULL\n");
203c2c66affSColin Finck if (Buffer)
204c2c66affSColin Finck {
205c2c66affSColin Finck TUser = (PTOKEN_USER)Buffer;
206c2c66affSColin Finck ok(RtlValidSid(TUser->User.Sid), "TokenUser has an invalid Sid\n");
207c2c66affSColin Finck ExFreePool(Buffer);
208c2c66affSColin Finck }
209c2c66affSColin Finck }
210c2c66affSColin Finck
211c2c66affSColin Finck //----------------------------------------------------------------//
212c2c66affSColin Finck
213c2c66affSColin Finck Buffer = NULL;
214c2c66affSColin Finck Status = SeQueryInformationToken(Token, TokenSandBoxInert, &Buffer);
215c2c66affSColin Finck ok(Status != STATUS_SUCCESS, "SQIT must fail with wrong TOKEN_INFORMATION_CLASS arg\n");
216c2c66affSColin Finck }
217c2c66affSColin Finck
218c2c66affSColin Finck //------------------------------------------------------------------------------//
219c2c66affSColin Finck
220c2c66affSColin Finck //------------------------------------------------------------------------------//
221c2c66affSColin Finck // Body of the main test //
222c2c66affSColin Finck //------------------------------------------------------------------------------//
223c2c66affSColin Finck
START_TEST(SeQueryInfoToken)224c2c66affSColin Finck START_TEST(SeQueryInfoToken)
225c2c66affSColin Finck {
226c2c66affSColin Finck PACCESS_STATE AccessState;
227c2c66affSColin Finck ACCESS_MASK AccessMask = MAXIMUM_ALLOWED;
228c2c66affSColin Finck ACCESS_MASK DesiredAccess = MAXIMUM_ALLOWED;
229c2c66affSColin Finck NTSTATUS Status = STATUS_SUCCESS;
230c2c66affSColin Finck PAUX_ACCESS_DATA AuxData = NULL;
231c2c66affSColin Finck PPRIVILEGE_SET NewPrivilegeSet;
232ff410211SThomas Faber ULONG InitialPrivilegeCount;
233c2c66affSColin Finck BOOLEAN Checker;
234c2c66affSColin Finck PPRIVILEGE_SET Privileges = NULL;
235c2c66affSColin Finck PSECURITY_SUBJECT_CONTEXT SubjectContext = NULL;
236c2c66affSColin Finck PACCESS_TOKEN Token = NULL;
237c2c66affSColin Finck PTOKEN_PRIVILEGES TPrivileges;
238c2c66affSColin Finck PVOID Buffer;
239c2c66affSColin Finck ULONG i;
240c2c66affSColin Finck
241c2c66affSColin Finck SubjectContext = ExAllocatePool(PagedPool, sizeof(SECURITY_SUBJECT_CONTEXT));
242c2c66affSColin Finck
243c2c66affSColin Finck SeCaptureSubjectContext(SubjectContext);
244c2c66affSColin Finck SeLockSubjectContext(SubjectContext);
245c2c66affSColin Finck Token = SeQuerySubjectContextToken(SubjectContext);
246c2c66affSColin Finck
247c2c66affSColin Finck // Testing SQIT with current Token
248c2c66affSColin Finck TestsSeQueryInformationToken(Token);
249c2c66affSColin Finck
250c2c66affSColin Finck //----------------------------------------------------------------//
251c2c66affSColin Finck // Creating an ACCESS_STATE structure //
252c2c66affSColin Finck //----------------------------------------------------------------//
253c2c66affSColin Finck
254c2c66affSColin Finck AccessState = ExAllocatePool(PagedPool, sizeof(ACCESS_STATE));
25564a6bd4cSThomas Faber // AUX_ACCESS_DATA gets larger in newer Windows version.
25664a6bd4cSThomas Faber // This is the largest known size, found in Windows 10/11.
25764a6bd4cSThomas Faber AuxData = ExAllocatePoolZero(PagedPool, 0xE0, 'QSmK');
258c2c66affSColin Finck
259c2c66affSColin Finck Status = SeCreateAccessState(AccessState,
26064a6bd4cSThomas Faber AuxData,
261c2c66affSColin Finck DesiredAccess,
26264a6bd4cSThomas Faber &ProcessGenericMapping
263c2c66affSColin Finck );
264c2c66affSColin Finck
265c2c66affSColin Finck ok((Status == STATUS_SUCCESS), "SeCreateAccessState failed with Status 0x%08X\n", Status);
266c2c66affSColin Finck
267c2c66affSColin Finck SeCaptureSubjectContext(&AccessState->SubjectSecurityContext);
268c2c66affSColin Finck SeLockSubjectContext(&AccessState->SubjectSecurityContext);
269c2c66affSColin Finck Token = SeQuerySubjectContextToken(&AccessState->SubjectSecurityContext);
270c2c66affSColin Finck
271c2c66affSColin Finck // Testing SQIT with AccessState Token
272c2c66affSColin Finck TestsSeQueryInformationToken(Token);
273c2c66affSColin Finck
274c2c66affSColin Finck //----------------------------------------------------------------//
275c2c66affSColin Finck // Testing other functions //
276c2c66affSColin Finck //----------------------------------------------------------------//
277c2c66affSColin Finck
278c2c66affSColin Finck //----------------------------------------------------------------//
279c2c66affSColin Finck // Testing SeAppendPrivileges //
280c2c66affSColin Finck //----------------------------------------------------------------//
281c2c66affSColin Finck
282156053caSThomas Faber InitialPrivilegeCount = AuxData->PrivilegesUsed->PrivilegeCount;
283ff410211SThomas Faber trace("Initial privilege count = %lu\n", InitialPrivilegeCount);
284c2c66affSColin Finck
285c2c66affSColin Finck // Testing SeAppendPrivileges. Must change PrivilegeCount to 2 (1 + 1)
286c2c66affSColin Finck
287206df96bSThomas Faber NewPrivilegeSet = ExAllocatePoolZero(PagedPool,
288206df96bSThomas Faber FIELD_OFFSET(PRIVILEGE_SET, Privilege[1]),
289206df96bSThomas Faber 'QSmK');
290c2c66affSColin Finck NewPrivilegeSet->PrivilegeCount = 1;
291c2c66affSColin Finck
292c2c66affSColin Finck Status = SeAppendPrivileges(AccessState, NewPrivilegeSet);
293c2c66affSColin Finck ok(Status == STATUS_SUCCESS, "SeAppendPrivileges failed\n");
294156053caSThomas Faber ok_eq_ulong(AuxData->PrivilegesUsed->PrivilegeCount, InitialPrivilegeCount + 1);
295206df96bSThomas Faber ExFreePoolWithTag(NewPrivilegeSet, 'QSmK');
296c2c66affSColin Finck
297c2c66affSColin Finck //----------------------------------------------------------------//
298c2c66affSColin Finck
299c2c66affSColin Finck // Testing SeAppendPrivileges. Must change PrivilegeCount to 6 (2 + 4)
300c2c66affSColin Finck
301206df96bSThomas Faber NewPrivilegeSet = ExAllocatePoolZero(PagedPool,
302206df96bSThomas Faber FIELD_OFFSET(PRIVILEGE_SET, Privilege[4]),
303206df96bSThomas Faber 'QSmK');
304c2c66affSColin Finck NewPrivilegeSet->PrivilegeCount = 4;
305c2c66affSColin Finck
306c2c66affSColin Finck Status = SeAppendPrivileges(AccessState, NewPrivilegeSet);
307c2c66affSColin Finck ok(Status == STATUS_SUCCESS, "SeAppendPrivileges failed\n");
308156053caSThomas Faber ok_eq_ulong(AuxData->PrivilegesUsed->PrivilegeCount, InitialPrivilegeCount + 5);
309206df96bSThomas Faber ExFreePoolWithTag(NewPrivilegeSet, 'QSmK');
310c2c66affSColin Finck
311c2c66affSColin Finck //----------------------------------------------------------------//
312c2c66affSColin Finck // Testing SePrivilegeCheck //
313c2c66affSColin Finck //----------------------------------------------------------------//
314c2c66affSColin Finck
315c2c66affSColin Finck // KPROCESSOR_MODE is set to KernelMode ===> Always return TRUE
316156053caSThomas Faber ok(SePrivilegeCheck(AuxData->PrivilegesUsed, &(AccessState->SubjectSecurityContext), KernelMode), "SePrivilegeCheck failed with KernelMode mode arg\n");
317c2c66affSColin Finck // and call it again
318156053caSThomas Faber ok(SePrivilegeCheck(AuxData->PrivilegesUsed, &(AccessState->SubjectSecurityContext), KernelMode), "SePrivilegeCheck failed with KernelMode mode arg\n");
319c2c66affSColin Finck
320c2c66affSColin Finck //----------------------------------------------------------------//
321c2c66affSColin Finck
322c2c66affSColin Finck // KPROCESSOR_MODE is set to UserMode. Expect false
323156053caSThomas Faber ok(!SePrivilegeCheck(AuxData->PrivilegesUsed, &(AccessState->SubjectSecurityContext), UserMode), "SePrivilegeCheck unexpected success with UserMode arg\n");
324c2c66affSColin Finck
325c2c66affSColin Finck //----------------------------------------------------------------//
326c2c66affSColin Finck
327c2c66affSColin Finck //----------------------------------------------------------------//
328c2c66affSColin Finck // Testing SeFreePrivileges //
329c2c66affSColin Finck //----------------------------------------------------------------//
330c2c66affSColin Finck
331*44bdafa1SThomas Faber // FIXME: KernelMode will automatically get all access granted without
332*44bdafa1SThomas Faber // getting Privileges filled in. For UserMode, Privileges will only get
333*44bdafa1SThomas Faber // filled if either WRITE_OWNER or ACCESS_SYSTEM_SECURITY is requested
334*44bdafa1SThomas Faber // and granted. So this doesn't really test SeFreePrivileges.
335c2c66affSColin Finck Privileges = NULL;
336c2c66affSColin Finck Checker = SeAccessCheck(
337c2c66affSColin Finck AccessState->SecurityDescriptor,
338c2c66affSColin Finck &AccessState->SubjectSecurityContext,
339c2c66affSColin Finck FALSE,
340c2c66affSColin Finck AccessState->OriginalDesiredAccess,
341c2c66affSColin Finck AccessState->PreviouslyGrantedAccess,
342c2c66affSColin Finck &Privileges,
34364a6bd4cSThomas Faber &ProcessGenericMapping,
344c2c66affSColin Finck KernelMode,
345c2c66affSColin Finck &AccessMask,
346c2c66affSColin Finck &Status
347c2c66affSColin Finck );
348c2c66affSColin Finck ok(Checker, "Checker is NULL\n");
349*44bdafa1SThomas Faber ok(Privileges == NULL, "Privileges is not NULL\n");
350c2c66affSColin Finck if (Privileges)
351c2c66affSColin Finck {
352156053caSThomas Faber trace("AuxData->PrivilegesUsed->PrivilegeCount = %d ; Privileges->PrivilegeCount = %d\n",
353156053caSThomas Faber AuxData->PrivilegesUsed->PrivilegeCount, Privileges->PrivilegeCount);
354c2c66affSColin Finck }
355c2c66affSColin Finck if (Privileges) SeFreePrivileges(Privileges);
356c2c66affSColin Finck
357c2c66affSColin Finck
358c2c66affSColin Finck //----------------------------------------------------------------//
359c2c66affSColin Finck // Testing SePrivilegeCheck //
360c2c66affSColin Finck //----------------------------------------------------------------//
361c2c66affSColin Finck // I'm trying to make success call of SePrivilegeCheck from UserMode
362c2c66affSColin Finck // If we sets Privileges properly, can we expect true from SePrivilegeCheck?
363c2c66affSColin Finck // answer: yes
364c2c66affSColin Finck // This test demonstrates it
365c2c66affSColin Finck
366c2c66affSColin Finck Buffer = NULL;
367c2c66affSColin Finck Status = SeQueryInformationToken(Token, TokenPrivileges, &Buffer);
368c2c66affSColin Finck if (Status == STATUS_SUCCESS)
369c2c66affSColin Finck {
370c2c66affSColin Finck ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenPrivileges arg. But Buffer == NULL\n");
371c2c66affSColin Finck if (Buffer)
372c2c66affSColin Finck {
373c2c66affSColin Finck TPrivileges = (PTOKEN_PRIVILEGES)(Buffer);
374c2c66affSColin Finck //trace("TPCount = %u\n\n", TPrivileges->PrivilegeCount);
375c2c66affSColin Finck
376206df96bSThomas Faber NewPrivilegeSet = ExAllocatePoolZero(PagedPool,
377206df96bSThomas Faber FIELD_OFFSET(PRIVILEGE_SET, Privilege[14]),
378206df96bSThomas Faber 'QSmK');
379c2c66affSColin Finck NewPrivilegeSet->PrivilegeCount = 14;
380c2c66affSColin Finck
381c2c66affSColin Finck ok((SeAppendPrivileges(AccessState, NewPrivilegeSet)) == STATUS_SUCCESS, "SeAppendPrivileges failed\n");
382156053caSThomas Faber ok_eq_ulong(AuxData->PrivilegesUsed->PrivilegeCount, InitialPrivilegeCount + 19);
383206df96bSThomas Faber ExFreePoolWithTag(NewPrivilegeSet, 'QSmK');
384156053caSThomas Faber for (i = 0; i < AuxData->PrivilegesUsed->PrivilegeCount; i++)
385c2c66affSColin Finck {
386156053caSThomas Faber AuxData->PrivilegesUsed->Privilege[i].Attributes = TPrivileges->Privileges[i].Attributes;
387156053caSThomas Faber AuxData->PrivilegesUsed->Privilege[i].Luid = TPrivileges->Privileges[i].Luid;
388c2c66affSColin Finck }
389156053caSThomas Faber //trace("AccessState->privCount = %u\n\n", ((PAUX_ACCESS_DATA)(AccessState->AuxData))->PrivilegesUsed->PrivilegeCount);
390c2c66affSColin Finck
391156053caSThomas Faber ok(SePrivilegeCheck(AuxData->PrivilegesUsed, &(AccessState->SubjectSecurityContext), UserMode), "SePrivilegeCheck fails in UserMode, but I wish it will success\n");
392c2c66affSColin Finck }
393c2c66affSColin Finck }
394c2c66affSColin Finck
395c2c66affSColin Finck // Call SeFreePrivileges again
396c2c66affSColin Finck
397*44bdafa1SThomas Faber // FIXME: See other SeAccessCheck call above, we're not really testing
398*44bdafa1SThomas Faber // SeFreePrivileges here.
399c2c66affSColin Finck Privileges = NULL;
400c2c66affSColin Finck Checker = SeAccessCheck(
401c2c66affSColin Finck AccessState->SecurityDescriptor,
402c2c66affSColin Finck &AccessState->SubjectSecurityContext,
403c2c66affSColin Finck TRUE,
404c2c66affSColin Finck AccessState->OriginalDesiredAccess,
405c2c66affSColin Finck AccessState->PreviouslyGrantedAccess,
406c2c66affSColin Finck &Privileges,
40764a6bd4cSThomas Faber &ProcessGenericMapping,
408c2c66affSColin Finck KernelMode,
409c2c66affSColin Finck &AccessMask,
410c2c66affSColin Finck &Status
411c2c66affSColin Finck );
412c2c66affSColin Finck ok(Checker, "Checker is NULL\n");
413*44bdafa1SThomas Faber ok(Privileges == NULL, "Privileges is not NULL\n");
414c2c66affSColin Finck if (Privileges)
415c2c66affSColin Finck {
416156053caSThomas Faber trace("AuxData->PrivilegesUsed->PrivilegeCount = %d ; Privileges->PrivilegeCount = %d\n",
417156053caSThomas Faber AuxData->PrivilegesUsed->PrivilegeCount, Privileges->PrivilegeCount);
418c2c66affSColin Finck }
419c2c66affSColin Finck if (Privileges) SeFreePrivileges(Privileges);
420c2c66affSColin Finck
421c2c66affSColin Finck //----------------------------------------------------------------//
422c2c66affSColin Finck // Missing for now //
423c2c66affSColin Finck //----------------------------------------------------------------//
424c2c66affSColin Finck
425c2c66affSColin Finck SeUnlockSubjectContext(&AccessState->SubjectSecurityContext);
426c2c66affSColin Finck SeUnlockSubjectContext(SubjectContext);
427c2c66affSColin Finck
428c2c66affSColin Finck SeDeleteAccessState(AccessState);
429c2c66affSColin Finck
430c2c66affSColin Finck if (SubjectContext) ExFreePool(SubjectContext);
43164a6bd4cSThomas Faber if (AuxData) ExFreePoolWithTag(AuxData, 'QSmK');
432c2c66affSColin Finck if (AccessState) ExFreePool(AccessState);
433c2c66affSColin Finck }
434