Fixed NtAdjustPrivilegeToken() and SeSinglePrivilegeCheck().

svn path=/trunk/; revision=4916
This commit is contained in:
Eric Kohl 2003-06-17 10:42:37 +00:00
parent a2be00bf0e
commit b905ce98aa
2 changed files with 265 additions and 175 deletions

View file

@ -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
* PROJECT: ReactOS kernel
@ -105,47 +105,48 @@ SepPrivilegeCheck (PACCESS_TOKEN Token,
ULONG PrivilegeControl,
KPROCESSOR_MODE PreviousMode)
{
PLUID_AND_ATTRIBUTES Current;
ULONG i;
ULONG j;
ULONG k;
DPRINT ("SepPrivilegeCheck() called\n");
if (PreviousMode == KernelMode)
{
return TRUE;
}
j = 0;
if (PrivilegeCount != 0)
k = 0;
if (PrivilegeCount > 0)
{
k = PrivilegeCount;
do
for (i = 0; i < Token->PrivilegeCount; i++)
{
i = Token->PrivilegeCount;
Current = Token->Privileges;
for (i = 0; i < Token->PrivilegeCount; i++)
for (j = 0; j < PrivilegeCount; j++)
{
if (!(Current[i].Attributes & SE_PRIVILEGE_ENABLED) &&
Privileges[i].Luid.LowPart == Current[i].Luid.LowPart &&
Privileges[i].Luid.HighPart == Current[i].Luid.HighPart)
if (Token->Privileges[i].Luid.LowPart == Privileges[j].Luid.LowPart &&
Token->Privileges[i].Luid.HighPart == Privileges[j].Luid.HighPart)
{
Privileges[i].Attributes |= SE_PRIVILEGE_USED_FOR_ACCESS;
j++;
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) &&
PrivilegeCount == j)
PrivilegeCount == k)
{
return TRUE;
}
if (j > 0 &&
if (k > 0 &&
!(PrivilegeControl & PRIVILEGE_SET_ALL_NECESSARY))
{
return TRUE;
@ -166,86 +167,91 @@ SeCaptureLuidAndAttributesArray (PLUID_AND_ATTRIBUTES Src,
PLUID_AND_ATTRIBUTES* Dest,
PULONG Length)
{
PLUID_AND_ATTRIBUTES* NewMem;
ULONG SrcLength;
PLUID_AND_ATTRIBUTES* NewMem;
ULONG SrcLength;
if (PrivilegeCount == 0)
{
*Dest = 0;
*Length = 0;
return(STATUS_SUCCESS);
}
if (PreviousMode == 0 && d == 0)
{
*Dest = Src;
return(STATUS_SUCCESS);
}
SrcLength = ((PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES)) + 3) & 0xfc;
*Length = SrcLength;
if (AllocatedMem == NULL)
{
NewMem = ExAllocatePool(PoolType, SrcLength);
*Dest = (PLUID_AND_ATTRIBUTES)NewMem;
if (NewMem == NULL)
{
return(STATUS_UNSUCCESSFUL);
}
}
else
{
if (SrcLength > AllocatedLength)
{
return(STATUS_UNSUCCESSFUL);
}
*Dest = AllocatedMem;
}
memmove(*Dest, Src, SrcLength);
return(STATUS_SUCCESS);
if (PrivilegeCount == 0)
{
*Dest = 0;
*Length = 0;
return STATUS_SUCCESS;
}
if (PreviousMode == KernelMode && d == 0)
{
*Dest = Src;
return STATUS_SUCCESS;
}
SrcLength = ((PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES)) + 3) & 0xfc;
*Length = SrcLength;
if (AllocatedMem == NULL)
{
NewMem = ExAllocatePool (PoolType,
SrcLength);
*Dest = (PLUID_AND_ATTRIBUTES)NewMem;
if (NewMem == NULL)
{
return STATUS_UNSUCCESSFUL;
}
}
else
{
if (SrcLength > AllocatedLength)
{
return STATUS_UNSUCCESSFUL;
}
*Dest = AllocatedMem;
}
memmove (*Dest, Src, SrcLength);
return STATUS_SUCCESS;
}
VOID
SeReleaseLuidAndAttributesArray(PLUID_AND_ATTRIBUTES Privilege,
KPROCESSOR_MODE PreviousMode,
ULONG a)
SeReleaseLuidAndAttributesArray (PLUID_AND_ATTRIBUTES Privilege,
KPROCESSOR_MODE PreviousMode,
ULONG a)
{
ExFreePool(Privilege);
ExFreePool (Privilege);
}
NTSTATUS STDCALL
NtPrivilegeCheck(IN HANDLE ClientToken,
IN PPRIVILEGE_SET RequiredPrivileges,
IN PBOOLEAN Result)
NtPrivilegeCheck (IN HANDLE ClientToken,
IN PPRIVILEGE_SET RequiredPrivileges,
IN PBOOLEAN Result)
{
NTSTATUS Status;
PACCESS_TOKEN Token;
ULONG PrivilegeCount;
BOOLEAN TResult;
ULONG PrivilegeControl;
PLUID_AND_ATTRIBUTES Privilege;
ULONG Length;
PLUID_AND_ATTRIBUTES Privilege;
PACCESS_TOKEN Token;
ULONG PrivilegeCount;
ULONG PrivilegeControl;
ULONG Length;
NTSTATUS Status;
Status = ObReferenceObjectByHandle(ClientToken,
Status = ObReferenceObjectByHandle (ClientToken,
0,
SepTokenObjectType,
UserMode,
(PVOID*)&Token,
NULL);
if (!NT_SUCCESS(Status))
{
return(Status);
}
if (Token->TokenType == TokenImpersonation &&
Token->ImpersonationLevel < SecurityAnonymous)
{
ObDereferenceObject(Token);
return(STATUS_UNSUCCESSFUL);
}
PrivilegeCount = RequiredPrivileges->PrivilegeCount;
PrivilegeControl = RequiredPrivileges->Control;
Privilege = 0;
Status = SeCaptureLuidAndAttributesArray(RequiredPrivileges->Privilege,
if (!NT_SUCCESS(Status))
{
return Status;
}
if (Token->TokenType == TokenImpersonation &&
Token->ImpersonationLevel < SecurityAnonymous)
{
ObDereferenceObject (Token);
return STATUS_UNSUCCESSFUL;
}
PrivilegeCount = RequiredPrivileges->PrivilegeCount;
PrivilegeControl = RequiredPrivileges->Control;
Privilege = 0;
Status = SeCaptureLuidAndAttributesArray (RequiredPrivileges->Privilege,
PrivilegeCount,
1,
0,
@ -254,80 +260,89 @@ NtPrivilegeCheck(IN HANDLE ClientToken,
1,
&Privilege,
&Length);
if (!NT_SUCCESS(Status))
{
ObDereferenceObject(Token);
return(STATUS_UNSUCCESSFUL);
}
TResult = SepPrivilegeCheck(Token,
if (!NT_SUCCESS(Status))
{
ObDereferenceObject (Token);
return STATUS_UNSUCCESSFUL;
}
*Result = SepPrivilegeCheck (Token,
Privilege,
PrivilegeCount,
PrivilegeControl,
UserMode);
memmove(RequiredPrivileges->Privilege, Privilege, Length);
*Result = TResult;
SeReleaseLuidAndAttributesArray(Privilege, UserMode, 1);
return(STATUS_SUCCESS);
memmove (RequiredPrivileges->Privilege,
Privilege,
Length);
SeReleaseLuidAndAttributesArray (Privilege,
UserMode,
1);
return STATUS_SUCCESS;
}
BOOLEAN STDCALL
SePrivilegeCheck(PPRIVILEGE_SET Privileges,
PSECURITY_SUBJECT_CONTEXT SubjectContext,
KPROCESSOR_MODE PreviousMode)
SePrivilegeCheck (PPRIVILEGE_SET Privileges,
PSECURITY_SUBJECT_CONTEXT SubjectContext,
KPROCESSOR_MODE PreviousMode)
{
PACCESS_TOKEN Token = NULL;
PACCESS_TOKEN Token = NULL;
if (SubjectContext->ClientToken == NULL)
{
Token = SubjectContext->PrimaryToken;
}
else
{
Token = SubjectContext->ClientToken;
if (SubjectContext->ImpersonationLevel < 2)
{
return(FALSE);
}
}
if (SubjectContext->ClientToken == NULL)
{
Token = SubjectContext->PrimaryToken;
}
else
{
Token = SubjectContext->ClientToken;
if (SubjectContext->ImpersonationLevel < 2)
{
return FALSE;
}
}
return(SepPrivilegeCheck(Token,
return SepPrivilegeCheck (Token,
Privileges->Privilege,
Privileges->PrivilegeCount,
Privileges->Control,
PreviousMode));
PreviousMode);
}
BOOLEAN STDCALL
SeSinglePrivilegeCheck(IN LUID PrivilegeValue,
IN KPROCESSOR_MODE PreviousMode)
SeSinglePrivilegeCheck (IN LUID PrivilegeValue,
IN KPROCESSOR_MODE PreviousMode)
{
SECURITY_SUBJECT_CONTEXT SubjectContext;
BOOLEAN r;
PRIVILEGE_SET Priv;
SECURITY_SUBJECT_CONTEXT SubjectContext;
PRIVILEGE_SET Priv;
BOOLEAN Result;
SeCaptureSubjectContext(&SubjectContext);
SeCaptureSubjectContext (&SubjectContext);
Priv.PrivilegeCount = 1;
Priv.Control = 1;
Priv.Privilege[0].Luid = PrivilegeValue;
Priv.Privilege[0].Attributes = 0;
Priv.PrivilegeCount = 1;
Priv.Control = PRIVILEGE_SET_ALL_NECESSARY;
Priv.Privilege[0].Luid = PrivilegeValue;
Priv.Privilege[0].Attributes = SE_PRIVILEGE_ENABLED;
r = SePrivilegeCheck(&Priv,
&SubjectContext,
PreviousMode);
Result = SePrivilegeCheck (&Priv,
&SubjectContext,
PreviousMode);
if (PreviousMode != KernelMode)
{
if (PreviousMode != KernelMode)
{
#if 0
SePrivilegeServiceAuditAlarm(0,
SePrivilegedServiceAuditAlarm (0,
&SubjectContext,
&PrivilegeValue);
#endif
}
SeReleaseSubjectContext(&SubjectContext);
return(r);
}
SeReleaseSubjectContext (&SubjectContext);
return Result;
}
/* EOF */

View file

@ -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
* PROJECT: ReactOS kernel
@ -879,18 +879,21 @@ SepAdjustPrivileges(PACCESS_TOKEN Token,
NTSTATUS STDCALL
NtAdjustPrivilegesToken(IN HANDLE TokenHandle,
IN BOOLEAN DisableAllPrivileges,
IN PTOKEN_PRIVILEGES NewState,
IN ULONG BufferLength,
OUT PTOKEN_PRIVILEGES PreviousState,
OUT PULONG ReturnLength)
NtAdjustPrivilegesToken (IN HANDLE TokenHandle,
IN BOOLEAN DisableAllPrivileges,
IN PTOKEN_PRIVILEGES NewState,
IN ULONG BufferLength,
OUT PTOKEN_PRIVILEGES PreviousState OPTIONAL,
OUT PULONG ReturnLength OPTIONAL)
{
PLUID_AND_ATTRIBUTES Privileges;
// PLUID_AND_ATTRIBUTES Privileges;
KPROCESSOR_MODE PreviousMode;
ULONG PrivilegeCount;
// ULONG PrivilegeCount;
PACCESS_TOKEN Token;
ULONG Length;
// ULONG Length;
ULONG i;
ULONG j;
ULONG k;
#if 0
ULONG a;
ULONG b;
@ -898,33 +901,33 @@ NtAdjustPrivilegesToken(IN HANDLE TokenHandle,
#endif
NTSTATUS Status;
DPRINT1("NtAdjustPrivilegesToken() called\n");
DPRINT ("NtAdjustPrivilegesToken() called\n");
PrivilegeCount = NewState->PrivilegeCount;
PreviousMode = KeGetPreviousMode();
SeCaptureLuidAndAttributesArray(NewState->Privileges,
PrivilegeCount,
PreviousMode,
NULL,
0,
NonPagedPool,
1,
&Privileges,
&Length);
// PrivilegeCount = NewState->PrivilegeCount;
PreviousMode = KeGetPreviousMode ();
// SeCaptureLuidAndAttributesArray(NewState->Privileges,
// PrivilegeCount,
// PreviousMode,
// NULL,
// 0,
// NonPagedPool,
// 1,
// &Privileges,
// &Length);
Status = ObReferenceObjectByHandle(TokenHandle,
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
SepTokenObjectType,
PreviousMode,
(PVOID*)&Token,
NULL);
Status = ObReferenceObjectByHandle (TokenHandle,
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
SepTokenObjectType,
PreviousMode,
(PVOID*)&Token,
NULL);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to reference token (Status %lx)\n", Status);
SeReleaseLuidAndAttributesArray(Privileges,
PreviousMode,
0);
return(Status);
DPRINT1 ("Failed to reference token (Status %lx)\n", Status);
// SeReleaseLuidAndAttributesArray(Privileges,
// PreviousMode,
// 0);
return Status;
}
@ -940,13 +943,85 @@ NtAdjustPrivilegesToken(IN HANDLE TokenHandle,
&c);
#endif
ObDereferenceObject(Token);
k = 0;
if (DisableAllPrivileges == TRUE)
{
for (i = 0; i < Token->PrivilegeCount; i++)
{
if (Token->Privileges[i].Attributes != 0)
{
DPRINT ("Attributes differ\n");
SeReleaseLuidAndAttributesArray(Privileges,
PreviousMode,
0);
/* 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++;
}
DPRINT1("NtAdjustPrivilegesToken() done\n");
/* 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);
// SeReleaseLuidAndAttributesArray(Privileges,
// PreviousMode,
// 0);
DPRINT ("NtAdjustPrivilegesToken() done\n");
if (k < NewState->PrivilegeCount)
{
return STATUS_NOT_ALL_ASSIGNED;
}
return STATUS_SUCCESS;
}