#pragma alloc_text(INIT, SepInitializeTokenImplementation)
#endif
+#include <ntlsa.h>
+
+typedef struct _TOKEN_AUDIT_POLICY_INFORMATION
+{
+ ULONG PolicyCount;
+ struct
+ {
+ ULONG Category;
+ UCHAR Value;
+ } Policies[1];
+} TOKEN_AUDIT_POLICY_INFORMATION, *PTOKEN_AUDIT_POLICY_INFORMATION;
+
/* GLOBALS ********************************************************************/
POBJECT_TYPE SeTokenObjectType = NULL;
TOKEN_SOURCE SeSystemTokenSource = {"*SYSTEM*", {0}};
LUID SeSystemAuthenticationId = SYSTEM_LUID;
+LUID SeAnonymousAuthenticationId = ANONYMOUS_LOGON_LUID;
static GENERIC_MAPPING SepTokenMapping = {
TOKEN_READ,
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 ),
+ ICI_SQ_SAME( sizeof(TOKEN_USER), sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE | ICIF_SET_SIZE_VARIABLE ),
/* TokenGroups */
- ICI_SQ_SAME( sizeof(TOKEN_GROUPS), sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE | ICIF_SET | ICIF_SET_SIZE_VARIABLE ),
+ ICI_SQ_SAME( sizeof(TOKEN_GROUPS), sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE | ICIF_SET_SIZE_VARIABLE ),
/* TokenPrivileges */
- ICI_SQ_SAME( sizeof(TOKEN_PRIVILEGES), sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE | ICIF_SET | ICIF_SET_SIZE_VARIABLE ),
+ ICI_SQ_SAME( sizeof(TOKEN_PRIVILEGES), sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE | ICIF_SET_SIZE_VARIABLE ),
/* TokenOwner */
ICI_SQ_SAME( sizeof(TOKEN_OWNER), sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE | ICIF_SET | ICIF_SET_SIZE_VARIABLE ),
/* TokenPrimaryGroup */
/* TokenDefaultDacl */
ICI_SQ_SAME( sizeof(TOKEN_DEFAULT_DACL), sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE | ICIF_SET | ICIF_SET_SIZE_VARIABLE ),
/* TokenSource */
- ICI_SQ_SAME( sizeof(TOKEN_SOURCE), sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE | ICIF_SET | ICIF_SET_SIZE_VARIABLE ),
+ ICI_SQ_SAME( sizeof(TOKEN_SOURCE), sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE | ICIF_SET_SIZE_VARIABLE ),
/* TokenType */
ICI_SQ_SAME( sizeof(TOKEN_TYPE), sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE ),
/* TokenImpersonationLevel */
ICI_SQ_SAME( sizeof(SECURITY_IMPERSONATION_LEVEL), sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE ),
/* TokenStatistics */
- ICI_SQ_SAME( sizeof(TOKEN_STATISTICS), sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE | ICIF_SET | ICIF_SET_SIZE_VARIABLE ),
+ ICI_SQ_SAME( sizeof(TOKEN_STATISTICS), sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE | ICIF_SET_SIZE_VARIABLE ),
/* TokenRestrictedSids */
ICI_SQ_SAME( sizeof(TOKEN_GROUPS), sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE ),
/* TokenSessionId */
/* TokenGroupsAndPrivileges */
ICI_SQ_SAME( sizeof(TOKEN_GROUPS_AND_PRIVILEGES), sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE ),
/* TokenSessionReference */
- ICI_SQ_SAME( /* FIXME */0, sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE ),
+ ICI_SQ_SAME( sizeof(ULONG), sizeof(ULONG), ICIF_SET | ICIF_QUERY_SIZE_VARIABLE ),
/* TokenSandBoxInert */
ICI_SQ_SAME( sizeof(ULONG), sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE ),
/* TokenAuditPolicy */
- ICI_SQ_SAME( /* FIXME */0, sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE ),
+ ICI_SQ_SAME( /* FIXME */0, sizeof(ULONG), ICIF_QUERY | ICIF_SET | ICIF_QUERY_SIZE_VARIABLE ),
/* TokenOrigin */
- ICI_SQ_SAME( sizeof(TOKEN_ORIGIN), sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE ),
+ ICI_SQ_SAME( sizeof(TOKEN_ORIGIN), sizeof(ULONG), ICIF_QUERY | ICIF_SET | ICIF_QUERY_SIZE_VARIABLE ),
};
/* FUNCTIONS *****************************************************************/
}
/* FIXME: Check if every privilege that is present in either token is also present in the other one */
+ DPRINT1("FIXME: Pretending tokens are equal!\n");
+ IsEqual = TRUE;
}
*Equal = IsEqual;
PAGED_CODE();
if (NewToken->TokenType != TokenPrimary) return(STATUS_BAD_TOKEN_TYPE);
- if (NewToken->TokenInUse) return(STATUS_TOKEN_ALREADY_IN_USE);
+ if (NewToken->TokenInUse)
+ {
+ BOOLEAN IsEqual;
+ NTSTATUS Status;
+
+ /* Maybe we're trying to set the same token */
+ OldToken = PsReferencePrimaryToken(Process);
+ if (OldToken == NewToken)
+ {
+ /* So it's a nop. */
+ *OldTokenP = OldToken;
+ return STATUS_SUCCESS;
+ }
+
+ Status = SepCompareTokens(OldToken, NewToken, &IsEqual);
+ if (!NT_SUCCESS(Status))
+ {
+ *OldTokenP = NULL;
+ PsDereferencePrimaryToken(OldToken);
+ return Status;
+ }
+
+ 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 */
NewToken->TokenInUse = 1;
for (i = 0; i < GroupCount; i++)
uLength += RtlLengthSid(Groups[i].Sid);
+ // FIXME: should use the object itself
AccessToken->UserAndGroups = ExAllocatePoolWithTag(PagedPool,
uLength,
TAG_TOKEN_USERS);
if (!NT_SUCCESS(Status))
goto done;
+ // FIXME: should use the object itself
uLength = PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES);
+ if (uLength == 0) uLength = sizeof(PVOID);
AccessToken->Privileges = ExAllocatePoolWithTag(PagedPool,
uLength,
TAG_TOKEN_PRIVILAGES);
/* Update privilege flags */
SepUpdatePrivilegeFlagsToken(AccessToken);
- AccessToken->DefaultDacl = ExAllocatePoolWithTag(PagedPool,
- DefaultDacl->AclSize,
- TAG_TOKEN_ACL);
- if (AccessToken->DefaultDacl == NULL)
+ if (DefaultDacl != NULL)
{
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto done;
- }
+ // FIXME: should use the object itself
+ AccessToken->DefaultDacl = ExAllocatePoolWithTag(PagedPool,
+ DefaultDacl->AclSize,
+ TAG_TOKEN_ACL);
+ if (AccessToken->DefaultDacl == NULL)
+ {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto done;
+ }
- RtlCopyMemory(AccessToken->DefaultDacl,
- DefaultDacl,
- DefaultDacl->AclSize);
+ RtlCopyMemory(AccessToken->DefaultDacl,
+ DefaultDacl,
+ DefaultDacl->AclSize);
+ }
+ else
+ {
+ AccessToken->DefaultDacl = NULL;
+ }
if (!SystemToken)
{
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- _SEH2_YIELD(return _SEH2_GetExceptionCode());
+ Status = _SEH2_GetExceptionCode();
+ goto Cleanup;
}
_SEH2_END;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- _SEH2_YIELD(return _SEH2_GetExceptionCode());
+ Status = _SEH2_GetExceptionCode();
+ goto Cleanup;
}
_SEH2_END;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- _SEH2_YIELD(return _SEH2_GetExceptionCode());
+ Status = _SEH2_GetExceptionCode();
+ goto Cleanup;
}
_SEH2_END;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- _SEH2_YIELD(return _SEH2_GetExceptionCode());
+ Status = _SEH2_GetExceptionCode();
+ goto Cleanup;
}
_SEH2_END;
break;
}
+ case TokenSessionReference:
+ {
+ ULONG SessionReference;
+
+ _SEH2_TRY
+ {
+ /* Buffer size was already verified, no need to check here again */
+ SessionReference = *(PULONG)TokenInformation;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ goto Cleanup;
+ }
+ _SEH2_END;
+
+ if (!SeSinglePrivilegeCheck(SeTcbPrivilege, PreviousMode))
+ {
+ Status = STATUS_PRIVILEGE_NOT_HELD;
+ goto Cleanup;
+ }
+
+ /* Check if it is 0 */
+ if (SessionReference == 0)
+ {
+ /* Atomically set the flag in the token */
+ RtlInterlockedSetBits(&Token->TokenFlags,
+ TOKEN_SESSION_NOT_REFERENCED);
+ }
+
+ break;
+
+ }
+
+
+ case TokenAuditPolicy:
+ {
+ PTOKEN_AUDIT_POLICY_INFORMATION PolicyInformation =
+ (PTOKEN_AUDIT_POLICY_INFORMATION)TokenInformation;
+ SEP_AUDIT_POLICY AuditPolicy;
+ ULONG i;
+
+ _SEH2_TRY
+ {
+ ProbeForRead(PolicyInformation,
+ FIELD_OFFSET(TOKEN_AUDIT_POLICY_INFORMATION,
+ Policies[PolicyInformation->PolicyCount]),
+ sizeof(ULONG));
+
+ /* Loop all policies in the structure */
+ for (i = 0; i < PolicyInformation->PolicyCount; i++)
+ {
+ /* Set the corresponding bits in the packed structure */
+ switch (PolicyInformation->Policies[i].Category)
+ {
+ case AuditCategorySystem:
+ AuditPolicy.PolicyElements.System = PolicyInformation->Policies[i].Value;
+ break;
+
+ case AuditCategoryLogon:
+ AuditPolicy.PolicyElements.Logon = PolicyInformation->Policies[i].Value;
+ break;
+
+ case AuditCategoryObjectAccess:
+ AuditPolicy.PolicyElements.ObjectAccess = PolicyInformation->Policies[i].Value;
+ break;
+
+ case AuditCategoryPrivilegeUse:
+ AuditPolicy.PolicyElements.PrivilegeUse = PolicyInformation->Policies[i].Value;
+ break;
+
+ case AuditCategoryDetailedTracking:
+ AuditPolicy.PolicyElements.DetailedTracking = PolicyInformation->Policies[i].Value;
+ break;
+
+ case AuditCategoryPolicyChange:
+ AuditPolicy.PolicyElements.PolicyChange = PolicyInformation->Policies[i].Value;
+ break;
+
+ case AuditCategoryAccountManagement:
+ AuditPolicy.PolicyElements.AccountManagement = PolicyInformation->Policies[i].Value;
+ break;
+
+ case AuditCategoryDirectoryServiceAccess:
+ AuditPolicy.PolicyElements.DirectoryServiceAccess = PolicyInformation->Policies[i].Value;
+ break;
+
+ case AuditCategoryAccountLogon:
+ AuditPolicy.PolicyElements.AccountLogon = PolicyInformation->Policies[i].Value;
+ break;
+ }
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ goto Cleanup;
+ }
+ _SEH2_END;
+
+ if (!SeSinglePrivilegeCheck(SeTcbPrivilege,
+ PreviousMode))
+ {
+ Status = STATUS_PRIVILEGE_NOT_HELD;
+ break;
+ }
+
+ /* Lock the token */
+ SepAcquireTokenLockExclusive(Token);
+
+ /* Set the new audit policy */
+ Token->AuditPolicy = AuditPolicy;
+
+ /* Unlock the token */
+ SepReleaseTokenLock(Token);
+
+ break;
+ }
+
+ case TokenOrigin:
+ {
+ TOKEN_ORIGIN TokenOrigin;
+
+ _SEH2_TRY
+ {
+ /* Copy the token origin */
+ TokenOrigin = *(PTOKEN_ORIGIN)TokenInformation;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ goto Cleanup;
+ }
+ _SEH2_END;
+
+ /* Check for TCB privilege */
+ if (!SeSinglePrivilegeCheck(SeTcbPrivilege, PreviousMode))
+ {
+ Status = STATUS_PRIVILEGE_NOT_HELD;
+ break;
+ }
+
+ /* Lock the token */
+ SepAcquireTokenLockExclusive(Token);
+
+ /* Check if there is no token origin set yet */
+ if ((Token->OriginatingLogonSession.LowPart == 0) &&
+ (Token->OriginatingLogonSession.HighPart == 0))
+ {
+ /* Set the token origin */
+ Token->OriginatingLogonSession =
+ TokenOrigin.OriginatingLogonSession;
+ }
+
+ /* Unlock the token */
+ SepReleaseTokenLock(Token);
+
+ break;
+ }
+
default:
{
- Status = STATUS_NOT_IMPLEMENTED;
+ DPRINT1("Invalid TokenInformationClass: 0x%lx\n",
+ TokenInformationClass);
+ Status = STATUS_INVALID_INFO_CLASS;
break;
}
}
-
+Cleanup:
ObDereferenceObject(Token);
}
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("NtSetInformationToken failed with Status 0x%lx\n", Status);
+ }
+
return 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)
+NtCreateToken(
+ _Out_ PHANDLE TokenHandle,
+ _In_ ACCESS_MASK DesiredAccess,
+ _In_opt_ 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_opt_ PTOKEN_OWNER TokenOwner,
+ _In_ PTOKEN_PRIMARY_GROUP TokenPrimaryGroup,
+ _In_opt_ PTOKEN_DEFAULT_DACL TokenDefaultDacl,
+ _In_ PTOKEN_SOURCE TokenSource)
{
HANDLE hToken;
KPROCESSOR_MODE PreviousMode;
- ULONG nTokenPrivileges = 0;
+ ULONG PrivilegeCount, GroupCount;
+ PSID OwnerSid, PrimaryGroupSid;
+ PACL DefaultDacl;
LARGE_INTEGER LocalExpirationTime = {{0, 0}};
+ LUID LocalAuthenticationId;
+ TOKEN_SOURCE LocalTokenSource;
+ SECURITY_QUALITY_OF_SERVICE LocalSecurityQos;
+ PLUID_AND_ATTRIBUTES CapturedPrivileges = NULL;
+ PSID_AND_ATTRIBUTES CapturedUser = NULL;
+ PSID_AND_ATTRIBUTES CapturedGroups = NULL;
+ PSID CapturedOwnerSid = NULL;
+ PSID CapturedPrimaryGroupSid = NULL;
+ PACL CapturedDefaultDacl = NULL;
+ ULONG PrivilegesLength, UserLength, GroupsLength;
NTSTATUS Status;
PAGED_CODE();
_SEH2_TRY
{
ProbeForWriteHandle(TokenHandle);
+
+ if (ObjectAttributes != NULL)
+ {
+ ProbeForRead(ObjectAttributes,
+ sizeof(OBJECT_ATTRIBUTES),
+ sizeof(ULONG));
+ LocalSecurityQos = *(SECURITY_QUALITY_OF_SERVICE*)ObjectAttributes->SecurityQualityOfService;
+ }
+
ProbeForRead(AuthenticationId,
sizeof(LUID),
sizeof(ULONG));
+ LocalAuthenticationId = *AuthenticationId;
+
LocalExpirationTime = ProbeForReadLargeInteger(ExpirationTime);
+
ProbeForRead(TokenUser,
sizeof(TOKEN_USER),
sizeof(ULONG));
+
ProbeForRead(TokenGroups,
sizeof(TOKEN_GROUPS),
sizeof(ULONG));
+ GroupCount = TokenGroups->GroupCount;
+
ProbeForRead(TokenPrivileges,
sizeof(TOKEN_PRIVILEGES),
sizeof(ULONG));
- ProbeForRead(TokenOwner,
- sizeof(TOKEN_OWNER),
- sizeof(ULONG));
+ PrivilegeCount = TokenPrivileges->PrivilegeCount;
+
+ if (TokenOwner != NULL)
+ {
+ ProbeForRead(TokenOwner,
+ sizeof(TOKEN_OWNER),
+ sizeof(ULONG));
+ OwnerSid = TokenOwner->Owner;
+ }
+ else
+ {
+ OwnerSid = NULL;
+ }
+
ProbeForRead(TokenPrimaryGroup,
sizeof(TOKEN_PRIMARY_GROUP),
sizeof(ULONG));
- ProbeForRead(TokenDefaultDacl,
- sizeof(TOKEN_DEFAULT_DACL),
- sizeof(ULONG));
+ PrimaryGroupSid = TokenPrimaryGroup->PrimaryGroup;
+
+ if (TokenDefaultDacl != NULL)
+ {
+ ProbeForRead(TokenDefaultDacl,
+ sizeof(TOKEN_DEFAULT_DACL),
+ sizeof(ULONG));
+ DefaultDacl = TokenDefaultDacl->DefaultDacl;
+ }
+ else
+ {
+ DefaultDacl = NULL;
+ }
+
ProbeForRead(TokenSource,
sizeof(TOKEN_SOURCE),
sizeof(ULONG));
- nTokenPrivileges = TokenPrivileges->PrivilegeCount;
+ LocalTokenSource = *TokenSource;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
/* Return the exception code */
- _SEH2_YIELD(return _SEH2_GetExceptionCode());
+ return _SEH2_GetExceptionCode();
}
_SEH2_END;
}
else
{
- nTokenPrivileges = TokenPrivileges->PrivilegeCount;
+ if (ObjectAttributes != NULL)
+ LocalSecurityQos = *(SECURITY_QUALITY_OF_SERVICE*)ObjectAttributes->SecurityQualityOfService;
+ LocalAuthenticationId = *AuthenticationId;
LocalExpirationTime = *ExpirationTime;
+ GroupCount = TokenGroups->GroupCount;
+ PrivilegeCount = TokenPrivileges->PrivilegeCount;
+ OwnerSid = TokenOwner ? TokenOwner->Owner : NULL;
+ PrimaryGroupSid = TokenPrimaryGroup->PrimaryGroup;
+ DefaultDacl = TokenDefaultDacl ? TokenDefaultDacl->DefaultDacl : NULL;
+ LocalTokenSource = *TokenSource;
}
+ /* Check token type */
+ if ((TokenType < TokenPrimary) ||
+ (TokenType > TokenImpersonation))
+ {
+ return STATUS_BAD_TOKEN_TYPE;
+ }
+
+ /* Capture the user SID and attributes */
+ Status = SeCaptureSidAndAttributesArray(&TokenUser->User,
+ 1,
+ PreviousMode,
+ NULL,
+ 0,
+ PagedPool,
+ FALSE,
+ &CapturedUser,
+ &UserLength);
+ if (!NT_SUCCESS(Status))
+ {
+ goto Cleanup;
+ }
+
+ /* Capture the groups SID and attributes array */
+ Status = SeCaptureSidAndAttributesArray(&TokenGroups->Groups[0],
+ GroupCount,
+ PreviousMode,
+ NULL,
+ 0,
+ PagedPool,
+ FALSE,
+ &CapturedGroups,
+ &GroupsLength);
+ if (!NT_SUCCESS(Status))
+ {
+ goto Cleanup;
+ }
+
+ /* Capture privileges */
+ Status = SeCaptureLuidAndAttributesArray(&TokenPrivileges->Privileges[0],
+ PrivilegeCount,
+ PreviousMode,
+ NULL,
+ 0,
+ PagedPool,
+ FALSE,
+ &CapturedPrivileges,
+ &PrivilegesLength);
+ if (!NT_SUCCESS(Status))
+ {
+ goto Cleanup;
+ }
+
+ /* Capture the token owner SID */
+ if (TokenOwner != NULL)
+ {
+ Status = SepCaptureSid(OwnerSid,
+ PreviousMode,
+ PagedPool,
+ FALSE,
+ &CapturedOwnerSid);
+ if (!NT_SUCCESS(Status))
+ {
+ goto Cleanup;
+ }
+ }
+
+ /* Capture the token primary group SID */
+ Status = SepCaptureSid(PrimaryGroupSid,
+ PreviousMode,
+ PagedPool,
+ FALSE,
+ &CapturedPrimaryGroupSid);
+ if (!NT_SUCCESS(Status))
+ {
+ goto Cleanup;
+ }
+
+ /* Capture DefaultDacl */
+ if (DefaultDacl != NULL)
+ {
+ Status = SepCaptureAcl(DefaultDacl,
+ PreviousMode,
+ NonPagedPool,
+ FALSE,
+ &CapturedDefaultDacl);
+ }
+
+ /* Call the internal function */
Status = SepCreateToken(&hToken,
PreviousMode,
DesiredAccess,
ObjectAttributes,
TokenType,
- ((PSECURITY_QUALITY_OF_SERVICE)(ObjectAttributes->SecurityQualityOfService))->ImpersonationLevel,
- AuthenticationId,
+ LocalSecurityQos.ImpersonationLevel,
+ &LocalAuthenticationId,
&LocalExpirationTime,
- &TokenUser->User,
- TokenGroups->GroupCount,
- TokenGroups->Groups,
+ CapturedUser,
+ GroupCount,
+ CapturedGroups,
0, // FIXME: Should capture
- nTokenPrivileges,
- TokenPrivileges->Privileges,
- TokenOwner->Owner,
- TokenPrimaryGroup->PrimaryGroup,
- TokenDefaultDacl->DefaultDacl,
- TokenSource,
+ PrivilegeCount,
+ CapturedPrivileges,
+ CapturedOwnerSid,
+ CapturedPrimaryGroupSid,
+ CapturedDefaultDacl,
+ &LocalTokenSource,
FALSE);
if (NT_SUCCESS(Status))
{
_SEH2_END;
}
+Cleanup:
+
+ /* Release what we captured */
+ SeReleaseSidAndAttributesArray(CapturedUser, PreviousMode, FALSE);
+ SeReleaseSidAndAttributesArray(CapturedGroups, PreviousMode, FALSE);
+ SeReleaseLuidAndAttributesArray(CapturedPrivileges, PreviousMode, FALSE);
+ SepReleaseSid(CapturedOwnerSid, PreviousMode, FALSE);
+ SepReleaseSid(CapturedPrimaryGroupSid, PreviousMode, FALSE);
+ SepReleaseAcl(CapturedDefaultDacl, PreviousMode, FALSE);
+
return Status;
}