windows-nt/Source/XPSP1/NT/ds/security/gina/userenv/rsop/maindll.cpp
2020-09-26 16:20:57 +08:00

436 lines
12 KiB
C++

//*************************************************************
//
// Microsoft Confidential. Copyright (c) Microsoft Corporation 1999.
//
// File: MainDll.cpp
//
// Description: Dll registry, get class object functions
//
// History: 8-20-99 leonardm Created
// 1-15-00 NishadM
//
//*************************************************************
#include "uenv.h"
#include "Factory.h"
#include "rsopdbg.h"
#include "initguid.h"
#include <wbemcli.h>
#define SECURITY_WIN32
#include <security.h>
#include <aclapi.h>
#include "smartptr.h"
#include "rsopinc.h"
#include "rsopsec.h"
HRESULT GetRsopSchemaVersionNumber(IWbemServices *pWbemServices, DWORD *dwVersionNumber);
// {B3FF88A4-96EC-4cc1-983F-72BE0EBB368B}
DEFINE_GUID(CLSID_CSnapProv, 0xb3ff88a4, 0x96ec, 0x4cc1, 0x98, 0x3f, 0x72, 0xbe, 0xe, 0xbb, 0x36, 0x8b);
// Count of objects and locks.
long g_cObj = 0;
long g_cLock = 0;
CDebug dbgRsop;
extern "C"
{
STDMETHODIMP RSoPMakeAbsoluteSD(SECURITY_DESCRIPTOR* pSelfRelativeSD, SECURITY_DESCRIPTOR** ppAbsoluteSD);
STDMETHODIMP GetNamespaceSD(IWbemServices* pWbemServices, SECURITY_DESCRIPTOR** ppSD);
STDMETHODIMP SetNamespaceSD(SECURITY_DESCRIPTOR* pSD, IWbemServices* pWbemServices);
STDMETHODIMP FreeAbsoluteSD(SECURITY_DESCRIPTOR* pAbsoluteSD);
STDMETHODIMP GetWbemServicesPtr( LPCWSTR, IWbemLocator**, IWbemServices** );
};
/*
LPWSTR GetDomainName();
DWORD MakeUserName( LPWSTR szDomain, LPWSTR szUser, LPWSTR* pszUserName );
STDMETHODIMP SetNameSpaceSecurity( IWbemServices*, PSECURITY_DESCRIPTOR, LPWSTR* pszPrincipals, DWORD nPrincipals );
*/
void
InitializeSnapProv( void )
{
dbgRsop.Initialize( L"Software\\Microsoft\\Windows NT\\CurrentVersion\\winlogon",
L"RsopDebugLevel",
L"userenv.log",
L"userenv.bak",
FALSE );
}
extern "C"
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
{
if (rclsid != CLSID_CSnapProv)
{
return CLASS_E_CLASSNOTAVAILABLE;
}
CProvFactory* pFactory = new CProvFactory();
if (pFactory == NULL)
{
return E_OUTOFMEMORY;
}
HRESULT hRes = pFactory->QueryInterface(riid, ppv);
pFactory->Release();
return hRes;
}
extern "C"
STDAPI DllCanUnloadNow()
{
// It is OK to unload if there are no objects or locks on the class factory.
if( g_cObj == 0L && g_cLock == 0L )
{
return S_OK;
}
else
{
return S_FALSE;
}
}
extern "C"
STDAPI DllRegisterServer(void)
{
wchar_t szID[128];
wchar_t szCLSID[128];
wchar_t szModule[MAX_PATH];
wchar_t* pName = L"Rsop Logging Mode Provider";
wchar_t* pModel = L"Both";
HKEY hKey1, hKey2;
// Create the path.
GuidToString( &CLSID_CSnapProv, szID );
wcscpy(szCLSID, TEXT("CLSID\\"));
lstrcat(szCLSID, szID);
// Create entries under CLSID
RegCreateKey(HKEY_CLASSES_ROOT, szCLSID, &hKey1);
RegSetValueEx(hKey1, NULL, 0, REG_SZ, (BYTE*)pName, (wcslen(pName) + 1) * sizeof(wchar_t));
RegCreateKey(hKey1, L"InprocServer32", &hKey2);
GetModuleFileName(g_hDllInstance, szModule, MAX_PATH);
RegSetValueEx(hKey2, NULL, 0, REG_SZ, (BYTE*)szModule, (wcslen(szModule) + 1) * sizeof(wchar_t));
RegSetValueEx(hKey2, L"ThreadingModel", 0, REG_SZ, (BYTE*)pModel, (wcslen(pModel) + 1) * sizeof(wchar_t));
CloseHandle(hKey1);
CloseHandle(hKey2);
return S_OK;
}
extern "C"
STDAPI DllUnregisterServer(void)
{
wchar_t szID[128];
wchar_t szCLSID[128];
HKEY hKey;
// Create the path using the CLSID
GuidToString( &CLSID_CSnapProv, szID );
wcscpy(szCLSID, TEXT("CLSID\\"));
wcscat(szCLSID, szID);
// First delete the InProcServer subkey.
DWORD dwRet = RegOpenKey(HKEY_CLASSES_ROOT, szCLSID, &hKey);
if(dwRet == ERROR_SUCCESS)
{
RegDeleteKey(hKey, L"InProcServer32");
CloseHandle(hKey);
}
dwRet = RegOpenKey(HKEY_CLASSES_ROOT, L"CLSID", &hKey);
if(dwRet == ERROR_SUCCESS)
{
RegDeleteKey(hKey,szID);
CloseHandle(hKey);
}
return S_OK;
}
BOOL RunningOnWow64()
{
#if defined(_WIN64)
// 64bit builds don't run in Wow64
return false;
#else
// OS version
OSVERSIONINFO osviVersion;
osviVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if (!GetVersionEx(&osviVersion)) {
DebugMsg((DM_WARNING, TEXT("RunningOnWow64: Couldn't detect Version with error %d"), GetLastError()));
return FALSE;
}
// on NT5 or later 32bit build. Check for 64 bit OS
if ((osviVersion.dwPlatformId == VER_PLATFORM_WIN32_NT) &&
(osviVersion.dwMajorVersion >= 5))
{
// QueryInformation for ProcessWow64Information returns a pointer to the Wow Info.
// if running native, it returns NULL.
PVOID pWow64Info = 0;
if (NT_SUCCESS(NtQueryInformationProcess(GetCurrentProcess(), ProcessWow64Information, &pWow64Info, sizeof(pWow64Info), NULL))
&& pWow64Info != NULL)
{
// running 32bit on Wow64.
return TRUE;
}
}
return FALSE;
#endif
}
HRESULT
CompileMOF( LPCWSTR szMOFFile, LPCWSTR szMFLFile )
{
WCHAR szNamespace[MAX_PATH];
BOOL bUpgrade = FALSE;
HRESULT hr;
XInterface<IWbemLocator> xWbemLocator;
XInterface<IWbemServices> xWbemServicesOld;
DWORD dwCurrentVersion= 0;
DWORD dwNewVersion = RSOP_MOF_SCHEMA_VERSION;
//
// On wow64 do nothing
//
if (RunningOnWow64()) {
DebugMsg((DM_VERBOSE, TEXT("CompileMof: Running on Wow64. returning without doing anything")));
return S_OK;
}
if ( !szMOFFile )
{
return E_POINTER;
}
wcscpy(szNamespace, RSOP_NS_ROOT);
//
// Get the wbem services pointer to the machine namespace
//
hr = GetWbemServicesPtr(RSOP_NS_MACHINE,
&xWbemLocator,
&xWbemServicesOld );
if (!xWbemLocator) {
DebugMsg((DM_WARNING, TEXT("CompileMof: Failed to get IWbemLocator pointer.Error 0x%x"), hr));
return hr;
}
if ( (SUCCEEDED(hr)) && (xWbemServicesOld)) {
hr = GetRsopSchemaVersionNumber(xWbemServicesOld, &dwCurrentVersion);
if (FAILED(hr)) {
return hr;
}
}
if (HIWORD(dwCurrentVersion) != HIWORD(dwNewVersion)) {
//
// We should cleanout the schema and recreate below
//
DebugMsg((DM_VERBOSE, TEXT("CompileMof: Major version schema upgrade detected. Deleting rsop namespace and rebuilding")));
xWbemServicesOld = NULL;
hr = DeleteRsopNameSpace(szNamespace, xWbemLocator);
if (FAILED(hr)) {
DebugMsg((DM_WARNING, TEXT("CompileMof: Failed to get delete the rsop namespace. Error 0x%x. Continuing.."), hr));
}
//
// Delete the state info on the machine
//
if (!RegDelnode(HKEY_LOCAL_MACHINE, GP_STATE_ROOT_KEY)) {
DebugMsg((DM_WARNING, TEXT("CompileMof: Failed to delete the state key. Error 0x%x. Continuing.."), hr));
}
bUpgrade = FALSE;
}
else {
bUpgrade = TRUE;
}
XInterface<IMofCompiler> xpMofCompiler;
//
// get a handle to IMofCompiler
//
hr = CoCreateInstance( CLSID_MofCompiler,
0,
CLSCTX_INPROC_SERVER,
IID_IMofCompiler,
(LPVOID*) &xpMofCompiler );
if ( FAILED(hr) )
{
DebugMsg((DM_WARNING, L"CompileMOF: CoCreateInstance() failed, 0x%X.", hr));
return hr;
}
WBEM_COMPILE_STATUS_INFO Info;
hr = xpMofCompiler->CompileFile((LPWSTR)szMOFFile,
0, // no server & namespace
0, // no user
0, // no authority
0, // no password
0, // no options
0, // no class flags
0, // no instance flags
&Info );
if ( FAILED( hr ) )
{
DebugMsg((DM_WARNING, L"CompileMOF: IMofCompiler::CompileFile() failed, 0x%X.", hr));
}
else
{
if (hr != S_OK )
{
DebugMsg((DM_WARNING, L"CompileMOF: IMofCompiler::CompileFile() returned with 0x%X.", hr));
DebugMsg((DM_WARNING, L"CompileMOF: Details - lPhaseError - %d, hRes = 0x%x, ObjectNum - %d, firstline - %d, LastLine - %d",
Info.lPhaseError, Info.hRes, Info.ObjectNum, Info.FirstLine, Info.LastLine ));
}
else
{
hr = xpMofCompiler->CompileFile((LPWSTR)szMFLFile,
0, // no server & namespace
0, // no user
0, // no authority
0, // no password
0, // no options
0, // no class flags
0, // no instance flags
&Info );
if ( FAILED( hr ) )
{
DebugMsg((DM_WARNING, L"CompileMOF: IMofCompiler::CompileFile() failed, 0x%X.", hr));
}
else
{
if (hr != S_OK )
{
DebugMsg((DM_WARNING, L"CompileMOF: IMofCompiler::CompileFile() returned with 0x%X.", hr));
DebugMsg((DM_WARNING, L"CompileMOF: Details - lPhaseError - %d, hRes = 0x%x, ObjectNum - %d, firstline - %d, LastLine - %d",
Info.lPhaseError, Info.hRes, Info.ObjectNum, Info.FirstLine, Info.LastLine ));
}
}
}
}
//
// if xWbemServicesOld exists, this is an upgrade.
// retain old security.
//
if ( !bUpgrade )
{
XPtrLF<SECURITY_DESCRIPTOR> xsd;
SECURITY_ATTRIBUTES sa;
CSecDesc Csd;
Csd.AddLocalSystem(RSOP_ALL_PERMS, CONTAINER_INHERIT_ACE);
Csd.AddAdministrators(RSOP_ALL_PERMS, CONTAINER_INHERIT_ACE);
Csd.AddAdministratorsAsOwner();
Csd.AddAdministratorsAsGroup();
Csd.AddAuthUsers(RSOP_READ_PERMS); // no inheritance
xsd = Csd.MakeSelfRelativeSD();
if (!xsd) {
dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("CompileMOF::MakeSelfSD failed with %d"), GetLastError());
return HRESULT_FROM_WIN32(GetLastError());
}
if (!SetSecurityDescriptorControl( (SECURITY_DESCRIPTOR *)xsd, SE_DACL_PROTECTED, SE_DACL_PROTECTED )) {
dbg.Msg( DEBUG_MESSAGE_WARNING, TEXT("CompileMOF::SetSecurityDescriptorControl failed with %d"), GetLastError());
return HRESULT_FROM_WIN32(GetLastError());
}
hr = SetNameSpaceSecurity(szNamespace, xsd, xWbemLocator);
if (FAILED(hr)) {
DebugMsg((DM_WARNING, L"CompileMOF: SetNamespaceSecurity() failed, 0x%X.", hr));
return hr;
}
hr = SetNameSpaceSecurity(RSOP_NS_USER, xsd, xWbemLocator);
if (FAILED(hr)) {
DebugMsg((DM_WARNING, L"CompileMOF: SetNamespaceSecurity() failed, 0x%X.", hr));
return hr;
}
hr = SetNameSpaceSecurity(RSOP_NS_MACHINE, xsd, xWbemLocator);
if (FAILED(hr)) {
DebugMsg((DM_WARNING, L"CompileMOF: SetNamespaceSecurity() failed, 0x%X.", hr));
return hr;
}
}
return hr;
}
//
// currently this code is intended to be called by regsvr32.
// setup does not call this code.
// "regsvr32 /n /i userenv.dll"
// waiting for WMI gives us a mechanism to install our MOF at setup time.
//
extern "C"
STDAPI DllInstall( BOOL, LPCWSTR )
{
HRESULT hr = S_OK;
WCHAR szMofFile[MAX_PATH];
WCHAR szMflFile[MAX_PATH];
if ( GetSystemDirectory( szMofFile, MAX_PATH ) )
{
wcscpy( szMflFile, szMofFile );
LPWSTR szMOF = CheckSlash(szMofFile);
LPWSTR szMFL = CheckSlash(szMflFile);
wcscat( szMOF, L"Wbem\\RSoP.mof" );
wcscat( szMFL, L"Wbem\\RSoP.mfl" );
hr = CompileMOF( szMofFile, szMflFile );
}
else
{
hr = GetLastError();
}
return hr;
}