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