2013-06-05 23:16:14 +00:00
/*
* PROJECT : ReactOS kernel - mode tests
* LICENSE : GPLv2 + - See COPYING in the top level directory
* PURPOSE : Kernel - Mode Test Suite Process Notification Routines test
* PROGRAMMER : Constantine Belev ( Moscow State Technical University )
* Denis Grishin ( Moscow State Technical University )
* Egor Sinitsyn ( Moscow State Technical University )
*/
# include <kmt_test.h>
# include <ntifs.h>
# define NDEBUG
# include <debug.h>
//------------------------------------------------------------------------------//
2013-06-06 09:44:34 +00:00
// Functions required forWorking with ACCESS_STATE structure //
2013-06-05 23:16:14 +00:00
//------------------------------------------------------------------------------//
NTKERNELAPI NTSTATUS NTAPI SeCreateAccessState (
PACCESS_STATE AccessState ,
PVOID AuxData ,
ACCESS_MASK DesiredAccess ,
PGENERIC_MAPPING Mapping
) ;
NTKERNELAPI VOID NTAPI SeDeleteAccessState (
PACCESS_STATE AccessState
) ;
//------------------------------------------------------------------------------//
2013-06-06 09:44:34 +00:00
// Testing Functions //
2013-06-05 23:16:14 +00:00
//------------------------------------------------------------------------------//
// Testing function for SQIT
void TestsSeQueryInformationToken ( PACCESS_TOKEN Token )
{
NTSTATUS Status ;
PVOID Buffer = NULL ;
PSID sid ;
PTOKEN_OWNER Towner ;
PTOKEN_DEFAULT_DACL TDefDacl ;
PTOKEN_GROUPS TGroups ;
ULONG GroupCount ;
PACL acl ;
PTOKEN_STATISTICS TStats ;
PTOKEN_TYPE TType ;
PTOKEN_USER TUser ;
2013-06-06 21:54:00 +00:00
BOOLEAN Flag ;
ULONG i ;
2013-06-05 23:16:14 +00:00
//----------------------------------------------------------------//
2013-06-06 09:44:34 +00:00
// Testing SeQueryInformationToken with various args //
2013-06-05 23:16:14 +00:00
//----------------------------------------------------------------//
ok ( Token ! = NULL , " Token is not captured. Testing SQIT interrupted \n \n " ) ;
if ( Token = = NULL ) return ;
Status = SeQueryInformationToken ( Token , TokenOwner , & Buffer ) ;
2013-06-06 09:44:34 +00:00
ok ( ( Status = = STATUS_SUCCESS ) , " SQIT with TokenOwner arg fails with status 0x%X \n " , Status ) ;
if ( Status = = STATUS_SUCCESS )
2013-06-05 23:16:14 +00:00
{
2013-06-06 09:44:34 +00:00
ok ( Buffer ! = NULL , " Wrong. SQIT call was successful with TokenOwner arg. But Buffer = NULL \n " ) ;
if ( Buffer )
{
Towner = ( TOKEN_OWNER * ) Buffer ;
sid = Towner - > Owner ;
ok ( ( RtlValidSid ( sid ) = = TRUE ) , " TokenOwner's SID is not a valid SID \n " ) ;
ExFreePool ( Buffer ) ;
}
2013-06-05 23:16:14 +00:00
}
2013-06-06 09:44:34 +00:00
//----------------------------------------------------------------//
Buffer = NULL ;
Status = SeQueryInformationToken ( Token , TokenDefaultDacl , & Buffer ) ;
ok ( Status = = STATUS_SUCCESS , " SQIT with TokenDefaultDacl fails with status 0x%X \n " , Status ) ;
if ( Status = = STATUS_SUCCESS )
{
ok ( Buffer ! = NULL , " Wrong. SQIT call was successful with TokenDefaultDacl arg. But Buffer = NULL \n " ) ;
if ( Buffer )
{
TDefDacl = ( PTOKEN_DEFAULT_DACL ) Buffer ;
acl = TDefDacl - > DefaultDacl ;
ok ( ( ( acl - > AclRevision = = ACL_REVISION | | acl - > AclRevision = = ACL_REVISION_DS ) = = TRUE ) , " DACL is invalid \n " ) ;
ExFreePool ( Buffer ) ;
}
2013-06-05 23:16:14 +00:00
}
2013-06-06 09:44:34 +00:00
//----------------------------------------------------------------//
Buffer = NULL ;
Status = SeQueryInformationToken ( Token , TokenGroups , & Buffer ) ;
ok ( Status = = STATUS_SUCCESS , " SQIT with TokenGroups fails with status 0x%X \n " , Status ) ;
if ( Status = = STATUS_SUCCESS )
2013-06-05 23:16:14 +00:00
{
2013-06-06 09:44:34 +00:00
ok ( Buffer ! = NULL , " Wrong. SQIT call was successful with TokenGroups arg. But Buffer = NULL \n " ) ;
if ( Buffer )
2013-06-05 23:16:14 +00:00
{
2013-06-06 09:44:34 +00:00
TGroups = ( PTOKEN_GROUPS ) Buffer ;
GroupCount = TGroups - > GroupCount ;
2013-06-06 21:54:00 +00:00
Flag = TRUE ;
2013-06-06 09:44:34 +00:00
for ( i = 0 ; i < GroupCount ; i + + )
2013-06-05 23:16:14 +00:00
{
2013-06-06 09:44:34 +00:00
sid = TGroups - > Groups [ i ] . Sid ;
if ( ! RtlValidSid ( sid ) )
{
2013-06-06 21:54:00 +00:00
Flag = FALSE ;
2013-06-06 09:44:34 +00:00
break ;
}
2013-06-05 23:16:14 +00:00
}
2013-06-06 21:54:00 +00:00
ok ( ( Flag = = TRUE ) , " TokenGroup's SIDs are not valid \n " ) ;
2013-06-06 09:44:34 +00:00
ExFreePool ( Buffer ) ;
2013-06-05 23:16:14 +00:00
}
}
//----------------------------------------------------------------//
2013-06-06 09:44:34 +00:00
// Call SQIT with TokenImpersonationLevel argument
//
// What's up? Why SQIT fails with right arg?
2013-06-05 23:16:14 +00:00
2013-06-06 09:44:34 +00:00
Buffer = NULL ;
Status = SeQueryInformationToken ( Token , TokenImpersonationLevel , & Buffer ) ;
ok ( Status = = STATUS_SUCCESS , " SQIT with TokenImpersonationLevel fails with status 0x%X \n " , Status ) ;
2013-06-05 23:16:14 +00:00
2013-06-06 09:44:34 +00:00
Buffer = NULL ;
Status = SeQueryInformationToken ( Token , TokenImpersonationLevel , & Buffer ) ;
ok ( Status = = STATUS_SUCCESS , " and again: SQIT with TokenImpersonationLevel fails with status 0x%X \n " , Status ) ;
if ( Status = = STATUS_SUCCESS )
2013-06-05 23:16:14 +00:00
{
2013-06-06 09:44:34 +00:00
ok ( Buffer ! = NULL , " Wrong. SQIT call was successful with TokenImpersonationLevel arg. But Buffer = NULL \n " ) ;
} else {
ok ( Buffer = = NULL , " Wrong. SQIT call is't success. But Buffer != NULL \n " ) ;
2013-06-05 23:16:14 +00:00
}
//----------------------------------------------------------------//
2013-06-06 09:44:34 +00:00
Buffer = NULL ;
Status = SeQueryInformationToken ( Token , TokenStatistics , & Buffer ) ;
ok ( Status = = STATUS_SUCCESS , " SQIT with TokenStatistics fails with status 0x%X \n " , Status ) ;
if ( Status = = STATUS_SUCCESS )
2013-06-05 23:16:14 +00:00
{
2013-06-06 09:44:34 +00:00
ok ( Buffer ! = NULL , " Wrong. SQIT call was successful with TokenStatistics arg. But Buffer = NULL \n " ) ;
if ( Buffer )
{
TStats = ( PTOKEN_STATISTICS ) Buffer ;
// just put 0 into 1st arg or use trace to print TokenStatistics f
ok ( 1 , " print statistics: \n \t TokenID = %u_%d \n \t SecurityImperLevel = %d \n \t PrivCount = %d \n \t GroupCount = %d \n \n " , TStats - > TokenId . LowPart ,
TStats - > TokenId . HighPart ,
TStats - > ImpersonationLevel ,
TStats - > PrivilegeCount ,
TStats - > GroupCount
) ;
ExFreePool ( TStats ) ;
}
} else {
ok ( Buffer = = NULL , " Wrong. SQIT call is't success. But Buffer != NULL \n " ) ;
2013-06-05 23:16:14 +00:00
}
//----------------------------------------------------------------//
2013-06-06 09:44:34 +00:00
Buffer = NULL ;
Status = SeQueryInformationToken ( Token , TokenType , & Buffer ) ;
ok ( Status = = STATUS_SUCCESS , " SQIT with TokenType fails with status 0x%X \n " , Status ) ;
if ( Status = = STATUS_SUCCESS )
2013-06-05 23:16:14 +00:00
{
2013-06-06 09:44:34 +00:00
ok ( Buffer ! = NULL , " Wrong. SQIT call was successful with TokenType arg. But Buffer = NULL \n " ) ;
if ( Buffer )
{
TType = ( PTOKEN_TYPE ) Buffer ;
ok ( ( * TType = = TokenPrimary | | * TType = = TokenImpersonation ) , " TokenType in not a primary nor impersonation. FAILED \n " ) ;
ExFreePool ( TType ) ;
}
2013-06-05 23:16:14 +00:00
}
//----------------------------------------------------------------//
2013-06-06 09:44:34 +00:00
Buffer = NULL ;
Status = SeQueryInformationToken ( Token , TokenUser , & Buffer ) ;
ok ( Status = = STATUS_SUCCESS , " SQIT with TokenUser fails \n " ) ;
if ( Status = = STATUS_SUCCESS )
{
ok ( Buffer ! = NULL , " Wrong. SQIT call was successful with TokenUser arg. But Buffer = NULL \n " ) ;
if ( Buffer )
{
TUser = ( PTOKEN_USER ) Buffer ;
ok ( RtlValidSid ( TUser - > User . Sid ) , " TokenUser has an invalid Sid \n " ) ;
ExFreePool ( TUser ) ;
}
}
//----------------------------------------------------------------//
2013-06-05 23:16:14 +00:00
2013-06-06 09:44:34 +00:00
Buffer = NULL ;
2013-06-05 23:16:14 +00:00
Status = SeQueryInformationToken ( Token , TokenSandBoxInert , & Buffer ) ;
ok ( Status ! = STATUS_SUCCESS , " SQIT must fail with wrong TOKEN_INFORMATION_CLASS arg \n " ) ;
}
//------------------------------------------------------------------------------//
//------------------------------------------------------------------------------//
2013-06-06 09:44:34 +00:00
// Body of the main test //
2013-06-05 23:16:14 +00:00
//------------------------------------------------------------------------------//
START_TEST ( SeQueryInfoToken )
{
PACCESS_STATE AccessState ;
ACCESS_MASK AccessMask = MAXIMUM_ALLOWED ;
ACCESS_MASK DesiredAccess = MAXIMUM_ALLOWED ;
NTSTATUS Status = STATUS_SUCCESS ;
PAUX_ACCESS_DATA AuxData = NULL ;
PPRIVILEGE_SET NewPrivilegeSet ;
BOOLEAN Checker ;
PPRIVILEGE_SET Privileges = NULL ;
PSECURITY_SUBJECT_CONTEXT SubjectContext = NULL ;
PACCESS_TOKEN Token = NULL ;
PTOKEN_PRIVILEGES TPrivileges ;
PVOID Buffer ;
POBJECT_TYPE PsProcessType = NULL ;
PGENERIC_MAPPING GenericMapping ;
2013-06-06 21:54:00 +00:00
ULONG i ;
2013-06-05 23:16:14 +00:00
SubjectContext = ExAllocatePool ( PagedPool , sizeof ( SECURITY_SUBJECT_CONTEXT ) ) ;
SeCaptureSubjectContext ( SubjectContext ) ;
SeLockSubjectContext ( SubjectContext ) ;
Token = SeQuerySubjectContextToken ( SubjectContext ) ;
// Testing SQIT with current Token
TestsSeQueryInformationToken ( Token ) ;
//----------------------------------------------------------------//
2013-06-06 09:44:34 +00:00
// Creating an ACCESS_STATE structure //
2013-06-05 23:16:14 +00:00
//----------------------------------------------------------------//
AccessState = ExAllocatePool ( PagedPool , sizeof ( ACCESS_STATE ) ) ;
PsProcessType = ExAllocatePool ( PagedPool , sizeof ( OBJECT_TYPE ) ) ;
AuxData = ExAllocatePool ( PagedPool , 0xC8 ) ;
GenericMapping = ExAllocatePool ( PagedPool , sizeof ( GENERIC_MAPPING ) ) ;
Status = SeCreateAccessState ( AccessState ,
( PVOID ) AuxData ,
DesiredAccess ,
GenericMapping
) ;
ok ( ( Status = = STATUS_SUCCESS ) , " SeCreateAccessState failed with Status 0x%08X \n " , Status ) ;
SeCaptureSubjectContext ( & AccessState - > SubjectSecurityContext ) ;
SeLockSubjectContext ( & AccessState - > SubjectSecurityContext ) ;
Token = SeQuerySubjectContextToken ( & AccessState - > SubjectSecurityContext ) ;
2013-06-06 09:44:34 +00:00
// Testing SQIT with AccessState Token
2013-06-05 23:16:14 +00:00
TestsSeQueryInformationToken ( Token ) ;
//----------------------------------------------------------------//
2013-06-06 09:44:34 +00:00
// Testing other functions //
2013-06-05 23:16:14 +00:00
//----------------------------------------------------------------//
//----------------------------------------------------------------//
2013-06-06 09:44:34 +00:00
// Testing SeAppendPrivileges //
2013-06-05 23:16:14 +00:00
//----------------------------------------------------------------//
AuxData - > PrivilegeSet - > PrivilegeCount = 1 ;
2013-06-06 09:44:34 +00:00
// Testing SeAppendPrivileges. Must change PrivilegeCount to 2 (1 + 1)
2013-06-05 23:16:14 +00:00
NewPrivilegeSet = ExAllocatePool ( PagedPool , sizeof ( PRIVILEGE_SET ) ) ;
NewPrivilegeSet - > PrivilegeCount = 1 ;
2013-06-06 09:44:34 +00:00
Status = SeAppendPrivileges ( AccessState , NewPrivilegeSet ) ;
ok ( Status = = STATUS_SUCCESS , " SeAppendPrivileges failed \n " ) ;
2013-06-05 23:16:14 +00:00
ok ( ( AuxData - > PrivilegeSet - > PrivilegeCount = = 2 ) , " PrivelegeCount must be 2, but it is %d \n " , AuxData - > PrivilegeSet - > PrivilegeCount ) ;
ExFreePool ( NewPrivilegeSet ) ;
//----------------------------------------------------------------//
// Testing SeAppendPrivileges. Must change PrivilegeCount to 6 (2 + 4)
NewPrivilegeSet = ExAllocatePool ( PagedPool , 4 * sizeof ( PRIVILEGE_SET ) ) ;
NewPrivilegeSet - > PrivilegeCount = 4 ;
2013-06-06 09:44:34 +00:00
Status = SeAppendPrivileges ( AccessState , NewPrivilegeSet ) ;
ok ( Status = = STATUS_SUCCESS , " SeAppendPrivileges failed \n " ) ;
2013-06-05 23:16:14 +00:00
ok ( ( AuxData - > PrivilegeSet - > PrivilegeCount = = 6 ) , " PrivelegeCount must be 6, but it is %d \n " , AuxData - > PrivilegeSet - > PrivilegeCount ) ;
ExFreePool ( NewPrivilegeSet ) ;
//----------------------------------------------------------------//
2013-06-06 09:44:34 +00:00
// Testing SePrivilegeCheck //
2013-06-05 23:16:14 +00:00
//----------------------------------------------------------------//
// KPROCESSOR_MODE is set to KernelMode ===> Always return TRUE
ok ( SePrivilegeCheck ( AuxData - > PrivilegeSet , & ( AccessState - > SubjectSecurityContext ) , KernelMode ) , " SePrivilegeCheck failed with KernelMode mode arg \n " ) ;
// and call it again
ok ( SePrivilegeCheck ( AuxData - > PrivilegeSet , & ( AccessState - > SubjectSecurityContext ) , KernelMode ) , " SePrivilegeCheck failed with KernelMode mode arg \n " ) ;
//----------------------------------------------------------------//
// KPROCESSOR_MODE is set to UserMode. Expect false
ok ( ! SePrivilegeCheck ( AuxData - > PrivilegeSet , & ( AccessState - > SubjectSecurityContext ) , UserMode ) , " SePrivilegeCheck unexpected success with UserMode arg \n " ) ;
//----------------------------------------------------------------//
//----------------------------------------------------------------//
2013-06-06 09:44:34 +00:00
// Testing SeFreePrivileges //
2013-06-05 23:16:14 +00:00
//----------------------------------------------------------------//
Privileges = ExAllocatePool ( PagedPool , AuxData - > PrivilegeSet - > PrivilegeCount * sizeof ( PRIVILEGE_SET ) ) ;
Checker = SeAccessCheck (
AccessState - > SecurityDescriptor ,
& AccessState - > SubjectSecurityContext ,
FALSE ,
AccessState - > OriginalDesiredAccess ,
AccessState - > PreviouslyGrantedAccess ,
& Privileges ,
( PGENERIC_MAPPING ) ( ( PCHAR * ) PsProcessType + 52 ) ,
KernelMode ,
& AccessMask ,
& Status
) ;
ok ( Checker , " Checker is NULL \n " ) ;
ok ( ( Privileges ! = NULL ) , " Privileges is NULL \n " ) ;
if ( Privileges ) SeFreePrivileges ( Privileges ) ;
//----------------------------------------------------------------//
2013-06-06 09:44:34 +00:00
// Testing SePrivilegeCheck //
2013-06-05 23:16:14 +00:00
//----------------------------------------------------------------//
// I'm trying to make success call of SePrivilegeCheck from UserMode
// If we sets Privileges properly, can we expect true from SePrivilegeCheck?
// answer: yes
// This test demonstrates it
2013-06-06 09:44:34 +00:00
Buffer = NULL ;
Status = SeQueryInformationToken ( Token , TokenPrivileges , & Buffer ) ;
if ( Status = = STATUS_SUCCESS )
2013-06-05 23:16:14 +00:00
{
2013-06-06 09:44:34 +00:00
ok ( Buffer ! = NULL , " Wrong. SQIT call was successful with TokenPrivileges arg. But Buffer = NULL \n " ) ;
if ( Buffer )
{
TPrivileges = ( PTOKEN_PRIVILEGES ) ( Buffer ) ;
//trace("TPCount = %u\n\n", TPrivileges->PrivilegeCount);
2013-06-05 23:16:14 +00:00
2013-06-06 09:44:34 +00:00
NewPrivilegeSet = ExAllocatePool ( PagedPool , 14 * sizeof ( PRIVILEGE_SET ) ) ;
NewPrivilegeSet - > PrivilegeCount = 14 ;
2013-06-05 23:16:14 +00:00
2013-06-06 09:44:34 +00:00
ok ( ( SeAppendPrivileges ( AccessState , NewPrivilegeSet ) ) = = STATUS_SUCCESS , " SeAppendPrivileges failed \n " ) ;
ok ( ( AuxData - > PrivilegeSet - > PrivilegeCount = = 20 ) , " PrivelegeCount must be 20, but it is %d \n " , AuxData - > PrivilegeSet - > PrivilegeCount ) ;
ExFreePool ( NewPrivilegeSet ) ;
for ( i = 0 ; i < AuxData - > PrivilegeSet - > PrivilegeCount ; i + + )
{
AuxData - > PrivilegeSet - > Privilege [ i ] . Attributes = TPrivileges - > Privileges [ i ] . Attributes ;
AuxData - > PrivilegeSet - > Privilege [ i ] . Luid = TPrivileges - > Privileges [ i ] . Luid ;
}
//trace("AccessState->privCount = %u\n\n", ((PAUX_ACCESS_DATA)(AccessState->AuxData))->PrivilegeSet->PrivilegeCount);
2013-06-05 23:16:14 +00:00
2013-06-06 09:44:34 +00:00
ok ( SePrivilegeCheck ( AuxData - > PrivilegeSet , & ( AccessState - > SubjectSecurityContext ) , UserMode ) , " SePrivilegeCheck fails in UserMode, but I wish it will success \n " ) ;
}
2013-06-05 23:16:14 +00:00
}
// Call SeFreePrivileges again
Privileges = ExAllocatePool ( PagedPool , 20 * sizeof ( PRIVILEGE_SET ) ) ;
Checker = SeAccessCheck (
AccessState - > SecurityDescriptor ,
& AccessState - > SubjectSecurityContext ,
TRUE ,
AccessState - > OriginalDesiredAccess ,
AccessState - > PreviouslyGrantedAccess ,
& Privileges ,
( PGENERIC_MAPPING ) ( ( PCHAR * ) PsProcessType + 52 ) ,
KernelMode ,
& AccessMask ,
& Status
) ;
ok ( Checker , " Checker is NULL \n " ) ;
ok ( ( Privileges ! = NULL ) , " Privileges is NULL \n " ) ;
if ( Privileges ) SeFreePrivileges ( Privileges ) ;
//----------------------------------------------------------------//
2013-06-06 09:44:34 +00:00
// Missing for now //
2013-06-05 23:16:14 +00:00
//----------------------------------------------------------------//
SeUnlockSubjectContext ( & AccessState - > SubjectSecurityContext ) ;
SeUnlockSubjectContext ( SubjectContext ) ;
SeDeleteAccessState ( AccessState ) ;
if ( GenericMapping ) ExFreePool ( GenericMapping ) ;
if ( PsProcessType ) ExFreePool ( PsProcessType ) ;
if ( SubjectContext ) ExFreePool ( SubjectContext ) ;
if ( AuxData ) ExFreePool ( AuxData ) ;
if ( AccessState ) ExFreePool ( AccessState ) ;
2013-06-06 09:44:34 +00:00
}