436 lines
13 KiB
C++
436 lines
13 KiB
C++
// logui.cpp : Implementation of CLoguiApp and DLL registration.
|
|
|
|
#include "stdafx.h"
|
|
#include "logui.h"
|
|
|
|
#include "wrapmb.h"
|
|
#include <iiscnfg.h>
|
|
#include <iiscnfgp.h>
|
|
#include <inetinfo.h>
|
|
|
|
#include "initguid.h"
|
|
#include <logtype.h>
|
|
#include <ilogobj.hxx>
|
|
|
|
#include "uincsa.h"
|
|
#include "uiextnd.h"
|
|
#include "uimsft.h"
|
|
#include "uiodbc.h"
|
|
|
|
#include "dcomperm.h"
|
|
|
|
//_tlid
|
|
|
|
|
|
// the global factory objects
|
|
CFacNcsaLogUI facNcsa;
|
|
CFacMsftLogUI facMsft;
|
|
CFacOdbcLogUI facOdbc;
|
|
CFacExtndLogUI facExtnd;
|
|
|
|
|
|
const GUID CDECL BASED_CODE _tlid =
|
|
{ 0x31dcab8a, 0xbb3e, 0x11d0, { 0x92, 0x99, 0x0, 0xc0, 0x4f, 0xb6, 0x67, 0x8b } };
|
|
const WORD _wVerMajor = 1;
|
|
const WORD _wVerMinor = 0;
|
|
|
|
// the key type strings for the metabaes keys
|
|
#define SZ_LOGGING_MAIN_TYPE _T("IIsLogModules")
|
|
#define SZ_LOGGING_TYPE _T("IIsLogModule")
|
|
|
|
BOOL _cdecl RegisterInMetabase( PWCHAR pszMachine );
|
|
|
|
int SetInfoAdminACL( CWrapMetaBase* pMB, LPCTSTR szSubKeyPath );
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
|
|
CLoguiApp NEAR theApp;
|
|
|
|
HINSTANCE g_hInstance = NULL;
|
|
|
|
|
|
|
|
//---------------------------------------------------------------
|
|
void CLoguiApp::PrepHelp( OLECHAR* pocMetabasePath )
|
|
{
|
|
// figure out the correct help file to use
|
|
CString szMetaPath = pocMetabasePath;
|
|
szMetaPath.MakeLower();
|
|
|
|
// default to the w3 help
|
|
UINT iHelp = IDS_HELPLOC_W3SVCHELP;
|
|
|
|
// test for ftp
|
|
if ( szMetaPath.Find(_T("msftpsvc")) >= 0 )
|
|
iHelp = IDS_HELPLOC_FTPHELP;
|
|
|
|
// finally, we need to redirect the winhelp file location to something more desirable
|
|
CString sz;
|
|
CString szHelpLocation;
|
|
sz.LoadString( iHelp );
|
|
|
|
// expand the path
|
|
ExpandEnvironmentStrings(
|
|
sz, // pointer to string with environment variables
|
|
szHelpLocation.GetBuffer(MAX_PATH + 1), // pointer to string with expanded environment variables
|
|
MAX_PATH // maximum characters in expanded string
|
|
);
|
|
szHelpLocation.ReleaseBuffer();
|
|
|
|
// free the existing path, and copy in the new one
|
|
if ( m_pszHelpFilePath )
|
|
free((void*)m_pszHelpFilePath);
|
|
m_pszHelpFilePath = _tcsdup(szHelpLocation);
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// CLoguiApp::InitInstance - DLL initialization
|
|
|
|
BOOL CLoguiApp::InitInstance()
|
|
{
|
|
g_hInstance = m_hInstance;
|
|
BOOL bInit = COleControlModule::InitInstance();
|
|
|
|
if (bInit)
|
|
{
|
|
CString sz;
|
|
// set the name of the application correctly
|
|
sz.LoadString( IDS_LOGUI_ERR_TITLE );
|
|
// Never free this string because now MF...kingC
|
|
// uses it internally BEFORE call to this function
|
|
//free((void*)m_pszAppName);
|
|
m_pszAppName = _tcsdup(sz);
|
|
}
|
|
|
|
return bInit;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// CLoguiApp::ExitInstance - DLL termination
|
|
|
|
int CLoguiApp::ExitInstance()
|
|
{
|
|
return COleControlModule::ExitInstance();
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// DllRegisterServer - Adds entries to the system registry
|
|
|
|
STDAPI DllRegisterServer(void)
|
|
{
|
|
AFX_MANAGE_STATE(_afxModuleAddrThis);
|
|
|
|
if (!COleObjectFactoryEx::UpdateRegistryAll(TRUE))
|
|
return ResultFromScode(SELFREG_E_CLASS);
|
|
|
|
// intialize the metabase /logging tree
|
|
if ( !RegisterInMetabase( NULL ) )
|
|
return GetLastError();
|
|
|
|
return NOERROR;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// DllUnregisterServer - Removes entries from the system registry
|
|
|
|
STDAPI DllUnregisterServer(void)
|
|
{
|
|
AFX_MANAGE_STATE(_afxModuleAddrThis);
|
|
|
|
// if (!AfxOleUnregisterTypeLib(_tlid, _wVerMajor, _wVerMinor))
|
|
// return ResultFromScode(SELFREG_E_TYPELIB);
|
|
|
|
if (!COleObjectFactoryEx::UpdateRegistryAll(FALSE))
|
|
return ResultFromScode(SELFREG_E_CLASS);
|
|
|
|
return NOERROR;
|
|
}
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
// add all the base logging info to the /LM portion of the tree Also, add in
|
|
// the ftp and w3 service logging load strings
|
|
BOOL _cdecl RegisterInMetabase( PWCHAR pszMachine )
|
|
{
|
|
CString sz;
|
|
BOOL f;
|
|
DWORD dw;
|
|
BOOL fODBCW3 = FALSE;
|
|
BOOL fODBCFTP = FALSE;
|
|
DWORD fAnswer = FALSE;
|
|
CString szAvail;
|
|
CWrapMetaBase mbWrap;
|
|
|
|
// specify the resources to use
|
|
HINSTANCE hOldRes = AfxGetResourceHandle();
|
|
AfxSetResourceHandle( g_hInstance );
|
|
|
|
// prep the metabase - during install we always target the local machine
|
|
IMSAdminBase* pMB = FInitMetabaseWrapper( pszMachine );
|
|
if ( !pMB )
|
|
{
|
|
goto CLEANUP_RES;
|
|
}
|
|
if ( !mbWrap.FInit(pMB) )
|
|
{
|
|
goto CLEANUP_RES;
|
|
}
|
|
|
|
// first, we will add the basic tree to the metabase
|
|
// start with the bottom item
|
|
// open the target
|
|
if ( !mbWrap.Open( _T("/lm"), METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE ) )
|
|
{
|
|
goto CLEANUP_RES;
|
|
}
|
|
|
|
// test to see if we can do odbc logging
|
|
if ( mbWrap.GetDword( _T("/w3svc/Info"), MD_SERVER_CAPABILITIES, IIS_MD_UT_SERVER, &dw ) )
|
|
fODBCW3 = (dw & IIS_CAP1_ODBC_LOGGING) > 0;
|
|
if ( mbWrap.GetDword( _T("/MSFTPSVC/Info"), MD_SERVER_CAPABILITIES, IIS_MD_UT_SERVER, &dw ) )
|
|
fODBCFTP = (dw & IIS_CAP1_ODBC_LOGGING) > 0;
|
|
|
|
// we shouldn't tie up the /lm object, so close it and open logging
|
|
mbWrap.Close();
|
|
|
|
// open the logging object
|
|
if ( !mbWrap.Open( _T("/lm/logging"), METADATA_PERMISSION_WRITE ) )
|
|
{
|
|
// the logging node doesn't exist. Create it
|
|
if ( !mbWrap.Open( _T("/lm"), METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE ) )
|
|
goto CLEANUP_RES;
|
|
|
|
// add the logging object
|
|
if ( mbWrap.AddObject(_T("logging")) )
|
|
{
|
|
// add the ACL to the node
|
|
SetInfoAdminACL( &mbWrap, _T("logging") );
|
|
}
|
|
|
|
// we shouldn't tie up the /lm object, so close it and open logging
|
|
mbWrap.Close();
|
|
|
|
// open the logging object
|
|
if ( !mbWrap.Open( _T("/lm/logging"), METADATA_PERMISSION_WRITE ) )
|
|
goto CLEANUP_RES;
|
|
}
|
|
|
|
// set the logging key type
|
|
mbWrap.SetString( _T(""), MD_KEY_TYPE, IIS_MD_UT_SERVER, SZ_LOGGING_MAIN_TYPE, 0 );
|
|
|
|
// add ncsa first
|
|
sz.LoadString( IDS_MTITLE_NCSA );
|
|
if ( mbWrap.AddObject( sz ) )
|
|
{
|
|
// set the key type
|
|
mbWrap.SetString( sz, MD_KEY_TYPE, IIS_MD_UT_SERVER, SZ_LOGGING_TYPE, 0 );
|
|
// add the logging module's guid string
|
|
f = mbWrap.SetString( sz, MD_LOG_PLUGIN_MOD_ID, IIS_MD_UT_SERVER, NCSALOG_CLSID );
|
|
// add the logging ui's guid string
|
|
f = mbWrap.SetString( sz, MD_LOG_PLUGIN_UI_ID, IIS_MD_UT_SERVER, NCSALOGUI_CLSID );
|
|
}
|
|
|
|
// add odbc logging
|
|
sz.LoadString( IDS_MTITLE_ODBC );
|
|
if ( (fODBCW3 || fODBCFTP) && mbWrap.AddObject( sz ) )
|
|
{
|
|
// set the key type
|
|
mbWrap.SetString( sz, MD_KEY_TYPE, IIS_MD_UT_SERVER, SZ_LOGGING_TYPE, 0 );
|
|
// add the logging module's guid string
|
|
f = mbWrap.SetString( sz, MD_LOG_PLUGIN_MOD_ID, IIS_MD_UT_SERVER, ODBCLOG_CLSID );
|
|
// add the logging ui's guid string
|
|
f = mbWrap.SetString( sz, MD_LOG_PLUGIN_UI_ID, IIS_MD_UT_SERVER, ODBCLOGUI_CLSID );
|
|
}
|
|
|
|
// add microsoft logging
|
|
sz.LoadString( IDS_MTITLE_MSFT );
|
|
if ( mbWrap.AddObject( sz ) )
|
|
{
|
|
// set the key type
|
|
mbWrap.SetString( sz, MD_KEY_TYPE, IIS_MD_UT_SERVER, SZ_LOGGING_TYPE, 0 );
|
|
// add the logging module's guid string
|
|
f = mbWrap.SetString( sz, MD_LOG_PLUGIN_MOD_ID, IIS_MD_UT_SERVER, ASCLOG_CLSID );
|
|
// add the logging ui's guid string
|
|
f = mbWrap.SetString( sz, MD_LOG_PLUGIN_UI_ID, IIS_MD_UT_SERVER, ASCLOGUI_CLSID );
|
|
}
|
|
|
|
// add extended logging
|
|
sz.LoadString( IDS_MTITLE_XTND );
|
|
if ( mbWrap.AddObject( sz ) )
|
|
{
|
|
// set the key type
|
|
mbWrap.SetString( sz, MD_KEY_TYPE, IIS_MD_UT_SERVER, SZ_LOGGING_TYPE, 0 );
|
|
// add the logging module's guid string
|
|
f = mbWrap.SetString( sz, MD_LOG_PLUGIN_MOD_ID, IIS_MD_UT_SERVER, EXTLOG_CLSID );
|
|
// add the logging ui's guid string
|
|
f = mbWrap.SetString( sz, MD_LOG_PLUGIN_UI_ID, IIS_MD_UT_SERVER, EXTLOGUI_CLSID );
|
|
}
|
|
|
|
// close the wrapper
|
|
mbWrap.Close();
|
|
|
|
// prepare the available logging extensions string
|
|
// start with w3svc
|
|
sz.LoadString( IDS_MTITLE_NCSA );
|
|
szAvail = sz;
|
|
sz.LoadString( IDS_MTITLE_MSFT );
|
|
szAvail += _T(',') + sz;
|
|
sz.LoadString( IDS_MTITLE_XTND );
|
|
szAvail += _T(',') + sz;
|
|
if ( fODBCW3 )
|
|
{
|
|
sz.LoadString( IDS_MTITLE_ODBC );
|
|
szAvail += _T(',') + sz;
|
|
}
|
|
// save the string
|
|
if ( mbWrap.Open( _T("/lm/w3svc/Info"), METADATA_PERMISSION_WRITE ) )
|
|
{
|
|
f = mbWrap.SetString( _T(""), MD_LOG_PLUGINS_AVAILABLE, IIS_MD_UT_SERVER, szAvail );
|
|
// close the wrapper
|
|
mbWrap.Close();
|
|
}
|
|
|
|
// now ftp - no ncsa
|
|
sz.LoadString( IDS_MTITLE_MSFT );
|
|
szAvail = sz;
|
|
sz.LoadString( IDS_MTITLE_XTND );
|
|
szAvail += _T(',') + sz;
|
|
if ( fODBCFTP )
|
|
{
|
|
sz.LoadString( IDS_MTITLE_ODBC );
|
|
szAvail += _T(',') + sz;
|
|
}
|
|
// save the string
|
|
if ( mbWrap.Open( _T("/lm/msftpsvc/Info"), METADATA_PERMISSION_WRITE ) )
|
|
{
|
|
f = mbWrap.SetString( _T(""), MD_LOG_PLUGINS_AVAILABLE, IIS_MD_UT_SERVER, szAvail );
|
|
// close the wrapper
|
|
mbWrap.Close();
|
|
}
|
|
|
|
// close the metabase wrappings
|
|
FCloseMetabaseWrapper(pMB);
|
|
fAnswer = TRUE;
|
|
|
|
CLEANUP_RES:
|
|
|
|
// we want to be able to recover a meaningful error, so get it and set it again after
|
|
// restoring the resource handle
|
|
DWORD err = GetLastError();
|
|
|
|
// restore the resources
|
|
if ( hOldRes )
|
|
AfxSetResourceHandle( hOldRes );
|
|
|
|
// reset the error code
|
|
SetLastError( err );
|
|
|
|
// return the error - hopefully success
|
|
return fAnswer;
|
|
}
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
int SetInfoAdminACL( CWrapMetaBase* pMB, LPCTSTR szSubKeyPath )
|
|
{
|
|
int retCode=-1;
|
|
BOOL b = FALSE;
|
|
DWORD dwLength = 0;
|
|
|
|
PSECURITY_DESCRIPTOR pSD = NULL;
|
|
PSECURITY_DESCRIPTOR outpSD = NULL;
|
|
DWORD cboutpSD = 0;
|
|
PACL pACLNew = NULL;
|
|
DWORD cbACL = 0;
|
|
PSID pAdminsSID = NULL, pEveryoneSID = NULL;
|
|
BOOL bWellKnownSID = FALSE;
|
|
|
|
// Initialize a new security descriptor
|
|
pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
|
|
if (NULL == pSD)
|
|
goto Cleanup;
|
|
InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
|
|
|
|
// Get Local Admins Sid
|
|
GetPrincipalSID (_T("Administrators"), &pAdminsSID, &bWellKnownSID);
|
|
|
|
// Get everyone Sid
|
|
GetPrincipalSID (_T("Everyone"), &pEveryoneSID, &bWellKnownSID);
|
|
|
|
// Initialize a new ACL, which only contains 2 aaace
|
|
cbACL = sizeof(ACL) +
|
|
(sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(pAdminsSID) - sizeof(DWORD)) +
|
|
(sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(pEveryoneSID) - sizeof(DWORD)) ;
|
|
pACLNew = (PACL) LocalAlloc(LPTR, cbACL);
|
|
if (NULL == pACLNew)
|
|
goto Cleanup;
|
|
InitializeAcl(pACLNew, cbACL, ACL_REVISION);
|
|
|
|
AddAccessAllowedAce(
|
|
pACLNew,
|
|
ACL_REVISION,
|
|
(MD_ACR_READ |
|
|
MD_ACR_WRITE |
|
|
MD_ACR_RESTRICTED_WRITE |
|
|
MD_ACR_UNSECURE_PROPS_READ |
|
|
MD_ACR_ENUM_KEYS |
|
|
MD_ACR_WRITE_DAC),
|
|
pAdminsSID);
|
|
|
|
AddAccessAllowedAce(
|
|
pACLNew,
|
|
ACL_REVISION,
|
|
(MD_ACR_READ | MD_ACR_ENUM_KEYS),
|
|
pEveryoneSID);
|
|
|
|
// Add the ACL to the security descriptor
|
|
b = SetSecurityDescriptorDacl(pSD, TRUE, pACLNew, FALSE);
|
|
b = SetSecurityDescriptorOwner(pSD, pAdminsSID, TRUE);
|
|
b = SetSecurityDescriptorGroup(pSD, pAdminsSID, TRUE);
|
|
|
|
// Security descriptor blob must be self relative
|
|
if (!MakeSelfRelativeSD(pSD, outpSD, &cboutpSD))
|
|
goto Cleanup;
|
|
outpSD = (PSECURITY_DESCRIPTOR)GlobalAlloc(GPTR, cboutpSD);
|
|
if (NULL == outpSD)
|
|
goto Cleanup;
|
|
if (!MakeSelfRelativeSD( pSD, outpSD, &cboutpSD ))
|
|
goto Cleanup;
|
|
|
|
// below this modify pSD to outpSD
|
|
|
|
// Apply the new security descriptor to the file
|
|
dwLength = GetSecurityDescriptorLength(outpSD);
|
|
|
|
|
|
// set the acl into the metabase at the given location
|
|
b = pMB->SetData( szSubKeyPath, MD_ADMIN_ACL, IIS_MD_UT_SERVER, BINARY_METADATA,
|
|
(LPBYTE)outpSD, dwLength,
|
|
METADATA_INHERIT | METADATA_REFERENCE | METADATA_SECURE );
|
|
|
|
retCode = 0;
|
|
|
|
Cleanup:
|
|
// both of Administrators and Everyone are well-known SIDs, use FreeSid() to free them.
|
|
if (outpSD)
|
|
GlobalFree(outpSD);
|
|
if (pAdminsSID)
|
|
FreeSid(pAdminsSID);
|
|
if (pEveryoneSID)
|
|
FreeSid(pEveryoneSID);
|
|
if (pSD)
|
|
LocalFree((HLOCAL) pSD);
|
|
if (pACLNew)
|
|
LocalFree((HLOCAL) pACLNew);
|
|
|
|
return (retCode);
|
|
}
|