-/* $Id$
- *
+/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/se/token.c
* PROGRAMMERS: David Welch <welch@cwcom.net>
*/
-/* INCLUDES *****************************************************************/
+/* INCLUDES *******************************************************************/
#include <ntoskrnl.h>
-
#define NDEBUG
-#include <internal/debug.h>
+#include <debug.h>
#if defined (ALLOC_PRAGMA)
#pragma alloc_text(INIT, SepInitializeTokenImplementation)
#endif
-
-/* GLOBALS *******************************************************************/
+/* GLOBALS ********************************************************************/
POBJECT_TYPE SepTokenObjectType = NULL;
ERESOURCE SepTokenLock;
+TOKEN_SOURCE SeSystemTokenSource = {"*SYSTEM*", {0}};
+LUID SeSystemAuthenticationId = SYSTEM_LUID;
+
static GENERIC_MAPPING SepTokenMapping = {TOKEN_READ,
- TOKEN_WRITE,
- TOKEN_EXECUTE,
- TOKEN_ALL_ACCESS};
+ TOKEN_WRITE,
+ TOKEN_EXECUTE,
+TOKEN_ALL_ACCESS};
static const INFORMATION_CLASS_INFO SeTokenInformationClass[] = {
-
+
/* Class 0 not used, blame M$! */
ICI_SQ_SAME( 0, 0, 0),
-
+
/* TokenUser */
ICI_SQ_SAME( sizeof(TOKEN_USER), sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE | ICIF_SET | ICIF_SET_SIZE_VARIABLE ),
/* TokenGroups */
/* FUNCTIONS *****************************************************************/
+static NTSTATUS
+SepCompareTokens(IN PTOKEN FirstToken,
+ IN PTOKEN SecondToken,
+ OUT PBOOLEAN Equal)
+{
+ BOOLEAN Restricted, IsEqual = FALSE;
+
+ ASSERT(FirstToken != SecondToken);
+
+ /* FIXME: Check if every SID that is present in either token is also present in the other one */
+
+ Restricted = SeTokenIsRestricted(FirstToken);
+ if (Restricted == SeTokenIsRestricted(SecondToken))
+ {
+ if (Restricted)
+ {
+ /* FIXME: Check if every SID that is restricted in either token is also restricted in the other one */
+ }
+
+ /* FIXME: Check if every privilege that is present in either token is also present in the other one */
+ }
+
+ *Equal = IsEqual;
+ return STATUS_SUCCESS;
+}
+
VOID
NTAPI
SepFreeProxyData(PVOID ProxyData)
{
- UNIMPLEMENTED;
+ UNIMPLEMENTED;
}
NTSTATUS
NTAPI
SepCopyProxyData(PVOID* Dest, PVOID Src)
{
- UNIMPLEMENTED;
- return(STATUS_NOT_IMPLEMENTED);
+ UNIMPLEMENTED;
+ return(STATUS_NOT_IMPLEMENTED);
}
NTSTATUS
{
PTOKEN OldToken;
PTOKEN NewToken = (PTOKEN)NewTokenP;
-
+
PAGED_CODE();
-
+
if (NewToken->TokenType != TokenPrimary) return(STATUS_BAD_TOKEN_TYPE);
if (NewToken->TokenInUse) return(STATUS_TOKEN_ALREADY_IN_USE);
-
+
/* Mark new token in use */
NewToken->TokenInUse = 1;
-
+
/* Reference the New Token */
ObReferenceObject(NewToken);
-
+
/* Replace the old with the new */
OldToken = ObFastReplaceObject(&Process->Token, NewToken);
-
+
/* Mark the Old Token as free */
OldToken->TokenInUse = 0;
-
+
*OldTokenP = (PACCESS_TOKEN)OldToken;
return STATUS_SUCCESS;
}
SeDeassignPrimaryToken(PEPROCESS Process)
{
PTOKEN OldToken;
-
+
/* Remove the Token */
OldToken = ObFastReplaceObject(&Process->Token, NULL);
-
+
/* Mark the Old Token as free */
OldToken->TokenInUse = 0;
}
RtlLengthSidAndAttributes(ULONG Count,
PSID_AND_ATTRIBUTES Src)
{
- ULONG i;
- ULONG uLength;
-
- PAGED_CODE();
-
- uLength = Count * sizeof(SID_AND_ATTRIBUTES);
- for (i = 0; i < Count; i++)
- uLength += RtlLengthSid(Src[i].Sid);
-
- return(uLength);
+ ULONG i;
+ ULONG uLength;
+
+ PAGED_CODE();
+
+ uLength = Count * sizeof(SID_AND_ATTRIBUTES);
+ for (i = 0; i < Count; i++)
+ uLength += RtlLengthSid(Src[i].Sid);
+
+ return(uLength);
}
PSID PrimaryGroup,
PSID DefaultOwner)
{
- ULONG i;
-
- Token->PrimaryGroup = 0;
-
- if (DefaultOwner)
+ ULONG i;
+
+ Token->PrimaryGroup = 0;
+
+ if (DefaultOwner)
{
- Token->DefaultOwnerIndex = Token->UserAndGroupCount;
+ Token->DefaultOwnerIndex = Token->UserAndGroupCount;
}
-
- /* Validate and set the primary group and user pointers */
- for (i = 0; i < Token->UserAndGroupCount; i++)
+
+ /* Validate and set the primary group and user pointers */
+ for (i = 0; i < Token->UserAndGroupCount; i++)
{
- if (DefaultOwner &&
- RtlEqualSid(Token->UserAndGroups[i].Sid, DefaultOwner))
+ if (DefaultOwner &&
+ RtlEqualSid(Token->UserAndGroups[i].Sid, DefaultOwner))
{
- Token->DefaultOwnerIndex = i;
+ Token->DefaultOwnerIndex = i;
}
-
- if (RtlEqualSid(Token->UserAndGroups[i].Sid, PrimaryGroup))
+
+ if (RtlEqualSid(Token->UserAndGroups[i].Sid, PrimaryGroup))
{
- Token->PrimaryGroup = Token->UserAndGroups[i].Sid;
+ Token->PrimaryGroup = Token->UserAndGroups[i].Sid;
}
}
-
- if (Token->DefaultOwnerIndex == Token->UserAndGroupCount)
+
+ if (Token->DefaultOwnerIndex == Token->UserAndGroupCount)
{
- return(STATUS_INVALID_OWNER);
+ return(STATUS_INVALID_OWNER);
}
-
- if (Token->PrimaryGroup == 0)
+
+ if (Token->PrimaryGroup == 0)
{
- return(STATUS_INVALID_PRIMARY_GROUP);
+ return(STATUS_INVALID_PRIMARY_GROUP);
}
-
- return(STATUS_SUCCESS);
+
+ return(STATUS_SUCCESS);
}
NTSTATUS
-STDCALL
+NTAPI
SepDuplicateToken(PTOKEN Token,
POBJECT_ATTRIBUTES ObjectAttributes,
BOOLEAN EffectiveOnly,
KPROCESSOR_MODE PreviousMode,
PTOKEN* NewAccessToken)
{
- ULONG uLength;
- ULONG i;
- PVOID EndMem;
- PTOKEN AccessToken;
- NTSTATUS Status;
-
- PAGED_CODE();
-
- Status = ObCreateObject(PreviousMode,
- SepTokenObjectType,
- ObjectAttributes,
- PreviousMode,
- NULL,
- sizeof(TOKEN),
- 0,
- 0,
- (PVOID*)&AccessToken);
- if (!NT_SUCCESS(Status))
+ ULONG uLength;
+ ULONG i;
+ PVOID EndMem;
+ PTOKEN AccessToken;
+ NTSTATUS Status;
+
+ PAGED_CODE();
+
+ Status = ObCreateObject(PreviousMode,
+ SepTokenObjectType,
+ ObjectAttributes,
+ PreviousMode,
+ NULL,
+ sizeof(TOKEN),
+ 0,
+ 0,
+ (PVOID*)&AccessToken);
+ if (!NT_SUCCESS(Status))
{
- DPRINT1("ObCreateObject() failed (Status %lx)\n");
- return(Status);
+ DPRINT1("ObCreateObject() failed (Status %lx)\n", Status);
+ return(Status);
}
- Status = ZwAllocateLocallyUniqueId(&AccessToken->TokenId);
- if (!NT_SUCCESS(Status))
+ /* Zero out the buffer */
+ RtlZeroMemory(AccessToken, sizeof(TOKEN));
+
+ Status = ZwAllocateLocallyUniqueId(&AccessToken->TokenId);
+ if (!NT_SUCCESS(Status))
{
- ObDereferenceObject(AccessToken);
- return(Status);
+ ObDereferenceObject(AccessToken);
+ return(Status);
}
-
- Status = ZwAllocateLocallyUniqueId(&AccessToken->ModifiedId);
- if (!NT_SUCCESS(Status))
+
+ Status = ZwAllocateLocallyUniqueId(&AccessToken->ModifiedId);
+ if (!NT_SUCCESS(Status))
{
- ObDereferenceObject(AccessToken);
- return(Status);
+ ObDereferenceObject(AccessToken);
+ return(Status);
}
-
- AccessToken->TokenLock = &SepTokenLock;
-
- AccessToken->TokenInUse = 0;
- AccessToken->TokenType = TokenType;
- AccessToken->ImpersonationLevel = Level;
- RtlCopyLuid(&AccessToken->AuthenticationId, &Token->AuthenticationId);
-
- AccessToken->TokenSource.SourceIdentifier.LowPart = Token->TokenSource.SourceIdentifier.LowPart;
- AccessToken->TokenSource.SourceIdentifier.HighPart = Token->TokenSource.SourceIdentifier.HighPart;
- memcpy(AccessToken->TokenSource.SourceName,
- Token->TokenSource.SourceName,
- sizeof(Token->TokenSource.SourceName));
- AccessToken->ExpirationTime.QuadPart = Token->ExpirationTime.QuadPart;
- AccessToken->UserAndGroupCount = Token->UserAndGroupCount;
- AccessToken->DefaultOwnerIndex = Token->DefaultOwnerIndex;
-
- uLength = sizeof(SID_AND_ATTRIBUTES) * AccessToken->UserAndGroupCount;
- for (i = 0; i < Token->UserAndGroupCount; i++)
- uLength += RtlLengthSid(Token->UserAndGroups[i].Sid);
-
- AccessToken->UserAndGroups =
+
+ AccessToken->TokenLock = &SepTokenLock;
+
+ AccessToken->TokenType = TokenType;
+ AccessToken->ImpersonationLevel = Level;
+ RtlCopyLuid(&AccessToken->AuthenticationId, &Token->AuthenticationId);
+
+ AccessToken->TokenSource.SourceIdentifier.LowPart = Token->TokenSource.SourceIdentifier.LowPart;
+ AccessToken->TokenSource.SourceIdentifier.HighPart = Token->TokenSource.SourceIdentifier.HighPart;
+ memcpy(AccessToken->TokenSource.SourceName,
+ Token->TokenSource.SourceName,
+ sizeof(Token->TokenSource.SourceName));
+ AccessToken->ExpirationTime.QuadPart = Token->ExpirationTime.QuadPart;
+ AccessToken->UserAndGroupCount = Token->UserAndGroupCount;
+ AccessToken->DefaultOwnerIndex = Token->DefaultOwnerIndex;
+
+ uLength = sizeof(SID_AND_ATTRIBUTES) * AccessToken->UserAndGroupCount;
+ for (i = 0; i < Token->UserAndGroupCount; i++)
+ uLength += RtlLengthSid(Token->UserAndGroups[i].Sid);
+
+ AccessToken->UserAndGroups =
(PSID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool,
uLength,
- TAG('T', 'O', 'K', 'u'));
-
- EndMem = &AccessToken->UserAndGroups[AccessToken->UserAndGroupCount];
-
- Status = RtlCopySidAndAttributesArray(AccessToken->UserAndGroupCount,
- Token->UserAndGroups,
- uLength,
- AccessToken->UserAndGroups,
- EndMem,
- &EndMem,
- &uLength);
- if (NT_SUCCESS(Status))
+ 'uKOT');
+
+ EndMem = &AccessToken->UserAndGroups[AccessToken->UserAndGroupCount];
+
+ Status = RtlCopySidAndAttributesArray(AccessToken->UserAndGroupCount,
+ Token->UserAndGroups,
+ uLength,
+ AccessToken->UserAndGroups,
+ EndMem,
+ &EndMem,
+ &uLength);
+ if (NT_SUCCESS(Status))
{
- Status = SepFindPrimaryGroupAndDefaultOwner(
- AccessToken,
- Token->PrimaryGroup,
- 0);
+ Status = SepFindPrimaryGroupAndDefaultOwner(
+ AccessToken,
+ Token->PrimaryGroup,
+ 0);
}
-
- if (NT_SUCCESS(Status))
+
+ if (NT_SUCCESS(Status))
{
- AccessToken->PrivilegeCount = Token->PrivilegeCount;
-
- uLength = AccessToken->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES);
- AccessToken->Privileges =
+ AccessToken->PrivilegeCount = Token->PrivilegeCount;
+
+ uLength = AccessToken->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES);
+ AccessToken->Privileges =
(PLUID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool,
uLength,
- TAG('T', 'O', 'K', 'p'));
-
- for (i = 0; i < AccessToken->PrivilegeCount; i++)
+ 'pKOT');
+
+ for (i = 0; i < AccessToken->PrivilegeCount; i++)
{
- RtlCopyLuid(&AccessToken->Privileges[i].Luid,
- &Token->Privileges[i].Luid);
- AccessToken->Privileges[i].Attributes =
+ RtlCopyLuid(&AccessToken->Privileges[i].Luid,
+ &Token->Privileges[i].Luid);
+ AccessToken->Privileges[i].Attributes =
Token->Privileges[i].Attributes;
}
-
- if ( Token->DefaultDacl )
+
+ if ( Token->DefaultDacl )
{
- AccessToken->DefaultDacl =
+ AccessToken->DefaultDacl =
(PACL) ExAllocatePoolWithTag(PagedPool,
Token->DefaultDacl->AclSize,
- TAG('T', 'O', 'K', 'd'));
- memcpy(AccessToken->DefaultDacl,
- Token->DefaultDacl,
- Token->DefaultDacl->AclSize);
- }
- else
- {
- AccessToken->DefaultDacl = 0;
+ 'kDOT');
+ memcpy(AccessToken->DefaultDacl,
+ Token->DefaultDacl,
+ Token->DefaultDacl->AclSize);
}
}
-
- if ( NT_SUCCESS(Status) )
+
+ if ( NT_SUCCESS(Status) )
{
- *NewAccessToken = AccessToken;
- return(STATUS_SUCCESS);
+ *NewAccessToken = AccessToken;
+ return(STATUS_SUCCESS);
}
-
- return(Status);
+
+ return(Status);
}
NTSTATUS
PTOKEN NewToken;
OBJECT_ATTRIBUTES ObjectAttributes;
NTSTATUS Status;
-
+
/* Initialize the attributes and duplicate it */
InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL);
Status = SepDuplicateToken(ParentToken,
/* Set the session ID */
NewToken->SessionId = SessionId;
NewToken->TokenInUse = InUse;
-
+
/* Return the token */
*Token = NewToken;
}
}
-
+
/* Return status */
return Status;
}
{
PTOKEN ProcessToken;
LUID ProcessLuid, CallerLuid;
-
+
/* Assume failure */
*IsChild = FALSE;
-
+
/* Reference the process token */
ProcessToken = PsReferencePrimaryToken(PsGetCurrentProcess());
-
+
/* Get the ID */
ProcessLuid = ProcessToken->TokenId;
-
+
/* Dereference the token */
ObFastDereferenceObject(&PsGetCurrentProcess()->Token, ProcessToken);
-
+
/* Get our LUID */
CallerLuid = Token->TokenId;
-
+
/* Compare the LUIDs */
if (RtlEqualLuid(&CallerLuid, &ProcessLuid)) *IsChild = TRUE;
-
+
/* Return success */
return STATUS_SUCCESS;
}
-/*
- * @unimplemented
- */
-NTSTATUS
-STDCALL
-SeAppendPrivileges(
- PACCESS_STATE AccessState,
- PPRIVILEGE_SET Privileges
- )
-{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
-}
-
-NTSTATUS
-STDCALL
-SeCopyClientToken(PACCESS_TOKEN Token,
- SECURITY_IMPERSONATION_LEVEL Level,
- KPROCESSOR_MODE PreviousMode,
- PACCESS_TOKEN* NewToken)
-{
- NTSTATUS Status;
- OBJECT_ATTRIBUTES ObjectAttributes;
-
- PAGED_CODE();
-
- InitializeObjectAttributes(&ObjectAttributes,
- NULL,
- 0,
- NULL,
- NULL);
- Status = SepDuplicateToken(Token,
- &ObjectAttributes,
- FALSE,
- TokenImpersonation,
- Level,
- PreviousMode,
- (PTOKEN*)NewToken);
-
- return(Status);
-}
-
-
-/*
- * @implemented
- */
NTSTATUS
NTAPI
-SeCreateClientSecurity(IN PETHREAD Thread,
- IN PSECURITY_QUALITY_OF_SERVICE Qos,
- IN BOOLEAN RemoteClient,
- OUT PSECURITY_CLIENT_CONTEXT ClientContext)
+SeCopyClientToken(IN PACCESS_TOKEN Token,
+ IN SECURITY_IMPERSONATION_LEVEL Level,
+ IN KPROCESSOR_MODE PreviousMode,
+ OUT PACCESS_TOKEN* NewToken)
{
- TOKEN_TYPE TokenType;
- BOOLEAN ThreadEffectiveOnly;
- SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
- PACCESS_TOKEN Token;
NTSTATUS Status;
- PACCESS_TOKEN NewToken;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+
PAGED_CODE();
-
- Token = PsReferenceEffectiveToken(Thread,
- &TokenType,
- &ThreadEffectiveOnly,
- &ImpersonationLevel);
- if (TokenType != TokenImpersonation)
- {
- ClientContext->DirectAccessEffectiveOnly = Qos->EffectiveOnly;
- }
- else
- {
- if (Qos->ImpersonationLevel > ImpersonationLevel)
- {
- if (Token) ObDereferenceObject(Token);
- return STATUS_BAD_IMPERSONATION_LEVEL;
- }
-
- if ((ImpersonationLevel == SecurityAnonymous) ||
- (ImpersonationLevel == SecurityIdentification) ||
- ((RemoteClient) && (ImpersonationLevel != SecurityDelegation)))
- {
- if (Token) ObDereferenceObject(Token);
- return STATUS_BAD_IMPERSONATION_LEVEL;
- }
-
- ClientContext->DirectAccessEffectiveOnly = ((ThreadEffectiveOnly) ||
- (Qos->EffectiveOnly)) ?
- TRUE : FALSE;
- }
-
- if (Qos->ContextTrackingMode == SECURITY_STATIC_TRACKING)
- {
- ClientContext->DirectlyAccessClientToken = FALSE;
- Status = SeCopyClientToken(Token, ImpersonationLevel, 0, &NewToken);
- if (!NT_SUCCESS(Status)) return Status;
- }
- else
- {
- ClientContext->DirectlyAccessClientToken = TRUE;
- if (RemoteClient != FALSE)
- {
-#if 0
- SeGetTokenControlInformation(Token,
- &ClientContext->ClientTokenControl);
-#endif
- }
-
- NewToken = Token;
- }
-
- ClientContext->SecurityQos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
- ClientContext->SecurityQos.ImpersonationLevel = Qos->ImpersonationLevel;
- ClientContext->SecurityQos.ContextTrackingMode = Qos->ContextTrackingMode;
- ClientContext->SecurityQos.EffectiveOnly = Qos->EffectiveOnly;
- ClientContext->ServerIsRemote = RemoteClient;
- ClientContext->ClientToken = NewToken;
- return STATUS_SUCCESS;
-}
-
-/*
- * @unimplemented
- */
-NTSTATUS
-STDCALL
-SeCreateClientSecurityFromSubjectContext(
- IN PSECURITY_SUBJECT_CONTEXT SubjectContext,
- IN PSECURITY_QUALITY_OF_SERVICE ClientSecurityQos,
- IN BOOLEAN ServerIsRemote,
- OUT PSECURITY_CLIENT_CONTEXT ClientContext
- )
-{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
-}
-
-/*
- * @unimplemented
- */
-NTSTATUS
-STDCALL
-SeFilterToken(
- IN PACCESS_TOKEN ExistingToken,
- IN ULONG Flags,
- IN PTOKEN_GROUPS SidsToDisable OPTIONAL,
- IN PTOKEN_PRIVILEGES PrivilegesToDelete OPTIONAL,
- IN PTOKEN_GROUPS RestrictedSids OPTIONAL,
- OUT PACCESS_TOKEN * FilteredToken
- )
-{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
-}
-
-/*
- * @unimplemented
- */
-VOID
-STDCALL
-SeFreePrivileges(
- IN PPRIVILEGE_SET Privileges
- )
-{
- UNIMPLEMENTED;
-}
-
-
-/*
- * @unimplemented
- */
-NTSTATUS
-STDCALL
-SeImpersonateClientEx(
- IN PSECURITY_CLIENT_CONTEXT ClientContext,
- IN PETHREAD ServerThread OPTIONAL
- )
-{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
-}
-
-/*
- * @implemented
- */
-VOID STDCALL
-SeImpersonateClient(IN PSECURITY_CLIENT_CONTEXT ClientContext,
- IN PETHREAD ServerThread OPTIONAL)
-{
- UCHAR b;
-
- PAGED_CODE();
-
- if (ClientContext->DirectlyAccessClientToken == FALSE)
- {
- b = ClientContext->SecurityQos.EffectiveOnly;
- }
- else
- {
- b = ClientContext->DirectAccessEffectiveOnly;
- }
- if (ServerThread == NULL)
- {
- ServerThread = PsGetCurrentThread();
- }
- PsImpersonateClient(ServerThread,
- ClientContext->ClientToken,
- 1,
- b,
- ClientContext->SecurityQos.ImpersonationLevel);
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ NULL,
+ 0,
+ NULL,
+ NULL);
+ Status = SepDuplicateToken(Token,
+ &ObjectAttributes,
+ FALSE,
+ TokenImpersonation,
+ Level,
+ PreviousMode,
+ (PTOKEN*)NewToken);
+
+ return(Status);
}
-
-VOID STDCALL
+VOID NTAPI
SepDeleteToken(PVOID ObjectBody)
{
- PTOKEN AccessToken = (PTOKEN)ObjectBody;
-
- if (AccessToken->UserAndGroups)
- ExFreePool(AccessToken->UserAndGroups);
-
- if (AccessToken->Privileges)
- ExFreePool(AccessToken->Privileges);
-
- if (AccessToken->DefaultDacl)
- ExFreePool(AccessToken->DefaultDacl);
+ PTOKEN AccessToken = (PTOKEN)ObjectBody;
+
+ if (AccessToken->UserAndGroups)
+ ExFreePool(AccessToken->UserAndGroups);
+
+ if (AccessToken->Privileges)
+ ExFreePool(AccessToken->Privileges);
+
+ if (AccessToken->DefaultDacl)
+ ExFreePool(AccessToken->DefaultDacl);
}
ExInitializeResource(&SepTokenLock);
DPRINT("Creating Token Object Type\n");
-
+
/* Initialize the Token type */
RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
RtlInitUnicodeString(&Name, L"Token");
ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &SepTokenObjectType);
}
-
-/*
- * @implemented
- */
-NTSTATUS STDCALL
-NtQueryInformationToken(IN HANDLE TokenHandle,
- IN TOKEN_INFORMATION_CLASS TokenInformationClass,
- OUT PVOID TokenInformation,
- IN ULONG TokenInformationLength,
- OUT PULONG ReturnLength)
+VOID
+NTAPI
+SeAssignPrimaryToken(IN PEPROCESS Process,
+ IN PTOKEN Token)
{
- union
- {
- PVOID Ptr;
- ULONG Ulong;
- } Unused;
- PTOKEN Token;
- ULONG RequiredLength;
- KPROCESSOR_MODE PreviousMode;
- NTSTATUS Status = STATUS_SUCCESS;
-
- PAGED_CODE();
-
- PreviousMode = ExGetPreviousMode();
-
- /* Check buffers and class validity */
- Status = DefaultQueryInfoBufferCheck(TokenInformationClass,
- SeTokenInformationClass,
- sizeof(SeTokenInformationClass) / sizeof(SeTokenInformationClass[0]),
- TokenInformation,
- TokenInformationLength,
- ReturnLength,
- PreviousMode);
-
- if(!NT_SUCCESS(Status))
- {
- DPRINT("NtQueryInformationToken() failed, Status: 0x%x\n", Status);
- return Status;
- }
-
- Status = ObReferenceObjectByHandle(TokenHandle,
- (TokenInformationClass == TokenSource) ? TOKEN_QUERY_SOURCE : TOKEN_QUERY,
- SepTokenObjectType,
- PreviousMode,
- (PVOID*)&Token,
- NULL);
- if (NT_SUCCESS(Status))
- {
- switch (TokenInformationClass)
- {
- case TokenUser:
- {
- PTOKEN_USER tu = (PTOKEN_USER)TokenInformation;
-
- DPRINT("NtQueryInformationToken(TokenUser)\n");
- RequiredLength = sizeof(TOKEN_USER) +
- RtlLengthSid(Token->UserAndGroups[0].Sid);
-
- _SEH_TRY
- {
- if(TokenInformationLength >= RequiredLength)
- {
- Status = RtlCopySidAndAttributesArray(1,
- &Token->UserAndGroups[0],
- RequiredLength - sizeof(TOKEN_USER),
- &tu->User,
- (PSID)(tu + 1),
- &Unused.Ptr,
- &Unused.Ulong);
- }
- else
- {
- Status = STATUS_BUFFER_TOO_SMALL;
- }
-
- if(ReturnLength != NULL)
- {
- *ReturnLength = RequiredLength;
- }
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- break;
- }
-
- case TokenGroups:
- {
- PTOKEN_GROUPS tg = (PTOKEN_GROUPS)TokenInformation;
-
- DPRINT("NtQueryInformationToken(TokenGroups)\n");
- RequiredLength = sizeof(tg->GroupCount) +
- RtlLengthSidAndAttributes(Token->UserAndGroupCount - 1, &Token->UserAndGroups[1]);
-
- _SEH_TRY
- {
- if(TokenInformationLength >= RequiredLength)
- {
- ULONG SidLen = RequiredLength - sizeof(tg->GroupCount) -
- ((Token->UserAndGroupCount - 1) * sizeof(SID_AND_ATTRIBUTES));
- PSID_AND_ATTRIBUTES Sid = (PSID_AND_ATTRIBUTES)((ULONG_PTR)TokenInformation + sizeof(tg->GroupCount) +
- ((Token->UserAndGroupCount - 1) * sizeof(SID_AND_ATTRIBUTES)));
-
- tg->GroupCount = Token->UserAndGroupCount - 1;
- Status = RtlCopySidAndAttributesArray(Token->UserAndGroupCount - 1,
- &Token->UserAndGroups[1],
- SidLen,
- &tg->Groups[0],
- (PSID)Sid,
- &Unused.Ptr,
- &Unused.Ulong);
- }
- else
- {
- Status = STATUS_BUFFER_TOO_SMALL;
- }
-
- if(ReturnLength != NULL)
- {
- *ReturnLength = RequiredLength;
- }
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- break;
- }
-
- case TokenPrivileges:
- {
- PTOKEN_PRIVILEGES tp = (PTOKEN_PRIVILEGES)TokenInformation;
-
- DPRINT("NtQueryInformationToken(TokenPrivileges)\n");
- RequiredLength = sizeof(tp->PrivilegeCount) +
- (Token->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES));
-
- _SEH_TRY
- {
- if(TokenInformationLength >= RequiredLength)
- {
- tp->PrivilegeCount = Token->PrivilegeCount;
- RtlCopyLuidAndAttributesArray(Token->PrivilegeCount,
- Token->Privileges,
- &tp->Privileges[0]);
- }
- else
- {
- Status = STATUS_BUFFER_TOO_SMALL;
- }
-
- if(ReturnLength != NULL)
- {
- *ReturnLength = RequiredLength;
- }
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- break;
- }
-
- case TokenOwner:
- {
- ULONG SidLen;
- PTOKEN_OWNER to = (PTOKEN_OWNER)TokenInformation;
+ PAGED_CODE();
+
+ /* Sanity checks */
+ ASSERT(Token->TokenType == TokenPrimary);
+ ASSERT(!Token->TokenInUse);
+
+ /* Clean any previous token */
+ if (Process->Token.Object) SeDeassignPrimaryToken(Process);
+
+ /* Set the new token */
+ ObReferenceObject(Token);
+ Token->TokenInUse = TRUE;
+ ObInitializeFastReference(&Process->Token, Token);
+}
- DPRINT("NtQueryInformationToken(TokenOwner)\n");
- SidLen = RtlLengthSid(Token->UserAndGroups[Token->DefaultOwnerIndex].Sid);
- RequiredLength = sizeof(TOKEN_OWNER) + SidLen;
- _SEH_TRY
- {
- if(TokenInformationLength >= RequiredLength)
- {
- to->Owner = (PSID)(to + 1);
- Status = RtlCopySid(SidLen,
- to->Owner,
- Token->UserAndGroups[Token->DefaultOwnerIndex].Sid);
- }
- else
- {
- Status = STATUS_BUFFER_TOO_SMALL;
- }
-
- if(ReturnLength != NULL)
- {
- *ReturnLength = RequiredLength;
- }
- }
- _SEH_HANDLE
+NTSTATUS
+NTAPI
+SepCreateToken(OUT PHANDLE TokenHandle,
+ IN KPROCESSOR_MODE PreviousMode,
+ IN ACCESS_MASK DesiredAccess,
+ IN POBJECT_ATTRIBUTES ObjectAttributes,
+ IN TOKEN_TYPE TokenType,
+ IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
+ IN PLUID AuthenticationId,
+ IN PLARGE_INTEGER ExpirationTime,
+ IN PSID_AND_ATTRIBUTES User,
+ IN ULONG GroupCount,
+ IN PSID_AND_ATTRIBUTES Groups,
+ IN ULONG GroupLength,
+ IN ULONG PrivilegeCount,
+ IN PLUID_AND_ATTRIBUTES Privileges,
+ IN PSID Owner,
+ IN PSID PrimaryGroup,
+ IN PACL DefaultDacl,
+ IN PTOKEN_SOURCE TokenSource,
+ IN BOOLEAN SystemToken)
+{
+ PTOKEN AccessToken;
+ LUID TokenId;
+ LUID ModifiedId;
+ PVOID EndMem;
+ ULONG uLength;
+ ULONG i;
+ NTSTATUS Status;
+ ULONG TokenFlags = 0;
+
+ /* Loop all groups */
+ for (i = 0; i < GroupCount; i++)
+ {
+ /* Check for mandatory groups */
+ if (Groups[i].Attributes & SE_GROUP_MANDATORY)
{
- Status = _SEH_GetExceptionCode();
+ /* Force them to be enabled */
+ Groups[i].Attributes |= (SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT);
}
- _SEH_END;
-
- break;
- }
-
- case TokenPrimaryGroup:
- {
- ULONG SidLen;
- PTOKEN_PRIMARY_GROUP tpg = (PTOKEN_PRIMARY_GROUP)TokenInformation;
-
- DPRINT("NtQueryInformationToken(TokenPrimaryGroup)\n");
- SidLen = RtlLengthSid(Token->PrimaryGroup);
- RequiredLength = sizeof(TOKEN_PRIMARY_GROUP) + SidLen;
-
- _SEH_TRY
+
+ /* Check of the group is an admin group */
+ if (RtlEqualSid(SeAliasAdminsSid, Groups[i].Sid))
{
- if(TokenInformationLength >= RequiredLength)
- {
- tpg->PrimaryGroup = (PSID)(tpg + 1);
- Status = RtlCopySid(SidLen,
- tpg->PrimaryGroup,
- Token->PrimaryGroup);
- }
- else
- {
- Status = STATUS_BUFFER_TOO_SMALL;
- }
-
- if(ReturnLength != NULL)
- {
- *ReturnLength = RequiredLength;
- }
+ /* Remember this so we can optimize queries later */
+ TokenFlags |= TOKEN_HAS_ADMIN_GROUP;
}
- _SEH_HANDLE
+ }
+
+ /* Loop all privileges */
+ for (i = 0; i < PrivilegeCount; i++)
+ {
+ /* For optimization, check for change notify and impersonate rights */
+ if (((RtlEqualLuid(&Privileges[i].Luid, &SeChangeNotifyPrivilege)) &&
+ (Privileges[i].Attributes & SE_PRIVILEGE_ENABLED)))
{
- Status = _SEH_GetExceptionCode();
+ /* Remember token has traverse */
+ TokenFlags |= TOKEN_HAS_TRAVERSE_PRIVILEGE;
}
- _SEH_END;
-
- break;
- }
-
- case TokenDefaultDacl:
- {
- PTOKEN_DEFAULT_DACL tdd = (PTOKEN_DEFAULT_DACL)TokenInformation;
-
- DPRINT("NtQueryInformationToken(TokenDefaultDacl)\n");
- RequiredLength = sizeof(TOKEN_DEFAULT_DACL);
+ }
- if(Token->DefaultDacl != NULL)
- {
- RequiredLength += Token->DefaultDacl->AclSize;
- }
+ Status = ZwAllocateLocallyUniqueId(&TokenId);
+ if (!NT_SUCCESS(Status))
+ return(Status);
+
+ Status = ZwAllocateLocallyUniqueId(&ModifiedId);
+ if (!NT_SUCCESS(Status))
+ return(Status);
+
+ Status = ObCreateObject(PreviousMode,
+ SepTokenObjectType,
+ ObjectAttributes,
+ PreviousMode,
+ NULL,
+ sizeof(TOKEN),
+ 0,
+ 0,
+ (PVOID*)&AccessToken);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("ObCreateObject() failed (Status %lx)\n");
+ return(Status);
+ }
- _SEH_TRY
+ /* Zero out the buffer */
+ RtlZeroMemory(AccessToken, sizeof(TOKEN));
+
+ AccessToken->TokenLock = &SepTokenLock;
+
+ RtlCopyLuid(&AccessToken->TokenSource.SourceIdentifier,
+ &TokenSource->SourceIdentifier);
+ memcpy(AccessToken->TokenSource.SourceName,
+ TokenSource->SourceName,
+ sizeof(TokenSource->SourceName));
+
+ RtlCopyLuid(&AccessToken->TokenId, &TokenId);
+ RtlCopyLuid(&AccessToken->AuthenticationId, AuthenticationId);
+ AccessToken->ExpirationTime = *ExpirationTime;
+ RtlCopyLuid(&AccessToken->ModifiedId, &ModifiedId);
+
+ AccessToken->UserAndGroupCount = GroupCount + 1;
+ AccessToken->PrivilegeCount = PrivilegeCount;
+
+ AccessToken->TokenFlags = TokenFlags;
+ AccessToken->TokenType = TokenType;
+ AccessToken->ImpersonationLevel = ImpersonationLevel;
+
+ /*
+ * Normally we would just point these members into the variable information
+ * area; however, our ObCreateObject() call can't allocate a variable information
+ * area, so we allocate them seperately and provide a destroy function.
+ */
+
+ uLength = sizeof(SID_AND_ATTRIBUTES) * AccessToken->UserAndGroupCount;
+ uLength += RtlLengthSid(User);
+ for (i = 0; i < GroupCount; i++)
+ uLength += RtlLengthSid(Groups[i].Sid);
+
+ AccessToken->UserAndGroups =
+ (PSID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool,
+ uLength,
+ 'uKOT');
+
+ EndMem = &AccessToken->UserAndGroups[AccessToken->UserAndGroupCount];
+
+ Status = RtlCopySidAndAttributesArray(1,
+ User,
+ uLength,
+ AccessToken->UserAndGroups,
+ EndMem,
+ &EndMem,
+ &uLength);
+ if (NT_SUCCESS(Status))
+ {
+ Status = RtlCopySidAndAttributesArray(GroupCount,
+ Groups,
+ uLength,
+ &AccessToken->UserAndGroups[1],
+ EndMem,
+ &EndMem,
+ &uLength);
+ }
+
+ if (NT_SUCCESS(Status))
+ {
+ Status = SepFindPrimaryGroupAndDefaultOwner(
+ AccessToken,
+ PrimaryGroup,
+ Owner);
+ }
+
+ if (NT_SUCCESS(Status))
+ {
+ uLength = PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES);
+ AccessToken->Privileges =
+ (PLUID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool,
+ uLength,
+ 'pKOT');
+
+ if (PreviousMode != KernelMode)
{
- if(TokenInformationLength >= RequiredLength)
- {
- if(Token->DefaultDacl != NULL)
+ _SEH2_TRY
{
- tdd->DefaultDacl = (PACL)(tdd + 1);
- RtlCopyMemory(tdd->DefaultDacl,
- Token->DefaultDacl,
- Token->DefaultDacl->AclSize);
+ RtlCopyMemory(AccessToken->Privileges,
+ Privileges,
+ PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES));
}
- else
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- tdd->DefaultDacl = NULL;
+ Status = _SEH2_GetExceptionCode();
}
- }
- else
- {
- Status = STATUS_BUFFER_TOO_SMALL;
- }
-
- if(ReturnLength != NULL)
- {
- *ReturnLength = RequiredLength;
- }
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- break;
- }
-
- case TokenSource:
- {
- PTOKEN_SOURCE ts = (PTOKEN_SOURCE)TokenInformation;
-
- DPRINT("NtQueryInformationToken(TokenSource)\n");
- RequiredLength = sizeof(TOKEN_SOURCE);
-
- _SEH_TRY
- {
- if(TokenInformationLength >= RequiredLength)
- {
- *ts = Token->TokenSource;
- }
- else
- {
- Status = STATUS_BUFFER_TOO_SMALL;
- }
-
- if(ReturnLength != NULL)
- {
- *ReturnLength = RequiredLength;
- }
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- break;
- }
-
- case TokenType:
- {
- PTOKEN_TYPE tt = (PTOKEN_TYPE)TokenInformation;
-
- DPRINT("NtQueryInformationToken(TokenType)\n");
- RequiredLength = sizeof(TOKEN_TYPE);
-
- _SEH_TRY
- {
- if(TokenInformationLength >= RequiredLength)
- {
- *tt = Token->TokenType;
- }
- else
- {
- Status = STATUS_BUFFER_TOO_SMALL;
- }
-
- if(ReturnLength != NULL)
- {
- *ReturnLength = RequiredLength;
- }
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- break;
- }
-
- case TokenImpersonationLevel:
- {
- PSECURITY_IMPERSONATION_LEVEL sil = (PSECURITY_IMPERSONATION_LEVEL)TokenInformation;
-
- DPRINT("NtQueryInformationToken(TokenImpersonationLevel)\n");
- RequiredLength = sizeof(SECURITY_IMPERSONATION_LEVEL);
-
- _SEH_TRY
- {
- if(TokenInformationLength >= RequiredLength)
- {
- *sil = Token->ImpersonationLevel;
- }
- else
- {
- Status = STATUS_BUFFER_TOO_SMALL;
- }
-
- if(ReturnLength != NULL)
- {
- *ReturnLength = RequiredLength;
- }
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
+ _SEH2_END;
}
- _SEH_END;
-
- break;
- }
-
- case TokenStatistics:
- {
- PTOKEN_STATISTICS ts = (PTOKEN_STATISTICS)TokenInformation;
-
- DPRINT("NtQueryInformationToken(TokenStatistics)\n");
- RequiredLength = sizeof(TOKEN_STATISTICS);
-
- _SEH_TRY
- {
- if(TokenInformationLength >= RequiredLength)
- {
- ts->TokenId = Token->TokenId;
- ts->AuthenticationId = Token->AuthenticationId;
- ts->ExpirationTime = Token->ExpirationTime;
- ts->TokenType = Token->TokenType;
- ts->ImpersonationLevel = Token->ImpersonationLevel;
- ts->DynamicCharged = Token->DynamicCharged;
- ts->DynamicAvailable = Token->DynamicAvailable;
- ts->GroupCount = Token->UserAndGroupCount - 1;
- ts->PrivilegeCount = Token->PrivilegeCount;
- ts->ModifiedId = Token->ModifiedId;
- }
- else
- {
- Status = STATUS_BUFFER_TOO_SMALL;
- }
-
- if(ReturnLength != NULL)
- {
- *ReturnLength = RequiredLength;
- }
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- break;
- }
-
- case TokenOrigin:
- {
- PTOKEN_ORIGIN to = (PTOKEN_ORIGIN)TokenInformation;
-
- DPRINT("NtQueryInformationToken(TokenOrigin)\n");
- RequiredLength = sizeof(TOKEN_ORIGIN);
-
- _SEH_TRY
- {
- if(TokenInformationLength >= RequiredLength)
- {
- RtlCopyLuid(&to->OriginatingLogonSession,
- &Token->AuthenticationId);
- }
- else
- {
- Status = STATUS_BUFFER_TOO_SMALL;
- }
-
- if(ReturnLength != NULL)
- {
- *ReturnLength = RequiredLength;
- }
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- break;
- }
-
- case TokenGroupsAndPrivileges:
- DPRINT1("NtQueryInformationToken(TokenGroupsAndPrivileges) not implemented\n");
- Status = STATUS_NOT_IMPLEMENTED;
- break;
-
- case TokenRestrictedSids:
- {
- PTOKEN_GROUPS tg = (PTOKEN_GROUPS)TokenInformation;
-
- DPRINT("NtQueryInformationToken(TokenRestrictedSids)\n");
- RequiredLength = sizeof(tg->GroupCount) +
- RtlLengthSidAndAttributes(Token->RestrictedSidCount, Token->RestrictedSids);
-
- _SEH_TRY
- {
- if(TokenInformationLength >= RequiredLength)
- {
- ULONG SidLen = RequiredLength - sizeof(tg->GroupCount) -
- (Token->RestrictedSidCount * sizeof(SID_AND_ATTRIBUTES));
- PSID_AND_ATTRIBUTES Sid = (PSID_AND_ATTRIBUTES)((ULONG_PTR)TokenInformation + sizeof(tg->GroupCount) +
- (Token->RestrictedSidCount * sizeof(SID_AND_ATTRIBUTES)));
-
- tg->GroupCount = Token->RestrictedSidCount;
- Status = RtlCopySidAndAttributesArray(Token->RestrictedSidCount,
- Token->RestrictedSids,
- SidLen,
- &tg->Groups[0],
- (PSID)Sid,
- &Unused.Ptr,
- &Unused.Ulong);
- }
- else
- {
- Status = STATUS_BUFFER_TOO_SMALL;
- }
-
- if(ReturnLength != NULL)
- {
- *ReturnLength = RequiredLength;
- }
- }
- _SEH_HANDLE
+ else
{
- Status = _SEH_GetExceptionCode();
+ RtlCopyMemory(AccessToken->Privileges,
+ Privileges,
+ PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES));
}
- _SEH_END;
-
- break;
- }
-
- case TokenSandBoxInert:
- DPRINT1("NtQueryInformationToken(TokenSandboxInert) not implemented\n");
- Status = STATUS_NOT_IMPLEMENTED;
- break;
-
- case TokenSessionId:
- {
- ULONG SessionId = 0;
-
- DPRINT("NtQueryInformationToken(TokenSessionId)\n");
-
- Status = SeQuerySessionIdToken(Token,
- &SessionId);
-
- if(NT_SUCCESS(Status))
+ }
+
+ if (NT_SUCCESS(Status))
+ {
+ AccessToken->DefaultDacl =
+ (PACL) ExAllocatePoolWithTag(PagedPool,
+ DefaultDacl->AclSize,
+ 'kDOT');
+ memcpy(AccessToken->DefaultDacl,
+ DefaultDacl,
+ DefaultDacl->AclSize);
+ }
+
+ if (!SystemToken)
+ {
+
+ Status = ObInsertObject ((PVOID)AccessToken,
+ NULL,
+ DesiredAccess,
+ 0,
+ NULL,
+ TokenHandle);
+ if (!NT_SUCCESS(Status))
{
- _SEH_TRY
- {
- /* buffer size was already verified, no need to check here again */
- *(PULONG)TokenInformation = SessionId;
-
- if(ReturnLength != NULL)
- {
- *ReturnLength = sizeof(ULONG);
- }
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
+ DPRINT1("ObInsertObject() failed (Status %lx)\n", Status);
}
-
- break;
- }
-
- default:
- DPRINT1("NtQueryInformationToken(%d) invalid information class\n", TokenInformationClass);
- Status = STATUS_INVALID_INFO_CLASS;
- break;
+ }
+ else
+ {
+ /* Return pointer instead of handle */
+ *TokenHandle = (HANDLE)AccessToken;
}
- ObDereferenceObject(Token);
- }
+ return Status;
+}
+
+PTOKEN
+NTAPI
+SepCreateSystemProcessToken(VOID)
+{
+ LUID_AND_ATTRIBUTES Privileges[25];
+ ULONG GroupAttributes, OwnerAttributes;
+ SID_AND_ATTRIBUTES Groups[32];
+ LARGE_INTEGER Expiration;
+ SID_AND_ATTRIBUTES UserSid;
+ ULONG GroupLength;
+ PSID PrimaryGroup;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ PSID Owner;
+ ULONG i;
+ PTOKEN Token;
+ NTSTATUS Status;
+
+ /* Don't ever expire */
+ Expiration.QuadPart = -1;
+
+ /* All groups mandatory and enabled */
+ GroupAttributes = SE_GROUP_ENABLED | SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT;
+ OwnerAttributes = SE_GROUP_ENABLED | SE_GROUP_OWNER | SE_GROUP_ENABLED_BY_DEFAULT;
+
+ /* User is system */
+ UserSid.Sid = SeLocalSystemSid;
+ UserSid.Attributes = 0;
+
+ /* Primary group is local system */
+ PrimaryGroup = SeLocalSystemSid;
+
+ /* Owner is admins */
+ Owner = SeAliasAdminsSid;
+
+ /* Groups are admins, world, and authenticated users */
+ Groups[0].Sid = SeAliasAdminsSid;
+ Groups[0].Attributes = OwnerAttributes;
+ Groups[1].Sid = SeWorldSid;
+ Groups[1].Attributes = GroupAttributes;
+ Groups[2].Sid = SeAuthenticatedUserSid;
+ Groups[2].Attributes = OwnerAttributes;
+ GroupLength = sizeof(SID_AND_ATTRIBUTES) +
+ SeLengthSid(Groups[0].Sid) +
+ SeLengthSid(Groups[1].Sid) +
+ SeLengthSid(Groups[2].Sid);
+ ASSERT(GroupLength <= sizeof(Groups));
+
+ /* Setup the privileges */
+ i = 0;
+ Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED;
+ Privileges[i++].Luid = SeTcbPrivilege;
+
+ Privileges[i].Attributes = 0;
+ Privileges[i++].Luid = SeCreateTokenPrivilege;
+
+ Privileges[i].Attributes = 0;
+ Privileges[i++].Luid = SeTakeOwnershipPrivilege;
+
+ Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED;
+ Privileges[i++].Luid = SeCreatePagefilePrivilege;
+
+ Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED;
+ Privileges[i++].Luid = SeLockMemoryPrivilege;
+
+ Privileges[i].Attributes = 0;
+ Privileges[i++].Luid = SeAssignPrimaryTokenPrivilege;
+
+ Privileges[i].Attributes = 0;
+ Privileges[i++].Luid = SeIncreaseQuotaPrivilege;
+
+ Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED;
+ Privileges[i++].Luid = SeIncreaseBasePriorityPrivilege;
+
+ Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED;
+ Privileges[i++].Luid = SeCreatePermanentPrivilege;
+
+ Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED;
+ Privileges[i++].Luid = SeDebugPrivilege;
+
+ Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED;
+ Privileges[i++].Luid = SeAuditPrivilege;
+
+ Privileges[i].Attributes = 0;
+ Privileges[i++].Luid = SeSecurityPrivilege;
+
+ Privileges[i].Attributes = 0;
+ Privileges[i++].Luid = SeSystemEnvironmentPrivilege;
+
+ Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED;
+ Privileges[i++].Luid = SeChangeNotifyPrivilege;
+
+ Privileges[i].Attributes = 0;
+ Privileges[i++].Luid = SeBackupPrivilege;
+
+ Privileges[i].Attributes = 0;
+ Privileges[i++].Luid = SeRestorePrivilege;
+
+ Privileges[i].Attributes = 0;
+ Privileges[i++].Luid = SeShutdownPrivilege;
+
+ Privileges[i].Attributes = 0;
+ Privileges[i++].Luid = SeLoadDriverPrivilege;
+
+ Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED;
+ Privileges[i++].Luid = SeProfileSingleProcessPrivilege;
+
+ Privileges[i].Attributes = 0;
+ Privileges[i++].Luid = SeSystemtimePrivilege;
+ ASSERT(i == 20);
+
+ /* Setup the object attributes */
+ InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL);
+ ASSERT(SeSystemDefaultDacl != NULL);
+
+ /* Create the token */
+ Status = SepCreateToken((PHANDLE)&Token,
+ KernelMode,
+ 0,
+ &ObjectAttributes,
+ TokenPrimary,
+ 0,
+ &SeSystemAuthenticationId,
+ &Expiration,
+ &UserSid,
+ 3,
+ Groups,
+ GroupLength,
+ 20,
+ Privileges,
+ Owner,
+ PrimaryGroup,
+ SeSystemDefaultDacl,
+ &SeSystemTokenSource,
+ TRUE);
+ ASSERT(Status == STATUS_SUCCESS);
+
+ /* Return the token */
+ return Token;
+}
- return(Status);
+/* PUBLIC FUNCTIONS ***********************************************************/
+
+/*
+ * @unimplemented
+ */
+NTSTATUS
+NTAPI
+SeFilterToken(IN PACCESS_TOKEN ExistingToken,
+ IN ULONG Flags,
+ IN PTOKEN_GROUPS SidsToDisable OPTIONAL,
+ IN PTOKEN_PRIVILEGES PrivilegesToDelete OPTIONAL,
+ IN PTOKEN_GROUPS RestrictedSids OPTIONAL,
+ OUT PACCESS_TOKEN * FilteredToken)
+{
+ UNIMPLEMENTED;
+ return STATUS_NOT_IMPLEMENTED;
}
/*
* @unimplemented
*/
NTSTATUS
-STDCALL
-SeQueryInformationToken(
- IN PACCESS_TOKEN Token,
- IN TOKEN_INFORMATION_CLASS TokenInformationClass,
- OUT PVOID *TokenInformation
- )
+NTAPI
+SeQueryInformationToken(IN PACCESS_TOKEN Token,
+ IN TOKEN_INFORMATION_CLASS TokenInformationClass,
+ OUT PVOID *TokenInformation)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
* @implemented
*/
NTSTATUS
-STDCALL
-SeQuerySessionIdToken(
- IN PACCESS_TOKEN Token,
- IN PULONG pSessionId
- )
+NTAPI
+SeQuerySessionIdToken(IN PACCESS_TOKEN Token,
+ IN PULONG pSessionId)
{
- *pSessionId = ((PTOKEN)Token)->SessionId;
- return STATUS_SUCCESS;
+ *pSessionId = ((PTOKEN)Token)->SessionId;
+ return STATUS_SUCCESS;
}
/*
- * NtSetTokenInformation: Partly implemented.
- * Unimplemented:
- * TokenOrigin, TokenDefaultDacl
+ * @implemented
*/
+NTSTATUS NTAPI
+SeQueryAuthenticationIdToken(IN PACCESS_TOKEN Token,
+ OUT PLUID LogonId)
+{
+ PAGED_CODE();
+
+ *LogonId = ((PTOKEN)Token)->AuthenticationId;
+
+ return STATUS_SUCCESS;
+}
-NTSTATUS STDCALL
-NtSetInformationToken(IN HANDLE TokenHandle,
- IN TOKEN_INFORMATION_CLASS TokenInformationClass,
- OUT PVOID TokenInformation,
- IN ULONG TokenInformationLength)
+
+/*
+ * @implemented
+ */
+SECURITY_IMPERSONATION_LEVEL
+NTAPI
+SeTokenImpersonationLevel(IN PACCESS_TOKEN Token)
{
- PTOKEN Token;
- KPROCESSOR_MODE PreviousMode;
- ULONG NeededAccess = TOKEN_ADJUST_DEFAULT;
- NTSTATUS Status = STATUS_SUCCESS;
-
- PAGED_CODE();
-
- PreviousMode = ExGetPreviousMode();
-
- Status = DefaultSetInfoBufferCheck(TokenInformationClass,
- SeTokenInformationClass,
- sizeof(SeTokenInformationClass) / sizeof(SeTokenInformationClass[0]),
- TokenInformation,
- TokenInformationLength,
- PreviousMode);
-
- if(!NT_SUCCESS(Status))
- {
- /* Invalid buffers */
- DPRINT("NtSetInformationToken() failed, Status: 0x%x\n", Status);
- return Status;
- }
-
- if(TokenInformationClass == TokenSessionId)
- {
- NeededAccess |= TOKEN_ADJUST_SESSIONID;
- }
-
- Status = ObReferenceObjectByHandle(TokenHandle,
- NeededAccess,
- SepTokenObjectType,
- PreviousMode,
- (PVOID*)&Token,
- NULL);
- if (NT_SUCCESS(Status))
- {
- switch (TokenInformationClass)
- {
- case TokenOwner:
- {
- if(TokenInformationLength >= sizeof(TOKEN_OWNER))
- {
- PTOKEN_OWNER to = (PTOKEN_OWNER)TokenInformation;
- PSID InputSid = NULL;
-
- _SEH_TRY
- {
- InputSid = to->Owner;
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- if(NT_SUCCESS(Status))
- {
- PSID CapturedSid;
-
- Status = SepCaptureSid(InputSid,
- PreviousMode,
- PagedPool,
- FALSE,
- &CapturedSid);
- if(NT_SUCCESS(Status))
+ PAGED_CODE();
+
+ return ((PTOKEN)Token)->ImpersonationLevel;
+}
+
+
+/*
+ * @implemented
+ */
+TOKEN_TYPE NTAPI
+SeTokenType(IN PACCESS_TOKEN Token)
+{
+ PAGED_CODE();
+
+ return ((PTOKEN)Token)->TokenType;
+}
+
+
+/*
+ * @implemented
+ */
+BOOLEAN
+NTAPI
+SeTokenIsAdmin(IN PACCESS_TOKEN Token)
+{
+ PAGED_CODE();
+ return (((PTOKEN)Token)->TokenFlags & TOKEN_WRITE_RESTRICTED) != 0;
+}
+
+/*
+ * @implemented
+ */
+BOOLEAN
+NTAPI
+SeTokenIsRestricted(IN PACCESS_TOKEN Token)
+{
+ PAGED_CODE();
+ return (((PTOKEN)Token)->TokenFlags & TOKEN_IS_RESTRICTED) != 0;
+}
+
+/*
+ * @implemented
+ */
+BOOLEAN
+NTAPI
+SeTokenIsWriteRestricted(IN PACCESS_TOKEN Token)
+{
+ PAGED_CODE();
+ return (((PTOKEN)Token)->TokenFlags & TOKEN_HAS_RESTORE_PRIVILEGE) != 0;
+}
+
+/* SYSTEM CALLS ***************************************************************/
+
+/*
+ * @implemented
+ */
+NTSTATUS NTAPI
+NtQueryInformationToken(IN HANDLE TokenHandle,
+ IN TOKEN_INFORMATION_CLASS TokenInformationClass,
+ OUT PVOID TokenInformation,
+ IN ULONG TokenInformationLength,
+ OUT PULONG ReturnLength)
+{
+ union
+ {
+ PVOID Ptr;
+ ULONG Ulong;
+ } Unused;
+ PTOKEN Token;
+ ULONG RequiredLength;
+ KPROCESSOR_MODE PreviousMode;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ PAGED_CODE();
+
+ PreviousMode = ExGetPreviousMode();
+
+ /* Check buffers and class validity */
+ Status = DefaultQueryInfoBufferCheck(TokenInformationClass,
+ SeTokenInformationClass,
+ sizeof(SeTokenInformationClass) / sizeof(SeTokenInformationClass[0]),
+ TokenInformation,
+ TokenInformationLength,
+ ReturnLength,
+ NULL,
+ PreviousMode);
+
+ if(!NT_SUCCESS(Status))
+ {
+ DPRINT("NtQueryInformationToken() failed, Status: 0x%x\n", Status);
+ return Status;
+ }
+
+ Status = ObReferenceObjectByHandle(TokenHandle,
+ (TokenInformationClass == TokenSource) ? TOKEN_QUERY_SOURCE : TOKEN_QUERY,
+ SepTokenObjectType,
+ PreviousMode,
+ (PVOID*)&Token,
+ NULL);
+ if (NT_SUCCESS(Status))
+ {
+ switch (TokenInformationClass)
+ {
+ case TokenUser:
{
- RtlCopySid(RtlLengthSid(CapturedSid),
- Token->UserAndGroups[Token->DefaultOwnerIndex].Sid,
- CapturedSid);
- SepReleaseSid(CapturedSid,
- PreviousMode,
- FALSE);
+ PTOKEN_USER tu = (PTOKEN_USER)TokenInformation;
+
+ DPRINT("NtQueryInformationToken(TokenUser)\n");
+ RequiredLength = sizeof(TOKEN_USER) +
+ RtlLengthSid(Token->UserAndGroups[0].Sid);
+
+ _SEH2_TRY
+ {
+ if(TokenInformationLength >= RequiredLength)
+ {
+ Status = RtlCopySidAndAttributesArray(1,
+ &Token->UserAndGroups[0],
+ RequiredLength - sizeof(TOKEN_USER),
+ &tu->User,
+ (PSID)(tu + 1),
+ &Unused.Ptr,
+ &Unused.Ulong);
+ }
+ else
+ {
+ Status = STATUS_BUFFER_TOO_SMALL;
+ }
+
+ if(ReturnLength != NULL)
+ {
+ *ReturnLength = RequiredLength;
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+
+ break;
}
- }
- }
- else
- {
- Status = STATUS_INFO_LENGTH_MISMATCH;
+
+ case TokenGroups:
+ {
+ PTOKEN_GROUPS tg = (PTOKEN_GROUPS)TokenInformation;
+
+ DPRINT("NtQueryInformationToken(TokenGroups)\n");
+ RequiredLength = sizeof(tg->GroupCount) +
+ RtlLengthSidAndAttributes(Token->UserAndGroupCount - 1, &Token->UserAndGroups[1]);
+
+ _SEH2_TRY
+ {
+ if(TokenInformationLength >= RequiredLength)
+ {
+ ULONG SidLen = RequiredLength - sizeof(tg->GroupCount) -
+ ((Token->UserAndGroupCount - 1) * sizeof(SID_AND_ATTRIBUTES));
+ PSID_AND_ATTRIBUTES Sid = (PSID_AND_ATTRIBUTES)((ULONG_PTR)TokenInformation + sizeof(tg->GroupCount) +
+ ((Token->UserAndGroupCount - 1) * sizeof(SID_AND_ATTRIBUTES)));
+
+ tg->GroupCount = Token->UserAndGroupCount - 1;
+ Status = RtlCopySidAndAttributesArray(Token->UserAndGroupCount - 1,
+ &Token->UserAndGroups[1],
+ SidLen,
+ &tg->Groups[0],
+ (PSID)Sid,
+ &Unused.Ptr,
+ &Unused.Ulong);
+ }
+ else
+ {
+ Status = STATUS_BUFFER_TOO_SMALL;
+ }
+
+ if(ReturnLength != NULL)
+ {
+ *ReturnLength = RequiredLength;
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+
+ break;
+ }
+
+ case TokenPrivileges:
+ {
+ PTOKEN_PRIVILEGES tp = (PTOKEN_PRIVILEGES)TokenInformation;
+
+ DPRINT("NtQueryInformationToken(TokenPrivileges)\n");
+ RequiredLength = sizeof(tp->PrivilegeCount) +
+ (Token->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES));
+
+ _SEH2_TRY
+ {
+ if(TokenInformationLength >= RequiredLength)
+ {
+ tp->PrivilegeCount = Token->PrivilegeCount;
+ RtlCopyLuidAndAttributesArray(Token->PrivilegeCount,
+ Token->Privileges,
+ &tp->Privileges[0]);
+ }
+ else
+ {
+ Status = STATUS_BUFFER_TOO_SMALL;
+ }
+
+ if(ReturnLength != NULL)
+ {
+ *ReturnLength = RequiredLength;
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+
+ break;
+ }
+
+ case TokenOwner:
+ {
+ ULONG SidLen;
+ PTOKEN_OWNER to = (PTOKEN_OWNER)TokenInformation;
+
+ DPRINT("NtQueryInformationToken(TokenOwner)\n");
+ SidLen = RtlLengthSid(Token->UserAndGroups[Token->DefaultOwnerIndex].Sid);
+ RequiredLength = sizeof(TOKEN_OWNER) + SidLen;
+
+ _SEH2_TRY
+ {
+ if(TokenInformationLength >= RequiredLength)
+ {
+ to->Owner = (PSID)(to + 1);
+ Status = RtlCopySid(SidLen,
+ to->Owner,
+ Token->UserAndGroups[Token->DefaultOwnerIndex].Sid);
+ }
+ else
+ {
+ Status = STATUS_BUFFER_TOO_SMALL;
+ }
+
+ if(ReturnLength != NULL)
+ {
+ *ReturnLength = RequiredLength;
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+
+ break;
+ }
+
+ case TokenPrimaryGroup:
+ {
+ ULONG SidLen;
+ PTOKEN_PRIMARY_GROUP tpg = (PTOKEN_PRIMARY_GROUP)TokenInformation;
+
+ DPRINT("NtQueryInformationToken(TokenPrimaryGroup)\n");
+ SidLen = RtlLengthSid(Token->PrimaryGroup);
+ RequiredLength = sizeof(TOKEN_PRIMARY_GROUP) + SidLen;
+
+ _SEH2_TRY
+ {
+ if(TokenInformationLength >= RequiredLength)
+ {
+ tpg->PrimaryGroup = (PSID)(tpg + 1);
+ Status = RtlCopySid(SidLen,
+ tpg->PrimaryGroup,
+ Token->PrimaryGroup);
+ }
+ else
+ {
+ Status = STATUS_BUFFER_TOO_SMALL;
+ }
+
+ if(ReturnLength != NULL)
+ {
+ *ReturnLength = RequiredLength;
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+
+ break;
+ }
+
+ case TokenDefaultDacl:
+ {
+ PTOKEN_DEFAULT_DACL tdd = (PTOKEN_DEFAULT_DACL)TokenInformation;
+
+ DPRINT("NtQueryInformationToken(TokenDefaultDacl)\n");
+ RequiredLength = sizeof(TOKEN_DEFAULT_DACL);
+
+ if(Token->DefaultDacl != NULL)
+ {
+ RequiredLength += Token->DefaultDacl->AclSize;
+ }
+
+ _SEH2_TRY
+ {
+ if(TokenInformationLength >= RequiredLength)
+ {
+ if(Token->DefaultDacl != NULL)
+ {
+ tdd->DefaultDacl = (PACL)(tdd + 1);
+ RtlCopyMemory(tdd->DefaultDacl,
+ Token->DefaultDacl,
+ Token->DefaultDacl->AclSize);
+ }
+ else
+ {
+ tdd->DefaultDacl = NULL;
+ }
+ }
+ else
+ {
+ Status = STATUS_BUFFER_TOO_SMALL;
+ }
+
+ if(ReturnLength != NULL)
+ {
+ *ReturnLength = RequiredLength;
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+
+ break;
+ }
+
+ case TokenSource:
+ {
+ PTOKEN_SOURCE ts = (PTOKEN_SOURCE)TokenInformation;
+
+ DPRINT("NtQueryInformationToken(TokenSource)\n");
+ RequiredLength = sizeof(TOKEN_SOURCE);
+
+ _SEH2_TRY
+ {
+ if(TokenInformationLength >= RequiredLength)
+ {
+ *ts = Token->TokenSource;
+ }
+ else
+ {
+ Status = STATUS_BUFFER_TOO_SMALL;
+ }
+
+ if(ReturnLength != NULL)
+ {
+ *ReturnLength = RequiredLength;
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+
+ break;
+ }
+
+ case TokenType:
+ {
+ PTOKEN_TYPE tt = (PTOKEN_TYPE)TokenInformation;
+
+ DPRINT("NtQueryInformationToken(TokenType)\n");
+ RequiredLength = sizeof(TOKEN_TYPE);
+
+ _SEH2_TRY
+ {
+ if(TokenInformationLength >= RequiredLength)
+ {
+ *tt = Token->TokenType;
+ }
+ else
+ {
+ Status = STATUS_BUFFER_TOO_SMALL;
+ }
+
+ if(ReturnLength != NULL)
+ {
+ *ReturnLength = RequiredLength;
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+
+ break;
+ }
+
+ case TokenImpersonationLevel:
+ {
+ PSECURITY_IMPERSONATION_LEVEL sil = (PSECURITY_IMPERSONATION_LEVEL)TokenInformation;
+
+ DPRINT("NtQueryInformationToken(TokenImpersonationLevel)\n");
+ RequiredLength = sizeof(SECURITY_IMPERSONATION_LEVEL);
+
+ _SEH2_TRY
+ {
+ if(TokenInformationLength >= RequiredLength)
+ {
+ *sil = Token->ImpersonationLevel;
+ }
+ else
+ {
+ Status = STATUS_BUFFER_TOO_SMALL;
+ }
+
+ if(ReturnLength != NULL)
+ {
+ *ReturnLength = RequiredLength;
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+
+ break;
+ }
+
+ case TokenStatistics:
+ {
+ PTOKEN_STATISTICS ts = (PTOKEN_STATISTICS)TokenInformation;
+
+ DPRINT("NtQueryInformationToken(TokenStatistics)\n");
+ RequiredLength = sizeof(TOKEN_STATISTICS);
+
+ _SEH2_TRY
+ {
+ if(TokenInformationLength >= RequiredLength)
+ {
+ ts->TokenId = Token->TokenId;
+ ts->AuthenticationId = Token->AuthenticationId;
+ ts->ExpirationTime = Token->ExpirationTime;
+ ts->TokenType = Token->TokenType;
+ ts->ImpersonationLevel = Token->ImpersonationLevel;
+ ts->DynamicCharged = Token->DynamicCharged;
+ ts->DynamicAvailable = Token->DynamicAvailable;
+ ts->GroupCount = Token->UserAndGroupCount - 1;
+ ts->PrivilegeCount = Token->PrivilegeCount;
+ ts->ModifiedId = Token->ModifiedId;
+ }
+ else
+ {
+ Status = STATUS_BUFFER_TOO_SMALL;
+ }
+
+ if(ReturnLength != NULL)
+ {
+ *ReturnLength = RequiredLength;
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+
+ break;
+ }
+
+ case TokenOrigin:
+ {
+ PTOKEN_ORIGIN to = (PTOKEN_ORIGIN)TokenInformation;
+
+ DPRINT("NtQueryInformationToken(TokenOrigin)\n");
+ RequiredLength = sizeof(TOKEN_ORIGIN);
+
+ _SEH2_TRY
+ {
+ if(TokenInformationLength >= RequiredLength)
+ {
+ RtlCopyLuid(&to->OriginatingLogonSession,
+ &Token->AuthenticationId);
+ }
+ else
+ {
+ Status = STATUS_BUFFER_TOO_SMALL;
+ }
+
+ if(ReturnLength != NULL)
+ {
+ *ReturnLength = RequiredLength;
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+
+ break;
+ }
+
+ case TokenGroupsAndPrivileges:
+ DPRINT1("NtQueryInformationToken(TokenGroupsAndPrivileges) not implemented\n");
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
+
+ case TokenRestrictedSids:
+ {
+ PTOKEN_GROUPS tg = (PTOKEN_GROUPS)TokenInformation;
+
+ DPRINT("NtQueryInformationToken(TokenRestrictedSids)\n");
+ RequiredLength = sizeof(tg->GroupCount) +
+ RtlLengthSidAndAttributes(Token->RestrictedSidCount, Token->RestrictedSids);
+
+ _SEH2_TRY
+ {
+ if(TokenInformationLength >= RequiredLength)
+ {
+ ULONG SidLen = RequiredLength - sizeof(tg->GroupCount) -
+ (Token->RestrictedSidCount * sizeof(SID_AND_ATTRIBUTES));
+ PSID_AND_ATTRIBUTES Sid = (PSID_AND_ATTRIBUTES)((ULONG_PTR)TokenInformation + sizeof(tg->GroupCount) +
+ (Token->RestrictedSidCount * sizeof(SID_AND_ATTRIBUTES)));
+
+ tg->GroupCount = Token->RestrictedSidCount;
+ Status = RtlCopySidAndAttributesArray(Token->RestrictedSidCount,
+ Token->RestrictedSids,
+ SidLen,
+ &tg->Groups[0],
+ (PSID)Sid,
+ &Unused.Ptr,
+ &Unused.Ulong);
+ }
+ else
+ {
+ Status = STATUS_BUFFER_TOO_SMALL;
+ }
+
+ if(ReturnLength != NULL)
+ {
+ *ReturnLength = RequiredLength;
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+
+ break;
+ }
+
+ case TokenSandBoxInert:
+ DPRINT1("NtQueryInformationToken(TokenSandboxInert) not implemented\n");
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
+
+ case TokenSessionId:
+ {
+ ULONG SessionId = 0;
+
+ DPRINT("NtQueryInformationToken(TokenSessionId)\n");
+
+ Status = SeQuerySessionIdToken(Token,
+ &SessionId);
+
+ if(NT_SUCCESS(Status))
+ {
+ _SEH2_TRY
+ {
+ /* buffer size was already verified, no need to check here again */
+ *(PULONG)TokenInformation = SessionId;
+
+ if(ReturnLength != NULL)
+ {
+ *ReturnLength = sizeof(ULONG);
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+ }
+
+ break;
+ }
+
+ default:
+ DPRINT1("NtQueryInformationToken(%d) invalid information class\n", TokenInformationClass);
+ Status = STATUS_INVALID_INFO_CLASS;
+ break;
}
- break;
- }
+
+ ObDereferenceObject(Token);
+ }
+
+ return(Status);
+}
+
+
+/*
+ * NtSetTokenInformation: Partly implemented.
+ * Unimplemented:
+ * TokenOrigin, TokenDefaultDacl
+ */
- case TokenPrimaryGroup:
- {
- if(TokenInformationLength >= sizeof(TOKEN_PRIMARY_GROUP))
+NTSTATUS NTAPI
+NtSetInformationToken(IN HANDLE TokenHandle,
+ IN TOKEN_INFORMATION_CLASS TokenInformationClass,
+ OUT PVOID TokenInformation,
+ IN ULONG TokenInformationLength)
+{
+ PTOKEN Token;
+ KPROCESSOR_MODE PreviousMode;
+ ULONG NeededAccess = TOKEN_ADJUST_DEFAULT;
+ NTSTATUS Status;
+
+ PAGED_CODE();
+
+ PreviousMode = ExGetPreviousMode();
+
+ Status = DefaultSetInfoBufferCheck(TokenInformationClass,
+ SeTokenInformationClass,
+ sizeof(SeTokenInformationClass) / sizeof(SeTokenInformationClass[0]),
+ TokenInformation,
+ TokenInformationLength,
+ PreviousMode);
+
+ if(!NT_SUCCESS(Status))
+ {
+ /* Invalid buffers */
+ DPRINT("NtSetInformationToken() failed, Status: 0x%x\n", Status);
+ return Status;
+ }
+
+ if(TokenInformationClass == TokenSessionId)
+ {
+ NeededAccess |= TOKEN_ADJUST_SESSIONID;
+ }
+
+ Status = ObReferenceObjectByHandle(TokenHandle,
+ NeededAccess,
+ SepTokenObjectType,
+ PreviousMode,
+ (PVOID*)&Token,
+ NULL);
+ if (NT_SUCCESS(Status))
+ {
+ switch (TokenInformationClass)
{
- PTOKEN_PRIMARY_GROUP tpg = (PTOKEN_PRIMARY_GROUP)TokenInformation;
- PSID InputSid = NULL;
-
- _SEH_TRY
- {
- InputSid = tpg->PrimaryGroup;
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- if(NT_SUCCESS(Status))
- {
- PSID CapturedSid;
-
- Status = SepCaptureSid(InputSid,
- PreviousMode,
- PagedPool,
- FALSE,
- &CapturedSid);
- if(NT_SUCCESS(Status))
+ case TokenOwner:
{
- RtlCopySid(RtlLengthSid(CapturedSid),
- Token->PrimaryGroup,
- CapturedSid);
- SepReleaseSid(CapturedSid,
- PreviousMode,
- FALSE);
+ if(TokenInformationLength >= sizeof(TOKEN_OWNER))
+ {
+ PTOKEN_OWNER to = (PTOKEN_OWNER)TokenInformation;
+ PSID InputSid = NULL, CapturedSid;
+
+ _SEH2_TRY
+ {
+ InputSid = to->Owner;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
+ }
+ _SEH2_END;
+
+ Status = SepCaptureSid(InputSid,
+ PreviousMode,
+ PagedPool,
+ FALSE,
+ &CapturedSid);
+ if(NT_SUCCESS(Status))
+ {
+ RtlCopySid(RtlLengthSid(CapturedSid),
+ Token->UserAndGroups[Token->DefaultOwnerIndex].Sid,
+ CapturedSid);
+ SepReleaseSid(CapturedSid,
+ PreviousMode,
+ FALSE);
+ }
+ }
+ else
+ {
+ Status = STATUS_INFO_LENGTH_MISMATCH;
+ }
+ break;
}
- }
- }
- else
- {
- Status = STATUS_INFO_LENGTH_MISMATCH;
- }
- break;
- }
+
+ case TokenPrimaryGroup:
+ {
+ if(TokenInformationLength >= sizeof(TOKEN_PRIMARY_GROUP))
+ {
+ PTOKEN_PRIMARY_GROUP tpg = (PTOKEN_PRIMARY_GROUP)TokenInformation;
+ PSID InputSid = NULL, CapturedSid;
+
+ _SEH2_TRY
+ {
+ InputSid = tpg->PrimaryGroup;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
+ }
+ _SEH2_END;
+
+ Status = SepCaptureSid(InputSid,
+ PreviousMode,
+ PagedPool,
+ FALSE,
+ &CapturedSid);
+ if(NT_SUCCESS(Status))
+ {
+ RtlCopySid(RtlLengthSid(CapturedSid),
+ Token->PrimaryGroup,
+ CapturedSid);
+ SepReleaseSid(CapturedSid,
+ PreviousMode,
+ FALSE);
+ }
+ }
+ else
+ {
+ Status = STATUS_INFO_LENGTH_MISMATCH;
+ }
+ break;
+ }
+
+ case TokenDefaultDacl:
+ {
+ if(TokenInformationLength >= sizeof(TOKEN_DEFAULT_DACL))
+ {
+ PTOKEN_DEFAULT_DACL tdd = (PTOKEN_DEFAULT_DACL)TokenInformation;
+ PACL InputAcl = NULL;
+
+ _SEH2_TRY
+ {
+ InputAcl = tdd->DefaultDacl;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
+ }
+ _SEH2_END;
- case TokenDefaultDacl:
- {
- if(TokenInformationLength >= sizeof(TOKEN_DEFAULT_DACL))
- {
- PTOKEN_DEFAULT_DACL tdd = (PTOKEN_DEFAULT_DACL)TokenInformation;
- PACL InputAcl = NULL;
-
- _SEH_TRY
- {
- InputAcl = tdd->DefaultDacl;
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- if(NT_SUCCESS(Status))
- {
- if(InputAcl != NULL)
+ if(InputAcl != NULL)
+ {
+ PACL CapturedAcl;
+
+ /* capture and copy the dacl */
+ Status = SepCaptureAcl(InputAcl,
+ PreviousMode,
+ PagedPool,
+ TRUE,
+ &CapturedAcl);
+ if(NT_SUCCESS(Status))
+ {
+ /* free the previous dacl if present */
+ if(Token->DefaultDacl != NULL)
+ {
+ ExFreePool(Token->DefaultDacl);
+ }
+
+ /* set the new dacl */
+ Token->DefaultDacl = CapturedAcl;
+ }
+ }
+ else
+ {
+ /* clear and free the default dacl if present */
+ if(Token->DefaultDacl != NULL)
+ {
+ ExFreePool(Token->DefaultDacl);
+ Token->DefaultDacl = NULL;
+ }
+ }
+ }
+ else
+ {
+ Status = STATUS_INFO_LENGTH_MISMATCH;
+ }
+ break;
+ }
+
+ case TokenSessionId:
{
- PACL CapturedAcl;
-
- /* capture and copy the dacl */
- Status = SepCaptureAcl(InputAcl,
- PreviousMode,
- PagedPool,
- TRUE,
- &CapturedAcl);
- if(NT_SUCCESS(Status))
- {
- /* free the previous dacl if present */
- if(Token->DefaultDacl != NULL)
+ ULONG SessionId = 0;
+
+ _SEH2_TRY
+ {
+ /* buffer size was already verified, no need to check here again */
+ SessionId = *(PULONG)TokenInformation;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
+ }
+ _SEH2_END;
+
+ if(!SeSinglePrivilegeCheck(SeTcbPrivilege,
+ PreviousMode))
{
- ExFreePool(Token->DefaultDacl);
+ Status = STATUS_PRIVILEGE_NOT_HELD;
+ break;
}
- /* set the new dacl */
- Token->DefaultDacl = CapturedAcl;
- }
+ Token->SessionId = SessionId;
+ break;
}
- else
+
+ default:
{
- /* clear and free the default dacl if present */
- if(Token->DefaultDacl != NULL)
- {
- ExFreePool(Token->DefaultDacl);
- Token->DefaultDacl = NULL;
- }
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
}
- }
- }
- else
- {
- Status = STATUS_INFO_LENGTH_MISMATCH;
- }
- break;
- }
-
- case TokenSessionId:
- {
- ULONG SessionId = 0;
-
- _SEH_TRY
- {
- /* buffer size was already verified, no need to check here again */
- SessionId = *(PULONG)TokenInformation;
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- if(NT_SUCCESS(Status))
- {
- if(!SeSinglePrivilegeCheck(SeTcbPrivilege,
- PreviousMode))
- {
- Status = STATUS_PRIVILEGE_NOT_HELD;
- break;
- }
-
- Token->SessionId = SessionId;
}
- break;
- }
-
- default:
- {
- Status = STATUS_NOT_IMPLEMENTED;
- break;
- }
+
+ ObDereferenceObject(Token);
}
-
- ObDereferenceObject(Token);
- }
-
- return(Status);
+
+ return(Status);
}
* is correct either. -Gunnar
* This is true. EffectiveOnly overrides SQOS.EffectiveOnly. - IAI
*/
-NTSTATUS STDCALL
+NTSTATUS NTAPI
NtDuplicateToken(IN HANDLE ExistingTokenHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN TOKEN_TYPE TokenType,
OUT PHANDLE NewTokenHandle)
{
- KPROCESSOR_MODE PreviousMode;
- HANDLE hToken;
- PTOKEN Token;
- PTOKEN NewToken;
- PSECURITY_QUALITY_OF_SERVICE CapturedSecurityQualityOfService;
- BOOLEAN QoSPresent;
- NTSTATUS Status = STATUS_SUCCESS;
-
- PAGED_CODE();
-
- PreviousMode = KeGetPreviousMode();
-
- if(PreviousMode != KernelMode)
- {
- _SEH_TRY
- {
- ProbeForWriteHandle(NewTokenHandle);
- }
- _SEH_HANDLE
+ KPROCESSOR_MODE PreviousMode;
+ HANDLE hToken;
+ PTOKEN Token;
+ PTOKEN NewToken;
+ PSECURITY_QUALITY_OF_SERVICE CapturedSecurityQualityOfService;
+ BOOLEAN QoSPresent;
+ NTSTATUS Status;
+
+ PAGED_CODE();
+
+ PreviousMode = KeGetPreviousMode();
+
+ if (PreviousMode != KernelMode)
{
- Status = _SEH_GetExceptionCode();
+ _SEH2_TRY
+ {
+ ProbeForWriteHandle(NewTokenHandle);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Return the exception code */
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
+ }
+ _SEH2_END;
}
- _SEH_END;
-
+
+ Status = SepCaptureSecurityQualityOfService(ObjectAttributes,
+ PreviousMode,
+ PagedPool,
+ FALSE,
+ &CapturedSecurityQualityOfService,
+ &QoSPresent);
if(!NT_SUCCESS(Status))
{
- return Status;
+ DPRINT1("NtDuplicateToken() failed to capture QoS! Status: 0x%x\n", Status);
+ return Status;
}
- }
-
- Status = SepCaptureSecurityQualityOfService(ObjectAttributes,
- PreviousMode,
- PagedPool,
- FALSE,
- &CapturedSecurityQualityOfService,
- &QoSPresent);
- if(!NT_SUCCESS(Status))
- {
- DPRINT1("NtDuplicateToken() failed to capture QoS! Status: 0x%x\n", Status);
- return Status;
- }
-
- Status = ObReferenceObjectByHandle(ExistingTokenHandle,
- TOKEN_DUPLICATE,
- SepTokenObjectType,
- PreviousMode,
- (PVOID*)&Token,
- NULL);
- if (NT_SUCCESS(Status))
- {
- Status = SepDuplicateToken(Token,
- ObjectAttributes,
- EffectiveOnly,
- TokenType,
- (QoSPresent ? CapturedSecurityQualityOfService->ImpersonationLevel : SecurityAnonymous),
- PreviousMode,
- &NewToken);
-
- ObDereferenceObject(Token);
-
+
+ Status = ObReferenceObjectByHandle(ExistingTokenHandle,
+ TOKEN_DUPLICATE,
+ SepTokenObjectType,
+ PreviousMode,
+ (PVOID*)&Token,
+ NULL);
if (NT_SUCCESS(Status))
{
- Status = ObInsertObject((PVOID)NewToken,
- NULL,
- DesiredAccess,
- 0,
- NULL,
- &hToken);
-
- if (NT_SUCCESS(Status))
- {
- _SEH_TRY
- {
- *NewTokenHandle = hToken;
- }
- _SEH_HANDLE
+ Status = SepDuplicateToken(Token,
+ ObjectAttributes,
+ EffectiveOnly,
+ TokenType,
+ (QoSPresent ? CapturedSecurityQualityOfService->ImpersonationLevel : SecurityAnonymous),
+ PreviousMode,
+ &NewToken);
+
+ ObDereferenceObject(Token);
+
+ if (NT_SUCCESS(Status))
{
- Status = _SEH_GetExceptionCode();
+ Status = ObInsertObject((PVOID)NewToken,
+ NULL,
+ DesiredAccess,
+ 0,
+ NULL,
+ &hToken);
+
+ if (NT_SUCCESS(Status))
+ {
+ _SEH2_TRY
+ {
+ *NewTokenHandle = hToken;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+ }
}
- _SEH_END;
- }
}
- }
-
- /* free the captured structure */
- SepReleaseSecurityQualityOfService(CapturedSecurityQualityOfService,
- PreviousMode,
- FALSE);
-
- return Status;
-}
-
-
-VOID SepAdjustGroups(PACCESS_TOKEN Token,
- ULONG a,
- BOOLEAN ResetToDefault,
- PSID_AND_ATTRIBUTES Groups,
- ULONG b,
- KPROCESSOR_MODE PreviousMode,
- ULONG c,
- PULONG d,
- PULONG e,
- PULONG f)
-{
- UNIMPLEMENTED;
+
+ /* free the captured structure */
+ SepReleaseSecurityQualityOfService(CapturedSecurityQualityOfService,
+ PreviousMode,
+ FALSE);
+
+ return Status;
}
-
-NTSTATUS STDCALL
+NTSTATUS NTAPI
NtAdjustGroupsToken(IN HANDLE TokenHandle,
IN BOOLEAN ResetToDefault,
IN PTOKEN_GROUPS NewState,
OUT PTOKEN_GROUPS PreviousState OPTIONAL,
OUT PULONG ReturnLength)
{
-#if 0
- NTSTATUS Status;
- PACCESS_TOKEN Token;
- ULONG a;
- ULONG b;
- ULONG c;
-
- PAGED_CODE();
-
- Status = ObReferenceObjectByHandle(TokenHandle,
- ?,
- SepTokenObjectType,
- UserMode,
- (PVOID*)&Token,
- NULL);
-
-
- SepAdjustGroups(Token,
- 0,
- ResetToDefault,
- NewState->Groups,
- ?,
- PreviousState,
- 0,
- &a,
- &b,
- &c);
-#else
- UNIMPLEMENTED;
- return(STATUS_NOT_IMPLEMENTED);
-#endif
-}
-
-
-#if 0
-NTSTATUS
-SepAdjustPrivileges(PACCESS_TOKEN Token,
- ULONG a,
- KPROCESSOR_MODE PreviousMode,
- ULONG PrivilegeCount,
- PLUID_AND_ATTRIBUTES Privileges,
- PTOKEN_PRIVILEGES* PreviousState,
- PULONG b,
- PULONG c,
- PULONG d)
-{
- ULONG i;
-
- *c = 0;
-
- if (Token->PrivilegeCount > 0)
- {
- for (i = 0; i < Token->PrivilegeCount; i++)
- {
- if (PreviousMode != KernelMode)
- {
- if (Token->Privileges[i]->Attributes & SE_PRIVILEGE_ENABLED == 0)
- {
- if (a != 0)
- {
- if (PreviousState != NULL)
- {
- memcpy(&PreviousState[i],
- &Token->Privileges[i],
- sizeof(LUID_AND_ATTRIBUTES));
- }
- Token->Privileges[i].Attributes &= (~SE_PRIVILEGE_ENABLED);
- }
- }
- }
- }
- }
-
- if (PreviousMode != KernelMode)
- {
- Token->TokenFlags = Token->TokenFlags & (~1);
- }
- else
- {
- if (PrivilegeCount <= ?)
- {
- }
- }
- if (
+ UNIMPLEMENTED;
+ return(STATUS_NOT_IMPLEMENTED);
}
-#endif
-
/*
* @implemented
*/
-NTSTATUS STDCALL
+NTSTATUS NTAPI
NtAdjustPrivilegesToken (IN HANDLE TokenHandle,
IN BOOLEAN DisableAllPrivileges,
IN PTOKEN_PRIVILEGES NewState,
OUT PTOKEN_PRIVILEGES PreviousState OPTIONAL,
OUT PULONG ReturnLength OPTIONAL)
{
-// PLUID_AND_ATTRIBUTES Privileges;
- KPROCESSOR_MODE PreviousMode;
- ULONG PrivilegeCount;
- PTOKEN Token;
-// ULONG Length;
- ULONG i;
- ULONG j;
- ULONG k;
- ULONG Count;
+ // PLUID_AND_ATTRIBUTES Privileges;
+ KPROCESSOR_MODE PreviousMode;
+ ULONG PrivilegeCount;
+ PTOKEN Token;
+ // ULONG Length;
+ ULONG i;
+ ULONG j;
+ ULONG k;
+ ULONG Count;
#if 0
- ULONG a;
- ULONG b;
- ULONG c;
+ ULONG a;
+ ULONG b;
+ ULONG c;
#endif
- NTSTATUS Status;
-
- PAGED_CODE();
-
- DPRINT ("NtAdjustPrivilegesToken() called\n");
-
-// PrivilegeCount = NewState->PrivilegeCount;
- PreviousMode = KeGetPreviousMode ();
-// SeCaptureLuidAndAttributesArray(NewState->Privileges,
-// PrivilegeCount,
-// PreviousMode,
-// NULL,
-// 0,
-// NonPagedPool,
-// 1,
-// &Privileges,
-// &Length);
-
- Status = ObReferenceObjectByHandle (TokenHandle,
- TOKEN_ADJUST_PRIVILEGES | (PreviousState != NULL ? TOKEN_QUERY : 0),
- SepTokenObjectType,
- PreviousMode,
- (PVOID*)&Token,
- NULL);
- if (!NT_SUCCESS(Status))
+ NTSTATUS Status;
+
+ PAGED_CODE();
+
+ DPRINT ("NtAdjustPrivilegesToken() called\n");
+
+ // PrivilegeCount = NewState->PrivilegeCount;
+ PreviousMode = KeGetPreviousMode ();
+ // SeCaptureLuidAndAttributesArray(NewState->Privileges,
+ // PrivilegeCount,
+ // PreviousMode,
+ // NULL,
+ // 0,
+ // NonPagedPool,
+ // 1,
+ // &Privileges,
+ // &Length);
+
+ Status = ObReferenceObjectByHandle (TokenHandle,
+ TOKEN_ADJUST_PRIVILEGES | (PreviousState != NULL ? TOKEN_QUERY : 0),
+ 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;
}
-
-
+
+
#if 0
- SepAdjustPrivileges(Token,
- 0,
- PreviousMode,
- PrivilegeCount,
- Privileges,
- PreviousState,
- &a,
- &b,
- &c);
+ SepAdjustPrivileges(Token,
+ 0,
+ PreviousMode,
+ PrivilegeCount,
+ Privileges,
+ PreviousState,
+ &a,
+ &b,
+ &c);
#endif
-
- PrivilegeCount = (BufferLength - FIELD_OFFSET(TOKEN_PRIVILEGES, Privileges)) /
- sizeof(LUID_AND_ATTRIBUTES);
-
- if (PreviousState != NULL)
- PreviousState->PrivilegeCount = 0;
-
- k = 0;
- if (DisableAllPrivileges == TRUE)
+
+ PrivilegeCount = (BufferLength - FIELD_OFFSET(TOKEN_PRIVILEGES, Privileges)) /
+ sizeof(LUID_AND_ATTRIBUTES);
+
+ if (PreviousState != NULL)
+ PreviousState->PrivilegeCount = 0;
+
+ k = 0;
+ if (DisableAllPrivileges == TRUE)
{
- for (i = 0; i < Token->PrivilegeCount; i++)
+ for (i = 0; i < Token->PrivilegeCount; i++)
{
- if (Token->Privileges[i].Attributes != 0)
+ if (Token->Privileges[i].Attributes != 0)
{
- DPRINT ("Attributes differ\n");
-
- /* Save current privilege */
- if (PreviousState != NULL)
+ DPRINT ("Attributes differ\n");
+
+ /* Save current privilege */
+ if (PreviousState != NULL)
{
- if (k < PrivilegeCount)
+ if (k < PrivilegeCount)
{
- PreviousState->PrivilegeCount++;
- PreviousState->Privileges[k].Luid = Token->Privileges[i].Luid;
- PreviousState->Privileges[k].Attributes = Token->Privileges[i].Attributes;
+ PreviousState->PrivilegeCount++;
+ PreviousState->Privileges[k].Luid = Token->Privileges[i].Luid;
+ PreviousState->Privileges[k].Attributes = Token->Privileges[i].Attributes;
}
- else
+ else
{
- /* FIXME: Should revert all the changes, calculate how
- * much space would be needed, set ResultLength
- * accordingly and fail.
- */
+ /* FIXME: Should revert all the changes, calculate how
+ * much space would be needed, set ResultLength
+ * accordingly and fail.
+ */
}
- k++;
+ k++;
}
-
- /* Update current privlege */
- Token->Privileges[i].Attributes &= ~SE_PRIVILEGE_ENABLED;
+
+ /* Update current privlege */
+ Token->Privileges[i].Attributes &= ~SE_PRIVILEGE_ENABLED;
}
}
- Status = STATUS_SUCCESS;
+ Status = STATUS_SUCCESS;
}
- else
+ else
{
- Count = 0;
- for (i = 0; i < Token->PrivilegeCount; i++)
+ Count = 0;
+ for (i = 0; i < Token->PrivilegeCount; i++)
{
- for (j = 0; j < NewState->PrivilegeCount; j++)
+ 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)
+ 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 ("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)
+ 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)
{
- if (k < PrivilegeCount)
+ if (k < PrivilegeCount)
{
- PreviousState->PrivilegeCount++;
- PreviousState->Privileges[k].Luid = Token->Privileges[i].Luid;
- PreviousState->Privileges[k].Attributes = Token->Privileges[i].Attributes;
+ PreviousState->PrivilegeCount++;
+ PreviousState->Privileges[k].Luid = Token->Privileges[i].Luid;
+ PreviousState->Privileges[k].Attributes = Token->Privileges[i].Attributes;
}
- else
+ else
{
- /* FIXME: Should revert all the changes, calculate how
- * much space would be needed, set ResultLength
- * accordingly and fail.
- */
+ /* FIXME: Should revert all the changes, calculate how
+ * much space would be needed, set ResultLength
+ * accordingly and fail.
+ */
}
- k++;
+ k++;
}
-
- /* Update current privlege */
- Token->Privileges[i].Attributes &= ~SE_PRIVILEGE_ENABLED;
- Token->Privileges[i].Attributes |=
+
+ /* 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);
+ DPRINT ("New attributes %lx\n",
+ Token->Privileges[i].Attributes);
}
- Count++;
+ Count++;
}
}
}
- Status = Count < NewState->PrivilegeCount ? STATUS_NOT_ALL_ASSIGNED : STATUS_SUCCESS;
- }
-
- if (ReturnLength != NULL)
- {
- *ReturnLength = sizeof(TOKEN_PRIVILEGES) +
- (sizeof(LUID_AND_ATTRIBUTES) * (k - 1));
- }
-
- ObDereferenceObject (Token);
-
-// SeReleaseLuidAndAttributesArray(Privileges,
-// PreviousMode,
-// 0);
-
- DPRINT ("NtAdjustPrivilegesToken() done\n");
-
- return Status;
-}
-
-VOID
-NTAPI
-SeAssignPrimaryToken(IN PEPROCESS Process,
- IN PTOKEN Token)
-{
- PAGED_CODE();
-
- /* Sanity checks */
- ASSERT(Token->TokenType == TokenPrimary);
- ASSERT(!Token->TokenInUse);
-
- /* Clean any previous token */
- if (Process->Token.Object) SeDeassignPrimaryToken(Process);
-
- /* Set the new token */
- ObReferenceObject(Token);
- Token->TokenInUse = TRUE;
- ObInitializeFastReference(&Process->Token, Token);
-}
-
-PTOKEN
-STDCALL
-SepCreateSystemProcessToken(VOID)
-{
- NTSTATUS Status;
- ULONG uSize;
- ULONG i;
- ULONG uLocalSystemLength;
- ULONG uWorldLength;
- ULONG uAuthUserLength;
- ULONG uAdminsLength;
- PTOKEN AccessToken;
- PVOID SidArea;
-
- PAGED_CODE();
-
- uLocalSystemLength = RtlLengthSid(SeLocalSystemSid);
- uWorldLength = RtlLengthSid(SeWorldSid);
- uAuthUserLength = RtlLengthSid(SeAuthenticatedUserSid);
- uAdminsLength = RtlLengthSid(SeAliasAdminsSid);
-
- /*
- * Initialize the token
- */
- Status = ObCreateObject(KernelMode,
- SepTokenObjectType,
- NULL,
- KernelMode,
- NULL,
- sizeof(TOKEN),
- 0,
- 0,
- (PVOID*)&AccessToken);
- if (!NT_SUCCESS(Status))
- {
- return NULL;
- }
-
- Status = ExpAllocateLocallyUniqueId(&AccessToken->TokenId);
- if (!NT_SUCCESS(Status))
- {
- ObDereferenceObject(AccessToken);
- return NULL;
- }
-
- Status = ExpAllocateLocallyUniqueId(&AccessToken->ModifiedId);
- if (!NT_SUCCESS(Status))
- {
- ObDereferenceObject(AccessToken);
- return NULL;
- }
-
- Status = ExpAllocateLocallyUniqueId(&AccessToken->AuthenticationId);
- if (!NT_SUCCESS(Status))
- {
- ObDereferenceObject(AccessToken);
- return NULL;
- }
-
- AccessToken->TokenLock = &SepTokenLock;
-
- AccessToken->TokenType = TokenPrimary;
- AccessToken->ImpersonationLevel = SecurityDelegation;
- AccessToken->TokenSource.SourceIdentifier.LowPart = 0;
- AccessToken->TokenSource.SourceIdentifier.HighPart = 0;
- memcpy(AccessToken->TokenSource.SourceName, "SeMgr\0\0\0", 8);
- AccessToken->ExpirationTime.QuadPart = -1;
- AccessToken->UserAndGroupCount = 4;
-
- uSize = sizeof(SID_AND_ATTRIBUTES) * AccessToken->UserAndGroupCount;
- uSize += uLocalSystemLength;
- uSize += uWorldLength;
- uSize += uAuthUserLength;
- uSize += uAdminsLength;
-
- AccessToken->UserAndGroups =
- (PSID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool,
- uSize,
- TAG('T', 'O', 'K', 'u'));
- SidArea = &AccessToken->UserAndGroups[AccessToken->UserAndGroupCount];
-
- i = 0;
- AccessToken->UserAndGroups[i].Sid = (PSID) SidArea;
- AccessToken->UserAndGroups[i++].Attributes = 0;
- RtlCopySid(uLocalSystemLength, SidArea, SeLocalSystemSid);
- SidArea = (char*)SidArea + uLocalSystemLength;
-
- AccessToken->DefaultOwnerIndex = i;
- AccessToken->UserAndGroups[i].Sid = (PSID) SidArea;
- AccessToken->PrimaryGroup = (PSID) SidArea;
- AccessToken->UserAndGroups[i++].Attributes = SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT;
- Status = RtlCopySid(uAdminsLength, SidArea, SeAliasAdminsSid);
- SidArea = (char*)SidArea + uAdminsLength;
-
- AccessToken->UserAndGroups[i].Sid = (PSID) SidArea;
- AccessToken->UserAndGroups[i++].Attributes = SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY;
- RtlCopySid(uWorldLength, SidArea, SeWorldSid);
- SidArea = (char*)SidArea + uWorldLength;
-
- AccessToken->UserAndGroups[i].Sid = (PSID) SidArea;
- AccessToken->UserAndGroups[i++].Attributes = SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY;
- RtlCopySid(uAuthUserLength, SidArea, SeAuthenticatedUserSid);
- SidArea = (char*)SidArea + uAuthUserLength;
-
- AccessToken->PrivilegeCount = 20;
-
- uSize = AccessToken->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES);
- AccessToken->Privileges =
- (PLUID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool,
- uSize,
- TAG('T', 'O', 'K', 'p'));
-
- i = 0;
- AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED;
- AccessToken->Privileges[i++].Luid = SeTcbPrivilege;
-
- AccessToken->Privileges[i].Attributes = 0;
- AccessToken->Privileges[i++].Luid = SeCreateTokenPrivilege;
-
- AccessToken->Privileges[i].Attributes = 0;
- AccessToken->Privileges[i++].Luid = SeTakeOwnershipPrivilege;
-
- AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED;
- AccessToken->Privileges[i++].Luid = SeCreatePagefilePrivilege;
-
- AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED;
- AccessToken->Privileges[i++].Luid = SeLockMemoryPrivilege;
-
- AccessToken->Privileges[i].Attributes = 0;
- AccessToken->Privileges[i++].Luid = SeAssignPrimaryTokenPrivilege;
-
- AccessToken->Privileges[i].Attributes = 0;
- AccessToken->Privileges[i++].Luid = SeIncreaseQuotaPrivilege;
-
- AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED;
- AccessToken->Privileges[i++].Luid = SeIncreaseBasePriorityPrivilege;
-
- AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED;
- AccessToken->Privileges[i++].Luid = SeCreatePermanentPrivilege;
-
- AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED;
- AccessToken->Privileges[i++].Luid = SeDebugPrivilege;
-
- AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED;
- AccessToken->Privileges[i++].Luid = SeAuditPrivilege;
-
- AccessToken->Privileges[i].Attributes = 0;
- AccessToken->Privileges[i++].Luid = SeSecurityPrivilege;
-
- AccessToken->Privileges[i].Attributes = 0;
- AccessToken->Privileges[i++].Luid = SeSystemEnvironmentPrivilege;
-
- AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED;
- AccessToken->Privileges[i++].Luid = SeChangeNotifyPrivilege;
-
- AccessToken->Privileges[i].Attributes = 0;
- AccessToken->Privileges[i++].Luid = SeBackupPrivilege;
-
- AccessToken->Privileges[i].Attributes = 0;
- AccessToken->Privileges[i++].Luid = SeRestorePrivilege;
-
- AccessToken->Privileges[i].Attributes = 0;
- AccessToken->Privileges[i++].Luid = SeShutdownPrivilege;
-
- AccessToken->Privileges[i].Attributes = 0;
- AccessToken->Privileges[i++].Luid = SeLoadDriverPrivilege;
-
- AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED;
- AccessToken->Privileges[i++].Luid = SeProfileSingleProcessPrivilege;
-
- AccessToken->Privileges[i].Attributes = 0;
- AccessToken->Privileges[i++].Luid = SeSystemtimePrivilege;
-#if 0
- AccessToken->Privileges[i].Attributes = 0;
- AccessToken->Privileges[i++].Luid = SeUndockPrivilege;
-
- AccessToken->Privileges[i].Attributes = 0;
- AccessToken->Privileges[i++].Luid = SeManageVolumePrivilege;
-#endif
-
- ASSERT(i == 20);
-
- uSize = sizeof(ACL);
- uSize += sizeof(ACE) + uLocalSystemLength;
- uSize += sizeof(ACE) + uAdminsLength;
- uSize = (uSize & (~3)) + 8;
- AccessToken->DefaultDacl =
- (PACL) ExAllocatePoolWithTag(PagedPool,
- uSize,
- TAG('T', 'O', 'K', 'd'));
- Status = RtlCreateAcl(AccessToken->DefaultDacl, uSize, ACL_REVISION);
- if ( NT_SUCCESS(Status) )
- {
- Status = RtlAddAccessAllowedAce(AccessToken->DefaultDacl, ACL_REVISION, GENERIC_ALL, SeLocalSystemSid);
- }
-
- if ( NT_SUCCESS(Status) )
- {
- Status = RtlAddAccessAllowedAce(AccessToken->DefaultDacl, ACL_REVISION, GENERIC_READ|GENERIC_WRITE|GENERIC_EXECUTE|READ_CONTROL, SeAliasAdminsSid);
- }
-
- if ( ! NT_SUCCESS(Status) )
- {
- ObDereferenceObject(AccessToken);
- return NULL;
- }
-
- return AccessToken;
-}
-
-
-NTSTATUS STDCALL
-NtCreateToken(OUT PHANDLE TokenHandle,
- IN ACCESS_MASK DesiredAccess,
- IN POBJECT_ATTRIBUTES ObjectAttributes,
- IN TOKEN_TYPE TokenType,
- IN PLUID AuthenticationId,
- IN PLARGE_INTEGER ExpirationTime,
- IN PTOKEN_USER TokenUser,
- IN PTOKEN_GROUPS TokenGroups,
- IN PTOKEN_PRIVILEGES TokenPrivileges,
- IN PTOKEN_OWNER TokenOwner,
- IN PTOKEN_PRIMARY_GROUP TokenPrimaryGroup,
- IN PTOKEN_DEFAULT_DACL TokenDefaultDacl,
- IN PTOKEN_SOURCE TokenSource)
-{
- HANDLE hToken;
- PTOKEN AccessToken;
- LUID TokenId;
- LUID ModifiedId;
- PVOID EndMem;
- ULONG uLength;
- ULONG i;
- KPROCESSOR_MODE PreviousMode;
- ULONG nTokenPrivileges = 0;
- LARGE_INTEGER LocalExpirationTime = {{0}};
- NTSTATUS Status = STATUS_SUCCESS;
-
- PAGED_CODE();
-
- PreviousMode = ExGetPreviousMode();
-
- if(PreviousMode != KernelMode)
- {
- _SEH_TRY
- {
- ProbeForWriteHandle(TokenHandle);
- ProbeForRead(AuthenticationId,
- sizeof(LUID),
- sizeof(ULONG));
- LocalExpirationTime = ProbeForReadLargeInteger(ExpirationTime);
- ProbeForRead(TokenUser,
- sizeof(TOKEN_USER),
- sizeof(ULONG));
- ProbeForRead(TokenGroups,
- sizeof(TOKEN_GROUPS),
- sizeof(ULONG));
- ProbeForRead(TokenPrivileges,
- sizeof(TOKEN_PRIVILEGES),
- sizeof(ULONG));
- ProbeForRead(TokenOwner,
- sizeof(TOKEN_OWNER),
- sizeof(ULONG));
- ProbeForRead(TokenPrimaryGroup,
- sizeof(TOKEN_PRIMARY_GROUP),
- sizeof(ULONG));
- ProbeForRead(TokenDefaultDacl,
- sizeof(TOKEN_DEFAULT_DACL),
- sizeof(ULONG));
- ProbeForRead(TokenSource,
- sizeof(TOKEN_SOURCE),
- sizeof(ULONG));
- nTokenPrivileges = TokenPrivileges->PrivilegeCount;
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- if(!NT_SUCCESS(Status))
- {
- return Status;
- }
- }
- else
- {
- nTokenPrivileges = TokenPrivileges->PrivilegeCount;
- LocalExpirationTime = *ExpirationTime;
- }
-
- Status = ZwAllocateLocallyUniqueId(&TokenId);
- if (!NT_SUCCESS(Status))
- return(Status);
-
- Status = ZwAllocateLocallyUniqueId(&ModifiedId);
- if (!NT_SUCCESS(Status))
- return(Status);
-
- Status = ObCreateObject(PreviousMode,
- SepTokenObjectType,
- ObjectAttributes,
- PreviousMode,
- NULL,
- sizeof(TOKEN),
- 0,
- 0,
- (PVOID*)&AccessToken);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("ObCreateObject() failed (Status %lx)\n");
- return(Status);
- }
-
- AccessToken->TokenLock = &SepTokenLock;
-
- RtlCopyLuid(&AccessToken->TokenSource.SourceIdentifier,
- &TokenSource->SourceIdentifier);
- memcpy(AccessToken->TokenSource.SourceName,
- TokenSource->SourceName,
- sizeof(TokenSource->SourceName));
-
- RtlCopyLuid(&AccessToken->TokenId, &TokenId);
- RtlCopyLuid(&AccessToken->AuthenticationId, AuthenticationId);
- AccessToken->ExpirationTime = *ExpirationTime;
- RtlCopyLuid(&AccessToken->ModifiedId, &ModifiedId);
-
- AccessToken->UserAndGroupCount = TokenGroups->GroupCount + 1;
- AccessToken->PrivilegeCount = TokenPrivileges->PrivilegeCount;
- AccessToken->UserAndGroups = 0;
- AccessToken->Privileges = 0;
-
- AccessToken->TokenType = TokenType;
- AccessToken->ImpersonationLevel = ((PSECURITY_QUALITY_OF_SERVICE)
- (ObjectAttributes->SecurityQualityOfService))->ImpersonationLevel;
-
- /*
- * Normally we would just point these members into the variable information
- * area; however, our ObCreateObject() call can't allocate a variable information
- * area, so we allocate them seperately and provide a destroy function.
- */
-
- uLength = sizeof(SID_AND_ATTRIBUTES) * AccessToken->UserAndGroupCount;
- uLength += RtlLengthSid(TokenUser->User.Sid);
- for (i = 0; i < TokenGroups->GroupCount; i++)
- uLength += RtlLengthSid(TokenGroups->Groups[i].Sid);
-
- AccessToken->UserAndGroups =
- (PSID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool,
- uLength,
- TAG('T', 'O', 'K', 'u'));
-
- EndMem = &AccessToken->UserAndGroups[AccessToken->UserAndGroupCount];
-
- Status = RtlCopySidAndAttributesArray(1,
- &TokenUser->User,
- uLength,
- AccessToken->UserAndGroups,
- EndMem,
- &EndMem,
- &uLength);
- if (NT_SUCCESS(Status))
- {
- Status = RtlCopySidAndAttributesArray(TokenGroups->GroupCount,
- TokenGroups->Groups,
- uLength,
- &AccessToken->UserAndGroups[1],
- EndMem,
- &EndMem,
- &uLength);
+ Status = Count < NewState->PrivilegeCount ? STATUS_NOT_ALL_ASSIGNED : STATUS_SUCCESS;
}
-
- if (NT_SUCCESS(Status))
+
+ if (ReturnLength != NULL)
{
- Status = SepFindPrimaryGroupAndDefaultOwner(
- AccessToken,
- TokenPrimaryGroup->PrimaryGroup,
- TokenOwner->Owner);
+ *ReturnLength = sizeof(TOKEN_PRIVILEGES) +
+ (sizeof(LUID_AND_ATTRIBUTES) * (k - 1));
}
+
+ ObDereferenceObject (Token);
+
+ // SeReleaseLuidAndAttributesArray(Privileges,
+ // PreviousMode,
+ // 0);
+
+ DPRINT ("NtAdjustPrivilegesToken() done\n");
+
+ return Status;
+}
- if (NT_SUCCESS(Status))
+NTSTATUS
+NTAPI
+NtCreateToken(OUT PHANDLE TokenHandle,
+ IN ACCESS_MASK DesiredAccess,
+ IN POBJECT_ATTRIBUTES ObjectAttributes,
+ IN TOKEN_TYPE TokenType,
+ IN PLUID AuthenticationId,
+ IN PLARGE_INTEGER ExpirationTime,
+ IN PTOKEN_USER TokenUser,
+ IN PTOKEN_GROUPS TokenGroups,
+ IN PTOKEN_PRIVILEGES TokenPrivileges,
+ IN PTOKEN_OWNER TokenOwner,
+ IN PTOKEN_PRIMARY_GROUP TokenPrimaryGroup,
+ IN PTOKEN_DEFAULT_DACL TokenDefaultDacl,
+ IN PTOKEN_SOURCE TokenSource)
+{
+ HANDLE hToken;
+ KPROCESSOR_MODE PreviousMode;
+ ULONG nTokenPrivileges = 0;
+ LARGE_INTEGER LocalExpirationTime = {{0, 0}};
+ NTSTATUS Status;
+
+ PAGED_CODE();
+
+ PreviousMode = ExGetPreviousMode();
+
+ if(PreviousMode != KernelMode)
{
- uLength = TokenPrivileges->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES);
- AccessToken->Privileges =
- (PLUID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool,
- uLength,
- TAG('T', 'O', 'K', 'p'));
-
- if (PreviousMode != KernelMode)
+ _SEH2_TRY
{
- _SEH_TRY
- {
- RtlCopyMemory(AccessToken->Privileges,
- TokenPrivileges->Privileges,
- nTokenPrivileges * sizeof(LUID_AND_ATTRIBUTES));
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
+ ProbeForWriteHandle(TokenHandle);
+ ProbeForRead(AuthenticationId,
+ sizeof(LUID),
+ sizeof(ULONG));
+ LocalExpirationTime = ProbeForReadLargeInteger(ExpirationTime);
+ ProbeForRead(TokenUser,
+ sizeof(TOKEN_USER),
+ sizeof(ULONG));
+ ProbeForRead(TokenGroups,
+ sizeof(TOKEN_GROUPS),
+ sizeof(ULONG));
+ ProbeForRead(TokenPrivileges,
+ sizeof(TOKEN_PRIVILEGES),
+ sizeof(ULONG));
+ ProbeForRead(TokenOwner,
+ sizeof(TOKEN_OWNER),
+ sizeof(ULONG));
+ ProbeForRead(TokenPrimaryGroup,
+ sizeof(TOKEN_PRIMARY_GROUP),
+ sizeof(ULONG));
+ ProbeForRead(TokenDefaultDacl,
+ sizeof(TOKEN_DEFAULT_DACL),
+ sizeof(ULONG));
+ ProbeForRead(TokenSource,
+ sizeof(TOKEN_SOURCE),
+ sizeof(ULONG));
+ nTokenPrivileges = TokenPrivileges->PrivilegeCount;
}
- else
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- RtlCopyMemory(AccessToken->Privileges,
- TokenPrivileges->Privileges,
- nTokenPrivileges * sizeof(LUID_AND_ATTRIBUTES));
+ /* Return the exception code */
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
}
+ _SEH2_END;
}
-
- if (NT_SUCCESS(Status))
- {
- AccessToken->DefaultDacl =
- (PACL) ExAllocatePoolWithTag(PagedPool,
- TokenDefaultDacl->DefaultDacl->AclSize,
- TAG('T', 'O', 'K', 'd'));
- memcpy(AccessToken->DefaultDacl,
- TokenDefaultDacl->DefaultDacl,
- TokenDefaultDacl->DefaultDacl->AclSize);
- }
-
- Status = ObInsertObject ((PVOID)AccessToken,
- NULL,
- DesiredAccess,
- 0,
- NULL,
- &hToken);
- if (!NT_SUCCESS(Status))
+ else
{
- DPRINT1("ObInsertObject() failed (Status %lx)\n", Status);
+ nTokenPrivileges = TokenPrivileges->PrivilegeCount;
+ LocalExpirationTime = *ExpirationTime;
}
-
- if (NT_SUCCESS(Status))
+
+ Status = SepCreateToken(&hToken,
+ PreviousMode,
+ DesiredAccess,
+ ObjectAttributes,
+ TokenType,
+ ((PSECURITY_QUALITY_OF_SERVICE)(ObjectAttributes->SecurityQualityOfService))->ImpersonationLevel,
+ AuthenticationId,
+ &LocalExpirationTime,
+ &TokenUser->User,
+ TokenGroups->GroupCount,
+ TokenGroups->Groups,
+ 0, // FIXME: Should capture
+ nTokenPrivileges,
+ TokenPrivileges->Privileges,
+ TokenOwner->Owner,
+ TokenPrimaryGroup->PrimaryGroup,
+ TokenDefaultDacl->DefaultDacl,
+ TokenSource,
+ FALSE);
+ if (NT_SUCCESS(Status))
{
- _SEH_TRY
- {
- *TokenHandle = hToken;
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
+ _SEH2_TRY
+ {
+ *TokenHandle = hToken;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
}
-
- return Status;
-}
-
-
-/*
- * @implemented
- */
-NTSTATUS STDCALL
-SeQueryAuthenticationIdToken(IN PACCESS_TOKEN Token,
- OUT PLUID LogonId)
-{
- PAGED_CODE();
-
- *LogonId = ((PTOKEN)Token)->AuthenticationId;
-
- return STATUS_SUCCESS;
-}
-
-
-/*
- * @implemented
- */
-SECURITY_IMPERSONATION_LEVEL
-STDCALL
-SeTokenImpersonationLevel(IN PACCESS_TOKEN Token)
-{
- PAGED_CODE();
-
- return ((PTOKEN)Token)->ImpersonationLevel;
-}
-
-
-/*
- * @implemented
- */
-TOKEN_TYPE STDCALL
-SeTokenType(IN PACCESS_TOKEN Token)
-{
- PAGED_CODE();
-
- return ((PTOKEN)Token)->TokenType;
-}
-
-
-/*
- * @implemented
- */
-BOOLEAN
-STDCALL
-SeTokenIsAdmin(
- IN PACCESS_TOKEN Token
- )
-{
- PAGED_CODE();
- return (((PTOKEN)Token)->TokenFlags & TOKEN_WRITE_RESTRICTED) != 0;
-}
-
-/*
- * @implemented
- */
-BOOLEAN
-STDCALL
-SeTokenIsRestricted(
- IN PACCESS_TOKEN Token
- )
-{
- PAGED_CODE();
- return (((PTOKEN)Token)->TokenFlags & TOKEN_IS_RESTRICTED) != 0;
-}
-
-/*
- * @implemented
- */
-BOOLEAN
-STDCALL
-SeTokenIsWriteRestricted(
- IN PACCESS_TOKEN Token
- )
-{
- PAGED_CODE();
- return (((PTOKEN)Token)->TokenFlags & TOKEN_HAS_RESTORE_PRIVILEGE) != 0;
-}
-
-
-/*
- * @unimplemented
- */
-NTSTATUS
-STDCALL
-NtImpersonateAnonymousToken(
- IN HANDLE Thread
- )
-{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+
+ return Status;
}
-
/*
* @implemented
*/
NTSTATUS
-STDCALL
+NTAPI
NtOpenThreadTokenEx(IN HANDLE ThreadHandle,
IN ACCESS_MASK DesiredAccess,
IN BOOLEAN OpenAsSelf,
IN ULONG HandleAttributes,
OUT PHANDLE TokenHandle)
{
- PETHREAD Thread;
- HANDLE hToken;
- PTOKEN Token, NewToken, PrimaryToken;
- BOOLEAN CopyOnOpen, EffectiveOnly;
- SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
- SE_IMPERSONATION_STATE ImpersonationState;
- OBJECT_ATTRIBUTES ObjectAttributes;
- SECURITY_DESCRIPTOR SecurityDescriptor;
- PACL Dacl = NULL;
- KPROCESSOR_MODE PreviousMode;
- NTSTATUS Status = STATUS_SUCCESS;
-
- PAGED_CODE();
-
- PreviousMode = ExGetPreviousMode();
-
- if(PreviousMode != KernelMode)
- {
- _SEH_TRY
- {
- ProbeForWriteHandle(TokenHandle);
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- if(!NT_SUCCESS(Status))
+ PETHREAD Thread, NewThread;
+ HANDLE hToken;
+ PTOKEN Token, NewToken = NULL, PrimaryToken;
+ BOOLEAN CopyOnOpen, EffectiveOnly;
+ SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
+ SE_IMPERSONATION_STATE ImpersonationState;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ SECURITY_DESCRIPTOR SecurityDescriptor;
+ PACL Dacl = NULL;
+ KPROCESSOR_MODE PreviousMode;
+ NTSTATUS Status;
+
+ PAGED_CODE();
+
+ PreviousMode = ExGetPreviousMode();
+
+ if (PreviousMode != KernelMode)
{
- return Status;
+ _SEH2_TRY
+ {
+ ProbeForWriteHandle(TokenHandle);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Return the exception code */
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
+ }
+ _SEH2_END;
}
- }
-
- /*
- * At first open the thread token for information access and verify
- * that the token associated with thread is valid.
- */
-
- Status = ObReferenceObjectByHandle(ThreadHandle, THREAD_QUERY_INFORMATION,
- PsThreadType, PreviousMode, (PVOID*)&Thread,
- NULL);
- if (!NT_SUCCESS(Status))
+
+ /*
+ * At first open the thread token for information access and verify
+ * that the token associated with thread is valid.
+ */
+
+ Status = ObReferenceObjectByHandle(ThreadHandle, THREAD_QUERY_INFORMATION,
+ PsThreadType, PreviousMode, (PVOID*)&Thread,
+ NULL);
+ if (!NT_SUCCESS(Status))
{
- return Status;
+ return Status;
}
-
- Token = PsReferenceImpersonationToken(Thread, &CopyOnOpen, &EffectiveOnly,
- &ImpersonationLevel);
- if (Token == NULL)
+
+ Token = PsReferenceImpersonationToken(Thread, &CopyOnOpen, &EffectiveOnly,
+ &ImpersonationLevel);
+ if (Token == NULL)
{
- ObfDereferenceObject(Thread);
- return STATUS_NO_TOKEN;
+ ObDereferenceObject(Thread);
+ return STATUS_NO_TOKEN;
}
-
- ObDereferenceObject(Thread);
-
- if (ImpersonationLevel == SecurityAnonymous)
+
+ if (ImpersonationLevel == SecurityAnonymous)
{
- ObfDereferenceObject(Token);
- return STATUS_CANT_OPEN_ANONYMOUS;
+ PsDereferenceImpersonationToken(Token);
+ ObDereferenceObject(Thread);
+ return STATUS_CANT_OPEN_ANONYMOUS;
}
-
- /*
- * Revert to self if OpenAsSelf is specified.
- */
-
- if (OpenAsSelf)
+
+ /*
+ * Revert to self if OpenAsSelf is specified.
+ */
+
+ if (OpenAsSelf)
{
- PsDisableImpersonation(PsGetCurrentThread(), &ImpersonationState);
+ PsDisableImpersonation(PsGetCurrentThread(), &ImpersonationState);
}
-
- if (CopyOnOpen)
+
+ if (CopyOnOpen)
{
- Status = ObReferenceObjectByHandle(ThreadHandle, THREAD_ALL_ACCESS,
- PsThreadType, PreviousMode,
- (PVOID*)&Thread, NULL);
- if (!NT_SUCCESS(Status))
- {
- ObfDereferenceObject(Token);
- if (OpenAsSelf)
- {
- PsRestoreImpersonation(PsGetCurrentThread(), &ImpersonationState);
- }
- return Status;
- }
-
- PrimaryToken = PsReferencePrimaryToken(Thread->ThreadsProcess);
- Status = SepCreateImpersonationTokenDacl(Token, PrimaryToken, &Dacl);
- KEBUGCHECK(0);
- ObfDereferenceObject(PrimaryToken);
- ObfDereferenceObject(Thread);
- if (!NT_SUCCESS(Status))
+ Status = ObReferenceObjectByHandle(ThreadHandle, THREAD_ALL_ACCESS,
+ PsThreadType, KernelMode,
+ (PVOID*)&NewThread, NULL);
+ if (NT_SUCCESS(Status))
{
- ObfDereferenceObject(Token);
- if (OpenAsSelf)
- {
- PsRestoreImpersonation(PsGetCurrentThread(), &ImpersonationState);
- }
- return Status;
- }
+ PrimaryToken = PsReferencePrimaryToken(NewThread->ThreadsProcess);
+
+ Status = SepCreateImpersonationTokenDacl(Token, PrimaryToken, &Dacl);
- RtlCreateSecurityDescriptor(&SecurityDescriptor,
- SECURITY_DESCRIPTOR_REVISION);
- RtlSetDaclSecurityDescriptor(&SecurityDescriptor, TRUE, Dacl,
- FALSE);
-
- InitializeObjectAttributes(&ObjectAttributes, NULL, HandleAttributes,
- NULL, &SecurityDescriptor);
-
- Status = SepDuplicateToken(Token, &ObjectAttributes, EffectiveOnly,
- TokenImpersonation, ImpersonationLevel,
- KernelMode, &NewToken);
- ExFreePool(Dacl);
- if (!NT_SUCCESS(Status))
- {
- ObfDereferenceObject(Token);
- if (OpenAsSelf)
+ ObFastDereferenceObject(&NewThread->ThreadsProcess->Token, PrimaryToken);
+
+ if (NT_SUCCESS(Status))
{
- PsRestoreImpersonation(PsGetCurrentThread(), &ImpersonationState);
+ if (Dacl)
+ {
+ RtlCreateSecurityDescriptor(&SecurityDescriptor,
+ SECURITY_DESCRIPTOR_REVISION);
+ RtlSetDaclSecurityDescriptor(&SecurityDescriptor, TRUE, Dacl,
+ FALSE);
+ }
+
+ InitializeObjectAttributes(&ObjectAttributes, NULL, HandleAttributes,
+ NULL, Dacl ? &SecurityDescriptor : NULL);
+
+
+ Status = SepDuplicateToken(Token, &ObjectAttributes, EffectiveOnly,
+ TokenImpersonation, ImpersonationLevel,
+ KernelMode, &NewToken);
+ if (NT_SUCCESS(Status))
+ {
+ ObReferenceObject(NewToken);
+ Status = ObInsertObject(NewToken, NULL, DesiredAccess, 0, NULL,
+ &hToken);
+ }
}
- return Status;
}
-
- Status = ObInsertObject(NewToken, NULL, DesiredAccess, 0, NULL,
- &hToken);
-
}
- else
+ else
{
- Status = ObOpenObjectByPointer(Token, HandleAttributes,
- NULL, DesiredAccess, SepTokenObjectType,
- PreviousMode, &hToken);
+ Status = ObOpenObjectByPointer(Token, HandleAttributes,
+ NULL, DesiredAccess, SepTokenObjectType,
+ PreviousMode, &hToken);
}
-
- ObfDereferenceObject(Token);
-
- if (OpenAsSelf)
+
+ if (Dacl) ExFreePool(Dacl);
+
+ if (OpenAsSelf)
{
- PsRestoreImpersonation(PsGetCurrentThread(), &ImpersonationState);
+ PsRestoreImpersonation(PsGetCurrentThread(), &ImpersonationState);
}
-
- if(NT_SUCCESS(Status))
- {
- _SEH_TRY
+
+ ObDereferenceObject(Token);
+
+ if (NT_SUCCESS(Status) && CopyOnOpen)
{
- *TokenHandle = hToken;
+ PsImpersonateClient(Thread, NewToken, FALSE, EffectiveOnly, ImpersonationLevel);
}
- _SEH_HANDLE
+
+ if (NewToken) ObDereferenceObject(NewToken);
+
+ if (CopyOnOpen && NewThread) ObDereferenceObject(NewThread);
+
+ if(NT_SUCCESS(Status))
{
- Status = _SEH_GetExceptionCode();
+ _SEH2_TRY
+ {
+ *TokenHandle = hToken;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
}
- _SEH_END;
- }
-
- return Status;
+
+ return Status;
}
/*
* @implemented
*/
-NTSTATUS STDCALL
+NTSTATUS NTAPI
NtOpenThreadToken(IN HANDLE ThreadHandle,
IN ACCESS_MASK DesiredAccess,
IN BOOLEAN OpenAsSelf,
OUT PHANDLE TokenHandle)
{
- return NtOpenThreadTokenEx(ThreadHandle, DesiredAccess, OpenAsSelf, 0,
- TokenHandle);
+ return NtOpenThreadTokenEx(ThreadHandle, DesiredAccess, OpenAsSelf, 0,
+ TokenHandle);
}
-static NTSTATUS
-SepCompareTokens(IN PTOKEN FirstToken,
- IN PTOKEN SecondToken,
- OUT PBOOLEAN Equal)
-{
- BOOLEAN Restricted, IsEqual = FALSE;
-
- ASSERT(FirstToken != SecondToken);
-
- /* FIXME: Check if every SID that is present in either token is also present in the other one */
-
- Restricted = SeTokenIsRestricted(FirstToken);
- if (Restricted == SeTokenIsRestricted(SecondToken))
- {
- if (Restricted)
- {
- /* FIXME: Check if every SID that is restricted in either token is also restricted in the other one */
- }
-
- /* FIXME: Check if every privilege that is present in either token is also present in the other one */
- }
- *Equal = IsEqual;
- return STATUS_SUCCESS;
-}
/*
* @unimplemented
KPROCESSOR_MODE PreviousMode;
PTOKEN FirstToken, SecondToken;
BOOLEAN IsEqual;
- NTSTATUS Status = STATUS_SUCCESS;
-
+ NTSTATUS Status;
+
PAGED_CODE();
-
+
PreviousMode = ExGetPreviousMode();
-
+
if (PreviousMode != KernelMode)
{
- _SEH_TRY
+ _SEH2_TRY
{
ProbeForWriteBoolean(Equal);
}
- _SEH_HANDLE
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- Status = _SEH_GetExceptionCode();
+ /* Return the exception code */
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
}
- _SEH_END;
-
- if (!NT_SUCCESS(Status))
- return Status;
+ _SEH2_END;
}
-
+
Status = ObReferenceObjectByHandle(FirstTokenHandle,
TOKEN_QUERY,
SepTokenObjectType,
NULL);
if (!NT_SUCCESS(Status))
return Status;
-
+
Status = ObReferenceObjectByHandle(SecondTokenHandle,
TOKEN_QUERY,
SepTokenObjectType,
ObDereferenceObject(FirstToken);
return Status;
}
-
+
if (FirstToken != SecondToken)
{
Status = SepCompareTokens(FirstToken,
}
else
IsEqual = TRUE;
-
+
ObDereferenceObject(FirstToken);
ObDereferenceObject(SecondToken);
-
+
if (NT_SUCCESS(Status))
{
- _SEH_TRY
+ _SEH2_TRY
{
*Equal = IsEqual;
}
- _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
+ _SEH2_EXCEPT(ExSystemExceptionFilter())
{
- Status = _SEH_GetExceptionCode();
+ Status = _SEH2_GetExceptionCode();
}
- _SEH_END;
+ _SEH2_END;
}
-
+
return Status;
}
return STATUS_NOT_IMPLEMENTED;
}
+/*
+ * @unimplemented
+ */
+NTSTATUS
+NTAPI
+NtImpersonateAnonymousToken(IN HANDLE Thread)
+{
+ UNIMPLEMENTED;
+ return STATUS_NOT_IMPLEMENTED;
+}
+
/* EOF */