[MSIEXEC] Sync with Wine Staging 2.16. CORE-13762
[reactos.git] / base / system / services / security.c
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 pLocalSystemSid = NULL;
18 static PSID pAuthenticatedUserSid = NULL;
19 static PSID pAliasAdminsSid = NULL;
20
21 static PACL pDefaultDacl = NULL;
22 static PACL pDefaultSacl = NULL;
23
24 static PSECURITY_DESCRIPTOR pDefaultSD = NULL;
25
26
27 /* FUNCTIONS ****************************************************************/
28
29 static
30 VOID
31 ScmFreeSids(VOID)
32 {
33 if (pNullSid != NULL)
34 RtlFreeHeap(RtlGetProcessHeap(), 0, pNullSid);
35
36 if (pLocalSystemSid != NULL)
37 RtlFreeHeap(RtlGetProcessHeap(), 0, pLocalSystemSid);
38
39 if (pAuthenticatedUserSid != NULL)
40 RtlFreeHeap(RtlGetProcessHeap(), 0, pAuthenticatedUserSid);
41
42 if (pAliasAdminsSid != NULL)
43 RtlFreeHeap(RtlGetProcessHeap(), 0, pAliasAdminsSid);
44
45 }
46
47
48 static
49 DWORD
50 ScmCreateSids(VOID)
51 {
52 SID_IDENTIFIER_AUTHORITY NullAuthority = {SECURITY_NULL_SID_AUTHORITY};
53 SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
54 PULONG pSubAuthority;
55 ULONG ulLength1 = RtlLengthRequiredSid(1);
56 ULONG ulLength2 = RtlLengthRequiredSid(2);
57
58 /* Create the Null SID */
59 pNullSid = RtlAllocateHeap(RtlGetProcessHeap(), 0, ulLength1);
60 if (pNullSid == NULL)
61 {
62 return ERROR_OUTOFMEMORY;
63 }
64
65 RtlInitializeSid(pNullSid, &NullAuthority, 1);
66 pSubAuthority = RtlSubAuthoritySid(pNullSid, 0);
67 *pSubAuthority = SECURITY_NULL_RID;
68
69 /* Create the LocalSystem SID */
70 pLocalSystemSid = RtlAllocateHeap(RtlGetProcessHeap(), 0, ulLength1);
71 if (pLocalSystemSid == NULL)
72 {
73 return ERROR_OUTOFMEMORY;
74 }
75
76 RtlInitializeSid(pLocalSystemSid, &NtAuthority, 1);
77 pSubAuthority = RtlSubAuthoritySid(pLocalSystemSid, 0);
78 *pSubAuthority = SECURITY_LOCAL_SYSTEM_RID;
79
80 /* Create the AuthenticatedUser SID */
81 pAuthenticatedUserSid = RtlAllocateHeap(RtlGetProcessHeap(), 0, ulLength1);
82 if (pAuthenticatedUserSid == NULL)
83 {
84 return ERROR_OUTOFMEMORY;
85 }
86
87 RtlInitializeSid(pAuthenticatedUserSid, &NtAuthority, 1);
88 pSubAuthority = RtlSubAuthoritySid(pAuthenticatedUserSid, 0);
89 *pSubAuthority = SECURITY_AUTHENTICATED_USER_RID;
90
91 /* Create the AliasAdmins SID */
92 pAliasAdminsSid = RtlAllocateHeap(RtlGetProcessHeap(), 0, ulLength2);
93 if (pAliasAdminsSid == NULL)
94 {
95 return ERROR_OUTOFMEMORY;
96 }
97
98 RtlInitializeSid(pAliasAdminsSid, &NtAuthority, 2);
99 pSubAuthority = RtlSubAuthoritySid(pAliasAdminsSid, 0);
100 *pSubAuthority = SECURITY_BUILTIN_DOMAIN_RID;
101 pSubAuthority = RtlSubAuthoritySid(pAliasAdminsSid, 1);
102 *pSubAuthority = DOMAIN_ALIAS_RID_ADMINS;
103
104 return ERROR_SUCCESS;
105 }
106
107
108 static
109 DWORD
110 ScmCreateAcls(VOID)
111 {
112 ULONG ulLength;
113
114 /* Create DACL */
115 ulLength = sizeof(ACL) +
116 (sizeof(ACE) + RtlLengthSid(pLocalSystemSid)) +
117 (sizeof(ACE) + RtlLengthSid(pAliasAdminsSid)) +
118 (sizeof(ACE) + RtlLengthSid(pAuthenticatedUserSid));
119
120 pDefaultDacl = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, ulLength);
121 if (pDefaultDacl == NULL)
122 return ERROR_OUTOFMEMORY;
123
124 RtlCreateAcl(pDefaultDacl, ulLength, ACL_REVISION);
125
126 RtlAddAccessAllowedAce(pDefaultDacl,
127 ACL_REVISION,
128 READ_CONTROL | SERVICE_ENUMERATE_DEPENDENTS | SERVICE_INTERROGATE |
129 SERVICE_PAUSE_CONTINUE | SERVICE_QUERY_CONFIG | SERVICE_QUERY_STATUS |
130 SERVICE_START | SERVICE_STOP | SERVICE_USER_DEFINED_CONTROL,
131 pLocalSystemSid);
132
133 RtlAddAccessAllowedAce(pDefaultDacl,
134 ACL_REVISION,
135 SERVICE_ALL_ACCESS,
136 pAliasAdminsSid);
137
138 RtlAddAccessAllowedAce(pDefaultDacl,
139 ACL_REVISION,
140 READ_CONTROL | SERVICE_ENUMERATE_DEPENDENTS | SERVICE_INTERROGATE |
141 SERVICE_QUERY_CONFIG | SERVICE_QUERY_STATUS | SERVICE_USER_DEFINED_CONTROL,
142 pAuthenticatedUserSid);
143
144 /* Create SACL */
145 ulLength = sizeof(ACL) +
146 (sizeof(ACE) + RtlLengthSid(pNullSid));
147
148 pDefaultSacl = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, ulLength);
149 if (pDefaultSacl == NULL)
150 return ERROR_OUTOFMEMORY;
151
152 RtlCreateAcl(pDefaultSacl, ulLength, ACL_REVISION);
153
154 RtlAddAuditAccessAce(pDefaultSacl,
155 ACL_REVISION,
156 SERVICE_ALL_ACCESS,
157 pNullSid,
158 FALSE,
159 TRUE);
160
161 return ERROR_SUCCESS;
162 }
163
164
165 static
166 VOID
167 ScmFreeAcls(VOID)
168 {
169 if (pDefaultDacl != NULL)
170 RtlFreeHeap(RtlGetProcessHeap(), 0, pDefaultDacl);
171
172 if (pDefaultSacl != NULL)
173 RtlFreeHeap(RtlGetProcessHeap(), 0, pDefaultSacl);
174 }
175
176
177 static
178 DWORD
179 ScmCreateDefaultSD(VOID)
180 {
181 NTSTATUS Status;
182
183 /* Create the absolute security descriptor */
184 pDefaultSD = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SECURITY_DESCRIPTOR));
185 if (pDefaultSD == NULL)
186 return ERROR_OUTOFMEMORY;
187
188 DPRINT("pDefaultSD %p\n", pDefaultSD);
189
190 Status = RtlCreateSecurityDescriptor(pDefaultSD,
191 SECURITY_DESCRIPTOR_REVISION);
192 if (!NT_SUCCESS(Status))
193 return RtlNtStatusToDosError(Status);
194
195 Status = RtlSetOwnerSecurityDescriptor(pDefaultSD,
196 pLocalSystemSid,
197 FALSE);
198 if (!NT_SUCCESS(Status))
199 return RtlNtStatusToDosError(Status);
200
201 Status = RtlSetGroupSecurityDescriptor(pDefaultSD,
202 pLocalSystemSid,
203 FALSE);
204 if (!NT_SUCCESS(Status))
205 return RtlNtStatusToDosError(Status);
206
207 Status = RtlSetDaclSecurityDescriptor(pDefaultSD,
208 TRUE,
209 pDefaultDacl,
210 FALSE);
211 if (!NT_SUCCESS(Status))
212 return RtlNtStatusToDosError(Status);
213
214 Status = RtlSetSaclSecurityDescriptor(pDefaultSD,
215 TRUE,
216 pDefaultSacl,
217 FALSE);
218 if (!NT_SUCCESS(Status))
219 return RtlNtStatusToDosError(Status);
220
221 return ERROR_SUCCESS;
222 }
223
224
225 static
226 VOID
227 ScmFreeDefaultSD(VOID)
228 {
229 if (pDefaultSD != NULL)
230 RtlFreeHeap(RtlGetProcessHeap(), 0, pDefaultSD);
231 }
232
233
234 DWORD
235 ScmCreateDefaultServiceSD(
236 PSECURITY_DESCRIPTOR *ppSecurityDescriptor)
237 {
238 PSECURITY_DESCRIPTOR pRelativeSD = NULL;
239 DWORD dwBufferLength = 0;
240 NTSTATUS Status;
241 DWORD dwError = ERROR_SUCCESS;
242
243 /* Convert the absolute SD to a self-relative SD */
244 Status = RtlAbsoluteToSelfRelativeSD(pDefaultSD,
245 NULL,
246 &dwBufferLength);
247 if (Status != STATUS_BUFFER_TOO_SMALL)
248 {
249 dwError = RtlNtStatusToDosError(Status);
250 goto done;
251 }
252
253 DPRINT("BufferLength %lu\n", dwBufferLength);
254
255 pRelativeSD = RtlAllocateHeap(RtlGetProcessHeap(),
256 HEAP_ZERO_MEMORY,
257 dwBufferLength);
258 if (pRelativeSD == NULL)
259 {
260 dwError = ERROR_OUTOFMEMORY;
261 goto done;
262 }
263 DPRINT("pRelativeSD %p\n", pRelativeSD);
264
265 Status = RtlAbsoluteToSelfRelativeSD(pDefaultSD,
266 pRelativeSD,
267 &dwBufferLength);
268 if (!NT_SUCCESS(Status))
269 {
270 dwError = RtlNtStatusToDosError(Status);
271 goto done;
272 }
273
274 *ppSecurityDescriptor = pRelativeSD;
275
276 done:
277 if (dwError != ERROR_SUCCESS)
278 {
279 if (pRelativeSD != NULL)
280 RtlFreeHeap(RtlGetProcessHeap(), 0, pRelativeSD);
281 }
282
283 return dwError;
284 }
285
286
287 DWORD
288 ScmInitializeSecurity(VOID)
289 {
290 DWORD dwError;
291
292 dwError = ScmCreateSids();
293 if (dwError != ERROR_SUCCESS)
294 return dwError;
295
296 dwError = ScmCreateAcls();
297 if (dwError != ERROR_SUCCESS)
298 return dwError;
299
300 dwError = ScmCreateDefaultSD();
301 if (dwError != ERROR_SUCCESS)
302 return dwError;
303
304 return ERROR_SUCCESS;
305 }
306
307
308 VOID
309 ScmShutdownSecurity(VOID)
310 {
311 ScmFreeDefaultSD();
312 ScmFreeAcls();
313 ScmFreeSids();
314 }
315
316 /* EOF */