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