Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygensemgr.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS kernel 00004 * FILE: ntoskrnl/se/semgr.c 00005 * PURPOSE: Security manager 00006 * 00007 * PROGRAMMERS: No programmer listed. 00008 */ 00009 00010 /* INCLUDES *******************************************************************/ 00011 00012 #include <ntoskrnl.h> 00013 #define NDEBUG 00014 #include <debug.h> 00015 00016 /* GLOBALS ********************************************************************/ 00017 00018 PSE_EXPORTS SeExports = NULL; 00019 SE_EXPORTS SepExports; 00020 ULONG SidInTokenCalls = 0; 00021 00022 extern ULONG ExpInitializationPhase; 00023 extern ERESOURCE SepSubjectContextLock; 00024 00025 /* PRIVATE FUNCTIONS **********************************************************/ 00026 00027 static BOOLEAN 00028 INIT_FUNCTION 00029 SepInitExports(VOID) 00030 { 00031 SepExports.SeCreateTokenPrivilege = SeCreateTokenPrivilege; 00032 SepExports.SeAssignPrimaryTokenPrivilege = SeAssignPrimaryTokenPrivilege; 00033 SepExports.SeLockMemoryPrivilege = SeLockMemoryPrivilege; 00034 SepExports.SeIncreaseQuotaPrivilege = SeIncreaseQuotaPrivilege; 00035 SepExports.SeUnsolicitedInputPrivilege = SeUnsolicitedInputPrivilege; 00036 SepExports.SeTcbPrivilege = SeTcbPrivilege; 00037 SepExports.SeSecurityPrivilege = SeSecurityPrivilege; 00038 SepExports.SeTakeOwnershipPrivilege = SeTakeOwnershipPrivilege; 00039 SepExports.SeLoadDriverPrivilege = SeLoadDriverPrivilege; 00040 SepExports.SeCreatePagefilePrivilege = SeCreatePagefilePrivilege; 00041 SepExports.SeIncreaseBasePriorityPrivilege = SeIncreaseBasePriorityPrivilege; 00042 SepExports.SeSystemProfilePrivilege = SeSystemProfilePrivilege; 00043 SepExports.SeSystemtimePrivilege = SeSystemtimePrivilege; 00044 SepExports.SeProfileSingleProcessPrivilege = SeProfileSingleProcessPrivilege; 00045 SepExports.SeCreatePermanentPrivilege = SeCreatePermanentPrivilege; 00046 SepExports.SeBackupPrivilege = SeBackupPrivilege; 00047 SepExports.SeRestorePrivilege = SeRestorePrivilege; 00048 SepExports.SeShutdownPrivilege = SeShutdownPrivilege; 00049 SepExports.SeDebugPrivilege = SeDebugPrivilege; 00050 SepExports.SeAuditPrivilege = SeAuditPrivilege; 00051 SepExports.SeSystemEnvironmentPrivilege = SeSystemEnvironmentPrivilege; 00052 SepExports.SeChangeNotifyPrivilege = SeChangeNotifyPrivilege; 00053 SepExports.SeRemoteShutdownPrivilege = SeRemoteShutdownPrivilege; 00054 00055 SepExports.SeNullSid = SeNullSid; 00056 SepExports.SeWorldSid = SeWorldSid; 00057 SepExports.SeLocalSid = SeLocalSid; 00058 SepExports.SeCreatorOwnerSid = SeCreatorOwnerSid; 00059 SepExports.SeCreatorGroupSid = SeCreatorGroupSid; 00060 SepExports.SeNtAuthoritySid = SeNtAuthoritySid; 00061 SepExports.SeDialupSid = SeDialupSid; 00062 SepExports.SeNetworkSid = SeNetworkSid; 00063 SepExports.SeBatchSid = SeBatchSid; 00064 SepExports.SeInteractiveSid = SeInteractiveSid; 00065 SepExports.SeLocalSystemSid = SeLocalSystemSid; 00066 SepExports.SeAliasAdminsSid = SeAliasAdminsSid; 00067 SepExports.SeAliasUsersSid = SeAliasUsersSid; 00068 SepExports.SeAliasGuestsSid = SeAliasGuestsSid; 00069 SepExports.SeAliasPowerUsersSid = SeAliasPowerUsersSid; 00070 SepExports.SeAliasAccountOpsSid = SeAliasAccountOpsSid; 00071 SepExports.SeAliasSystemOpsSid = SeAliasSystemOpsSid; 00072 SepExports.SeAliasPrintOpsSid = SeAliasPrintOpsSid; 00073 SepExports.SeAliasBackupOpsSid = SeAliasBackupOpsSid; 00074 SepExports.SeAuthenticatedUsersSid = SeAuthenticatedUsersSid; 00075 SepExports.SeRestrictedSid = SeRestrictedSid; 00076 SepExports.SeAnonymousLogonSid = SeAnonymousLogonSid; 00077 00078 SepExports.SeUndockPrivilege = SeUndockPrivilege; 00079 SepExports.SeSyncAgentPrivilege = SeSyncAgentPrivilege; 00080 SepExports.SeEnableDelegationPrivilege = SeEnableDelegationPrivilege; 00081 00082 SeExports = &SepExports; 00083 return TRUE; 00084 } 00085 00086 00087 BOOLEAN 00088 NTAPI 00089 INIT_FUNCTION 00090 SepInitializationPhase0(VOID) 00091 { 00092 PAGED_CODE(); 00093 00094 ExpInitLuid(); 00095 if (!SepInitSecurityIDs()) return FALSE; 00096 if (!SepInitDACLs()) return FALSE; 00097 if (!SepInitSDs()) return FALSE; 00098 SepInitPrivileges(); 00099 if (!SepInitExports()) return FALSE; 00100 00101 /* Initialize the subject context lock */ 00102 ExInitializeResource(&SepSubjectContextLock); 00103 00104 /* Initialize token objects */ 00105 SepInitializeTokenImplementation(); 00106 00107 /* Clear impersonation info for the idle thread */ 00108 PsGetCurrentThread()->ImpersonationInfo = NULL; 00109 PspClearCrossThreadFlag(PsGetCurrentThread(), 00110 CT_ACTIVE_IMPERSONATION_INFO_BIT); 00111 00112 /* Initialize the boot token */ 00113 ObInitializeFastReference(&PsGetCurrentProcess()->Token, NULL); 00114 ObInitializeFastReference(&PsGetCurrentProcess()->Token, 00115 SepCreateSystemProcessToken()); 00116 return TRUE; 00117 } 00118 00119 BOOLEAN 00120 NTAPI 00121 INIT_FUNCTION 00122 SepInitializationPhase1(VOID) 00123 { 00124 NTSTATUS Status; 00125 00126 PAGED_CODE(); 00127 00128 /* Insert the system token into the tree */ 00129 Status = ObInsertObject((PVOID)(PsGetCurrentProcess()->Token.Value & 00130 ~MAX_FAST_REFS), 00131 NULL, 00132 0, 00133 0, 00134 NULL, 00135 NULL); 00136 ASSERT(NT_SUCCESS(Status)); 00137 00138 /* FIXME: TODO \\ Security directory */ 00139 return TRUE; 00140 } 00141 00142 BOOLEAN 00143 NTAPI 00144 INIT_FUNCTION 00145 SeInitSystem(VOID) 00146 { 00147 /* Check the initialization phase */ 00148 switch (ExpInitializationPhase) 00149 { 00150 case 0: 00151 00152 /* Do Phase 0 */ 00153 return SepInitializationPhase0(); 00154 00155 case 1: 00156 00157 /* Do Phase 1 */ 00158 return SepInitializationPhase1(); 00159 00160 default: 00161 00162 /* Don't know any other phase! Bugcheck! */ 00163 KeBugCheckEx(UNEXPECTED_INITIALIZATION_CALL, 00164 0, 00165 ExpInitializationPhase, 00166 0, 00167 0); 00168 return FALSE; 00169 } 00170 } 00171 00172 BOOLEAN 00173 NTAPI 00174 INIT_FUNCTION 00175 SeInitSRM(VOID) 00176 { 00177 OBJECT_ATTRIBUTES ObjectAttributes; 00178 UNICODE_STRING Name; 00179 HANDLE DirectoryHandle; 00180 HANDLE EventHandle; 00181 NTSTATUS Status; 00182 00183 /* Create '\Security' directory */ 00184 RtlInitUnicodeString(&Name, 00185 L"\\Security"); 00186 InitializeObjectAttributes(&ObjectAttributes, 00187 &Name, 00188 OBJ_PERMANENT, 00189 0, 00190 NULL); 00191 Status = ZwCreateDirectoryObject(&DirectoryHandle, 00192 DIRECTORY_ALL_ACCESS, 00193 &ObjectAttributes); 00194 if (!NT_SUCCESS(Status)) 00195 { 00196 DPRINT1("Failed to create 'Security' directory!\n"); 00197 return FALSE; 00198 } 00199 00200 /* Create 'LSA_AUTHENTICATION_INITALIZED' event */ 00201 RtlInitUnicodeString(&Name, 00202 L"\\LSA_AUTHENTICATION_INITALIZED"); 00203 InitializeObjectAttributes(&ObjectAttributes, 00204 &Name, 00205 OBJ_PERMANENT, 00206 DirectoryHandle, 00207 SePublicDefaultSd); 00208 Status = ZwCreateEvent(&EventHandle, 00209 EVENT_ALL_ACCESS, 00210 &ObjectAttributes, 00211 SynchronizationEvent, 00212 FALSE); 00213 if (!NT_SUCCESS(Status)) 00214 { 00215 DPRINT1("Failed to create 'LSA_AUTHENTICATION_INITALIZED' event!\n"); 00216 NtClose(DirectoryHandle); 00217 return FALSE; 00218 } 00219 00220 ZwClose(EventHandle); 00221 ZwClose(DirectoryHandle); 00222 00223 /* FIXME: Create SRM port and listener thread */ 00224 00225 return TRUE; 00226 } 00227 00228 NTSTATUS 00229 NTAPI 00230 SeDefaultObjectMethod(IN PVOID Object, 00231 IN SECURITY_OPERATION_CODE OperationType, 00232 IN PSECURITY_INFORMATION SecurityInformation, 00233 IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor, 00234 IN OUT PULONG ReturnLength OPTIONAL, 00235 IN OUT PSECURITY_DESCRIPTOR *OldSecurityDescriptor, 00236 IN POOL_TYPE PoolType, 00237 IN PGENERIC_MAPPING GenericMapping) 00238 { 00239 PAGED_CODE(); 00240 00241 /* Select the operation type */ 00242 switch (OperationType) 00243 { 00244 /* Setting a new descriptor */ 00245 case SetSecurityDescriptor: 00246 00247 /* Sanity check */ 00248 ASSERT((PoolType == PagedPool) || (PoolType == NonPagedPool)); 00249 00250 /* Set the information */ 00251 return ObSetSecurityDescriptorInfo(Object, 00252 SecurityInformation, 00253 SecurityDescriptor, 00254 OldSecurityDescriptor, 00255 PoolType, 00256 GenericMapping); 00257 00258 case QuerySecurityDescriptor: 00259 00260 /* Query the information */ 00261 return ObQuerySecurityDescriptorInfo(Object, 00262 SecurityInformation, 00263 SecurityDescriptor, 00264 ReturnLength, 00265 OldSecurityDescriptor); 00266 00267 case DeleteSecurityDescriptor: 00268 00269 /* De-assign it */ 00270 return ObDeassignSecurity(OldSecurityDescriptor); 00271 00272 case AssignSecurityDescriptor: 00273 00274 /* Assign it */ 00275 ObAssignObjectSecurityDescriptor(Object, SecurityDescriptor, PoolType); 00276 return STATUS_SUCCESS; 00277 00278 default: 00279 00280 /* Bug check */ 00281 KeBugCheckEx(SECURITY_SYSTEM, 0, STATUS_INVALID_PARAMETER, 0, 0); 00282 } 00283 00284 /* Should never reach here */ 00285 ASSERT(FALSE); 00286 return STATUS_SUCCESS; 00287 } 00288 00289 static BOOLEAN 00290 SepSidInToken(PACCESS_TOKEN _Token, 00291 PSID Sid) 00292 { 00293 ULONG i; 00294 PTOKEN Token = (PTOKEN)_Token; 00295 00296 PAGED_CODE(); 00297 00298 SidInTokenCalls++; 00299 if (!(SidInTokenCalls % 10000)) DPRINT1("SidInToken Calls: %d\n", SidInTokenCalls); 00300 00301 if (Token->UserAndGroupCount == 0) 00302 { 00303 return FALSE; 00304 } 00305 00306 for (i=0; i<Token->UserAndGroupCount; i++) 00307 { 00308 if (RtlEqualSid(Sid, Token->UserAndGroups[i].Sid)) 00309 { 00310 if ((i == 0)|| (Token->UserAndGroups[i].Attributes & SE_GROUP_ENABLED)) 00311 { 00312 return TRUE; 00313 } 00314 00315 return FALSE; 00316 } 00317 } 00318 00319 return FALSE; 00320 } 00321 00322 static BOOLEAN 00323 SepTokenIsOwner(PACCESS_TOKEN Token, 00324 PSECURITY_DESCRIPTOR SecurityDescriptor) 00325 { 00326 NTSTATUS Status; 00327 PSID Sid = NULL; 00328 BOOLEAN Defaulted; 00329 00330 Status = RtlGetOwnerSecurityDescriptor(SecurityDescriptor, 00331 &Sid, 00332 &Defaulted); 00333 if (!NT_SUCCESS(Status)) 00334 { 00335 DPRINT1("RtlGetOwnerSecurityDescriptor() failed (Status %lx)\n", Status); 00336 return FALSE; 00337 } 00338 00339 if (Sid == NULL) 00340 { 00341 DPRINT1("Owner Sid is NULL\n"); 00342 return FALSE; 00343 } 00344 00345 return SepSidInToken(Token, Sid); 00346 } 00347 00348 VOID 00349 NTAPI 00350 SeQuerySecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation, 00351 OUT PACCESS_MASK DesiredAccess) 00352 { 00353 *DesiredAccess = 0; 00354 00355 if (SecurityInformation & (OWNER_SECURITY_INFORMATION | 00356 GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION)) 00357 { 00358 *DesiredAccess |= READ_CONTROL; 00359 } 00360 00361 if (SecurityInformation & SACL_SECURITY_INFORMATION) 00362 { 00363 *DesiredAccess |= ACCESS_SYSTEM_SECURITY; 00364 } 00365 } 00366 00367 VOID 00368 NTAPI 00369 SeSetSecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation, 00370 OUT PACCESS_MASK DesiredAccess) 00371 { 00372 *DesiredAccess = 0; 00373 00374 if (SecurityInformation & (OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION)) 00375 { 00376 *DesiredAccess |= WRITE_OWNER; 00377 } 00378 00379 if (SecurityInformation & DACL_SECURITY_INFORMATION) 00380 { 00381 *DesiredAccess |= WRITE_DAC; 00382 } 00383 00384 if (SecurityInformation & SACL_SECURITY_INFORMATION) 00385 { 00386 *DesiredAccess |= ACCESS_SYSTEM_SECURITY; 00387 } 00388 } 00389 00390 00391 #define OLD_ACCESS_CHECK 00392 00393 BOOLEAN NTAPI 00394 SepAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor, 00395 IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext, 00396 IN ACCESS_MASK DesiredAccess, 00397 IN ACCESS_MASK PreviouslyGrantedAccess, 00398 OUT PPRIVILEGE_SET* Privileges, 00399 IN PGENERIC_MAPPING GenericMapping, 00400 IN KPROCESSOR_MODE AccessMode, 00401 OUT PACCESS_MASK GrantedAccess, 00402 OUT PNTSTATUS AccessStatus) 00403 { 00404 LUID_AND_ATTRIBUTES Privilege; 00405 #ifdef OLD_ACCESS_CHECK 00406 ACCESS_MASK CurrentAccess, AccessMask; 00407 #endif 00408 ACCESS_MASK RemainingAccess; 00409 ACCESS_MASK TempAccess; 00410 ACCESS_MASK TempGrantedAccess = 0; 00411 ACCESS_MASK TempDeniedAccess = 0; 00412 PACCESS_TOKEN Token; 00413 ULONG i; 00414 PACL Dacl; 00415 BOOLEAN Present; 00416 BOOLEAN Defaulted; 00417 PACE CurrentAce; 00418 PSID Sid; 00419 NTSTATUS Status; 00420 PAGED_CODE(); 00421 00422 /* Check for no access desired */ 00423 if (!DesiredAccess) 00424 { 00425 /* Check if we had no previous access */ 00426 if (!PreviouslyGrantedAccess) 00427 { 00428 /* Then there's nothing to give */ 00429 *AccessStatus = STATUS_ACCESS_DENIED; 00430 return FALSE; 00431 } 00432 00433 /* Return the previous access only */ 00434 *GrantedAccess = PreviouslyGrantedAccess; 00435 *AccessStatus = STATUS_SUCCESS; 00436 *Privileges = NULL; 00437 return TRUE; 00438 } 00439 00440 /* Map given accesses */ 00441 RtlMapGenericMask(&DesiredAccess, GenericMapping); 00442 if (PreviouslyGrantedAccess) 00443 RtlMapGenericMask(&PreviouslyGrantedAccess, GenericMapping); 00444 00445 #ifdef OLD_ACCESS_CHECK 00446 CurrentAccess = PreviouslyGrantedAccess; 00447 #endif 00448 /* Initialize remaining access rights */ 00449 RemainingAccess = DesiredAccess; 00450 00451 Token = SubjectSecurityContext->ClientToken ? 00452 SubjectSecurityContext->ClientToken : SubjectSecurityContext->PrimaryToken; 00453 00454 /* Check for system security access */ 00455 if (RemainingAccess & ACCESS_SYSTEM_SECURITY) 00456 { 00457 Privilege.Luid = SeSecurityPrivilege; 00458 Privilege.Attributes = SE_PRIVILEGE_ENABLED; 00459 00460 /* Fail if we do not the SeSecurityPrivilege */ 00461 if (!SepPrivilegeCheck(Token, 00462 &Privilege, 00463 1, 00464 PRIVILEGE_SET_ALL_NECESSARY, 00465 AccessMode)) 00466 { 00467 *AccessStatus = STATUS_PRIVILEGE_NOT_HELD; 00468 return FALSE; 00469 } 00470 00471 /* Adjust access rights */ 00472 RemainingAccess &= ~ACCESS_SYSTEM_SECURITY; 00473 PreviouslyGrantedAccess |= ACCESS_SYSTEM_SECURITY; 00474 00475 /* Succeed if there are no more rights to grant */ 00476 if (RemainingAccess == 0) 00477 { 00478 *GrantedAccess = PreviouslyGrantedAccess; 00479 *AccessStatus = STATUS_SUCCESS; 00480 return TRUE; 00481 } 00482 } 00483 00484 /* Get the DACL */ 00485 Status = RtlGetDaclSecurityDescriptor(SecurityDescriptor, 00486 &Present, 00487 &Dacl, 00488 &Defaulted); 00489 if (!NT_SUCCESS(Status)) 00490 { 00491 *AccessStatus = Status; 00492 return FALSE; 00493 } 00494 00495 /* RULE 1: Grant desired access if the object is unprotected */ 00496 if (Present == FALSE || Dacl == NULL) 00497 { 00498 if (DesiredAccess & MAXIMUM_ALLOWED) 00499 { 00500 *GrantedAccess = GenericMapping->GenericAll; 00501 *GrantedAccess |= (DesiredAccess & ~MAXIMUM_ALLOWED); 00502 } 00503 else 00504 { 00505 *GrantedAccess = DesiredAccess | PreviouslyGrantedAccess; 00506 } 00507 00508 *AccessStatus = STATUS_SUCCESS; 00509 return TRUE; 00510 } 00511 00512 #ifdef OLD_ACCESS_CHECK 00513 CurrentAccess = PreviouslyGrantedAccess; 00514 #endif 00515 00516 /* RULE 2: Check token for 'take ownership' privilege */ 00517 if (DesiredAccess & WRITE_OWNER) 00518 { 00519 Privilege.Luid = SeTakeOwnershipPrivilege; 00520 Privilege.Attributes = SE_PRIVILEGE_ENABLED; 00521 00522 if (SepPrivilegeCheck(Token, 00523 &Privilege, 00524 1, 00525 PRIVILEGE_SET_ALL_NECESSARY, 00526 AccessMode)) 00527 { 00528 /* Adjust access rights */ 00529 RemainingAccess &= ~WRITE_OWNER; 00530 PreviouslyGrantedAccess |= WRITE_OWNER; 00531 #ifdef OLD_ACCESS_CHECK 00532 CurrentAccess |= WRITE_OWNER; 00533 #endif 00534 00535 /* Succeed if there are no more rights to grant */ 00536 if (RemainingAccess == 0) 00537 { 00538 *GrantedAccess = PreviouslyGrantedAccess; 00539 *AccessStatus = STATUS_SUCCESS; 00540 return TRUE; 00541 } 00542 } 00543 } 00544 00545 /* Deny access if the DACL is empty */ 00546 if (Dacl->AceCount == 0) 00547 { 00548 if (RemainingAccess == MAXIMUM_ALLOWED && PreviouslyGrantedAccess != 0) 00549 { 00550 *GrantedAccess = PreviouslyGrantedAccess; 00551 *AccessStatus = STATUS_SUCCESS; 00552 return TRUE; 00553 } 00554 else 00555 { 00556 *GrantedAccess = 0; 00557 *AccessStatus = STATUS_ACCESS_DENIED; 00558 return FALSE; 00559 } 00560 } 00561 00562 /* Fail if DACL is absent */ 00563 if (Present == FALSE) 00564 { 00565 *GrantedAccess = 0; 00566 *AccessStatus = STATUS_ACCESS_DENIED; 00567 return FALSE; 00568 } 00569 00570 /* Determine the MAXIMUM_ALLOWED access rights according to the DACL */ 00571 if (DesiredAccess & MAXIMUM_ALLOWED) 00572 { 00573 CurrentAce = (PACE)(Dacl + 1); 00574 for (i = 0; i < Dacl->AceCount; i++) 00575 { 00576 if (!(CurrentAce->Header.AceFlags & INHERIT_ONLY_ACE)) 00577 { 00578 Sid = (PSID)(CurrentAce + 1); 00579 if (CurrentAce->Header.AceType == ACCESS_DENIED_ACE_TYPE) 00580 { 00581 if (SepSidInToken(Token, Sid)) 00582 { 00583 /* Map access rights from the ACE */ 00584 TempAccess = CurrentAce->AccessMask; 00585 RtlMapGenericMask(&TempAccess, GenericMapping); 00586 00587 /* Deny access rights that have not been granted yet */ 00588 TempDeniedAccess |= (TempAccess & ~TempGrantedAccess); 00589 } 00590 } 00591 else if (CurrentAce->Header.AceType == ACCESS_ALLOWED_ACE_TYPE) 00592 { 00593 if (SepSidInToken(Token, Sid)) 00594 { 00595 /* Map access rights from the ACE */ 00596 TempAccess = CurrentAce->AccessMask; 00597 RtlMapGenericMask(&TempAccess, GenericMapping); 00598 00599 /* Grant access rights that have not been denied yet */ 00600 TempGrantedAccess |= (TempAccess & ~TempDeniedAccess); 00601 } 00602 } 00603 else 00604 { 00605 DPRINT1("Unsupported ACE type 0x%lx\n", CurrentAce->Header.AceType); 00606 } 00607 } 00608 00609 /* Get the next ACE */ 00610 CurrentAce = (PACE)((ULONG_PTR)CurrentAce + CurrentAce->Header.AceSize); 00611 } 00612 00613 /* Fail if some rights have not been granted */ 00614 RemainingAccess &= ~(MAXIMUM_ALLOWED | TempGrantedAccess); 00615 if (RemainingAccess != 0) 00616 { 00617 *GrantedAccess = 0; 00618 *AccessStatus = STATUS_ACCESS_DENIED; 00619 return FALSE; 00620 } 00621 00622 /* Set granted access right and access status */ 00623 *GrantedAccess = TempGrantedAccess | PreviouslyGrantedAccess; 00624 if (*GrantedAccess != 0) 00625 { 00626 *AccessStatus = STATUS_SUCCESS; 00627 return TRUE; 00628 } 00629 else 00630 { 00631 *AccessStatus = STATUS_ACCESS_DENIED; 00632 return FALSE; 00633 } 00634 } 00635 00636 /* RULE 4: Grant rights according to the DACL */ 00637 CurrentAce = (PACE)(Dacl + 1); 00638 for (i = 0; i < Dacl->AceCount; i++) 00639 { 00640 if (!(CurrentAce->Header.AceFlags & INHERIT_ONLY_ACE)) 00641 { 00642 Sid = (PSID)(CurrentAce + 1); 00643 if (CurrentAce->Header.AceType == ACCESS_DENIED_ACE_TYPE) 00644 { 00645 if (SepSidInToken(Token, Sid)) 00646 { 00647 #ifdef OLD_ACCESS_CHECK 00648 *GrantedAccess = 0; 00649 *AccessStatus = STATUS_ACCESS_DENIED; 00650 return FALSE; 00651 #else 00652 /* Map access rights from the ACE */ 00653 TempAccess = CurrentAce->AccessMask; 00654 RtlMapGenericMask(&TempAccess, GenericMapping); 00655 00656 /* Leave if a remaining right must be denied */ 00657 if (RemainingAccess & TempAccess) 00658 break; 00659 #endif 00660 } 00661 } 00662 else if (CurrentAce->Header.AceType == ACCESS_ALLOWED_ACE_TYPE) 00663 { 00664 if (SepSidInToken(Token, Sid)) 00665 { 00666 #ifdef OLD_ACCESS_CHECK 00667 AccessMask = CurrentAce->AccessMask; 00668 RtlMapGenericMask(&AccessMask, GenericMapping); 00669 CurrentAccess |= AccessMask; 00670 #else 00671 /* Map access rights from the ACE */ 00672 TempAccess = CurrentAce->AccessMask; 00673 RtlMapGenericMask(&TempAccess, GenericMapping); 00674 00675 /* Remove granted rights */ 00676 RemainingAccess &= ~TempAccess; 00677 #endif 00678 } 00679 } 00680 else 00681 { 00682 DPRINT1("Unsupported ACE type 0x%lx\n", CurrentAce->Header.AceType); 00683 } 00684 } 00685 00686 /* Get the next ACE */ 00687 CurrentAce = (PACE)((ULONG_PTR)CurrentAce + CurrentAce->Header.AceSize); 00688 } 00689 00690 #ifdef OLD_ACCESS_CHECK 00691 DPRINT("CurrentAccess %08lx\n DesiredAccess %08lx\n", 00692 CurrentAccess, DesiredAccess); 00693 00694 *GrantedAccess = CurrentAccess & DesiredAccess; 00695 00696 if ((*GrantedAccess & ~VALID_INHERIT_FLAGS) == 00697 (DesiredAccess & ~VALID_INHERIT_FLAGS)) 00698 { 00699 *AccessStatus = STATUS_SUCCESS; 00700 return TRUE; 00701 } 00702 else 00703 { 00704 DPRINT1("HACK: Should deny access for caller: granted 0x%lx, desired 0x%lx (generic mapping %p).\n", 00705 *GrantedAccess, DesiredAccess, GenericMapping); 00706 //*AccessStatus = STATUS_ACCESS_DENIED; 00707 //return FALSE; 00708 *GrantedAccess = DesiredAccess; 00709 *AccessStatus = STATUS_SUCCESS; 00710 return TRUE; 00711 } 00712 #else 00713 DPRINT("DesiredAccess %08lx\nPreviouslyGrantedAccess %08lx\nRemainingAccess %08lx\n", 00714 DesiredAccess, PreviouslyGrantedAccess, RemainingAccess); 00715 00716 /* Fail if some rights have not been granted */ 00717 if (RemainingAccess != 0) 00718 { 00719 *GrantedAccess = 0; 00720 *AccessStatus = STATUS_ACCESS_DENIED; 00721 return FALSE; 00722 } 00723 00724 /* Set granted access rights */ 00725 *GrantedAccess = DesiredAccess | PreviouslyGrantedAccess; 00726 00727 DPRINT("GrantedAccess %08lx\n", *GrantedAccess); 00728 00729 /* Fail if no rights have been granted */ 00730 if (*GrantedAccess == 0) 00731 { 00732 *AccessStatus = STATUS_ACCESS_DENIED; 00733 return FALSE; 00734 } 00735 00736 *AccessStatus = STATUS_SUCCESS; 00737 return TRUE; 00738 #endif 00739 } 00740 00741 static PSID 00742 SepGetSDOwner(IN PSECURITY_DESCRIPTOR _SecurityDescriptor) 00743 { 00744 PISECURITY_DESCRIPTOR SecurityDescriptor = _SecurityDescriptor; 00745 PSID Owner; 00746 00747 if (SecurityDescriptor->Control & SE_SELF_RELATIVE) 00748 Owner = (PSID)((ULONG_PTR)SecurityDescriptor->Owner + 00749 (ULONG_PTR)SecurityDescriptor); 00750 else 00751 Owner = (PSID)SecurityDescriptor->Owner; 00752 00753 return Owner; 00754 } 00755 00756 static PSID 00757 SepGetSDGroup(IN PSECURITY_DESCRIPTOR _SecurityDescriptor) 00758 { 00759 PISECURITY_DESCRIPTOR SecurityDescriptor = _SecurityDescriptor; 00760 PSID Group; 00761 00762 if (SecurityDescriptor->Control & SE_SELF_RELATIVE) 00763 Group = (PSID)((ULONG_PTR)SecurityDescriptor->Group + 00764 (ULONG_PTR)SecurityDescriptor); 00765 else 00766 Group = (PSID)SecurityDescriptor->Group; 00767 00768 return Group; 00769 } 00770 00771 00772 /* PUBLIC FUNCTIONS ***********************************************************/ 00773 00774 /* 00775 * @implemented 00776 */ 00777 BOOLEAN 00778 NTAPI 00779 SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor, 00780 IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext, 00781 IN BOOLEAN SubjectContextLocked, 00782 IN ACCESS_MASK DesiredAccess, 00783 IN ACCESS_MASK PreviouslyGrantedAccess, 00784 OUT PPRIVILEGE_SET* Privileges, 00785 IN PGENERIC_MAPPING GenericMapping, 00786 IN KPROCESSOR_MODE AccessMode, 00787 OUT PACCESS_MASK GrantedAccess, 00788 OUT PNTSTATUS AccessStatus) 00789 { 00790 BOOLEAN ret; 00791 00792 PAGED_CODE(); 00793 00794 /* Check if this is kernel mode */ 00795 if (AccessMode == KernelMode) 00796 { 00797 /* Check if kernel wants everything */ 00798 if (DesiredAccess & MAXIMUM_ALLOWED) 00799 { 00800 /* Give it */ 00801 *GrantedAccess = GenericMapping->GenericAll; 00802 *GrantedAccess |= (DesiredAccess &~ MAXIMUM_ALLOWED); 00803 *GrantedAccess |= PreviouslyGrantedAccess; 00804 } 00805 else 00806 { 00807 /* Give the desired and previous access */ 00808 *GrantedAccess = DesiredAccess | PreviouslyGrantedAccess; 00809 } 00810 00811 /* Success */ 00812 *AccessStatus = STATUS_SUCCESS; 00813 return TRUE; 00814 } 00815 00816 /* Check if we didn't get an SD */ 00817 if (!SecurityDescriptor) 00818 { 00819 /* Automatic failure */ 00820 *AccessStatus = STATUS_ACCESS_DENIED; 00821 return FALSE; 00822 } 00823 00824 /* Check for invalid impersonation */ 00825 if ((SubjectSecurityContext->ClientToken) && 00826 (SubjectSecurityContext->ImpersonationLevel < SecurityImpersonation)) 00827 { 00828 *AccessStatus = STATUS_BAD_IMPERSONATION_LEVEL; 00829 return FALSE; 00830 } 00831 00832 /* Acquire the lock if needed */ 00833 if (!SubjectContextLocked) 00834 SeLockSubjectContext(SubjectSecurityContext); 00835 00836 /* Check if the token is the owner and grant WRITE_DAC and READ_CONTROL rights */ 00837 if (DesiredAccess & (WRITE_DAC | READ_CONTROL | MAXIMUM_ALLOWED)) 00838 { 00839 PACCESS_TOKEN Token = SubjectSecurityContext->ClientToken ? 00840 SubjectSecurityContext->ClientToken : SubjectSecurityContext->PrimaryToken; 00841 00842 if (SepTokenIsOwner(Token, 00843 SecurityDescriptor)) 00844 { 00845 if (DesiredAccess & MAXIMUM_ALLOWED) 00846 PreviouslyGrantedAccess |= (WRITE_DAC | READ_CONTROL); 00847 else 00848 PreviouslyGrantedAccess |= (DesiredAccess & (WRITE_DAC | READ_CONTROL)); 00849 00850 DesiredAccess &= ~(WRITE_DAC | READ_CONTROL); 00851 } 00852 } 00853 00854 if (DesiredAccess == 0) 00855 { 00856 *GrantedAccess = PreviouslyGrantedAccess; 00857 *AccessStatus = STATUS_SUCCESS; 00858 ret = TRUE; 00859 } 00860 else 00861 { 00862 /* Call the internal function */ 00863 ret = SepAccessCheck(SecurityDescriptor, 00864 SubjectSecurityContext, 00865 DesiredAccess, 00866 PreviouslyGrantedAccess, 00867 Privileges, 00868 GenericMapping, 00869 AccessMode, 00870 GrantedAccess, 00871 AccessStatus); 00872 } 00873 00874 /* Release the lock if needed */ 00875 if (!SubjectContextLocked) 00876 SeUnlockSubjectContext(SubjectSecurityContext); 00877 00878 return ret; 00879 } 00880 00881 /* SYSTEM CALLS ***************************************************************/ 00882 00883 /* 00884 * @implemented 00885 */ 00886 NTSTATUS 00887 NTAPI 00888 NtAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor, 00889 IN HANDLE TokenHandle, 00890 IN ACCESS_MASK DesiredAccess, 00891 IN PGENERIC_MAPPING GenericMapping, 00892 OUT PPRIVILEGE_SET PrivilegeSet OPTIONAL, 00893 IN OUT PULONG PrivilegeSetLength, 00894 OUT PACCESS_MASK GrantedAccess, 00895 OUT PNTSTATUS AccessStatus) 00896 { 00897 PSECURITY_DESCRIPTOR CapturedSecurityDescriptor = NULL; 00898 SECURITY_SUBJECT_CONTEXT SubjectSecurityContext; 00899 KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); 00900 ACCESS_MASK PreviouslyGrantedAccess = 0; 00901 PTOKEN Token; 00902 NTSTATUS Status; 00903 PAGED_CODE(); 00904 00905 /* Check if this is kernel mode */ 00906 if (PreviousMode == KernelMode) 00907 { 00908 /* Check if kernel wants everything */ 00909 if (DesiredAccess & MAXIMUM_ALLOWED) 00910 { 00911 /* Give it */ 00912 *GrantedAccess = GenericMapping->GenericAll; 00913 *GrantedAccess |= (DesiredAccess &~ MAXIMUM_ALLOWED); 00914 } 00915 else 00916 { 00917 /* Just give the desired access */ 00918 *GrantedAccess = DesiredAccess; 00919 } 00920 00921 /* Success */ 00922 *AccessStatus = STATUS_SUCCESS; 00923 return STATUS_SUCCESS; 00924 } 00925 00926 /* Protect probe in SEH */ 00927 _SEH2_TRY 00928 { 00929 /* Probe all pointers */ 00930 ProbeForRead(GenericMapping, sizeof(GENERIC_MAPPING), sizeof(ULONG)); 00931 ProbeForRead(PrivilegeSetLength, sizeof(ULONG), sizeof(ULONG)); 00932 ProbeForWrite(PrivilegeSet, *PrivilegeSetLength, sizeof(ULONG)); 00933 ProbeForWrite(GrantedAccess, sizeof(ACCESS_MASK), sizeof(ULONG)); 00934 ProbeForWrite(AccessStatus, sizeof(NTSTATUS), sizeof(ULONG)); 00935 } 00936 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 00937 { 00938 /* Return the exception code */ 00939 _SEH2_YIELD(return _SEH2_GetExceptionCode()); 00940 } 00941 _SEH2_END; 00942 00943 /* Check for unmapped access rights */ 00944 if (DesiredAccess & (GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL)) 00945 return STATUS_GENERIC_NOT_MAPPED; 00946 00947 /* Reference the token */ 00948 Status = ObReferenceObjectByHandle(TokenHandle, 00949 TOKEN_QUERY, 00950 SeTokenObjectType, 00951 PreviousMode, 00952 (PVOID*)&Token, 00953 NULL); 00954 if (!NT_SUCCESS(Status)) 00955 { 00956 DPRINT("Failed to reference token (Status %lx)\n", Status); 00957 return Status; 00958 } 00959 00960 /* Check token type */ 00961 if (Token->TokenType != TokenImpersonation) 00962 { 00963 DPRINT("No impersonation token\n"); 00964 ObDereferenceObject(Token); 00965 return STATUS_NO_IMPERSONATION_TOKEN; 00966 } 00967 00968 /* Check the impersonation level */ 00969 if (Token->ImpersonationLevel < SecurityIdentification) 00970 { 00971 DPRINT("Impersonation level < SecurityIdentification\n"); 00972 ObDereferenceObject(Token); 00973 return STATUS_BAD_IMPERSONATION_LEVEL; 00974 } 00975 00976 /* Capture the security descriptor */ 00977 Status = SeCaptureSecurityDescriptor(SecurityDescriptor, 00978 PreviousMode, 00979 PagedPool, 00980 FALSE, 00981 &CapturedSecurityDescriptor); 00982 if (!NT_SUCCESS(Status)) 00983 { 00984 DPRINT("Failed to capture the Security Descriptor\n"); 00985 ObDereferenceObject(Token); 00986 return Status; 00987 } 00988 00989 /* Check the captured security descriptor */ 00990 if (CapturedSecurityDescriptor == NULL) 00991 { 00992 DPRINT("Security Descriptor is NULL\n"); 00993 ObDereferenceObject(Token); 00994 return STATUS_INVALID_SECURITY_DESCR; 00995 } 00996 00997 /* Check security descriptor for valid owner and group */ 00998 if (SepGetSDOwner(SecurityDescriptor) == NULL || // FIXME: use CapturedSecurityDescriptor 00999 SepGetSDGroup(SecurityDescriptor) == NULL) // FIXME: use CapturedSecurityDescriptor 01000 { 01001 DPRINT("Security Descriptor does not have a valid group or owner\n"); 01002 SeReleaseSecurityDescriptor(CapturedSecurityDescriptor, 01003 PreviousMode, 01004 FALSE); 01005 ObDereferenceObject(Token); 01006 return STATUS_INVALID_SECURITY_DESCR; 01007 } 01008 01009 /* Set up the subject context, and lock it */ 01010 SubjectSecurityContext.ClientToken = Token; 01011 SubjectSecurityContext.ImpersonationLevel = Token->ImpersonationLevel; 01012 SubjectSecurityContext.PrimaryToken = NULL; 01013 SubjectSecurityContext.ProcessAuditId = NULL; 01014 SeLockSubjectContext(&SubjectSecurityContext); 01015 01016 /* Check if the token is the owner and grant WRITE_DAC and READ_CONTROL rights */ 01017 if (DesiredAccess & (WRITE_DAC | READ_CONTROL | MAXIMUM_ALLOWED)) 01018 { 01019 if (SepTokenIsOwner(Token, SecurityDescriptor)) // FIXME: use CapturedSecurityDescriptor 01020 { 01021 if (DesiredAccess & MAXIMUM_ALLOWED) 01022 PreviouslyGrantedAccess |= (WRITE_DAC | READ_CONTROL); 01023 else 01024 PreviouslyGrantedAccess |= (DesiredAccess & (WRITE_DAC | READ_CONTROL)); 01025 01026 DesiredAccess &= ~(WRITE_DAC | READ_CONTROL); 01027 } 01028 } 01029 01030 if (DesiredAccess == 0) 01031 { 01032 *GrantedAccess = PreviouslyGrantedAccess; 01033 *AccessStatus = STATUS_SUCCESS; 01034 } 01035 else 01036 { 01037 /* Now perform the access check */ 01038 SepAccessCheck(SecurityDescriptor, // FIXME: use CapturedSecurityDescriptor 01039 &SubjectSecurityContext, 01040 DesiredAccess, 01041 PreviouslyGrantedAccess, 01042 &PrivilegeSet, //FIXME 01043 GenericMapping, 01044 PreviousMode, 01045 GrantedAccess, 01046 AccessStatus); 01047 } 01048 01049 /* Unlock subject context */ 01050 SeUnlockSubjectContext(&SubjectSecurityContext); 01051 01052 /* Release the captured security descriptor */ 01053 SeReleaseSecurityDescriptor(CapturedSecurityDescriptor, 01054 PreviousMode, 01055 FALSE); 01056 01057 /* Dereference the token */ 01058 ObDereferenceObject(Token); 01059 01060 /* Check succeeded */ 01061 return STATUS_SUCCESS; 01062 } 01063 01064 01065 NTSTATUS 01066 NTAPI 01067 NtAccessCheckByType(IN PSECURITY_DESCRIPTOR SecurityDescriptor, 01068 IN PSID PrincipalSelfSid, 01069 IN HANDLE ClientToken, 01070 IN ACCESS_MASK DesiredAccess, 01071 IN POBJECT_TYPE_LIST ObjectTypeList, 01072 IN ULONG ObjectTypeLength, 01073 IN PGENERIC_MAPPING GenericMapping, 01074 IN PPRIVILEGE_SET PrivilegeSet, 01075 IN ULONG PrivilegeSetLength, 01076 OUT PACCESS_MASK GrantedAccess, 01077 OUT PNTSTATUS AccessStatus) 01078 { 01079 UNIMPLEMENTED; 01080 return STATUS_NOT_IMPLEMENTED; 01081 } 01082 01083 NTSTATUS 01084 NTAPI 01085 NtAccessCheckByTypeAndAuditAlarm(IN PUNICODE_STRING SubsystemName, 01086 IN HANDLE HandleId, 01087 IN PUNICODE_STRING ObjectTypeName, 01088 IN PUNICODE_STRING ObjectName, 01089 IN PSECURITY_DESCRIPTOR SecurityDescriptor, 01090 IN PSID PrincipalSelfSid, 01091 IN ACCESS_MASK DesiredAccess, 01092 IN AUDIT_EVENT_TYPE AuditType, 01093 IN ULONG Flags, 01094 IN POBJECT_TYPE_LIST ObjectTypeList, 01095 IN ULONG ObjectTypeLength, 01096 IN PGENERIC_MAPPING GenericMapping, 01097 IN BOOLEAN ObjectCreation, 01098 OUT PACCESS_MASK GrantedAccess, 01099 OUT PNTSTATUS AccessStatus, 01100 OUT PBOOLEAN GenerateOnClose) 01101 { 01102 UNIMPLEMENTED; 01103 return STATUS_NOT_IMPLEMENTED; 01104 } 01105 01106 NTSTATUS 01107 NTAPI 01108 NtAccessCheckByTypeResultList(IN PSECURITY_DESCRIPTOR SecurityDescriptor, 01109 IN PSID PrincipalSelfSid, 01110 IN HANDLE ClientToken, 01111 IN ACCESS_MASK DesiredAccess, 01112 IN POBJECT_TYPE_LIST ObjectTypeList, 01113 IN ULONG ObjectTypeLength, 01114 IN PGENERIC_MAPPING GenericMapping, 01115 IN PPRIVILEGE_SET PrivilegeSet, 01116 IN ULONG PrivilegeSetLength, 01117 OUT PACCESS_MASK GrantedAccess, 01118 OUT PNTSTATUS AccessStatus) 01119 { 01120 UNIMPLEMENTED; 01121 return STATUS_NOT_IMPLEMENTED; 01122 } 01123 01124 NTSTATUS 01125 NTAPI 01126 NtAccessCheckByTypeResultListAndAuditAlarm(IN PUNICODE_STRING SubsystemName, 01127 IN HANDLE HandleId, 01128 IN PUNICODE_STRING ObjectTypeName, 01129 IN PUNICODE_STRING ObjectName, 01130 IN PSECURITY_DESCRIPTOR SecurityDescriptor, 01131 IN PSID PrincipalSelfSid, 01132 IN ACCESS_MASK DesiredAccess, 01133 IN AUDIT_EVENT_TYPE AuditType, 01134 IN ULONG Flags, 01135 IN POBJECT_TYPE_LIST ObjectTypeList, 01136 IN ULONG ObjectTypeLength, 01137 IN PGENERIC_MAPPING GenericMapping, 01138 IN BOOLEAN ObjectCreation, 01139 OUT PACCESS_MASK GrantedAccess, 01140 OUT PNTSTATUS AccessStatus, 01141 OUT PBOOLEAN GenerateOnClose) 01142 { 01143 UNIMPLEMENTED; 01144 return STATUS_NOT_IMPLEMENTED; 01145 } 01146 01147 NTSTATUS 01148 NTAPI 01149 NtAccessCheckByTypeResultListAndAuditAlarmByHandle(IN PUNICODE_STRING SubsystemName, 01150 IN HANDLE HandleId, 01151 IN HANDLE ClientToken, 01152 IN PUNICODE_STRING ObjectTypeName, 01153 IN PUNICODE_STRING ObjectName, 01154 IN PSECURITY_DESCRIPTOR SecurityDescriptor, 01155 IN PSID PrincipalSelfSid, 01156 IN ACCESS_MASK DesiredAccess, 01157 IN AUDIT_EVENT_TYPE AuditType, 01158 IN ULONG Flags, 01159 IN POBJECT_TYPE_LIST ObjectTypeList, 01160 IN ULONG ObjectTypeLength, 01161 IN PGENERIC_MAPPING GenericMapping, 01162 IN BOOLEAN ObjectCreation, 01163 OUT PACCESS_MASK GrantedAccess, 01164 OUT PNTSTATUS AccessStatus, 01165 OUT PBOOLEAN GenerateOnClose) 01166 { 01167 UNIMPLEMENTED; 01168 return STATUS_NOT_IMPLEMENTED; 01169 } 01170 01171 /* EOF */ Generated on Sun May 27 2012 04:37:41 for ReactOS by
1.7.6.1
|