1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS kernel 4 * FILE: ntoskrnl/se/semgr.c 5 * PURPOSE: Security manager 6 * 7 * PROGRAMMERS: No programmer listed. 8 */ 9 10 /* INCLUDES *******************************************************************/ 11 12 #include <ntoskrnl.h> 13 #define NDEBUG 14 #include <debug.h> 15 16 /* GLOBALS ********************************************************************/ 17 18 PTOKEN SeAnonymousLogonToken = NULL; 19 PTOKEN SeAnonymousLogonTokenNoEveryone = NULL; 20 PSE_EXPORTS SeExports = NULL; 21 SE_EXPORTS SepExports; 22 ULONG SidInTokenCalls = 0; 23 24 extern ULONG ExpInitializationPhase; 25 extern ERESOURCE SepSubjectContextLock; 26 27 /* PRIVATE FUNCTIONS **********************************************************/ 28 29 static 30 CODE_SEG("INIT") 31 BOOLEAN 32 SepInitExports(VOID) 33 { 34 SepExports.SeCreateTokenPrivilege = SeCreateTokenPrivilege; 35 SepExports.SeAssignPrimaryTokenPrivilege = SeAssignPrimaryTokenPrivilege; 36 SepExports.SeLockMemoryPrivilege = SeLockMemoryPrivilege; 37 SepExports.SeIncreaseQuotaPrivilege = SeIncreaseQuotaPrivilege; 38 SepExports.SeUnsolicitedInputPrivilege = SeUnsolicitedInputPrivilege; 39 SepExports.SeTcbPrivilege = SeTcbPrivilege; 40 SepExports.SeSecurityPrivilege = SeSecurityPrivilege; 41 SepExports.SeTakeOwnershipPrivilege = SeTakeOwnershipPrivilege; 42 SepExports.SeLoadDriverPrivilege = SeLoadDriverPrivilege; 43 SepExports.SeCreatePagefilePrivilege = SeCreatePagefilePrivilege; 44 SepExports.SeIncreaseBasePriorityPrivilege = SeIncreaseBasePriorityPrivilege; 45 SepExports.SeSystemProfilePrivilege = SeSystemProfilePrivilege; 46 SepExports.SeSystemtimePrivilege = SeSystemtimePrivilege; 47 SepExports.SeProfileSingleProcessPrivilege = SeProfileSingleProcessPrivilege; 48 SepExports.SeCreatePermanentPrivilege = SeCreatePermanentPrivilege; 49 SepExports.SeBackupPrivilege = SeBackupPrivilege; 50 SepExports.SeRestorePrivilege = SeRestorePrivilege; 51 SepExports.SeShutdownPrivilege = SeShutdownPrivilege; 52 SepExports.SeDebugPrivilege = SeDebugPrivilege; 53 SepExports.SeAuditPrivilege = SeAuditPrivilege; 54 SepExports.SeSystemEnvironmentPrivilege = SeSystemEnvironmentPrivilege; 55 SepExports.SeChangeNotifyPrivilege = SeChangeNotifyPrivilege; 56 SepExports.SeRemoteShutdownPrivilege = SeRemoteShutdownPrivilege; 57 58 SepExports.SeNullSid = SeNullSid; 59 SepExports.SeWorldSid = SeWorldSid; 60 SepExports.SeLocalSid = SeLocalSid; 61 SepExports.SeCreatorOwnerSid = SeCreatorOwnerSid; 62 SepExports.SeCreatorGroupSid = SeCreatorGroupSid; 63 SepExports.SeNtAuthoritySid = SeNtAuthoritySid; 64 SepExports.SeDialupSid = SeDialupSid; 65 SepExports.SeNetworkSid = SeNetworkSid; 66 SepExports.SeBatchSid = SeBatchSid; 67 SepExports.SeInteractiveSid = SeInteractiveSid; 68 SepExports.SeLocalSystemSid = SeLocalSystemSid; 69 SepExports.SeAliasAdminsSid = SeAliasAdminsSid; 70 SepExports.SeAliasUsersSid = SeAliasUsersSid; 71 SepExports.SeAliasGuestsSid = SeAliasGuestsSid; 72 SepExports.SeAliasPowerUsersSid = SeAliasPowerUsersSid; 73 SepExports.SeAliasAccountOpsSid = SeAliasAccountOpsSid; 74 SepExports.SeAliasSystemOpsSid = SeAliasSystemOpsSid; 75 SepExports.SeAliasPrintOpsSid = SeAliasPrintOpsSid; 76 SepExports.SeAliasBackupOpsSid = SeAliasBackupOpsSid; 77 SepExports.SeAuthenticatedUsersSid = SeAuthenticatedUsersSid; 78 SepExports.SeRestrictedSid = SeRestrictedSid; 79 SepExports.SeAnonymousLogonSid = SeAnonymousLogonSid; 80 SepExports.SeLocalServiceSid = SeLocalServiceSid; 81 SepExports.SeNetworkServiceSid = SeNetworkServiceSid; 82 83 SepExports.SeUndockPrivilege = SeUndockPrivilege; 84 SepExports.SeSyncAgentPrivilege = SeSyncAgentPrivilege; 85 SepExports.SeEnableDelegationPrivilege = SeEnableDelegationPrivilege; 86 SepExports.SeManageVolumePrivilege = SeManageVolumePrivilege; 87 SepExports.SeImpersonatePrivilege = SeImpersonatePrivilege; 88 SepExports.SeCreateGlobalPrivilege = SeCreateGlobalPrivilege; 89 90 SeExports = &SepExports; 91 return TRUE; 92 } 93 94 95 CODE_SEG("INIT") 96 BOOLEAN 97 NTAPI 98 SepInitializationPhase0(VOID) 99 { 100 PAGED_CODE(); 101 102 if (!ExLuidInitialization()) return FALSE; 103 if (!SepInitSecurityIDs()) return FALSE; 104 if (!SepInitDACLs()) return FALSE; 105 if (!SepInitSDs()) return FALSE; 106 SepInitPrivileges(); 107 if (!SepInitExports()) return FALSE; 108 109 /* Initialize the subject context lock */ 110 ExInitializeResource(&SepSubjectContextLock); 111 112 /* Initialize token objects */ 113 SepInitializeTokenImplementation(); 114 115 /* Initialize logon sessions */ 116 if (!SeRmInitPhase0()) return FALSE; 117 118 /* Clear impersonation info for the idle thread */ 119 PsGetCurrentThread()->ImpersonationInfo = NULL; 120 PspClearCrossThreadFlag(PsGetCurrentThread(), 121 CT_ACTIVE_IMPERSONATION_INFO_BIT); 122 123 /* Initialize the boot token */ 124 ObInitializeFastReference(&PsGetCurrentProcess()->Token, NULL); 125 ObInitializeFastReference(&PsGetCurrentProcess()->Token, 126 SepCreateSystemProcessToken()); 127 128 /* Initialise the anonymous logon tokens */ 129 SeAnonymousLogonToken = SepCreateSystemAnonymousLogonToken(); 130 if (!SeAnonymousLogonToken) 131 return FALSE; 132 133 SeAnonymousLogonTokenNoEveryone = SepCreateSystemAnonymousLogonTokenNoEveryone(); 134 if (!SeAnonymousLogonTokenNoEveryone) 135 return FALSE; 136 137 return TRUE; 138 } 139 140 CODE_SEG("INIT") 141 BOOLEAN 142 NTAPI 143 SepInitializationPhase1(VOID) 144 { 145 OBJECT_ATTRIBUTES ObjectAttributes; 146 UNICODE_STRING Name; 147 HANDLE SecurityHandle; 148 HANDLE EventHandle; 149 NTSTATUS Status; 150 SECURITY_DESCRIPTOR SecurityDescriptor; 151 PACL Dacl; 152 ULONG DaclLength; 153 154 PAGED_CODE(); 155 156 /* Insert the system token into the tree */ 157 Status = ObInsertObject((PVOID)(PsGetCurrentProcess()->Token.Value & 158 ~MAX_FAST_REFS), 159 NULL, 160 0, 161 0, 162 NULL, 163 NULL); 164 ASSERT(NT_SUCCESS(Status)); 165 166 /* Create a security descriptor for the directory */ 167 RtlCreateSecurityDescriptor(&SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION); 168 169 /* Setup the ACL */ 170 DaclLength = sizeof(ACL) + 3 * sizeof(ACCESS_ALLOWED_ACE) + 171 RtlLengthSid(SeLocalSystemSid) + 172 RtlLengthSid(SeAliasAdminsSid) + 173 RtlLengthSid(SeWorldSid); 174 Dacl = ExAllocatePoolWithTag(NonPagedPool, DaclLength, TAG_SE); 175 if (Dacl == NULL) 176 { 177 return FALSE; 178 } 179 180 Status = RtlCreateAcl(Dacl, DaclLength, ACL_REVISION); 181 ASSERT(NT_SUCCESS(Status)); 182 183 /* Grant full access to SYSTEM */ 184 Status = RtlAddAccessAllowedAce(Dacl, 185 ACL_REVISION, 186 DIRECTORY_ALL_ACCESS, 187 SeLocalSystemSid); 188 ASSERT(NT_SUCCESS(Status)); 189 190 /* Allow admins to traverse and query */ 191 Status = RtlAddAccessAllowedAce(Dacl, 192 ACL_REVISION, 193 READ_CONTROL | DIRECTORY_TRAVERSE | DIRECTORY_QUERY, 194 SeAliasAdminsSid); 195 ASSERT(NT_SUCCESS(Status)); 196 197 /* Allow anyone to traverse */ 198 Status = RtlAddAccessAllowedAce(Dacl, 199 ACL_REVISION, 200 DIRECTORY_TRAVERSE, 201 SeWorldSid); 202 ASSERT(NT_SUCCESS(Status)); 203 204 /* And link ACL and SD */ 205 Status = RtlSetDaclSecurityDescriptor(&SecurityDescriptor, TRUE, Dacl, FALSE); 206 ASSERT(NT_SUCCESS(Status)); 207 208 /* Create '\Security' directory */ 209 RtlInitUnicodeString(&Name, L"\\Security"); 210 InitializeObjectAttributes(&ObjectAttributes, 211 &Name, 212 OBJ_PERMANENT | OBJ_CASE_INSENSITIVE, 213 0, 214 &SecurityDescriptor); 215 216 Status = ZwCreateDirectoryObject(&SecurityHandle, 217 DIRECTORY_ALL_ACCESS, 218 &ObjectAttributes); 219 ASSERT(NT_SUCCESS(Status)); 220 221 /* Free the DACL */ 222 ExFreePoolWithTag(Dacl, TAG_SE); 223 224 /* Create 'LSA_AUTHENTICATION_INITIALIZED' event */ 225 RtlInitUnicodeString(&Name, L"LSA_AUTHENTICATION_INITIALIZED"); 226 InitializeObjectAttributes(&ObjectAttributes, 227 &Name, 228 OBJ_PERMANENT | OBJ_CASE_INSENSITIVE, 229 SecurityHandle, 230 SePublicDefaultSd); 231 232 Status = ZwCreateEvent(&EventHandle, 233 GENERIC_WRITE, 234 &ObjectAttributes, 235 NotificationEvent, 236 FALSE); 237 ASSERT(NT_SUCCESS(Status)); 238 239 Status = ZwClose(EventHandle); 240 ASSERT(NT_SUCCESS(Status)); 241 242 Status = ZwClose(SecurityHandle); 243 ASSERT(NT_SUCCESS(Status)); 244 245 return TRUE; 246 } 247 248 CODE_SEG("INIT") 249 BOOLEAN 250 NTAPI 251 SeInitSystem(VOID) 252 { 253 /* Check the initialization phase */ 254 switch (ExpInitializationPhase) 255 { 256 case 0: 257 258 /* Do Phase 0 */ 259 return SepInitializationPhase0(); 260 261 case 1: 262 263 /* Do Phase 1 */ 264 return SepInitializationPhase1(); 265 266 default: 267 268 /* Don't know any other phase! Bugcheck! */ 269 KeBugCheckEx(UNEXPECTED_INITIALIZATION_CALL, 270 0, 271 ExpInitializationPhase, 272 0, 273 0); 274 return FALSE; 275 } 276 } 277 278 NTSTATUS 279 NTAPI 280 SeDefaultObjectMethod(IN PVOID Object, 281 IN SECURITY_OPERATION_CODE OperationType, 282 IN PSECURITY_INFORMATION SecurityInformation, 283 IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor, 284 IN OUT PULONG ReturnLength OPTIONAL, 285 IN OUT PSECURITY_DESCRIPTOR *OldSecurityDescriptor, 286 IN POOL_TYPE PoolType, 287 IN PGENERIC_MAPPING GenericMapping) 288 { 289 PAGED_CODE(); 290 291 /* Select the operation type */ 292 switch (OperationType) 293 { 294 /* Setting a new descriptor */ 295 case SetSecurityDescriptor: 296 297 /* Sanity check */ 298 ASSERT((PoolType == PagedPool) || (PoolType == NonPagedPool)); 299 300 /* Set the information */ 301 return ObSetSecurityDescriptorInfo(Object, 302 SecurityInformation, 303 SecurityDescriptor, 304 OldSecurityDescriptor, 305 PoolType, 306 GenericMapping); 307 308 case QuerySecurityDescriptor: 309 310 /* Query the information */ 311 return ObQuerySecurityDescriptorInfo(Object, 312 SecurityInformation, 313 SecurityDescriptor, 314 ReturnLength, 315 OldSecurityDescriptor); 316 317 case DeleteSecurityDescriptor: 318 319 /* De-assign it */ 320 return ObDeassignSecurity(OldSecurityDescriptor); 321 322 case AssignSecurityDescriptor: 323 324 /* Assign it */ 325 ObAssignObjectSecurityDescriptor(Object, SecurityDescriptor, PoolType); 326 return STATUS_SUCCESS; 327 328 default: 329 330 /* Bug check */ 331 KeBugCheckEx(SECURITY_SYSTEM, 0, STATUS_INVALID_PARAMETER, 0, 0); 332 } 333 334 /* Should never reach here */ 335 ASSERT(FALSE); 336 return STATUS_SUCCESS; 337 } 338 339 VOID 340 NTAPI 341 SeQuerySecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation, 342 OUT PACCESS_MASK DesiredAccess) 343 { 344 *DesiredAccess = 0; 345 346 if (SecurityInformation & (OWNER_SECURITY_INFORMATION | 347 GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION)) 348 { 349 *DesiredAccess |= READ_CONTROL; 350 } 351 352 if (SecurityInformation & SACL_SECURITY_INFORMATION) 353 { 354 *DesiredAccess |= ACCESS_SYSTEM_SECURITY; 355 } 356 } 357 358 VOID 359 NTAPI 360 SeSetSecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation, 361 OUT PACCESS_MASK DesiredAccess) 362 { 363 *DesiredAccess = 0; 364 365 if (SecurityInformation & (OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION)) 366 { 367 *DesiredAccess |= WRITE_OWNER; 368 } 369 370 if (SecurityInformation & DACL_SECURITY_INFORMATION) 371 { 372 *DesiredAccess |= WRITE_DAC; 373 } 374 375 if (SecurityInformation & SACL_SECURITY_INFORMATION) 376 { 377 *DesiredAccess |= ACCESS_SYSTEM_SECURITY; 378 } 379 } 380 381 NTSTATUS 382 NTAPI 383 SeReportSecurityEvent( 384 _In_ ULONG Flags, 385 _In_ PUNICODE_STRING SourceName, 386 _In_opt_ PSID UserSid, 387 _In_ PSE_ADT_PARAMETER_ARRAY AuditParameters) 388 { 389 SECURITY_SUBJECT_CONTEXT SubjectContext; 390 PTOKEN EffectiveToken; 391 PISID Sid; 392 NTSTATUS Status; 393 394 /* Validate parameters */ 395 if ((Flags != 0) || 396 (SourceName == NULL) || 397 (SourceName->Buffer == NULL) || 398 (SourceName->Length == 0) || 399 (AuditParameters == NULL) || 400 (AuditParameters->ParameterCount > SE_MAX_AUDIT_PARAMETERS - 4)) 401 { 402 return STATUS_INVALID_PARAMETER; 403 } 404 405 /* Validate the source name */ 406 Status = RtlValidateUnicodeString(0, SourceName); 407 if (!NT_SUCCESS(Status)) 408 { 409 return Status; 410 } 411 412 /* Check if we have a user SID */ 413 if (UserSid != NULL) 414 { 415 /* Validate it */ 416 if (!RtlValidSid(UserSid)) 417 { 418 return STATUS_INVALID_PARAMETER; 419 } 420 421 /* Use the user SID */ 422 Sid = UserSid; 423 } 424 else 425 { 426 /* No user SID, capture the security subject context */ 427 SeCaptureSubjectContext(&SubjectContext); 428 429 /* Extract the effective token */ 430 EffectiveToken = SubjectContext.ClientToken ? 431 SubjectContext.ClientToken : SubjectContext.PrimaryToken; 432 433 /* Use the user-and-groups SID */ 434 Sid = EffectiveToken->UserAndGroups->Sid; 435 } 436 437 UNIMPLEMENTED; 438 439 /* Check if we captured the subject context */ 440 if (Sid != UserSid) 441 { 442 /* Release it */ 443 SeReleaseSubjectContext(&SubjectContext); 444 } 445 446 /* Return success */ 447 return STATUS_SUCCESS; 448 } 449 450 _Const_ 451 NTSTATUS 452 NTAPI 453 SeSetAuditParameter( 454 _Inout_ PSE_ADT_PARAMETER_ARRAY AuditParameters, 455 _In_ SE_ADT_PARAMETER_TYPE Type, 456 _In_range_(<, SE_MAX_AUDIT_PARAMETERS) ULONG Index, 457 _In_reads_(_Inexpressible_("depends on SE_ADT_PARAMETER_TYPE")) PVOID Data) 458 { 459 UNIMPLEMENTED; 460 return STATUS_SUCCESS; 461 } 462 463 /* EOF */ 464