mirror of
https://github.com/reactos/reactos.git
synced 2025-06-27 15:59:43 +00:00
Fixed NtAdjustPrivilegeToken() and SeSinglePrivilegeCheck().
svn path=/trunk/; revision=4916
This commit is contained in:
parent
a2be00bf0e
commit
b905ce98aa
2 changed files with 265 additions and 175 deletions
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: priv.c,v 1.6 2003/05/31 11:10:30 ekohl Exp $
|
/* $Id: priv.c,v 1.7 2003/06/17 10:42:37 ekohl Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -105,47 +105,48 @@ SepPrivilegeCheck (PACCESS_TOKEN Token,
|
||||||
ULONG PrivilegeControl,
|
ULONG PrivilegeControl,
|
||||||
KPROCESSOR_MODE PreviousMode)
|
KPROCESSOR_MODE PreviousMode)
|
||||||
{
|
{
|
||||||
PLUID_AND_ATTRIBUTES Current;
|
|
||||||
ULONG i;
|
ULONG i;
|
||||||
ULONG j;
|
ULONG j;
|
||||||
ULONG k;
|
ULONG k;
|
||||||
|
|
||||||
|
DPRINT ("SepPrivilegeCheck() called\n");
|
||||||
|
|
||||||
if (PreviousMode == KernelMode)
|
if (PreviousMode == KernelMode)
|
||||||
{
|
{
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
j = 0;
|
k = 0;
|
||||||
if (PrivilegeCount != 0)
|
if (PrivilegeCount > 0)
|
||||||
{
|
{
|
||||||
k = PrivilegeCount;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
i = Token->PrivilegeCount;
|
|
||||||
Current = Token->Privileges;
|
|
||||||
for (i = 0; i < Token->PrivilegeCount; i++)
|
for (i = 0; i < Token->PrivilegeCount; i++)
|
||||||
{
|
{
|
||||||
if (!(Current[i].Attributes & SE_PRIVILEGE_ENABLED) &&
|
for (j = 0; j < PrivilegeCount; j++)
|
||||||
Privileges[i].Luid.LowPart == Current[i].Luid.LowPart &&
|
|
||||||
Privileges[i].Luid.HighPart == Current[i].Luid.HighPart)
|
|
||||||
{
|
{
|
||||||
Privileges[i].Attributes |= SE_PRIVILEGE_USED_FOR_ACCESS;
|
if (Token->Privileges[i].Luid.LowPart == Privileges[j].Luid.LowPart &&
|
||||||
j++;
|
Token->Privileges[i].Luid.HighPart == Privileges[j].Luid.HighPart)
|
||||||
break;
|
{
|
||||||
|
DPRINT ("Found privilege\n");
|
||||||
|
DPRINT ("Privilege attributes %lx\n",
|
||||||
|
Token->Privileges[i].Attributes);
|
||||||
|
|
||||||
|
if (Token->Privileges[i].Attributes & SE_PRIVILEGE_ENABLED)
|
||||||
|
{
|
||||||
|
Privileges[j].Attributes |= SE_PRIVILEGE_USED_FOR_ACCESS;
|
||||||
|
k++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
k--;
|
|
||||||
}
|
}
|
||||||
while (k > 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((PrivilegeControl & PRIVILEGE_SET_ALL_NECESSARY) &&
|
if ((PrivilegeControl & PRIVILEGE_SET_ALL_NECESSARY) &&
|
||||||
PrivilegeCount == j)
|
PrivilegeCount == k)
|
||||||
{
|
{
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (j > 0 &&
|
if (k > 0 &&
|
||||||
!(PrivilegeControl & PRIVILEGE_SET_ALL_NECESSARY))
|
!(PrivilegeControl & PRIVILEGE_SET_ALL_NECESSARY))
|
||||||
{
|
{
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -173,34 +174,38 @@ SeCaptureLuidAndAttributesArray (PLUID_AND_ATTRIBUTES Src,
|
||||||
{
|
{
|
||||||
*Dest = 0;
|
*Dest = 0;
|
||||||
*Length = 0;
|
*Length = 0;
|
||||||
return(STATUS_SUCCESS);
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
if (PreviousMode == 0 && d == 0)
|
|
||||||
|
if (PreviousMode == KernelMode && d == 0)
|
||||||
{
|
{
|
||||||
*Dest = Src;
|
*Dest = Src;
|
||||||
return(STATUS_SUCCESS);
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
SrcLength = ((PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES)) + 3) & 0xfc;
|
SrcLength = ((PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES)) + 3) & 0xfc;
|
||||||
*Length = SrcLength;
|
*Length = SrcLength;
|
||||||
if (AllocatedMem == NULL)
|
if (AllocatedMem == NULL)
|
||||||
{
|
{
|
||||||
NewMem = ExAllocatePool(PoolType, SrcLength);
|
NewMem = ExAllocatePool (PoolType,
|
||||||
|
SrcLength);
|
||||||
*Dest = (PLUID_AND_ATTRIBUTES)NewMem;
|
*Dest = (PLUID_AND_ATTRIBUTES)NewMem;
|
||||||
if (NewMem == NULL)
|
if (NewMem == NULL)
|
||||||
{
|
{
|
||||||
return(STATUS_UNSUCCESSFUL);
|
return STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (SrcLength > AllocatedLength)
|
if (SrcLength > AllocatedLength)
|
||||||
{
|
{
|
||||||
return(STATUS_UNSUCCESSFUL);
|
return STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
*Dest = AllocatedMem;
|
*Dest = AllocatedMem;
|
||||||
}
|
}
|
||||||
memmove (*Dest, Src, SrcLength);
|
memmove (*Dest, Src, SrcLength);
|
||||||
return(STATUS_SUCCESS);
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -218,13 +223,12 @@ NtPrivilegeCheck(IN HANDLE ClientToken,
|
||||||
IN PPRIVILEGE_SET RequiredPrivileges,
|
IN PPRIVILEGE_SET RequiredPrivileges,
|
||||||
IN PBOOLEAN Result)
|
IN PBOOLEAN Result)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
PLUID_AND_ATTRIBUTES Privilege;
|
||||||
PACCESS_TOKEN Token;
|
PACCESS_TOKEN Token;
|
||||||
ULONG PrivilegeCount;
|
ULONG PrivilegeCount;
|
||||||
BOOLEAN TResult;
|
|
||||||
ULONG PrivilegeControl;
|
ULONG PrivilegeControl;
|
||||||
PLUID_AND_ATTRIBUTES Privilege;
|
|
||||||
ULONG Length;
|
ULONG Length;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
Status = ObReferenceObjectByHandle (ClientToken,
|
Status = ObReferenceObjectByHandle (ClientToken,
|
||||||
0,
|
0,
|
||||||
|
@ -234,14 +238,16 @@ NtPrivilegeCheck(IN HANDLE ClientToken,
|
||||||
NULL);
|
NULL);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
return(Status);
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Token->TokenType == TokenImpersonation &&
|
if (Token->TokenType == TokenImpersonation &&
|
||||||
Token->ImpersonationLevel < SecurityAnonymous)
|
Token->ImpersonationLevel < SecurityAnonymous)
|
||||||
{
|
{
|
||||||
ObDereferenceObject (Token);
|
ObDereferenceObject (Token);
|
||||||
return(STATUS_UNSUCCESSFUL);
|
return STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
PrivilegeCount = RequiredPrivileges->PrivilegeCount;
|
PrivilegeCount = RequiredPrivileges->PrivilegeCount;
|
||||||
PrivilegeControl = RequiredPrivileges->Control;
|
PrivilegeControl = RequiredPrivileges->Control;
|
||||||
Privilege = 0;
|
Privilege = 0;
|
||||||
|
@ -257,17 +263,24 @@ NtPrivilegeCheck(IN HANDLE ClientToken,
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
ObDereferenceObject (Token);
|
ObDereferenceObject (Token);
|
||||||
return(STATUS_UNSUCCESSFUL);
|
return STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
TResult = SepPrivilegeCheck(Token,
|
|
||||||
|
*Result = SepPrivilegeCheck (Token,
|
||||||
Privilege,
|
Privilege,
|
||||||
PrivilegeCount,
|
PrivilegeCount,
|
||||||
PrivilegeControl,
|
PrivilegeControl,
|
||||||
UserMode);
|
UserMode);
|
||||||
memmove(RequiredPrivileges->Privilege, Privilege, Length);
|
|
||||||
*Result = TResult;
|
memmove (RequiredPrivileges->Privilege,
|
||||||
SeReleaseLuidAndAttributesArray(Privilege, UserMode, 1);
|
Privilege,
|
||||||
return(STATUS_SUCCESS);
|
Length);
|
||||||
|
|
||||||
|
SeReleaseLuidAndAttributesArray (Privilege,
|
||||||
|
UserMode,
|
||||||
|
1);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -287,15 +300,15 @@ SePrivilegeCheck(PPRIVILEGE_SET Privileges,
|
||||||
Token = SubjectContext->ClientToken;
|
Token = SubjectContext->ClientToken;
|
||||||
if (SubjectContext->ImpersonationLevel < 2)
|
if (SubjectContext->ImpersonationLevel < 2)
|
||||||
{
|
{
|
||||||
return(FALSE);
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return(SepPrivilegeCheck(Token,
|
return SepPrivilegeCheck (Token,
|
||||||
Privileges->Privilege,
|
Privileges->Privilege,
|
||||||
Privileges->PrivilegeCount,
|
Privileges->PrivilegeCount,
|
||||||
Privileges->Control,
|
Privileges->Control,
|
||||||
PreviousMode));
|
PreviousMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -304,30 +317,32 @@ SeSinglePrivilegeCheck(IN LUID PrivilegeValue,
|
||||||
IN KPROCESSOR_MODE PreviousMode)
|
IN KPROCESSOR_MODE PreviousMode)
|
||||||
{
|
{
|
||||||
SECURITY_SUBJECT_CONTEXT SubjectContext;
|
SECURITY_SUBJECT_CONTEXT SubjectContext;
|
||||||
BOOLEAN r;
|
|
||||||
PRIVILEGE_SET Priv;
|
PRIVILEGE_SET Priv;
|
||||||
|
BOOLEAN Result;
|
||||||
|
|
||||||
SeCaptureSubjectContext (&SubjectContext);
|
SeCaptureSubjectContext (&SubjectContext);
|
||||||
|
|
||||||
Priv.PrivilegeCount = 1;
|
Priv.PrivilegeCount = 1;
|
||||||
Priv.Control = 1;
|
Priv.Control = PRIVILEGE_SET_ALL_NECESSARY;
|
||||||
Priv.Privilege[0].Luid = PrivilegeValue;
|
Priv.Privilege[0].Luid = PrivilegeValue;
|
||||||
Priv.Privilege[0].Attributes = 0;
|
Priv.Privilege[0].Attributes = SE_PRIVILEGE_ENABLED;
|
||||||
|
|
||||||
r = SePrivilegeCheck(&Priv,
|
Result = SePrivilegeCheck (&Priv,
|
||||||
&SubjectContext,
|
&SubjectContext,
|
||||||
PreviousMode);
|
PreviousMode);
|
||||||
|
|
||||||
if (PreviousMode != KernelMode)
|
if (PreviousMode != KernelMode)
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
SePrivilegeServiceAuditAlarm(0,
|
SePrivilegedServiceAuditAlarm (0,
|
||||||
&SubjectContext,
|
&SubjectContext,
|
||||||
&PrivilegeValue);
|
&PrivilegeValue);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
SeReleaseSubjectContext (&SubjectContext);
|
SeReleaseSubjectContext (&SubjectContext);
|
||||||
return(r);
|
|
||||||
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: token.c,v 1.24 2003/06/07 12:23:14 chorns Exp $
|
/* $Id: token.c,v 1.25 2003/06/17 10:42:37 ekohl Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -883,14 +883,17 @@ NtAdjustPrivilegesToken(IN HANDLE TokenHandle,
|
||||||
IN BOOLEAN DisableAllPrivileges,
|
IN BOOLEAN DisableAllPrivileges,
|
||||||
IN PTOKEN_PRIVILEGES NewState,
|
IN PTOKEN_PRIVILEGES NewState,
|
||||||
IN ULONG BufferLength,
|
IN ULONG BufferLength,
|
||||||
OUT PTOKEN_PRIVILEGES PreviousState,
|
OUT PTOKEN_PRIVILEGES PreviousState OPTIONAL,
|
||||||
OUT PULONG ReturnLength)
|
OUT PULONG ReturnLength OPTIONAL)
|
||||||
{
|
{
|
||||||
PLUID_AND_ATTRIBUTES Privileges;
|
// PLUID_AND_ATTRIBUTES Privileges;
|
||||||
KPROCESSOR_MODE PreviousMode;
|
KPROCESSOR_MODE PreviousMode;
|
||||||
ULONG PrivilegeCount;
|
// ULONG PrivilegeCount;
|
||||||
PACCESS_TOKEN Token;
|
PACCESS_TOKEN Token;
|
||||||
ULONG Length;
|
// ULONG Length;
|
||||||
|
ULONG i;
|
||||||
|
ULONG j;
|
||||||
|
ULONG k;
|
||||||
#if 0
|
#if 0
|
||||||
ULONG a;
|
ULONG a;
|
||||||
ULONG b;
|
ULONG b;
|
||||||
|
@ -898,19 +901,19 @@ NtAdjustPrivilegesToken(IN HANDLE TokenHandle,
|
||||||
#endif
|
#endif
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
DPRINT1("NtAdjustPrivilegesToken() called\n");
|
DPRINT ("NtAdjustPrivilegesToken() called\n");
|
||||||
|
|
||||||
PrivilegeCount = NewState->PrivilegeCount;
|
// PrivilegeCount = NewState->PrivilegeCount;
|
||||||
PreviousMode = KeGetPreviousMode ();
|
PreviousMode = KeGetPreviousMode ();
|
||||||
SeCaptureLuidAndAttributesArray(NewState->Privileges,
|
// SeCaptureLuidAndAttributesArray(NewState->Privileges,
|
||||||
PrivilegeCount,
|
// PrivilegeCount,
|
||||||
PreviousMode,
|
// PreviousMode,
|
||||||
NULL,
|
// NULL,
|
||||||
0,
|
// 0,
|
||||||
NonPagedPool,
|
// NonPagedPool,
|
||||||
1,
|
// 1,
|
||||||
&Privileges,
|
// &Privileges,
|
||||||
&Length);
|
// &Length);
|
||||||
|
|
||||||
Status = ObReferenceObjectByHandle (TokenHandle,
|
Status = ObReferenceObjectByHandle (TokenHandle,
|
||||||
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
|
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
|
||||||
|
@ -921,10 +924,10 @@ NtAdjustPrivilegesToken(IN HANDLE TokenHandle,
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1 ("Failed to reference token (Status %lx)\n", Status);
|
DPRINT1 ("Failed to reference token (Status %lx)\n", Status);
|
||||||
SeReleaseLuidAndAttributesArray(Privileges,
|
// SeReleaseLuidAndAttributesArray(Privileges,
|
||||||
PreviousMode,
|
// PreviousMode,
|
||||||
0);
|
// 0);
|
||||||
return(Status);
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -940,13 +943,85 @@ NtAdjustPrivilegesToken(IN HANDLE TokenHandle,
|
||||||
&c);
|
&c);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
k = 0;
|
||||||
|
if (DisableAllPrivileges == TRUE)
|
||||||
|
{
|
||||||
|
for (i = 0; i < Token->PrivilegeCount; i++)
|
||||||
|
{
|
||||||
|
if (Token->Privileges[i].Attributes != 0)
|
||||||
|
{
|
||||||
|
DPRINT ("Attributes differ\n");
|
||||||
|
|
||||||
|
/* Save current privilege */
|
||||||
|
if (PreviousState != NULL && k < PreviousState->PrivilegeCount)
|
||||||
|
{
|
||||||
|
PreviousState->Privileges[k].Luid = Token->Privileges[i].Luid;
|
||||||
|
PreviousState->Privileges[k].Attributes = Token->Privileges[i].Attributes;
|
||||||
|
k++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update current privlege */
|
||||||
|
Token->Privileges[i].Attributes &= ~SE_PRIVILEGE_ENABLED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i = 0; i < Token->PrivilegeCount; i++)
|
||||||
|
{
|
||||||
|
for (j = 0; j < NewState->PrivilegeCount; j++)
|
||||||
|
{
|
||||||
|
if (Token->Privileges[i].Luid.LowPart == NewState->Privileges[j].Luid.LowPart &&
|
||||||
|
Token->Privileges[i].Luid.HighPart == NewState->Privileges[j].Luid.HighPart)
|
||||||
|
{
|
||||||
|
DPRINT ("Found privilege\n");
|
||||||
|
|
||||||
|
if ((Token->Privileges[i].Attributes & SE_PRIVILEGE_ENABLED) !=
|
||||||
|
(NewState->Privileges[j].Attributes & SE_PRIVILEGE_ENABLED))
|
||||||
|
{
|
||||||
|
DPRINT ("Attributes differ\n");
|
||||||
|
DPRINT ("Current attributes %lx desired attributes %lx\n",
|
||||||
|
Token->Privileges[i].Attributes,
|
||||||
|
NewState->Privileges[j].Attributes);
|
||||||
|
|
||||||
|
/* Save current privilege */
|
||||||
|
if (PreviousState != NULL && k < PreviousState->PrivilegeCount)
|
||||||
|
{
|
||||||
|
PreviousState->Privileges[k].Luid = Token->Privileges[i].Luid;
|
||||||
|
PreviousState->Privileges[k].Attributes = Token->Privileges[i].Attributes;
|
||||||
|
k++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update current privlege */
|
||||||
|
Token->Privileges[i].Attributes &= ~SE_PRIVILEGE_ENABLED;
|
||||||
|
Token->Privileges[i].Attributes |=
|
||||||
|
(NewState->Privileges[j].Attributes & SE_PRIVILEGE_ENABLED);
|
||||||
|
DPRINT ("New attributes %lx\n",
|
||||||
|
Token->Privileges[i].Attributes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ReturnLength != NULL)
|
||||||
|
{
|
||||||
|
*ReturnLength = sizeof(TOKEN_PRIVILEGES) +
|
||||||
|
(sizeof(LUID_AND_ATTRIBUTES) * (k - 1));
|
||||||
|
}
|
||||||
|
|
||||||
ObDereferenceObject (Token);
|
ObDereferenceObject (Token);
|
||||||
|
|
||||||
SeReleaseLuidAndAttributesArray(Privileges,
|
// SeReleaseLuidAndAttributesArray(Privileges,
|
||||||
PreviousMode,
|
// PreviousMode,
|
||||||
0);
|
// 0);
|
||||||
|
|
||||||
DPRINT1("NtAdjustPrivilegesToken() done\n");
|
DPRINT ("NtAdjustPrivilegesToken() done\n");
|
||||||
|
|
||||||
|
if (k < NewState->PrivilegeCount)
|
||||||
|
{
|
||||||
|
return STATUS_NOT_ALL_ASSIGNED;
|
||||||
|
}
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue