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