1 /*
2  * PROJECT:         ReactOS kernel-mode tests
3  * LICENSE:         LGPLv2.1+ - See COPYING.LIB in the top level directory
4  * PURPOSE:         Kernel-Mode Test Suite object 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 CheckDirectorySecurityWithOwnerAndGroup(name, Owner, Group, AceCount, ...) CheckDirectorySecurity_(name, Owner, Group, AceCount, __FILE__, __LINE__, ##__VA_ARGS__)
12 #define CheckDirectorySecurity(name, AceCount, ...) CheckDirectorySecurity_(name, SeExports->SeAliasAdminsSid, SeExports->SeLocalSystemSid, AceCount, __FILE__, __LINE__, ##__VA_ARGS__)
13 #define CheckDirectorySecurity_(name, Owner, Group, AceCount, file, line, ...) CheckDirectorySecurity__(name, Owner, Group, AceCount, file ":" KMT_STRINGIZE(line), ##__VA_ARGS__)
14 static
15 VOID
16 CheckDirectorySecurity__(
17     _In_ PCWSTR DirectoryName,
18     _In_ PSID ExpectedOwner,
19     _In_ PSID ExpectedGroup,
20     _In_ ULONG AceCount,
21     _In_ PCSTR FileAndLine,
22     ...)
23 {
24     NTSTATUS Status;
25     UNICODE_STRING DirectoryNameString;
26     OBJECT_ATTRIBUTES ObjectAttributes;
27     HANDLE DirectoryHandle;
28     PSECURITY_DESCRIPTOR SecurityDescriptor;
29     ULONG SecurityDescriptorSize;
30     PSID Owner;
31     PSID Group;
32     PACL Dacl;
33     PACL Sacl;
34     BOOLEAN Present;
35     BOOLEAN Defaulted;
36     va_list Arguments;
37 
38     RtlInitUnicodeString(&DirectoryNameString, DirectoryName);
39     InitializeObjectAttributes(&ObjectAttributes,
40                                &DirectoryNameString,
41                                OBJ_KERNEL_HANDLE,
42                                NULL,
43                                NULL);
44     Status = ZwOpenDirectoryObject(&DirectoryHandle,
45                                    READ_CONTROL | ACCESS_SYSTEM_SECURITY,
46                                    &ObjectAttributes);
47     ok_eq_hex(Status, STATUS_SUCCESS);
48     if (skip(NT_SUCCESS(Status), "No directory (%ls)\n", DirectoryName))
49     {
50         return;
51     }
52 
53     Status = ZwQuerySecurityObject(DirectoryHandle,
54                                    OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION,
55                                    NULL,
56                                    0,
57                                    &SecurityDescriptorSize);
58     ok_eq_hex(Status, STATUS_BUFFER_TOO_SMALL);
59     if (skip(Status == STATUS_BUFFER_TOO_SMALL, "No security size (%ls)\n", DirectoryName))
60     {
61         ObCloseHandle(DirectoryHandle, KernelMode);
62         return;
63     }
64 
65     SecurityDescriptor = ExAllocatePoolWithTag(PagedPool,
66                                                SecurityDescriptorSize,
67                                                'dSmK');
68     ok(SecurityDescriptor != NULL, "Failed to allocate %lu bytes\n", SecurityDescriptorSize);
69     if (skip(SecurityDescriptor != NULL, "No memory for descriptor (%ls)\n", DirectoryName))
70     {
71         ObCloseHandle(DirectoryHandle, KernelMode);
72         return;
73     }
74 
75     Status = ZwQuerySecurityObject(DirectoryHandle,
76                                    OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION,
77                                    SecurityDescriptor,
78                                    SecurityDescriptorSize,
79                                    &SecurityDescriptorSize);
80     ok_eq_hex(Status, STATUS_SUCCESS);
81     if (NT_SUCCESS(Status))
82     {
83         Owner = NULL;
84         Status = RtlGetOwnerSecurityDescriptor(SecurityDescriptor,
85                                                &Owner,
86                                                &Defaulted);
87         if (ExpectedOwner)
88             CheckSid__(Owner, NO_SIZE, ExpectedOwner, FileAndLine);
89         ok(Defaulted == FALSE, "Owner defaulted for %ls\n", DirectoryName);
90 
91         Group = NULL;
92         Status = RtlGetGroupSecurityDescriptor(SecurityDescriptor,
93                                                &Group,
94                                                &Defaulted);
95         if (ExpectedGroup)
96             CheckSid__(Group, NO_SIZE, ExpectedGroup, FileAndLine);
97         ok(Defaulted == FALSE, "Group defaulted for %ls\n", DirectoryName);
98 
99         Dacl = NULL;
100         Status = RtlGetDaclSecurityDescriptor(SecurityDescriptor,
101                                               &Present,
102                                               &Dacl,
103                                               &Defaulted);
104         ok_eq_hex(Status, STATUS_SUCCESS);
105         ok(Present == TRUE, "DACL not present for %ls\n", DirectoryName);
106         ok(Defaulted == FALSE, "DACL defaulted for %ls\n", DirectoryName);
107         va_start(Arguments, FileAndLine);
108         VCheckAcl__(Dacl, AceCount, FileAndLine, Arguments);
109         va_end(Arguments);
110 
111         Sacl = NULL;
112         Status = RtlGetSaclSecurityDescriptor(SecurityDescriptor,
113                                               &Present,
114                                               &Sacl,
115                                               &Defaulted);
116         ok_eq_hex(Status, STATUS_SUCCESS);
117         ok(Present == FALSE, "SACL present for %ls\n", DirectoryName);
118         ok(Defaulted == FALSE, "SACL defaulted for %ls\n", DirectoryName);
119         ok(Sacl == NULL, "Sacl is %p for %ls\n", Sacl, DirectoryName);
120     }
121     ExFreePoolWithTag(SecurityDescriptor, 'dSmK');
122     ObCloseHandle(DirectoryHandle, KernelMode);
123 }
124 
125 START_TEST(ObSecurity)
126 {
127 #define DIRECTORY_GENERIC_READ      STANDARD_RIGHTS_READ | DIRECTORY_TRAVERSE | DIRECTORY_QUERY
128 #define DIRECTORY_GENERIC_WRITE     STANDARD_RIGHTS_WRITE | DIRECTORY_CREATE_SUBDIRECTORY | DIRECTORY_CREATE_OBJECT
129 
130     CheckDirectorySecurityWithOwnerAndGroup(L"\\??", SeExports->SeAliasAdminsSid, NULL, // Group is "Domain Users"
131                            4, ACCESS_ALLOWED_ACE_TYPE, CONTAINER_INHERIT_ACE |
132                                                        OBJECT_INHERIT_ACE,      SeExports->SeLocalSystemSid, DIRECTORY_ALL_ACCESS,
133                               ACCESS_ALLOWED_ACE_TYPE, CONTAINER_INHERIT_ACE |
134                                                        OBJECT_INHERIT_ACE,      SeExports->SeAliasAdminsSid, DIRECTORY_ALL_ACCESS,
135                               ACCESS_ALLOWED_ACE_TYPE, 0,                       SeExports->SeAliasAdminsSid, DIRECTORY_ALL_ACCESS,
136                               ACCESS_ALLOWED_ACE_TYPE, INHERIT_ONLY_ACE |
137                                                        CONTAINER_INHERIT_ACE |
138                                                        OBJECT_INHERIT_ACE,      SeExports->SeCreatorOwnerSid,GENERIC_ALL);
139 
140     CheckDirectorySecurity(L"\\",
141                            4, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeWorldSid,       DIRECTORY_GENERIC_READ,
142                               ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, DIRECTORY_ALL_ACCESS,
143                               ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, DIRECTORY_ALL_ACCESS,
144                               ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeRestrictedSid,  DIRECTORY_GENERIC_READ);
145 
146     CheckDirectorySecurity(L"\\ArcName",
147                            4, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeWorldSid,       DIRECTORY_GENERIC_READ,
148                               ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, DIRECTORY_ALL_ACCESS,
149                               ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, DIRECTORY_ALL_ACCESS,
150                               ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeRestrictedSid,  DIRECTORY_GENERIC_READ);
151 
152     CheckDirectorySecurity(L"\\BaseNamedObjects",
153                            3, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeWorldSid,       DIRECTORY_GENERIC_WRITE | DIRECTORY_GENERIC_READ,
154                               ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, DIRECTORY_ALL_ACCESS,
155                               ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeRestrictedSid,  DIRECTORY_TRAVERSE);
156 
157     CheckDirectorySecurity(L"\\Callback",
158                            3, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeWorldSid,       DIRECTORY_GENERIC_READ,
159                               ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, DIRECTORY_ALL_ACCESS,
160                               ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, DIRECTORY_ALL_ACCESS);
161 
162     CheckDirectorySecurity(L"\\Device",
163                            4, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeWorldSid,       DIRECTORY_GENERIC_READ,
164                               ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, DIRECTORY_ALL_ACCESS,
165                               ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, DIRECTORY_ALL_ACCESS,
166                               ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeRestrictedSid,  DIRECTORY_GENERIC_READ);
167 
168     CheckDirectorySecurity(L"\\Driver",
169                            2, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, DIRECTORY_ALL_ACCESS,
170                               ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, DIRECTORY_GENERIC_READ);
171 
172     CheckDirectorySecurity(L"\\GLOBAL??",
173                            6, ACCESS_ALLOWED_ACE_TYPE, 0,                       SeExports->SeWorldSid,       DIRECTORY_GENERIC_READ,
174                               ACCESS_ALLOWED_ACE_TYPE, 0,                       SeExports->SeLocalSystemSid, DIRECTORY_ALL_ACCESS,
175                               ACCESS_ALLOWED_ACE_TYPE, INHERIT_ONLY_ACE |
176                                                        CONTAINER_INHERIT_ACE |
177                                                        OBJECT_INHERIT_ACE,      SeExports->SeWorldSid,       GENERIC_EXECUTE,
178                               ACCESS_ALLOWED_ACE_TYPE, INHERIT_ONLY_ACE |
179                                                        CONTAINER_INHERIT_ACE |
180                                                        OBJECT_INHERIT_ACE,      SeExports->SeAliasAdminsSid, GENERIC_ALL,
181                               ACCESS_ALLOWED_ACE_TYPE, INHERIT_ONLY_ACE |
182                                                        CONTAINER_INHERIT_ACE |
183                                                        OBJECT_INHERIT_ACE,      SeExports->SeLocalSystemSid, GENERIC_ALL,
184                               ACCESS_ALLOWED_ACE_TYPE, INHERIT_ONLY_ACE |
185                                                        CONTAINER_INHERIT_ACE |
186                                                        OBJECT_INHERIT_ACE,      SeExports->SeCreatorOwnerSid,GENERIC_ALL);
187 
188     CheckDirectorySecurity(L"\\KernelObjects",
189                            3, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeWorldSid,       DIRECTORY_GENERIC_READ,
190                               ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, DIRECTORY_ALL_ACCESS,
191                               ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, DIRECTORY_ALL_ACCESS);
192 
193     CheckDirectorySecurity(L"\\ObjectTypes",
194                            2, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, DIRECTORY_ALL_ACCESS,
195                               ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, DIRECTORY_GENERIC_READ);
196 }
197