[KMTESTS]
[reactos.git] / rostests / kmtests / ntos_se / SeQueryInfoToken.c
1 /*
2 * PROJECT: ReactOS kernel-mode tests
3 * LICENSE: GPLv2+ - See COPYING in the top level directory
4 * PURPOSE: Kernel-Mode Test Suite Process Notification Routines test
5 * PROGRAMMER: Constantine Belev (Moscow State Technical University)
6 * Denis Grishin (Moscow State Technical University)
7 * Egor Sinitsyn (Moscow State Technical University)
8 */
9
10 #include <kmt_test.h>
11 #include <ntifs.h>
12
13 #define NDEBUG
14 #include <debug.h>
15
16 //------------------------------------------------------------------------------//
17 // Testing Functions //
18 //------------------------------------------------------------------------------//
19
20 // Testing function for SQIT
21
22 void TestsSeQueryInformationToken(PACCESS_TOKEN Token)
23 {
24 NTSTATUS Status;
25 PVOID Buffer = NULL;
26 PSID sid;
27 PTOKEN_OWNER Towner;
28 PTOKEN_DEFAULT_DACL TDefDacl;
29 PTOKEN_GROUPS TGroups;
30 ULONG GroupCount;
31 PACL acl;
32 PTOKEN_STATISTICS TStats;
33 PTOKEN_TYPE TType;
34 PTOKEN_USER TUser;
35 BOOLEAN Flag;
36 ULONG i;
37
38 //----------------------------------------------------------------//
39 // Testing SeQueryInformationToken with various args //
40 //----------------------------------------------------------------//
41
42 ok(Token != NULL, "Token is not captured. Testing SQIT interrupted\n\n");
43
44 if (Token == NULL) return;
45
46 Status = SeQueryInformationToken(Token, TokenOwner, &Buffer);
47 ok((Status == STATUS_SUCCESS), "SQIT with TokenOwner arg fails with status 0x%X\n", Status);
48 if (Status == STATUS_SUCCESS)
49 {
50 ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenOwner arg. But Buffer = NULL\n");
51
52 if (Buffer)
53 {
54 Towner = (TOKEN_OWNER *)Buffer;
55 sid = Towner->Owner;
56 ok((RtlValidSid(sid) == TRUE), "TokenOwner's SID is not a valid SID\n");
57 ExFreePool(Buffer);
58 }
59 }
60
61 //----------------------------------------------------------------//
62
63 Buffer = NULL;
64 Status = SeQueryInformationToken(Token, TokenDefaultDacl, &Buffer);
65 ok(Status == STATUS_SUCCESS, "SQIT with TokenDefaultDacl fails with status 0x%X\n", Status);
66 if (Status == STATUS_SUCCESS)
67 {
68 ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenDefaultDacl arg. But Buffer = NULL\n");
69 if (Buffer)
70 {
71 TDefDacl = (PTOKEN_DEFAULT_DACL)Buffer;
72 acl = TDefDacl->DefaultDacl;
73 ok(((acl->AclRevision == ACL_REVISION || acl->AclRevision == ACL_REVISION_DS) == TRUE), "DACL is invalid\n");
74 ExFreePool(Buffer);
75 }
76 }
77
78 //----------------------------------------------------------------//
79
80 Buffer = NULL;
81 Status = SeQueryInformationToken(Token, TokenGroups, &Buffer);
82 ok(Status == STATUS_SUCCESS, "SQIT with TokenGroups fails with status 0x%X\n", Status);
83 if (Status == STATUS_SUCCESS)
84 {
85 ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenGroups arg. But Buffer = NULL\n");
86 if (Buffer)
87 {
88 TGroups = (PTOKEN_GROUPS)Buffer;
89 GroupCount = TGroups->GroupCount;
90 Flag = TRUE;
91 for (i = 0; i < GroupCount; i++)
92 {
93 sid = TGroups->Groups[i].Sid;
94 if (!RtlValidSid(sid))
95 {
96 Flag = FALSE;
97 break;
98 }
99 }
100 ok((Flag == TRUE), "TokenGroup's SIDs are not valid\n");
101 ExFreePool(Buffer);
102 }
103 }
104
105 //----------------------------------------------------------------//
106
107 // Call SQIT with TokenImpersonationLevel argument
108 //
109 // What's up? Why SQIT fails with right arg?
110
111 Buffer = NULL;
112 Status = SeQueryInformationToken(Token, TokenImpersonationLevel, &Buffer);
113 ok(Status == STATUS_SUCCESS, "SQIT with TokenImpersonationLevel fails with status 0x%X\n", Status);
114
115 Buffer = NULL;
116 Status = SeQueryInformationToken(Token, TokenImpersonationLevel, &Buffer);
117 ok(Status == STATUS_SUCCESS, "and again: SQIT with TokenImpersonationLevel fails with status 0x%X\n", Status);
118 if (Status == STATUS_SUCCESS)
119 {
120 ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenImpersonationLevel arg. But Buffer = NULL\n");
121 } else {
122 ok(Buffer == NULL, "Wrong. SQIT call is't success. But Buffer != NULL\n");
123 }
124
125 //----------------------------------------------------------------//
126
127 Buffer = NULL;
128 Status = SeQueryInformationToken(Token, TokenStatistics, &Buffer);
129 ok(Status == STATUS_SUCCESS, "SQIT with TokenStatistics fails with status 0x%X\n", Status);
130 if (Status == STATUS_SUCCESS)
131 {
132 ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenStatistics arg. But Buffer = NULL\n");
133 if (Buffer)
134 {
135 TStats = (PTOKEN_STATISTICS)Buffer;
136 // just put 0 into 1st arg or use trace to print TokenStatistics f
137 ok(1, "print statistics:\n\tTokenID = %u_%d\n\tSecurityImperLevel = %d\n\tPrivCount = %d\n\tGroupCount = %d\n\n", TStats->TokenId.LowPart,
138 TStats->TokenId.HighPart,
139 TStats->ImpersonationLevel,
140 TStats->PrivilegeCount,
141 TStats->GroupCount
142 );
143 ExFreePool(TStats);
144 }
145 } else {
146 ok(Buffer == NULL, "Wrong. SQIT call is't success. But Buffer != NULL\n");
147 }
148
149 //----------------------------------------------------------------//
150
151 Buffer = NULL;
152 Status = SeQueryInformationToken(Token, TokenType, &Buffer);
153 ok(Status == STATUS_SUCCESS, "SQIT with TokenType fails with status 0x%X\n", Status);
154 if (Status == STATUS_SUCCESS)
155 {
156 ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenType arg. But Buffer = NULL\n");
157 if (Buffer)
158 {
159 TType = (PTOKEN_TYPE)Buffer;
160 ok((*TType == TokenPrimary || *TType == TokenImpersonation), "TokenType in not a primary nor impersonation. FAILED\n");
161 ExFreePool(TType);
162 }
163 }
164
165 //----------------------------------------------------------------//
166
167 Buffer = NULL;
168 Status = SeQueryInformationToken(Token, TokenUser, &Buffer);
169 ok(Status == STATUS_SUCCESS, "SQIT with TokenUser fails\n");
170 if (Status == STATUS_SUCCESS)
171 {
172 ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenUser arg. But Buffer = NULL\n");
173 if (Buffer)
174 {
175 TUser = (PTOKEN_USER)Buffer;
176 ok(RtlValidSid(TUser->User.Sid), "TokenUser has an invalid Sid\n");
177 ExFreePool(TUser);
178 }
179 }
180
181 //----------------------------------------------------------------//
182
183 Buffer = NULL;
184 Status = SeQueryInformationToken(Token, TokenSandBoxInert, &Buffer);
185 ok(Status != STATUS_SUCCESS, "SQIT must fail with wrong TOKEN_INFORMATION_CLASS arg\n");
186 }
187
188 //------------------------------------------------------------------------------//
189
190 //------------------------------------------------------------------------------//
191 // Body of the main test //
192 //------------------------------------------------------------------------------//
193
194 START_TEST(SeQueryInfoToken)
195 {
196 PACCESS_STATE AccessState;
197 ACCESS_MASK AccessMask = MAXIMUM_ALLOWED;
198 ACCESS_MASK DesiredAccess = MAXIMUM_ALLOWED;
199 NTSTATUS Status = STATUS_SUCCESS;
200 PAUX_ACCESS_DATA AuxData = NULL;
201 PPRIVILEGE_SET NewPrivilegeSet;
202 BOOLEAN Checker;
203 PPRIVILEGE_SET Privileges = NULL;
204 PSECURITY_SUBJECT_CONTEXT SubjectContext = NULL;
205 PACCESS_TOKEN Token = NULL;
206 PTOKEN_PRIVILEGES TPrivileges;
207 PVOID Buffer;
208 POBJECT_TYPE PsProcessType = NULL;
209 PGENERIC_MAPPING GenericMapping;
210 ULONG i;
211
212 SubjectContext = ExAllocatePool(PagedPool, sizeof(SECURITY_SUBJECT_CONTEXT));
213
214 SeCaptureSubjectContext(SubjectContext);
215 SeLockSubjectContext(SubjectContext);
216 Token = SeQuerySubjectContextToken(SubjectContext);
217
218 // Testing SQIT with current Token
219 TestsSeQueryInformationToken(Token);
220
221 //----------------------------------------------------------------//
222 // Creating an ACCESS_STATE structure //
223 //----------------------------------------------------------------//
224
225 AccessState = ExAllocatePool(PagedPool, sizeof(ACCESS_STATE));
226 PsProcessType = ExAllocatePool(PagedPool, sizeof(OBJECT_TYPE));
227 AuxData = ExAllocatePool(PagedPool, 0xC8);
228 GenericMapping = ExAllocatePool(PagedPool, sizeof(GENERIC_MAPPING));
229
230 Status = SeCreateAccessState(AccessState,
231 (PVOID)AuxData,
232 DesiredAccess,
233 GenericMapping
234 );
235
236 ok((Status == STATUS_SUCCESS), "SeCreateAccessState failed with Status 0x%08X\n", Status);
237
238 SeCaptureSubjectContext(&AccessState->SubjectSecurityContext);
239 SeLockSubjectContext(&AccessState->SubjectSecurityContext);
240
241 Token = SeQuerySubjectContextToken(&AccessState->SubjectSecurityContext);
242
243 // Testing SQIT with AccessState Token
244 TestsSeQueryInformationToken(Token);
245
246 //----------------------------------------------------------------//
247 // Testing other functions //
248 //----------------------------------------------------------------//
249
250 //----------------------------------------------------------------//
251 // Testing SeAppendPrivileges //
252 //----------------------------------------------------------------//
253
254 AuxData->PrivilegeSet->PrivilegeCount = 1;
255
256 // Testing SeAppendPrivileges. Must change PrivilegeCount to 2 (1 + 1)
257
258 NewPrivilegeSet = ExAllocatePool(PagedPool, sizeof(PRIVILEGE_SET));
259 NewPrivilegeSet->PrivilegeCount = 1;
260
261 Status = SeAppendPrivileges(AccessState, NewPrivilegeSet);
262 ok(Status == STATUS_SUCCESS, "SeAppendPrivileges failed\n");
263 ok((AuxData->PrivilegeSet->PrivilegeCount == 2),"PrivelegeCount must be 2, but it is %d\n", AuxData->PrivilegeSet->PrivilegeCount);
264 ExFreePool(NewPrivilegeSet);
265
266 //----------------------------------------------------------------//
267
268 // Testing SeAppendPrivileges. Must change PrivilegeCount to 6 (2 + 4)
269
270 NewPrivilegeSet = ExAllocatePool(PagedPool, 4*sizeof(PRIVILEGE_SET));
271 NewPrivilegeSet->PrivilegeCount = 4;
272
273 Status = SeAppendPrivileges(AccessState, NewPrivilegeSet);
274 ok(Status == STATUS_SUCCESS, "SeAppendPrivileges failed\n");
275 ok((AuxData->PrivilegeSet->PrivilegeCount == 6),"PrivelegeCount must be 6, but it is %d\n", AuxData->PrivilegeSet->PrivilegeCount);
276 ExFreePool(NewPrivilegeSet);
277
278 //----------------------------------------------------------------//
279 // Testing SePrivilegeCheck //
280 //----------------------------------------------------------------//
281
282 // KPROCESSOR_MODE is set to KernelMode ===> Always return TRUE
283 ok(SePrivilegeCheck(AuxData->PrivilegeSet, &(AccessState->SubjectSecurityContext), KernelMode), "SePrivilegeCheck failed with KernelMode mode arg\n");
284 // and call it again
285 ok(SePrivilegeCheck(AuxData->PrivilegeSet, &(AccessState->SubjectSecurityContext), KernelMode), "SePrivilegeCheck failed with KernelMode mode arg\n");
286
287 //----------------------------------------------------------------//
288
289 // KPROCESSOR_MODE is set to UserMode. Expect false
290 ok(!SePrivilegeCheck(AuxData->PrivilegeSet, &(AccessState->SubjectSecurityContext), UserMode), "SePrivilegeCheck unexpected success with UserMode arg\n");
291
292 //----------------------------------------------------------------//
293
294 //----------------------------------------------------------------//
295 // Testing SeFreePrivileges //
296 //----------------------------------------------------------------//
297
298 Privileges = ExAllocatePool(PagedPool, AuxData->PrivilegeSet->PrivilegeCount*sizeof(PRIVILEGE_SET));
299
300 Checker = SeAccessCheck(
301 AccessState->SecurityDescriptor,
302 &AccessState->SubjectSecurityContext,
303 FALSE,
304 AccessState->OriginalDesiredAccess,
305 AccessState->PreviouslyGrantedAccess,
306 &Privileges,
307 (PGENERIC_MAPPING)((PCHAR*)PsProcessType + 52),
308 KernelMode,
309 &AccessMask,
310 &Status
311 );
312 ok(Checker, "Checker is NULL\n");
313 ok((Privileges != NULL), "Privileges is NULL\n");
314 if (Privileges) SeFreePrivileges(Privileges);
315
316
317 //----------------------------------------------------------------//
318 // Testing SePrivilegeCheck //
319 //----------------------------------------------------------------//
320 // I'm trying to make success call of SePrivilegeCheck from UserMode
321 // If we sets Privileges properly, can we expect true from SePrivilegeCheck?
322 // answer: yes
323 // This test demonstrates it
324
325 Buffer = NULL;
326 Status = SeQueryInformationToken(Token, TokenPrivileges, &Buffer);
327 if (Status == STATUS_SUCCESS)
328 {
329 ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenPrivileges arg. But Buffer = NULL\n");
330 if (Buffer)
331 {
332 TPrivileges = (PTOKEN_PRIVILEGES)(Buffer);
333 //trace("TPCount = %u\n\n", TPrivileges->PrivilegeCount);
334
335 NewPrivilegeSet = ExAllocatePool(PagedPool, 14*sizeof(PRIVILEGE_SET));
336 NewPrivilegeSet->PrivilegeCount = 14;
337
338 ok((SeAppendPrivileges(AccessState, NewPrivilegeSet)) == STATUS_SUCCESS, "SeAppendPrivileges failed\n");
339 ok((AuxData->PrivilegeSet->PrivilegeCount == 20),"PrivelegeCount must be 20, but it is %d\n", AuxData->PrivilegeSet->PrivilegeCount);
340 ExFreePool(NewPrivilegeSet);
341 for (i = 0; i < AuxData->PrivilegeSet->PrivilegeCount; i++)
342 {
343 AuxData->PrivilegeSet->Privilege[i].Attributes = TPrivileges->Privileges[i].Attributes;
344 AuxData->PrivilegeSet->Privilege[i].Luid = TPrivileges->Privileges[i].Luid;
345 }
346 //trace("AccessState->privCount = %u\n\n", ((PAUX_ACCESS_DATA)(AccessState->AuxData))->PrivilegeSet->PrivilegeCount);
347
348 ok(SePrivilegeCheck(AuxData->PrivilegeSet, &(AccessState->SubjectSecurityContext), UserMode), "SePrivilegeCheck fails in UserMode, but I wish it will success\n");
349 }
350 }
351
352 // Call SeFreePrivileges again
353
354 Privileges = ExAllocatePool(PagedPool, 20*sizeof(PRIVILEGE_SET));
355
356 Checker = SeAccessCheck(
357 AccessState->SecurityDescriptor,
358 &AccessState->SubjectSecurityContext,
359 TRUE,
360 AccessState->OriginalDesiredAccess,
361 AccessState->PreviouslyGrantedAccess,
362 &Privileges,
363 (PGENERIC_MAPPING)((PCHAR*)PsProcessType + 52),
364 KernelMode,
365 &AccessMask,
366 &Status
367 );
368 ok(Checker, "Checker is NULL\n");
369 ok((Privileges != NULL), "Privileges is NULL\n");
370 if (Privileges) SeFreePrivileges(Privileges);
371
372 //----------------------------------------------------------------//
373 // Missing for now //
374 //----------------------------------------------------------------//
375
376 SeUnlockSubjectContext(&AccessState->SubjectSecurityContext);
377 SeUnlockSubjectContext(SubjectContext);
378
379 SeDeleteAccessState(AccessState);
380
381 if (GenericMapping) ExFreePool(GenericMapping);
382 if (PsProcessType) ExFreePool(PsProcessType);
383 if (SubjectContext) ExFreePool(SubjectContext);
384 if (AuxData) ExFreePool(AuxData);
385 if (AccessState) ExFreePool(AccessState);
386 }