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
TestSeAssignSecurity(_In_ PSECURITY_SUBJECT_CONTEXT SubjectContext)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     /* ACE type that Win2003 doesn't know about (> ACCESS_MAX_MS_ACE_TYPE) */
784     for (UsingDefault = 0; UsingDefault <= 3; UsingDefault++)
785     {
786         Status = RtlCreateAcl(Acl, AclSize, ACL_REVISION);
787         ok_eq_hex(Status, STATUS_SUCCESS);
788         Status = RtlxAddMandatoryLabelAceEx(Acl, ACL_REVISION, 0, SYSTEM_MANDATORY_LABEL_NO_WRITE_UP, SeExports->SeWorldSid);
789         ok_eq_hex(Status, STATUS_SUCCESS);
790         Status = RtlSetSaclSecurityDescriptor(&ParentDescriptor,
791                                               TRUE,
792                                               Acl,
793                                               BooleanFlagOn(UsingDefault, 1));
794         ok_eq_hex(Status, STATUS_SUCCESS);
795         Status = RtlSetSaclSecurityDescriptor(&ExplicitDescriptor,
796                                               TRUE,
797                                               Acl,
798                                               BooleanFlagOn(UsingDefault, 2));
799         ok_eq_hex(Status, STATUS_SUCCESS);
800 
801         TestAssignExpectDefault(&ParentDescriptor, NULL, FALSE)
802         TestAssignExpectDefault(&ParentDescriptor, NULL, TRUE)
803         StartTestAssign(NULL, &ExplicitDescriptor, FALSE, TRUE, TRUE)
804             ok_eq_uint(DaclDefaulted, FALSE);
805             CheckAcl(Dacl, 2, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid,    STANDARD_RIGHTS_ALL | 0x800F,
806                               ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid,    STANDARD_RIGHTS_READ | 0x0005);
807             ok_eq_uint(SaclDefaulted, FALSE);
808             CheckAcl(Sacl, 1, SYSTEM_MANDATORY_LABEL_ACE_TYPE, 0, SeExports->SeWorldSid, SYSTEM_MANDATORY_LABEL_NO_WRITE_UP);
809             ok_eq_uint(OwnerDefaulted, FALSE);
810             CheckSid(Owner, NO_SIZE, Token->UserAndGroups[Token->DefaultOwnerIndex].Sid);
811             ok_eq_uint(GroupDefaulted, FALSE);
812             CheckSid(Group, NO_SIZE, Token->PrimaryGroup);
813         EndTestAssign()
814     }
815 
816     for (UsingDefault = 0; UsingDefault <= 3; UsingDefault++)
817     {
818         Status = RtlCreateAcl(Acl, AclSize, ACL_REVISION);
819         ok_eq_hex(Status, STATUS_SUCCESS);
820         Status = RtlxAddMandatoryLabelAceEx(Acl, ACL_REVISION, OBJECT_INHERIT_ACE, SYSTEM_MANDATORY_LABEL_NO_WRITE_UP, SeExports->SeCreatorOwnerSid);
821         ok_eq_hex(Status, STATUS_SUCCESS);
822         Status = RtlSetSaclSecurityDescriptor(&ParentDescriptor,
823                                               TRUE,
824                                               Acl,
825                                               BooleanFlagOn(UsingDefault, 1));
826         ok_eq_hex(Status, STATUS_SUCCESS);
827         Status = RtlSetSaclSecurityDescriptor(&ExplicitDescriptor,
828                                               TRUE,
829                                               Acl,
830                                               BooleanFlagOn(UsingDefault, 2));
831         ok_eq_hex(Status, STATUS_SUCCESS);
832 
833         StartTestAssign(&ParentDescriptor, NULL, FALSE, TRUE, TRUE)
834             ok_eq_uint(DaclDefaulted, FALSE);
835             CheckAcl(Dacl, 2, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid,    STANDARD_RIGHTS_ALL | 0x800F,
836                               ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid,    STANDARD_RIGHTS_READ | 0x0005);
837             ok_eq_uint(SaclDefaulted, FALSE);
838             CheckAcl(Sacl, 1, SYSTEM_MANDATORY_LABEL_ACE_TYPE, 0, Token->UserAndGroups[Token->DefaultOwnerIndex].Sid, SYSTEM_MANDATORY_LABEL_NO_WRITE_UP);
839             ok_eq_uint(OwnerDefaulted, FALSE);
840             CheckSid(Owner, NO_SIZE, Token->UserAndGroups[Token->DefaultOwnerIndex].Sid);
841             ok_eq_uint(GroupDefaulted, FALSE);
842             CheckSid(Group, NO_SIZE, Token->PrimaryGroup);
843         EndTestAssign()
844         StartTestAssign(NULL, &ExplicitDescriptor, FALSE, TRUE, TRUE)
845             ok_eq_uint(DaclDefaulted, FALSE);
846             CheckAcl(Dacl, 2, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid,    STANDARD_RIGHTS_ALL | 0x800F,
847                               ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid,    STANDARD_RIGHTS_READ | 0x0005);
848             ok_eq_uint(SaclDefaulted, FALSE);
849             CheckAcl(Sacl, 1, SYSTEM_MANDATORY_LABEL_ACE_TYPE, OBJECT_INHERIT_ACE, SeExports->SeCreatorOwnerSid, SYSTEM_MANDATORY_LABEL_NO_WRITE_UP);
850             ok_eq_uint(OwnerDefaulted, FALSE);
851             CheckSid(Owner, NO_SIZE, Token->UserAndGroups[Token->DefaultOwnerIndex].Sid);
852             ok_eq_uint(GroupDefaulted, FALSE);
853             CheckSid(Group, NO_SIZE, Token->PrimaryGroup);
854         EndTestAssign()
855     }
856 
857     /* TODO: Test object/compound ACEs */
858     /* TODO: Test duplicate ACEs */
859     /* TODO: Test INHERITED_ACE flag */
860     /* TODO: Test invalid ACE flags */
861     /* TODO: Test more AutoInheritFlags values */
862 
863     ExFreePoolWithTag(Acl2, 'ASmK');
864     ExFreePoolWithTag(Acl, 'ASmK');
865 }
866 
867 static
868 VOID
869 NTAPI
SystemThread(_In_ PVOID Context)870 SystemThread(
871     _In_ PVOID Context)
872 {
873     SECURITY_SUBJECT_CONTEXT SubjectContext;
874     ok_eq_pointer(Context, NULL);
875 
876     SeCaptureSubjectContext(&SubjectContext);
877     TestSeAssignSecurity(&SubjectContext);
878     /* TODO: Test SeSetSecurityDescrptorInfo[Ex] */
879     SeReleaseSubjectContext(&SubjectContext);
880 }
881 
882 static
883 VOID
TestObRootSecurity(VOID)884 TestObRootSecurity(VOID)
885 {
886     NTSTATUS Status;
887     UNICODE_STRING ObjectPath = RTL_CONSTANT_STRING(L"\\");
888     OBJECT_ATTRIBUTES ObjectAttributes;
889     HANDLE Handle;
890     PVOID RootDirectory;
891     PSECURITY_DESCRIPTOR SecurityDescriptor;
892     BOOLEAN MemoryAllocated;
893     PACL Acl;
894     BOOLEAN Present;
895     BOOLEAN Defaulted;
896 
897     InitializeObjectAttributes(&ObjectAttributes,
898                                &ObjectPath,
899                                OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
900                                NULL,
901                                NULL);
902     Status = ZwOpenDirectoryObject(&Handle,
903                                    0,
904                                    &ObjectAttributes);
905     ok_eq_hex(Status, STATUS_SUCCESS);
906     if (skip(NT_SUCCESS(Status), "No handle\n"))
907         return;
908     Status = ObReferenceObjectByHandle(Handle,
909                                        0,
910                                        NULL,
911                                        KernelMode,
912                                        &RootDirectory,
913                                        NULL);
914     ObCloseHandle(Handle, KernelMode);
915     ok_eq_hex(Status, STATUS_SUCCESS);
916     if (skip(NT_SUCCESS(Status), "No object\n"))
917         return;
918     Status = ObGetObjectSecurity(RootDirectory,
919                                  &SecurityDescriptor,
920                                  &MemoryAllocated);
921     ObDereferenceObject(RootDirectory);
922     ok_eq_hex(Status, STATUS_SUCCESS);
923     if (skip(NT_SUCCESS(Status), "No security\n"))
924         return;
925     Status = RtlGetDaclSecurityDescriptor(SecurityDescriptor,
926                                           &Present,
927                                           &Acl,
928                                           &Defaulted);
929     ok_eq_hex(Status, STATUS_SUCCESS);
930     ok_eq_uint(Present, TRUE);
931     if (!skip(NT_SUCCESS(Status) && Present, "No DACL\n"))
932     {
933         ok_eq_uint(Defaulted, FALSE);
934         CheckAcl(Acl, 4, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeWorldSid,         STANDARD_RIGHTS_READ | DIRECTORY_TRAVERSE | DIRECTORY_QUERY,
935                          ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid,   DIRECTORY_ALL_ACCESS,
936                          ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid,   DIRECTORY_ALL_ACCESS,
937                          ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeRestrictedSid,    STANDARD_RIGHTS_READ | DIRECTORY_TRAVERSE | DIRECTORY_QUERY);
938     }
939     Status = RtlGetSaclSecurityDescriptor(SecurityDescriptor,
940                                           &Present,
941                                           &Acl,
942                                           &Defaulted);
943     ok_eq_hex(Status, STATUS_SUCCESS);
944     ok_eq_uint(Present, FALSE);
945     ObReleaseObjectSecurity(SecurityDescriptor, MemoryAllocated);
946 }
947 
START_TEST(SeInheritance)948 START_TEST(SeInheritance)
949 {
950     PKTHREAD Thread;
951 
952     TestObRootSecurity();
953     Thread = KmtStartThread(SystemThread, NULL);
954     KmtFinishThread(Thread, NULL);
955 }
956