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>
11 static GENERIC_MAPPING GenericMapping
=
13 STANDARD_RIGHTS_READ
| 0x1001,
14 STANDARD_RIGHTS_WRITE
| 0x2002,
15 STANDARD_RIGHTS_EXECUTE
| 0x4004,
16 STANDARD_RIGHTS_ALL
| 0x800F,
22 _In_ PSECURITY_SUBJECT_CONTEXT SubjectContext
)
26 PSECURITY_DESCRIPTOR SecurityDescriptor
;
27 SECURITY_DESCRIPTOR ParentDescriptor
;
28 SECURITY_DESCRIPTOR ExplicitDescriptor
;
40 ACCESS_MASK GenericMask
;
41 ACCESS_MASK GenericMask2
;
43 ACCESS_MASK SpecificMask
;
44 ACCESS_MASK SpecificMask2
;
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, \
57 &SecurityDescriptor, \
64 ok_eq_hex(Status, STATUS_SUCCESS); \
65 if (!skip(NT_SUCCESS(Status), "No security\n")) \
70 BOOLEAN DaclDefaulted, SaclDefaulted; \
71 BOOLEAN OwnerDefaulted, GroupDefaulted; \
72 Status = RtlGetDaclSecurityDescriptor(SecurityDescriptor, \
76 ok_eq_hex(Status, STATUS_SUCCESS); \
77 ok_eq_uint(Present, GotDacl); \
78 if (!NT_SUCCESS(Status) || !Present) \
80 Status = RtlGetSaclSecurityDescriptor(SecurityDescriptor, \
84 ok_eq_hex(Status, STATUS_SUCCESS); \
85 ok_eq_uint(Present, GotSacl); \
86 if (!NT_SUCCESS(Status) || !Present) \
88 Status = RtlGetOwnerSecurityDescriptor(SecurityDescriptor, \
91 ok_eq_hex(Status, STATUS_SUCCESS); \
92 if (skip(NT_SUCCESS(Status), "No owner\n")) \
94 Status = RtlGetGroupSecurityDescriptor(SecurityDescriptor, \
97 ok_eq_hex(Status, STATUS_SUCCESS); \
98 if (skip(NT_SUCCESS(Status), "No group\n")) \
101 #define EndTestAssign() \
102 SeDeassignSecurity(&SecurityDescriptor); \
104 #define StartTestAssignLoop(Parent, Explicit) \
107 BOOLEAN UsingParent; \
108 BOOLEAN UsingExplicit; \
109 for (IsDir = FALSE; IsDir <= TRUE; IsDir++) \
111 for (UsingParent = FALSE; UsingParent <= TRUE; UsingParent++) \
113 for (UsingExplicit = FALSE; UsingExplicit <= TRUE; UsingExplicit++) \
115 StartTestAssign(UsingParent ? Parent : NULL, \
116 UsingExplicit ? Explicit : NULL, \
120 #define EndTestAssignLoop() \
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); \
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)
144 TestAssignExpectDefault(NULL
, NULL
, FALSE
)
145 TestAssignExpectDefault(NULL
, NULL
, TRUE
)
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()
156 /* NULL DACL in parent/explicit descriptor */
157 for (UsingDefault
= FALSE
; UsingDefault
<= TRUE
; UsingDefault
++)
159 Status
= RtlSetDaclSecurityDescriptor(&ParentDescriptor
,
163 ok_eq_hex(Status
, STATUS_SUCCESS
);
164 Status
= RtlSetDaclSecurityDescriptor(&ExplicitDescriptor
,
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
);
174 ok(Dacl
== NULL
, "Dacl = %p\n", Dacl
);
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);
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
);
188 /* Empty default DACL in parent/explicit descriptor */
189 for (UsingDefault
= FALSE
; UsingDefault
<= TRUE
; UsingDefault
++)
191 Status
= RtlCreateAcl(&EmptyAcl
, sizeof(EmptyAcl
), ACL_REVISION
);
192 ok_eq_hex(Status
, STATUS_SUCCESS
);
193 Status
= RtlSetDaclSecurityDescriptor(&ParentDescriptor
,
197 ok_eq_hex(Status
, STATUS_SUCCESS
);
198 Status
= RtlSetDaclSecurityDescriptor(&ExplicitDescriptor
,
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
);
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);
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
);
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"))
228 Acl2
= ExAllocatePoolWithTag(PagedPool
, AclSize
, 'ASmK');
229 if (skip(Acl2
!= NULL
, "Out of memory\n"))
231 ExFreePoolWithTag(Acl
, 'ASmK');
235 /* Simple DACL in parent/explicit descriptor */
236 for (UsingDefault
= 0; UsingDefault
<= 3; UsingDefault
++)
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
,
245 BooleanFlagOn(UsingDefault
, 1));
246 ok_eq_hex(Status
, STATUS_SUCCESS
);
247 Status
= RtlSetDaclSecurityDescriptor(&ExplicitDescriptor
,
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
);
257 CheckAcl(Dacl
, 1, ACCESS_ALLOWED_ACE_TYPE
, 0, SeExports
->SeWorldSid
, READ_CONTROL
);
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);
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
);
271 /* Object-inheritable DACL in parent/explicit descriptor */
272 for (UsingDefault
= 0; UsingDefault
<= 3; UsingDefault
++)
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
,
281 BooleanFlagOn(UsingDefault
, 1));
282 ok_eq_hex(Status
, STATUS_SUCCESS
);
283 Status
= RtlSetDaclSecurityDescriptor(&ExplicitDescriptor
,
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)))
293 CheckAcl(Dacl
, 1, ACCESS_ALLOWED_ACE_TYPE
, OBJECT_INHERIT_ACE
, SeExports
->SeWorldSid
, READ_CONTROL
);
295 else if (UsingParent
)
297 CheckAcl(Dacl
, 1, ACCESS_ALLOWED_ACE_TYPE
, IsDir
? INHERIT_ONLY_ACE
| OBJECT_INHERIT_ACE
: 0, SeExports
->SeWorldSid
, READ_CONTROL
);
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);
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
);
311 /* Container-inheritable DACL in parent/explicit descriptor */
312 for (UsingDefault
= 0; UsingDefault
<= 3; UsingDefault
++)
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
,
321 BooleanFlagOn(UsingDefault
, 1));
322 ok_eq_hex(Status
, STATUS_SUCCESS
);
323 Status
= RtlSetDaclSecurityDescriptor(&ExplicitDescriptor
,
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
))
333 CheckAcl(Dacl
, 1, ACCESS_ALLOWED_ACE_TYPE
, CONTAINER_INHERIT_ACE
, SeExports
->SeWorldSid
, READ_CONTROL
);
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);
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
);
347 /* Fully inheritable DACL in parent/explicit descriptor */
348 for (UsingDefault
= 0; UsingDefault
<= 3; UsingDefault
++)
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
,
357 BooleanFlagOn(UsingDefault
, 1));
358 ok_eq_hex(Status
, STATUS_SUCCESS
);
359 Status
= RtlSetDaclSecurityDescriptor(&ExplicitDescriptor
,
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)))
369 CheckAcl(Dacl
, 1, ACCESS_ALLOWED_ACE_TYPE
, OBJECT_INHERIT_ACE
| CONTAINER_INHERIT_ACE
, SeExports
->SeWorldSid
, READ_CONTROL
);
371 else if (UsingParent
)
373 CheckAcl(Dacl
, 1, ACCESS_ALLOWED_ACE_TYPE
, IsDir
? OBJECT_INHERIT_ACE
| CONTAINER_INHERIT_ACE
: 0, SeExports
->SeWorldSid
, READ_CONTROL
);
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);
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
);
387 /* Different DACLs in parent and explicit descriptors */
388 for (Access
= 0; Access
<= 1; Access
++)
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;
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
;
410 for (CanInherit
= 0; CanInherit
<= 255; CanInherit
++)
412 for (UsingDefault
= 0; UsingDefault
<= 3; UsingDefault
++)
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
,
427 BooleanFlagOn(UsingDefault
, 1));
428 ok_eq_hex(Status
, STATUS_SUCCESS
);
429 Status
= RtlSetDaclSecurityDescriptor(&ExplicitDescriptor
,
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
;
444 if (UsingExplicit
&& (!FlagOn(UsingDefault
, 2) || !ParentUsable
))
446 CheckAcl(Dacl
, 1, ACCESS_ALLOWED_ACE_TYPE
, AceFlags2
, GenericSid2
, FlagOn(AceFlags2
, INHERIT_ONLY_ACE
) ? GenericMask2
: SpecificMask2
);
448 else if (ParentUsable
)
450 if (IsDir
&& !FlagOn(AceFlags
, NO_PROPAGATE_INHERIT_ACE
))
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
);
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
);
460 CheckAcl(Dacl
, 1, ACCESS_ALLOWED_ACE_TYPE
, 0, SpecificSid
, SpecificMask
);
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);
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
);
476 /* NULL parameters */
477 ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
479 Status
= SeAssignSecurity(NULL
,
486 KmtEndSeh(STATUS_ACCESS_VIOLATION
);
487 ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
489 SecurityDescriptor
= KmtInvalidPointer
;
491 Status
= SeAssignSecurity(NULL
,
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");
503 ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
505 Status
= SeAssignSecurity(NULL
,
512 KmtEndSeh(STATUS_ACCESS_VIOLATION
);
513 ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
515 /* Test with Token == NULL */
518 /* Crash in SeLockSubjectContext while holding a critical region */
519 SubjectContext
->PrimaryToken
= NULL
;
521 SecurityDescriptor
= KmtInvalidPointer
;
522 Status
= SeAssignSecurity(NULL
,
529 KmtEndSeh(STATUS_ACCESS_VIOLATION
)
530 ok_bool_true(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
531 KeLeaveCriticalRegion();
532 ok_eq_pointer(SecurityDescriptor
, KmtInvalidPointer
);
533 SubjectContext
->PrimaryToken
= Token
;
535 ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
537 /* Test with NULL owner in Token */
540 /* Crash after locking the subject context */
542 OldOwner
= Token
->UserAndGroups
[Token
->DefaultOwnerIndex
].Sid
;
543 Token
->UserAndGroups
[Token
->DefaultOwnerIndex
].Sid
= NULL
;
545 SecurityDescriptor
= KmtInvalidPointer
;
546 Status
= SeAssignSecurity(NULL
,
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
;
559 ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
561 /* Test with NULL group in Token */
565 OldGroup
= Token
->PrimaryGroup
;
566 Token
->PrimaryGroup
= NULL
;
568 SecurityDescriptor
= KmtInvalidPointer
;
569 Status
= SeAssignSecurity(NULL
,
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
;
582 ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
584 /* Test with NULL DACL in Token */
588 OldDacl
= Token
->DefaultDacl
;
589 Token
->DefaultDacl
= NULL
;
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
);
597 KmtEndSeh(STATUS_SUCCESS
);
598 Token
->DefaultDacl
= OldDacl
;
600 ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
602 /* SEF_DEFAULT_OWNER_FROM_PARENT/SEF_DEFAULT_GROUP_FROM_PARENT */
603 SecurityDescriptor
= KmtInvalidPointer
;
604 Status
= SeAssignSecurityEx(NULL
,
609 SEF_DEFAULT_OWNER_FROM_PARENT
,
613 ok_eq_hex(Status
, STATUS_INVALID_OWNER
);
614 ok_eq_pointer(SecurityDescriptor
, NULL
);
615 SeDeassignSecurity(&SecurityDescriptor
);
616 SecurityDescriptor
= KmtInvalidPointer
;
617 Status
= SeAssignSecurityEx(NULL
,
622 SEF_DEFAULT_GROUP_FROM_PARENT
,
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
,
635 SEF_DEFAULT_OWNER_FROM_PARENT
| SEF_DEFAULT_GROUP_FROM_PARENT
,
639 ok_eq_hex(Status
, STATUS_INVALID_OWNER
);
640 ok_eq_pointer(SecurityDescriptor
, NULL
);
641 SeDeassignSecurity(&SecurityDescriptor
);
643 /* Quick test whether inheritance for SACLs behaves the same as DACLs */
644 Status
= RtlSetDaclSecurityDescriptor(&ParentDescriptor
,
648 ok_eq_hex(Status
, STATUS_SUCCESS
);
649 Status
= RtlSetDaclSecurityDescriptor(&ExplicitDescriptor
,
653 ok_eq_hex(Status
, STATUS_SUCCESS
);
654 for (UsingDefault
= 0; UsingDefault
<= 3; UsingDefault
++)
656 Status
= RtlSetSaclSecurityDescriptor(&ParentDescriptor
,
659 BooleanFlagOn(UsingDefault
, 1));
660 ok_eq_hex(Status
, STATUS_SUCCESS
);
661 Status
= RtlSetSaclSecurityDescriptor(&ExplicitDescriptor
,
664 BooleanFlagOn(UsingDefault
, 2));
665 ok_eq_hex(Status
, STATUS_SUCCESS
);
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
);
682 for (UsingDefault
= 0; UsingDefault
<= 3; UsingDefault
++)
684 Status
= RtlSetSaclSecurityDescriptor(&ParentDescriptor
,
687 BooleanFlagOn(UsingDefault
, 1));
688 ok_eq_hex(Status
, STATUS_SUCCESS
);
689 Status
= RtlSetSaclSecurityDescriptor(&ExplicitDescriptor
,
692 BooleanFlagOn(UsingDefault
, 2));
693 ok_eq_hex(Status
, STATUS_SUCCESS
);
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
);
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
);
710 for (UsingDefault
= 0; UsingDefault
<= 3; UsingDefault
++)
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
,
719 BooleanFlagOn(UsingDefault
, 1));
720 ok_eq_hex(Status
, STATUS_SUCCESS
);
721 Status
= RtlSetSaclSecurityDescriptor(&ExplicitDescriptor
,
724 BooleanFlagOn(UsingDefault
, 2));
725 ok_eq_hex(Status
, STATUS_SUCCESS
);
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
);
742 for (UsingDefault
= 0; UsingDefault
<= 3; UsingDefault
++)
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
,
751 BooleanFlagOn(UsingDefault
, 1));
752 ok_eq_hex(Status
, STATUS_SUCCESS
);
753 Status
= RtlSetSaclSecurityDescriptor(&ExplicitDescriptor
,
756 BooleanFlagOn(UsingDefault
, 2));
757 ok_eq_hex(Status
, STATUS_SUCCESS
);
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
);
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
);
783 /* TODO: Test duplicate ACEs */
784 /* TODO: Test INHERITED_ACE flag */
785 /* TODO: Test invalid ACE flags */
786 /* TODO: Test more AutoInheritFlags values */
788 ExFreePoolWithTag(Acl2
, 'ASmK');
789 ExFreePoolWithTag(Acl
, 'ASmK');
798 SECURITY_SUBJECT_CONTEXT SubjectContext
;
799 ok_eq_pointer(Context
, NULL
);
801 SeCaptureSubjectContext(&SubjectContext
);
802 TestSeAssignSecurity(&SubjectContext
);
803 /* TODO: Test SeSetSecurityDescrptorInfo[Ex] */
804 SeReleaseSubjectContext(&SubjectContext
);
809 TestObRootSecurity(VOID
)
812 UNICODE_STRING ObjectPath
= RTL_CONSTANT_STRING(L
"\\");
813 OBJECT_ATTRIBUTES ObjectAttributes
;
816 PSECURITY_DESCRIPTOR SecurityDescriptor
;
817 BOOLEAN MemoryAllocated
;
822 InitializeObjectAttributes(&ObjectAttributes
,
824 OBJ_KERNEL_HANDLE
| OBJ_CASE_INSENSITIVE
,
827 Status
= ZwOpenDirectoryObject(&Handle
,
830 ok_eq_hex(Status
, STATUS_SUCCESS
);
831 if (skip(NT_SUCCESS(Status
), "No handle\n"))
833 Status
= ObReferenceObjectByHandle(Handle
,
839 ObCloseHandle(Handle
, KernelMode
);
840 ok_eq_hex(Status
, STATUS_SUCCESS
);
841 if (skip(NT_SUCCESS(Status
), "No object\n"))
843 Status
= ObGetObjectSecurity(RootDirectory
,
846 ObDereferenceObject(RootDirectory
);
847 ok_eq_hex(Status
, STATUS_SUCCESS
);
848 if (skip(NT_SUCCESS(Status
), "No security\n"))
850 Status
= RtlGetDaclSecurityDescriptor(SecurityDescriptor
,
854 ok_eq_hex(Status
, STATUS_SUCCESS
);
855 ok_eq_uint(Present
, TRUE
);
856 if (!skip(NT_SUCCESS(Status
) && Present
, "No DACL\n"))
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
);
864 Status
= RtlGetSaclSecurityDescriptor(SecurityDescriptor
,
868 ok_eq_hex(Status
, STATUS_SUCCESS
);
869 ok_eq_uint(Present
, FALSE
);
870 ObReleaseObjectSecurity(SecurityDescriptor
, MemoryAllocated
);
873 START_TEST(SeInheritance
)
877 TestObRootSecurity();
878 Thread
= KmtStartThread(SystemThread
, NULL
);
879 KmtFinishThread(Thread
, NULL
);