2269 lines
55 KiB
C++
2269 lines
55 KiB
C++
|
/*++
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Copyright (c) 1996 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
w3inst.cxx
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
This module defines the W3_SERVER_INSTANCE class
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Johnson Apacible (JohnsonA) June-04-1996
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
#include "w3p.hxx"
|
|||
|
|
|||
|
#include <ole2.h>
|
|||
|
#include <imd.h>
|
|||
|
#include <mb.hxx>
|
|||
|
|
|||
|
#include <nsepname.hxx>
|
|||
|
#include <mbstring.h>
|
|||
|
#include <issched.hxx>
|
|||
|
|
|||
|
#if DBG
|
|||
|
#define VALIDATE_HEAP() DBG_ASSERT( RtlValidateProcessHeaps() )
|
|||
|
#else
|
|||
|
#define VALIDATE_HEAP()
|
|||
|
#endif
|
|||
|
|
|||
|
//
|
|||
|
// Constants
|
|||
|
//
|
|||
|
|
|||
|
//
|
|||
|
// Globals
|
|||
|
//
|
|||
|
|
|||
|
LPVOID g_pMappers[MT_LAST] = { NULL, NULL, NULL, NULL };
|
|||
|
PFN_SF_NOTIFY g_pFlushMapperNotify[MT_LAST] = { NULL, NULL, NULL, NULL };
|
|||
|
PFN_SF_NOTIFY g_pSslKeysNotify = NULL;
|
|||
|
extern STORE_CHANGE_NOTIFIER *g_pStoreChangeNotifier;
|
|||
|
|
|||
|
//
|
|||
|
// Prototypes
|
|||
|
//
|
|||
|
|
|||
|
|
|||
|
DWORD
|
|||
|
InitializeInstances(
|
|||
|
PW3_IIS_SERVICE pService
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Reads the instances from the metabase
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
pService - Server instances added to.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Win32
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
DWORD i;
|
|||
|
DWORD cInstances = 0;
|
|||
|
MB mb( (IMDCOM*) pService->QueryMDObject() );
|
|||
|
CHAR szKeyName[MAX_PATH+1];
|
|||
|
DWORD err = NO_ERROR;
|
|||
|
BUFFER buff;
|
|||
|
BOOL fMigrateRoots = FALSE;
|
|||
|
|
|||
|
//
|
|||
|
// Open the metabase for write to get an atomic snapshot
|
|||
|
//
|
|||
|
|
|||
|
ReOpen:
|
|||
|
|
|||
|
if ( !mb.Open( "/LM/W3SVC/",
|
|||
|
METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE ))
|
|||
|
{
|
|||
|
DBGPRINTF(( DBG_CONTEXT,
|
|||
|
"InitializeInstances: Cannot open path %s, error %lu\n",
|
|||
|
"/LM/W3SVC/", GetLastError() ));
|
|||
|
|
|||
|
//
|
|||
|
// If the web service key isn't here, just create it
|
|||
|
//
|
|||
|
|
|||
|
if ( !mb.Open( "",
|
|||
|
METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE ) ||
|
|||
|
!mb.AddObject( "/LM/W3SVC/" ))
|
|||
|
{
|
|||
|
return GetLastError();
|
|||
|
}
|
|||
|
|
|||
|
DBGPRINTF(( DBG_CONTEXT,
|
|||
|
"/LM/W3Svc not found, auto-created\n" ));
|
|||
|
|
|||
|
mb.Close();
|
|||
|
goto ReOpen;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Loop through instance keys and build a list. We don't keep the
|
|||
|
// metabase open because the instance instantiation code will need
|
|||
|
// to write to the metabase
|
|||
|
//
|
|||
|
|
|||
|
TryAgain:
|
|||
|
i = 0;
|
|||
|
while ( mb.EnumObjects( "",
|
|||
|
szKeyName,
|
|||
|
i++ ))
|
|||
|
{
|
|||
|
BOOL fRet;
|
|||
|
DWORD dwInstance;
|
|||
|
CHAR szRegKey[MAX_PATH+1];
|
|||
|
|
|||
|
//
|
|||
|
// Get the instance id
|
|||
|
//
|
|||
|
|
|||
|
IF_DEBUG(INSTANCE) {
|
|||
|
DBGPRINTF((DBG_CONTEXT,"instance key %s\n",szKeyName));
|
|||
|
}
|
|||
|
|
|||
|
dwInstance = atoi( szKeyName );
|
|||
|
if ( dwInstance == 0 ) {
|
|||
|
IF_DEBUG(INSTANCE) {
|
|||
|
DBGPRINTF((DBG_CONTEXT,"invalid instance ID %s\n",szKeyName));
|
|||
|
}
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
if ( buff.QuerySize() < (cInstances + 1) * sizeof(DWORD) )
|
|||
|
{
|
|||
|
if ( !buff.Resize( (cInstances + 10) * sizeof(DWORD)) )
|
|||
|
{
|
|||
|
return GetLastError();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
((DWORD *) buff.QueryPtr())[cInstances++] = dwInstance;
|
|||
|
}
|
|||
|
|
|||
|
if ( cInstances == 0 )
|
|||
|
{
|
|||
|
DBGPRINTF(( DBG_CONTEXT,
|
|||
|
"No defined instances\n" ));
|
|||
|
|
|||
|
if ( !mb.AddObject( "1" ))
|
|||
|
{
|
|||
|
DBGPRINTF(( DBG_CONTEXT,
|
|||
|
"Unable to create first instance, error %d\n",
|
|||
|
GetLastError() ));
|
|||
|
|
|||
|
return GetLastError();
|
|||
|
}
|
|||
|
|
|||
|
fMigrateRoots = TRUE; // Force reg->metabase migration of virtual directories
|
|||
|
goto TryAgain;
|
|||
|
}
|
|||
|
|
|||
|
DBG_REQUIRE( mb.Close() );
|
|||
|
|
|||
|
for ( i = 0; i < cInstances; i++ )
|
|||
|
{
|
|||
|
DWORD dwInstance = ((DWORD *)buff.QueryPtr())[i];
|
|||
|
pService->StartUpIndicateClientActivity();
|
|||
|
|
|||
|
if( !g_pInetSvc->AddInstanceInfo( dwInstance, fMigrateRoots ) ) {
|
|||
|
|
|||
|
err = GetLastError();
|
|||
|
|
|||
|
DBGPRINTF((
|
|||
|
DBG_CONTEXT,
|
|||
|
"InitializeInstances: cannot create instance %lu, error %lu\n",
|
|||
|
dwInstance,
|
|||
|
err
|
|||
|
));
|
|||
|
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return err;
|
|||
|
|
|||
|
} // InitializeInstances
|
|||
|
|
|||
|
|
|||
|
|
|||
|
W3_SERVER_INSTANCE::W3_SERVER_INSTANCE(
|
|||
|
IN PW3_IIS_SERVICE pService,
|
|||
|
IN DWORD dwInstanceId,
|
|||
|
IN USHORT Port,
|
|||
|
IN LPCSTR lpszRegParamKey,
|
|||
|
IN LPWSTR lpwszAnonPasswordSecretName,
|
|||
|
IN LPWSTR lpwszVirtualRootsSecretName,
|
|||
|
IN BOOL fMigrateRoots
|
|||
|
)
|
|||
|
: IIS_SERVER_INSTANCE(pService,
|
|||
|
dwInstanceId,
|
|||
|
Port,
|
|||
|
lpszRegParamKey,
|
|||
|
lpwszAnonPasswordSecretName,
|
|||
|
lpwszVirtualRootsSecretName,
|
|||
|
fMigrateRoots),
|
|||
|
|
|||
|
m_signature (W3_SERVER_INSTANCE_SIGNATURE),
|
|||
|
m_fAnySecureFilters (fAnySecureFilters),
|
|||
|
m_dwUseHostName (DEFAULT_W3_USE_HOST_NAME ),
|
|||
|
m_pszDefaultHostName (NULL ),
|
|||
|
m_fAcceptByteRanges (DEFAULT_W3_ACCEPT_BYTE_RANGES ),
|
|||
|
m_fLogErrors (DEFAULT_W3_LOG_ERRORS ),
|
|||
|
m_fLogSuccess (DEFAULT_W3_LOG_SUCCESS ),
|
|||
|
#if 0
|
|||
|
m_cbUploadReadAhead (DEFAULT_W3_UPLOAD_READ_AHEAD ),
|
|||
|
#endif
|
|||
|
m_fUsePoolThreadForCGI (DEFAULT_W3_USE_POOL_THREAD_FOR_CGI ),
|
|||
|
m_pszAccessDeniedMsg (NULL ),
|
|||
|
m_dwNetLogonWks (DEFAULT_W3_NET_LOGON_WKS),
|
|||
|
m_cAdvNotPwdExpInDays (DEFAULT_W3_ADV_NOT_PWD_EXP_IN_DAYS),
|
|||
|
m_dwAdvCacheTTL (DEFAULT_W3_ADV_CACHE_TTL),
|
|||
|
m_pFilterList ( NULL ),
|
|||
|
m_fAllowPathInfoForScriptMappings ( DEFAULT_W3_ALLOW_PATH_INFO_FOR_SCRIPT_MAPPINGS ),
|
|||
|
m_fProcessNtcrIfLoggedOn ( DEFAULT_W3_PROCESS_NTCR_IF_LOGGED_ON ),
|
|||
|
m_pW3Stats ( NULL ),
|
|||
|
m_dwSslCa ( 0 ),
|
|||
|
m_dwJobResetInterval ( DEFAULT_W3_CPU_RESET_INTERVAL ),
|
|||
|
m_tsJobLock ( ),
|
|||
|
m_llJobResetIntervalCPU ( GetCPUTimeFromInterval(DEFAULT_W3_CPU_RESET_INTERVAL) ),
|
|||
|
m_dwJobQueryInterval ( DEFAULT_W3_CPU_QUERY_INTERVAL ),
|
|||
|
m_dwJobLoggingSchedulerCookie ( 0 ),
|
|||
|
m_dwJobIntervalSchedulerCookie ( 0 ),
|
|||
|
m_dwJobCGICPULimit ( DEFAULT_W3_CPU_CGI_LIMIT ),
|
|||
|
m_dwJobLoggingOptions ( DEFAULT_W3_CPU_LOGGING_OPTIONS ),
|
|||
|
m_pwjoApplication ( NULL ),
|
|||
|
m_pwjoCGI ( NULL ),
|
|||
|
m_dwLastJobState ( MD_SERVER_STATE_STOPPED ),
|
|||
|
m_llJobSiteCPULimitLogEvent ( PercentCPULimitToCPUTime(DEFAULT_W3_CPU_LIMIT_EVENTLOG) ),
|
|||
|
m_llJobSiteCPULimitPriority ( PercentCPULimitToCPUTime(DEFAULT_W3_CPU_LIMIT_PRIORITY) ),
|
|||
|
m_llJobSiteCPULimitProcStop ( PercentCPULimitToCPUTime(DEFAULT_W3_CPU_LIMIT_PROCSTOP) ),
|
|||
|
m_llJobSiteCPULimitPause ( PercentCPULimitToCPUTime(DEFAULT_W3_CPU_LIMIT_PAUSE) ),
|
|||
|
m_fJobSiteCPULimitLogEventEnabled ( FALSE ),
|
|||
|
m_fJobSiteCPULimitPriorityEnabled ( FALSE ),
|
|||
|
m_fJobSiteCPULimitProcStopEnabled ( FALSE ),
|
|||
|
m_fJobSiteCPULimitPauseEnabled ( FALSE ),
|
|||
|
m_fCPULoggingEnabled ( FALSE ),
|
|||
|
m_fCPULimitsEnabled ( FALSE ),
|
|||
|
m_pSSLInfo ( NULL )
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
DWORD i;
|
|||
|
|
|||
|
IF_DEBUG(INSTANCE) {
|
|||
|
DBGPRINTF(( DBG_CONTEXT,
|
|||
|
"Init instance from %s\n", lpszRegParamKey ));
|
|||
|
}
|
|||
|
|
|||
|
for ( i = 0 ; i < MT_LAST ; ++i ) {
|
|||
|
m_apMappers[i] = NULL;
|
|||
|
}
|
|||
|
|
|||
|
if ( QueryServerState( ) == MD_SERVER_STATE_INVALID ) {
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Create statistics object
|
|||
|
//
|
|||
|
|
|||
|
m_pW3Stats = new W3_SERVER_STATISTICS();
|
|||
|
|
|||
|
if ( m_pW3Stats == NULL ) {
|
|||
|
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
|
|||
|
SetServerState(MD_SERVER_STATE_INVALID, ERROR_NOT_ENOUGH_MEMORY);
|
|||
|
}
|
|||
|
|
|||
|
return;
|
|||
|
|
|||
|
} // W3_SERVER_INSTANCE::W3_SERVER_INSTANCE
|
|||
|
|
|||
|
|
|||
|
|
|||
|
W3_SERVER_INSTANCE::~W3_SERVER_INSTANCE(
|
|||
|
VOID
|
|||
|
)
|
|||
|
{
|
|||
|
DWORD i = 0;
|
|||
|
|
|||
|
//
|
|||
|
// There seems to be a lag betwenn calling RemoveWorkItem and
|
|||
|
// the last possible call from the scheduler. For now,
|
|||
|
// Just put this at the beginning of the destructor so items
|
|||
|
// will actually get removed before constructor completes.
|
|||
|
//
|
|||
|
|
|||
|
|
|||
|
if (m_dwJobLoggingSchedulerCookie != 0) {
|
|||
|
RemoveWorkItem( m_dwJobLoggingSchedulerCookie );
|
|||
|
}
|
|||
|
|
|||
|
if (m_dwJobIntervalSchedulerCookie != 0) {
|
|||
|
RemoveWorkItem( m_dwJobIntervalSchedulerCookie );
|
|||
|
}
|
|||
|
|
|||
|
if ((m_dwJobLoggingSchedulerCookie != 0) ||
|
|||
|
(m_dwJobIntervalSchedulerCookie != 0)) {
|
|||
|
QueryAndLogJobInfo(JOLE_SITE_STOP);
|
|||
|
}
|
|||
|
|
|||
|
delete m_pwjoApplication;
|
|||
|
delete m_pwjoCGI;
|
|||
|
|
|||
|
//
|
|||
|
// delete statistics object
|
|||
|
//
|
|||
|
|
|||
|
if( m_pW3Stats != NULL )
|
|||
|
{
|
|||
|
delete m_pW3Stats;
|
|||
|
m_pW3Stats = NULL;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Free the registry strings.
|
|||
|
//
|
|||
|
|
|||
|
CleanupRegistryStrings( );
|
|||
|
|
|||
|
if ( m_pszDefaultHostName != NULL ) {
|
|||
|
TCP_FREE(m_pszDefaultHostName);
|
|||
|
m_pszDefaultHostName = NULL;
|
|||
|
}
|
|||
|
|
|||
|
if ( m_pFilterList ) {
|
|||
|
FILTER_LIST::Dereference( m_pFilterList );
|
|||
|
}
|
|||
|
|
|||
|
UINT iM;
|
|||
|
for ( iM = 0 ; iM < MT_LAST ; ++iM )
|
|||
|
{
|
|||
|
if ( m_apMappers[iM] )
|
|||
|
{
|
|||
|
((RefBlob*)(m_apMappers[iM]))->Release();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
ResetSSLInfo( this );
|
|||
|
|
|||
|
} // W3_SERVER_INSTANCE::~W3_SERVER_INSTANCE
|
|||
|
|
|||
|
|
|||
|
DWORD
|
|||
|
W3_SERVER_INSTANCE::StartInstance()
|
|||
|
{
|
|||
|
IF_DEBUG(INSTANCE) {
|
|||
|
DBGPRINTF((
|
|||
|
DBG_CONTEXT,
|
|||
|
"W3_SERVER_INSTANCE::StartInstance called for %p. Current state %d\n",
|
|||
|
this,
|
|||
|
QueryServerState()
|
|||
|
));
|
|||
|
}
|
|||
|
|
|||
|
DWORD dwError = IIS_SERVER_INSTANCE::StartInstance();
|
|||
|
|
|||
|
if ( dwError)
|
|||
|
{
|
|||
|
IF_DEBUG(INSTANCE) {
|
|||
|
DBGPRINTF((
|
|||
|
DBG_CONTEXT,
|
|||
|
"W3_SERVER_INSTANCE - IIS_SERVER_INSTANCE Failed. StartInstance returned 0x%x",
|
|||
|
dwError
|
|||
|
));
|
|||
|
}
|
|||
|
|
|||
|
return dwError;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Read the w3 specfic params
|
|||
|
//
|
|||
|
|
|||
|
if ( !ReadPrivateW3Params( ) ) {
|
|||
|
|
|||
|
DBGERROR((
|
|||
|
DBG_CONTEXT,
|
|||
|
"[W3_SERVER_INSTANCE::StartInstance] id(%d) "
|
|||
|
"ReadPrivateW3Params failed\n",
|
|||
|
QueryInstanceId()
|
|||
|
));
|
|||
|
|
|||
|
goto error_exit;
|
|||
|
}
|
|||
|
|
|||
|
if ( !ReadPublicW3Params( FC_W3_ALL ) ) {
|
|||
|
|
|||
|
DBGERROR((
|
|||
|
DBG_CONTEXT,
|
|||
|
"[W3_SERVER_INSTANCE::StartInstance] id(%d) "
|
|||
|
"ReadPublicW3Params failed\n",
|
|||
|
QueryInstanceId()
|
|||
|
));
|
|||
|
|
|||
|
goto error_exit;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Get host name
|
|||
|
//
|
|||
|
|
|||
|
InitializeHostName( );
|
|||
|
|
|||
|
//
|
|||
|
// Directory browsing
|
|||
|
//
|
|||
|
|
|||
|
InitializeDirBrowsing( );
|
|||
|
|
|||
|
if ( !CreateFilterList() ) {
|
|||
|
|
|||
|
DBGERROR((
|
|||
|
DBG_CONTEXT,
|
|||
|
"[W3_SERVER_INSTANCE::StartInstance] id(%d) "
|
|||
|
"CreateFilterList failed\n",
|
|||
|
QueryInstanceId()
|
|||
|
));
|
|||
|
|
|||
|
goto error_exit;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Don't listen on the secure port if there aren't any filters to
|
|||
|
// handle it
|
|||
|
//
|
|||
|
|
|||
|
if ( !m_fAnySecureFilters ) {
|
|||
|
LockThisForWrite();
|
|||
|
RemoveSecureBindings();
|
|||
|
UnlockThis();
|
|||
|
}
|
|||
|
|
|||
|
DBG_ASSERT(m_pW3Stats);
|
|||
|
m_pW3Stats->UpdateStartTime();
|
|||
|
|
|||
|
|
|||
|
return ERROR_SUCCESS;
|
|||
|
|
|||
|
error_exit:
|
|||
|
|
|||
|
//
|
|||
|
// We don't know the exact error to set here, as the above functions
|
|||
|
// that can fail do not SetLastError() consistently.
|
|||
|
//
|
|||
|
|
|||
|
return (GetLastError() != NO_ERROR) ? GetLastError() :
|
|||
|
ERROR_NOT_ENOUGH_MEMORY;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
DWORD
|
|||
|
W3_SERVER_INSTANCE::StopInstance()
|
|||
|
{
|
|||
|
DBG_ASSERT(m_pW3Stats);
|
|||
|
m_pW3Stats->UpdateStopTime();
|
|||
|
|
|||
|
return IIS_SERVER_INSTANCE::StopInstance();
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
BOOL
|
|||
|
W3_SERVER_INSTANCE::ReadMappers(
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Description
|
|||
|
|
|||
|
Read mappers for this instance
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
TRUE if successful, FALSE otherwise
|
|||
|
|
|||
|
Note :
|
|||
|
Instance must be locked before calling this function
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
DWORD dwR;
|
|||
|
UINT iM;
|
|||
|
LPVOID aOldMappers[MT_LAST];
|
|||
|
BOOL fSt = FALSE;
|
|||
|
|
|||
|
//
|
|||
|
// release reference to current mappers
|
|||
|
//
|
|||
|
|
|||
|
memcpy( aOldMappers, m_apMappers, MT_LAST*sizeof(LPVOID) );
|
|||
|
|
|||
|
for ( iM = 0 ; iM < MT_LAST ; ++iM )
|
|||
|
{
|
|||
|
if ( m_apMappers[iM] )
|
|||
|
{
|
|||
|
((RefBlob*)(m_apMappers[iM]))->Release();
|
|||
|
m_apMappers[iM] = NULL;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Read mappers from Name Space Extension Metabase
|
|||
|
//
|
|||
|
|
|||
|
if ( !g_pInetSvc->QueryMDNseObject() )
|
|||
|
{
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
MB mbx( (IMDCOM*) g_pInetSvc->QueryMDNseObject() );
|
|||
|
|
|||
|
if ( mbx.Open( QueryMDPath() ) )
|
|||
|
{
|
|||
|
dwR = sizeof(LPVOID);
|
|||
|
if ( !mbx.GetData( NSEPM_CERT11_PATH,
|
|||
|
MD_CPP_CERT11,
|
|||
|
IIS_MD_UT_SERVER,
|
|||
|
BINARY_METADATA,
|
|||
|
&m_apMappers[MT_CERT11],
|
|||
|
&dwR,
|
|||
|
0 ) )
|
|||
|
{
|
|||
|
m_apMappers[MT_CERT11] = NULL;
|
|||
|
}
|
|||
|
dwR = sizeof(LPVOID);
|
|||
|
if ( !mbx.GetData( NSEPM_CERTW_PATH,
|
|||
|
MD_CPP_CERTW,
|
|||
|
IIS_MD_UT_SERVER,
|
|||
|
BINARY_METADATA,
|
|||
|
&m_apMappers[MT_CERTW],
|
|||
|
&dwR,
|
|||
|
0 ) )
|
|||
|
{
|
|||
|
m_apMappers[MT_CERTW] = NULL;
|
|||
|
}
|
|||
|
dwR = sizeof(LPVOID);
|
|||
|
if ( !mbx.GetData( NSEPM_BASIC_PATH,
|
|||
|
MD_CPP_ITA,
|
|||
|
IIS_MD_UT_SERVER,
|
|||
|
BINARY_METADATA,
|
|||
|
&m_apMappers[MT_ITA],
|
|||
|
&dwR,
|
|||
|
0 ) )
|
|||
|
{
|
|||
|
m_apMappers[MT_ITA] = NULL;
|
|||
|
}
|
|||
|
dwR = sizeof(LPVOID);
|
|||
|
if ( !mbx.GetData( NSEPM_DIGEST_PATH,
|
|||
|
MD_CPP_DIGEST,
|
|||
|
IIS_MD_UT_SERVER,
|
|||
|
BINARY_METADATA,
|
|||
|
&m_apMappers[MT_MD5],
|
|||
|
&dwR,
|
|||
|
0 ) )
|
|||
|
{
|
|||
|
m_apMappers[MT_MD5] = NULL;
|
|||
|
}
|
|||
|
mbx.Close();
|
|||
|
|
|||
|
fSt = TRUE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Call notification functions for mappers existence change
|
|||
|
// ( i.e. from non-exist to exist or exist to non-exist )
|
|||
|
//
|
|||
|
|
|||
|
if ( (aOldMappers[MT_CERT11] == NULL) != (m_apMappers[MT_CERT11] == NULL)
|
|||
|
&& g_pFlushMapperNotify[MT_CERT11] )
|
|||
|
{
|
|||
|
(g_pFlushMapperNotify[MT_CERT11])( SF_NOTIFY_MAPPER_CERT11_CHANGED, this );
|
|||
|
}
|
|||
|
|
|||
|
if ( (aOldMappers[MT_CERTW] == NULL) != (m_apMappers[MT_CERTW] == NULL)
|
|||
|
&& g_pFlushMapperNotify[MT_CERTW] )
|
|||
|
{
|
|||
|
(g_pFlushMapperNotify[MT_CERTW])( SF_NOTIFY_MAPPER_CERTW_CHANGED, this );
|
|||
|
}
|
|||
|
|
|||
|
if ( (aOldMappers[MT_ITA] == NULL) != (m_apMappers[MT_ITA] == NULL)
|
|||
|
&& g_pFlushMapperNotify[MT_ITA] )
|
|||
|
{
|
|||
|
(g_pFlushMapperNotify[MT_ITA])( SF_NOTIFY_MAPPER_ITA_CHANGED, this );
|
|||
|
}
|
|||
|
|
|||
|
if ( (aOldMappers[MT_MD5] == NULL) != (m_apMappers[MT_MD5] == NULL)
|
|||
|
&& g_pFlushMapperNotify[MT_MD5] )
|
|||
|
{
|
|||
|
(g_pFlushMapperNotify[MT_MD5])( SF_NOTIFY_MAPPER_MD5_CHANGED, this );
|
|||
|
}
|
|||
|
|
|||
|
return fSt;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
BOOL
|
|||
|
W3_SERVER_INSTANCE::ReadPrivateW3Params(
|
|||
|
VOID
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Description
|
|||
|
|
|||
|
Reads reg values not defined in UI
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
fc - Items to read
|
|||
|
|
|||
|
Note:
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
DWORD err;
|
|||
|
HKEY hkey;
|
|||
|
HKEY hDefkey;
|
|||
|
DWORD cProv = 0;
|
|||
|
BOOL fRet = TRUE;
|
|||
|
STR strProviderList;
|
|||
|
MB mb( (IMDCOM*) g_pInetSvc->QueryMDObject() );
|
|||
|
DWORD dwValue;
|
|||
|
DWORD i;
|
|||
|
|
|||
|
err = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
|
|||
|
QueryRegParamKey( ),
|
|||
|
0,
|
|||
|
KEY_READ,
|
|||
|
&hkey );
|
|||
|
|
|||
|
if ( err != NO_ERROR ) {
|
|||
|
return(TRUE);
|
|||
|
}
|
|||
|
|
|||
|
err = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
|
|||
|
W3_PARAMETERS_KEY,
|
|||
|
0,
|
|||
|
KEY_READ,
|
|||
|
&hDefkey );
|
|||
|
|
|||
|
if ( err != NO_ERROR ) {
|
|||
|
RegCloseKey( hkey );
|
|||
|
return(TRUE);
|
|||
|
}
|
|||
|
|
|||
|
LockThisForWrite();
|
|||
|
|
|||
|
if ( !ReadMappers() ) {
|
|||
|
|
|||
|
//
|
|||
|
// Ignore error for win95
|
|||
|
//
|
|||
|
|
|||
|
if ( !g_fIsWindows95 ) {
|
|||
|
DBGPRINTF((DBG_CONTEXT,"Call to ReadMapper failed\n"));
|
|||
|
fRet = FALSE;
|
|||
|
goto exit;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#if 0
|
|||
|
m_fUseHostName = !!ReadRegistryDword( hkey,
|
|||
|
W3_DEFAULT_HOST_NAME,
|
|||
|
DEFAULT_W3_USE_HOST_NAME);
|
|||
|
#endif
|
|||
|
m_fAcceptByteRanges = !!ReadRegistryDword( hkey,
|
|||
|
W3_ACCEPT_BYTE_RANGES,
|
|||
|
DEFAULT_W3_ACCEPT_BYTE_RANGES);
|
|||
|
|
|||
|
m_fLogErrors = !!ReadRegistryDword( hkey,
|
|||
|
W3_LOG_ERRORS,
|
|||
|
DEFAULT_W3_LOG_ERRORS );
|
|||
|
|
|||
|
m_fLogSuccess = !!ReadRegistryDword( hkey,
|
|||
|
W3_LOG_SUCCESS,
|
|||
|
DEFAULT_W3_LOG_SUCCESS );
|
|||
|
|
|||
|
|
|||
|
ReadRegString( hkey,
|
|||
|
&m_pszAccessDeniedMsg,
|
|||
|
W3_ACCESS_DENIED_MSG,
|
|||
|
DEFAULT_W3_ACCESS_DENIED_MSG );
|
|||
|
|
|||
|
if ( mb.Open( QueryMDPath() ) )
|
|||
|
{
|
|||
|
mb.GetStr( "",
|
|||
|
MD_AUTH_CHANGE_URL,
|
|||
|
IIS_MD_UT_SERVER,
|
|||
|
&m_strAuthChangeUrl );
|
|||
|
|
|||
|
mb.GetStr( "",
|
|||
|
MD_AUTH_EXPIRED_URL,
|
|||
|
IIS_MD_UT_SERVER,
|
|||
|
&m_strAuthExpiredUrl );
|
|||
|
|
|||
|
mb.GetStr( "",
|
|||
|
MD_AUTH_NOTIFY_PWD_EXP_URL,
|
|||
|
IIS_MD_UT_SERVER,
|
|||
|
&m_strAdvNotPwdExpUrl );
|
|||
|
|
|||
|
mb.GetStr( "",
|
|||
|
MD_AUTH_EXPIRED_UNSECUREURL,
|
|||
|
IIS_MD_UT_SERVER,
|
|||
|
&m_strAuthExpiredUnsecureUrl );
|
|||
|
|
|||
|
mb.GetStr( "",
|
|||
|
MD_AUTH_NOTIFY_PWD_EXP_UNSECUREURL,
|
|||
|
IIS_MD_UT_SERVER,
|
|||
|
&m_strAdvNotPwdExpUnsecureUrl );
|
|||
|
|
|||
|
if ( !mb.GetDword( "",
|
|||
|
MD_ADV_NOTIFY_PWD_EXP_IN_DAYS,
|
|||
|
IIS_MD_UT_SERVER,
|
|||
|
&m_cAdvNotPwdExpInDays ) )
|
|||
|
{
|
|||
|
m_cAdvNotPwdExpInDays = DEFAULT_W3_ADV_NOT_PWD_EXP_IN_DAYS;
|
|||
|
}
|
|||
|
|
|||
|
if ( !mb.GetDword( "",
|
|||
|
MD_CERT_CHECK_MODE,
|
|||
|
IIS_MD_UT_SERVER,
|
|||
|
&m_dwCertCheckMode ) )
|
|||
|
{
|
|||
|
m_dwCertCheckMode = 0;
|
|||
|
}
|
|||
|
|
|||
|
if ( !mb.GetDword( "",
|
|||
|
MD_AUTH_CHANGE_FLAGS,
|
|||
|
IIS_MD_UT_SERVER,
|
|||
|
&m_dwAuthChangeFlags ) )
|
|||
|
{
|
|||
|
m_dwAuthChangeFlags = 0;
|
|||
|
}
|
|||
|
|
|||
|
if ( !mb.GetDword( "",
|
|||
|
MD_ADV_CACHE_TTL,
|
|||
|
IIS_MD_UT_SERVER,
|
|||
|
&m_dwAdvCacheTTL ) )
|
|||
|
{
|
|||
|
m_dwAdvCacheTTL = DEFAULT_W3_ADV_CACHE_TTL;
|
|||
|
}
|
|||
|
|
|||
|
if ( !mb.GetDword( "",
|
|||
|
MD_NET_LOGON_WKS,
|
|||
|
IIS_MD_UT_SERVER,
|
|||
|
&m_dwNetLogonWks ) )
|
|||
|
{
|
|||
|
m_dwNetLogonWks = DEFAULT_W3_NET_LOGON_WKS;
|
|||
|
}
|
|||
|
|
|||
|
if ( !mb.GetDword( "",
|
|||
|
MD_USE_HOST_NAME,
|
|||
|
IIS_MD_UT_SERVER,
|
|||
|
&m_dwUseHostName ) )
|
|||
|
{
|
|||
|
m_dwUseHostName = DEFAULT_W3_USE_HOST_NAME;
|
|||
|
}
|
|||
|
|
|||
|
if ( !mb.GetDword( "",
|
|||
|
MD_ALLOW_PATH_INFO_FOR_SCRIPT_MAPPINGS,
|
|||
|
IIS_MD_UT_SERVER,
|
|||
|
&dwValue ) )
|
|||
|
{
|
|||
|
m_fAllowPathInfoForScriptMappings = DEFAULT_W3_ALLOW_PATH_INFO_FOR_SCRIPT_MAPPINGS;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
m_fAllowPathInfoForScriptMappings = !!dwValue;
|
|||
|
}
|
|||
|
|
|||
|
if ( !mb.GetDword( "",
|
|||
|
MD_PROCESS_NTCR_IF_LOGGED_ON,
|
|||
|
IIS_MD_UT_SERVER,
|
|||
|
&dwValue ) )
|
|||
|
{
|
|||
|
m_fProcessNtcrIfLoggedOn = DEFAULT_W3_PROCESS_NTCR_IF_LOGGED_ON;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
m_fProcessNtcrIfLoggedOn = !!dwValue;
|
|||
|
}
|
|||
|
|
|||
|
if ( !mb.GetBuffer( "",
|
|||
|
MD_SSL_CA,
|
|||
|
IIS_MD_UT_SERVER,
|
|||
|
&m_buSslCa,
|
|||
|
&m_dwSslCa ) )
|
|||
|
{
|
|||
|
m_dwSslCa = 0;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Get Job Object Info
|
|||
|
// Constructor initialized these to defaults, so don't need to handle
|
|||
|
// error case. Do need to handle changes;
|
|||
|
//
|
|||
|
|
|||
|
if ((!mb.GetDword( NULL,
|
|||
|
MD_CPU_RESET_INTERVAL,
|
|||
|
IIS_MD_UT_SERVER,
|
|||
|
&dwValue )) ||
|
|||
|
(dwValue == 0) )
|
|||
|
{
|
|||
|
//
|
|||
|
// 0 is invalid and could result in a divide by 0 error
|
|||
|
//
|
|||
|
|
|||
|
dwValue = DEFAULT_W3_CPU_RESET_INTERVAL;
|
|||
|
}
|
|||
|
|
|||
|
if (m_dwJobResetInterval != dwValue)
|
|||
|
{
|
|||
|
m_dwJobResetInterval = dwValue;
|
|||
|
ResetJobResetInterval();
|
|||
|
}
|
|||
|
|
|||
|
LockJobsForWrite();
|
|||
|
|
|||
|
if (!mb.GetDword( NULL,
|
|||
|
MD_CPU_LIMITS_ENABLED,
|
|||
|
IIS_MD_UT_SERVER,
|
|||
|
&dwValue ))
|
|||
|
{
|
|||
|
dwValue = FALSE;
|
|||
|
}
|
|||
|
|
|||
|
if ((BOOL)dwValue != m_fCPULimitsEnabled)
|
|||
|
{
|
|||
|
|
|||
|
m_fCPULimitsEnabled = dwValue;
|
|||
|
|
|||
|
if (m_fCPULimitsEnabled) {
|
|||
|
|
|||
|
//
|
|||
|
// Start the reset interval, completion ports, and limits
|
|||
|
//
|
|||
|
|
|||
|
StartJobs();
|
|||
|
}
|
|||
|
else {
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Start the reset interval, completion ports, and limits
|
|||
|
//
|
|||
|
|
|||
|
StopJobs();
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if ((!mb.GetDword( NULL,
|
|||
|
MD_CPU_LOGGING_INTERVAL,
|
|||
|
IIS_MD_UT_SERVER,
|
|||
|
&dwValue )) ||
|
|||
|
(dwValue == 0))
|
|||
|
{
|
|||
|
dwValue = DEFAULT_W3_CPU_QUERY_INTERVAL;
|
|||
|
}
|
|||
|
|
|||
|
if (m_dwJobQueryInterval != dwValue)
|
|||
|
{
|
|||
|
m_dwJobQueryInterval = dwValue;
|
|||
|
ResetJobQueryInterval();
|
|||
|
}
|
|||
|
|
|||
|
if (!mb.GetDword( NULL,
|
|||
|
MD_CPU_LOGGING_MASK,
|
|||
|
IIS_MD_UT_SERVER,
|
|||
|
&dwValue )) {
|
|||
|
dwValue = DEFAULT_W3_CPU_LOGGING_MASK;
|
|||
|
}
|
|||
|
|
|||
|
{
|
|||
|
BOOL fLoggingEnabled = ((dwValue & MD_CPU_ENABLE_LOGGING) != 0) ? TRUE : FALSE;
|
|||
|
if (m_fCPULoggingEnabled != fLoggingEnabled)
|
|||
|
{
|
|||
|
m_fCPULoggingEnabled = fLoggingEnabled;
|
|||
|
if (m_fCPULoggingEnabled) {
|
|||
|
|
|||
|
//
|
|||
|
// Start the reset interval, logging interval
|
|||
|
//
|
|||
|
|
|||
|
StartJobs();
|
|||
|
}
|
|||
|
else {
|
|||
|
|
|||
|
//
|
|||
|
// Stop the reset interval, logging interval
|
|||
|
//
|
|||
|
|
|||
|
StopJobs();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (mb.GetDword( NULL,
|
|||
|
MD_CPU_CGI_LIMIT,
|
|||
|
IIS_MD_UT_SERVER,
|
|||
|
&dwValue ))
|
|||
|
{
|
|||
|
if (m_dwJobCGICPULimit != dwValue)
|
|||
|
{
|
|||
|
m_dwJobCGICPULimit = dwValue;
|
|||
|
SetJobLimits(SLA_PROCESS_CPU_LIMIT, m_dwJobCGICPULimit);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
mb.GetDword( NULL,
|
|||
|
MD_CPU_LOGGING_OPTIONS,
|
|||
|
IIS_MD_UT_SERVER,
|
|||
|
&m_dwJobLoggingOptions );
|
|||
|
|
|||
|
BOOL fLimitsChanged = FALSE;
|
|||
|
|
|||
|
if (mb.GetDword( NULL,
|
|||
|
MD_CPU_LIMIT_LOGEVENT,
|
|||
|
IIS_MD_UT_SERVER,
|
|||
|
&dwValue ))
|
|||
|
{
|
|||
|
if (m_llJobSiteCPULimitLogEvent != PercentCPULimitToCPUTime(dwValue))
|
|||
|
{
|
|||
|
m_llJobSiteCPULimitLogEvent = PercentCPULimitToCPUTime(dwValue);
|
|||
|
fLimitsChanged = TRUE;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (mb.GetDword( NULL,
|
|||
|
MD_CPU_LIMIT_PRIORITY,
|
|||
|
IIS_MD_UT_SERVER,
|
|||
|
&dwValue ))
|
|||
|
{
|
|||
|
if (m_llJobSiteCPULimitPriority != PercentCPULimitToCPUTime(dwValue))
|
|||
|
{
|
|||
|
m_llJobSiteCPULimitPriority = PercentCPULimitToCPUTime(dwValue);
|
|||
|
fLimitsChanged = TRUE;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (mb.GetDword( NULL,
|
|||
|
MD_CPU_LIMIT_PROCSTOP,
|
|||
|
IIS_MD_UT_SERVER,
|
|||
|
&dwValue ))
|
|||
|
{
|
|||
|
if (m_llJobSiteCPULimitProcStop != PercentCPULimitToCPUTime(dwValue))
|
|||
|
{
|
|||
|
m_llJobSiteCPULimitProcStop = PercentCPULimitToCPUTime(dwValue);
|
|||
|
fLimitsChanged = TRUE;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (mb.GetDword( NULL,
|
|||
|
MD_CPU_LIMIT_PAUSE,
|
|||
|
IIS_MD_UT_SERVER,
|
|||
|
&dwValue ))
|
|||
|
{
|
|||
|
if (m_llJobSiteCPULimitPause != PercentCPULimitToCPUTime(dwValue))
|
|||
|
{
|
|||
|
m_llJobSiteCPULimitPause = PercentCPULimitToCPUTime(dwValue);
|
|||
|
fLimitsChanged = TRUE;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (fLimitsChanged) {
|
|||
|
SetJobSiteCPULimits(TRUE);
|
|||
|
}
|
|||
|
|
|||
|
UnlockJobs();
|
|||
|
|
|||
|
mb.Close();
|
|||
|
}
|
|||
|
|
|||
|
#if 0
|
|||
|
m_cbUploadReadAhead = ReadRegistryDword( hkey,
|
|||
|
W3_UPLOAD_READ_AHEAD,
|
|||
|
DEFAULT_W3_UPLOAD_READ_AHEAD );
|
|||
|
#endif
|
|||
|
|
|||
|
m_fUsePoolThreadForCGI = !!ReadRegistryDword( hkey,
|
|||
|
W3_USE_POOL_THREAD_FOR_CGI,
|
|||
|
DEFAULT_W3_USE_POOL_THREAD_FOR_CGI );
|
|||
|
|
|||
|
exit:
|
|||
|
UnlockThis();
|
|||
|
|
|||
|
DBG_REQUIRE( !RegCloseKey( hkey ));
|
|||
|
DBG_REQUIRE( !RegCloseKey( hDefkey ));
|
|||
|
return(fRet);
|
|||
|
|
|||
|
} // W3_SERVER_INSTANCE::ReadPrivateW3Params
|
|||
|
|
|||
|
|
|||
|
|
|||
|
BOOL
|
|||
|
W3_SERVER_INSTANCE::ReadPublicW3Params(
|
|||
|
IN FIELD_CONTROL fc
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Initializes HTTP parameters from the registry
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
fc - Items to read
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
TRUE if successful, FALSE on error
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
#if 0
|
|||
|
DWORD err;
|
|||
|
BOOL fRet = TRUE;
|
|||
|
HKEY hkeyW3;
|
|||
|
|
|||
|
//
|
|||
|
// Connect to the registry.
|
|||
|
//
|
|||
|
|
|||
|
err = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
|
|||
|
QueryRegParamKey( ),
|
|||
|
0,
|
|||
|
KEY_ALL_ACCESS,
|
|||
|
&hkeyW3 );
|
|||
|
|
|||
|
if( err != NO_ERROR )
|
|||
|
{
|
|||
|
DBGPRINTF(( DBG_CONTEXT,
|
|||
|
"cannot open registry key, error %lu\n",
|
|||
|
err ));
|
|||
|
|
|||
|
err = NO_ERROR;
|
|||
|
}
|
|||
|
|
|||
|
LockThisForWrite();
|
|||
|
|
|||
|
//
|
|||
|
// Read registry data.
|
|||
|
//
|
|||
|
|
|||
|
UnlockThis( );
|
|||
|
RegCloseKey( hkeyW3 );
|
|||
|
|
|||
|
return fRet;
|
|||
|
#endif
|
|||
|
|
|||
|
return TRUE;
|
|||
|
} // W3_SERVER_INSTANCE::ReadPublicW3Params
|
|||
|
|
|||
|
|
|||
|
|
|||
|
BOOL
|
|||
|
W3_SERVER_INSTANCE::WritePublicW3Params(
|
|||
|
IN LPW3_CONFIG_INFO pConfig
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Description
|
|||
|
|
|||
|
Updates the registry with the passed parameters
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
pConfig - Items to write to the registry
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
DWORD err;
|
|||
|
BOOL fRet = TRUE;
|
|||
|
HKEY hkey;
|
|||
|
DWORD disp;
|
|||
|
|
|||
|
//
|
|||
|
// Connect to the registry.
|
|||
|
//
|
|||
|
|
|||
|
err = RegCreateKeyEx( HKEY_LOCAL_MACHINE,
|
|||
|
QueryRegParamKey(),
|
|||
|
0,
|
|||
|
NULL,
|
|||
|
0,
|
|||
|
KEY_READ|KEY_WRITE,
|
|||
|
NULL,
|
|||
|
&hkey,
|
|||
|
&disp );
|
|||
|
|
|||
|
if( err != NO_ERROR )
|
|||
|
{
|
|||
|
DBGPRINTF(( DBG_CONTEXT,
|
|||
|
"cannot open registry key, error %lu\n",
|
|||
|
err ));
|
|||
|
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Write the strings - Note some of these are written for registry
|
|||
|
// compatiblity with pre-metabase applications
|
|||
|
//
|
|||
|
|
|||
|
if ( !err && IsFieldSet( pConfig->FieldControl, FC_W3_DEFAULT_LOAD_FILE )
|
|||
|
&& (pConfig->lpszDefaultLoadFile != NULL) )
|
|||
|
{
|
|||
|
err = WriteRegistryStringW( hkey,
|
|||
|
W3_DEFAULT_FILE_W,
|
|||
|
pConfig->lpszDefaultLoadFile,
|
|||
|
(wcslen( pConfig->lpszDefaultLoadFile ) + 1) *
|
|||
|
sizeof( WCHAR ),
|
|||
|
REG_SZ);
|
|||
|
}
|
|||
|
|
|||
|
if ( hkey )
|
|||
|
RegCloseKey( hkey );
|
|||
|
|
|||
|
if ( err )
|
|||
|
{
|
|||
|
SetLastError( err );
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
return TRUE;
|
|||
|
|
|||
|
} // W3_SERVER_INSTANCE::WritePublicW3Params
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
W3_SERVER_INSTANCE::MDChangeNotify(
|
|||
|
MD_CHANGE_OBJECT * pcoChangeList
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
This method handles the metabase change notification for this instance
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
pcoChangeList - path and id that has changed
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
DWORD i;
|
|||
|
BOOL fFiltersModified = FALSE;
|
|||
|
PCSTR pszURL;
|
|||
|
DWORD dwURLLength;
|
|||
|
BOOL fSslModified = FALSE;
|
|||
|
|
|||
|
LockThisForWrite();
|
|||
|
|
|||
|
//
|
|||
|
// Tell our parent about the change notification first
|
|||
|
//
|
|||
|
|
|||
|
IIS_SERVER_INSTANCE::MDChangeNotify( pcoChangeList );
|
|||
|
|
|||
|
//
|
|||
|
// Now flush the metacache and relevant file handle cache entries.
|
|||
|
//
|
|||
|
|
|||
|
TsFlushMetaCache(METACACHE_W3_SERVER_ID, FALSE);
|
|||
|
|
|||
|
if (!IISstrnicmp((PUCHAR)pcoChangeList->pszMDPath, (PUCHAR)QueryMDVRPath(),
|
|||
|
IISstrlen( (PUCHAR)QueryMDVRPath() )))
|
|||
|
{
|
|||
|
pszURL = (CHAR *)pcoChangeList->pszMDPath + QueryMDVRPathLen() - 1;
|
|||
|
|
|||
|
//
|
|||
|
// Figure out the length of the URL. Unless this is the root,
|
|||
|
// we want to strip the trailing slash.
|
|||
|
|
|||
|
if (memcmp(pszURL, "/", sizeof("/")) != 0)
|
|||
|
{
|
|||
|
dwURLLength = strlen(pszURL) - 1;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
dwURLLength = sizeof("/") - 1;
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
//
|
|||
|
// Presumably this is for a change above the root URL level, i.e. a
|
|||
|
// change of a property at the service level. Since this affects
|
|||
|
// everything, flush starting at the root.
|
|||
|
//
|
|||
|
|
|||
|
pszURL = "/";
|
|||
|
dwURLLength = sizeof("/") - 1;
|
|||
|
}
|
|||
|
|
|||
|
DBG_ASSERT(pszURL != NULL);
|
|||
|
DBG_ASSERT(*pszURL != '\0');
|
|||
|
|
|||
|
TsFlushURL(GetTsvcCache(), pszURL, dwURLLength, RESERVED_DEMUX_URI_INFO);
|
|||
|
|
|||
|
BOOL fReadPrivateW3Params = FALSE;
|
|||
|
|
|||
|
for ( i = 0; i < pcoChangeList->dwMDNumDataIDs; i++ )
|
|||
|
{
|
|||
|
switch ( pcoChangeList->pdwMDDataIDs[i] )
|
|||
|
{
|
|||
|
|
|||
|
case MD_FILTER_ENABLED:
|
|||
|
case MD_FILTER_IMAGE_PATH:
|
|||
|
case MD_FILTER_LOAD_ORDER:
|
|||
|
|
|||
|
if ( fFiltersModified ) // First change will pick up all changes
|
|||
|
continue;
|
|||
|
|
|||
|
if ( !CreateFilterList() )
|
|||
|
{
|
|||
|
DBGPRINTF(( DBG_CONTEXT,
|
|||
|
"Failed to create new filter list\n" ));
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
fFiltersModified = TRUE;
|
|||
|
}
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
case MD_SERIAL_CERT11: // Cert mapper support
|
|||
|
case MD_SERIAL_CERTW:
|
|||
|
case MD_SERIAL_DIGEST:
|
|||
|
case MD_SERIAL_ITA:
|
|||
|
|
|||
|
case MD_AUTH_CHANGE_URL:
|
|||
|
case MD_AUTH_EXPIRED_URL:
|
|||
|
case MD_AUTH_NOTIFY_PWD_EXP_URL:
|
|||
|
case MD_AUTH_EXPIRED_UNSECUREURL:
|
|||
|
case MD_AUTH_NOTIFY_PWD_EXP_UNSECUREURL:
|
|||
|
case MD_ADV_NOTIFY_PWD_EXP_IN_DAYS:
|
|||
|
case MD_CERT_CHECK_MODE:
|
|||
|
case MD_AUTH_CHANGE_FLAGS:
|
|||
|
case MD_ADV_CACHE_TTL:
|
|||
|
case MD_NET_LOGON_WKS:
|
|||
|
case MD_USE_HOST_NAME:
|
|||
|
case MD_ALLOW_PATH_INFO_FOR_SCRIPT_MAPPINGS:
|
|||
|
case MD_PROCESS_NTCR_IF_LOGGED_ON:
|
|||
|
case MD_CPU_LOGGING_OPTIONS:
|
|||
|
case MD_CPU_LOGGING_INTERVAL:
|
|||
|
case MD_CPU_RESET_INTERVAL:
|
|||
|
case MD_CPU_CGI_LIMIT:
|
|||
|
case MD_CPU_LIMIT_LOGEVENT:
|
|||
|
case MD_CPU_LIMIT_PRIORITY:
|
|||
|
case MD_CPU_LIMIT_PROCSTOP:
|
|||
|
case MD_CPU_LIMIT_PAUSE:
|
|||
|
case MD_CPU_LOGGING_MASK:
|
|||
|
case MD_CPU_LIMITS_ENABLED:
|
|||
|
case MD_SERVER_COMMENT:
|
|||
|
|
|||
|
fReadPrivateW3Params = TRUE;
|
|||
|
break;
|
|||
|
|
|||
|
//
|
|||
|
// Server cert properties
|
|||
|
//
|
|||
|
case MD_SSL_CERT_HASH:
|
|||
|
case MD_SSL_CERT_CONTAINER:
|
|||
|
case MD_SSL_CERT_PROVIDER:
|
|||
|
case MD_SSL_CERT_OPEN_FLAGS:
|
|||
|
case MD_SSL_CERT_STORE_NAME:
|
|||
|
|
|||
|
//
|
|||
|
// Fortezza-specific
|
|||
|
//
|
|||
|
case MD_SSL_CERT_IS_FORTEZZA:
|
|||
|
case MD_SSL_CERT_FORTEZZA_PIN:
|
|||
|
case MD_SSL_CERT_FORTEZZA_SERIAL_NUMBER:
|
|||
|
case MD_SSL_CERT_FORTEZZA_PERSONALITY:
|
|||
|
case MD_SSL_CERT_FORTEZZA_PROG_PIN:
|
|||
|
|
|||
|
//
|
|||
|
// Server CTL properties
|
|||
|
//
|
|||
|
case MD_SSL_CTL_IDENTIFIER:
|
|||
|
case MD_SSL_CTL_CONTAINER:
|
|||
|
case MD_SSL_CTL_PROVIDER:
|
|||
|
case MD_SSL_CTL_PROVIDER_TYPE:
|
|||
|
case MD_SSL_CTL_OPEN_FLAGS:
|
|||
|
case MD_SSL_CTL_STORE_NAME:
|
|||
|
case MD_SSL_CTL_SIGNER_HASH:
|
|||
|
case MD_SSL_USE_DS_MAPPER:
|
|||
|
|
|||
|
fSslModified = TRUE;
|
|||
|
break;
|
|||
|
|
|||
|
case MD_SERVER_STATE:
|
|||
|
|
|||
|
switch (QueryServerState()) {
|
|||
|
case MD_SERVER_STATE_STARTED:
|
|||
|
ProcessStartNotification();
|
|||
|
break;
|
|||
|
case MD_SERVER_STATE_STOPPED:
|
|||
|
ProcessStopNotification();
|
|||
|
break;
|
|||
|
case MD_SERVER_STATE_PAUSED:
|
|||
|
ProcessPauseNotification();
|
|||
|
break;
|
|||
|
default:
|
|||
|
;
|
|||
|
}
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (fReadPrivateW3Params) {
|
|||
|
if ( !ReadPrivateW3Params() )
|
|||
|
{
|
|||
|
DBGPRINTF(( DBG_CONTEXT,
|
|||
|
"Failed to re-read parameters\n" ));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
UnlockThis();
|
|||
|
|
|||
|
//
|
|||
|
// If anything related to SSL has changed, call the function used to flush
|
|||
|
// the SSL/Schannel credential cache and reset the server certificate
|
|||
|
//
|
|||
|
if ( fSslModified )
|
|||
|
{
|
|||
|
ResetSSLInfo( this );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
BOOL
|
|||
|
W3_SERVER_INSTANCE::CreateFilterList(
|
|||
|
VOID
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Description
|
|||
|
|
|||
|
Creates the list of filters this server instance needs to notify.
|
|||
|
If there's an existing filter list on this instance, the old filter
|
|||
|
list is atomically exchanged and allowed to die off.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
CHAR szFilterKey[MAX_PATH+1];
|
|||
|
FILTER_LIST * pfl;
|
|||
|
FILTER_LIST * pflOld;
|
|||
|
DWORD cb;
|
|||
|
DWORD fEnabled;
|
|||
|
CHAR szLoadOrder[1024];
|
|||
|
CHAR szDllName[MAX_PATH+1];
|
|||
|
CHAR * pchFilter;
|
|||
|
CHAR * pchComma;
|
|||
|
MB mb( (IMDCOM*) g_pInetSvc->QueryMDObject() );
|
|||
|
BOOL fOpened;
|
|||
|
|
|||
|
strcpy( szFilterKey, QueryMDPath() );
|
|||
|
strcat( szFilterKey, IIS_MD_ISAPI_FILTERS );
|
|||
|
DBG_ASSERT( strlen( szFilterKey ) + 1 < sizeof( szFilterKey ));
|
|||
|
|
|||
|
//
|
|||
|
// Create a filter list for this instance
|
|||
|
//
|
|||
|
|
|||
|
pfl = new FILTER_LIST();
|
|||
|
|
|||
|
if ( !pfl || !pfl->InsertGlobalFilters() ) {
|
|||
|
|
|||
|
delete pfl;
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Loop through filter keys, if we can't access the metabase, we assume
|
|||
|
// success and continue
|
|||
|
//
|
|||
|
|
|||
|
if ( mb.Open( szFilterKey,
|
|||
|
METADATA_PERMISSION_READ ))
|
|||
|
{
|
|||
|
fOpened = TRUE;
|
|||
|
|
|||
|
//
|
|||
|
// Get the filter load order
|
|||
|
//
|
|||
|
|
|||
|
cb = sizeof( szLoadOrder );
|
|||
|
*szLoadOrder = '\0';
|
|||
|
|
|||
|
if ( mb.GetString( "",
|
|||
|
MD_FILTER_LOAD_ORDER,
|
|||
|
IIS_MD_UT_SERVER,
|
|||
|
szLoadOrder,
|
|||
|
&cb,
|
|||
|
0 ))
|
|||
|
{
|
|||
|
pchFilter = szLoadOrder;
|
|||
|
|
|||
|
while ( *pchFilter )
|
|||
|
{
|
|||
|
if ( !fOpened &&
|
|||
|
!mb.Open( szFilterKey, METADATA_PERMISSION_READ ))
|
|||
|
{
|
|||
|
DBGPRINTF(( DBG_CONTEXT,
|
|||
|
"CreateFilterList: Cannot open path %s, error %lu\n",
|
|||
|
szFilterKey, GetLastError() ));
|
|||
|
break;
|
|||
|
}
|
|||
|
fOpened = TRUE;
|
|||
|
|
|||
|
pchComma = strchr( pchFilter, ',' );
|
|||
|
|
|||
|
if ( pchComma )
|
|||
|
{
|
|||
|
*pchComma = '\0';
|
|||
|
}
|
|||
|
|
|||
|
while ( ISWHITEA( *pchFilter ))
|
|||
|
{
|
|||
|
pchFilter++;
|
|||
|
}
|
|||
|
|
|||
|
fEnabled = TRUE;
|
|||
|
mb.GetDword( pchFilter,
|
|||
|
MD_FILTER_ENABLED,
|
|||
|
IIS_MD_UT_SERVER,
|
|||
|
&fEnabled );
|
|||
|
|
|||
|
if ( fEnabled )
|
|||
|
{
|
|||
|
cb = sizeof(szDllName);
|
|||
|
if ( mb.GetString( pchFilter,
|
|||
|
MD_FILTER_IMAGE_PATH,
|
|||
|
IIS_MD_UT_SERVER,
|
|||
|
szDllName,
|
|||
|
&cb,
|
|||
|
0 ))
|
|||
|
{
|
|||
|
mb.Close();
|
|||
|
fOpened = FALSE;
|
|||
|
|
|||
|
if ( pfl->LoadFilter( &mb, szFilterKey, &fOpened, pchFilter, szDllName, FALSE ))
|
|||
|
{
|
|||
|
DBGPRINTF(( DBG_CONTEXT,
|
|||
|
"[CreateFilterList] Loaded %s\n",
|
|||
|
szDllName ));
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if ( pchComma )
|
|||
|
{
|
|||
|
pchFilter = pchComma + 1;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Replace the old filter list with the new filter list
|
|||
|
//
|
|||
|
|
|||
|
LockThisForWrite();
|
|||
|
|
|||
|
pflOld = m_pFilterList;
|
|||
|
m_pFilterList = pfl;
|
|||
|
|
|||
|
UnlockThis();
|
|||
|
|
|||
|
if ( pflOld ) {
|
|||
|
FILTER_LIST::Dereference( pflOld );
|
|||
|
}
|
|||
|
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
#if 0
|
|||
|
|
|||
|
|
|||
|
|
|||
|
BOOL
|
|||
|
W3_SERVER_INSTANCE::UpdateFilterList(
|
|||
|
CHAR * pszNewDll,
|
|||
|
CHAR * pszOldDll
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Description
|
|||
|
|
|||
|
Given a filter dll to replace on this instance, this routine updates
|
|||
|
the filter list with the new dll and lets the old filter list die off
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
pszNewDll - Fully Qualified path to new dll - may be NULL
|
|||
|
pszOldDll - The DLL this filter is replacing (or NULL for just adding a
|
|||
|
new Filter)
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
FILTER_LIST * pfl;
|
|||
|
FILTER_LIST * pflOld;
|
|||
|
|
|||
|
DBG_ASSERT( m_pFilterList );
|
|||
|
|
|||
|
//
|
|||
|
// Create a new filter list for this instance and copy the old filter list
|
|||
|
//
|
|||
|
|
|||
|
pfl = new FILTER_LIST();
|
|||
|
|
|||
|
if ( !pfl ||
|
|||
|
!pfl->Copy( m_pFilterList ) ||
|
|||
|
!pfl->LoadFilter( pszNewDll, FALSE ) ||
|
|||
|
!pfl->Remove( pszOldDll ))
|
|||
|
{
|
|||
|
DBGPRINTF(( DBG_CONTEXT,
|
|||
|
"[UpdateFilterList] Failed - Error %d\n",
|
|||
|
GetLastError() ));
|
|||
|
|
|||
|
delete pfl;
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Replace the old filter list with the new filter list
|
|||
|
//
|
|||
|
|
|||
|
LockThisForWrite();
|
|||
|
|
|||
|
pflOld = m_pFilterList;
|
|||
|
m_pFilterList = pfl;
|
|||
|
|
|||
|
UnlockThis();
|
|||
|
|
|||
|
if ( pflOld ) {
|
|||
|
FILTER_LIST::Dereference( pflOld );
|
|||
|
}
|
|||
|
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
|
|||
|
APIERR
|
|||
|
W3_SERVER_INSTANCE::InitializeHostName(
|
|||
|
VOID
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Initializes the default host name
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Win32
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
//
|
|||
|
// Build Host Name to be used in URL creation
|
|||
|
//
|
|||
|
|
|||
|
if ( m_dwUseHostName )
|
|||
|
{
|
|||
|
char hn[128];
|
|||
|
PHOSTENT pH;
|
|||
|
|
|||
|
if ( !gethostname( hn, sizeof(hn) )
|
|||
|
&& (pH = gethostbyname( hn ))
|
|||
|
&& pH->h_name
|
|||
|
&& pH->h_addr_list
|
|||
|
&& pH->h_addr_list[0]
|
|||
|
#if 0
|
|||
|
// disabled for now : if the UseHostName flag is set,
|
|||
|
// we will always use the DNS name specified in the
|
|||
|
// TCP/IP configuration panel
|
|||
|
//
|
|||
|
|
|||
|
&& pH->h_addr_list[1] == NULL
|
|||
|
#endif
|
|||
|
)
|
|||
|
{
|
|||
|
m_pszDefaultHostName = (PCHAR)TCP_ALLOC(strlen( pH->h_name ) + 1);
|
|||
|
if ( m_pszDefaultHostName == NULL )
|
|||
|
{
|
|||
|
return(ERROR_NOT_ENOUGH_MEMORY);
|
|||
|
}
|
|||
|
strcpy( m_pszDefaultHostName, pH->h_name );
|
|||
|
|
|||
|
if ( m_pszDefaultHostName[0] == '\0' ) {
|
|||
|
TCP_FREE(m_pszDefaultHostName);
|
|||
|
m_pszDefaultHostName = NULL;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return(NO_ERROR);
|
|||
|
|
|||
|
} // W3_SERVER_INSTANCE::InitializeHostName
|
|||
|
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
W3_SERVER_INSTANCE::CleanupRegistryStrings(
|
|||
|
VOID
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Description
|
|||
|
|
|||
|
Frees all configurable strings in the W3_SERVER_INSTANCE class
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
DWORD i = 0;
|
|||
|
|
|||
|
if ( m_pszAccessDeniedMsg != NULL ) {
|
|||
|
TCP_FREE(m_pszAccessDeniedMsg);
|
|||
|
m_pszAccessDeniedMsg = NULL;
|
|||
|
}
|
|||
|
|
|||
|
return;
|
|||
|
|
|||
|
} // W3_SERVER_INSTANCE::CleanupRegistryStrings
|
|||
|
|
|||
|
|
|||
|
LPVOID
|
|||
|
W3_SERVER_INSTANCE::QueryMapper(
|
|||
|
MAPPER_TYPE mt
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Description
|
|||
|
|
|||
|
Returns mapper
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
mt - mapper type
|
|||
|
|
|||
|
Returns:
|
|||
|
|
|||
|
ptr to Blob referencing mapper or NULL if no such mapper
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
LPVOID pV;
|
|||
|
|
|||
|
LockThisForRead();
|
|||
|
|
|||
|
if ( pV = m_apMappers[(UINT)mt] )
|
|||
|
{
|
|||
|
((RefBlob*)pV)->AddRef();
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
pV = NULL;
|
|||
|
}
|
|||
|
|
|||
|
UnlockThis();
|
|||
|
|
|||
|
return pV;
|
|||
|
}
|
|||
|
|
|||
|
IIS_SSL_INFO*
|
|||
|
W3_SERVER_INSTANCE::GetAndReferenceSSLInfoObj( VOID )
|
|||
|
/*++
|
|||
|
|
|||
|
Description
|
|||
|
|
|||
|
Returns SSL info for this instance; calls Reference() before returning
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Returns:
|
|||
|
|
|||
|
Ptr to SSL info object on success, NULL if failure
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
IIS_SSL_INFO *pPtr = NULL;
|
|||
|
|
|||
|
LockThisForRead();
|
|||
|
|
|||
|
//
|
|||
|
// If it's null, we may have to create it - unlock, lock for write and make sure it's
|
|||
|
// still NULL before creating it
|
|||
|
//
|
|||
|
if ( !m_pSSLInfo )
|
|||
|
{
|
|||
|
UnlockThis();
|
|||
|
|
|||
|
LockThisForWrite();
|
|||
|
|
|||
|
//
|
|||
|
// Still null, so create it now
|
|||
|
//
|
|||
|
if ( !m_pSSLInfo )
|
|||
|
{
|
|||
|
m_pSSLInfo = IIS_SSL_INFO::CreateSSLInfo(
|
|||
|
(LPTSTR) QueryMDPath(),
|
|||
|
(IMDCOM *) g_pInetSvc->QueryMDObject() );
|
|||
|
|
|||
|
if ( m_pSSLInfo == NULL )
|
|||
|
{
|
|||
|
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
|
|||
|
UnlockThis();
|
|||
|
return NULL;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Acquire an internal reference
|
|||
|
//
|
|||
|
m_pSSLInfo->Reference();
|
|||
|
|
|||
|
//
|
|||
|
// Construct the server certificate and CTL and log
|
|||
|
// the status
|
|||
|
//
|
|||
|
IIS_SERVER_CERT *pCert = m_pSSLInfo->GetCertificate();
|
|||
|
if ( pCert )
|
|||
|
{
|
|||
|
LogCertStatus();
|
|||
|
}
|
|||
|
|
|||
|
IIS_CTL *pCTL = m_pSSLInfo->GetCTL();
|
|||
|
if ( pCTL )
|
|||
|
{
|
|||
|
LogCTLStatus();
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Register for changes
|
|||
|
//
|
|||
|
|
|||
|
if ( g_pStoreChangeNotifier )
|
|||
|
{
|
|||
|
if ( pCert && pCert->IsValid() )
|
|||
|
{
|
|||
|
//
|
|||
|
// Watch for changes to the store the cert came out of
|
|||
|
//
|
|||
|
if (!g_pStoreChangeNotifier->RegisterStoreForChange( pCert->QueryStoreName(),
|
|||
|
pCert->QueryStoreHandle(),
|
|||
|
ResetSSLInfo,
|
|||
|
(PVOID) this ) )
|
|||
|
{
|
|||
|
DBGPRINTF((DBG_CONTEXT,
|
|||
|
"Failed to register for change event on store %s\n",
|
|||
|
pCert->QueryStoreName()));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if ( pCTL && pCTL->IsValid() )
|
|||
|
{
|
|||
|
//
|
|||
|
// Watch for changes to the store the CTL came out of
|
|||
|
//
|
|||
|
if (!g_pStoreChangeNotifier->RegisterStoreForChange( pCTL->QueryStoreName(),
|
|||
|
pCTL->QueryOriginalStore(),
|
|||
|
ResetSSLInfo,
|
|||
|
(PVOID) this ) )
|
|||
|
{
|
|||
|
DBGPRINTF((DBG_CONTEXT,
|
|||
|
"Failed to register for change event on store %s\n",
|
|||
|
pCTL->QueryStoreName()));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
if ( ( pCert && pCert->IsValid()) ||
|
|||
|
( pCTL && pCTL->IsValid() ) )
|
|||
|
{
|
|||
|
HCERTSTORE hRootStore = CertOpenStore( CERT_STORE_PROV_SYSTEM_A,
|
|||
|
0,
|
|||
|
NULL,
|
|||
|
CERT_SYSTEM_STORE_LOCAL_MACHINE,
|
|||
|
"ROOT" );
|
|||
|
|
|||
|
if ( hRootStore )
|
|||
|
{
|
|||
|
//
|
|||
|
// Watch for changes to the ROOT store
|
|||
|
//
|
|||
|
if ( !g_pStoreChangeNotifier->RegisterStoreForChange( "ROOT",
|
|||
|
hRootStore,
|
|||
|
ResetSSLInfo,
|
|||
|
(PVOID) this ) )
|
|||
|
{
|
|||
|
DBGPRINTF((DBG_CONTEXT,
|
|||
|
"Failed to register for change event on root store\n"));
|
|||
|
}
|
|||
|
|
|||
|
CertCloseStore( hRootStore,
|
|||
|
0 );
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
DBGPRINTF((DBG_CONTEXT,
|
|||
|
"Failed to open ROOT store, error 0x%d\n",
|
|||
|
GetLastError()));
|
|||
|
|
|||
|
}
|
|||
|
} // if ( pCert || pCTL )
|
|||
|
|
|||
|
} // if (g_pStoreChangeNotifier)
|
|||
|
|
|||
|
} // if ( !m_pSSLInfo )
|
|||
|
|
|||
|
} //if ( !m_pSSLInfo )
|
|||
|
|
|||
|
//
|
|||
|
// At this point, m_pSSLInfo should not be NULL anymore, so add the external reference
|
|||
|
//
|
|||
|
m_pSSLInfo->Reference();
|
|||
|
|
|||
|
pPtr = m_pSSLInfo;
|
|||
|
|
|||
|
UnlockThis();
|
|||
|
|
|||
|
return pPtr;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
BOOL
|
|||
|
SetFlushMapperNotify(
|
|||
|
SF_NOTIFY_TYPE nt,
|
|||
|
PFN_SF_NOTIFY pFn
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Description
|
|||
|
|
|||
|
Set the function called to notify that a mapper is being flushed
|
|||
|
Can be called only once for a given mapper type
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
nt - notification type
|
|||
|
pFn - function to call to notify mapper flushed
|
|||
|
|
|||
|
Returns:
|
|||
|
|
|||
|
TRUE if function reference stored, FALSE otherwise
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
MAPPER_TYPE mt;
|
|||
|
|
|||
|
switch ( nt )
|
|||
|
{
|
|||
|
case SF_NOTIFY_MAPPER_MD5_CHANGED:
|
|||
|
mt = MT_MD5;
|
|||
|
break;
|
|||
|
|
|||
|
case SF_NOTIFY_MAPPER_ITA_CHANGED:
|
|||
|
mt = MT_ITA;
|
|||
|
break;
|
|||
|
|
|||
|
case SF_NOTIFY_MAPPER_CERT11_CHANGED:
|
|||
|
mt = MT_CERT11;
|
|||
|
break;
|
|||
|
|
|||
|
case SF_NOTIFY_MAPPER_CERTW_CHANGED:
|
|||
|
mt = MT_CERTW;
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
if ( g_pFlushMapperNotify[(UINT)mt] == NULL || pFn == NULL )
|
|||
|
{
|
|||
|
g_pFlushMapperNotify[(UINT)mt] = pFn;
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
VOID W3_SERVER_INSTANCE::ResetSSLInfo( LPVOID pvParam )
|
|||
|
/*++
|
|||
|
Description:
|
|||
|
|
|||
|
Wrapper function for function to call to notify of SSL changes
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
pvParam - pointer to instance for which SSL keys have changed
|
|||
|
|
|||
|
Returns:
|
|||
|
|
|||
|
Nothing
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
//
|
|||
|
// Call function to flush credential cache etc
|
|||
|
//
|
|||
|
if ( g_pSslKeysNotify )
|
|||
|
{
|
|||
|
g_pSslKeysNotify( SF_NOTIFY_MAPPER_SSLKEYS_CHANGED,
|
|||
|
pvParam );
|
|||
|
}
|
|||
|
|
|||
|
W3_SERVER_INSTANCE *pInst = (W3_SERVER_INSTANCE *) pvParam;
|
|||
|
|
|||
|
//
|
|||
|
// Clean up all the SSL information associated with this instance
|
|||
|
//
|
|||
|
pInst->LockThisForRead();
|
|||
|
|
|||
|
if ( pInst->m_pSSLInfo )
|
|||
|
{
|
|||
|
pInst->UnlockThis();
|
|||
|
|
|||
|
pInst->LockThisForWrite();
|
|||
|
|
|||
|
if ( pInst->m_pSSLInfo )
|
|||
|
{
|
|||
|
//
|
|||
|
// Stop watching for change notifications
|
|||
|
//
|
|||
|
IIS_SERVER_CERT *pCert = pInst->m_pSSLInfo->QueryCertificate();
|
|||
|
IIS_CTL *pCTL = pInst->m_pSSLInfo->QueryCTL();
|
|||
|
|
|||
|
if ( g_pStoreChangeNotifier )
|
|||
|
{
|
|||
|
//
|
|||
|
// Stop watching the store the cert came out of
|
|||
|
//
|
|||
|
if ( pCert && pCert->IsValid() )
|
|||
|
{
|
|||
|
g_pStoreChangeNotifier->UnregisterStore( pCert->QueryStoreName(),
|
|||
|
ResetSSLInfo,
|
|||
|
(PVOID) pvParam );
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Stop watching the store the CTL came out of
|
|||
|
//
|
|||
|
if ( pCTL && pCTL->IsValid() )
|
|||
|
{
|
|||
|
g_pStoreChangeNotifier->UnregisterStore( pCTL->QueryStoreName(),
|
|||
|
ResetSSLInfo,
|
|||
|
(PVOID) pvParam );
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Stop watching the ROOT store
|
|||
|
//
|
|||
|
g_pStoreChangeNotifier->UnregisterStore( "ROOT",
|
|||
|
ResetSSLInfo,
|
|||
|
(PVOID) pvParam );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
pInst->m_pSSLInfo->ReleaseFortezzaHandlers();
|
|||
|
|
|||
|
//
|
|||
|
// Release internal reference
|
|||
|
//
|
|||
|
IIS_SSL_INFO::Release( pInst->m_pSSLInfo );
|
|||
|
|
|||
|
//
|
|||
|
// Next call to GetAndReferenceSSLObj() will create it again
|
|||
|
//
|
|||
|
pInst->m_pSSLInfo = NULL;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
pInst->UnlockThis();
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
VOID W3_SERVER_INSTANCE::LogCertStatus()
|
|||
|
/*++
|
|||
|
Description:
|
|||
|
|
|||
|
Writes system log event about status of server certificate if the cert is in some
|
|||
|
way not quite kosher eg expired, revoked, not signature-valid
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None
|
|||
|
|
|||
|
Returns:
|
|||
|
|
|||
|
Nothing
|
|||
|
--*/
|
|||
|
{
|
|||
|
DBG_ASSERT( m_pSSLInfo );
|
|||
|
|
|||
|
DWORD dwCertValidity = 0;
|
|||
|
|
|||
|
//
|
|||
|
// If we didn't construct the cert fully, log an error
|
|||
|
//
|
|||
|
if ( !m_pSSLInfo->QueryCertificate()->IsValid() )
|
|||
|
{
|
|||
|
CONST CHAR *apszMsgs[2];
|
|||
|
CHAR achInstance[20];
|
|||
|
CHAR achErrorNumber[20];
|
|||
|
wsprintf( achInstance,
|
|||
|
"%lu",
|
|||
|
QueryInstanceId() );
|
|||
|
wsprintf( achErrorNumber,
|
|||
|
"0x%x",
|
|||
|
GetLastError() );
|
|||
|
|
|||
|
apszMsgs[0] = achInstance;
|
|||
|
apszMsgs[1] = achErrorNumber;
|
|||
|
|
|||
|
DWORD dwStatus = m_pSSLInfo->QueryCertificate()->Status();
|
|||
|
DWORD dwStringID = 0;
|
|||
|
|
|||
|
DBGPRINTF((DBG_CONTEXT,
|
|||
|
"Couldn't retrieve server cert; status : %d\n",
|
|||
|
dwStatus));
|
|||
|
|
|||
|
switch ( dwStatus )
|
|||
|
{
|
|||
|
case CERT_ERR_MB:
|
|||
|
dwStringID = SSL_MSG_CERT_MB_ERROR;
|
|||
|
break;
|
|||
|
|
|||
|
case CERT_ERR_CAPI:
|
|||
|
dwStringID = SSL_MSG_CERT_CAPI_ERROR;
|
|||
|
break;
|
|||
|
|
|||
|
case CERT_ERR_CERT_NOT_FOUND:
|
|||
|
dwStringID = SSL_MSG_CERT_NOT_FOUND;
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
dwStringID = SSL_MSG_CERT_INTERNAL_ERROR;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
g_pInetSvc->LogEvent( dwStringID,
|
|||
|
2,
|
|||
|
apszMsgs,
|
|||
|
0 );
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// If cert is invalid in some other way , write the appropriate log message
|
|||
|
//
|
|||
|
if ( m_pSSLInfo->QueryCertValidity( &dwCertValidity ) )
|
|||
|
{
|
|||
|
const CHAR *apszMsgs[1];
|
|||
|
CHAR achInstance[20];
|
|||
|
wsprintfA( achInstance,
|
|||
|
"%lu",
|
|||
|
QueryInstanceId() );
|
|||
|
apszMsgs[0] = achInstance;
|
|||
|
DWORD dwMsgID = 0;
|
|||
|
|
|||
|
if ( ( dwCertValidity & CERT_TRUST_IS_NOT_TIME_VALID ) ||
|
|||
|
( dwCertValidity & CERT_TRUST_IS_NOT_TIME_NESTED ) ||
|
|||
|
( dwCertValidity & CERT_TRUST_CTL_IS_NOT_TIME_VALID ) )
|
|||
|
{
|
|||
|
DBGPRINTF((DBG_CONTEXT,
|
|||
|
"Server cert/CTL is not time-valid or time-nested\n"));
|
|||
|
|
|||
|
dwMsgID = SSL_MSG_TIME_INVALID_SERVER_CERT;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
if ( dwCertValidity & CERT_TRUST_IS_REVOKED )
|
|||
|
{
|
|||
|
DBGPRINTF((DBG_CONTEXT,
|
|||
|
"Server Cert is revoked\n"));
|
|||
|
|
|||
|
dwMsgID = SSL_MSG_REVOKED_SERVER_CERT;
|
|||
|
}
|
|||
|
|
|||
|
if ( ( dwCertValidity & CERT_TRUST_IS_UNTRUSTED_ROOT ) ||
|
|||
|
( dwCertValidity & CERT_TRUST_IS_PARTIAL_CHAIN ) )
|
|||
|
{
|
|||
|
DBGPRINTF((DBG_CONTEXT,
|
|||
|
"Server Cert doesn't chain up to a trusted root\n"));
|
|||
|
|
|||
|
dwMsgID = SSL_MSG_UNTRUSTED_SERVER_CERT;
|
|||
|
}
|
|||
|
|
|||
|
if ( ( dwCertValidity & CERT_TRUST_IS_NOT_SIGNATURE_VALID ) ||
|
|||
|
( dwCertValidity & CERT_TRUST_CTL_IS_NOT_SIGNATURE_VALID ) )
|
|||
|
{
|
|||
|
DBGPRINTF((DBG_CONTEXT,
|
|||
|
"Server Cert/CTL is not signature valid\n"));
|
|||
|
|
|||
|
dwMsgID = SSL_MSG_SIGNATURE_INVALID_SERVER_CERT;
|
|||
|
}
|
|||
|
|
|||
|
if ( dwMsgID )
|
|||
|
{
|
|||
|
g_pInetSvc->LogEvent( dwMsgID,
|
|||
|
1,
|
|||
|
apszMsgs,
|
|||
|
0 ) ;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
VOID W3_SERVER_INSTANCE::LogCTLStatus()
|
|||
|
/*++
|
|||
|
Description:
|
|||
|
|
|||
|
Writes system log event about status of server CTL if CTL isn't valid
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None
|
|||
|
|
|||
|
Returns:
|
|||
|
|
|||
|
Nothing
|
|||
|
--*/
|
|||
|
{
|
|||
|
DBG_ASSERT( m_pSSLInfo );
|
|||
|
|
|||
|
//
|
|||
|
// If we didn't construct the CTL fully, log an error
|
|||
|
//
|
|||
|
if ( !m_pSSLInfo->QueryCTL()->IsValid() )
|
|||
|
{
|
|||
|
CONST CHAR *apszMsgs[2];
|
|||
|
CHAR achInstance[20];
|
|||
|
CHAR achErrorNumber[20];
|
|||
|
wsprintf( achInstance,
|
|||
|
"%lu",
|
|||
|
QueryInstanceId() );
|
|||
|
wsprintf( achErrorNumber,
|
|||
|
"0x%x",
|
|||
|
GetLastError() );
|
|||
|
|
|||
|
apszMsgs[0] = achInstance;
|
|||
|
apszMsgs[1] = achErrorNumber;
|
|||
|
|
|||
|
DWORD dwStatus = m_pSSLInfo->QueryCTL()->QueryStatus();
|
|||
|
DWORD dwStringID = 0;
|
|||
|
|
|||
|
DBGPRINTF((DBG_CONTEXT,
|
|||
|
"Couldn't retrieve server CTL; status : %d\n",
|
|||
|
dwStatus));
|
|||
|
|
|||
|
switch ( dwStatus )
|
|||
|
{
|
|||
|
case CERT_ERR_MB:
|
|||
|
dwStringID = SSL_MSG_CTL_MB_ERROR;
|
|||
|
break;
|
|||
|
|
|||
|
case CERT_ERR_CAPI:
|
|||
|
dwStringID = SSL_MSG_CTL_CAPI_ERROR;
|
|||
|
break;
|
|||
|
|
|||
|
case CERT_ERR_CERT_NOT_FOUND:
|
|||
|
dwStringID = SSL_MSG_CTL_NOT_FOUND;
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
dwStringID = SSL_MSG_CTL_INTERNAL_ERROR;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
g_pInetSvc->LogEvent( dwStringID,
|
|||
|
2,
|
|||
|
apszMsgs,
|
|||
|
0 );
|
|||
|
return;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
BOOL
|
|||
|
SetSllKeysNotify(
|
|||
|
PFN_SF_NOTIFY pFn
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Description
|
|||
|
|
|||
|
Set the function called to notify SSL keys have changed
|
|||
|
Can be called only once
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
pFn - function to call to notify SSL keys change
|
|||
|
|
|||
|
Returns:
|
|||
|
|
|||
|
TRUE if function reference stored, FALSE otherwise
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
if ( g_pSslKeysNotify == NULL || pFn == NULL )
|
|||
|
{
|
|||
|
g_pSslKeysNotify = pFn;
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|