[SHELL32]
[reactos.git] / rostests / kmtests / ntos_se / SeInheritance.c
1 /*
2 * PROJECT: ReactOS kernel-mode tests
3 * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
4 * PURPOSE: Kernel-Mode Test for object security inheritance
5 * PROGRAMMER: Thomas Faber <thomas.faber@reactos.org>
6 */
7
8 #include <kmt_test.h>
9 #include "se.h"
10
11 static GENERIC_MAPPING GenericMapping =
12 {
13 STANDARD_RIGHTS_READ | 0x1001,
14 STANDARD_RIGHTS_WRITE | 0x2002,
15 STANDARD_RIGHTS_EXECUTE | 0x4004,
16 STANDARD_RIGHTS_ALL | 0x800F,
17 };
18
19 static
20 VOID
21 TestSeAssignSecurity(
22 _In_ PSECURITY_SUBJECT_CONTEXT SubjectContext)
23 {
24 NTSTATUS Status;
25 PTOKEN Token;
26 PSECURITY_DESCRIPTOR SecurityDescriptor;
27 SECURITY_DESCRIPTOR ParentDescriptor;
28 SECURITY_DESCRIPTOR ExplicitDescriptor;
29 ACL EmptyAcl;
30 PACL Acl;
31 PACL Acl2;
32 ULONG AclSize;
33 ULONG UsingDefault;
34 ULONG CanInherit;
35 ULONG AceFlags;
36 ULONG AceFlags2;
37 ULONG Access;
38 PSID GenericSid;
39 PSID GenericSid2;
40 ACCESS_MASK GenericMask;
41 ACCESS_MASK GenericMask2;
42 PSID SpecificSid;
43 ACCESS_MASK SpecificMask;
44 ACCESS_MASK SpecificMask2;
45 BOOLEAN ParentUsable;
46
47 Token = SubjectContext->PrimaryToken;
48 CheckAcl(Token->DefaultDacl, 2, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, GENERIC_ALL,
49 ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, GENERIC_READ | GENERIC_EXECUTE | STANDARD_RIGHTS_READ);
50 CheckSid(Token->UserAndGroups[Token->DefaultOwnerIndex].Sid, NO_SIZE, SeExports->SeAliasAdminsSid);
51 CheckSid(Token->PrimaryGroup, NO_SIZE, SeExports->SeLocalSystemSid);
52 // Flags with no effect on current tests: SEF_SACL_AUTO_INHERIT, SEF_DEFAULT_DESCRIPTOR_FOR_OBJECT
53 #define StartTestAssign(Parent, Explicit, IsDir, GotDacl, GotSacl) \
54 SecurityDescriptor = NULL; \
55 Status = SeAssignSecurity (Parent, \
56 Explicit, \
57 &SecurityDescriptor, \
58 /*NULL,*/ \
59 IsDir, \
60 /*0,*/ \
61 SubjectContext, \
62 &GenericMapping, \
63 PagedPool); \
64 ok_eq_hex(Status, STATUS_SUCCESS); \
65 if (!skip(NT_SUCCESS(Status), "No security\n")) \
66 { \
67 PACL Dacl, Sacl; \
68 PSID Owner, Group; \
69 BOOLEAN Present; \
70 BOOLEAN DaclDefaulted, SaclDefaulted; \
71 BOOLEAN OwnerDefaulted, GroupDefaulted; \
72 Status = RtlGetDaclSecurityDescriptor(SecurityDescriptor, \
73 &Present, \
74 &Dacl, \
75 &DaclDefaulted); \
76 ok_eq_hex(Status, STATUS_SUCCESS); \
77 ok_eq_uint(Present, GotDacl); \
78 if (!NT_SUCCESS(Status) || !Present) \
79 Dacl = NULL; \
80 Status = RtlGetSaclSecurityDescriptor(SecurityDescriptor, \
81 &Present, \
82 &Sacl, \
83 &SaclDefaulted); \
84 ok_eq_hex(Status, STATUS_SUCCESS); \
85 ok_eq_uint(Present, GotSacl); \
86 if (!NT_SUCCESS(Status) || !Present) \
87 Sacl = NULL; \
88 Status = RtlGetOwnerSecurityDescriptor(SecurityDescriptor, \
89 &Owner, \
90 &OwnerDefaulted); \
91 ok_eq_hex(Status, STATUS_SUCCESS); \
92 if (skip(NT_SUCCESS(Status), "No owner\n")) \
93 Owner = NULL; \
94 Status = RtlGetGroupSecurityDescriptor(SecurityDescriptor, \
95 &Group, \
96 &GroupDefaulted); \
97 ok_eq_hex(Status, STATUS_SUCCESS); \
98 if (skip(NT_SUCCESS(Status), "No group\n")) \
99 Group = NULL;
100
101 #define EndTestAssign() \
102 SeDeassignSecurity(&SecurityDescriptor); \
103 }
104 #define StartTestAssignLoop(Parent, Explicit) \
105 { \
106 BOOLEAN IsDir; \
107 BOOLEAN UsingParent; \
108 BOOLEAN UsingExplicit; \
109 for (IsDir = FALSE; IsDir <= TRUE; IsDir++) \
110 { \
111 for (UsingParent = FALSE; UsingParent <= TRUE; UsingParent++) \
112 { \
113 for (UsingExplicit = FALSE; UsingExplicit <= TRUE; UsingExplicit++) \
114 { \
115 StartTestAssign(UsingParent ? Parent : NULL, \
116 UsingExplicit ? Explicit : NULL, \
117 IsDir, \
118 TRUE, \
119 FALSE)
120 #define EndTestAssignLoop() \
121 EndTestAssign() \
122 } \
123 } \
124 } \
125 }
126 #define TestAssignExpectDefault(Parent, Explicit, IsDir) \
127 StartTestAssign(Parent, Explicit, IsDir, TRUE, FALSE) \
128 ok_eq_uint(DaclDefaulted, FALSE); \
129 CheckAcl(Dacl, 2, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, STANDARD_RIGHTS_ALL | 0x800F, \
130 ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, STANDARD_RIGHTS_READ | 0x0005); \
131 ok_eq_uint(OwnerDefaulted, FALSE); \
132 CheckSid(Owner, NO_SIZE, Token->UserAndGroups[Token->DefaultOwnerIndex].Sid); \
133 ok_eq_uint(GroupDefaulted, FALSE); \
134 CheckSid(Group, NO_SIZE, Token->PrimaryGroup); \
135 EndTestAssign()
136 #define TestAssignExpectDefaultAll() \
137 TestAssignExpectDefault(&ParentDescriptor, NULL, FALSE) \
138 TestAssignExpectDefault(&ParentDescriptor, NULL, TRUE) \
139 TestAssignExpectDefault(NULL, &ExplicitDescriptor, FALSE) \
140 TestAssignExpectDefault(NULL, &ExplicitDescriptor, TRUE) \
141 TestAssignExpectDefault(&ParentDescriptor, &ExplicitDescriptor, FALSE) \
142 TestAssignExpectDefault(&ParentDescriptor, &ExplicitDescriptor, TRUE)
143
144 TestAssignExpectDefault(NULL, NULL, FALSE)
145 TestAssignExpectDefault(NULL, NULL, TRUE)
146
147 /* Empty parent/explicit descriptors */
148 Status = RtlCreateSecurityDescriptor(&ParentDescriptor,
149 SECURITY_DESCRIPTOR_REVISION);
150 ok_eq_hex(Status, STATUS_SUCCESS);
151 Status = RtlCreateSecurityDescriptor(&ExplicitDescriptor,
152 SECURITY_DESCRIPTOR_REVISION);
153 ok_eq_hex(Status, STATUS_SUCCESS);
154 TestAssignExpectDefaultAll()
155
156 /* NULL DACL in parent/explicit descriptor */
157 for (UsingDefault = FALSE; UsingDefault <= TRUE; UsingDefault++)
158 {
159 Status = RtlSetDaclSecurityDescriptor(&ParentDescriptor,
160 TRUE,
161 NULL,
162 UsingDefault);
163 ok_eq_hex(Status, STATUS_SUCCESS);
164 Status = RtlSetDaclSecurityDescriptor(&ExplicitDescriptor,
165 TRUE,
166 NULL,
167 UsingDefault);
168 ok_eq_hex(Status, STATUS_SUCCESS);
169 StartTestAssignLoop(&ParentDescriptor, &ExplicitDescriptor)
170 //trace("Explicit %u, Parent %u, Dir %u, Default %u\n", UsingExplicit, UsingParent, IsDir, UsingDefault);
171 ok_eq_uint(DaclDefaulted, FALSE);
172 if (UsingExplicit)
173 {
174 ok(Dacl == NULL, "Dacl = %p\n", Dacl);
175 }
176 else
177 {
178 CheckAcl(Dacl, 2, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, STANDARD_RIGHTS_ALL | 0x800F,
179 ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, STANDARD_RIGHTS_READ | 0x0005);
180 }
181 ok_eq_uint(OwnerDefaulted, FALSE);
182 CheckSid(Owner, NO_SIZE, SeExports->SeAliasAdminsSid);
183 ok_eq_uint(GroupDefaulted, FALSE);
184 CheckSid(Group, NO_SIZE, SeExports->SeLocalSystemSid);
185 EndTestAssignLoop()
186 }
187
188 /* Empty default DACL in parent/explicit descriptor */
189 for (UsingDefault = FALSE; UsingDefault <= TRUE; UsingDefault++)
190 {
191 Status = RtlCreateAcl(&EmptyAcl, sizeof(EmptyAcl), ACL_REVISION);
192 ok_eq_hex(Status, STATUS_SUCCESS);
193 Status = RtlSetDaclSecurityDescriptor(&ParentDescriptor,
194 TRUE,
195 &EmptyAcl,
196 UsingDefault);
197 ok_eq_hex(Status, STATUS_SUCCESS);
198 Status = RtlSetDaclSecurityDescriptor(&ExplicitDescriptor,
199 TRUE,
200 &EmptyAcl,
201 UsingDefault);
202 ok_eq_hex(Status, STATUS_SUCCESS);
203 StartTestAssignLoop(&ParentDescriptor, &ExplicitDescriptor)
204 //trace("Explicit %u, Parent %u, Dir %u, Default %u\n", UsingExplicit, UsingParent, IsDir, UsingDefault);
205 ok_eq_uint(DaclDefaulted, FALSE);
206 if (UsingExplicit)
207 {
208 CheckAcl(Dacl, 0);
209 }
210 else
211 {
212 CheckAcl(Dacl, 2, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, STANDARD_RIGHTS_ALL | 0x800F,
213 ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, STANDARD_RIGHTS_READ | 0x0005);
214 }
215 ok_eq_uint(OwnerDefaulted, FALSE);
216 CheckSid(Owner, NO_SIZE, SeExports->SeAliasAdminsSid);
217 ok_eq_uint(GroupDefaulted, FALSE);
218 CheckSid(Group, NO_SIZE, SeExports->SeLocalSystemSid);
219 EndTestAssignLoop()
220 }
221
222
223 AclSize = sizeof(ACL) + FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + RtlLengthSid(SeExports->SeWorldSid);
224 Acl = ExAllocatePoolWithTag(PagedPool, AclSize, 'ASmK');
225 if (skip(Acl != NULL, "Out of memory\n"))
226 return;
227
228 Acl2 = ExAllocatePoolWithTag(PagedPool, AclSize, 'ASmK');
229 if (skip(Acl2 != NULL, "Out of memory\n"))
230 {
231 ExFreePoolWithTag(Acl, 'ASmK');
232 return;
233 }
234
235 /* Simple DACL in parent/explicit descriptor */
236 for (UsingDefault = 0; UsingDefault <= 3; UsingDefault++)
237 {
238 Status = RtlCreateAcl(Acl, AclSize, ACL_REVISION);
239 ok_eq_hex(Status, STATUS_SUCCESS);
240 Status = RtlAddAccessAllowedAceEx(Acl, ACL_REVISION, 0, READ_CONTROL, SeExports->SeWorldSid);
241 ok_eq_hex(Status, STATUS_SUCCESS);
242 Status = RtlSetDaclSecurityDescriptor(&ParentDescriptor,
243 TRUE,
244 Acl,
245 BooleanFlagOn(UsingDefault, 1));
246 ok_eq_hex(Status, STATUS_SUCCESS);
247 Status = RtlSetDaclSecurityDescriptor(&ExplicitDescriptor,
248 TRUE,
249 Acl,
250 BooleanFlagOn(UsingDefault, 2));
251 ok_eq_hex(Status, STATUS_SUCCESS);
252 StartTestAssignLoop(&ParentDescriptor, &ExplicitDescriptor)
253 //trace("Explicit %u, Parent %u, Dir %u, Default %u\n", UsingExplicit, UsingParent, IsDir, UsingDefault);
254 ok_eq_uint(DaclDefaulted, FALSE);
255 if (UsingExplicit)
256 {
257 CheckAcl(Dacl, 1, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeWorldSid, READ_CONTROL);
258 }
259 else
260 {
261 CheckAcl(Dacl, 2, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, STANDARD_RIGHTS_ALL | 0x800F,
262 ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, STANDARD_RIGHTS_READ | 0x0005);
263 }
264 ok_eq_uint(OwnerDefaulted, FALSE);
265 CheckSid(Owner, NO_SIZE, SeExports->SeAliasAdminsSid);
266 ok_eq_uint(GroupDefaulted, FALSE);
267 CheckSid(Group, NO_SIZE, SeExports->SeLocalSystemSid);
268 EndTestAssignLoop()
269 }
270
271 /* Object-inheritable DACL in parent/explicit descriptor */
272 for (UsingDefault = 0; UsingDefault <= 3; UsingDefault++)
273 {
274 Status = RtlCreateAcl(Acl, AclSize, ACL_REVISION);
275 ok_eq_hex(Status, STATUS_SUCCESS);
276 Status = RtlAddAccessAllowedAceEx(Acl, ACL_REVISION, OBJECT_INHERIT_ACE, READ_CONTROL, SeExports->SeWorldSid);
277 ok_eq_hex(Status, STATUS_SUCCESS);
278 Status = RtlSetDaclSecurityDescriptor(&ParentDescriptor,
279 TRUE,
280 Acl,
281 BooleanFlagOn(UsingDefault, 1));
282 ok_eq_hex(Status, STATUS_SUCCESS);
283 Status = RtlSetDaclSecurityDescriptor(&ExplicitDescriptor,
284 TRUE,
285 Acl,
286 BooleanFlagOn(UsingDefault, 2));
287 ok_eq_hex(Status, STATUS_SUCCESS);
288 StartTestAssignLoop(&ParentDescriptor, &ExplicitDescriptor)
289 //trace("Explicit %u, Parent %u, Dir %u, Default %u\n", UsingExplicit, UsingParent, IsDir, UsingDefault);
290 ok_eq_uint(DaclDefaulted, FALSE);
291 if (UsingExplicit && (!UsingParent || !FlagOn(UsingDefault, 2)))
292 {
293 CheckAcl(Dacl, 1, ACCESS_ALLOWED_ACE_TYPE, OBJECT_INHERIT_ACE, SeExports->SeWorldSid, READ_CONTROL);
294 }
295 else if (UsingParent)
296 {
297 CheckAcl(Dacl, 1, ACCESS_ALLOWED_ACE_TYPE, IsDir ? INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE : 0, SeExports->SeWorldSid, READ_CONTROL);
298 }
299 else
300 {
301 CheckAcl(Dacl, 2, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, STANDARD_RIGHTS_ALL | 0x800F,
302 ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, STANDARD_RIGHTS_READ | 0x0005);
303 }
304 ok_eq_uint(OwnerDefaulted, FALSE);
305 CheckSid(Owner, NO_SIZE, SeExports->SeAliasAdminsSid);
306 ok_eq_uint(GroupDefaulted, FALSE);
307 CheckSid(Group, NO_SIZE, SeExports->SeLocalSystemSid);
308 EndTestAssignLoop()
309 }
310
311 /* Container-inheritable DACL in parent/explicit descriptor */
312 for (UsingDefault = 0; UsingDefault <= 3; UsingDefault++)
313 {
314 Status = RtlCreateAcl(Acl, AclSize, ACL_REVISION);
315 ok_eq_hex(Status, STATUS_SUCCESS);
316 Status = RtlAddAccessAllowedAceEx(Acl, ACL_REVISION, CONTAINER_INHERIT_ACE, READ_CONTROL, SeExports->SeWorldSid);
317 ok_eq_hex(Status, STATUS_SUCCESS);
318 Status = RtlSetDaclSecurityDescriptor(&ParentDescriptor,
319 TRUE,
320 Acl,
321 BooleanFlagOn(UsingDefault, 1));
322 ok_eq_hex(Status, STATUS_SUCCESS);
323 Status = RtlSetDaclSecurityDescriptor(&ExplicitDescriptor,
324 TRUE,
325 Acl,
326 BooleanFlagOn(UsingDefault, 2));
327 ok_eq_hex(Status, STATUS_SUCCESS);
328 StartTestAssignLoop(&ParentDescriptor, &ExplicitDescriptor)
329 //trace("Explicit %u, Parent %u, Dir %u, Default %u\n", UsingExplicit, UsingParent, IsDir, UsingDefault);
330 ok_eq_uint(DaclDefaulted, FALSE);
331 if (UsingExplicit || (UsingParent && IsDir))
332 {
333 CheckAcl(Dacl, 1, ACCESS_ALLOWED_ACE_TYPE, CONTAINER_INHERIT_ACE, SeExports->SeWorldSid, READ_CONTROL);
334 }
335 else
336 {
337 CheckAcl(Dacl, 2, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, STANDARD_RIGHTS_ALL | 0x800F,
338 ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, STANDARD_RIGHTS_READ | 0x0005);
339 }
340 ok_eq_uint(OwnerDefaulted, FALSE);
341 CheckSid(Owner, NO_SIZE, SeExports->SeAliasAdminsSid);
342 ok_eq_uint(GroupDefaulted, FALSE);
343 CheckSid(Group, NO_SIZE, SeExports->SeLocalSystemSid);
344 EndTestAssignLoop()
345 }
346
347 /* Fully inheritable DACL in parent/explicit descriptor */
348 for (UsingDefault = 0; UsingDefault <= 3; UsingDefault++)
349 {
350 Status = RtlCreateAcl(Acl, AclSize, ACL_REVISION);
351 ok_eq_hex(Status, STATUS_SUCCESS);
352 Status = RtlAddAccessAllowedAceEx(Acl, ACL_REVISION, OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE, READ_CONTROL, SeExports->SeWorldSid);
353 ok_eq_hex(Status, STATUS_SUCCESS);
354 Status = RtlSetDaclSecurityDescriptor(&ParentDescriptor,
355 TRUE,
356 Acl,
357 BooleanFlagOn(UsingDefault, 1));
358 ok_eq_hex(Status, STATUS_SUCCESS);
359 Status = RtlSetDaclSecurityDescriptor(&ExplicitDescriptor,
360 TRUE,
361 Acl,
362 BooleanFlagOn(UsingDefault, 2));
363 ok_eq_hex(Status, STATUS_SUCCESS);
364 StartTestAssignLoop(&ParentDescriptor, &ExplicitDescriptor)
365 //trace("Explicit %u, Parent %u, Dir %u, Default %u\n", UsingExplicit, UsingParent, IsDir, UsingDefault);
366 ok_eq_uint(DaclDefaulted, FALSE);
367 if (UsingExplicit && (!UsingParent || !FlagOn(UsingDefault, 2)))
368 {
369 CheckAcl(Dacl, 1, ACCESS_ALLOWED_ACE_TYPE, OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE, SeExports->SeWorldSid, READ_CONTROL);
370 }
371 else if (UsingParent)
372 {
373 CheckAcl(Dacl, 1, ACCESS_ALLOWED_ACE_TYPE, IsDir ? OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE : 0, SeExports->SeWorldSid, READ_CONTROL);
374 }
375 else
376 {
377 CheckAcl(Dacl, 2, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, STANDARD_RIGHTS_ALL | 0x800F,
378 ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, STANDARD_RIGHTS_READ | 0x0005);
379 }
380 ok_eq_uint(OwnerDefaulted, FALSE);
381 CheckSid(Owner, NO_SIZE, SeExports->SeAliasAdminsSid);
382 ok_eq_uint(GroupDefaulted, FALSE);
383 CheckSid(Group, NO_SIZE, SeExports->SeLocalSystemSid);
384 EndTestAssignLoop()
385 }
386
387 /* Different DACLs in parent and explicit descriptors */
388 for (Access = 0; Access <= 1; Access++)
389 {
390 if (Access == 1)
391 {
392 GenericSid = SeExports->SeCreatorOwnerSid;
393 SpecificSid = SeExports->SeAliasAdminsSid;
394 GenericMask = GENERIC_READ;
395 SpecificMask = STANDARD_RIGHTS_READ | 0x0001;
396 GenericSid2 = SeExports->SeCreatorGroupSid;
397 GenericMask2 = GENERIC_EXECUTE;
398 SpecificMask2 = STANDARD_RIGHTS_EXECUTE | 0x0004;
399 }
400 else
401 {
402 GenericSid = SeExports->SeWorldSid;
403 SpecificSid = SeExports->SeWorldSid;
404 GenericMask = READ_CONTROL;
405 SpecificMask = READ_CONTROL;
406 GenericSid2 = SeExports->SeLocalSystemSid;
407 GenericMask2 = SYNCHRONIZE;
408 SpecificMask2 = SYNCHRONIZE;
409 }
410 for (CanInherit = 0; CanInherit <= 255; CanInherit++)
411 {
412 for (UsingDefault = 0; UsingDefault <= 3; UsingDefault++)
413 {
414 Status = RtlCreateAcl(Acl, AclSize, ACL_REVISION);
415 ok_eq_hex(Status, STATUS_SUCCESS);
416 AceFlags = CanInherit & 0xf;
417 Status = RtlAddAccessAllowedAceEx(Acl, ACL_REVISION, AceFlags, GenericMask, GenericSid);
418 ok_eq_hex(Status, STATUS_SUCCESS);
419 Status = RtlCreateAcl(Acl2, AclSize, ACL_REVISION);
420 ok_eq_hex(Status, STATUS_SUCCESS);
421 AceFlags2 = CanInherit >> 4;
422 Status = RtlAddAccessAllowedAceEx(Acl2, ACL_REVISION, AceFlags2, GenericMask2, GenericSid2);
423 ok_eq_hex(Status, STATUS_SUCCESS);
424 Status = RtlSetDaclSecurityDescriptor(&ParentDescriptor,
425 TRUE,
426 Acl,
427 BooleanFlagOn(UsingDefault, 1));
428 ok_eq_hex(Status, STATUS_SUCCESS);
429 Status = RtlSetDaclSecurityDescriptor(&ExplicitDescriptor,
430 TRUE,
431 Acl2,
432 BooleanFlagOn(UsingDefault, 2));
433 ok_eq_hex(Status, STATUS_SUCCESS);
434 StartTestAssignLoop(&ParentDescriptor, &ExplicitDescriptor)
435 //trace("Explicit %u, Parent %u, Dir %u, Default %u, Inherit %u, Access %u\n", UsingExplicit, UsingParent, IsDir, UsingDefault, CanInherit, Access);
436 ok_eq_uint(DaclDefaulted, FALSE);
437 ParentUsable = UsingParent;
438 if (!IsDir && !FlagOn(AceFlags, OBJECT_INHERIT_ACE))
439 ParentUsable = FALSE;
440 else if (IsDir && !FlagOn(AceFlags, CONTAINER_INHERIT_ACE) &&
441 (!FlagOn(AceFlags, OBJECT_INHERIT_ACE) || FlagOn(AceFlags, NO_PROPAGATE_INHERIT_ACE)))
442 ParentUsable = FALSE;
443
444 if (UsingExplicit && (!FlagOn(UsingDefault, 2) || !ParentUsable))
445 {
446 CheckAcl(Dacl, 1, ACCESS_ALLOWED_ACE_TYPE, AceFlags2, GenericSid2, FlagOn(AceFlags2, INHERIT_ONLY_ACE) ? GenericMask2 : SpecificMask2);
447 }
448 else if (ParentUsable)
449 {
450 if (IsDir && !FlagOn(AceFlags, NO_PROPAGATE_INHERIT_ACE))
451 {
452 if (FlagOn(AceFlags, CONTAINER_INHERIT_ACE) && (SpecificMask != GenericMask || SpecificSid != GenericSid))
453 CheckAcl(Dacl, 2, ACCESS_ALLOWED_ACE_TYPE, 0, SpecificSid, SpecificMask,
454 ACCESS_ALLOWED_ACE_TYPE, INHERIT_ONLY_ACE | CONTAINER_INHERIT_ACE | (AceFlags & OBJECT_INHERIT_ACE), GenericSid, GenericMask);
455 else
456 CheckAcl(Dacl, 1, ACCESS_ALLOWED_ACE_TYPE, (FlagOn(AceFlags, CONTAINER_INHERIT_ACE) ? 0 : INHERIT_ONLY_ACE) |
457 (AceFlags & (CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE)), GenericSid, GenericMask);
458 }
459 else
460 CheckAcl(Dacl, 1, ACCESS_ALLOWED_ACE_TYPE, 0, SpecificSid, SpecificMask);
461 }
462 else
463 {
464 CheckAcl(Dacl, 2, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, STANDARD_RIGHTS_ALL | 0x800F,
465 ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, STANDARD_RIGHTS_READ | 0x0005);
466 }
467 ok_eq_uint(OwnerDefaulted, FALSE);
468 CheckSid(Owner, NO_SIZE, SeExports->SeAliasAdminsSid);
469 ok_eq_uint(GroupDefaulted, FALSE);
470 CheckSid(Group, NO_SIZE, SeExports->SeLocalSystemSid);
471 EndTestAssignLoop()
472 }
473 }
474 }
475
476 /* NULL parameters */
477 ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
478 KmtStartSeh()
479 Status = SeAssignSecurity(NULL,
480 NULL,
481 NULL,
482 FALSE,
483 SubjectContext,
484 &GenericMapping,
485 PagedPool);
486 KmtEndSeh(STATUS_ACCESS_VIOLATION);
487 ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
488
489 SecurityDescriptor = KmtInvalidPointer;
490 KmtStartSeh()
491 Status = SeAssignSecurity(NULL,
492 NULL,
493 &SecurityDescriptor,
494 FALSE,
495 NULL,
496 &GenericMapping,
497 PagedPool);
498 ok_eq_hex(Status, STATUS_NO_TOKEN);
499 KmtEndSeh(STATUS_SUCCESS);
500 ok_eq_pointer(SecurityDescriptor, NULL);
501 ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
502
503 ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
504 KmtStartSeh()
505 Status = SeAssignSecurity(NULL,
506 NULL,
507 NULL,
508 FALSE,
509 NULL,
510 &GenericMapping,
511 PagedPool);
512 KmtEndSeh(STATUS_ACCESS_VIOLATION);
513 ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
514
515 /* Test with Token == NULL */
516 if (1)
517 {
518 /* Crash in SeLockSubjectContext while holding a critical region */
519 SubjectContext->PrimaryToken = NULL;
520 KmtStartSeh()
521 SecurityDescriptor = KmtInvalidPointer;
522 Status = SeAssignSecurity(NULL,
523 NULL,
524 &SecurityDescriptor,
525 FALSE,
526 SubjectContext,
527 &GenericMapping,
528 PagedPool);
529 KmtEndSeh(STATUS_ACCESS_VIOLATION)
530 ok_bool_true(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
531 KeLeaveCriticalRegion();
532 ok_eq_pointer(SecurityDescriptor, KmtInvalidPointer);
533 SubjectContext->PrimaryToken = Token;
534 }
535 ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
536
537 /* Test with NULL owner in Token */
538 if (1)
539 {
540 /* Crash after locking the subject context */
541 PSID OldOwner;
542 OldOwner = Token->UserAndGroups[Token->DefaultOwnerIndex].Sid;
543 Token->UserAndGroups[Token->DefaultOwnerIndex].Sid = NULL;
544 KmtStartSeh()
545 SecurityDescriptor = KmtInvalidPointer;
546 Status = SeAssignSecurity(NULL,
547 NULL,
548 &SecurityDescriptor,
549 FALSE,
550 SubjectContext,
551 &GenericMapping,
552 PagedPool);
553 KmtEndSeh(STATUS_ACCESS_VIOLATION)
554 ok_bool_true(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
555 SeUnlockSubjectContext(SubjectContext);
556 ok_eq_pointer(SecurityDescriptor, KmtInvalidPointer);
557 Token->UserAndGroups[Token->DefaultOwnerIndex].Sid = OldOwner;
558 }
559 ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
560
561 /* Test with NULL group in Token */
562 if (1)
563 {
564 PSID OldGroup;
565 OldGroup = Token->PrimaryGroup;
566 Token->PrimaryGroup = NULL;
567 KmtStartSeh()
568 SecurityDescriptor = KmtInvalidPointer;
569 Status = SeAssignSecurity(NULL,
570 NULL,
571 &SecurityDescriptor,
572 FALSE,
573 SubjectContext,
574 &GenericMapping,
575 PagedPool);
576 ok_eq_hex(Status, STATUS_INVALID_PRIMARY_GROUP);
577 ok_eq_pointer(SecurityDescriptor, NULL);
578 SeDeassignSecurity(&SecurityDescriptor);
579 KmtEndSeh(STATUS_SUCCESS);
580 Token->PrimaryGroup = OldGroup;
581 }
582 ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
583
584 /* Test with NULL DACL in Token */
585 if (1)
586 {
587 PACL OldDacl;
588 OldDacl = Token->DefaultDacl;
589 Token->DefaultDacl = NULL;
590 KmtStartSeh()
591 StartTestAssign(NULL, NULL, FALSE, FALSE, FALSE)
592 ok_eq_uint(OwnerDefaulted, FALSE);
593 CheckSid(Owner, NO_SIZE, Token->UserAndGroups[Token->DefaultOwnerIndex].Sid);
594 ok_eq_uint(GroupDefaulted, FALSE);
595 CheckSid(Group, NO_SIZE, Token->PrimaryGroup);
596 EndTestAssign()
597 KmtEndSeh(STATUS_SUCCESS);
598 Token->DefaultDacl = OldDacl;
599 }
600 ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
601
602 /* SEF_DEFAULT_OWNER_FROM_PARENT/SEF_DEFAULT_GROUP_FROM_PARENT */
603 SecurityDescriptor = KmtInvalidPointer;
604 Status = SeAssignSecurityEx(NULL,
605 NULL,
606 &SecurityDescriptor,
607 NULL,
608 FALSE,
609 SEF_DEFAULT_OWNER_FROM_PARENT,
610 SubjectContext,
611 &GenericMapping,
612 PagedPool);
613 ok_eq_hex(Status, STATUS_INVALID_OWNER);
614 ok_eq_pointer(SecurityDescriptor, NULL);
615 SeDeassignSecurity(&SecurityDescriptor);
616 SecurityDescriptor = KmtInvalidPointer;
617 Status = SeAssignSecurityEx(NULL,
618 NULL,
619 &SecurityDescriptor,
620 NULL,
621 FALSE,
622 SEF_DEFAULT_GROUP_FROM_PARENT,
623 SubjectContext,
624 &GenericMapping,
625 PagedPool);
626 ok_eq_hex(Status, STATUS_INVALID_PRIMARY_GROUP);
627 ok_eq_pointer(SecurityDescriptor, NULL);
628 SeDeassignSecurity(&SecurityDescriptor);
629 SecurityDescriptor = KmtInvalidPointer;
630 Status = SeAssignSecurityEx(NULL,
631 NULL,
632 &SecurityDescriptor,
633 NULL,
634 FALSE,
635 SEF_DEFAULT_OWNER_FROM_PARENT | SEF_DEFAULT_GROUP_FROM_PARENT,
636 SubjectContext,
637 &GenericMapping,
638 PagedPool);
639 ok_eq_hex(Status, STATUS_INVALID_OWNER);
640 ok_eq_pointer(SecurityDescriptor, NULL);
641 SeDeassignSecurity(&SecurityDescriptor);
642
643 /* Quick test whether inheritance for SACLs behaves the same as DACLs */
644 Status = RtlSetDaclSecurityDescriptor(&ParentDescriptor,
645 FALSE,
646 NULL,
647 FALSE);
648 ok_eq_hex(Status, STATUS_SUCCESS);
649 Status = RtlSetDaclSecurityDescriptor(&ExplicitDescriptor,
650 FALSE,
651 NULL,
652 FALSE);
653 ok_eq_hex(Status, STATUS_SUCCESS);
654 for (UsingDefault = 0; UsingDefault <= 3; UsingDefault++)
655 {
656 Status = RtlSetSaclSecurityDescriptor(&ParentDescriptor,
657 TRUE,
658 NULL,
659 BooleanFlagOn(UsingDefault, 1));
660 ok_eq_hex(Status, STATUS_SUCCESS);
661 Status = RtlSetSaclSecurityDescriptor(&ExplicitDescriptor,
662 TRUE,
663 NULL,
664 BooleanFlagOn(UsingDefault, 2));
665 ok_eq_hex(Status, STATUS_SUCCESS);
666
667 TestAssignExpectDefault(&ParentDescriptor, NULL, FALSE)
668 TestAssignExpectDefault(&ParentDescriptor, NULL, TRUE)
669 StartTestAssign(NULL, &ExplicitDescriptor, FALSE, TRUE, TRUE)
670 ok_eq_uint(DaclDefaulted, FALSE);
671 CheckAcl(Dacl, 2, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, STANDARD_RIGHTS_ALL | 0x800F,
672 ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, STANDARD_RIGHTS_READ | 0x0005);
673 ok_eq_uint(SaclDefaulted, FALSE);
674 ok_eq_pointer(Sacl, NULL);
675 ok_eq_uint(OwnerDefaulted, FALSE);
676 CheckSid(Owner, NO_SIZE, Token->UserAndGroups[Token->DefaultOwnerIndex].Sid);
677 ok_eq_uint(GroupDefaulted, FALSE);
678 CheckSid(Group, NO_SIZE, Token->PrimaryGroup);
679 EndTestAssign()
680 }
681
682 for (UsingDefault = 0; UsingDefault <= 3; UsingDefault++)
683 {
684 Status = RtlSetSaclSecurityDescriptor(&ParentDescriptor,
685 TRUE,
686 &EmptyAcl,
687 BooleanFlagOn(UsingDefault, 1));
688 ok_eq_hex(Status, STATUS_SUCCESS);
689 Status = RtlSetSaclSecurityDescriptor(&ExplicitDescriptor,
690 TRUE,
691 &EmptyAcl,
692 BooleanFlagOn(UsingDefault, 2));
693 ok_eq_hex(Status, STATUS_SUCCESS);
694
695 TestAssignExpectDefault(&ParentDescriptor, NULL, FALSE)
696 TestAssignExpectDefault(&ParentDescriptor, NULL, TRUE)
697 StartTestAssign(NULL, &ExplicitDescriptor, FALSE, TRUE, TRUE)
698 ok_eq_uint(DaclDefaulted, FALSE);
699 CheckAcl(Dacl, 2, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, STANDARD_RIGHTS_ALL | 0x800F,
700 ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, STANDARD_RIGHTS_READ | 0x0005);
701 ok_eq_uint(SaclDefaulted, FALSE);
702 CheckAcl(Sacl, 0);
703 ok_eq_uint(OwnerDefaulted, FALSE);
704 CheckSid(Owner, NO_SIZE, Token->UserAndGroups[Token->DefaultOwnerIndex].Sid);
705 ok_eq_uint(GroupDefaulted, FALSE);
706 CheckSid(Group, NO_SIZE, Token->PrimaryGroup);
707 EndTestAssign()
708 }
709
710 for (UsingDefault = 0; UsingDefault <= 3; UsingDefault++)
711 {
712 Status = RtlCreateAcl(Acl, AclSize, ACL_REVISION);
713 ok_eq_hex(Status, STATUS_SUCCESS);
714 Status = RtlxAddAuditAccessAceEx(Acl, ACL_REVISION, 0, READ_CONTROL, SeExports->SeWorldSid, TRUE, TRUE);
715 ok_eq_hex(Status, STATUS_SUCCESS);
716 Status = RtlSetSaclSecurityDescriptor(&ParentDescriptor,
717 TRUE,
718 Acl,
719 BooleanFlagOn(UsingDefault, 1));
720 ok_eq_hex(Status, STATUS_SUCCESS);
721 Status = RtlSetSaclSecurityDescriptor(&ExplicitDescriptor,
722 TRUE,
723 Acl,
724 BooleanFlagOn(UsingDefault, 2));
725 ok_eq_hex(Status, STATUS_SUCCESS);
726
727 TestAssignExpectDefault(&ParentDescriptor, NULL, FALSE)
728 TestAssignExpectDefault(&ParentDescriptor, NULL, TRUE)
729 StartTestAssign(NULL, &ExplicitDescriptor, FALSE, TRUE, TRUE)
730 ok_eq_uint(DaclDefaulted, FALSE);
731 CheckAcl(Dacl, 2, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, STANDARD_RIGHTS_ALL | 0x800F,
732 ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, STANDARD_RIGHTS_READ | 0x0005);
733 ok_eq_uint(SaclDefaulted, FALSE);
734 CheckAcl(Sacl, 1, SYSTEM_AUDIT_ACE_TYPE, SUCCESSFUL_ACCESS_ACE_FLAG | FAILED_ACCESS_ACE_FLAG, SeExports->SeWorldSid, READ_CONTROL);
735 ok_eq_uint(OwnerDefaulted, FALSE);
736 CheckSid(Owner, NO_SIZE, Token->UserAndGroups[Token->DefaultOwnerIndex].Sid);
737 ok_eq_uint(GroupDefaulted, FALSE);
738 CheckSid(Group, NO_SIZE, Token->PrimaryGroup);
739 EndTestAssign()
740 }
741
742 for (UsingDefault = 0; UsingDefault <= 3; UsingDefault++)
743 {
744 Status = RtlCreateAcl(Acl, AclSize, ACL_REVISION);
745 ok_eq_hex(Status, STATUS_SUCCESS);
746 Status = RtlxAddAuditAccessAceEx(Acl, ACL_REVISION, OBJECT_INHERIT_ACE, READ_CONTROL, SeExports->SeCreatorOwnerSid, TRUE, TRUE);
747 ok_eq_hex(Status, STATUS_SUCCESS);
748 Status = RtlSetSaclSecurityDescriptor(&ParentDescriptor,
749 TRUE,
750 Acl,
751 BooleanFlagOn(UsingDefault, 1));
752 ok_eq_hex(Status, STATUS_SUCCESS);
753 Status = RtlSetSaclSecurityDescriptor(&ExplicitDescriptor,
754 TRUE,
755 Acl,
756 BooleanFlagOn(UsingDefault, 2));
757 ok_eq_hex(Status, STATUS_SUCCESS);
758
759 StartTestAssign(&ParentDescriptor, NULL, FALSE, TRUE, TRUE)
760 ok_eq_uint(DaclDefaulted, FALSE);
761 CheckAcl(Dacl, 2, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, STANDARD_RIGHTS_ALL | 0x800F,
762 ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, STANDARD_RIGHTS_READ | 0x0005);
763 ok_eq_uint(SaclDefaulted, FALSE);
764 CheckAcl(Sacl, 1, SYSTEM_AUDIT_ACE_TYPE, SUCCESSFUL_ACCESS_ACE_FLAG | FAILED_ACCESS_ACE_FLAG, Token->UserAndGroups[Token->DefaultOwnerIndex].Sid, READ_CONTROL);
765 ok_eq_uint(OwnerDefaulted, FALSE);
766 CheckSid(Owner, NO_SIZE, Token->UserAndGroups[Token->DefaultOwnerIndex].Sid);
767 ok_eq_uint(GroupDefaulted, FALSE);
768 CheckSid(Group, NO_SIZE, Token->PrimaryGroup);
769 EndTestAssign()
770 StartTestAssign(NULL, &ExplicitDescriptor, FALSE, TRUE, TRUE)
771 ok_eq_uint(DaclDefaulted, FALSE);
772 CheckAcl(Dacl, 2, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, STANDARD_RIGHTS_ALL | 0x800F,
773 ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, STANDARD_RIGHTS_READ | 0x0005);
774 ok_eq_uint(SaclDefaulted, FALSE);
775 CheckAcl(Sacl, 1, SYSTEM_AUDIT_ACE_TYPE, OBJECT_INHERIT_ACE | SUCCESSFUL_ACCESS_ACE_FLAG | FAILED_ACCESS_ACE_FLAG, SeExports->SeCreatorOwnerSid, READ_CONTROL);
776 ok_eq_uint(OwnerDefaulted, FALSE);
777 CheckSid(Owner, NO_SIZE, Token->UserAndGroups[Token->DefaultOwnerIndex].Sid);
778 ok_eq_uint(GroupDefaulted, FALSE);
779 CheckSid(Group, NO_SIZE, Token->PrimaryGroup);
780 EndTestAssign()
781 }
782
783 /* TODO: Test duplicate ACEs */
784 /* TODO: Test INHERITED_ACE flag */
785 /* TODO: Test invalid ACE flags */
786 /* TODO: Test more AutoInheritFlags values */
787
788 ExFreePoolWithTag(Acl2, 'ASmK');
789 ExFreePoolWithTag(Acl, 'ASmK');
790 }
791
792 static
793 VOID
794 NTAPI
795 SystemThread(
796 _In_ PVOID Context)
797 {
798 SECURITY_SUBJECT_CONTEXT SubjectContext;
799 ok_eq_pointer(Context, NULL);
800
801 SeCaptureSubjectContext(&SubjectContext);
802 TestSeAssignSecurity(&SubjectContext);
803 /* TODO: Test SeSetSecurityDescrptorInfo[Ex] */
804 SeReleaseSubjectContext(&SubjectContext);
805 }
806
807 static
808 VOID
809 TestObRootSecurity(VOID)
810 {
811 NTSTATUS Status;
812 UNICODE_STRING ObjectPath = RTL_CONSTANT_STRING(L"\\");
813 OBJECT_ATTRIBUTES ObjectAttributes;
814 HANDLE Handle;
815 PVOID RootDirectory;
816 PSECURITY_DESCRIPTOR SecurityDescriptor;
817 BOOLEAN MemoryAllocated;
818 PACL Acl;
819 BOOLEAN Present;
820 BOOLEAN Defaulted;
821
822 InitializeObjectAttributes(&ObjectAttributes,
823 &ObjectPath,
824 OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
825 NULL,
826 NULL);
827 Status = ZwOpenDirectoryObject(&Handle,
828 0,
829 &ObjectAttributes);
830 ok_eq_hex(Status, STATUS_SUCCESS);
831 if (skip(NT_SUCCESS(Status), "No handle\n"))
832 return;
833 Status = ObReferenceObjectByHandle(Handle,
834 0,
835 NULL,
836 KernelMode,
837 &RootDirectory,
838 NULL);
839 ObCloseHandle(Handle, KernelMode);
840 ok_eq_hex(Status, STATUS_SUCCESS);
841 if (skip(NT_SUCCESS(Status), "No object\n"))
842 return;
843 Status = ObGetObjectSecurity(RootDirectory,
844 &SecurityDescriptor,
845 &MemoryAllocated);
846 ObDereferenceObject(RootDirectory);
847 ok_eq_hex(Status, STATUS_SUCCESS);
848 if (skip(NT_SUCCESS(Status), "No security\n"))
849 return;
850 Status = RtlGetDaclSecurityDescriptor(SecurityDescriptor,
851 &Present,
852 &Acl,
853 &Defaulted);
854 ok_eq_hex(Status, STATUS_SUCCESS);
855 ok_eq_uint(Present, TRUE);
856 if (!skip(NT_SUCCESS(Status) && Present, "No DACL\n"))
857 {
858 ok_eq_uint(Defaulted, FALSE);
859 CheckAcl(Acl, 4, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeWorldSid, STANDARD_RIGHTS_READ | DIRECTORY_TRAVERSE | DIRECTORY_QUERY,
860 ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, DIRECTORY_ALL_ACCESS,
861 ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, DIRECTORY_ALL_ACCESS,
862 ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeRestrictedSid, STANDARD_RIGHTS_READ | DIRECTORY_TRAVERSE | DIRECTORY_QUERY);
863 }
864 Status = RtlGetSaclSecurityDescriptor(SecurityDescriptor,
865 &Present,
866 &Acl,
867 &Defaulted);
868 ok_eq_hex(Status, STATUS_SUCCESS);
869 ok_eq_uint(Present, FALSE);
870 ObReleaseObjectSecurity(SecurityDescriptor, MemoryAllocated);
871 }
872
873 START_TEST(SeInheritance)
874 {
875 PKTHREAD Thread;
876
877 TestObRootSecurity();
878 Thread = KmtStartThread(SystemThread, NULL);
879 KmtFinishThread(Thread, NULL);
880 }