|
|
// 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); }
|