_In_ ULONG Index)
{
ULONG TokenFlag;
- NT_ASSERT(Index < Token->PrivilegeCount);
+ ASSERT(Index < Token->PrivilegeCount);
/* The high part of all values we are interested in is 0 */
if (Token->Privileges[Index].Luid.HighPart != 0)
_In_ ULONG Index)
{
ULONG MoveCount;
- NT_ASSERT(Index < Token->PrivilegeCount);
+ ASSERT(Index < Token->PrivilegeCount);
/* Calculate the number of trailing privileges */
MoveCount = Token->PrivilegeCount - Index - 1;
if (OldToken == NewToken)
{
/* So it's a nop. */
- PsDereferencePrimaryToken(OldToken);
+ *OldTokenP = OldToken;
return STATUS_SUCCESS;
}
Status = SepCompareTokens(OldToken, NewToken, &IsEqual);
if (!NT_SUCCESS(Status))
{
+ *OldTokenP = NULL;
PsDereferencePrimaryToken(OldToken);
return Status;
}
- PsDereferencePrimaryToken(OldToken);
- return IsEqual ? STATUS_SUCCESS : STATUS_TOKEN_ALREADY_IN_USE;
+ if (!IsEqual)
+ {
+ *OldTokenP = NULL;
+ PsDereferencePrimaryToken(OldToken);
+ return STATUS_TOKEN_ALREADY_IN_USE;
+ }
+ /* Silently return STATUS_SUCCESS but do not set the new token,
+ * as it's already in use elsewhere. */
+ *OldTokenP = OldToken;
+ return STATUS_SUCCESS;
}
/* Mark new token in use */
/* Zero out the buffer */
RtlZeroMemory(AccessToken, sizeof(TOKEN));
- Status = ZwAllocateLocallyUniqueId(&AccessToken->TokenId);
- if (!NT_SUCCESS(Status))
- {
- ObDereferenceObject(AccessToken);
- return Status;
- }
-
- Status = ZwAllocateLocallyUniqueId(&AccessToken->ModifiedId);
- if (!NT_SUCCESS(Status))
- {
- ObDereferenceObject(AccessToken);
- return Status;
- }
+ ExAllocateLocallyUniqueId(&AccessToken->TokenId);
AccessToken->TokenLock = &SepTokenLock;
AccessToken->TokenType = TokenType;
AccessToken->ImpersonationLevel = Level;
RtlCopyLuid(&AccessToken->AuthenticationId, &Token->AuthenticationId);
+ RtlCopyLuid(&AccessToken->ModifiedId, &Token->ModifiedId);
AccessToken->TokenSource.SourceIdentifier.LowPart = Token->TokenSource.SourceIdentifier.LowPart;
AccessToken->TokenSource.SourceIdentifier.HighPart = Token->TokenSource.SourceIdentifier.HighPart;
ProcessToken = PsReferencePrimaryToken(PsGetCurrentProcess());
/* Get the ID */
- ProcessLuid = ProcessToken->TokenId;
+ ProcessLuid = ProcessToken->AuthenticationId;
/* Dereference the token */
ObFastDereferenceObject(&PsGetCurrentProcess()->Token, ProcessToken);
/* Get our LUID */
- CallerLuid = Token->TokenId;
+ CallerLuid = Token->AuthenticationId;
/* Compare the LUIDs */
if (RtlEqualLuid(&CallerLuid, &ProcessLuid)) *IsChild = TRUE;
}
}
- Status = ZwAllocateLocallyUniqueId(&TokenId);
- if (!NT_SUCCESS(Status))
- return Status;
-
- Status = ZwAllocateLocallyUniqueId(&ModifiedId);
- if (!NT_SUCCESS(Status))
- return Status;
+ ExAllocateLocallyUniqueId(&TokenId);
+ ExAllocateLocallyUniqueId(&ModifiedId);
Status = ObCreateObject(PreviousMode,
SeTokenObjectType,
IN TOKEN_INFORMATION_CLASS TokenInformationClass,
OUT PVOID *TokenInformation)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ NTSTATUS Status;
+ PSECURITY_IMPERSONATION_LEVEL SeImpersonationLvl;
+ PAGED_CODE();
+
+ if (TokenInformationClass >= MaxTokenInfoClass)
+ {
+ DPRINT1("SeQueryInformationToken(%d) invalid information class\n", TokenInformationClass);
+ return STATUS_INVALID_INFO_CLASS;
+ }
+
+ switch (TokenInformationClass)
+ {
+ case TokenImpersonationLevel:
+ /* It is mandatory to have an impersonation token */
+ if (((PTOKEN)Token)->TokenType != TokenImpersonation)
+ {
+ Status = STATUS_INVALID_INFO_CLASS;
+ break;
+ }
+
+ /* Allocate the output buffer */
+ SeImpersonationLvl = ExAllocatePoolWithTag(PagedPool, sizeof(SECURITY_IMPERSONATION_LEVEL), TAG_SE);
+ if (SeImpersonationLvl == NULL)
+ {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ break;
+ }
+
+ /* Set impersonation level and return the structure */
+ *SeImpersonationLvl = ((PTOKEN)Token)->ImpersonationLevel;
+ *TokenInformation = SeImpersonationLvl;
+ Status = STATUS_SUCCESS;
+ break;
+
+ default:
+ UNIMPLEMENTED;
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
+ }
+
+ return Status;
}
/*
ExFreePoolWithTag(Token->DefaultDacl, TAG_TOKEN_ACL);
}
- /* Set the new dacl */
- Token->DefaultDacl = CapturedAcl;
+ Token->DefaultDacl = ExAllocatePoolWithTag(PagedPool,
+ CapturedAcl->AclSize,
+ TAG_TOKEN_ACL);
+ if (!Token->DefaultDacl)
+ {
+ ExFreePoolWithTag(CapturedAcl, TAG_ACL);
+ Status = STATUS_NO_MEMORY;
+ }
+ else
+ {
+ /* Set the new dacl */
+ RtlCopyMemory(Token->DefaultDacl, CapturedAcl, CapturedAcl->AclSize);
+ ExFreePoolWithTag(CapturedAcl, TAG_ACL);
+ }
}
}
else
NonPagedPool,
FALSE,
&CapturedDefaultDacl);
+ if (!NT_SUCCESS(Status))
+ {
+ goto Cleanup;
+ }
}
/* Call the internal function */
_SEH2_END;
}
+ /* Validate object attributes */
+ HandleAttributes = ObpValidateAttributes(HandleAttributes, PreviousMode);
+
/*
* At first open the thread token for information access and verify
- * that the token associated with thread is valid.
- */
+ * that the token associated with thread is valid. */
Status = ObReferenceObjectByHandle(ThreadHandle, THREAD_QUERY_INFORMATION,
PsThreadType, PreviousMode, (PVOID*)&Thread,
if (CopyOnOpen && NewThread) ObDereferenceObject(NewThread);
+ ObDereferenceObject(Thread);
+
if (NT_SUCCESS(Status))
{
_SEH2_TRY