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