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