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