372 lines
7.8 KiB
C
372 lines
7.8 KiB
C
/*++
|
||
|
||
Copyright (c) 1989 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
seinit.c
|
||
|
||
Abstract:
|
||
|
||
Executive security components Initialization.
|
||
|
||
Author:
|
||
|
||
Jim Kelly (JimK) 10-May-1990
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
#include "pch.h"
|
||
|
||
#pragma hdrstop
|
||
|
||
#include "adt.h"
|
||
#include <string.h>
|
||
|
||
//
|
||
// Security Database Constants
|
||
//
|
||
|
||
#define SEP_INITIAL_KEY_COUNT 15
|
||
#define SEP_INITIAL_LEVEL_COUNT 6L
|
||
|
||
#ifdef ALLOC_PRAGMA
|
||
#pragma alloc_text(INIT,SeInitSystem)
|
||
#pragma alloc_text(INIT,SepInitializationPhase0)
|
||
#pragma alloc_text(INIT,SepInitializationPhase1)
|
||
#endif
|
||
|
||
BOOLEAN
|
||
SeInitSystem( VOID )
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Perform security related system initialization functions.
|
||
|
||
Arguments:
|
||
|
||
None.
|
||
|
||
Return Value:
|
||
|
||
TRUE - Initialization succeeded.
|
||
|
||
FALSE - Initialization failed.
|
||
|
||
--*/
|
||
|
||
{
|
||
PAGED_CODE();
|
||
|
||
switch ( InitializationPhase ) {
|
||
|
||
case 0 :
|
||
return SepInitializationPhase0();
|
||
case 1 :
|
||
return SepInitializationPhase1();
|
||
default:
|
||
KeBugCheckEx(UNEXPECTED_INITIALIZATION_CALL, 0, InitializationPhase, 0, 0);
|
||
}
|
||
}
|
||
|
||
VOID
|
||
SepInitProcessAuditSd( VOID );
|
||
|
||
|
||
BOOLEAN
|
||
SepInitializationPhase0( VOID )
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Perform phase 0 security initialization.
|
||
|
||
This includes:
|
||
|
||
- Initialize LUID allocation
|
||
- Initialize security global variables
|
||
- initialize the token object.
|
||
- Initialize the necessary security components of the boot thread/process
|
||
|
||
|
||
Arguments:
|
||
|
||
None.
|
||
|
||
Return Value:
|
||
|
||
TRUE - Initialization was successful.
|
||
|
||
FALSE - Initialization Failed.
|
||
|
||
--*/
|
||
|
||
{
|
||
|
||
PAGED_CODE();
|
||
|
||
//
|
||
// LUID allocation services are needed by security prior to phase 0
|
||
// Executive initialization. So, LUID initialization is performed
|
||
// here
|
||
//
|
||
|
||
if (ExLuidInitialization() == FALSE) {
|
||
KdPrint(("Security: Locally Unique ID initialization failed.\n"));
|
||
return FALSE;
|
||
}
|
||
|
||
//
|
||
// Initialize security global variables
|
||
//
|
||
|
||
if (!SepVariableInitialization()) {
|
||
KdPrint(("Security: Global variable initialization failed.\n"));
|
||
return FALSE;
|
||
}
|
||
|
||
//
|
||
// Perform Phase 0 Reference Monitor Initialization.
|
||
//
|
||
|
||
if (!SepRmInitPhase0()) {
|
||
KdPrint(("Security: Ref Mon state initialization failed.\n"));
|
||
return FALSE;
|
||
}
|
||
|
||
//
|
||
// Initialize the token object type.
|
||
//
|
||
|
||
if (!SepTokenInitialization()) {
|
||
KdPrint(("Security: Token object initialization failed.\n"));
|
||
return FALSE;
|
||
}
|
||
|
||
// //
|
||
// // Initialize auditing structures
|
||
// //
|
||
//
|
||
// if (!SepAdtInitializePhase0()) {
|
||
// KdPrint(("Security: Auditing initialization failed.\n"));
|
||
// return FALSE;
|
||
// }
|
||
//
|
||
//
|
||
// Initialize SpinLock and list for the LSA worker thread
|
||
//
|
||
|
||
//
|
||
// Initialize the work queue spinlock, list head, and semaphore
|
||
// for each of the work queues.
|
||
//
|
||
|
||
if (!SepInitializeWorkList()) {
|
||
KdPrint(("Security: Unable to initialize work queue\n"));
|
||
return FALSE;
|
||
}
|
||
|
||
//
|
||
// Initialize the security fields of the boot thread.
|
||
//
|
||
PsGetCurrentThread()->ImpersonationInfo = NULL;
|
||
PS_CLEAR_BITS (&PsGetCurrentThread()->CrossThreadFlags, PS_CROSS_THREAD_FLAGS_IMPERSONATING);
|
||
ObInitializeFastReference (&PsGetCurrentProcess()->Token, NULL);
|
||
|
||
ObInitializeFastReference (&PsGetCurrentProcess()->Token, SeMakeSystemToken());
|
||
|
||
return ( !ExFastRefObjectNull (PsGetCurrentProcess()->Token) );
|
||
}
|
||
|
||
|
||
BOOLEAN
|
||
SepInitializationPhase1( VOID )
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Perform phase 1 security initialization.
|
||
|
||
This includes:
|
||
|
||
- Create an object directory for security related objects.
|
||
(\Security).
|
||
|
||
- Create an event to be signalled after the LSA has initialized.
|
||
(\Security\LSA_Initialized)
|
||
|
||
|
||
|
||
|
||
Arguments:
|
||
|
||
None.
|
||
|
||
Return Value:
|
||
|
||
TRUE - Initialization was successful.
|
||
|
||
FALSE - Initialization Failed.
|
||
|
||
--*/
|
||
|
||
{
|
||
|
||
NTSTATUS Status;
|
||
STRING Name;
|
||
UNICODE_STRING UnicodeName;
|
||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||
HANDLE SecurityRoot, TemporaryHandle;
|
||
PSECURITY_DESCRIPTOR SD ;
|
||
UCHAR SDBuffer[ SECURITY_DESCRIPTOR_MIN_LENGTH ];
|
||
PACL Dacl ;
|
||
|
||
PAGED_CODE();
|
||
|
||
//
|
||
// Insert the system token
|
||
//
|
||
|
||
Status = ObInsertObject( ExFastRefGetObject (PsGetCurrentProcess()->Token),
|
||
NULL,
|
||
0,
|
||
0,
|
||
NULL,
|
||
NULL );
|
||
|
||
ASSERT( NT_SUCCESS(Status) );
|
||
|
||
SeAnonymousLogonToken = SeMakeAnonymousLogonToken();
|
||
ASSERT(SeAnonymousLogonToken != NULL);
|
||
|
||
SeAnonymousLogonTokenNoEveryone = SeMakeAnonymousLogonTokenNoEveryone();
|
||
ASSERT(SeAnonymousLogonTokenNoEveryone != NULL);
|
||
|
||
//
|
||
// Create the security object directory.
|
||
//
|
||
|
||
RtlInitString( &Name, "\\Security" );
|
||
Status = RtlAnsiStringToUnicodeString(
|
||
&UnicodeName,
|
||
&Name,
|
||
TRUE );
|
||
ASSERT( NT_SUCCESS(Status) );
|
||
|
||
//
|
||
// Build up the security descriptor
|
||
//
|
||
|
||
SD = (PSECURITY_DESCRIPTOR) SDBuffer ;
|
||
|
||
RtlCreateSecurityDescriptor( SD,
|
||
SECURITY_DESCRIPTOR_REVISION );
|
||
|
||
Dacl = ExAllocatePool(
|
||
NonPagedPool,
|
||
256 );
|
||
|
||
if ( !Dacl )
|
||
{
|
||
return FALSE ;
|
||
}
|
||
|
||
RtlCreateAcl( Dacl, 256, ACL_REVISION );
|
||
|
||
RtlAddAccessAllowedAce( Dacl,
|
||
ACL_REVISION,
|
||
DIRECTORY_ALL_ACCESS,
|
||
SeLocalSystemSid );
|
||
|
||
RtlAddAccessAllowedAce( Dacl,
|
||
ACL_REVISION,
|
||
DIRECTORY_QUERY | DIRECTORY_TRAVERSE |
|
||
READ_CONTROL,
|
||
SeAliasAdminsSid );
|
||
|
||
RtlAddAccessAllowedAce( Dacl,
|
||
ACL_REVISION,
|
||
DIRECTORY_TRAVERSE,
|
||
SeWorldSid );
|
||
|
||
RtlSetDaclSecurityDescriptor(
|
||
SD,
|
||
TRUE,
|
||
Dacl,
|
||
FALSE );
|
||
|
||
InitializeObjectAttributes(
|
||
&ObjectAttributes,
|
||
&UnicodeName,
|
||
(OBJ_PERMANENT | OBJ_CASE_INSENSITIVE),
|
||
NULL,
|
||
SD
|
||
);
|
||
|
||
Status = NtCreateDirectoryObject(
|
||
&SecurityRoot,
|
||
DIRECTORY_ALL_ACCESS,
|
||
&ObjectAttributes
|
||
);
|
||
RtlFreeUnicodeString( &UnicodeName );
|
||
ASSERTMSG("Security root object directory creation failed.",NT_SUCCESS(Status));
|
||
|
||
ExFreePool( Dacl );
|
||
|
||
//
|
||
// Create an event in the security directory
|
||
//
|
||
|
||
RtlInitString( &Name, "LSA_AUTHENTICATION_INITIALIZED" );
|
||
Status = RtlAnsiStringToUnicodeString(
|
||
&UnicodeName,
|
||
&Name,
|
||
TRUE ); ASSERT( NT_SUCCESS(Status) );
|
||
InitializeObjectAttributes(
|
||
&ObjectAttributes,
|
||
&UnicodeName,
|
||
(OBJ_PERMANENT | OBJ_CASE_INSENSITIVE),
|
||
SecurityRoot,
|
||
SePublicDefaultSd
|
||
);
|
||
|
||
Status = NtCreateEvent(
|
||
&TemporaryHandle,
|
||
GENERIC_WRITE,
|
||
&ObjectAttributes,
|
||
NotificationEvent,
|
||
FALSE
|
||
);
|
||
RtlFreeUnicodeString( &UnicodeName );
|
||
ASSERTMSG("LSA Initialization Event Creation Failed.",NT_SUCCESS(Status));
|
||
|
||
Status = NtClose( SecurityRoot );
|
||
ASSERTMSG("Security object directory handle closure Failed.",NT_SUCCESS(Status));
|
||
Status = NtClose( TemporaryHandle );
|
||
ASSERTMSG("LSA Initialization Event handle closure Failed.",NT_SUCCESS(Status));
|
||
|
||
//
|
||
// Initialize the default SACL to use for auditing
|
||
// accesses to system processes. This initializes SepProcessSacl
|
||
//
|
||
|
||
SepInitProcessAuditSd();
|
||
|
||
#ifndef SETEST
|
||
|
||
return TRUE;
|
||
|
||
#else
|
||
|
||
return SepDevelopmentTest();
|
||
|
||
#endif //SETEST
|
||
|
||
}
|