580 lines
15 KiB
C
580 lines
15 KiB
C
|
//////////////////////////////////////////////////////////////////////////
|
|||
|
// WARNING - WARNING - WARNING - WARNING - WARNING - WARNING - WARNING //
|
|||
|
// //
|
|||
|
// This test file is not current with the security implementation. //
|
|||
|
// This file contains references to data types and APIs that do not //
|
|||
|
// exist. //
|
|||
|
// //
|
|||
|
//////////////////////////////////////////////////////////////////////////
|
|||
|
|
|||
|
/*++
|
|||
|
Copyright (c) 1989 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
tse.c
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
Test program for the SE subcomponent of the NTOS project
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Gary Kimura (garyki) 20-Nov-1989
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
#include <stdio.h>
|
|||
|
|
|||
|
#include "sep.h"
|
|||
|
#include <zwapi.h>
|
|||
|
|
|||
|
BOOLEAN SeTest();
|
|||
|
|
|||
|
#include "ttoken.c"
|
|||
|
|
|||
|
int
|
|||
|
main(
|
|||
|
int argc,
|
|||
|
char *argv[]
|
|||
|
)
|
|||
|
{
|
|||
|
VOID KiSystemStartup();
|
|||
|
|
|||
|
TestFunction = SeTest;
|
|||
|
KiSystemStartup();
|
|||
|
return( 0 );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
SeTest()
|
|||
|
{
|
|||
|
BOOLEAN TestMakeSystemToken();
|
|||
|
BOOLEAN TestTokenCopy();
|
|||
|
BOOLEAN TestTokenSize();
|
|||
|
BOOLEAN TestDefaultObjectMethod();
|
|||
|
BOOLEAN TestCaptureSecurityDescriptor();
|
|||
|
BOOLEAN TestAssignSecurity();
|
|||
|
BOOLEAN TestAccessCheck();
|
|||
|
BOOLEAN TestGenerateMessage();
|
|||
|
|
|||
|
DbgPrint("Start SeTest()\n");
|
|||
|
|
|||
|
if (!TestMakeSystemToken()) {
|
|||
|
DbgPrint("TestMakeSystemToken() Error\n");
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
if (!TestTokenCopy()) {
|
|||
|
DbgPrint("TestTokenCopy() Error\n");
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
if (!TestTokenSize()) {
|
|||
|
DbgPrint("TestTokenSize() Error\n");
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
if (!TestDefaultObjectMethod()) {
|
|||
|
DbgPrint("TestDefaultObjectMethod() Error\n");
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
if (!TestCaptureSecurityDescriptor()) {
|
|||
|
DbgPrint("TestCaptureSecurityDescriptor() Error\n");
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
if (!TestAssignSecurity()) {
|
|||
|
DbgPrint("TestAssignSecurity() Error\n");
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
if (!TestAccessCheck()) {
|
|||
|
DbgPrint("TestAccessCheck() Error\n");
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
if (!TestGenerateMessage()) {
|
|||
|
DbgPrint("TestGenerateMessage() Error\n");
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
DbgPrint("End SeTest()\n");
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
TestMakeSystemToken()
|
|||
|
{
|
|||
|
PACCESS_TOKEN Token;
|
|||
|
|
|||
|
//
|
|||
|
// Make the system token
|
|||
|
//
|
|||
|
|
|||
|
Token = (PACCESS_TOKEN)SeMakeSystemToken( PagedPool );
|
|||
|
|
|||
|
//
|
|||
|
// and check its contents
|
|||
|
//
|
|||
|
|
|||
|
if (!SepIsSystemToken( Token, ((ACCESS_TOKEN *)Token)->Size )) {
|
|||
|
DbgPrint("SepIsSystemToken Error\n");
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
ExFreePool( Token );
|
|||
|
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
TestTokenCopy()
|
|||
|
{
|
|||
|
PACCESS_TOKEN InToken;
|
|||
|
PACCESS_TOKEN OutToken;
|
|||
|
|
|||
|
NTSTATUS Status;
|
|||
|
|
|||
|
ULONG i;
|
|||
|
|
|||
|
//
|
|||
|
// Allocate Buffers, and build a token
|
|||
|
//
|
|||
|
|
|||
|
InToken = (PACCESS_TOKEN)ExAllocatePool(PagedPool, 512);
|
|||
|
OutToken = (PACCESS_TOKEN)ExAllocatePool(PagedPool, 512);
|
|||
|
|
|||
|
BuildToken( Fred, InToken );
|
|||
|
|
|||
|
//
|
|||
|
// Make a copy of the token
|
|||
|
//
|
|||
|
|
|||
|
if (!NT_SUCCESS(Status = SeTokenCopy( InToken, OutToken, 512))) {
|
|||
|
DbgPrint("SeTokenCopy Error: %8lx\n", Status);
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// check both tokens for equality
|
|||
|
//
|
|||
|
|
|||
|
for (i = 0; i < ((ACCESS_TOKEN *)InToken)->Size; i += 1) {
|
|||
|
if (*((PUCHAR)InToken + 1) != *((PUCHAR)OutToken + 1)) {
|
|||
|
DbgPrint("Token copy error\n");
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
ExFreePool( InToken );
|
|||
|
ExFreePool( OutToken );
|
|||
|
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
TestTokenSize()
|
|||
|
{
|
|||
|
PACCESS_TOKEN Token;
|
|||
|
|
|||
|
//
|
|||
|
// Allocate and build a token
|
|||
|
//
|
|||
|
|
|||
|
Token = (PACCESS_TOKEN)ExAllocatePool(PagedPool, 512);
|
|||
|
|
|||
|
BuildToken( Wilma, Token );
|
|||
|
|
|||
|
//
|
|||
|
// Get the token size
|
|||
|
//
|
|||
|
|
|||
|
if (SeTokenSize(Token) != ((ACCESS_TOKEN *)Token)->Size) {
|
|||
|
DbgPrint("SeTokenSize error\n");
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
ExFreePool( Token );
|
|||
|
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
TestDefaultObjectMethod()
|
|||
|
{
|
|||
|
SECURITY_DESCRIPTOR SecurityDescriptor;
|
|||
|
PSECURITY_DESCRIPTOR Buffer;
|
|||
|
PACL Acl;
|
|||
|
NTSTATUS Status;
|
|||
|
PSECURITY_DESCRIPTOR ObjectsSecurityDescriptor;
|
|||
|
ULONG Length;
|
|||
|
|
|||
|
Acl = (PACL)ExAllocatePool( PagedPool, 1024 );
|
|||
|
Buffer = (PSECURITY_DESCRIPTOR)ExAllocatePool( PagedPool, 1024 );
|
|||
|
|
|||
|
BuildAcl( Fred, Acl, 1024 );
|
|||
|
DiscretionarySecurityDescriptor( &SecurityDescriptor, Acl );
|
|||
|
|
|||
|
ObjectsSecurityDescriptor = NULL;
|
|||
|
|
|||
|
//
|
|||
|
// Set the descriptor
|
|||
|
//
|
|||
|
|
|||
|
if (!NT_SUCCESS(Status = SeDefaultObjectMethod( NULL,
|
|||
|
SetSecurityDescriptor,
|
|||
|
&SecurityDescriptor,
|
|||
|
0,
|
|||
|
NULL,
|
|||
|
&ObjectsSecurityDescriptor,
|
|||
|
PagedPool ))) {
|
|||
|
|
|||
|
DbgPrint("SeDefaultObjectMethod setting error: %8lx\n", Status );
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Query the descriptor
|
|||
|
//
|
|||
|
|
|||
|
if (!NT_SUCCESS(Status = SeDefaultObjectMethod( NULL,
|
|||
|
QuerySecurityDescriptor,
|
|||
|
Buffer,
|
|||
|
AllAclInformation,
|
|||
|
&Length,
|
|||
|
&ObjectsSecurityDescriptor,
|
|||
|
PagedPool ))) {
|
|||
|
|
|||
|
DbgPrint("SeDefaultObjectMethod reading error: %8lx\n", Status );
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Replace the descriptor
|
|||
|
//
|
|||
|
|
|||
|
BuildAcl( Wilma, Acl, 1024 );
|
|||
|
|
|||
|
if (!NT_SUCCESS(Status = SeDefaultObjectMethod( NULL,
|
|||
|
SetSecurityDescriptor,
|
|||
|
&SecurityDescriptor,
|
|||
|
AllAclInformation,
|
|||
|
&Length,
|
|||
|
&ObjectsSecurityDescriptor,
|
|||
|
PagedPool ))) {
|
|||
|
|
|||
|
DbgPrint("SeDefaultObjectMethod reading error: %8lx\n", Status );
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Delete the descriptor
|
|||
|
//
|
|||
|
|
|||
|
if (!NT_SUCCESS(Status = SeDefaultObjectMethod( NULL,
|
|||
|
DeleteSecurityDescriptor,
|
|||
|
NULL,
|
|||
|
0,
|
|||
|
NULL,
|
|||
|
&ObjectsSecurityDescriptor,
|
|||
|
PagedPool ))) {
|
|||
|
|
|||
|
DbgPrint("SeDefaultObjectMethod deleting error: %8lx\n", Status );
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
ExFreePool(Acl);
|
|||
|
ExFreePool(Buffer);
|
|||
|
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
TestCaptureSecurityDescriptor()
|
|||
|
{
|
|||
|
SECURITY_DESCRIPTOR SecurityDescriptor;
|
|||
|
PACL Sacl;
|
|||
|
PACL Dacl;
|
|||
|
PSECURITY_DESCRIPTOR NewDescriptor;
|
|||
|
NTSTATUS Status;
|
|||
|
|
|||
|
Sacl = (PACL)ExAllocatePool( PagedPool, 1024 );
|
|||
|
Dacl = (PACL)ExAllocatePool( PagedPool, 1024 );
|
|||
|
BuildAcl( Pebbles, Sacl, 1024 );
|
|||
|
BuildAcl( Barney, Dacl, 1024 );
|
|||
|
|
|||
|
DiscretionarySecurityDescriptor( &SecurityDescriptor, Dacl );
|
|||
|
SecurityDescriptor.SecurityInformationClass = AllAclInformation;
|
|||
|
SecurityDescriptor.SystemAcl = Sacl;
|
|||
|
|
|||
|
//
|
|||
|
// Capture kernel mode and don't force
|
|||
|
//
|
|||
|
|
|||
|
if (!NT_SUCCESS(Status = SeCaptureSecurityDescriptor( &SecurityDescriptor,
|
|||
|
KernelMode,
|
|||
|
PagedPool,
|
|||
|
FALSE,
|
|||
|
&NewDescriptor ))) {
|
|||
|
DbgPrint("SeCapture Error, KernelMode, FALSE : %8lx\n", Status );
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Capture kernel mode and force
|
|||
|
//
|
|||
|
|
|||
|
if (!NT_SUCCESS(Status = SeCaptureSecurityDescriptor( &SecurityDescriptor,
|
|||
|
KernelMode,
|
|||
|
PagedPool,
|
|||
|
TRUE,
|
|||
|
&NewDescriptor ))) {
|
|||
|
DbgPrint("SeCapture Error, KernelMode, TRUE : %8lx\n", Status );
|
|||
|
return FALSE;
|
|||
|
} else {
|
|||
|
ExFreePool( NewDescriptor );
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Capture user mode
|
|||
|
//
|
|||
|
|
|||
|
if (!NT_SUCCESS(Status = SeCaptureSecurityDescriptor( &SecurityDescriptor,
|
|||
|
UserMode,
|
|||
|
PagedPool,
|
|||
|
TRUE,
|
|||
|
&NewDescriptor ))) {
|
|||
|
DbgPrint("SeCapture Error, UserMode, FALSE : %8lx\n", Status );
|
|||
|
return FALSE;
|
|||
|
} else {
|
|||
|
ExFreePool( NewDescriptor );
|
|||
|
}
|
|||
|
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
TestAssignSecurity()
|
|||
|
{
|
|||
|
SECURITY_DESCRIPTOR SecurityDescriptor;
|
|||
|
PACL Acl;
|
|||
|
|
|||
|
PACCESS_TOKEN Token;
|
|||
|
|
|||
|
GENERIC_MAPPING GenericMapping;
|
|||
|
|
|||
|
PSECURITY_DESCRIPTOR NewDescriptor;
|
|||
|
|
|||
|
NTSTATUS Status;
|
|||
|
|
|||
|
Acl = (PACL)ExAllocatePool( PagedPool, 1024 );
|
|||
|
BuildAcl( Fred, Acl, 1024 );
|
|||
|
|
|||
|
Token = (PACCESS_TOKEN)ExAllocatePool( PagedPool, 512 );
|
|||
|
BuildToken( Fred, Token );
|
|||
|
|
|||
|
DiscretionarySecurityDescriptor( &SecurityDescriptor, Acl );
|
|||
|
|
|||
|
//
|
|||
|
// Kernel mode, non dir, and no new
|
|||
|
//
|
|||
|
|
|||
|
NewDescriptor = NULL;
|
|||
|
if (!NT_SUCCESS(Status = SeAssignSecurity( &SecurityDescriptor,
|
|||
|
&NewDescriptor,
|
|||
|
FALSE,
|
|||
|
Token,
|
|||
|
&GenericMapping,
|
|||
|
KernelMode ))) {
|
|||
|
DbgPrint("SeAssign Error NoNew, NoDir, Kernel : %8lx\n", Status );
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Kernel mode, non dir, and new
|
|||
|
//
|
|||
|
|
|||
|
if (!NT_SUCCESS(Status = SeAssignSecurity( &SecurityDescriptor,
|
|||
|
&NewDescriptor,
|
|||
|
FALSE,
|
|||
|
Token,
|
|||
|
&GenericMapping,
|
|||
|
KernelMode ))) {
|
|||
|
DbgPrint("SeAssign Error New, NoDir, Kernel : %8lx\n", Status );
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Kernel mode, dir, and no new
|
|||
|
//
|
|||
|
|
|||
|
NewDescriptor = NULL;
|
|||
|
if (!NT_SUCCESS(Status = SeAssignSecurity( &SecurityDescriptor,
|
|||
|
&NewDescriptor,
|
|||
|
TRUE,
|
|||
|
Token,
|
|||
|
&GenericMapping,
|
|||
|
KernelMode ))) {
|
|||
|
DbgPrint("SeAssign Error NoNew, Dir, Kernel : %8lx\n", Status );
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Kernel mode, dir, and new
|
|||
|
//
|
|||
|
|
|||
|
if (!NT_SUCCESS(Status = SeAssignSecurity( &SecurityDescriptor,
|
|||
|
&NewDescriptor,
|
|||
|
TRUE,
|
|||
|
Token,
|
|||
|
&GenericMapping,
|
|||
|
KernelMode ))) {
|
|||
|
DbgPrint("SeAssign Error New, Dir, Kernel : %8lx\n", Status );
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// User mode, non dir, and no new
|
|||
|
//
|
|||
|
|
|||
|
NewDescriptor = NULL;
|
|||
|
if (!NT_SUCCESS(Status = SeAssignSecurity( &SecurityDescriptor,
|
|||
|
&NewDescriptor,
|
|||
|
FALSE,
|
|||
|
Token,
|
|||
|
&GenericMapping,
|
|||
|
UserMode ))) {
|
|||
|
DbgPrint("SeAssign Error NoNew, NoDir, User : %8lx\n", Status );
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// User mode, non dir, and new
|
|||
|
//
|
|||
|
|
|||
|
if (!NT_SUCCESS(Status = SeAssignSecurity( &SecurityDescriptor,
|
|||
|
&NewDescriptor,
|
|||
|
FALSE,
|
|||
|
Token,
|
|||
|
&GenericMapping,
|
|||
|
UserMode ))) {
|
|||
|
DbgPrint("SeAssign Error New, NoDir, User : %8lx\n", Status );
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// User mode, dir, and no new
|
|||
|
//
|
|||
|
|
|||
|
NewDescriptor = NULL;
|
|||
|
if (!NT_SUCCESS(Status = SeAssignSecurity( &SecurityDescriptor,
|
|||
|
&NewDescriptor,
|
|||
|
TRUE,
|
|||
|
Token,
|
|||
|
&GenericMapping,
|
|||
|
UserMode ))) {
|
|||
|
DbgPrint("SeAssign Error NoNew, Dir, User : %8lx\n", Status );
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// User mode, dir, and new
|
|||
|
//
|
|||
|
|
|||
|
if (!NT_SUCCESS(Status = SeAssignSecurity( &SecurityDescriptor,
|
|||
|
&NewDescriptor,
|
|||
|
TRUE,
|
|||
|
Token,
|
|||
|
&GenericMapping,
|
|||
|
UserMode ))) {
|
|||
|
DbgPrint("SeAssign Error New, Dir, User : %8lx\n", Status );
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
TestAccessCheck()
|
|||
|
{
|
|||
|
SECURITY_DESCRIPTOR SecurityDescriptor;
|
|||
|
PACL Acl;
|
|||
|
|
|||
|
PACCESS_TOKEN Token;
|
|||
|
|
|||
|
Acl = (PACL)ExAllocatePool( PagedPool, 1024 );
|
|||
|
BuildAcl( Fred, Acl, 1024 );
|
|||
|
|
|||
|
Token = (PACCESS_TOKEN)ExAllocatePool( PagedPool, 512 );
|
|||
|
BuildToken( Fred, Token );
|
|||
|
|
|||
|
DiscretionarySecurityDescriptor( &SecurityDescriptor, Acl );
|
|||
|
|
|||
|
//
|
|||
|
// Test should be successful based on aces
|
|||
|
//
|
|||
|
|
|||
|
if (!SeAccessCheck( &SecurityDescriptor,
|
|||
|
Token,
|
|||
|
0x00000001,
|
|||
|
NULL,
|
|||
|
UserMode )) {
|
|||
|
DbgPrint("SeAccessCheck Error should allow access\n");
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Test should be successful based on owner
|
|||
|
//
|
|||
|
|
|||
|
if (!SeAccessCheck( &SecurityDescriptor,
|
|||
|
Token,
|
|||
|
READ_CONTROL,
|
|||
|
&FredGuid,
|
|||
|
UserMode )) {
|
|||
|
DbgPrint("SeAccessCheck Error should allow owner\n");
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Test should be unsuccessful based on aces
|
|||
|
//
|
|||
|
|
|||
|
if (SeAccessCheck( &SecurityDescriptor,
|
|||
|
Token,
|
|||
|
0x0000000f,
|
|||
|
&FredGuid,
|
|||
|
UserMode )) {
|
|||
|
DbgPrint("SeAccessCheck Error shouldn't allow access\n");
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Test should be unsuccessful based on non owner
|
|||
|
//
|
|||
|
|
|||
|
if (SeAccessCheck( &SecurityDescriptor,
|
|||
|
Token,
|
|||
|
READ_CONTROL,
|
|||
|
&BarneyGuid,
|
|||
|
UserMode )) {
|
|||
|
DbgPrint("SeAccessCheck Error shouldn't allow non owner access\n");
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
TestGenerateMessage()
|
|||
|
{
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
|