966 lines
29 KiB
C
966 lines
29 KiB
C
/*++
|
||
|
||
Copyright (c) 1989 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
seglobal.c
|
||
|
||
Abstract:
|
||
|
||
This module contains the global variables used and exported by the security
|
||
component.
|
||
|
||
Author:
|
||
|
||
Jim Kelly (JimK) 5-Aug-1990
|
||
|
||
Environment:
|
||
|
||
Kernel mode only.
|
||
|
||
Revision History:
|
||
|
||
|
||
--*/
|
||
|
||
#include "sep.h"
|
||
#include "adt.h"
|
||
#include "seopaque.h"
|
||
|
||
VOID
|
||
SepInitializePrivilegeSets( VOID );
|
||
|
||
|
||
VOID
|
||
SepInitSystemDacls( VOID );
|
||
|
||
|
||
#ifdef ALLOC_PRAGMA
|
||
#pragma alloc_text(INIT,SepVariableInitialization)
|
||
#pragma alloc_text(INIT,SepInitializePrivilegeSets)
|
||
#pragma alloc_text(INIT,SepInitSystemDacls)
|
||
#pragma alloc_text(INIT,SepInitializeWorkList)
|
||
#pragma alloc_text(PAGE,SepAssemblePrivileges)
|
||
#endif
|
||
|
||
#ifdef SE_DIAGNOSTICS_ENABLED
|
||
|
||
//
|
||
// Used to control the active SE diagnostic support provided
|
||
//
|
||
|
||
ULONG SeGlobalFlag = 0;
|
||
|
||
#endif // SE_DIAGNOSTICS_ENABLED
|
||
|
||
|
||
|
||
////////////////////////////////////////////////////////////////////////
|
||
// //
|
||
// Global, READ ONLY, Security variables //
|
||
// //
|
||
////////////////////////////////////////////////////////////////////////
|
||
|
||
//
|
||
// Authentication ID and source name used for system processes
|
||
//
|
||
|
||
TOKEN_SOURCE SeSystemTokenSource = {"*SYSTEM*", 0};
|
||
LUID SeSystemAuthenticationId = SYSTEM_LUID;
|
||
|
||
|
||
//
|
||
// Universal well known SIDs
|
||
//
|
||
|
||
PSID SeNullSid;
|
||
PSID SeWorldSid;
|
||
PSID SeLocalSid;
|
||
PSID SeCreatorOwnerSid;
|
||
PSID SeCreatorGroupSid;
|
||
PSID SeCreatorGroupServerSid;
|
||
PSID SeCreatorOwnerServerSid;
|
||
|
||
//
|
||
// Sids defined by NT
|
||
//
|
||
|
||
PSID SeNtAuthoritySid;
|
||
|
||
PSID SeDialupSid;
|
||
PSID SeNetworkSid;
|
||
PSID SeBatchSid;
|
||
PSID SeInteractiveSid;
|
||
PSID SeServiceSid;
|
||
PSID SeLocalSystemSid;
|
||
PSID SeAliasAdminsSid;
|
||
PSID SeAliasUsersSid;
|
||
PSID SeAliasGuestsSid;
|
||
PSID SeAliasPowerUsersSid;
|
||
PSID SeAliasAccountOpsSid;
|
||
PSID SeAliasSystemOpsSid;
|
||
PSID SeAliasPrintOpsSid;
|
||
PSID SeAliasBackupOpsSid;
|
||
|
||
|
||
//
|
||
// System default DACLs & Security Descriptors
|
||
//
|
||
// SePublicDefaultDacl - Protects objects so that WORLD:E, Admins:ALL, System: ALL.
|
||
// Not inherited by sub-objects.
|
||
//
|
||
// SePublicOpenDacl - Protects so that WORLD can RWE and Admins: All.
|
||
// Not inherited by sub-objects.
|
||
//
|
||
// SeSystemDefaultDacl - Protects objects so that SYSTEM & ADMIN can use them.
|
||
// Not inherited by subobjects.
|
||
//
|
||
|
||
PSECURITY_DESCRIPTOR SePublicDefaultSd;
|
||
SECURITY_DESCRIPTOR SepPublicDefaultSd;
|
||
PSECURITY_DESCRIPTOR SePublicOpenSd;
|
||
SECURITY_DESCRIPTOR SepPublicOpenSd;
|
||
PSECURITY_DESCRIPTOR SeSystemDefaultSd;
|
||
SECURITY_DESCRIPTOR SepSystemDefaultSd;
|
||
|
||
PACL SePublicDefaultDacl;
|
||
PACL SePublicOpenDacl;
|
||
PACL SeSystemDefaultDacl;
|
||
|
||
//
|
||
// Sid of primary domain, and admin account in that domain
|
||
//
|
||
|
||
PSID SepPrimaryDomainSid;
|
||
PSID SepPrimaryDomainAdminSid;
|
||
|
||
|
||
|
||
//
|
||
// Well known privilege values
|
||
//
|
||
|
||
|
||
LUID SeCreateTokenPrivilege;
|
||
LUID SeAssignPrimaryTokenPrivilege;
|
||
LUID SeLockMemoryPrivilege;
|
||
LUID SeIncreaseQuotaPrivilege;
|
||
LUID SeUnsolicitedInputPrivilege;
|
||
LUID SeTcbPrivilege;
|
||
LUID SeSecurityPrivilege;
|
||
LUID SeTakeOwnershipPrivilege;
|
||
LUID SeLoadDriverPrivilege;
|
||
LUID SeCreatePagefilePrivilege;
|
||
LUID SeIncreaseBasePriorityPrivilege;
|
||
LUID SeSystemProfilePrivilege;
|
||
LUID SeSystemtimePrivilege;
|
||
LUID SeProfileSingleProcessPrivilege;
|
||
LUID SeCreatePermanentPrivilege;
|
||
LUID SeBackupPrivilege;
|
||
LUID SeRestorePrivilege;
|
||
LUID SeShutdownPrivilege;
|
||
LUID SeDebugPrivilege;
|
||
LUID SeAuditPrivilege;
|
||
LUID SeSystemEnvironmentPrivilege;
|
||
LUID SeChangeNotifyPrivilege;
|
||
LUID SeRemoteShutdownPrivilege;
|
||
|
||
|
||
//
|
||
// Define the following structures for export from the kernel.
|
||
// This will allow us to export pointers to these structures
|
||
// rather than a pointer for each element in the structure.
|
||
//
|
||
|
||
PSE_EXPORTS SeExports;
|
||
SE_EXPORTS SepExports;
|
||
|
||
|
||
static SID_IDENTIFIER_AUTHORITY SepNullSidAuthority = SECURITY_NULL_SID_AUTHORITY;
|
||
static SID_IDENTIFIER_AUTHORITY SepWorldSidAuthority = SECURITY_WORLD_SID_AUTHORITY;
|
||
static SID_IDENTIFIER_AUTHORITY SepLocalSidAuthority = SECURITY_LOCAL_SID_AUTHORITY;
|
||
static SID_IDENTIFIER_AUTHORITY SepCreatorSidAuthority = SECURITY_CREATOR_SID_AUTHORITY;
|
||
static SID_IDENTIFIER_AUTHORITY SepNtAuthority = SECURITY_NT_AUTHORITY;
|
||
|
||
|
||
//
|
||
// Some variables we are going to use to help speed up access
|
||
// checking.
|
||
//
|
||
|
||
static ULONG SinglePrivilegeSetSize;
|
||
static ULONG DoublePrivilegeSetSize;
|
||
|
||
static PPRIVILEGE_SET SepSystemSecurityPrivilegeSet;
|
||
static PPRIVILEGE_SET SepTakeOwnershipPrivilegeSet;
|
||
static PPRIVILEGE_SET SepDoublePrivilegeSet;
|
||
|
||
|
||
//
|
||
// Array containing information describing what is to be audited
|
||
//
|
||
|
||
SE_AUDITING_STATE SeAuditingState[POLICY_AUDIT_EVENT_TYPE_COUNT] =
|
||
{
|
||
{ FALSE, FALSE },
|
||
{ FALSE, FALSE },
|
||
{ FALSE, FALSE },
|
||
{ FALSE, FALSE },
|
||
{ FALSE, FALSE },
|
||
{ FALSE, FALSE },
|
||
{ FALSE, FALSE }
|
||
};
|
||
|
||
//
|
||
// Boolean indicating whether or not auditing is enabled for the system
|
||
//
|
||
|
||
BOOLEAN SepAdtAuditingEnabled = FALSE;
|
||
|
||
//
|
||
// Boolean to hold whether or not the user wants the system to crash when
|
||
// an audit fails.
|
||
//
|
||
|
||
BOOLEAN SepCrashOnAuditFail = FALSE;
|
||
|
||
//
|
||
// Handle to the LSA process
|
||
//
|
||
|
||
HANDLE SepLsaHandle;
|
||
|
||
//
|
||
// Boolean indicating that we're auditing detailed events
|
||
// such as process creation.
|
||
//
|
||
|
||
BOOLEAN SeDetailedAuditing = FALSE;
|
||
|
||
UNICODE_STRING SeSubsystemName;
|
||
|
||
|
||
//
|
||
// Mutex protecting the queue of work being passed to LSA
|
||
//
|
||
|
||
ERESOURCE SepLsaQueueLock;
|
||
|
||
//
|
||
// Doubly linked list of work items queued to worker threads.
|
||
//
|
||
|
||
LIST_ENTRY SepLsaQueue;
|
||
|
||
//
|
||
// Count to tell us how long the queue gets in SepRmCallLsa
|
||
//
|
||
|
||
ULONG SepLsaQueueLength = 0;
|
||
|
||
SEP_WORK_ITEM SepExWorkItem;
|
||
|
||
|
||
|
||
////////////////////////////////////////////////////////////////////////
|
||
// //
|
||
// Variable Initialization Routines //
|
||
// //
|
||
////////////////////////////////////////////////////////////////////////
|
||
|
||
BOOLEAN
|
||
SepVariableInitialization()
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This function initializes the global variables used by and exposed
|
||
by security.
|
||
|
||
Arguments:
|
||
|
||
None.
|
||
|
||
Return Value:
|
||
|
||
TRUE if variables successfully initialized.
|
||
FALSE if not successfully initialized.
|
||
|
||
--*/
|
||
{
|
||
|
||
ULONG SidWithZeroSubAuthorities;
|
||
ULONG SidWithOneSubAuthority;
|
||
ULONG SidWithTwoSubAuthorities;
|
||
ULONG SidWithThreeSubAuthorities;
|
||
|
||
SID_IDENTIFIER_AUTHORITY NullSidAuthority;
|
||
SID_IDENTIFIER_AUTHORITY WorldSidAuthority;
|
||
SID_IDENTIFIER_AUTHORITY LocalSidAuthority;
|
||
SID_IDENTIFIER_AUTHORITY CreatorSidAuthority;
|
||
SID_IDENTIFIER_AUTHORITY SeNtAuthority;
|
||
|
||
PAGED_CODE();
|
||
|
||
NullSidAuthority = SepNullSidAuthority;
|
||
WorldSidAuthority = SepWorldSidAuthority;
|
||
LocalSidAuthority = SepLocalSidAuthority;
|
||
CreatorSidAuthority = SepCreatorSidAuthority;
|
||
SeNtAuthority = SepNtAuthority;
|
||
|
||
|
||
//
|
||
// The following SID sizes need to be allocated
|
||
//
|
||
|
||
SidWithZeroSubAuthorities = RtlLengthRequiredSid( 0 );
|
||
SidWithOneSubAuthority = RtlLengthRequiredSid( 1 );
|
||
SidWithTwoSubAuthorities = RtlLengthRequiredSid( 2 );
|
||
SidWithThreeSubAuthorities = RtlLengthRequiredSid( 3 );
|
||
|
||
//
|
||
// Allocate and initialize the universal SIDs
|
||
//
|
||
|
||
SeNullSid = (PSID)ExAllocatePoolWithTag(PagedPool,SidWithOneSubAuthority,'iSeS');
|
||
SeWorldSid = (PSID)ExAllocatePoolWithTag(PagedPool,SidWithOneSubAuthority,'iSeS');
|
||
SeLocalSid = (PSID)ExAllocatePoolWithTag(PagedPool,SidWithOneSubAuthority,'iSeS');
|
||
SeCreatorOwnerSid = (PSID)ExAllocatePoolWithTag(PagedPool,SidWithOneSubAuthority,'iSeS');
|
||
SeCreatorGroupSid = (PSID)ExAllocatePoolWithTag(PagedPool,SidWithOneSubAuthority,'iSeS');
|
||
SeCreatorOwnerServerSid = (PSID)ExAllocatePoolWithTag(PagedPool,SidWithOneSubAuthority,'iSeS');
|
||
SeCreatorGroupServerSid = (PSID)ExAllocatePoolWithTag(PagedPool,SidWithOneSubAuthority,'iSeS');
|
||
|
||
//
|
||
// Fail initialization if we didn't get enough memory for the universal
|
||
// SIDs.
|
||
//
|
||
|
||
if ( (SeNullSid == NULL) ||
|
||
(SeWorldSid == NULL) ||
|
||
(SeLocalSid == NULL) ||
|
||
(SeCreatorOwnerSid == NULL) ||
|
||
(SeCreatorGroupSid == NULL) ||
|
||
(SeCreatorOwnerServerSid == NULL ) ||
|
||
(SeCreatorGroupServerSid == NULL )
|
||
) {
|
||
|
||
return( FALSE );
|
||
}
|
||
|
||
RtlInitializeSid( SeNullSid, &NullSidAuthority, 1 );
|
||
RtlInitializeSid( SeWorldSid, &WorldSidAuthority, 1 );
|
||
RtlInitializeSid( SeLocalSid, &LocalSidAuthority, 1 );
|
||
RtlInitializeSid( SeCreatorOwnerSid, &CreatorSidAuthority, 1 );
|
||
RtlInitializeSid( SeCreatorGroupSid, &CreatorSidAuthority, 1 );
|
||
RtlInitializeSid( SeCreatorOwnerServerSid, &CreatorSidAuthority, 1 );
|
||
RtlInitializeSid( SeCreatorGroupServerSid, &CreatorSidAuthority, 1 );
|
||
|
||
*(RtlSubAuthoritySid( SeNullSid, 0 )) = SECURITY_NULL_RID;
|
||
*(RtlSubAuthoritySid( SeWorldSid, 0 )) = SECURITY_WORLD_RID;
|
||
*(RtlSubAuthoritySid( SeLocalSid, 0 )) = SECURITY_LOCAL_RID;
|
||
*(RtlSubAuthoritySid( SeCreatorOwnerSid, 0 )) = SECURITY_CREATOR_OWNER_RID;
|
||
*(RtlSubAuthoritySid( SeCreatorGroupSid, 0 )) = SECURITY_CREATOR_GROUP_RID;
|
||
*(RtlSubAuthoritySid( SeCreatorOwnerServerSid, 0 )) = SECURITY_CREATOR_OWNER_SERVER_RID;
|
||
*(RtlSubAuthoritySid( SeCreatorGroupServerSid, 0 )) = SECURITY_CREATOR_GROUP_SERVER_RID;
|
||
|
||
//
|
||
// Allocate and initialize the NT defined SIDs
|
||
//
|
||
|
||
SeNtAuthoritySid = (PSID)ExAllocatePoolWithTag(PagedPool,SidWithZeroSubAuthorities,'iSeS');
|
||
SeDialupSid = (PSID)ExAllocatePoolWithTag(PagedPool,SidWithOneSubAuthority,'iSeS');
|
||
SeNetworkSid = (PSID)ExAllocatePoolWithTag(PagedPool,SidWithOneSubAuthority,'iSeS');
|
||
SeBatchSid = (PSID)ExAllocatePoolWithTag(PagedPool,SidWithOneSubAuthority,'iSeS');
|
||
SeInteractiveSid = (PSID)ExAllocatePoolWithTag(PagedPool,SidWithOneSubAuthority,'iSeS');
|
||
SeServiceSid = (PSID)ExAllocatePoolWithTag(PagedPool,SidWithOneSubAuthority,'iSeS');
|
||
SeLocalSystemSid = (PSID)ExAllocatePoolWithTag(PagedPool,SidWithOneSubAuthority,'iSeS');
|
||
|
||
SeAliasAdminsSid = (PSID)ExAllocatePoolWithTag(PagedPool,SidWithTwoSubAuthorities,'iSeS');
|
||
SeAliasUsersSid = (PSID)ExAllocatePoolWithTag(PagedPool,SidWithTwoSubAuthorities,'iSeS');
|
||
SeAliasGuestsSid = (PSID)ExAllocatePoolWithTag(PagedPool,SidWithTwoSubAuthorities,'iSeS');
|
||
SeAliasPowerUsersSid = (PSID)ExAllocatePoolWithTag(PagedPool,SidWithTwoSubAuthorities,'iSeS');
|
||
SeAliasAccountOpsSid = (PSID)ExAllocatePoolWithTag(PagedPool,SidWithTwoSubAuthorities,'iSeS');
|
||
SeAliasSystemOpsSid = (PSID)ExAllocatePoolWithTag(PagedPool,SidWithTwoSubAuthorities,'iSeS');
|
||
SeAliasPrintOpsSid = (PSID)ExAllocatePoolWithTag(PagedPool,SidWithTwoSubAuthorities,'iSeS');
|
||
SeAliasBackupOpsSid = (PSID)ExAllocatePoolWithTag(PagedPool,SidWithTwoSubAuthorities,'iSeS');
|
||
|
||
//
|
||
// Fail initialization if we didn't get enough memory for the NT SIDs.
|
||
//
|
||
|
||
if ( (SeNtAuthoritySid == NULL) ||
|
||
(SeDialupSid == NULL) ||
|
||
(SeNetworkSid == NULL) ||
|
||
(SeBatchSid == NULL) ||
|
||
(SeInteractiveSid == NULL) ||
|
||
(SeServiceSid == NULL) ||
|
||
(SeLocalSystemSid == NULL) ||
|
||
(SeAliasAdminsSid == NULL) ||
|
||
(SeAliasUsersSid == NULL) ||
|
||
(SeAliasGuestsSid == NULL) ||
|
||
(SeAliasPowerUsersSid == NULL) ||
|
||
(SeAliasAccountOpsSid == NULL) ||
|
||
(SeAliasSystemOpsSid == NULL) ||
|
||
(SeAliasPrintOpsSid == NULL) ||
|
||
(SeAliasBackupOpsSid == NULL)
|
||
) {
|
||
|
||
return( FALSE );
|
||
}
|
||
|
||
RtlInitializeSid( SeNtAuthoritySid, &SeNtAuthority, 0 );
|
||
RtlInitializeSid( SeDialupSid, &SeNtAuthority, 1 );
|
||
RtlInitializeSid( SeNetworkSid, &SeNtAuthority, 1 );
|
||
RtlInitializeSid( SeBatchSid, &SeNtAuthority, 1 );
|
||
RtlInitializeSid( SeInteractiveSid, &SeNtAuthority, 1 );
|
||
RtlInitializeSid( SeServiceSid, &SeNtAuthority, 1 );
|
||
RtlInitializeSid( SeLocalSystemSid, &SeNtAuthority, 1 );
|
||
|
||
RtlInitializeSid( SeAliasAdminsSid, &SeNtAuthority, 2);
|
||
RtlInitializeSid( SeAliasUsersSid, &SeNtAuthority, 2);
|
||
RtlInitializeSid( SeAliasGuestsSid, &SeNtAuthority, 2);
|
||
RtlInitializeSid( SeAliasPowerUsersSid, &SeNtAuthority, 2);
|
||
RtlInitializeSid( SeAliasAccountOpsSid, &SeNtAuthority, 2);
|
||
RtlInitializeSid( SeAliasSystemOpsSid, &SeNtAuthority, 2);
|
||
RtlInitializeSid( SeAliasPrintOpsSid, &SeNtAuthority, 2);
|
||
RtlInitializeSid( SeAliasBackupOpsSid, &SeNtAuthority, 2);
|
||
|
||
*(RtlSubAuthoritySid( SeDialupSid, 0 )) = SECURITY_DIALUP_RID;
|
||
*(RtlSubAuthoritySid( SeNetworkSid, 0 )) = SECURITY_NETWORK_RID;
|
||
*(RtlSubAuthoritySid( SeBatchSid, 0 )) = SECURITY_BATCH_RID;
|
||
*(RtlSubAuthoritySid( SeInteractiveSid, 0 )) = SECURITY_INTERACTIVE_RID;
|
||
*(RtlSubAuthoritySid( SeServiceSid, 0 )) = SECURITY_SERVICE_RID;
|
||
*(RtlSubAuthoritySid( SeLocalSystemSid, 0 )) = SECURITY_LOCAL_SYSTEM_RID;
|
||
|
||
|
||
*(RtlSubAuthoritySid( SeAliasAdminsSid, 0 )) = SECURITY_BUILTIN_DOMAIN_RID;
|
||
*(RtlSubAuthoritySid( SeAliasUsersSid, 0 )) = SECURITY_BUILTIN_DOMAIN_RID;
|
||
*(RtlSubAuthoritySid( SeAliasGuestsSid, 0 )) = SECURITY_BUILTIN_DOMAIN_RID;
|
||
*(RtlSubAuthoritySid( SeAliasPowerUsersSid, 0 )) = SECURITY_BUILTIN_DOMAIN_RID;
|
||
*(RtlSubAuthoritySid( SeAliasAccountOpsSid, 0 )) = SECURITY_BUILTIN_DOMAIN_RID;
|
||
*(RtlSubAuthoritySid( SeAliasSystemOpsSid, 0 )) = SECURITY_BUILTIN_DOMAIN_RID;
|
||
*(RtlSubAuthoritySid( SeAliasPrintOpsSid, 0 )) = SECURITY_BUILTIN_DOMAIN_RID;
|
||
*(RtlSubAuthoritySid( SeAliasBackupOpsSid, 0 )) = SECURITY_BUILTIN_DOMAIN_RID;
|
||
|
||
*(RtlSubAuthoritySid( SeAliasAdminsSid, 1 )) = DOMAIN_ALIAS_RID_ADMINS;
|
||
*(RtlSubAuthoritySid( SeAliasUsersSid, 1 )) = DOMAIN_ALIAS_RID_USERS;
|
||
*(RtlSubAuthoritySid( SeAliasGuestsSid, 1 )) = DOMAIN_ALIAS_RID_GUESTS;
|
||
*(RtlSubAuthoritySid( SeAliasPowerUsersSid, 1 )) = DOMAIN_ALIAS_RID_POWER_USERS;
|
||
*(RtlSubAuthoritySid( SeAliasAccountOpsSid, 1 )) = DOMAIN_ALIAS_RID_ACCOUNT_OPS;
|
||
*(RtlSubAuthoritySid( SeAliasSystemOpsSid, 1 )) = DOMAIN_ALIAS_RID_SYSTEM_OPS;
|
||
*(RtlSubAuthoritySid( SeAliasPrintOpsSid, 1 )) = DOMAIN_ALIAS_RID_PRINT_OPS;
|
||
*(RtlSubAuthoritySid( SeAliasBackupOpsSid, 1 )) = DOMAIN_ALIAS_RID_BACKUP_OPS;
|
||
|
||
|
||
|
||
//
|
||
// Initialize system default dacl
|
||
//
|
||
|
||
SepInitSystemDacls();
|
||
|
||
|
||
//
|
||
// Initialize the well known privilege values
|
||
//
|
||
|
||
SeCreateTokenPrivilege =
|
||
RtlConvertLongToLuid(SE_CREATE_TOKEN_PRIVILEGE);
|
||
SeAssignPrimaryTokenPrivilege =
|
||
RtlConvertLongToLuid(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE);
|
||
SeLockMemoryPrivilege =
|
||
RtlConvertLongToLuid(SE_LOCK_MEMORY_PRIVILEGE);
|
||
SeIncreaseQuotaPrivilege =
|
||
RtlConvertLongToLuid(SE_INCREASE_QUOTA_PRIVILEGE);
|
||
SeUnsolicitedInputPrivilege =
|
||
RtlConvertLongToLuid(SE_UNSOLICITED_INPUT_PRIVILEGE);
|
||
SeTcbPrivilege =
|
||
RtlConvertLongToLuid(SE_TCB_PRIVILEGE);
|
||
SeSecurityPrivilege =
|
||
RtlConvertLongToLuid(SE_SECURITY_PRIVILEGE);
|
||
SeTakeOwnershipPrivilege =
|
||
RtlConvertLongToLuid(SE_TAKE_OWNERSHIP_PRIVILEGE);
|
||
SeLoadDriverPrivilege =
|
||
RtlConvertLongToLuid(SE_LOAD_DRIVER_PRIVILEGE);
|
||
SeCreatePagefilePrivilege =
|
||
RtlConvertLongToLuid(SE_CREATE_PAGEFILE_PRIVILEGE);
|
||
SeIncreaseBasePriorityPrivilege =
|
||
RtlConvertLongToLuid(SE_INC_BASE_PRIORITY_PRIVILEGE);
|
||
SeSystemProfilePrivilege =
|
||
RtlConvertLongToLuid(SE_SYSTEM_PROFILE_PRIVILEGE);
|
||
SeSystemtimePrivilege =
|
||
RtlConvertLongToLuid(SE_SYSTEMTIME_PRIVILEGE);
|
||
SeProfileSingleProcessPrivilege =
|
||
RtlConvertLongToLuid(SE_PROF_SINGLE_PROCESS_PRIVILEGE);
|
||
SeCreatePermanentPrivilege =
|
||
RtlConvertLongToLuid(SE_CREATE_PERMANENT_PRIVILEGE);
|
||
SeBackupPrivilege =
|
||
RtlConvertLongToLuid(SE_BACKUP_PRIVILEGE);
|
||
SeRestorePrivilege =
|
||
RtlConvertLongToLuid(SE_RESTORE_PRIVILEGE);
|
||
SeShutdownPrivilege =
|
||
RtlConvertLongToLuid(SE_SHUTDOWN_PRIVILEGE);
|
||
SeDebugPrivilege =
|
||
RtlConvertLongToLuid(SE_DEBUG_PRIVILEGE);
|
||
SeAuditPrivilege =
|
||
RtlConvertLongToLuid(SE_AUDIT_PRIVILEGE);
|
||
SeSystemEnvironmentPrivilege =
|
||
RtlConvertLongToLuid(SE_SYSTEM_ENVIRONMENT_PRIVILEGE);
|
||
SeChangeNotifyPrivilege =
|
||
RtlConvertLongToLuid(SE_CHANGE_NOTIFY_PRIVILEGE);
|
||
SeRemoteShutdownPrivilege =
|
||
RtlConvertLongToLuid(SE_REMOTE_SHUTDOWN_PRIVILEGE);
|
||
|
||
|
||
|
||
//
|
||
// Initialize the SeExports structure for exporting all
|
||
// of the information we've created out of the kernel.
|
||
//
|
||
|
||
//
|
||
// Package these together for export
|
||
//
|
||
|
||
|
||
SepExports.SeNullSid = SeNullSid;
|
||
SepExports.SeWorldSid = SeWorldSid;
|
||
SepExports.SeLocalSid = SeLocalSid;
|
||
SepExports.SeCreatorOwnerSid = SeCreatorOwnerSid;
|
||
SepExports.SeCreatorGroupSid = SeCreatorGroupSid;
|
||
|
||
|
||
SepExports.SeNtAuthoritySid = SeNtAuthoritySid;
|
||
SepExports.SeDialupSid = SeDialupSid;
|
||
SepExports.SeNetworkSid = SeNetworkSid;
|
||
SepExports.SeBatchSid = SeBatchSid;
|
||
SepExports.SeInteractiveSid = SeInteractiveSid;
|
||
SepExports.SeLocalSystemSid = SeLocalSystemSid;
|
||
SepExports.SeAliasAdminsSid = SeAliasAdminsSid;
|
||
SepExports.SeAliasUsersSid = SeAliasUsersSid;
|
||
SepExports.SeAliasGuestsSid = SeAliasGuestsSid;
|
||
SepExports.SeAliasPowerUsersSid = SeAliasPowerUsersSid;
|
||
SepExports.SeAliasAccountOpsSid = SeAliasAccountOpsSid;
|
||
SepExports.SeAliasSystemOpsSid = SeAliasSystemOpsSid;
|
||
SepExports.SeAliasPrintOpsSid = SeAliasPrintOpsSid;
|
||
SepExports.SeAliasBackupOpsSid = SeAliasBackupOpsSid;
|
||
|
||
|
||
|
||
SepExports.SeCreateTokenPrivilege = SeCreateTokenPrivilege;
|
||
SepExports.SeAssignPrimaryTokenPrivilege = SeAssignPrimaryTokenPrivilege;
|
||
SepExports.SeLockMemoryPrivilege = SeLockMemoryPrivilege;
|
||
SepExports.SeIncreaseQuotaPrivilege = SeIncreaseQuotaPrivilege;
|
||
SepExports.SeUnsolicitedInputPrivilege = SeUnsolicitedInputPrivilege;
|
||
SepExports.SeTcbPrivilege = SeTcbPrivilege;
|
||
SepExports.SeSecurityPrivilege = SeSecurityPrivilege;
|
||
SepExports.SeTakeOwnershipPrivilege = SeTakeOwnershipPrivilege;
|
||
SepExports.SeLoadDriverPrivilege = SeLoadDriverPrivilege;
|
||
SepExports.SeCreatePagefilePrivilege = SeCreatePagefilePrivilege;
|
||
SepExports.SeIncreaseBasePriorityPrivilege = SeIncreaseBasePriorityPrivilege;
|
||
SepExports.SeSystemProfilePrivilege = SeSystemProfilePrivilege;
|
||
SepExports.SeSystemtimePrivilege = SeSystemtimePrivilege;
|
||
SepExports.SeProfileSingleProcessPrivilege = SeProfileSingleProcessPrivilege;
|
||
SepExports.SeCreatePermanentPrivilege = SeCreatePermanentPrivilege;
|
||
SepExports.SeBackupPrivilege = SeBackupPrivilege;
|
||
SepExports.SeRestorePrivilege = SeRestorePrivilege;
|
||
SepExports.SeShutdownPrivilege = SeShutdownPrivilege;
|
||
SepExports.SeDebugPrivilege = SeDebugPrivilege;
|
||
SepExports.SeAuditPrivilege = SeAuditPrivilege;
|
||
SepExports.SeSystemEnvironmentPrivilege = SeSystemEnvironmentPrivilege;
|
||
SepExports.SeChangeNotifyPrivilege = SeChangeNotifyPrivilege;
|
||
SepExports.SeRemoteShutdownPrivilege = SeRemoteShutdownPrivilege;
|
||
|
||
SeExports = &SepExports;
|
||
|
||
//
|
||
// Initialize frequently used privilege sets to speed up access
|
||
// validation.
|
||
//
|
||
|
||
SepInitializePrivilegeSets();
|
||
|
||
return TRUE;
|
||
|
||
}
|
||
|
||
VOID
|
||
SepInitSystemDacls( VOID )
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This function initializes the system's default dacls & security
|
||
descriptors.
|
||
|
||
Arguments:
|
||
|
||
None.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
|
||
--*/
|
||
{
|
||
|
||
NTSTATUS
|
||
Status;
|
||
|
||
ULONG
|
||
PublicLength,
|
||
SystemLength,
|
||
PublicOpenLength;
|
||
|
||
|
||
PAGED_CODE();
|
||
|
||
//
|
||
// Set up a default ACLs
|
||
//
|
||
// Public: WORLD:execute, SYSTEM:all, ADMINS:all
|
||
// Public Open: WORLD:(Read|Write|Execute), ADMINS:(all), SYSTEM:all
|
||
// System: SYSTEM:all, ADMINS:(read|execute|read_control)
|
||
|
||
SystemLength = (ULONG)sizeof(ACL) +
|
||
(2*((ULONG)sizeof(ACCESS_ALLOWED_ACE))) +
|
||
SeLengthSid( SeLocalSystemSid ) +
|
||
SeLengthSid( SeAliasAdminsSid ) +
|
||
8; // The 8 is just for good measure
|
||
|
||
PublicLength = SystemLength +
|
||
((ULONG)sizeof(ACCESS_ALLOWED_ACE)) +
|
||
SeLengthSid( SeWorldSid );
|
||
|
||
PublicOpenLength = PublicLength;
|
||
|
||
|
||
SePublicDefaultDacl = (PACL)ExAllocatePoolWithTag(PagedPool, PublicLength, 'cAeS');
|
||
SePublicOpenDacl = (PACL)ExAllocatePoolWithTag(PagedPool, PublicOpenLength, 'cAeS');
|
||
SeSystemDefaultDacl = (PACL)ExAllocatePoolWithTag(PagedPool, SystemLength, 'cAeS');
|
||
ASSERT(SePublicDefaultDacl != NULL);
|
||
ASSERT(SePublicOpenDacl != NULL);
|
||
ASSERT(SeSystemDefaultDacl != NULL);
|
||
|
||
|
||
|
||
Status = RtlCreateAcl( SePublicDefaultDacl, PublicLength, ACL_REVISION2);
|
||
ASSERT( NT_SUCCESS(Status) );
|
||
Status = RtlCreateAcl( SePublicOpenDacl, PublicOpenLength, ACL_REVISION2);
|
||
ASSERT( NT_SUCCESS(Status) );
|
||
Status = RtlCreateAcl( SeSystemDefaultDacl, SystemLength, ACL_REVISION2);
|
||
ASSERT( NT_SUCCESS(Status) );
|
||
|
||
|
||
//
|
||
// WORLD access (Public DACLs only)
|
||
//
|
||
|
||
Status = RtlAddAccessAllowedAce (
|
||
SePublicDefaultDacl,
|
||
ACL_REVISION2,
|
||
GENERIC_EXECUTE,
|
||
SeWorldSid
|
||
);
|
||
ASSERT( NT_SUCCESS(Status) );
|
||
|
||
|
||
Status = RtlAddAccessAllowedAce (
|
||
SePublicOpenDacl,
|
||
ACL_REVISION2,
|
||
(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE),
|
||
SeWorldSid
|
||
);
|
||
ASSERT( NT_SUCCESS(Status) );
|
||
|
||
|
||
|
||
//
|
||
// SYSTEM access (PublicDefault, PublicOpen, and SystemDefault)
|
||
//
|
||
|
||
|
||
Status = RtlAddAccessAllowedAce (
|
||
SePublicDefaultDacl,
|
||
ACL_REVISION2,
|
||
GENERIC_ALL,
|
||
SeLocalSystemSid
|
||
);
|
||
ASSERT( NT_SUCCESS(Status) );
|
||
|
||
|
||
Status = RtlAddAccessAllowedAce (
|
||
SePublicOpenDacl,
|
||
ACL_REVISION2,
|
||
GENERIC_ALL,
|
||
SeLocalSystemSid
|
||
);
|
||
ASSERT( NT_SUCCESS(Status) );
|
||
|
||
|
||
Status = RtlAddAccessAllowedAce (
|
||
SeSystemDefaultDacl,
|
||
ACL_REVISION2,
|
||
GENERIC_ALL,
|
||
SeLocalSystemSid
|
||
);
|
||
ASSERT( NT_SUCCESS(Status) );
|
||
|
||
//
|
||
// ADMINISTRATORS access (PublicDefault, PublicOpen, and SystemDefault)
|
||
//
|
||
|
||
Status = RtlAddAccessAllowedAce (
|
||
SePublicDefaultDacl,
|
||
ACL_REVISION2,
|
||
GENERIC_ALL,
|
||
SeAliasAdminsSid
|
||
);
|
||
ASSERT( NT_SUCCESS(Status) );
|
||
|
||
|
||
Status = RtlAddAccessAllowedAce (
|
||
SePublicOpenDacl,
|
||
ACL_REVISION2,
|
||
GENERIC_ALL,
|
||
SeAliasAdminsSid
|
||
);
|
||
ASSERT( NT_SUCCESS(Status) );
|
||
|
||
|
||
Status = RtlAddAccessAllowedAce (
|
||
SeSystemDefaultDacl,
|
||
ACL_REVISION2,
|
||
GENERIC_READ | GENERIC_EXECUTE | READ_CONTROL,
|
||
SeAliasAdminsSid
|
||
);
|
||
ASSERT( NT_SUCCESS(Status) );
|
||
|
||
|
||
|
||
//
|
||
// Now initialize security descriptors
|
||
// that export this protection
|
||
//
|
||
|
||
|
||
SePublicDefaultSd = (PSECURITY_DESCRIPTOR)&SepPublicDefaultSd;
|
||
Status = RtlCreateSecurityDescriptor(
|
||
SePublicDefaultSd,
|
||
SECURITY_DESCRIPTOR_REVISION1
|
||
);
|
||
ASSERT( NT_SUCCESS(Status) );
|
||
Status = RtlSetDaclSecurityDescriptor(
|
||
SePublicDefaultSd,
|
||
TRUE, // DaclPresent
|
||
SePublicDefaultDacl,
|
||
FALSE // DaclDefaulted
|
||
);
|
||
ASSERT( NT_SUCCESS(Status) );
|
||
|
||
|
||
SePublicOpenSd = (PSECURITY_DESCRIPTOR)&SepPublicOpenSd;
|
||
Status = RtlCreateSecurityDescriptor(
|
||
SePublicOpenSd,
|
||
SECURITY_DESCRIPTOR_REVISION1
|
||
);
|
||
ASSERT( NT_SUCCESS(Status) );
|
||
Status = RtlSetDaclSecurityDescriptor(
|
||
SePublicOpenSd,
|
||
TRUE, // DaclPresent
|
||
SePublicOpenDacl,
|
||
FALSE // DaclDefaulted
|
||
);
|
||
ASSERT( NT_SUCCESS(Status) );
|
||
|
||
|
||
SeSystemDefaultSd = (PSECURITY_DESCRIPTOR)&SepSystemDefaultSd;
|
||
Status = RtlCreateSecurityDescriptor(
|
||
SeSystemDefaultSd,
|
||
SECURITY_DESCRIPTOR_REVISION1
|
||
);
|
||
ASSERT( NT_SUCCESS(Status) );
|
||
Status = RtlSetDaclSecurityDescriptor(
|
||
SeSystemDefaultSd,
|
||
TRUE, // DaclPresent
|
||
SeSystemDefaultDacl,
|
||
FALSE // DaclDefaulted
|
||
);
|
||
ASSERT( NT_SUCCESS(Status) );
|
||
|
||
|
||
return;
|
||
|
||
}
|
||
|
||
|
||
VOID
|
||
SepInitializePrivilegeSets( VOID )
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is called once during system initialization to pre-allocate
|
||
and initialize some commonly used privilege sets.
|
||
|
||
Arguments:
|
||
|
||
None
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
PAGED_CODE();
|
||
|
||
SinglePrivilegeSetSize = sizeof( PRIVILEGE_SET );
|
||
DoublePrivilegeSetSize = sizeof( PRIVILEGE_SET ) +
|
||
(ULONG)sizeof( LUID_AND_ATTRIBUTES );
|
||
|
||
SepSystemSecurityPrivilegeSet = ExAllocatePoolWithTag( PagedPool, SinglePrivilegeSetSize, 'rPeS' );
|
||
SepTakeOwnershipPrivilegeSet = ExAllocatePoolWithTag( PagedPool, SinglePrivilegeSetSize, 'rPeS' );
|
||
SepDoublePrivilegeSet = ExAllocatePoolWithTag( PagedPool, DoublePrivilegeSetSize, 'rPeS' );
|
||
|
||
SepSystemSecurityPrivilegeSet->PrivilegeCount = 1;
|
||
SepSystemSecurityPrivilegeSet->Control = 0;
|
||
SepSystemSecurityPrivilegeSet->Privilege[0].Luid = SeSecurityPrivilege;
|
||
SepSystemSecurityPrivilegeSet->Privilege[0].Attributes = SE_PRIVILEGE_USED_FOR_ACCESS;
|
||
|
||
SepTakeOwnershipPrivilegeSet->PrivilegeCount = 1;
|
||
SepTakeOwnershipPrivilegeSet->Control = 0;
|
||
SepTakeOwnershipPrivilegeSet->Privilege[0].Luid = SeTakeOwnershipPrivilege;
|
||
SepTakeOwnershipPrivilegeSet->Privilege[0].Attributes = SE_PRIVILEGE_USED_FOR_ACCESS;
|
||
|
||
SepDoublePrivilegeSet->PrivilegeCount = 2;
|
||
SepDoublePrivilegeSet->Control = 0;
|
||
|
||
SepDoublePrivilegeSet->Privilege[0].Luid = SeSecurityPrivilege;
|
||
SepDoublePrivilegeSet->Privilege[0].Attributes = SE_PRIVILEGE_USED_FOR_ACCESS;
|
||
|
||
SepDoublePrivilegeSet->Privilege[1].Luid = SeTakeOwnershipPrivilege;
|
||
SepDoublePrivilegeSet->Privilege[1].Attributes = SE_PRIVILEGE_USED_FOR_ACCESS;
|
||
|
||
}
|
||
|
||
|
||
|
||
VOID
|
||
SepAssemblePrivileges(
|
||
IN ULONG PrivilegeCount,
|
||
IN BOOLEAN SystemSecurity,
|
||
IN BOOLEAN WriteOwner,
|
||
OUT PPRIVILEGE_SET *Privileges
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine takes the results of the various privilege checks
|
||
in SeAccessCheck and returns an appropriate privilege set.
|
||
|
||
Arguments:
|
||
|
||
PrivilegeCount - The number of privileges granted.
|
||
|
||
SystemSecurity - Provides a boolean indicating whether to put
|
||
SeSecurityPrivilege into the output privilege set.
|
||
|
||
WriteOwner - Provides a boolean indicating whether to put
|
||
SeTakeOwnershipPrivilege into the output privilege set.
|
||
|
||
Privileges - Supplies a pointer that will return the privilege
|
||
set. Should be freed with ExFreePool when no longer needed.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
PPRIVILEGE_SET PrivilegeSet;
|
||
ULONG SizeRequired;
|
||
|
||
PAGED_CODE();
|
||
|
||
ASSERT( (PrivilegeCount != 0) && (PrivilegeCount <= 2) );
|
||
|
||
if ( !ARGUMENT_PRESENT( Privileges ) ) {
|
||
return;
|
||
}
|
||
|
||
if ( PrivilegeCount == 1 ) {
|
||
|
||
SizeRequired = SinglePrivilegeSetSize;
|
||
|
||
if ( SystemSecurity ) {
|
||
|
||
PrivilegeSet = SepSystemSecurityPrivilegeSet;
|
||
|
||
} else {
|
||
|
||
ASSERT( WriteOwner );
|
||
|
||
PrivilegeSet = SepTakeOwnershipPrivilegeSet;
|
||
}
|
||
|
||
} else {
|
||
|
||
SizeRequired = DoublePrivilegeSetSize;
|
||
PrivilegeSet = SepDoublePrivilegeSet;
|
||
}
|
||
|
||
*Privileges = ExAllocatePoolWithTag( PagedPool, SizeRequired, 'rPeS' );
|
||
|
||
if ( *Privileges != NULL ) {
|
||
|
||
RtlMoveMemory (
|
||
*Privileges,
|
||
PrivilegeSet,
|
||
SizeRequired
|
||
);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
BOOLEAN
|
||
SepInitializeWorkList(
|
||
VOID
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Initializes the mutex and list head used to queue work from the
|
||
Executive to LSA. This mechanism operates on top of the normal ExWorkerThread
|
||
mechanism by capturing the first thread to perform LSA work and keeping it
|
||
until all the current work is done.
|
||
|
||
The reduces the number of worker threads that are blocked on I/O to LSA.
|
||
|
||
Arguments:
|
||
|
||
None.
|
||
|
||
|
||
Return Value:
|
||
|
||
TRUE if successful, FALSE otherwise.
|
||
|
||
--*/
|
||
|
||
{
|
||
PAGED_CODE();
|
||
|
||
ExInitializeResource(&SepLsaQueueLock);
|
||
InitializeListHead(&SepLsaQueue);
|
||
return( TRUE );
|
||
}
|