1 /*
2  * PROJECT:         ReactOS kernel-mode tests
3  * LICENSE:         LGPLv2+ - See COPYING.LIB in the top level directory
4  * PURPOSE:         Kernel-Mode Test Suite NPFS security test
5  * PROGRAMMER:      Thomas Faber <thomas.faber@reactos.org>
6  */
7 
8 #include <kmt_test.h>
9 #include "../ntos_se/se.h"
10 
11 #define CheckKeySecurity(name, AceCount, ...) CheckKeySecurity_(name, AceCount, __FILE__, __LINE__, ##__VA_ARGS__)
12 #define CheckKeySecurity_(name, AceCount, file, line, ...) CheckKeySecurity__(name, AceCount, file ":" KMT_STRINGIZE(line), ##__VA_ARGS__)
13 static
14 VOID
15 CheckKeySecurity__(
16     _In_ PCWSTR KeyName,
17     _In_ ULONG AceCount,
18     _In_ PCSTR FileAndLine,
19     ...)
20 {
21     NTSTATUS Status;
22     UNICODE_STRING KeyNameString;
23     OBJECT_ATTRIBUTES ObjectAttributes;
24     HANDLE KeyHandle;
25     PSECURITY_DESCRIPTOR SecurityDescriptor;
26     ULONG SecurityDescriptorSize;
27     PSID Owner;
28     PSID Group;
29     PACL Dacl;
30     PACL Sacl;
31     BOOLEAN Present;
32     BOOLEAN Defaulted;
33     va_list Arguments;
34 
35     RtlInitUnicodeString(&KeyNameString, KeyName);
36     InitializeObjectAttributes(&ObjectAttributes,
37                                &KeyNameString,
38                                OBJ_KERNEL_HANDLE,
39                                NULL,
40                                NULL);
41     Status = ZwOpenKey(&KeyHandle,
42                        READ_CONTROL | ACCESS_SYSTEM_SECURITY,
43                        &ObjectAttributes);
44     ok_eq_hex(Status, STATUS_SUCCESS);
45     if (skip(NT_SUCCESS(Status), "No key (%ls)\n", KeyName))
46     {
47         return;
48     }
49 
50     Status = ZwQuerySecurityObject(KeyHandle,
51                                    OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION,
52                                    NULL,
53                                    0,
54                                    &SecurityDescriptorSize);
55     ok_eq_hex(Status, STATUS_BUFFER_TOO_SMALL);
56     if (skip(Status == STATUS_BUFFER_TOO_SMALL, "No security size (%ls)\n", KeyName))
57     {
58         ObCloseHandle(KeyHandle, KernelMode);
59         return;
60     }
61 
62     SecurityDescriptor = ExAllocatePoolWithTag(PagedPool,
63                                                SecurityDescriptorSize,
64                                                'dSmK');
65     ok(SecurityDescriptor != NULL, "Failed to allocate %lu bytes\n", SecurityDescriptorSize);
66     if (skip(SecurityDescriptor != NULL, "No memory for descriptor (%ls)\n", KeyName))
67     {
68         ObCloseHandle(KeyHandle, KernelMode);
69         return;
70     }
71 
72     Status = ZwQuerySecurityObject(KeyHandle,
73                                    OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION,
74                                    SecurityDescriptor,
75                                    SecurityDescriptorSize,
76                                    &SecurityDescriptorSize);
77     ok_eq_hex(Status, STATUS_SUCCESS);
78     if (NT_SUCCESS(Status))
79     {
80         Owner = NULL;
81         Status = RtlGetOwnerSecurityDescriptor(SecurityDescriptor,
82                                                &Owner,
83                                                &Defaulted);
84         CheckSid(Owner, NO_SIZE, SeExports->SeAliasAdminsSid);
85         ok(Defaulted == FALSE, "Owner defaulted for %ls\n", KeyName);
86 
87         Group = NULL;
88         Status = RtlGetGroupSecurityDescriptor(SecurityDescriptor,
89                                                &Group,
90                                                &Defaulted);
91         CheckSid(Group, NO_SIZE, SeExports->SeLocalSystemSid);
92         ok(Defaulted == FALSE, "Group defaulted for %ls\n", KeyName);
93 
94         Dacl = NULL;
95         Status = RtlGetDaclSecurityDescriptor(SecurityDescriptor,
96                                               &Present,
97                                               &Dacl,
98                                               &Defaulted);
99         ok_eq_hex(Status, STATUS_SUCCESS);
100         ok(Present == TRUE, "DACL not present for %ls\n", KeyName);
101         ok(Defaulted == FALSE, "DACL defaulted for %ls\n", KeyName);
102         va_start(Arguments, FileAndLine);
103         VCheckAcl__(Dacl, AceCount, FileAndLine, Arguments);
104         va_end(Arguments);
105 
106         Sacl = NULL;
107         Status = RtlGetSaclSecurityDescriptor(SecurityDescriptor,
108                                               &Present,
109                                               &Sacl,
110                                               &Defaulted);
111         ok_eq_hex(Status, STATUS_SUCCESS);
112         ok(Present == FALSE, "SACL present for %ls\n", KeyName);
113         ok(Defaulted == FALSE, "SACL defaulted for %ls\n", KeyName);
114         ok(Sacl == NULL, "Sacl is %p for %ls\n", Sacl, KeyName);
115     }
116     ExFreePoolWithTag(SecurityDescriptor, 'dSmK');
117     ObCloseHandle(KeyHandle, KernelMode);
118 }
119 
120 START_TEST(CmSecurity)
121 {
122     SID_IDENTIFIER_AUTHORITY NtSidAuthority = {SECURITY_NT_AUTHORITY};
123     PSID TerminalServerSid;
124 
125     TerminalServerSid = ExAllocatePoolWithTag(PagedPool,
126                                               RtlLengthRequiredSid(1),
127                                               'iSmK');
128     if (TerminalServerSid != NULL)
129     {
130         RtlInitializeSid(TerminalServerSid, &NtSidAuthority, 1);
131         *RtlSubAuthoritySid(TerminalServerSid, 0) = SECURITY_TERMINAL_SERVER_RID;
132     }
133     CheckKeySecurity(L"\\REGISTRY",
134                      4, ACCESS_ALLOWED_ACE_TYPE, CONTAINER_INHERIT_ACE, SeExports->SeLocalSystemSid, KEY_ALL_ACCESS,
135                         ACCESS_ALLOWED_ACE_TYPE, CONTAINER_INHERIT_ACE, SeExports->SeAliasAdminsSid, KEY_ALL_ACCESS,
136                         ACCESS_ALLOWED_ACE_TYPE, CONTAINER_INHERIT_ACE, SeExports->SeWorldSid,       KEY_READ,
137                         ACCESS_ALLOWED_ACE_TYPE, CONTAINER_INHERIT_ACE, SeExports->SeRestrictedSid,  KEY_READ);
138 
139     CheckKeySecurity(L"\\REGISTRY\\MACHINE",
140                      4, ACCESS_ALLOWED_ACE_TYPE, CONTAINER_INHERIT_ACE, SeExports->SeLocalSystemSid, KEY_ALL_ACCESS,
141                         ACCESS_ALLOWED_ACE_TYPE, CONTAINER_INHERIT_ACE, SeExports->SeAliasAdminsSid, KEY_ALL_ACCESS,
142                         ACCESS_ALLOWED_ACE_TYPE, CONTAINER_INHERIT_ACE, SeExports->SeWorldSid,       KEY_READ,
143                         ACCESS_ALLOWED_ACE_TYPE, CONTAINER_INHERIT_ACE, SeExports->SeRestrictedSid,  KEY_READ);
144 
145     CheckKeySecurity(L"\\REGISTRY\\MACHINE\\HARDWARE",
146                      4, ACCESS_ALLOWED_ACE_TYPE, CONTAINER_INHERIT_ACE, SeExports->SeLocalSystemSid, KEY_ALL_ACCESS,
147                         ACCESS_ALLOWED_ACE_TYPE, CONTAINER_INHERIT_ACE, SeExports->SeAliasAdminsSid, KEY_ALL_ACCESS,
148                         ACCESS_ALLOWED_ACE_TYPE, CONTAINER_INHERIT_ACE, SeExports->SeWorldSid,       KEY_READ,
149                         ACCESS_ALLOWED_ACE_TYPE, CONTAINER_INHERIT_ACE, SeExports->SeRestrictedSid,  KEY_READ);
150 
151     CheckKeySecurity(L"\\REGISTRY\\MACHINE\\SAM",
152                      4, ACCESS_ALLOWED_ACE_TYPE, CONTAINER_INHERIT_ACE, SeExports->SeLocalSystemSid, KEY_ALL_ACCESS,
153                         ACCESS_ALLOWED_ACE_TYPE, CONTAINER_INHERIT_ACE, SeExports->SeAliasAdminsSid, KEY_ALL_ACCESS,
154                         ACCESS_ALLOWED_ACE_TYPE, CONTAINER_INHERIT_ACE, SeExports->SeWorldSid,       KEY_READ,
155                         ACCESS_ALLOWED_ACE_TYPE, CONTAINER_INHERIT_ACE, SeExports->SeRestrictedSid,  KEY_READ);
156 
157     CheckKeySecurity(L"\\REGISTRY\\MACHINE\\SECURITY",
158                      2, ACCESS_ALLOWED_ACE_TYPE, CONTAINER_INHERIT_ACE, SeExports->SeLocalSystemSid, KEY_ALL_ACCESS,
159                         ACCESS_ALLOWED_ACE_TYPE, CONTAINER_INHERIT_ACE, SeExports->SeAliasAdminsSid, WRITE_DAC | READ_CONTROL);
160 
161     CheckKeySecurity(L"\\REGISTRY\\MACHINE\\SOFTWARE",
162                     12, ACCESS_ALLOWED_ACE_TYPE,                     0, SeExports->SeAliasUsersSid,      KEY_READ,
163                         ACCESS_ALLOWED_ACE_TYPE, INHERIT_ONLY_ACE |
164                                                  CONTAINER_INHERIT_ACE, SeExports->SeAliasUsersSid,      GENERIC_READ,
165                         ACCESS_ALLOWED_ACE_TYPE,                     0, SeExports->SeAliasPowerUsersSid, KEY_READ | KEY_WRITE | DELETE,
166                         ACCESS_ALLOWED_ACE_TYPE, INHERIT_ONLY_ACE |
167                                                  CONTAINER_INHERIT_ACE, SeExports->SeAliasPowerUsersSid, GENERIC_READ | GENERIC_WRITE | DELETE,
168                         ACCESS_ALLOWED_ACE_TYPE,                     0, SeExports->SeAliasAdminsSid,     KEY_ALL_ACCESS,
169                         ACCESS_ALLOWED_ACE_TYPE, INHERIT_ONLY_ACE |
170                                                  CONTAINER_INHERIT_ACE, SeExports->SeAliasAdminsSid,     GENERIC_ALL,
171                         ACCESS_ALLOWED_ACE_TYPE,                     0, SeExports->SeLocalSystemSid,     KEY_ALL_ACCESS,
172                         ACCESS_ALLOWED_ACE_TYPE, INHERIT_ONLY_ACE |
173                                                  CONTAINER_INHERIT_ACE, SeExports->SeLocalSystemSid,     GENERIC_ALL,
174                         ACCESS_ALLOWED_ACE_TYPE,                     0, SeExports->SeAliasAdminsSid,     KEY_ALL_ACCESS,
175                         ACCESS_ALLOWED_ACE_TYPE, INHERIT_ONLY_ACE |
176                                                  CONTAINER_INHERIT_ACE, SeExports->SeCreatorOwnerSid,    GENERIC_ALL,
177                         ACCESS_ALLOWED_ACE_TYPE,                     0, TerminalServerSid,               KEY_READ | KEY_WRITE | DELETE,
178                         ACCESS_ALLOWED_ACE_TYPE, INHERIT_ONLY_ACE |
179                                                  CONTAINER_INHERIT_ACE, TerminalServerSid,               GENERIC_READ | GENERIC_WRITE | DELETE);
180 
181     CheckKeySecurity(L"\\REGISTRY\\MACHINE\\SYSTEM",
182                     10, ACCESS_ALLOWED_ACE_TYPE,                     0, SeExports->SeAliasUsersSid,      KEY_READ,
183                         ACCESS_ALLOWED_ACE_TYPE, INHERIT_ONLY_ACE |
184                                                  CONTAINER_INHERIT_ACE, SeExports->SeAliasUsersSid,      GENERIC_READ,
185                         ACCESS_ALLOWED_ACE_TYPE,                     0, SeExports->SeAliasPowerUsersSid, KEY_READ,
186                         ACCESS_ALLOWED_ACE_TYPE, INHERIT_ONLY_ACE |
187                                                  CONTAINER_INHERIT_ACE, SeExports->SeAliasPowerUsersSid, GENERIC_READ,
188                         ACCESS_ALLOWED_ACE_TYPE,                     0, SeExports->SeAliasAdminsSid,     KEY_ALL_ACCESS,
189                         ACCESS_ALLOWED_ACE_TYPE, INHERIT_ONLY_ACE |
190                                                  CONTAINER_INHERIT_ACE, SeExports->SeAliasAdminsSid,     GENERIC_ALL,
191                         ACCESS_ALLOWED_ACE_TYPE,                     0, SeExports->SeLocalSystemSid,     KEY_ALL_ACCESS,
192                         ACCESS_ALLOWED_ACE_TYPE, INHERIT_ONLY_ACE |
193                                                  CONTAINER_INHERIT_ACE, SeExports->SeLocalSystemSid,     GENERIC_ALL,
194                         ACCESS_ALLOWED_ACE_TYPE,                     0, SeExports->SeAliasAdminsSid,     KEY_ALL_ACCESS,
195                         ACCESS_ALLOWED_ACE_TYPE, INHERIT_ONLY_ACE |
196                                                  CONTAINER_INHERIT_ACE, SeExports->SeCreatorOwnerSid,    GENERIC_ALL);
197 
198     CheckKeySecurity(L"\\REGISTRY\\USER",
199                      4, ACCESS_ALLOWED_ACE_TYPE, CONTAINER_INHERIT_ACE, SeExports->SeLocalSystemSid, KEY_ALL_ACCESS,
200                         ACCESS_ALLOWED_ACE_TYPE, CONTAINER_INHERIT_ACE, SeExports->SeAliasAdminsSid, KEY_ALL_ACCESS,
201                         ACCESS_ALLOWED_ACE_TYPE, CONTAINER_INHERIT_ACE, SeExports->SeWorldSid,       KEY_READ,
202                         ACCESS_ALLOWED_ACE_TYPE, CONTAINER_INHERIT_ACE, SeExports->SeRestrictedSid,  KEY_READ);
203 
204     CheckKeySecurity(L"\\REGISTRY\\USER\\.DEFAULT",
205                     10, ACCESS_ALLOWED_ACE_TYPE,                     0, SeExports->SeAliasUsersSid,      KEY_READ,
206                         ACCESS_ALLOWED_ACE_TYPE, INHERIT_ONLY_ACE |
207                                                  CONTAINER_INHERIT_ACE, SeExports->SeAliasUsersSid,      GENERIC_READ,
208                         ACCESS_ALLOWED_ACE_TYPE,                     0, SeExports->SeAliasPowerUsersSid, KEY_READ,
209                         ACCESS_ALLOWED_ACE_TYPE, INHERIT_ONLY_ACE |
210                                                  CONTAINER_INHERIT_ACE, SeExports->SeAliasPowerUsersSid, GENERIC_READ,
211                         ACCESS_ALLOWED_ACE_TYPE,                     0, SeExports->SeAliasAdminsSid,     KEY_ALL_ACCESS,
212                         ACCESS_ALLOWED_ACE_TYPE, INHERIT_ONLY_ACE |
213                                                  CONTAINER_INHERIT_ACE, SeExports->SeAliasAdminsSid,     GENERIC_ALL,
214                         ACCESS_ALLOWED_ACE_TYPE,                     0, SeExports->SeLocalSystemSid,     KEY_ALL_ACCESS,
215                         ACCESS_ALLOWED_ACE_TYPE, INHERIT_ONLY_ACE |
216                                                  CONTAINER_INHERIT_ACE, SeExports->SeLocalSystemSid,     GENERIC_ALL,
217                         ACCESS_ALLOWED_ACE_TYPE,                     0, SeExports->SeAliasAdminsSid,     KEY_ALL_ACCESS,
218                         ACCESS_ALLOWED_ACE_TYPE, INHERIT_ONLY_ACE |
219                                                  CONTAINER_INHERIT_ACE, SeExports->SeCreatorOwnerSid,    GENERIC_ALL);
220 
221     CheckKeySecurity(L"\\REGISTRY\\USER\\S-1-5-18",
222                     10, ACCESS_ALLOWED_ACE_TYPE,                     0, SeExports->SeAliasUsersSid,      KEY_READ,
223                         ACCESS_ALLOWED_ACE_TYPE, INHERIT_ONLY_ACE |
224                                                  CONTAINER_INHERIT_ACE, SeExports->SeAliasUsersSid,      GENERIC_READ,
225                         ACCESS_ALLOWED_ACE_TYPE,                     0, SeExports->SeAliasPowerUsersSid, KEY_READ,
226                         ACCESS_ALLOWED_ACE_TYPE, INHERIT_ONLY_ACE |
227                                                  CONTAINER_INHERIT_ACE, SeExports->SeAliasPowerUsersSid, GENERIC_READ,
228                         ACCESS_ALLOWED_ACE_TYPE,                     0, SeExports->SeAliasAdminsSid,     KEY_ALL_ACCESS,
229                         ACCESS_ALLOWED_ACE_TYPE, INHERIT_ONLY_ACE |
230                                                  CONTAINER_INHERIT_ACE, SeExports->SeAliasAdminsSid,     GENERIC_ALL,
231                         ACCESS_ALLOWED_ACE_TYPE,                     0, SeExports->SeLocalSystemSid,     KEY_ALL_ACCESS,
232                         ACCESS_ALLOWED_ACE_TYPE, INHERIT_ONLY_ACE |
233                                                  CONTAINER_INHERIT_ACE, SeExports->SeLocalSystemSid,     GENERIC_ALL,
234                         ACCESS_ALLOWED_ACE_TYPE,                     0, SeExports->SeAliasAdminsSid,     KEY_ALL_ACCESS,
235                         ACCESS_ALLOWED_ACE_TYPE, INHERIT_ONLY_ACE |
236                                                  CONTAINER_INHERIT_ACE, SeExports->SeCreatorOwnerSid,    GENERIC_ALL);
237 
238     CheckKeySecurity(L"\\REGISTRY\\USER\\S-1-5-20",
239                      8, ACCESS_ALLOWED_ACE_TYPE,                     0, SeExports->SeNetworkServiceSid,  KEY_ALL_ACCESS,
240                         ACCESS_ALLOWED_ACE_TYPE,                     0, SeExports->SeLocalSystemSid,     KEY_ALL_ACCESS,
241                         ACCESS_ALLOWED_ACE_TYPE,                     0, SeExports->SeAliasAdminsSid,     KEY_ALL_ACCESS,
242                         ACCESS_ALLOWED_ACE_TYPE,                     0, SeExports->SeRestrictedSid,      KEY_READ,
243                         ACCESS_ALLOWED_ACE_TYPE, INHERIT_ONLY_ACE |
244                                                  CONTAINER_INHERIT_ACE |
245                                                  OBJECT_INHERIT_ACE,    SeExports->SeNetworkServiceSid,  GENERIC_ALL,
246                         ACCESS_ALLOWED_ACE_TYPE, INHERIT_ONLY_ACE |
247                                                  CONTAINER_INHERIT_ACE |
248                                                  OBJECT_INHERIT_ACE,    SeExports->SeLocalSystemSid,     GENERIC_ALL,
249                         ACCESS_ALLOWED_ACE_TYPE, INHERIT_ONLY_ACE |
250                                                  CONTAINER_INHERIT_ACE |
251                                                  OBJECT_INHERIT_ACE,    SeExports->SeAliasAdminsSid,     GENERIC_ALL,
252                         ACCESS_ALLOWED_ACE_TYPE, INHERIT_ONLY_ACE |
253                                                  CONTAINER_INHERIT_ACE |
254                                                  OBJECT_INHERIT_ACE,    SeExports->SeRestrictedSid,      GENERIC_READ);
255 
256     if (TerminalServerSid != NULL)
257     {
258         ExFreePoolWithTag(TerminalServerSid, 'iSmK');
259     }
260 }
261