xref: /reactos/base/system/services/security.c (revision ebaf247c)
1 /*
2  * PROJECT:     ReactOS Service Control Manager
3  * LICENSE:     GPL - See COPYING in the top level directory
4  * FILE:        base/system/services/security.c
5  * PURPOSE:     Security functions
6  * COPYRIGHT:   Eric Kohl
7  */
8 
9 /* INCLUDES *****************************************************************/
10 
11 #include "services.h"
12 
13 #define NDEBUG
14 #include <debug.h>
15 
16 static PSID pNullSid = NULL;
17 static PSID pWorldSid = NULL;
18 static PSID pLocalSystemSid = NULL;
19 static PSID pAuthenticatedUserSid = NULL;
20 static PSID pAliasAdminsSid = NULL;
21 
22 static PACL pDefaultDacl = NULL;
23 static PACL pDefaultSacl = NULL;
24 static PACL pPipeDacl = NULL;
25 
26 static PSECURITY_DESCRIPTOR pDefaultSD = NULL;
27 PSECURITY_DESCRIPTOR pPipeSD = NULL;
28 
29 
30 /* FUNCTIONS ****************************************************************/
31 
32 static
33 VOID
34 ScmFreeSids(VOID)
35 {
36     if (pNullSid != NULL)
37         RtlFreeHeap(RtlGetProcessHeap(), 0, pNullSid);
38 
39     if (pWorldSid != NULL)
40         RtlFreeHeap(RtlGetProcessHeap(), 0, pWorldSid);
41 
42     if (pLocalSystemSid != NULL)
43         RtlFreeHeap(RtlGetProcessHeap(), 0, pLocalSystemSid);
44 
45     if (pAuthenticatedUserSid != NULL)
46         RtlFreeHeap(RtlGetProcessHeap(), 0, pAuthenticatedUserSid);
47 
48     if (pAliasAdminsSid != NULL)
49         RtlFreeHeap(RtlGetProcessHeap(), 0, pAliasAdminsSid);
50 }
51 
52 
53 static
54 DWORD
55 ScmCreateSids(VOID)
56 {
57     SID_IDENTIFIER_AUTHORITY NullAuthority = {SECURITY_NULL_SID_AUTHORITY};
58     SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
59     PULONG pSubAuthority;
60     ULONG ulLength1 = RtlLengthRequiredSid(1);
61     ULONG ulLength2 = RtlLengthRequiredSid(2);
62 
63     /* Create the Null SID */
64     pNullSid = RtlAllocateHeap(RtlGetProcessHeap(), 0, ulLength1);
65     if (pNullSid == NULL)
66     {
67         return ERROR_OUTOFMEMORY;
68     }
69 
70     RtlInitializeSid(pNullSid, &NullAuthority, 1);
71     pSubAuthority = RtlSubAuthoritySid(pNullSid, 0);
72     *pSubAuthority = SECURITY_NULL_RID;
73 
74     /* Create the World SID */
75     pWorldSid = RtlAllocateHeap(RtlGetProcessHeap(), 0, ulLength1);
76     if (pWorldSid == NULL)
77     {
78         return ERROR_OUTOFMEMORY;
79     }
80 
81     RtlInitializeSid(pWorldSid, &NullAuthority, 1);
82     pSubAuthority = RtlSubAuthoritySid(pWorldSid, 0);
83     *pSubAuthority = SECURITY_WORLD_RID;
84 
85     /* Create the LocalSystem SID */
86     pLocalSystemSid = RtlAllocateHeap(RtlGetProcessHeap(), 0, ulLength1);
87     if (pLocalSystemSid == NULL)
88     {
89         return ERROR_OUTOFMEMORY;
90     }
91 
92     RtlInitializeSid(pLocalSystemSid, &NtAuthority, 1);
93     pSubAuthority = RtlSubAuthoritySid(pLocalSystemSid, 0);
94     *pSubAuthority = SECURITY_LOCAL_SYSTEM_RID;
95 
96     /* Create the AuthenticatedUser SID */
97     pAuthenticatedUserSid = RtlAllocateHeap(RtlGetProcessHeap(), 0, ulLength1);
98     if (pAuthenticatedUserSid == NULL)
99     {
100         return ERROR_OUTOFMEMORY;
101     }
102 
103     RtlInitializeSid(pAuthenticatedUserSid, &NtAuthority, 1);
104     pSubAuthority = RtlSubAuthoritySid(pAuthenticatedUserSid, 0);
105     *pSubAuthority = SECURITY_AUTHENTICATED_USER_RID;
106 
107     /* Create the AliasAdmins SID */
108     pAliasAdminsSid = RtlAllocateHeap(RtlGetProcessHeap(), 0, ulLength2);
109     if (pAliasAdminsSid == NULL)
110     {
111         return ERROR_OUTOFMEMORY;
112     }
113 
114     RtlInitializeSid(pAliasAdminsSid, &NtAuthority, 2);
115     pSubAuthority = RtlSubAuthoritySid(pAliasAdminsSid, 0);
116     *pSubAuthority = SECURITY_BUILTIN_DOMAIN_RID;
117     pSubAuthority = RtlSubAuthoritySid(pAliasAdminsSid, 1);
118     *pSubAuthority = DOMAIN_ALIAS_RID_ADMINS;
119 
120     return ERROR_SUCCESS;
121 }
122 
123 
124 static
125 DWORD
126 ScmCreateAcls(VOID)
127 {
128     ULONG ulLength;
129 
130     /* Create DACL */
131     ulLength = sizeof(ACL) +
132                (sizeof(ACE) + RtlLengthSid(pLocalSystemSid)) +
133                (sizeof(ACE) + RtlLengthSid(pAliasAdminsSid)) +
134                (sizeof(ACE) + RtlLengthSid(pAuthenticatedUserSid));
135 
136     pDefaultDacl = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, ulLength);
137     if (pDefaultDacl == NULL)
138         return ERROR_OUTOFMEMORY;
139 
140     RtlCreateAcl(pDefaultDacl, ulLength, ACL_REVISION);
141 
142     RtlAddAccessAllowedAce(pDefaultDacl,
143                            ACL_REVISION,
144                            READ_CONTROL | SERVICE_ENUMERATE_DEPENDENTS | SERVICE_INTERROGATE |
145                            SERVICE_PAUSE_CONTINUE | SERVICE_QUERY_CONFIG | SERVICE_QUERY_STATUS |
146                            SERVICE_START | SERVICE_STOP | SERVICE_USER_DEFINED_CONTROL,
147                            pLocalSystemSid);
148 
149     RtlAddAccessAllowedAce(pDefaultDacl,
150                            ACL_REVISION,
151                            SERVICE_ALL_ACCESS,
152                            pAliasAdminsSid);
153 
154     RtlAddAccessAllowedAce(pDefaultDacl,
155                            ACL_REVISION,
156                            READ_CONTROL | SERVICE_ENUMERATE_DEPENDENTS | SERVICE_INTERROGATE |
157                            SERVICE_QUERY_CONFIG | SERVICE_QUERY_STATUS | SERVICE_USER_DEFINED_CONTROL,
158                            pAuthenticatedUserSid);
159 
160     /* Create SACL */
161     ulLength = sizeof(ACL) +
162                (sizeof(ACE) + RtlLengthSid(pNullSid));
163 
164     pDefaultSacl = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, ulLength);
165     if (pDefaultSacl == NULL)
166         return ERROR_OUTOFMEMORY;
167 
168     RtlCreateAcl(pDefaultSacl, ulLength, ACL_REVISION);
169 
170     RtlAddAuditAccessAce(pDefaultSacl,
171                          ACL_REVISION,
172                          SERVICE_ALL_ACCESS,
173                          pNullSid,
174                          FALSE,
175                          TRUE);
176 
177     /* Create the pipe DACL */
178     ulLength = sizeof(ACL) +
179                (sizeof(ACE) + RtlLengthSid(pWorldSid));
180 
181     pPipeDacl = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, ulLength);
182     if (pPipeDacl == NULL)
183         return ERROR_OUTOFMEMORY;
184 
185     RtlCreateAcl(pPipeDacl, ulLength, ACL_REVISION);
186 
187     RtlAddAccessAllowedAce(pPipeDacl,
188                            ACL_REVISION,
189                            GENERIC_ALL,
190                            pWorldSid);
191 
192     return ERROR_SUCCESS;
193 }
194 
195 
196 static
197 VOID
198 ScmFreeAcls(VOID)
199 {
200     if (pDefaultDacl != NULL)
201         RtlFreeHeap(RtlGetProcessHeap(), 0, pDefaultDacl);
202 
203     if (pDefaultSacl != NULL)
204         RtlFreeHeap(RtlGetProcessHeap(), 0, pDefaultSacl);
205 
206     if (pPipeDacl != NULL)
207         RtlFreeHeap(RtlGetProcessHeap(), 0, pPipeDacl);
208 }
209 
210 
211 static
212 DWORD
213 ScmCreateDefaultSD(VOID)
214 {
215     NTSTATUS Status;
216 
217     /* Create the absolute security descriptor */
218     pDefaultSD = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SECURITY_DESCRIPTOR));
219     if (pDefaultSD == NULL)
220         return ERROR_OUTOFMEMORY;
221 
222     DPRINT("pDefaultSD %p\n", pDefaultSD);
223 
224     Status = RtlCreateSecurityDescriptor(pDefaultSD,
225                                          SECURITY_DESCRIPTOR_REVISION);
226     if (!NT_SUCCESS(Status))
227         return RtlNtStatusToDosError(Status);
228 
229     Status = RtlSetOwnerSecurityDescriptor(pDefaultSD,
230                                            pLocalSystemSid,
231                                            FALSE);
232     if (!NT_SUCCESS(Status))
233         return RtlNtStatusToDosError(Status);
234 
235     Status = RtlSetGroupSecurityDescriptor(pDefaultSD,
236                                            pLocalSystemSid,
237                                            FALSE);
238     if (!NT_SUCCESS(Status))
239         return RtlNtStatusToDosError(Status);
240 
241     Status = RtlSetDaclSecurityDescriptor(pDefaultSD,
242                                           TRUE,
243                                           pDefaultDacl,
244                                           FALSE);
245     if (!NT_SUCCESS(Status))
246         return RtlNtStatusToDosError(Status);
247 
248     Status = RtlSetSaclSecurityDescriptor(pDefaultSD,
249                                           TRUE,
250                                           pDefaultSacl,
251                                           FALSE);
252     if (!NT_SUCCESS(Status))
253         return RtlNtStatusToDosError(Status);
254 
255     return ERROR_SUCCESS;
256 }
257 
258 
259 static
260 VOID
261 ScmFreeDefaultSD(VOID)
262 {
263     if (pDefaultSD != NULL)
264         RtlFreeHeap(RtlGetProcessHeap(), 0, pDefaultSD);
265 }
266 
267 
268 static
269 DWORD
270 ScmCreatePipeSD(VOID)
271 {
272     NTSTATUS Status;
273 
274     /* Create the absolute security descriptor */
275     pPipeSD = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SECURITY_DESCRIPTOR));
276     if (pPipeSD == NULL)
277         return ERROR_OUTOFMEMORY;
278 
279     DPRINT("pPipeSD %p\n", pDefaultSD);
280 
281     Status = RtlCreateSecurityDescriptor(pPipeSD,
282                                          SECURITY_DESCRIPTOR_REVISION);
283     if (!NT_SUCCESS(Status))
284         return RtlNtStatusToDosError(Status);
285 
286     Status = RtlSetOwnerSecurityDescriptor(pPipeSD,
287                                            pLocalSystemSid,
288                                            FALSE);
289     if (!NT_SUCCESS(Status))
290         return RtlNtStatusToDosError(Status);
291 
292     Status = RtlSetGroupSecurityDescriptor(pPipeSD,
293                                            pLocalSystemSid,
294                                            FALSE);
295     if (!NT_SUCCESS(Status))
296         return RtlNtStatusToDosError(Status);
297 
298     Status = RtlSetDaclSecurityDescriptor(pPipeSD,
299                                           TRUE,
300                                           pPipeDacl,
301                                           FALSE);
302     if (!NT_SUCCESS(Status))
303         return RtlNtStatusToDosError(Status);
304 
305     return ERROR_SUCCESS;
306 }
307 
308 
309 static
310 VOID
311 ScmFreePipeSD(VOID)
312 {
313     if (pPipeSD != NULL)
314         RtlFreeHeap(RtlGetProcessHeap(), 0, pPipeSD);
315 }
316 
317 
318 DWORD
319 ScmCreateDefaultServiceSD(
320     PSECURITY_DESCRIPTOR *ppSecurityDescriptor)
321 {
322     PSECURITY_DESCRIPTOR pRelativeSD = NULL;
323     DWORD dwBufferLength = 0;
324     NTSTATUS Status;
325     DWORD dwError = ERROR_SUCCESS;
326 
327     /* Convert the absolute SD to a self-relative SD */
328     Status = RtlAbsoluteToSelfRelativeSD(pDefaultSD,
329                                          NULL,
330                                          &dwBufferLength);
331     if (Status != STATUS_BUFFER_TOO_SMALL)
332     {
333         dwError = RtlNtStatusToDosError(Status);
334         goto done;
335     }
336 
337     DPRINT("BufferLength %lu\n", dwBufferLength);
338 
339     pRelativeSD = RtlAllocateHeap(RtlGetProcessHeap(),
340                                   HEAP_ZERO_MEMORY,
341                                   dwBufferLength);
342     if (pRelativeSD == NULL)
343     {
344         dwError = ERROR_OUTOFMEMORY;
345         goto done;
346     }
347     DPRINT("pRelativeSD %p\n", pRelativeSD);
348 
349     Status = RtlAbsoluteToSelfRelativeSD(pDefaultSD,
350                                          pRelativeSD,
351                                          &dwBufferLength);
352     if (!NT_SUCCESS(Status))
353     {
354         dwError = RtlNtStatusToDosError(Status);
355         goto done;
356     }
357 
358     *ppSecurityDescriptor = pRelativeSD;
359 
360 done:
361     if (dwError != ERROR_SUCCESS)
362     {
363         if (pRelativeSD != NULL)
364             RtlFreeHeap(RtlGetProcessHeap(), 0, pRelativeSD);
365     }
366 
367     return dwError;
368 }
369 
370 
371 DWORD
372 ScmInitializeSecurity(VOID)
373 {
374     DWORD dwError;
375 
376     dwError = ScmCreateSids();
377     if (dwError != ERROR_SUCCESS)
378         return dwError;
379 
380     dwError = ScmCreateAcls();
381     if (dwError != ERROR_SUCCESS)
382         return dwError;
383 
384     dwError = ScmCreateDefaultSD();
385     if (dwError != ERROR_SUCCESS)
386         return dwError;
387 
388     dwError = ScmCreatePipeSD();
389     if (dwError != ERROR_SUCCESS)
390         return dwError;
391 
392     return ERROR_SUCCESS;
393 }
394 
395 
396 VOID
397 ScmShutdownSecurity(VOID)
398 {
399     ScmFreePipeSD();
400     ScmFreeDefaultSD();
401     ScmFreeAcls();
402     ScmFreeSids();
403 }
404 
405 /* EOF */
406