Remove a hack from NtAccessCheck(). Bug #4169.

svn path=/trunk/; revision=41610
This commit is contained in:
Dmitry Gorbachev 2009-06-25 13:29:58 +00:00
parent d53c35b02b
commit ff37974bba

View file

@ -49,7 +49,7 @@ SepInitExports(VOID)
SepExports.SeSystemEnvironmentPrivilege = SeSystemEnvironmentPrivilege; SepExports.SeSystemEnvironmentPrivilege = SeSystemEnvironmentPrivilege;
SepExports.SeChangeNotifyPrivilege = SeChangeNotifyPrivilege; SepExports.SeChangeNotifyPrivilege = SeChangeNotifyPrivilege;
SepExports.SeRemoteShutdownPrivilege = SeRemoteShutdownPrivilege; SepExports.SeRemoteShutdownPrivilege = SeRemoteShutdownPrivilege;
SepExports.SeNullSid = SeNullSid; SepExports.SeNullSid = SeNullSid;
SepExports.SeWorldSid = SeWorldSid; SepExports.SeWorldSid = SeWorldSid;
SepExports.SeLocalSid = SeLocalSid; SepExports.SeLocalSid = SeLocalSid;
@ -72,11 +72,11 @@ SepInitExports(VOID)
SepExports.SeAuthenticatedUsersSid = SeAuthenticatedUsersSid; SepExports.SeAuthenticatedUsersSid = SeAuthenticatedUsersSid;
SepExports.SeRestrictedSid = SeRestrictedSid; SepExports.SeRestrictedSid = SeRestrictedSid;
SepExports.SeAnonymousLogonSid = SeAnonymousLogonSid; SepExports.SeAnonymousLogonSid = SeAnonymousLogonSid;
SepExports.SeUndockPrivilege = SeUndockPrivilege; SepExports.SeUndockPrivilege = SeUndockPrivilege;
SepExports.SeSyncAgentPrivilege = SeSyncAgentPrivilege; SepExports.SeSyncAgentPrivilege = SeSyncAgentPrivilege;
SepExports.SeEnableDelegationPrivilege = SeEnableDelegationPrivilege; SepExports.SeEnableDelegationPrivilege = SeEnableDelegationPrivilege;
SeExports = &SepExports; SeExports = &SepExports;
return TRUE; return TRUE;
} }
@ -92,18 +92,18 @@ SepInitializationPhase0(VOID)
if (!SepInitSDs()) return FALSE; if (!SepInitSDs()) return FALSE;
SepInitPrivileges(); SepInitPrivileges();
if (!SepInitExports()) return FALSE; if (!SepInitExports()) return FALSE;
/* Initialize the subject context lock */ /* Initialize the subject context lock */
ExInitializeResource(&SepSubjectContextLock); ExInitializeResource(&SepSubjectContextLock);
/* Initialize token objects */ /* Initialize token objects */
SepInitializeTokenImplementation(); SepInitializeTokenImplementation();
/* Clear impersonation info for the idle thread */ /* Clear impersonation info for the idle thread */
PsGetCurrentThread()->ImpersonationInfo = NULL; PsGetCurrentThread()->ImpersonationInfo = NULL;
PspClearCrossThreadFlag(PsGetCurrentThread(), PspClearCrossThreadFlag(PsGetCurrentThread(),
CT_ACTIVE_IMPERSONATION_INFO_BIT); CT_ACTIVE_IMPERSONATION_INFO_BIT);
/* Initialize the boot token */ /* Initialize the boot token */
ObInitializeFastReference(&PsGetCurrentProcess()->Token, NULL); ObInitializeFastReference(&PsGetCurrentProcess()->Token, NULL);
ObInitializeFastReference(&PsGetCurrentProcess()->Token, ObInitializeFastReference(&PsGetCurrentProcess()->Token,
@ -117,7 +117,7 @@ SepInitializationPhase1(VOID)
{ {
NTSTATUS Status; NTSTATUS Status;
PAGED_CODE(); PAGED_CODE();
/* Insert the system token into the tree */ /* Insert the system token into the tree */
Status = ObInsertObject((PVOID)(PsGetCurrentProcess()->Token.Value & Status = ObInsertObject((PVOID)(PsGetCurrentProcess()->Token.Value &
~MAX_FAST_REFS), ~MAX_FAST_REFS),
@ -127,7 +127,7 @@ SepInitializationPhase1(VOID)
NULL, NULL,
NULL); NULL);
ASSERT(NT_SUCCESS(Status)); ASSERT(NT_SUCCESS(Status));
/* FIXME: TODO \\ Security directory */ /* FIXME: TODO \\ Security directory */
return TRUE; return TRUE;
} }
@ -140,17 +140,17 @@ SeInitSystem(VOID)
switch (ExpInitializationPhase) switch (ExpInitializationPhase)
{ {
case 0: case 0:
/* Do Phase 0 */ /* Do Phase 0 */
return SepInitializationPhase0(); return SepInitializationPhase0();
case 1: case 1:
/* Do Phase 1 */ /* Do Phase 1 */
return SepInitializationPhase1(); return SepInitializationPhase1();
default: default:
/* Don't know any other phase! Bugcheck! */ /* Don't know any other phase! Bugcheck! */
KeBugCheckEx(UNEXPECTED_INITIALIZATION_CALL, KeBugCheckEx(UNEXPECTED_INITIALIZATION_CALL,
0, 0,
@ -170,7 +170,7 @@ SeInitSRM(VOID)
HANDLE DirectoryHandle; HANDLE DirectoryHandle;
HANDLE EventHandle; HANDLE EventHandle;
NTSTATUS Status; NTSTATUS Status;
/* Create '\Security' directory */ /* Create '\Security' directory */
RtlInitUnicodeString(&Name, RtlInitUnicodeString(&Name,
L"\\Security"); L"\\Security");
@ -187,7 +187,7 @@ SeInitSRM(VOID)
DPRINT1("Failed to create 'Security' directory!\n"); DPRINT1("Failed to create 'Security' directory!\n");
return FALSE; return FALSE;
} }
/* Create 'LSA_AUTHENTICATION_INITALIZED' event */ /* Create 'LSA_AUTHENTICATION_INITALIZED' event */
RtlInitUnicodeString(&Name, RtlInitUnicodeString(&Name,
L"\\LSA_AUTHENTICATION_INITALIZED"); L"\\LSA_AUTHENTICATION_INITALIZED");
@ -207,12 +207,12 @@ SeInitSRM(VOID)
NtClose(DirectoryHandle); NtClose(DirectoryHandle);
return FALSE; return FALSE;
} }
ZwClose(EventHandle); ZwClose(EventHandle);
ZwClose(DirectoryHandle); ZwClose(DirectoryHandle);
/* FIXME: Create SRM port and listener thread */ /* FIXME: Create SRM port and listener thread */
return TRUE; return TRUE;
} }
@ -228,16 +228,16 @@ SeDefaultObjectMethod(IN PVOID Object,
IN PGENERIC_MAPPING GenericMapping) IN PGENERIC_MAPPING GenericMapping)
{ {
PAGED_CODE(); PAGED_CODE();
/* Select the operation type */ /* Select the operation type */
switch (OperationType) switch (OperationType)
{ {
/* Setting a new descriptor */ /* Setting a new descriptor */
case SetSecurityDescriptor: case SetSecurityDescriptor:
/* Sanity check */ /* Sanity check */
ASSERT((PoolType == PagedPool) || (PoolType == NonPagedPool)); ASSERT((PoolType == PagedPool) || (PoolType == NonPagedPool));
/* Set the information */ /* Set the information */
return ObSetSecurityDescriptorInfo(Object, return ObSetSecurityDescriptorInfo(Object,
SecurityInformation, SecurityInformation,
@ -245,33 +245,33 @@ SeDefaultObjectMethod(IN PVOID Object,
OldSecurityDescriptor, OldSecurityDescriptor,
PoolType, PoolType,
GenericMapping); GenericMapping);
case QuerySecurityDescriptor: case QuerySecurityDescriptor:
/* Query the information */ /* Query the information */
return ObQuerySecurityDescriptorInfo(Object, return ObQuerySecurityDescriptorInfo(Object,
SecurityInformation, SecurityInformation,
SecurityDescriptor, SecurityDescriptor,
ReturnLength, ReturnLength,
OldSecurityDescriptor); OldSecurityDescriptor);
case DeleteSecurityDescriptor: case DeleteSecurityDescriptor:
/* De-assign it */ /* De-assign it */
return ObDeassignSecurity(OldSecurityDescriptor); return ObDeassignSecurity(OldSecurityDescriptor);
case AssignSecurityDescriptor: case AssignSecurityDescriptor:
/* Assign it */ /* Assign it */
ObAssignObjectSecurityDescriptor(Object, SecurityDescriptor, PoolType); ObAssignObjectSecurityDescriptor(Object, SecurityDescriptor, PoolType);
return STATUS_SUCCESS; return STATUS_SUCCESS;
default: default:
/* Bug check */ /* Bug check */
KeBugCheckEx(SECURITY_SYSTEM, 0, STATUS_INVALID_PARAMETER, 0, 0); KeBugCheckEx(SECURITY_SYSTEM, 0, STATUS_INVALID_PARAMETER, 0, 0);
} }
/* Should never reach here */ /* Should never reach here */
ASSERT(FALSE); ASSERT(FALSE);
return STATUS_SUCCESS; return STATUS_SUCCESS;
@ -284,14 +284,14 @@ SepSidInToken(PACCESS_TOKEN _Token,
{ {
ULONG i; ULONG i;
PTOKEN Token = (PTOKEN)_Token; PTOKEN Token = (PTOKEN)_Token;
PAGED_CODE(); PAGED_CODE();
if (Token->UserAndGroupCount == 0) if (Token->UserAndGroupCount == 0)
{ {
return FALSE; return FALSE;
} }
for (i=0; i<Token->UserAndGroupCount; i++) for (i=0; i<Token->UserAndGroupCount; i++)
{ {
if (RtlEqualSid(Sid, Token->UserAndGroups[i].Sid)) if (RtlEqualSid(Sid, Token->UserAndGroups[i].Sid))
@ -300,11 +300,11 @@ SepSidInToken(PACCESS_TOKEN _Token,
{ {
return TRUE; return TRUE;
} }
return FALSE; return FALSE;
} }
} }
return FALSE; return FALSE;
} }
@ -314,7 +314,7 @@ SeQuerySecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation,
OUT PACCESS_MASK DesiredAccess) OUT PACCESS_MASK DesiredAccess)
{ {
*DesiredAccess = 0; *DesiredAccess = 0;
if (SecurityInformation & (OWNER_SECURITY_INFORMATION | if (SecurityInformation & (OWNER_SECURITY_INFORMATION |
GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION)) GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION))
{ {
@ -331,7 +331,7 @@ SeSetSecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation,
OUT PACCESS_MASK DesiredAccess) OUT PACCESS_MASK DesiredAccess)
{ {
*DesiredAccess = 0; *DesiredAccess = 0;
if (SecurityInformation & (OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION)) if (SecurityInformation & (OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION))
{ {
*DesiredAccess |= WRITE_OWNER; *DesiredAccess |= WRITE_OWNER;
@ -374,7 +374,7 @@ SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
PSID Sid; PSID Sid;
NTSTATUS Status; NTSTATUS Status;
PAGED_CODE(); PAGED_CODE();
/* Check if this is kernel mode */ /* Check if this is kernel mode */
if (AccessMode == KernelMode) if (AccessMode == KernelMode)
{ {
@ -391,12 +391,12 @@ SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
/* Give the desired and previous access */ /* Give the desired and previous access */
*GrantedAccess = DesiredAccess | PreviouslyGrantedAccess; *GrantedAccess = DesiredAccess | PreviouslyGrantedAccess;
} }
/* Success */ /* Success */
*AccessStatus = STATUS_SUCCESS; *AccessStatus = STATUS_SUCCESS;
return TRUE; return TRUE;
} }
/* Check if we didn't get an SD */ /* Check if we didn't get an SD */
if (!SecurityDescriptor) if (!SecurityDescriptor)
{ {
@ -404,7 +404,7 @@ SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
*AccessStatus = STATUS_ACCESS_DENIED; *AccessStatus = STATUS_ACCESS_DENIED;
return FALSE; return FALSE;
} }
/* Check for invalid impersonation */ /* Check for invalid impersonation */
if ((SubjectSecurityContext->ClientToken) && if ((SubjectSecurityContext->ClientToken) &&
(SubjectSecurityContext->ImpersonationLevel < SecurityImpersonation)) (SubjectSecurityContext->ImpersonationLevel < SecurityImpersonation))
@ -412,7 +412,7 @@ SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
*AccessStatus = STATUS_BAD_IMPERSONATION_LEVEL; *AccessStatus = STATUS_BAD_IMPERSONATION_LEVEL;
return FALSE; return FALSE;
} }
/* Check for no access desired */ /* Check for no access desired */
if (!DesiredAccess) if (!DesiredAccess)
{ {
@ -423,31 +423,31 @@ SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
*AccessStatus = STATUS_ACCESS_DENIED; *AccessStatus = STATUS_ACCESS_DENIED;
return FALSE; return FALSE;
} }
/* Return the previous access only */ /* Return the previous access only */
*GrantedAccess = PreviouslyGrantedAccess; *GrantedAccess = PreviouslyGrantedAccess;
*AccessStatus = STATUS_SUCCESS; *AccessStatus = STATUS_SUCCESS;
*Privileges = NULL; *Privileges = NULL;
return TRUE; return TRUE;
} }
/* Acquire the lock if needed */ /* Acquire the lock if needed */
if (!SubjectContextLocked) SeLockSubjectContext(SubjectSecurityContext); if (!SubjectContextLocked) SeLockSubjectContext(SubjectSecurityContext);
/* Map given accesses */ /* Map given accesses */
RtlMapGenericMask(&DesiredAccess, GenericMapping); RtlMapGenericMask(&DesiredAccess, GenericMapping);
if (PreviouslyGrantedAccess) if (PreviouslyGrantedAccess)
RtlMapGenericMask(&PreviouslyGrantedAccess, GenericMapping); RtlMapGenericMask(&PreviouslyGrantedAccess, GenericMapping);
CurrentAccess = PreviouslyGrantedAccess; CurrentAccess = PreviouslyGrantedAccess;
Token = SubjectSecurityContext->ClientToken ? Token = SubjectSecurityContext->ClientToken ?
SubjectSecurityContext->ClientToken : SubjectSecurityContext->PrimaryToken; SubjectSecurityContext->ClientToken : SubjectSecurityContext->PrimaryToken;
/* Get the DACL */ /* Get the DACL */
Status = RtlGetDaclSecurityDescriptor(SecurityDescriptor, Status = RtlGetDaclSecurityDescriptor(SecurityDescriptor,
&Present, &Present,
@ -459,11 +459,11 @@ SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
{ {
SeUnlockSubjectContext(SubjectSecurityContext); SeUnlockSubjectContext(SubjectSecurityContext);
} }
*AccessStatus = Status; *AccessStatus = Status;
return FALSE; return FALSE;
} }
/* RULE 1: Grant desired access if the object is unprotected */ /* RULE 1: Grant desired access if the object is unprotected */
if (Present == TRUE && Dacl == NULL) if (Present == TRUE && Dacl == NULL)
{ {
@ -471,18 +471,18 @@ SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
{ {
SeUnlockSubjectContext(SubjectSecurityContext); SeUnlockSubjectContext(SubjectSecurityContext);
} }
*GrantedAccess = DesiredAccess; *GrantedAccess = DesiredAccess;
*AccessStatus = STATUS_SUCCESS; *AccessStatus = STATUS_SUCCESS;
return TRUE; return TRUE;
} }
CurrentAccess = PreviouslyGrantedAccess; CurrentAccess = PreviouslyGrantedAccess;
/* RULE 2: Check token for 'take ownership' privilege */ /* RULE 2: Check token for 'take ownership' privilege */
Privilege.Luid = SeTakeOwnershipPrivilege; Privilege.Luid = SeTakeOwnershipPrivilege;
Privilege.Attributes = SE_PRIVILEGE_ENABLED; Privilege.Attributes = SE_PRIVILEGE_ENABLED;
if (SepPrivilegeCheck(Token, if (SepPrivilegeCheck(Token,
&Privilege, &Privilege,
1, 1,
@ -497,13 +497,13 @@ SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
{ {
SeUnlockSubjectContext(SubjectSecurityContext); SeUnlockSubjectContext(SubjectSecurityContext);
} }
*GrantedAccess = CurrentAccess; *GrantedAccess = CurrentAccess;
*AccessStatus = STATUS_SUCCESS; *AccessStatus = STATUS_SUCCESS;
return TRUE; return TRUE;
} }
} }
/* RULE 3: Check whether the token is the owner */ /* RULE 3: Check whether the token is the owner */
Status = RtlGetOwnerSecurityDescriptor(SecurityDescriptor, Status = RtlGetOwnerSecurityDescriptor(SecurityDescriptor,
&Sid, &Sid,
@ -515,11 +515,11 @@ SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
{ {
SeUnlockSubjectContext(SubjectSecurityContext); SeUnlockSubjectContext(SubjectSecurityContext);
} }
*AccessStatus = Status; *AccessStatus = Status;
return FALSE; return FALSE;
} }
if (Sid && SepSidInToken(Token, Sid)) if (Sid && SepSidInToken(Token, Sid))
{ {
CurrentAccess |= (READ_CONTROL | WRITE_DAC); CurrentAccess |= (READ_CONTROL | WRITE_DAC);
@ -530,13 +530,13 @@ SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
{ {
SeUnlockSubjectContext(SubjectSecurityContext); SeUnlockSubjectContext(SubjectSecurityContext);
} }
*GrantedAccess = CurrentAccess; *GrantedAccess = CurrentAccess;
*AccessStatus = STATUS_SUCCESS; *AccessStatus = STATUS_SUCCESS;
return TRUE; return TRUE;
} }
} }
/* Fail if DACL is absent */ /* Fail if DACL is absent */
if (Present == FALSE) if (Present == FALSE)
{ {
@ -544,12 +544,12 @@ SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
{ {
SeUnlockSubjectContext(SubjectSecurityContext); SeUnlockSubjectContext(SubjectSecurityContext);
} }
*GrantedAccess = 0; *GrantedAccess = 0;
*AccessStatus = STATUS_ACCESS_DENIED; *AccessStatus = STATUS_ACCESS_DENIED;
return FALSE; return FALSE;
} }
/* RULE 4: Grant rights according to the DACL */ /* RULE 4: Grant rights according to the DACL */
CurrentAce = (PACE)(Dacl + 1); CurrentAce = (PACE)(Dacl + 1);
for (i = 0; i < Dacl->AceCount; i++) for (i = 0; i < Dacl->AceCount; i++)
@ -563,13 +563,13 @@ SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
{ {
SeUnlockSubjectContext(SubjectSecurityContext); SeUnlockSubjectContext(SubjectSecurityContext);
} }
*GrantedAccess = 0; *GrantedAccess = 0;
*AccessStatus = STATUS_ACCESS_DENIED; *AccessStatus = STATUS_ACCESS_DENIED;
return FALSE; return FALSE;
} }
} }
else if (CurrentAce->Header.AceType == ACCESS_ALLOWED_ACE_TYPE) else if (CurrentAce->Header.AceType == ACCESS_ALLOWED_ACE_TYPE)
{ {
if (SepSidInToken(Token, Sid)) if (SepSidInToken(Token, Sid))
@ -585,17 +585,17 @@ SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
} }
CurrentAce = (PACE)((ULONG_PTR)CurrentAce + CurrentAce->Header.AceSize); CurrentAce = (PACE)((ULONG_PTR)CurrentAce + CurrentAce->Header.AceSize);
} }
if (SubjectContextLocked == FALSE) if (SubjectContextLocked == FALSE)
{ {
SeUnlockSubjectContext(SubjectSecurityContext); SeUnlockSubjectContext(SubjectSecurityContext);
} }
DPRINT("CurrentAccess %08lx\n DesiredAccess %08lx\n", DPRINT("CurrentAccess %08lx\n DesiredAccess %08lx\n",
CurrentAccess, DesiredAccess); CurrentAccess, DesiredAccess);
*GrantedAccess = CurrentAccess & DesiredAccess; *GrantedAccess = CurrentAccess & DesiredAccess;
if (DesiredAccess & MAXIMUM_ALLOWED) if (DesiredAccess & MAXIMUM_ALLOWED)
{ {
*GrantedAccess = CurrentAccess; *GrantedAccess = CurrentAccess;
@ -688,32 +688,24 @@ NtAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
SubjectSecurityContext.ProcessAuditId = NULL; SubjectSecurityContext.ProcessAuditId = NULL;
SeLockSubjectContext(&SubjectSecurityContext); SeLockSubjectContext(&SubjectSecurityContext);
/* FIXME */
/* Now perform the access check */ /* Now perform the access check */
if (SeAccessCheck(SecurityDescriptor, SeAccessCheck(SecurityDescriptor,
&SubjectSecurityContext, &SubjectSecurityContext,
TRUE, TRUE,
DesiredAccess, DesiredAccess,
0, 0,
&PrivilegeSet, //FIXME &PrivilegeSet, //FIXME
GenericMapping, GenericMapping,
PreviousMode, PreviousMode,
GrantedAccess, GrantedAccess,
AccessStatus)) AccessStatus);
{
Status = *AccessStatus;
}
else
{
Status = STATUS_ACCESS_DENIED;
}
/* Unlock subject context and dereference the token */ /* Unlock subject context and dereference the token */
SeUnlockSubjectContext(&SubjectSecurityContext); SeUnlockSubjectContext(&SubjectSecurityContext);
ObDereferenceObject(Token); ObDereferenceObject(Token);
/* Check succeeded? */ /* Check succeeded */
return Status; return STATUS_SUCCESS;
} }