mirror of
https://github.com/reactos/reactos.git
synced 2025-05-22 02:25:18 +00:00
[NTOS]
- accesschk.c: Remove redundant SepAccessCheck/SepAccessCheckEx pair of private functions; instead just rename SepAccessCheckEx into SepAccessCheck and use it directly in the code. NOTE: SepAccessCheck is *incomplete* (in particular it doesn't retrieve the information needed to initialize the 'Privileges' parameter). - sid.c: Comments formatting fix. - token.c: * Finish to implement SeQueryInformationToken . This function is really the same as NtQueryInformationToken but without all the stuff needed for user-mode buffer access protection. * Some code simplifications in NtQueryInformationToken. I need this to fix a "FIXME: Use SeQueryInformationToken" in some code I'm also fixing (& commit later). [NDK]: Fix parameter types and add annotations to RtlCopySidAndAttributesArray. [KMTESTS:NTOS_SE] - Reenable the 'SeQueryInfoToken' test. - Show that SeQueryInformationToken doesn't support 4 token information classes, which are supported only by NtQueryInformationToken. - Fix calling of SeAccessCheck. In particular the 'Privileges' parameter is not allocated by the caller, but instead is allocated by SeAccessCheck *and* returned to the caller (who then must free the buffer using SeFreePrivileges). This fixes the encountered BSODs that leaded to disabling preventively the test in r59178. - Minor code cleaning. svn path=/trunk/; revision=73122
This commit is contained in:
parent
3430268b90
commit
15d77be6fd
7 changed files with 511 additions and 118 deletions
|
@ -18,8 +18,11 @@
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS **********************************************************/
|
/* PRIVATE FUNCTIONS **********************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FIXME: Incomplete!
|
||||||
|
*/
|
||||||
BOOLEAN NTAPI
|
BOOLEAN NTAPI
|
||||||
SepAccessCheckEx(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
|
SepAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
|
||||||
IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext,
|
IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext,
|
||||||
IN ACCESS_MASK DesiredAccess,
|
IN ACCESS_MASK DesiredAccess,
|
||||||
IN POBJECT_TYPE_LIST ObjectTypeList,
|
IN POBJECT_TYPE_LIST ObjectTypeList,
|
||||||
|
@ -46,7 +49,7 @@ SepAccessCheckEx(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
DPRINT("SepAccessCheckEx()\n");
|
DPRINT("SepAccessCheck()\n");
|
||||||
|
|
||||||
/* Check for no access desired */
|
/* Check for no access desired */
|
||||||
if (!DesiredAccess)
|
if (!DesiredAccess)
|
||||||
|
@ -283,31 +286,6 @@ ReturnCommonStatus:
|
||||||
return NT_SUCCESS(Status);
|
return NT_SUCCESS(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN NTAPI
|
|
||||||
SepAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
|
|
||||||
IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext,
|
|
||||||
IN ACCESS_MASK DesiredAccess,
|
|
||||||
IN ACCESS_MASK PreviouslyGrantedAccess,
|
|
||||||
OUT PPRIVILEGE_SET* Privileges,
|
|
||||||
IN PGENERIC_MAPPING GenericMapping,
|
|
||||||
IN KPROCESSOR_MODE AccessMode,
|
|
||||||
OUT PACCESS_MASK GrantedAccess,
|
|
||||||
OUT PNTSTATUS AccessStatus)
|
|
||||||
{
|
|
||||||
return SepAccessCheckEx(SecurityDescriptor,
|
|
||||||
SubjectSecurityContext,
|
|
||||||
DesiredAccess,
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
PreviouslyGrantedAccess,
|
|
||||||
Privileges,
|
|
||||||
GenericMapping,
|
|
||||||
AccessMode,
|
|
||||||
GrantedAccess,
|
|
||||||
AccessStatus,
|
|
||||||
FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static PSID
|
static PSID
|
||||||
SepGetSDOwner(IN PSECURITY_DESCRIPTOR _SecurityDescriptor)
|
SepGetSDOwner(IN PSECURITY_DESCRIPTOR _SecurityDescriptor)
|
||||||
{
|
{
|
||||||
|
@ -443,12 +421,15 @@ SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
|
||||||
ret = SepAccessCheck(SecurityDescriptor,
|
ret = SepAccessCheck(SecurityDescriptor,
|
||||||
SubjectSecurityContext,
|
SubjectSecurityContext,
|
||||||
DesiredAccess,
|
DesiredAccess,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
PreviouslyGrantedAccess,
|
PreviouslyGrantedAccess,
|
||||||
Privileges,
|
Privileges,
|
||||||
GenericMapping,
|
GenericMapping,
|
||||||
AccessMode,
|
AccessMode,
|
||||||
GrantedAccess,
|
GrantedAccess,
|
||||||
AccessStatus);
|
AccessStatus,
|
||||||
|
FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Release the lock if needed */
|
/* Release the lock if needed */
|
||||||
|
@ -687,12 +668,15 @@ NtAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
|
||||||
SepAccessCheck(SecurityDescriptor, // FIXME: use CapturedSecurityDescriptor
|
SepAccessCheck(SecurityDescriptor, // FIXME: use CapturedSecurityDescriptor
|
||||||
&SubjectSecurityContext,
|
&SubjectSecurityContext,
|
||||||
DesiredAccess,
|
DesiredAccess,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
PreviouslyGrantedAccess,
|
PreviouslyGrantedAccess,
|
||||||
&PrivilegeSet, //FIXME
|
&PrivilegeSet, //FIXME
|
||||||
GenericMapping,
|
GenericMapping,
|
||||||
PreviousMode,
|
PreviousMode,
|
||||||
GrantedAccess,
|
GrantedAccess,
|
||||||
AccessStatus);
|
AccessStatus,
|
||||||
|
FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Release subject context and unlock the token */
|
/* Release subject context and unlock the token */
|
||||||
|
|
|
@ -297,7 +297,7 @@ SepCaptureSid(IN PSID InputSid,
|
||||||
}
|
}
|
||||||
_SEH2_END;
|
_SEH2_END;
|
||||||
|
|
||||||
/* allocate a SID and copy it */
|
/* Allocate a SID and copy it */
|
||||||
NewSid = ExAllocatePoolWithTag(PoolType, SidSize, TAG_SID);
|
NewSid = ExAllocatePoolWithTag(PoolType, SidSize, TAG_SID);
|
||||||
if (!NewSid)
|
if (!NewSid)
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
@ -324,7 +324,7 @@ SepCaptureSid(IN PSID InputSid,
|
||||||
{
|
{
|
||||||
SidSize = RtlLengthRequiredSid(Sid->SubAuthorityCount);
|
SidSize = RtlLengthRequiredSid(Sid->SubAuthorityCount);
|
||||||
|
|
||||||
/* allocate a SID and copy it */
|
/* Allocate a SID and copy it */
|
||||||
NewSid = ExAllocatePoolWithTag(PoolType, SidSize, TAG_SID);
|
NewSid = ExAllocatePoolWithTag(PoolType, SidSize, TAG_SID);
|
||||||
if (NewSid == NULL)
|
if (NewSid == NULL)
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
|
@ -232,7 +232,7 @@ SeExchangePrimaryToken(PEPROCESS Process,
|
||||||
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
if (NewToken->TokenType != TokenPrimary) return(STATUS_BAD_TOKEN_TYPE);
|
if (NewToken->TokenType != TokenPrimary) return STATUS_BAD_TOKEN_TYPE;
|
||||||
if (NewToken->TokenInUse)
|
if (NewToken->TokenInUse)
|
||||||
{
|
{
|
||||||
BOOLEAN IsEqual;
|
BOOLEAN IsEqual;
|
||||||
|
@ -348,12 +348,12 @@ SepFindPrimaryGroupAndDefaultOwner(PTOKEN Token,
|
||||||
|
|
||||||
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;
|
||||||
|
@ -1060,16 +1060,26 @@ SeFilterToken(IN PACCESS_TOKEN ExistingToken,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @unimplemented
|
* @implemented
|
||||||
|
*
|
||||||
|
* NOTE: SeQueryInformationToken is just NtQueryInformationToken without all
|
||||||
|
* the bells and whistles needed for user-mode buffer access protection.
|
||||||
*/
|
*/
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
SeQueryInformationToken(IN PACCESS_TOKEN Token,
|
SeQueryInformationToken(IN PACCESS_TOKEN AccessToken,
|
||||||
IN TOKEN_INFORMATION_CLASS TokenInformationClass,
|
IN TOKEN_INFORMATION_CLASS TokenInformationClass,
|
||||||
OUT PVOID *TokenInformation)
|
OUT PVOID *TokenInformation)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PSECURITY_IMPERSONATION_LEVEL SeImpersonationLvl;
|
PTOKEN Token = (PTOKEN)AccessToken;
|
||||||
|
ULONG RequiredLength;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
PSID PSid;
|
||||||
|
ULONG Ulong;
|
||||||
|
} Unused;
|
||||||
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
if (TokenInformationClass >= MaxTokenInfoClass)
|
if (TokenInformationClass >= MaxTokenInfoClass)
|
||||||
|
@ -1080,31 +1090,395 @@ SeQueryInformationToken(IN PACCESS_TOKEN Token,
|
||||||
|
|
||||||
switch (TokenInformationClass)
|
switch (TokenInformationClass)
|
||||||
{
|
{
|
||||||
|
case TokenUser:
|
||||||
|
{
|
||||||
|
PTOKEN_USER tu;
|
||||||
|
|
||||||
|
DPRINT("SeQueryInformationToken(TokenUser)\n");
|
||||||
|
RequiredLength = sizeof(TOKEN_USER) +
|
||||||
|
RtlLengthSid(Token->UserAndGroups[0].Sid);
|
||||||
|
|
||||||
|
/* Allocate the output buffer */
|
||||||
|
tu = ExAllocatePoolWithTag(PagedPool, RequiredLength, TAG_SE);
|
||||||
|
if (tu == NULL)
|
||||||
|
{
|
||||||
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = RtlCopySidAndAttributesArray(1,
|
||||||
|
&Token->UserAndGroups[0],
|
||||||
|
RequiredLength - sizeof(TOKEN_USER),
|
||||||
|
&tu->User,
|
||||||
|
(PSID)(tu + 1),
|
||||||
|
&Unused.PSid,
|
||||||
|
&Unused.Ulong);
|
||||||
|
|
||||||
|
/* Return the structure */
|
||||||
|
*TokenInformation = tu;
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TokenGroups:
|
||||||
|
{
|
||||||
|
PTOKEN_GROUPS tg;
|
||||||
|
ULONG SidLen;
|
||||||
|
PSID Sid;
|
||||||
|
|
||||||
|
DPRINT("SeQueryInformationToken(TokenGroups)\n");
|
||||||
|
RequiredLength = sizeof(tg->GroupCount) +
|
||||||
|
RtlLengthSidAndAttributes(Token->UserAndGroupCount - 1, &Token->UserAndGroups[1]);
|
||||||
|
|
||||||
|
SidLen = RequiredLength - sizeof(tg->GroupCount) -
|
||||||
|
((Token->UserAndGroupCount - 1) * sizeof(SID_AND_ATTRIBUTES));
|
||||||
|
|
||||||
|
/* Allocate the output buffer */
|
||||||
|
tg = ExAllocatePoolWithTag(PagedPool, RequiredLength, TAG_SE);
|
||||||
|
if (tg == NULL)
|
||||||
|
{
|
||||||
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Sid = (PSID)((ULONG_PTR)tg + 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],
|
||||||
|
Sid,
|
||||||
|
&Unused.PSid,
|
||||||
|
&Unused.Ulong);
|
||||||
|
|
||||||
|
/* Return the structure */
|
||||||
|
*TokenInformation = tg;
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TokenPrivileges:
|
||||||
|
{
|
||||||
|
PTOKEN_PRIVILEGES tp;
|
||||||
|
|
||||||
|
DPRINT("SeQueryInformationToken(TokenPrivileges)\n");
|
||||||
|
RequiredLength = sizeof(tp->PrivilegeCount) +
|
||||||
|
(Token->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES));
|
||||||
|
|
||||||
|
/* Allocate the output buffer */
|
||||||
|
tp = ExAllocatePoolWithTag(PagedPool, RequiredLength, TAG_SE);
|
||||||
|
if (tp == NULL)
|
||||||
|
{
|
||||||
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
tp->PrivilegeCount = Token->PrivilegeCount;
|
||||||
|
RtlCopyLuidAndAttributesArray(Token->PrivilegeCount,
|
||||||
|
Token->Privileges,
|
||||||
|
&tp->Privileges[0]);
|
||||||
|
|
||||||
|
/* Return the structure */
|
||||||
|
*TokenInformation = tp;
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TokenOwner:
|
||||||
|
{
|
||||||
|
PTOKEN_OWNER to;
|
||||||
|
ULONG SidLen;
|
||||||
|
|
||||||
|
DPRINT("SeQueryInformationToken(TokenOwner)\n");
|
||||||
|
SidLen = RtlLengthSid(Token->UserAndGroups[Token->DefaultOwnerIndex].Sid);
|
||||||
|
RequiredLength = sizeof(TOKEN_OWNER) + SidLen;
|
||||||
|
|
||||||
|
/* Allocate the output buffer */
|
||||||
|
to = ExAllocatePoolWithTag(PagedPool, RequiredLength, TAG_SE);
|
||||||
|
if (to == NULL)
|
||||||
|
{
|
||||||
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
to->Owner = (PSID)(to + 1);
|
||||||
|
Status = RtlCopySid(SidLen,
|
||||||
|
to->Owner,
|
||||||
|
Token->UserAndGroups[Token->DefaultOwnerIndex].Sid);
|
||||||
|
|
||||||
|
/* Return the structure */
|
||||||
|
*TokenInformation = to;
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TokenPrimaryGroup:
|
||||||
|
{
|
||||||
|
PTOKEN_PRIMARY_GROUP tpg;
|
||||||
|
ULONG SidLen;
|
||||||
|
|
||||||
|
DPRINT("SeQueryInformationToken(TokenPrimaryGroup)\n");
|
||||||
|
SidLen = RtlLengthSid(Token->PrimaryGroup);
|
||||||
|
RequiredLength = sizeof(TOKEN_PRIMARY_GROUP) + SidLen;
|
||||||
|
|
||||||
|
/* Allocate the output buffer */
|
||||||
|
tpg = ExAllocatePoolWithTag(PagedPool, RequiredLength, TAG_SE);
|
||||||
|
if (tpg == NULL)
|
||||||
|
{
|
||||||
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
tpg->PrimaryGroup = (PSID)(tpg + 1);
|
||||||
|
Status = RtlCopySid(SidLen,
|
||||||
|
tpg->PrimaryGroup,
|
||||||
|
Token->PrimaryGroup);
|
||||||
|
|
||||||
|
/* Return the structure */
|
||||||
|
*TokenInformation = tpg;
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TokenDefaultDacl:
|
||||||
|
{
|
||||||
|
PTOKEN_DEFAULT_DACL tdd;
|
||||||
|
|
||||||
|
DPRINT("SeQueryInformationToken(TokenDefaultDacl)\n");
|
||||||
|
RequiredLength = sizeof(TOKEN_DEFAULT_DACL);
|
||||||
|
|
||||||
|
if (Token->DefaultDacl != NULL)
|
||||||
|
RequiredLength += Token->DefaultDacl->AclSize;
|
||||||
|
|
||||||
|
/* Allocate the output buffer */
|
||||||
|
tdd = ExAllocatePoolWithTag(PagedPool, RequiredLength, TAG_SE);
|
||||||
|
if (tdd == NULL)
|
||||||
|
{
|
||||||
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Token->DefaultDacl != NULL)
|
||||||
|
{
|
||||||
|
tdd->DefaultDacl = (PACL)(tdd + 1);
|
||||||
|
RtlCopyMemory(tdd->DefaultDacl,
|
||||||
|
Token->DefaultDacl,
|
||||||
|
Token->DefaultDacl->AclSize);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tdd->DefaultDacl = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the structure */
|
||||||
|
*TokenInformation = tdd;
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TokenSource:
|
||||||
|
{
|
||||||
|
PTOKEN_SOURCE ts;
|
||||||
|
|
||||||
|
DPRINT("SeQueryInformationToken(TokenSource)\n");
|
||||||
|
RequiredLength = sizeof(TOKEN_SOURCE);
|
||||||
|
|
||||||
|
/* Allocate the output buffer */
|
||||||
|
ts = ExAllocatePoolWithTag(PagedPool, RequiredLength, TAG_SE);
|
||||||
|
if (ts == NULL)
|
||||||
|
{
|
||||||
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ts = Token->TokenSource;
|
||||||
|
|
||||||
|
/* Return the structure */
|
||||||
|
*TokenInformation = ts;
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TokenType:
|
||||||
|
{
|
||||||
|
PTOKEN_TYPE tt;
|
||||||
|
|
||||||
|
DPRINT("SeQueryInformationToken(TokenType)\n");
|
||||||
|
RequiredLength = sizeof(TOKEN_TYPE);
|
||||||
|
|
||||||
|
/* Allocate the output buffer */
|
||||||
|
tt = ExAllocatePoolWithTag(PagedPool, RequiredLength, TAG_SE);
|
||||||
|
if (tt == NULL)
|
||||||
|
{
|
||||||
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
*tt = Token->TokenType;
|
||||||
|
|
||||||
|
/* Return the structure */
|
||||||
|
*TokenInformation = tt;
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case TokenImpersonationLevel:
|
case TokenImpersonationLevel:
|
||||||
/* It is mandatory to have an impersonation token */
|
{
|
||||||
if (((PTOKEN)Token)->TokenType != TokenImpersonation)
|
PSECURITY_IMPERSONATION_LEVEL sil;
|
||||||
|
|
||||||
|
DPRINT("SeQueryInformationToken(TokenImpersonationLevel)\n");
|
||||||
|
RequiredLength = sizeof(SECURITY_IMPERSONATION_LEVEL);
|
||||||
|
|
||||||
|
/* Fail if the token is not an impersonation token */
|
||||||
|
if (Token->TokenType != TokenImpersonation)
|
||||||
{
|
{
|
||||||
Status = STATUS_INVALID_INFO_CLASS;
|
Status = STATUS_INVALID_INFO_CLASS;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate the output buffer */
|
/* Allocate the output buffer */
|
||||||
SeImpersonationLvl = ExAllocatePoolWithTag(PagedPool, sizeof(SECURITY_IMPERSONATION_LEVEL), TAG_SE);
|
sil = ExAllocatePoolWithTag(PagedPool, RequiredLength, TAG_SE);
|
||||||
if (SeImpersonationLvl == NULL)
|
if (sil == NULL)
|
||||||
{
|
{
|
||||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set impersonation level and return the structure */
|
*sil = Token->ImpersonationLevel;
|
||||||
*SeImpersonationLvl = ((PTOKEN)Token)->ImpersonationLevel;
|
|
||||||
*TokenInformation = SeImpersonationLvl;
|
/* Return the structure */
|
||||||
|
*TokenInformation = sil;
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TokenStatistics:
|
||||||
|
{
|
||||||
|
PTOKEN_STATISTICS ts;
|
||||||
|
|
||||||
|
DPRINT("SeQueryInformationToken(TokenStatistics)\n");
|
||||||
|
RequiredLength = sizeof(TOKEN_STATISTICS);
|
||||||
|
|
||||||
|
/* Allocate the output buffer */
|
||||||
|
ts = ExAllocatePoolWithTag(PagedPool, RequiredLength, TAG_SE);
|
||||||
|
if (ts == NULL)
|
||||||
|
{
|
||||||
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
/* Return the structure */
|
||||||
|
*TokenInformation = ts;
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following 4 cases are only implemented in NtQueryInformationToken
|
||||||
|
*/
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
case TokenOrigin:
|
||||||
|
{
|
||||||
|
PTOKEN_ORIGIN to;
|
||||||
|
|
||||||
|
DPRINT("SeQueryInformationToken(TokenOrigin)\n");
|
||||||
|
RequiredLength = sizeof(TOKEN_ORIGIN);
|
||||||
|
|
||||||
|
/* Allocate the output buffer */
|
||||||
|
to = ExAllocatePoolWithTag(PagedPool, RequiredLength, TAG_SE);
|
||||||
|
if (to == NULL)
|
||||||
|
{
|
||||||
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
RtlCopyLuid(&to->OriginatingLogonSession,
|
||||||
|
&Token->AuthenticationId);
|
||||||
|
|
||||||
|
/* Return the structure */
|
||||||
|
*TokenInformation = to;
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TokenGroupsAndPrivileges:
|
||||||
|
DPRINT1("SeQueryInformationToken(TokenGroupsAndPrivileges) not implemented\n");
|
||||||
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TokenRestrictedSids:
|
||||||
|
{
|
||||||
|
PTOKEN_GROUPS tg = (PTOKEN_GROUPS)TokenInformation;
|
||||||
|
ULONG SidLen;
|
||||||
|
PSID Sid;
|
||||||
|
|
||||||
|
DPRINT("SeQueryInformationToken(TokenRestrictedSids)\n");
|
||||||
|
RequiredLength = sizeof(tg->GroupCount) +
|
||||||
|
RtlLengthSidAndAttributes(Token->RestrictedSidCount, Token->RestrictedSids);
|
||||||
|
|
||||||
|
SidLen = RequiredLength - sizeof(tg->GroupCount) -
|
||||||
|
(Token->RestrictedSidCount * sizeof(SID_AND_ATTRIBUTES));
|
||||||
|
|
||||||
|
/* Allocate the output buffer */
|
||||||
|
tg = ExAllocatePoolWithTag(PagedPool, RequiredLength, TAG_SE);
|
||||||
|
if (tg == NULL)
|
||||||
|
{
|
||||||
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Sid = (PSID)((ULONG_PTR)tg + sizeof(tg->GroupCount) +
|
||||||
|
(Token->RestrictedSidCount * sizeof(SID_AND_ATTRIBUTES)));
|
||||||
|
|
||||||
|
tg->GroupCount = Token->RestrictedSidCount;
|
||||||
|
Status = RtlCopySidAndAttributesArray(Token->RestrictedSidCount,
|
||||||
|
Token->RestrictedSids,
|
||||||
|
SidLen,
|
||||||
|
&tg->Groups[0],
|
||||||
|
Sid,
|
||||||
|
&Unused.PSid,
|
||||||
|
&Unused.Ulong);
|
||||||
|
|
||||||
|
/* Return the structure */
|
||||||
|
*TokenInformation = tg;
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TokenSandBoxInert:
|
||||||
|
DPRINT1("SeQueryInformationToken(TokenSandboxInert) not implemented\n");
|
||||||
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
|
break;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
case TokenSessionId:
|
||||||
|
{
|
||||||
|
DPRINT("SeQueryInformationToken(TokenSessionId)\n");
|
||||||
|
|
||||||
|
Status = SeQuerySessionIdToken(Token, (PULONG)TokenInformation);
|
||||||
|
|
||||||
|
// Status = STATUS_SUCCESS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
UNIMPLEMENTED;
|
DPRINT1("SeQueryInformationToken(%d) invalid information class\n", TokenInformationClass);
|
||||||
Status = STATUS_NOT_IMPLEMENTED;
|
Status = STATUS_INVALID_INFO_CLASS;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1212,15 +1586,15 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
|
||||||
IN ULONG TokenInformationLength,
|
IN ULONG TokenInformationLength,
|
||||||
OUT PULONG ReturnLength)
|
OUT PULONG ReturnLength)
|
||||||
{
|
{
|
||||||
union
|
NTSTATUS Status;
|
||||||
{
|
KPROCESSOR_MODE PreviousMode;
|
||||||
PVOID Ptr;
|
|
||||||
ULONG Ulong;
|
|
||||||
} Unused;
|
|
||||||
PTOKEN Token;
|
PTOKEN Token;
|
||||||
ULONG RequiredLength;
|
ULONG RequiredLength;
|
||||||
KPROCESSOR_MODE PreviousMode;
|
union
|
||||||
NTSTATUS Status;
|
{
|
||||||
|
PSID PSid;
|
||||||
|
ULONG Ulong;
|
||||||
|
} Unused;
|
||||||
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
|
@ -1229,7 +1603,7 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
|
||||||
/* Check buffers and class validity */
|
/* Check buffers and class validity */
|
||||||
Status = DefaultQueryInfoBufferCheck(TokenInformationClass,
|
Status = DefaultQueryInfoBufferCheck(TokenInformationClass,
|
||||||
SeTokenInformationClass,
|
SeTokenInformationClass,
|
||||||
sizeof(SeTokenInformationClass) / sizeof(SeTokenInformationClass[0]),
|
RTL_NUMBER_OF(SeTokenInformationClass),
|
||||||
TokenInformation,
|
TokenInformation,
|
||||||
TokenInformationLength,
|
TokenInformationLength,
|
||||||
ReturnLength,
|
ReturnLength,
|
||||||
|
@ -1268,7 +1642,7 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
|
||||||
RequiredLength - sizeof(TOKEN_USER),
|
RequiredLength - sizeof(TOKEN_USER),
|
||||||
&tu->User,
|
&tu->User,
|
||||||
(PSID)(tu + 1),
|
(PSID)(tu + 1),
|
||||||
&Unused.Ptr,
|
&Unused.PSid,
|
||||||
&Unused.Ulong);
|
&Unused.Ulong);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1304,7 +1678,7 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
|
||||||
{
|
{
|
||||||
ULONG SidLen = RequiredLength - sizeof(tg->GroupCount) -
|
ULONG SidLen = RequiredLength - sizeof(tg->GroupCount) -
|
||||||
((Token->UserAndGroupCount - 1) * sizeof(SID_AND_ATTRIBUTES));
|
((Token->UserAndGroupCount - 1) * sizeof(SID_AND_ATTRIBUTES));
|
||||||
PSID_AND_ATTRIBUTES Sid = (PSID_AND_ATTRIBUTES)((ULONG_PTR)TokenInformation + sizeof(tg->GroupCount) +
|
PSID Sid = (PSID_AND_ATTRIBUTES)((ULONG_PTR)tg + sizeof(tg->GroupCount) +
|
||||||
((Token->UserAndGroupCount - 1) * sizeof(SID_AND_ATTRIBUTES)));
|
((Token->UserAndGroupCount - 1) * sizeof(SID_AND_ATTRIBUTES)));
|
||||||
|
|
||||||
tg->GroupCount = Token->UserAndGroupCount - 1;
|
tg->GroupCount = Token->UserAndGroupCount - 1;
|
||||||
|
@ -1312,8 +1686,8 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
|
||||||
&Token->UserAndGroups[1],
|
&Token->UserAndGroups[1],
|
||||||
SidLen,
|
SidLen,
|
||||||
&tg->Groups[0],
|
&tg->Groups[0],
|
||||||
(PSID)Sid,
|
Sid,
|
||||||
&Unused.Ptr,
|
&Unused.PSid,
|
||||||
&Unused.Ulong);
|
&Unused.Ulong);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1373,8 +1747,8 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
|
||||||
|
|
||||||
case TokenOwner:
|
case TokenOwner:
|
||||||
{
|
{
|
||||||
ULONG SidLen;
|
|
||||||
PTOKEN_OWNER to = (PTOKEN_OWNER)TokenInformation;
|
PTOKEN_OWNER to = (PTOKEN_OWNER)TokenInformation;
|
||||||
|
ULONG SidLen;
|
||||||
|
|
||||||
DPRINT("NtQueryInformationToken(TokenOwner)\n");
|
DPRINT("NtQueryInformationToken(TokenOwner)\n");
|
||||||
SidLen = RtlLengthSid(Token->UserAndGroups[Token->DefaultOwnerIndex].Sid);
|
SidLen = RtlLengthSid(Token->UserAndGroups[Token->DefaultOwnerIndex].Sid);
|
||||||
|
@ -1410,8 +1784,8 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
|
||||||
|
|
||||||
case TokenPrimaryGroup:
|
case TokenPrimaryGroup:
|
||||||
{
|
{
|
||||||
ULONG SidLen;
|
|
||||||
PTOKEN_PRIMARY_GROUP tpg = (PTOKEN_PRIMARY_GROUP)TokenInformation;
|
PTOKEN_PRIMARY_GROUP tpg = (PTOKEN_PRIMARY_GROUP)TokenInformation;
|
||||||
|
ULONG SidLen;
|
||||||
|
|
||||||
DPRINT("NtQueryInformationToken(TokenPrimaryGroup)\n");
|
DPRINT("NtQueryInformationToken(TokenPrimaryGroup)\n");
|
||||||
SidLen = RtlLengthSid(Token->PrimaryGroup);
|
SidLen = RtlLengthSid(Token->PrimaryGroup);
|
||||||
|
@ -1453,9 +1827,7 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
|
||||||
RequiredLength = sizeof(TOKEN_DEFAULT_DACL);
|
RequiredLength = sizeof(TOKEN_DEFAULT_DACL);
|
||||||
|
|
||||||
if (Token->DefaultDacl != NULL)
|
if (Token->DefaultDacl != NULL)
|
||||||
{
|
|
||||||
RequiredLength += Token->DefaultDacl->AclSize;
|
RequiredLength += Token->DefaultDacl->AclSize;
|
||||||
}
|
|
||||||
|
|
||||||
_SEH2_TRY
|
_SEH2_TRY
|
||||||
{
|
{
|
||||||
|
@ -1689,7 +2061,7 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
|
||||||
{
|
{
|
||||||
ULONG SidLen = RequiredLength - sizeof(tg->GroupCount) -
|
ULONG SidLen = RequiredLength - sizeof(tg->GroupCount) -
|
||||||
(Token->RestrictedSidCount * sizeof(SID_AND_ATTRIBUTES));
|
(Token->RestrictedSidCount * sizeof(SID_AND_ATTRIBUTES));
|
||||||
PSID_AND_ATTRIBUTES Sid = (PSID_AND_ATTRIBUTES)((ULONG_PTR)TokenInformation + sizeof(tg->GroupCount) +
|
PSID Sid = (PSID)((ULONG_PTR)tg + sizeof(tg->GroupCount) +
|
||||||
(Token->RestrictedSidCount * sizeof(SID_AND_ATTRIBUTES)));
|
(Token->RestrictedSidCount * sizeof(SID_AND_ATTRIBUTES)));
|
||||||
|
|
||||||
tg->GroupCount = Token->RestrictedSidCount;
|
tg->GroupCount = Token->RestrictedSidCount;
|
||||||
|
@ -1697,8 +2069,8 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
|
||||||
Token->RestrictedSids,
|
Token->RestrictedSids,
|
||||||
SidLen,
|
SidLen,
|
||||||
&tg->Groups[0],
|
&tg->Groups[0],
|
||||||
(PSID)Sid,
|
Sid,
|
||||||
&Unused.Ptr,
|
&Unused.PSid,
|
||||||
&Unused.Ulong);
|
&Unused.Ulong);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1731,14 +2103,12 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
|
||||||
|
|
||||||
DPRINT("NtQueryInformationToken(TokenSessionId)\n");
|
DPRINT("NtQueryInformationToken(TokenSessionId)\n");
|
||||||
|
|
||||||
Status = SeQuerySessionIdToken(Token,
|
Status = SeQuerySessionIdToken(Token, &SessionId);
|
||||||
&SessionId);
|
|
||||||
|
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
_SEH2_TRY
|
_SEH2_TRY
|
||||||
{
|
{
|
||||||
/* buffer size was already verified, no need to check here again */
|
/* Buffer size was already verified, no need to check here again */
|
||||||
*(PULONG)TokenInformation = SessionId;
|
*(PULONG)TokenInformation = SessionId;
|
||||||
|
|
||||||
if (ReturnLength != NULL)
|
if (ReturnLength != NULL)
|
||||||
|
@ -1792,7 +2162,7 @@ NtSetInformationToken(IN HANDLE TokenHandle,
|
||||||
|
|
||||||
Status = DefaultSetInfoBufferCheck(TokenInformationClass,
|
Status = DefaultSetInfoBufferCheck(TokenInformationClass,
|
||||||
SeTokenInformationClass,
|
SeTokenInformationClass,
|
||||||
sizeof(SeTokenInformationClass) / sizeof(SeTokenInformationClass[0]),
|
RTL_NUMBER_OF(SeTokenInformationClass),
|
||||||
TokenInformation,
|
TokenInformation,
|
||||||
TokenInformationLength,
|
TokenInformationLength,
|
||||||
PreviousMode);
|
PreviousMode);
|
||||||
|
@ -2179,9 +2549,11 @@ Cleanup:
|
||||||
* @implemented
|
* @implemented
|
||||||
*
|
*
|
||||||
* NOTE: Some sources claim 4th param is ImpersonationLevel, but on W2K
|
* NOTE: Some sources claim 4th param is ImpersonationLevel, but on W2K
|
||||||
* this is certainly NOT true, thou i can't say for sure that EffectiveOnly
|
* this is certainly NOT true, although I can't say for sure that EffectiveOnly
|
||||||
* is correct either. -Gunnar
|
* is correct either. -Gunnar
|
||||||
* This is true. EffectiveOnly overrides SQOS.EffectiveOnly. - IAI
|
* This is true. EffectiveOnly overrides SQOS.EffectiveOnly. - IAI
|
||||||
|
* NOTE for readers: http://hex.pp.ua/nt/NtDuplicateToken.php is therefore
|
||||||
|
* wrong in that regard.
|
||||||
*/
|
*/
|
||||||
NTSTATUS NTAPI
|
NTSTATUS NTAPI
|
||||||
NtDuplicateToken(IN HANDLE ExistingTokenHandle,
|
NtDuplicateToken(IN HANDLE ExistingTokenHandle,
|
||||||
|
@ -2330,7 +2702,7 @@ NtAdjustGroupsToken(IN HANDLE TokenHandle,
|
||||||
OUT PULONG ReturnLength)
|
OUT PULONG ReturnLength)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
UNIMPLEMENTED;
|
||||||
return(STATUS_NOT_IMPLEMENTED);
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1279,13 +1279,13 @@ NTSYSAPI
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
RtlCopySidAndAttributesArray(
|
RtlCopySidAndAttributesArray(
|
||||||
ULONG Count,
|
_In_ ULONG Count,
|
||||||
PSID_AND_ATTRIBUTES Src,
|
_In_ PSID_AND_ATTRIBUTES Src,
|
||||||
ULONG SidAreaSize,
|
_In_ ULONG SidAreaSize,
|
||||||
PSID_AND_ATTRIBUTES Dest,
|
_In_ PSID_AND_ATTRIBUTES Dest,
|
||||||
PVOID SidArea,
|
_In_ PSID SidArea,
|
||||||
PVOID* RemainingSidArea,
|
_Out_ PSID* RemainingSidArea,
|
||||||
PULONG RemainingSidAreaSize
|
_Out_ PULONG RemainingSidAreaSize
|
||||||
);
|
);
|
||||||
|
|
||||||
_IRQL_requires_max_(APC_LEVEL)
|
_IRQL_requires_max_(APC_LEVEL)
|
||||||
|
|
|
@ -250,8 +250,8 @@ RtlCopySidAndAttributesArray(IN ULONG Count,
|
||||||
IN PSID_AND_ATTRIBUTES Src,
|
IN PSID_AND_ATTRIBUTES Src,
|
||||||
IN ULONG SidAreaSize,
|
IN ULONG SidAreaSize,
|
||||||
IN PSID_AND_ATTRIBUTES Dest,
|
IN PSID_AND_ATTRIBUTES Dest,
|
||||||
IN PVOID SidArea,
|
IN PSID SidArea,
|
||||||
OUT PVOID* RemainingSidArea,
|
OUT PSID* RemainingSidArea,
|
||||||
OUT PULONG RemainingSidAreaSize)
|
OUT PULONG RemainingSidAreaSize)
|
||||||
{
|
{
|
||||||
ULONG SidLength, i;
|
ULONG SidLength, i;
|
||||||
|
@ -273,7 +273,7 @@ RtlCopySidAndAttributesArray(IN ULONG Count,
|
||||||
RtlCopySid(SidLength, SidArea, Src[i].Sid);
|
RtlCopySid(SidLength, SidArea, Src[i].Sid);
|
||||||
|
|
||||||
/* Push the buffer area where the SID will reset */
|
/* Push the buffer area where the SID will reset */
|
||||||
SidArea = (PVOID)((ULONG_PTR)SidArea + SidLength);
|
SidArea = (PSID)((ULONG_PTR)SidArea + SidLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return how much space is left, and where the buffer is at now */
|
/* Return how much space is left, and where the buffer is at now */
|
||||||
|
|
|
@ -132,8 +132,6 @@ const KMT_TEST TestList[] =
|
||||||
{ "-ObTypeNoClean", Test_ObTypeNoClean },
|
{ "-ObTypeNoClean", Test_ObTypeNoClean },
|
||||||
{ "ObTypes", Test_ObTypes },
|
{ "ObTypes", Test_ObTypes },
|
||||||
{ "PsNotify", Test_PsNotify },
|
{ "PsNotify", Test_PsNotify },
|
||||||
{ "SeInheritance", Test_SeInheritance },
|
|
||||||
{ "-SeQueryInfoToken", Test_SeQueryInfoToken },
|
|
||||||
{ "RtlAvlTreeKM", Test_RtlAvlTree },
|
{ "RtlAvlTreeKM", Test_RtlAvlTree },
|
||||||
{ "RtlExceptionKM", Test_RtlException },
|
{ "RtlExceptionKM", Test_RtlException },
|
||||||
{ "RtlIntSafeKM", Test_RtlIntSafe },
|
{ "RtlIntSafeKM", Test_RtlIntSafe },
|
||||||
|
@ -142,6 +140,8 @@ const KMT_TEST TestList[] =
|
||||||
{ "RtlRegistryKM", Test_RtlRegistry },
|
{ "RtlRegistryKM", Test_RtlRegistry },
|
||||||
{ "RtlSplayTreeKM", Test_RtlSplayTree },
|
{ "RtlSplayTreeKM", Test_RtlSplayTree },
|
||||||
{ "RtlUnicodeStringKM", Test_RtlUnicodeString },
|
{ "RtlUnicodeStringKM", Test_RtlUnicodeString },
|
||||||
|
{ "SeInheritance", Test_SeInheritance },
|
||||||
|
{ "SeQueryInfoToken", Test_SeQueryInfoToken },
|
||||||
{ "ZwAllocateVirtualMemory", Test_ZwAllocateVirtualMemory },
|
{ "ZwAllocateVirtualMemory", Test_ZwAllocateVirtualMemory },
|
||||||
{ "ZwCreateSection", Test_ZwCreateSection },
|
{ "ZwCreateSection", Test_ZwCreateSection },
|
||||||
{ "ZwMapViewOfSection", Test_ZwMapViewOfSection },
|
{ "ZwMapViewOfSection", Test_ZwMapViewOfSection },
|
||||||
|
|
|
@ -44,10 +44,10 @@ void TestsSeQueryInformationToken(PACCESS_TOKEN Token)
|
||||||
if (Token == NULL) return;
|
if (Token == NULL) return;
|
||||||
|
|
||||||
Status = SeQueryInformationToken(Token, TokenOwner, &Buffer);
|
Status = SeQueryInformationToken(Token, TokenOwner, &Buffer);
|
||||||
ok((Status == STATUS_SUCCESS), "SQIT with TokenOwner arg fails with status 0x%X\n", Status);
|
ok((Status == STATUS_SUCCESS), "SQIT with TokenOwner arg fails with status 0x%08X\n", Status);
|
||||||
if (Status == STATUS_SUCCESS)
|
if (Status == STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenOwner arg. But Buffer = NULL\n");
|
ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenOwner arg. But Buffer == NULL\n");
|
||||||
|
|
||||||
if (Buffer)
|
if (Buffer)
|
||||||
{
|
{
|
||||||
|
@ -62,10 +62,10 @@ void TestsSeQueryInformationToken(PACCESS_TOKEN Token)
|
||||||
|
|
||||||
Buffer = NULL;
|
Buffer = NULL;
|
||||||
Status = SeQueryInformationToken(Token, TokenDefaultDacl, &Buffer);
|
Status = SeQueryInformationToken(Token, TokenDefaultDacl, &Buffer);
|
||||||
ok(Status == STATUS_SUCCESS, "SQIT with TokenDefaultDacl fails with status 0x%X\n", Status);
|
ok(Status == STATUS_SUCCESS, "SQIT with TokenDefaultDacl fails with status 0x%08X\n", Status);
|
||||||
if (Status == STATUS_SUCCESS)
|
if (Status == STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenDefaultDacl arg. But Buffer = NULL\n");
|
ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenDefaultDacl arg. But Buffer == NULL\n");
|
||||||
if (Buffer)
|
if (Buffer)
|
||||||
{
|
{
|
||||||
TDefDacl = (PTOKEN_DEFAULT_DACL)Buffer;
|
TDefDacl = (PTOKEN_DEFAULT_DACL)Buffer;
|
||||||
|
@ -79,10 +79,10 @@ void TestsSeQueryInformationToken(PACCESS_TOKEN Token)
|
||||||
|
|
||||||
Buffer = NULL;
|
Buffer = NULL;
|
||||||
Status = SeQueryInformationToken(Token, TokenGroups, &Buffer);
|
Status = SeQueryInformationToken(Token, TokenGroups, &Buffer);
|
||||||
ok(Status == STATUS_SUCCESS, "SQIT with TokenGroups fails with status 0x%X\n", Status);
|
ok(Status == STATUS_SUCCESS, "SQIT with TokenGroups fails with status 0x%08X\n", Status);
|
||||||
if (Status == STATUS_SUCCESS)
|
if (Status == STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenGroups arg. But Buffer = NULL\n");
|
ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenGroups arg. But Buffer == NULL\n");
|
||||||
if (Buffer)
|
if (Buffer)
|
||||||
{
|
{
|
||||||
TGroups = (PTOKEN_GROUPS)Buffer;
|
TGroups = (PTOKEN_GROUPS)Buffer;
|
||||||
|
@ -107,58 +107,88 @@ void TestsSeQueryInformationToken(PACCESS_TOKEN Token)
|
||||||
// Call SQIT with TokenImpersonationLevel argument
|
// Call SQIT with TokenImpersonationLevel argument
|
||||||
//
|
//
|
||||||
// What's up? Why SQIT fails with right arg?
|
// What's up? Why SQIT fails with right arg?
|
||||||
|
// Because your token has Token->TokenType != TokenImpersonation. -hbelusca
|
||||||
|
|
||||||
Buffer = NULL;
|
Buffer = NULL;
|
||||||
Status = SeQueryInformationToken(Token, TokenImpersonationLevel, &Buffer);
|
Status = SeQueryInformationToken(Token, TokenImpersonationLevel, &Buffer);
|
||||||
ok(Status == STATUS_SUCCESS, "SQIT with TokenImpersonationLevel fails with status 0x%X\n", Status);
|
ok(Status == STATUS_SUCCESS, "SQIT with TokenImpersonationLevel fails with status 0x%08X\n", Status);
|
||||||
|
if (Buffer) ExFreePool(Buffer);
|
||||||
|
|
||||||
Buffer = NULL;
|
Buffer = NULL;
|
||||||
Status = SeQueryInformationToken(Token, TokenImpersonationLevel, &Buffer);
|
Status = SeQueryInformationToken(Token, TokenImpersonationLevel, &Buffer);
|
||||||
ok(Status == STATUS_SUCCESS, "and again: SQIT with TokenImpersonationLevel fails with status 0x%X\n", Status);
|
ok(Status == STATUS_SUCCESS, "and again: SQIT with TokenImpersonationLevel fails with status 0x%08X\n", Status);
|
||||||
if (Status == STATUS_SUCCESS)
|
if (Status == STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenImpersonationLevel arg. But Buffer = NULL\n");
|
ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenImpersonationLevel arg. But Buffer == NULL\n");
|
||||||
} else {
|
} else {
|
||||||
ok(Buffer == NULL, "Wrong. SQIT call is't success. But Buffer != NULL\n");
|
ok(Buffer == NULL, "Wrong. SQIT call failed. But Buffer != NULL\n");
|
||||||
}
|
}
|
||||||
|
if (Buffer) ExFreePool(Buffer);
|
||||||
|
|
||||||
|
//----------------------------------------------------------------//
|
||||||
|
|
||||||
|
// Call SQIT with the 4 classes (TokenOrigin, TokenGroupsAndPrivileges,
|
||||||
|
// TokenRestrictedSids and TokenSandBoxInert) are not supported by
|
||||||
|
// SeQueryInformationToken (only NtQueryInformationToken supports them).
|
||||||
|
//
|
||||||
|
|
||||||
|
Buffer = NULL;
|
||||||
|
Status = SeQueryInformationToken(Token, TokenOrigin, &Buffer);
|
||||||
|
ok(Status == STATUS_INVALID_INFO_CLASS, "SQIT with TokenOrigin failed with Status 0x%08X; expected STATUS_INVALID_INFO_CLASS\n", Status);
|
||||||
|
ok(Buffer == NULL, "Wrong. SQIT call failed. But Buffer != NULL\n");
|
||||||
|
|
||||||
|
Buffer = NULL;
|
||||||
|
Status = SeQueryInformationToken(Token, TokenGroupsAndPrivileges, &Buffer);
|
||||||
|
ok(Status == STATUS_INVALID_INFO_CLASS, "SQIT with TokenGroupsAndPrivileges failed with Status 0x%08X; expected STATUS_INVALID_INFO_CLASS\n", Status);
|
||||||
|
ok(Buffer == NULL, "Wrong. SQIT call failed. But Buffer != NULL\n");
|
||||||
|
|
||||||
|
Buffer = NULL;
|
||||||
|
Status = SeQueryInformationToken(Token, TokenRestrictedSids, &Buffer);
|
||||||
|
ok(Status == STATUS_INVALID_INFO_CLASS, "SQIT with TokenRestrictedSids failed with Status 0x%08X; expected STATUS_INVALID_INFO_CLASS\n", Status);
|
||||||
|
ok(Buffer == NULL, "Wrong. SQIT call failed. But Buffer != NULL\n");
|
||||||
|
|
||||||
|
Buffer = NULL;
|
||||||
|
Status = SeQueryInformationToken(Token, TokenSandBoxInert, &Buffer);
|
||||||
|
ok(Status == STATUS_INVALID_INFO_CLASS, "SQIT with TokenSandBoxInert failed with Status 0x%08X; expected STATUS_INVALID_INFO_CLASS\n", Status);
|
||||||
|
ok(Buffer == NULL, "Wrong. SQIT call failed. But Buffer != NULL\n");
|
||||||
|
|
||||||
//----------------------------------------------------------------//
|
//----------------------------------------------------------------//
|
||||||
|
|
||||||
Buffer = NULL;
|
Buffer = NULL;
|
||||||
Status = SeQueryInformationToken(Token, TokenStatistics, &Buffer);
|
Status = SeQueryInformationToken(Token, TokenStatistics, &Buffer);
|
||||||
ok(Status == STATUS_SUCCESS, "SQIT with TokenStatistics fails with status 0x%X\n", Status);
|
ok(Status == STATUS_SUCCESS, "SQIT with TokenStatistics fails with status 0x%08X\n", Status);
|
||||||
if (Status == STATUS_SUCCESS)
|
if (Status == STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenStatistics arg. But Buffer = NULL\n");
|
ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenStatistics arg. But Buffer == NULL\n");
|
||||||
if (Buffer)
|
if (Buffer)
|
||||||
{
|
{
|
||||||
TStats = (PTOKEN_STATISTICS)Buffer;
|
TStats = (PTOKEN_STATISTICS)Buffer;
|
||||||
// just put 0 into 1st arg or use trace to print TokenStatistics f
|
// just put 0 into 1st arg or use trace to print TokenStatistics
|
||||||
ok(1, "print statistics:\n\tTokenID = %u_%d\n\tSecurityImperLevel = %d\n\tPrivCount = %d\n\tGroupCount = %d\n\n", TStats->TokenId.LowPart,
|
ok(1, "print statistics:\n\tTokenID = %u_%d\n\tSecurityImperLevel = %d\n\tPrivCount = %d\n\tGroupCount = %d\n\n", TStats->TokenId.LowPart,
|
||||||
TStats->TokenId.HighPart,
|
TStats->TokenId.HighPart,
|
||||||
TStats->ImpersonationLevel,
|
TStats->ImpersonationLevel,
|
||||||
TStats->PrivilegeCount,
|
TStats->PrivilegeCount,
|
||||||
TStats->GroupCount
|
TStats->GroupCount
|
||||||
);
|
);
|
||||||
ExFreePool(TStats);
|
ExFreePool(Buffer);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ok(Buffer == NULL, "Wrong. SQIT call is't success. But Buffer != NULL\n");
|
ok(Buffer == NULL, "Wrong. SQIT call failed. But Buffer != NULL\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------//
|
//----------------------------------------------------------------//
|
||||||
|
|
||||||
Buffer = NULL;
|
Buffer = NULL;
|
||||||
Status = SeQueryInformationToken(Token, TokenType, &Buffer);
|
Status = SeQueryInformationToken(Token, TokenType, &Buffer);
|
||||||
ok(Status == STATUS_SUCCESS, "SQIT with TokenType fails with status 0x%X\n", Status);
|
ok(Status == STATUS_SUCCESS, "SQIT with TokenType fails with status 0x%08X\n", Status);
|
||||||
if (Status == STATUS_SUCCESS)
|
if (Status == STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenType arg. But Buffer = NULL\n");
|
ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenType arg. But Buffer == NULL\n");
|
||||||
if (Buffer)
|
if (Buffer)
|
||||||
{
|
{
|
||||||
TType = (PTOKEN_TYPE)Buffer;
|
TType = (PTOKEN_TYPE)Buffer;
|
||||||
ok((*TType == TokenPrimary || *TType == TokenImpersonation), "TokenType in not a primary nor impersonation. FAILED\n");
|
ok((*TType == TokenPrimary || *TType == TokenImpersonation), "TokenType in not a primary nor impersonation. FAILED\n");
|
||||||
ExFreePool(TType);
|
ExFreePool(Buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,12 +199,12 @@ void TestsSeQueryInformationToken(PACCESS_TOKEN Token)
|
||||||
ok(Status == STATUS_SUCCESS, "SQIT with TokenUser fails\n");
|
ok(Status == STATUS_SUCCESS, "SQIT with TokenUser fails\n");
|
||||||
if (Status == STATUS_SUCCESS)
|
if (Status == STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenUser arg. But Buffer = NULL\n");
|
ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenUser arg. But Buffer == NULL\n");
|
||||||
if (Buffer)
|
if (Buffer)
|
||||||
{
|
{
|
||||||
TUser = (PTOKEN_USER)Buffer;
|
TUser = (PTOKEN_USER)Buffer;
|
||||||
ok(RtlValidSid(TUser->User.Sid), "TokenUser has an invalid Sid\n");
|
ok(RtlValidSid(TUser->User.Sid), "TokenUser has an invalid Sid\n");
|
||||||
ExFreePool(TUser);
|
ExFreePool(Buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,7 +267,6 @@ START_TEST(SeQueryInfoToken)
|
||||||
|
|
||||||
SeCaptureSubjectContext(&AccessState->SubjectSecurityContext);
|
SeCaptureSubjectContext(&AccessState->SubjectSecurityContext);
|
||||||
SeLockSubjectContext(&AccessState->SubjectSecurityContext);
|
SeLockSubjectContext(&AccessState->SubjectSecurityContext);
|
||||||
|
|
||||||
Token = SeQuerySubjectContextToken(&AccessState->SubjectSecurityContext);
|
Token = SeQuerySubjectContextToken(&AccessState->SubjectSecurityContext);
|
||||||
|
|
||||||
// Testing SQIT with AccessState Token
|
// Testing SQIT with AccessState Token
|
||||||
|
@ -295,8 +324,7 @@ START_TEST(SeQueryInfoToken)
|
||||||
// Testing SeFreePrivileges //
|
// Testing SeFreePrivileges //
|
||||||
//----------------------------------------------------------------//
|
//----------------------------------------------------------------//
|
||||||
|
|
||||||
Privileges = ExAllocatePool(PagedPool, AuxData->PrivilegeSet->PrivilegeCount*sizeof(PRIVILEGE_SET));
|
Privileges = NULL;
|
||||||
|
|
||||||
Checker = SeAccessCheck(
|
Checker = SeAccessCheck(
|
||||||
AccessState->SecurityDescriptor,
|
AccessState->SecurityDescriptor,
|
||||||
&AccessState->SubjectSecurityContext,
|
&AccessState->SubjectSecurityContext,
|
||||||
|
@ -311,6 +339,11 @@ START_TEST(SeQueryInfoToken)
|
||||||
);
|
);
|
||||||
ok(Checker, "Checker is NULL\n");
|
ok(Checker, "Checker is NULL\n");
|
||||||
ok((Privileges != NULL), "Privileges is NULL\n");
|
ok((Privileges != NULL), "Privileges is NULL\n");
|
||||||
|
if (Privileges)
|
||||||
|
{
|
||||||
|
trace("AuxData->PrivilegeSet->PrivilegeCount = %d ; Privileges->PrivilegeCount = %d\n",
|
||||||
|
AuxData->PrivilegeSet->PrivilegeCount, Privileges->PrivilegeCount);
|
||||||
|
}
|
||||||
if (Privileges) SeFreePrivileges(Privileges);
|
if (Privileges) SeFreePrivileges(Privileges);
|
||||||
|
|
||||||
|
|
||||||
|
@ -326,7 +359,7 @@ START_TEST(SeQueryInfoToken)
|
||||||
Status = SeQueryInformationToken(Token, TokenPrivileges, &Buffer);
|
Status = SeQueryInformationToken(Token, TokenPrivileges, &Buffer);
|
||||||
if (Status == STATUS_SUCCESS)
|
if (Status == STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenPrivileges arg. But Buffer = NULL\n");
|
ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenPrivileges arg. But Buffer == NULL\n");
|
||||||
if (Buffer)
|
if (Buffer)
|
||||||
{
|
{
|
||||||
TPrivileges = (PTOKEN_PRIVILEGES)(Buffer);
|
TPrivileges = (PTOKEN_PRIVILEGES)(Buffer);
|
||||||
|
@ -351,8 +384,7 @@ START_TEST(SeQueryInfoToken)
|
||||||
|
|
||||||
// Call SeFreePrivileges again
|
// Call SeFreePrivileges again
|
||||||
|
|
||||||
Privileges = ExAllocatePool(PagedPool, 20*sizeof(PRIVILEGE_SET));
|
Privileges = NULL;
|
||||||
|
|
||||||
Checker = SeAccessCheck(
|
Checker = SeAccessCheck(
|
||||||
AccessState->SecurityDescriptor,
|
AccessState->SecurityDescriptor,
|
||||||
&AccessState->SubjectSecurityContext,
|
&AccessState->SubjectSecurityContext,
|
||||||
|
@ -367,6 +399,11 @@ START_TEST(SeQueryInfoToken)
|
||||||
);
|
);
|
||||||
ok(Checker, "Checker is NULL\n");
|
ok(Checker, "Checker is NULL\n");
|
||||||
ok((Privileges != NULL), "Privileges is NULL\n");
|
ok((Privileges != NULL), "Privileges is NULL\n");
|
||||||
|
if (Privileges)
|
||||||
|
{
|
||||||
|
trace("AuxData->PrivilegeSet->PrivilegeCount = %d ; Privileges->PrivilegeCount = %d\n",
|
||||||
|
AuxData->PrivilegeSet->PrivilegeCount, Privileges->PrivilegeCount);
|
||||||
|
}
|
||||||
if (Privileges) SeFreePrivileges(Privileges);
|
if (Privileges) SeFreePrivileges(Privileges);
|
||||||
|
|
||||||
//----------------------------------------------------------------//
|
//----------------------------------------------------------------//
|
||||||
|
|
Loading…
Reference in a new issue