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,
NTSTATUS
-STDCALL
+NTAPI
SepDuplicateToken(PTOKEN Token,
POBJECT_ATTRIBUTES ObjectAttributes,
BOOLEAN EffectiveOnly,
(PVOID*)&AccessToken);
if (!NT_SUCCESS(Status))
{
- DPRINT1("ObCreateObject() failed (Status %lx)\n");
+ DPRINT1("ObCreateObject() failed (Status %lx)\n", Status);
return(Status);
}
-
+
+ /* Zero out the buffer */
+ RtlZeroMemory(AccessToken, sizeof(TOKEN));
+
Status = ZwAllocateLocallyUniqueId(&AccessToken->TokenId);
if (!NT_SUCCESS(Status))
{
AccessToken->TokenLock = &SepTokenLock;
- AccessToken->TokenInUse = 0;
AccessToken->TokenType = TokenType;
AccessToken->ImpersonationLevel = Level;
RtlCopyLuid(&AccessToken->AuthenticationId, &Token->AuthenticationId);
AccessToken->UserAndGroups =
(PSID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool,
uLength,
- TAG('T', 'O', 'K', 'u'));
+ 'uKOT');
EndMem = &AccessToken->UserAndGroups[AccessToken->UserAndGroupCount];
AccessToken->Privileges =
(PLUID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool,
uLength,
- TAG('T', 'O', 'K', 'p'));
+ 'pKOT');
for (i = 0; i < AccessToken->PrivilegeCount; i++)
{
AccessToken->DefaultDacl =
(PACL) ExAllocatePoolWithTag(PagedPool,
Token->DefaultDacl->AclSize,
- TAG('T', 'O', 'K', 'd'));
+ 'kDOT');
memcpy(AccessToken->DefaultDacl,
Token->DefaultDacl,
Token->DefaultDacl->AclSize);
}
- else
- {
- AccessToken->DefaultDacl = 0;
- }
}
if ( NT_SUCCESS(Status) )
}
NTSTATUS
-STDCALL
+NTAPI
SeCopyClientToken(IN PACCESS_TOKEN Token,
IN SECURITY_IMPERSONATION_LEVEL Level,
IN KPROCESSOR_MODE PreviousMode,
return(Status);
}
-VOID STDCALL
+VOID NTAPI
SepDeleteToken(PVOID ObjectBody)
{
PTOKEN AccessToken = (PTOKEN)ObjectBody;
ObInitializeFastReference(&Process->Token, Token);
}
-PTOKEN
-STDCALL
-SepCreateSystemProcessToken(VOID)
-{
- NTSTATUS Status;
- ULONG uSize;
- ULONG i;
- ULONG uLocalSystemLength;
- ULONG uWorldLength;
- ULONG uAuthUserLength;
- ULONG uAdminsLength;
+
+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;
- PVOID SidArea;
+ LUID TokenId;
+ LUID ModifiedId;
+ PVOID EndMem;
+ ULONG uLength;
+ ULONG i;
+ NTSTATUS Status;
+ ULONG TokenFlags = 0;
- PAGED_CODE();
+ /* Loop all groups */
+ for (i = 0; i < GroupCount; i++)
+ {
+ /* Check for mandatory groups */
+ if (Groups[i].Attributes & SE_GROUP_MANDATORY)
+ {
+ /* Force them to be enabled */
+ Groups[i].Attributes |= (SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT);
+ }
+
+ /* Check of the group is an admin group */
+ if (RtlEqualSid(SeAliasAdminsSid, Groups[i].Sid))
+ {
+ /* Remember this so we can optimize queries later */
+ TokenFlags |= TOKEN_HAS_ADMIN_GROUP;
+ }
+ }
- uLocalSystemLength = RtlLengthSid(SeLocalSystemSid);
- uWorldLength = RtlLengthSid(SeWorldSid);
- uAuthUserLength = RtlLengthSid(SeAuthenticatedUserSid);
- uAdminsLength = RtlLengthSid(SeAliasAdminsSid);
+ /* 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)))
+ {
+ /* Remember token has traverse */
+ TokenFlags |= TOKEN_HAS_TRAVERSE_PRIVILEGE;
+ }
+ }
+
+ Status = ZwAllocateLocallyUniqueId(&TokenId);
+ if (!NT_SUCCESS(Status))
+ return(Status);
- /*
- * Initialize the token
- */
- Status = ObCreateObject(KernelMode,
+ Status = ZwAllocateLocallyUniqueId(&ModifiedId);
+ if (!NT_SUCCESS(Status))
+ return(Status);
+
+ Status = ObCreateObject(PreviousMode,
SepTokenObjectType,
- NULL,
- KernelMode,
+ ObjectAttributes,
+ PreviousMode,
NULL,
sizeof(TOKEN),
0,
(PVOID*)&AccessToken);
if (!NT_SUCCESS(Status))
{
- return NULL;
+ DPRINT1("ObCreateObject() failed (Status %lx)\n");
+ return(Status);
}
+
+ /* Zero out the buffer */
+ RtlZeroMemory(AccessToken, sizeof(TOKEN));
- Status = ExpAllocateLocallyUniqueId(&AccessToken->TokenId);
- if (!NT_SUCCESS(Status))
- {
- ObDereferenceObject(AccessToken);
- return NULL;
- }
+ AccessToken->TokenLock = &SepTokenLock;
- Status = ExpAllocateLocallyUniqueId(&AccessToken->ModifiedId);
- if (!NT_SUCCESS(Status))
- {
- ObDereferenceObject(AccessToken);
- return NULL;
- }
+ RtlCopyLuid(&AccessToken->TokenSource.SourceIdentifier,
+ &TokenSource->SourceIdentifier);
+ memcpy(AccessToken->TokenSource.SourceName,
+ TokenSource->SourceName,
+ sizeof(TokenSource->SourceName));
- Status = ExpAllocateLocallyUniqueId(&AccessToken->AuthenticationId);
- if (!NT_SUCCESS(Status))
- {
- ObDereferenceObject(AccessToken);
- return NULL;
- }
+ RtlCopyLuid(&AccessToken->TokenId, &TokenId);
+ RtlCopyLuid(&AccessToken->AuthenticationId, AuthenticationId);
+ AccessToken->ExpirationTime = *ExpirationTime;
+ RtlCopyLuid(&AccessToken->ModifiedId, &ModifiedId);
- AccessToken->TokenLock = &SepTokenLock;
+ AccessToken->UserAndGroupCount = GroupCount + 1;
+ AccessToken->PrivilegeCount = PrivilegeCount;
- 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;
+ AccessToken->TokenFlags = TokenFlags;
+ AccessToken->TokenType = TokenType;
+ AccessToken->ImpersonationLevel = ImpersonationLevel;
- uSize = sizeof(SID_AND_ATTRIBUTES) * AccessToken->UserAndGroupCount;
- uSize += uLocalSystemLength;
- uSize += uWorldLength;
- uSize += uAuthUserLength;
- uSize += uAdminsLength;
+ /*
+ * 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,
- uSize,
- TAG('T', 'O', 'K', 'u'));
- SidArea = &AccessToken->UserAndGroups[AccessToken->UserAndGroupCount];
+ uLength,
+ 'uKOT');
- 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'));
+ EndMem = &AccessToken->UserAndGroups[AccessToken->UserAndGroupCount];
- i = 0;
- AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED;
- AccessToken->Privileges[i++].Luid = SeTcbPrivilege;
+ 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);
+ }
- AccessToken->Privileges[i].Attributes = 0;
- AccessToken->Privileges[i++].Luid = SeCreateTokenPrivilege;
+ if (NT_SUCCESS(Status))
+ {
+ uLength = PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES);
+ AccessToken->Privileges =
+ (PLUID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool,
+ uLength,
+ 'pKOT');
+
+ if (PreviousMode != KernelMode)
+ {
+ _SEH2_TRY
+ {
+ RtlCopyMemory(AccessToken->Privileges,
+ Privileges,
+ PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES));
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+ }
+ else
+ {
+ RtlCopyMemory(AccessToken->Privileges,
+ Privileges,
+ PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES));
+ }
+ }
- AccessToken->Privileges[i].Attributes = 0;
- AccessToken->Privileges[i++].Luid = SeTakeOwnershipPrivilege;
+ if (NT_SUCCESS(Status))
+ {
+ AccessToken->DefaultDacl =
+ (PACL) ExAllocatePoolWithTag(PagedPool,
+ DefaultDacl->AclSize,
+ 'kDOT');
+ memcpy(AccessToken->DefaultDacl,
+ DefaultDacl,
+ DefaultDacl->AclSize);
+ }
- AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED;
- AccessToken->Privileges[i++].Luid = SeCreatePagefilePrivilege;
+ if (!SystemToken)
+ {
+
+ Status = ObInsertObject ((PVOID)AccessToken,
+ NULL,
+ DesiredAccess,
+ 0,
+ NULL,
+ TokenHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("ObInsertObject() failed (Status %lx)\n", Status);
+ }
+ }
+ else
+ {
+ /* Return pointer instead of handle */
+ *TokenHandle = (HANDLE)AccessToken;
+ }
+
+ 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;
- AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED;
- AccessToken->Privileges[i++].Luid = SeLockMemoryPrivilege;
+ /* 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;
- AccessToken->Privileges[i].Attributes = 0;
- AccessToken->Privileges[i++].Luid = SeAssignPrimaryTokenPrivilege;
+ Privileges[i].Attributes = 0;
+ Privileges[i++].Luid = SeCreateTokenPrivilege;
- AccessToken->Privileges[i].Attributes = 0;
- AccessToken->Privileges[i++].Luid = SeIncreaseQuotaPrivilege;
+ Privileges[i].Attributes = 0;
+ Privileges[i++].Luid = SeTakeOwnershipPrivilege;
- AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED;
- AccessToken->Privileges[i++].Luid = SeIncreaseBasePriorityPrivilege;
+ Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED;
+ Privileges[i++].Luid = SeCreatePagefilePrivilege;
- AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED;
- AccessToken->Privileges[i++].Luid = SeCreatePermanentPrivilege;
+ Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED;
+ Privileges[i++].Luid = SeLockMemoryPrivilege;
- AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED;
- AccessToken->Privileges[i++].Luid = SeDebugPrivilege;
+ Privileges[i].Attributes = 0;
+ Privileges[i++].Luid = SeAssignPrimaryTokenPrivilege;
- AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED;
- AccessToken->Privileges[i++].Luid = SeAuditPrivilege;
+ Privileges[i].Attributes = 0;
+ Privileges[i++].Luid = SeIncreaseQuotaPrivilege;
- AccessToken->Privileges[i].Attributes = 0;
- AccessToken->Privileges[i++].Luid = SeSecurityPrivilege;
+ Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED;
+ Privileges[i++].Luid = SeIncreaseBasePriorityPrivilege;
- AccessToken->Privileges[i].Attributes = 0;
- AccessToken->Privileges[i++].Luid = SeSystemEnvironmentPrivilege;
+ Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED;
+ Privileges[i++].Luid = SeCreatePermanentPrivilege;
- AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED;
- AccessToken->Privileges[i++].Luid = SeChangeNotifyPrivilege;
+ Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED;
+ Privileges[i++].Luid = SeDebugPrivilege;
- AccessToken->Privileges[i].Attributes = 0;
- AccessToken->Privileges[i++].Luid = SeBackupPrivilege;
+ Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED;
+ Privileges[i++].Luid = SeAuditPrivilege;
- AccessToken->Privileges[i].Attributes = 0;
- AccessToken->Privileges[i++].Luid = SeRestorePrivilege;
+ Privileges[i].Attributes = 0;
+ Privileges[i++].Luid = SeSecurityPrivilege;
- AccessToken->Privileges[i].Attributes = 0;
- AccessToken->Privileges[i++].Luid = SeShutdownPrivilege;
+ Privileges[i].Attributes = 0;
+ Privileges[i++].Luid = SeSystemEnvironmentPrivilege;
- AccessToken->Privileges[i].Attributes = 0;
- AccessToken->Privileges[i++].Luid = SeLoadDriverPrivilege;
+ Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED;
+ Privileges[i++].Luid = SeChangeNotifyPrivilege;
- AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED;
- AccessToken->Privileges[i++].Luid = SeProfileSingleProcessPrivilege;
+ Privileges[i].Attributes = 0;
+ Privileges[i++].Luid = SeBackupPrivilege;
- AccessToken->Privileges[i].Attributes = 0;
- AccessToken->Privileges[i++].Luid = SeSystemtimePrivilege;
-#if 0
- AccessToken->Privileges[i].Attributes = 0;
- AccessToken->Privileges[i++].Luid = SeUndockPrivilege;
+ Privileges[i].Attributes = 0;
+ Privileges[i++].Luid = SeRestorePrivilege;
- AccessToken->Privileges[i].Attributes = 0;
- AccessToken->Privileges[i++].Luid = SeManageVolumePrivilege;
-#endif
+ Privileges[i].Attributes = 0;
+ Privileges[i++].Luid = SeShutdownPrivilege;
- ASSERT(i == 20);
+ Privileges[i].Attributes = 0;
+ Privileges[i++].Luid = SeLoadDriverPrivilege;
- 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);
- }
+ Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED;
+ Privileges[i++].Luid = SeProfileSingleProcessPrivilege;
- if ( NT_SUCCESS(Status) )
- {
- Status = RtlAddAccessAllowedAce(AccessToken->DefaultDacl, ACL_REVISION, GENERIC_READ|GENERIC_WRITE|GENERIC_EXECUTE|READ_CONTROL, SeAliasAdminsSid);
- }
+ Privileges[i].Attributes = 0;
+ Privileges[i++].Luid = SeSystemtimePrivilege;
+ ASSERT(i == 20);
- if ( ! NT_SUCCESS(Status) )
- {
- ObDereferenceObject(AccessToken);
- return NULL;
- }
+ /* Setup the object attributes */
+ InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL);
+ ASSERT(SeSystemDefaultDacl != NULL);
- return AccessToken;
+ /* 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;
}
/* PUBLIC FUNCTIONS ***********************************************************/
* @unimplemented
*/
NTSTATUS
-STDCALL
+NTAPI
SeFilterToken(IN PACCESS_TOKEN ExistingToken,
IN ULONG Flags,
IN PTOKEN_GROUPS SidsToDisable OPTIONAL,
* @unimplemented
*/
NTSTATUS
-STDCALL
+NTAPI
SeQueryInformationToken(IN PACCESS_TOKEN Token,
IN TOKEN_INFORMATION_CLASS TokenInformationClass,
OUT PVOID *TokenInformation)
* @implemented
*/
NTSTATUS
-STDCALL
+NTAPI
SeQuerySessionIdToken(IN PACCESS_TOKEN Token,
IN PULONG pSessionId)
{
/*
* @implemented
*/
-NTSTATUS STDCALL
+NTSTATUS NTAPI
SeQueryAuthenticationIdToken(IN PACCESS_TOKEN Token,
OUT PLUID LogonId)
{
* @implemented
*/
SECURITY_IMPERSONATION_LEVEL
-STDCALL
+NTAPI
SeTokenImpersonationLevel(IN PACCESS_TOKEN Token)
{
PAGED_CODE();
/*
* @implemented
*/
-TOKEN_TYPE STDCALL
+TOKEN_TYPE NTAPI
SeTokenType(IN PACCESS_TOKEN Token)
{
PAGED_CODE();
* @implemented
*/
BOOLEAN
-STDCALL
+NTAPI
SeTokenIsAdmin(IN PACCESS_TOKEN Token)
{
PAGED_CODE();
* @implemented
*/
BOOLEAN
-STDCALL
+NTAPI
SeTokenIsRestricted(IN PACCESS_TOKEN Token)
{
PAGED_CODE();
* @implemented
*/
BOOLEAN
-STDCALL
+NTAPI
SeTokenIsWriteRestricted(IN PACCESS_TOKEN Token)
{
PAGED_CODE();
/*
* @implemented
*/
-NTSTATUS STDCALL
+NTSTATUS NTAPI
NtQueryInformationToken(IN HANDLE TokenHandle,
IN TOKEN_INFORMATION_CLASS TokenInformationClass,
OUT PVOID TokenInformation,
TokenInformation,
TokenInformationLength,
ReturnLength,
+ NULL,
PreviousMode);
if(!NT_SUCCESS(Status))
RequiredLength = sizeof(TOKEN_USER) +
RtlLengthSid(Token->UserAndGroups[0].Sid);
- _SEH_TRY
+ _SEH2_TRY
{
if(TokenInformationLength >= RequiredLength)
{
*ReturnLength = RequiredLength;
}
}
- _SEH_HANDLE
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- Status = _SEH_GetExceptionCode();
+ Status = _SEH2_GetExceptionCode();
}
- _SEH_END;
+ _SEH2_END;
break;
}
RequiredLength = sizeof(tg->GroupCount) +
RtlLengthSidAndAttributes(Token->UserAndGroupCount - 1, &Token->UserAndGroups[1]);
- _SEH_TRY
+ _SEH2_TRY
{
if(TokenInformationLength >= RequiredLength)
{
*ReturnLength = RequiredLength;
}
}
- _SEH_HANDLE
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- Status = _SEH_GetExceptionCode();
+ Status = _SEH2_GetExceptionCode();
}
- _SEH_END;
+ _SEH2_END;
break;
}
RequiredLength = sizeof(tp->PrivilegeCount) +
(Token->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES));
- _SEH_TRY
+ _SEH2_TRY
{
if(TokenInformationLength >= RequiredLength)
{
*ReturnLength = RequiredLength;
}
}
- _SEH_HANDLE
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- Status = _SEH_GetExceptionCode();
+ Status = _SEH2_GetExceptionCode();
}
- _SEH_END;
+ _SEH2_END;
break;
}
SidLen = RtlLengthSid(Token->UserAndGroups[Token->DefaultOwnerIndex].Sid);
RequiredLength = sizeof(TOKEN_OWNER) + SidLen;
- _SEH_TRY
+ _SEH2_TRY
{
if(TokenInformationLength >= RequiredLength)
{
*ReturnLength = RequiredLength;
}
}
- _SEH_HANDLE
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- Status = _SEH_GetExceptionCode();
+ Status = _SEH2_GetExceptionCode();
}
- _SEH_END;
+ _SEH2_END;
break;
}
SidLen = RtlLengthSid(Token->PrimaryGroup);
RequiredLength = sizeof(TOKEN_PRIMARY_GROUP) + SidLen;
- _SEH_TRY
+ _SEH2_TRY
{
if(TokenInformationLength >= RequiredLength)
{
*ReturnLength = RequiredLength;
}
}
- _SEH_HANDLE
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- Status = _SEH_GetExceptionCode();
+ Status = _SEH2_GetExceptionCode();
}
- _SEH_END;
+ _SEH2_END;
break;
}
RequiredLength += Token->DefaultDacl->AclSize;
}
- _SEH_TRY
+ _SEH2_TRY
{
if(TokenInformationLength >= RequiredLength)
{
*ReturnLength = RequiredLength;
}
}
- _SEH_HANDLE
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- Status = _SEH_GetExceptionCode();
+ Status = _SEH2_GetExceptionCode();
}
- _SEH_END;
+ _SEH2_END;
break;
}
DPRINT("NtQueryInformationToken(TokenSource)\n");
RequiredLength = sizeof(TOKEN_SOURCE);
- _SEH_TRY
+ _SEH2_TRY
{
if(TokenInformationLength >= RequiredLength)
{
*ReturnLength = RequiredLength;
}
}
- _SEH_HANDLE
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- Status = _SEH_GetExceptionCode();
+ Status = _SEH2_GetExceptionCode();
}
- _SEH_END;
+ _SEH2_END;
break;
}
DPRINT("NtQueryInformationToken(TokenType)\n");
RequiredLength = sizeof(TOKEN_TYPE);
- _SEH_TRY
+ _SEH2_TRY
{
if(TokenInformationLength >= RequiredLength)
{
*ReturnLength = RequiredLength;
}
}
- _SEH_HANDLE
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- Status = _SEH_GetExceptionCode();
+ Status = _SEH2_GetExceptionCode();
}
- _SEH_END;
+ _SEH2_END;
break;
}
PSECURITY_IMPERSONATION_LEVEL sil = (PSECURITY_IMPERSONATION_LEVEL)TokenInformation;
DPRINT("NtQueryInformationToken(TokenImpersonationLevel)\n");
+
+ /* Fail if the token is not an impersonation token */
+ if (Token->TokenType != TokenImpersonation)
+ {
+ Status = STATUS_INVALID_INFO_CLASS;
+ break;
+ }
+
RequiredLength = sizeof(SECURITY_IMPERSONATION_LEVEL);
- _SEH_TRY
+ _SEH2_TRY
{
if(TokenInformationLength >= RequiredLength)
{
*ReturnLength = RequiredLength;
}
}
- _SEH_HANDLE
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- Status = _SEH_GetExceptionCode();
+ Status = _SEH2_GetExceptionCode();
}
- _SEH_END;
+ _SEH2_END;
break;
}
DPRINT("NtQueryInformationToken(TokenStatistics)\n");
RequiredLength = sizeof(TOKEN_STATISTICS);
- _SEH_TRY
+ _SEH2_TRY
{
if(TokenInformationLength >= RequiredLength)
{
*ReturnLength = RequiredLength;
}
}
- _SEH_HANDLE
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- Status = _SEH_GetExceptionCode();
+ Status = _SEH2_GetExceptionCode();
}
- _SEH_END;
+ _SEH2_END;
break;
}
DPRINT("NtQueryInformationToken(TokenOrigin)\n");
RequiredLength = sizeof(TOKEN_ORIGIN);
- _SEH_TRY
+ _SEH2_TRY
{
if(TokenInformationLength >= RequiredLength)
{
*ReturnLength = RequiredLength;
}
}
- _SEH_HANDLE
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- Status = _SEH_GetExceptionCode();
+ Status = _SEH2_GetExceptionCode();
}
- _SEH_END;
+ _SEH2_END;
break;
}
RequiredLength = sizeof(tg->GroupCount) +
RtlLengthSidAndAttributes(Token->RestrictedSidCount, Token->RestrictedSids);
- _SEH_TRY
+ _SEH2_TRY
{
if(TokenInformationLength >= RequiredLength)
{
*ReturnLength = RequiredLength;
}
}
- _SEH_HANDLE
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- Status = _SEH_GetExceptionCode();
+ Status = _SEH2_GetExceptionCode();
}
- _SEH_END;
+ _SEH2_END;
break;
}
if(NT_SUCCESS(Status))
{
- _SEH_TRY
+ _SEH2_TRY
{
/* buffer size was already verified, no need to check here again */
*(PULONG)TokenInformation = SessionId;
*ReturnLength = sizeof(ULONG);
}
}
- _SEH_HANDLE
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- Status = _SEH_GetExceptionCode();
+ Status = _SEH2_GetExceptionCode();
}
- _SEH_END;
+ _SEH2_END;
}
break;
* TokenOrigin, TokenDefaultDacl
*/
-NTSTATUS STDCALL
+NTSTATUS NTAPI
NtSetInformationToken(IN HANDLE TokenHandle,
IN TOKEN_INFORMATION_CLASS TokenInformationClass,
OUT PVOID TokenInformation,
PTOKEN Token;
KPROCESSOR_MODE PreviousMode;
ULONG NeededAccess = TOKEN_ADJUST_DEFAULT;
- NTSTATUS Status = STATUS_SUCCESS;
+ NTSTATUS Status;
PAGED_CODE();
if(TokenInformationLength >= sizeof(TOKEN_OWNER))
{
PTOKEN_OWNER to = (PTOKEN_OWNER)TokenInformation;
- PSID InputSid = NULL;
+ PSID InputSid = NULL, CapturedSid;
- _SEH_TRY
+ _SEH2_TRY
{
InputSid = to->Owner;
}
- _SEH_HANDLE
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- Status = _SEH_GetExceptionCode();
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
}
- _SEH_END;
+ _SEH2_END;
+ Status = SepCaptureSid(InputSid,
+ PreviousMode,
+ PagedPool,
+ FALSE,
+ &CapturedSid);
if(NT_SUCCESS(Status))
{
- PSID CapturedSid;
-
- Status = SepCaptureSid(InputSid,
- PreviousMode,
- PagedPool,
- FALSE,
- &CapturedSid);
- if(NT_SUCCESS(Status))
- {
- RtlCopySid(RtlLengthSid(CapturedSid),
- Token->UserAndGroups[Token->DefaultOwnerIndex].Sid,
- CapturedSid);
- SepReleaseSid(CapturedSid,
- PreviousMode,
- FALSE);
- }
+ RtlCopySid(RtlLengthSid(CapturedSid),
+ Token->UserAndGroups[Token->DefaultOwnerIndex].Sid,
+ CapturedSid);
+ SepReleaseSid(CapturedSid,
+ PreviousMode,
+ FALSE);
}
}
else
if(TokenInformationLength >= sizeof(TOKEN_PRIMARY_GROUP))
{
PTOKEN_PRIMARY_GROUP tpg = (PTOKEN_PRIMARY_GROUP)TokenInformation;
- PSID InputSid = NULL;
+ PSID InputSid = NULL, CapturedSid;
- _SEH_TRY
+ _SEH2_TRY
{
InputSid = tpg->PrimaryGroup;
}
- _SEH_HANDLE
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- Status = _SEH_GetExceptionCode();
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
}
- _SEH_END;
+ _SEH2_END;
+ Status = SepCaptureSid(InputSid,
+ PreviousMode,
+ PagedPool,
+ FALSE,
+ &CapturedSid);
if(NT_SUCCESS(Status))
{
- PSID CapturedSid;
-
- Status = SepCaptureSid(InputSid,
- PreviousMode,
- PagedPool,
- FALSE,
- &CapturedSid);
- if(NT_SUCCESS(Status))
- {
- RtlCopySid(RtlLengthSid(CapturedSid),
- Token->PrimaryGroup,
- CapturedSid);
- SepReleaseSid(CapturedSid,
- PreviousMode,
- FALSE);
- }
+ RtlCopySid(RtlLengthSid(CapturedSid),
+ Token->PrimaryGroup,
+ CapturedSid);
+ SepReleaseSid(CapturedSid,
+ PreviousMode,
+ FALSE);
}
}
else
PTOKEN_DEFAULT_DACL tdd = (PTOKEN_DEFAULT_DACL)TokenInformation;
PACL InputAcl = NULL;
- _SEH_TRY
+ _SEH2_TRY
{
InputAcl = tdd->DefaultDacl;
}
- _SEH_HANDLE
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- Status = _SEH_GetExceptionCode();
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
}
- _SEH_END;
-
- if(NT_SUCCESS(Status))
+ _SEH2_END;
+
+ 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
+ PACL CapturedAcl;
+
+ /* capture and copy the dacl */
+ Status = SepCaptureAcl(InputAcl,
+ PreviousMode,
+ PagedPool,
+ TRUE,
+ &CapturedAcl);
+ if(NT_SUCCESS(Status))
{
- /* clear and free the default dacl if present */
+ /* free the previous dacl if present */
if(Token->DefaultDacl != NULL)
{
ExFreePool(Token->DefaultDacl);
- Token->DefaultDacl = NULL;
}
+
+ /* 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;
}
}
}
{
ULONG SessionId = 0;
- _SEH_TRY
+ _SEH2_TRY
{
/* buffer size was already verified, no need to check here again */
SessionId = *(PULONG)TokenInformation;
}
- _SEH_HANDLE
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- Status = _SEH_GetExceptionCode();
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
}
- _SEH_END;
+ _SEH2_END;
- if(NT_SUCCESS(Status))
+ if(!SeSinglePrivilegeCheck(SeTcbPrivilege,
+ PreviousMode))
{
- if(!SeSinglePrivilegeCheck(SeTcbPrivilege,
- PreviousMode))
- {
- Status = STATUS_PRIVILEGE_NOT_HELD;
- break;
- }
-
- Token->SessionId = SessionId;
+ Status = STATUS_PRIVILEGE_NOT_HELD;
+ break;
}
+
+ Token->SessionId = SessionId;
break;
}
* 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,
PTOKEN NewToken;
PSECURITY_QUALITY_OF_SERVICE CapturedSecurityQualityOfService;
BOOLEAN QoSPresent;
- NTSTATUS Status = STATUS_SUCCESS;
+ NTSTATUS Status;
PAGED_CODE();
PreviousMode = KeGetPreviousMode();
- if(PreviousMode != KernelMode)
+ if (PreviousMode != KernelMode)
{
- _SEH_TRY
+ _SEH2_TRY
{
ProbeForWriteHandle(NewTokenHandle);
}
- _SEH_HANDLE
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- if(!NT_SUCCESS(Status))
- {
- return Status;
+ /* Return the exception code */
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
}
+ _SEH2_END;
}
Status = SepCaptureSecurityQualityOfService(ObjectAttributes,
if (NT_SUCCESS(Status))
{
- _SEH_TRY
+ _SEH2_TRY
{
*NewTokenHandle = hToken;
}
- _SEH_HANDLE
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- Status = _SEH_GetExceptionCode();
+ Status = _SEH2_GetExceptionCode();
}
- _SEH_END;
+ _SEH2_END;
}
}
}
return Status;
}
-NTSTATUS STDCALL
+NTSTATUS NTAPI
NtAdjustGroupsToken(IN HANDLE TokenHandle,
IN BOOLEAN ResetToDefault,
IN PTOKEN_GROUPS NewState,
/*
* @implemented
*/
-NTSTATUS STDCALL
+NTSTATUS NTAPI
NtAdjustPrivilegesToken (IN HANDLE TokenHandle,
IN BOOLEAN DisableAllPrivileges,
IN PTOKEN_PRIVILEGES NewState,
return Status;
}
-NTSTATUS STDCALL
+NTSTATUS
+NTAPI
NtCreateToken(OUT PHANDLE TokenHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
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;
+ LARGE_INTEGER LocalExpirationTime = {{0, 0}};
+ NTSTATUS Status;
PAGED_CODE();
if(PreviousMode != KernelMode)
{
- _SEH_TRY
+ _SEH2_TRY
{
ProbeForWriteHandle(TokenHandle);
ProbeForRead(AuthenticationId,
sizeof(ULONG));
nTokenPrivileges = TokenPrivileges->PrivilegeCount;
}
- _SEH_HANDLE
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- if(!NT_SUCCESS(Status))
- {
- return Status;
+ /* Return the exception code */
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
}
+ _SEH2_END;
}
else
{
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,
+ Status = SepCreateToken(&hToken,
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);
- }
-
- if (NT_SUCCESS(Status))
- {
- Status = SepFindPrimaryGroupAndDefaultOwner(
- AccessToken,
- TokenPrimaryGroup->PrimaryGroup,
- TokenOwner->Owner);
- }
-
- if (NT_SUCCESS(Status))
- {
- uLength = TokenPrivileges->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES);
- AccessToken->Privileges =
- (PLUID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool,
- uLength,
- TAG('T', 'O', 'K', 'p'));
-
- if (PreviousMode != KernelMode)
- {
- _SEH_TRY
- {
- RtlCopyMemory(AccessToken->Privileges,
- TokenPrivileges->Privileges,
- nTokenPrivileges * sizeof(LUID_AND_ATTRIBUTES));
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
- }
- else
- {
- RtlCopyMemory(AccessToken->Privileges,
- TokenPrivileges->Privileges,
- nTokenPrivileges * sizeof(LUID_AND_ATTRIBUTES));
- }
- }
-
- 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))
- {
- DPRINT1("ObInsertObject() failed (Status %lx)\n", Status);
- }
-
+ 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
+ _SEH2_TRY
{
*TokenHandle = hToken;
}
- _SEH_HANDLE
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- Status = _SEH_GetExceptionCode();
+ Status = _SEH2_GetExceptionCode();
}
- _SEH_END;
+ _SEH2_END;
}
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;
+ PETHREAD Thread, NewThread;
HANDLE hToken;
- PTOKEN Token, NewToken, PrimaryToken;
+ PTOKEN Token, NewToken = NULL, PrimaryToken;
BOOLEAN CopyOnOpen, EffectiveOnly;
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
SE_IMPERSONATION_STATE ImpersonationState;
SECURITY_DESCRIPTOR SecurityDescriptor;
PACL Dacl = NULL;
KPROCESSOR_MODE PreviousMode;
- NTSTATUS Status = STATUS_SUCCESS;
+ NTSTATUS Status;
PAGED_CODE();
PreviousMode = ExGetPreviousMode();
- if(PreviousMode != KernelMode)
+ if (PreviousMode != KernelMode)
{
- _SEH_TRY
+ _SEH2_TRY
{
ProbeForWriteHandle(TokenHandle);
}
- _SEH_HANDLE
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- if(!NT_SUCCESS(Status))
- {
- return Status;
+ /* Return the exception code */
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
}
+ _SEH2_END;
}
/*
&ImpersonationLevel);
if (Token == NULL)
{
- ObfDereferenceObject(Thread);
+ ObDereferenceObject(Thread);
return STATUS_NO_TOKEN;
}
-
- ObDereferenceObject(Thread);
-
+
if (ImpersonationLevel == SecurityAnonymous)
{
- ObfDereferenceObject(Token);
+ PsDereferenceImpersonationToken(Token);
+ ObDereferenceObject(Thread);
return STATUS_CANT_OPEN_ANONYMOUS;
}
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);
- ASSERT(FALSE);
- ObfDereferenceObject(PrimaryToken);
- ObfDereferenceObject(Thread);
- if (!NT_SUCCESS(Status))
+ PsThreadType, KernelMode,
+ (PVOID*)&NewThread, NULL);
+ if (NT_SUCCESS(Status))
{
- ObfDereferenceObject(Token);
- if (OpenAsSelf)
+ PrimaryToken = PsReferencePrimaryToken(NewThread->ThreadsProcess);
+
+ Status = SepCreateImpersonationTokenDacl(Token, PrimaryToken, &Dacl);
+
+ ObFastDereferenceObject(&NewThread->ThreadsProcess->Token, PrimaryToken);
+
+ if (NT_SUCCESS(Status))
{
- PsRestoreImpersonation(PsGetCurrentThread(), &ImpersonationState);
- }
- return Status;
- }
-
- RtlCreateSecurityDescriptor(&SecurityDescriptor,
- SECURITY_DESCRIPTOR_REVISION);
- RtlSetDaclSecurityDescriptor(&SecurityDescriptor, TRUE, Dacl,
- FALSE);
-
- InitializeObjectAttributes(&ObjectAttributes, NULL, HandleAttributes,
- NULL, &SecurityDescriptor);
+ if (Dacl)
+ {
+ RtlCreateSecurityDescriptor(&SecurityDescriptor,
+ SECURITY_DESCRIPTOR_REVISION);
+ RtlSetDaclSecurityDescriptor(&SecurityDescriptor, TRUE, Dacl,
+ FALSE);
+ }
- Status = SepDuplicateToken(Token, &ObjectAttributes, EffectiveOnly,
- TokenImpersonation, ImpersonationLevel,
- KernelMode, &NewToken);
- ExFreePool(Dacl);
- if (!NT_SUCCESS(Status))
- {
- ObfDereferenceObject(Token);
- if (OpenAsSelf)
- {
- PsRestoreImpersonation(PsGetCurrentThread(), &ImpersonationState);
+ 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
{
PreviousMode, &hToken);
}
- ObfDereferenceObject(Token);
+ if (Dacl) ExFreePool(Dacl);
if (OpenAsSelf)
{
PsRestoreImpersonation(PsGetCurrentThread(), &ImpersonationState);
}
+ ObDereferenceObject(Token);
+
+ if (NT_SUCCESS(Status) && CopyOnOpen)
+ {
+ PsImpersonateClient(Thread, NewToken, FALSE, EffectiveOnly, ImpersonationLevel);
+ }
+
+ if (NewToken) ObDereferenceObject(NewToken);
+
+ if (CopyOnOpen && NewThread) ObDereferenceObject(NewThread);
+
if(NT_SUCCESS(Status))
{
- _SEH_TRY
+ _SEH2_TRY
{
*TokenHandle = hToken;
}
- _SEH_HANDLE
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- Status = _SEH_GetExceptionCode();
+ Status = _SEH2_GetExceptionCode();
}
- _SEH_END;
+ _SEH2_END;
}
return Status;
/*
* @implemented
*/
-NTSTATUS STDCALL
+NTSTATUS NTAPI
NtOpenThreadToken(IN HANDLE ThreadHandle,
IN ACCESS_MASK DesiredAccess,
IN BOOLEAN OpenAsSelf,
KPROCESSOR_MODE PreviousMode;
PTOKEN FirstToken, SecondToken;
BOOLEAN IsEqual;
- NTSTATUS Status = STATUS_SUCCESS;
+ NTSTATUS Status;
PAGED_CODE();
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,
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;
* @unimplemented
*/
NTSTATUS
-STDCALL
+NTAPI
NtImpersonateAnonymousToken(IN HANDLE Thread)
{
UNIMPLEMENTED;