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