[SHELL32_APITEST] -Add tests for Control_RunDLLW.
[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%08X\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%08X\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%08X\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 // Because your token has Token->TokenType != TokenImpersonation. -hbelusca
111
112 Buffer = NULL;
113 Status = SeQueryInformationToken(Token, TokenImpersonationLevel, &Buffer);
114 ok(Status == STATUS_SUCCESS, "SQIT with TokenImpersonationLevel fails with status 0x%08X\n", Status);
115 if (Buffer) ExFreePool(Buffer);
116
117 Buffer = NULL;
118 Status = SeQueryInformationToken(Token, TokenImpersonationLevel, &Buffer);
119 ok(Status == STATUS_SUCCESS, "and again: SQIT with TokenImpersonationLevel fails with status 0x%08X\n", Status);
120 if (Status == STATUS_SUCCESS)
121 {
122 ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenImpersonationLevel arg. But Buffer == NULL\n");
123 } else {
124 ok(Buffer == NULL, "Wrong. SQIT call failed. But Buffer != NULL\n");
125 }
126 if (Buffer) ExFreePool(Buffer);
127
128 //----------------------------------------------------------------//
129
130 // Call SQIT with the 4 classes (TokenOrigin, TokenGroupsAndPrivileges,
131 // TokenRestrictedSids and TokenSandBoxInert) are not supported by
132 // SeQueryInformationToken (only NtQueryInformationToken supports them).
133 //
134
135 Buffer = NULL;
136 Status = SeQueryInformationToken(Token, TokenOrigin, &Buffer);
137 ok(Status == STATUS_INVALID_INFO_CLASS, "SQIT with TokenOrigin failed with Status 0x%08X; expected STATUS_INVALID_INFO_CLASS\n", Status);
138 ok(Buffer == NULL, "Wrong. SQIT call failed. But Buffer != NULL\n");
139
140 Buffer = NULL;
141 Status = SeQueryInformationToken(Token, TokenGroupsAndPrivileges, &Buffer);
142 ok(Status == STATUS_INVALID_INFO_CLASS, "SQIT with TokenGroupsAndPrivileges failed with Status 0x%08X; expected STATUS_INVALID_INFO_CLASS\n", Status);
143 ok(Buffer == NULL, "Wrong. SQIT call failed. But Buffer != NULL\n");
144
145 Buffer = NULL;
146 Status = SeQueryInformationToken(Token, TokenRestrictedSids, &Buffer);
147 ok(Status == STATUS_INVALID_INFO_CLASS, "SQIT with TokenRestrictedSids failed with Status 0x%08X; expected STATUS_INVALID_INFO_CLASS\n", Status);
148 ok(Buffer == NULL, "Wrong. SQIT call failed. But Buffer != NULL\n");
149
150 Buffer = NULL;
151 Status = SeQueryInformationToken(Token, TokenSandBoxInert, &Buffer);
152 ok(Status == STATUS_INVALID_INFO_CLASS, "SQIT with TokenSandBoxInert failed with Status 0x%08X; expected STATUS_INVALID_INFO_CLASS\n", Status);
153 ok(Buffer == NULL, "Wrong. SQIT call failed. But Buffer != NULL\n");
154
155 //----------------------------------------------------------------//
156
157 Buffer = NULL;
158 Status = SeQueryInformationToken(Token, TokenStatistics, &Buffer);
159 ok(Status == STATUS_SUCCESS, "SQIT with TokenStatistics fails with status 0x%08X\n", Status);
160 if (Status == STATUS_SUCCESS)
161 {
162 ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenStatistics arg. But Buffer == NULL\n");
163 if (Buffer)
164 {
165 TStats = (PTOKEN_STATISTICS)Buffer;
166 // just put 0 into 1st arg or use trace to print TokenStatistics
167 ok(1, "print statistics:\n\tTokenID = %u_%d\n\tSecurityImperLevel = %d\n\tPrivCount = %d\n\tGroupCount = %d\n\n", TStats->TokenId.LowPart,
168 TStats->TokenId.HighPart,
169 TStats->ImpersonationLevel,
170 TStats->PrivilegeCount,
171 TStats->GroupCount
172 );
173 ExFreePool(Buffer);
174 }
175 } else {
176 ok(Buffer == NULL, "Wrong. SQIT call failed. But Buffer != NULL\n");
177 }
178
179 //----------------------------------------------------------------//
180
181 Buffer = NULL;
182 Status = SeQueryInformationToken(Token, TokenType, &Buffer);
183 ok(Status == STATUS_SUCCESS, "SQIT with TokenType fails with status 0x%08X\n", Status);
184 if (Status == STATUS_SUCCESS)
185 {
186 ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenType arg. But Buffer == NULL\n");
187 if (Buffer)
188 {
189 TType = (PTOKEN_TYPE)Buffer;
190 ok((*TType == TokenPrimary || *TType == TokenImpersonation), "TokenType in not a primary nor impersonation. FAILED\n");
191 ExFreePool(Buffer);
192 }
193 }
194
195 //----------------------------------------------------------------//
196
197 Buffer = NULL;
198 Status = SeQueryInformationToken(Token, TokenUser, &Buffer);
199 ok(Status == STATUS_SUCCESS, "SQIT with TokenUser fails\n");
200 if (Status == STATUS_SUCCESS)
201 {
202 ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenUser arg. But Buffer == NULL\n");
203 if (Buffer)
204 {
205 TUser = (PTOKEN_USER)Buffer;
206 ok(RtlValidSid(TUser->User.Sid), "TokenUser has an invalid Sid\n");
207 ExFreePool(Buffer);
208 }
209 }
210
211 //----------------------------------------------------------------//
212
213 Buffer = NULL;
214 Status = SeQueryInformationToken(Token, TokenSandBoxInert, &Buffer);
215 ok(Status != STATUS_SUCCESS, "SQIT must fail with wrong TOKEN_INFORMATION_CLASS arg\n");
216 }
217
218 //------------------------------------------------------------------------------//
219
220 //------------------------------------------------------------------------------//
221 // Body of the main test //
222 //------------------------------------------------------------------------------//
223
224 START_TEST(SeQueryInfoToken)
225 {
226 PACCESS_STATE AccessState;
227 ACCESS_MASK AccessMask = MAXIMUM_ALLOWED;
228 ACCESS_MASK DesiredAccess = MAXIMUM_ALLOWED;
229 NTSTATUS Status = STATUS_SUCCESS;
230 PAUX_ACCESS_DATA AuxData = NULL;
231 PPRIVILEGE_SET NewPrivilegeSet;
232 BOOLEAN Checker;
233 PPRIVILEGE_SET Privileges = NULL;
234 PSECURITY_SUBJECT_CONTEXT SubjectContext = NULL;
235 PACCESS_TOKEN Token = NULL;
236 PTOKEN_PRIVILEGES TPrivileges;
237 PVOID Buffer;
238 POBJECT_TYPE PsProcessType = NULL;
239 PGENERIC_MAPPING GenericMapping;
240 ULONG i;
241
242 SubjectContext = ExAllocatePool(PagedPool, sizeof(SECURITY_SUBJECT_CONTEXT));
243
244 SeCaptureSubjectContext(SubjectContext);
245 SeLockSubjectContext(SubjectContext);
246 Token = SeQuerySubjectContextToken(SubjectContext);
247
248 // Testing SQIT with current Token
249 TestsSeQueryInformationToken(Token);
250
251 //----------------------------------------------------------------//
252 // Creating an ACCESS_STATE structure //
253 //----------------------------------------------------------------//
254
255 AccessState = ExAllocatePool(PagedPool, sizeof(ACCESS_STATE));
256 PsProcessType = ExAllocatePool(PagedPool, sizeof(OBJECT_TYPE));
257 AuxData = ExAllocatePool(PagedPool, 0xC8);
258 GenericMapping = ExAllocatePool(PagedPool, sizeof(GENERIC_MAPPING));
259
260 Status = SeCreateAccessState(AccessState,
261 (PVOID)AuxData,
262 DesiredAccess,
263 GenericMapping
264 );
265
266 ok((Status == STATUS_SUCCESS), "SeCreateAccessState failed with Status 0x%08X\n", Status);
267
268 SeCaptureSubjectContext(&AccessState->SubjectSecurityContext);
269 SeLockSubjectContext(&AccessState->SubjectSecurityContext);
270 Token = SeQuerySubjectContextToken(&AccessState->SubjectSecurityContext);
271
272 // Testing SQIT with AccessState Token
273 TestsSeQueryInformationToken(Token);
274
275 //----------------------------------------------------------------//
276 // Testing other functions //
277 //----------------------------------------------------------------//
278
279 //----------------------------------------------------------------//
280 // Testing SeAppendPrivileges //
281 //----------------------------------------------------------------//
282
283 AuxData->PrivilegeSet->PrivilegeCount = 1;
284
285 // Testing SeAppendPrivileges. Must change PrivilegeCount to 2 (1 + 1)
286
287 NewPrivilegeSet = ExAllocatePool(PagedPool, sizeof(PRIVILEGE_SET));
288 NewPrivilegeSet->PrivilegeCount = 1;
289
290 Status = SeAppendPrivileges(AccessState, NewPrivilegeSet);
291 ok(Status == STATUS_SUCCESS, "SeAppendPrivileges failed\n");
292 ok((AuxData->PrivilegeSet->PrivilegeCount == 2),"PrivelegeCount must be 2, but it is %d\n", AuxData->PrivilegeSet->PrivilegeCount);
293 ExFreePool(NewPrivilegeSet);
294
295 //----------------------------------------------------------------//
296
297 // Testing SeAppendPrivileges. Must change PrivilegeCount to 6 (2 + 4)
298
299 NewPrivilegeSet = ExAllocatePool(PagedPool, 4*sizeof(PRIVILEGE_SET));
300 NewPrivilegeSet->PrivilegeCount = 4;
301
302 Status = SeAppendPrivileges(AccessState, NewPrivilegeSet);
303 ok(Status == STATUS_SUCCESS, "SeAppendPrivileges failed\n");
304 ok((AuxData->PrivilegeSet->PrivilegeCount == 6),"PrivelegeCount must be 6, but it is %d\n", AuxData->PrivilegeSet->PrivilegeCount);
305 ExFreePool(NewPrivilegeSet);
306
307 //----------------------------------------------------------------//
308 // Testing SePrivilegeCheck //
309 //----------------------------------------------------------------//
310
311 // KPROCESSOR_MODE is set to KernelMode ===> Always return TRUE
312 ok(SePrivilegeCheck(AuxData->PrivilegeSet, &(AccessState->SubjectSecurityContext), KernelMode), "SePrivilegeCheck failed with KernelMode mode arg\n");
313 // and call it again
314 ok(SePrivilegeCheck(AuxData->PrivilegeSet, &(AccessState->SubjectSecurityContext), KernelMode), "SePrivilegeCheck failed with KernelMode mode arg\n");
315
316 //----------------------------------------------------------------//
317
318 // KPROCESSOR_MODE is set to UserMode. Expect false
319 ok(!SePrivilegeCheck(AuxData->PrivilegeSet, &(AccessState->SubjectSecurityContext), UserMode), "SePrivilegeCheck unexpected success with UserMode arg\n");
320
321 //----------------------------------------------------------------//
322
323 //----------------------------------------------------------------//
324 // Testing SeFreePrivileges //
325 //----------------------------------------------------------------//
326
327 Privileges = NULL;
328 Checker = SeAccessCheck(
329 AccessState->SecurityDescriptor,
330 &AccessState->SubjectSecurityContext,
331 FALSE,
332 AccessState->OriginalDesiredAccess,
333 AccessState->PreviouslyGrantedAccess,
334 &Privileges,
335 (PGENERIC_MAPPING)((PCHAR*)PsProcessType + 52),
336 KernelMode,
337 &AccessMask,
338 &Status
339 );
340 ok(Checker, "Checker is NULL\n");
341 ok((Privileges != NULL), "Privileges is NULL\n");
342 if (Privileges)
343 {
344 trace("AuxData->PrivilegeSet->PrivilegeCount = %d ; Privileges->PrivilegeCount = %d\n",
345 AuxData->PrivilegeSet->PrivilegeCount, Privileges->PrivilegeCount);
346 }
347 if (Privileges) SeFreePrivileges(Privileges);
348
349
350 //----------------------------------------------------------------//
351 // Testing SePrivilegeCheck //
352 //----------------------------------------------------------------//
353 // I'm trying to make success call of SePrivilegeCheck from UserMode
354 // If we sets Privileges properly, can we expect true from SePrivilegeCheck?
355 // answer: yes
356 // This test demonstrates it
357
358 Buffer = NULL;
359 Status = SeQueryInformationToken(Token, TokenPrivileges, &Buffer);
360 if (Status == STATUS_SUCCESS)
361 {
362 ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenPrivileges arg. But Buffer == NULL\n");
363 if (Buffer)
364 {
365 TPrivileges = (PTOKEN_PRIVILEGES)(Buffer);
366 //trace("TPCount = %u\n\n", TPrivileges->PrivilegeCount);
367
368 NewPrivilegeSet = ExAllocatePool(PagedPool, 14*sizeof(PRIVILEGE_SET));
369 NewPrivilegeSet->PrivilegeCount = 14;
370
371 ok((SeAppendPrivileges(AccessState, NewPrivilegeSet)) == STATUS_SUCCESS, "SeAppendPrivileges failed\n");
372 ok((AuxData->PrivilegeSet->PrivilegeCount == 20),"PrivelegeCount must be 20, but it is %d\n", AuxData->PrivilegeSet->PrivilegeCount);
373 ExFreePool(NewPrivilegeSet);
374 for (i = 0; i < AuxData->PrivilegeSet->PrivilegeCount; i++)
375 {
376 AuxData->PrivilegeSet->Privilege[i].Attributes = TPrivileges->Privileges[i].Attributes;
377 AuxData->PrivilegeSet->Privilege[i].Luid = TPrivileges->Privileges[i].Luid;
378 }
379 //trace("AccessState->privCount = %u\n\n", ((PAUX_ACCESS_DATA)(AccessState->AuxData))->PrivilegeSet->PrivilegeCount);
380
381 ok(SePrivilegeCheck(AuxData->PrivilegeSet, &(AccessState->SubjectSecurityContext), UserMode), "SePrivilegeCheck fails in UserMode, but I wish it will success\n");
382 }
383 }
384
385 // Call SeFreePrivileges again
386
387 Privileges = NULL;
388 Checker = SeAccessCheck(
389 AccessState->SecurityDescriptor,
390 &AccessState->SubjectSecurityContext,
391 TRUE,
392 AccessState->OriginalDesiredAccess,
393 AccessState->PreviouslyGrantedAccess,
394 &Privileges,
395 (PGENERIC_MAPPING)((PCHAR*)PsProcessType + 52),
396 KernelMode,
397 &AccessMask,
398 &Status
399 );
400 ok(Checker, "Checker is NULL\n");
401 ok((Privileges != NULL), "Privileges is NULL\n");
402 if (Privileges)
403 {
404 trace("AuxData->PrivilegeSet->PrivilegeCount = %d ; Privileges->PrivilegeCount = %d\n",
405 AuxData->PrivilegeSet->PrivilegeCount, Privileges->PrivilegeCount);
406 }
407 if (Privileges) SeFreePrivileges(Privileges);
408
409 //----------------------------------------------------------------//
410 // Missing for now //
411 //----------------------------------------------------------------//
412
413 SeUnlockSubjectContext(&AccessState->SubjectSecurityContext);
414 SeUnlockSubjectContext(SubjectContext);
415
416 SeDeleteAccessState(AccessState);
417
418 if (GenericMapping) ExFreePool(GenericMapping);
419 if (PsProcessType) ExFreePool(PsProcessType);
420 if (SubjectContext) ExFreePool(SubjectContext);
421 if (AuxData) ExFreePool(AuxData);
422 if (AccessState) ExFreePool(AccessState);
423 }