windows-nt/Source/XPSP1/NT/admin/wmi/wbem/policman/provider/policman.cpp
2020-09-26 16:20:57 +08:00

378 lines
9.1 KiB
C++

#include <windows.h>
#include <wbemcli.h>
#include <wbemprov.h>
#include <stdio.h>
#include <commain.h>
#include <clsfac.h>
#include <wbemcomn.h>
#include <ql.h>
#include <sync.h>
#include <Dsrole.h>
#include "utility.h"
#include "PolicMan.h"
#include "PolicTempl.h"
#include "PolicSOM.h"
#include "PolicType.h"
#include "PolicRange.h"
#include "PolicGPO.h"
#include "PolicStatus.h"
#include <tchar.h>
#define REG_RUN_KEY L"Software\\Microsoft\\Windows\\CurrentVersion\\Run"
class CMyServer : public CComServer
{
public:
CMyServer(void) { InitGlobalNames(); }
~CMyServer(void) { FreeGlobalNames(); }
HRESULT Initialize()
{
AddClassInfo(CLSID_PolicySOM,
new CClassFactory<CPolicySOM>(GetLifeControl()),
_T("WMI Policy SOM Provider"), TRUE);
AddClassInfo(CLSID_PolicyStatus,
new CClassFactory<CPolicyStatus>(GetLifeControl()),
_T("WMI Policy Status Provider"), TRUE);
return S_OK;
}
HRESULT InitializeCom()
{
return CoInitializeEx(NULL, COINIT_MULTITHREADED);
}
/*
void Register(void)
{
wchar_t
swKeyValue[] = L"RUNDLL32.EXE %systemroot%\\system32\\wbem\\policman.dll,CreateADContainers",
swExpandedValue[512],
swRunOnceKey[] = REG_RUN_KEY ;
HKEY
hkRunOnce;
LONG
lReturnCode;
lReturnCode = ExpandEnvironmentStrings(swKeyValue, swExpandedValue, 512);
lReturnCode = RegOpenKeyEx(HKEY_LOCAL_MACHINE, swRunOnceKey, 0, KEY_SET_VALUE, &hkRunOnce);
if(ERROR_SUCCESS != lReturnCode)
{
// error
}
lReturnCode = RegSetValueEx(hkRunOnce, L"PolicMan", 0, REG_EXPAND_SZ, (BYTE *)swExpandedValue,
(lstrlen(swExpandedValue)+1) * sizeof(wchar_t));
if(ERROR_SUCCESS != lReturnCode)
{
// error
}
RegCloseKey(hkRunOnce);
}
*/
} Server;
HRESULT GetOrCreateObj(CComQIPtr<IADsContainer, &IID_IADsContainer> &pIADsContainer_In,
CComBSTR &bstrObjName,
CComQIPtr<IADsContainer, &IID_IADsContainer> &pIADsContainer_Out)
{
HRESULT
hres = WBEM_E_FAILED;
CComQIPtr<IDispatch, &IID_IDispatch>
pDisp;
CComQIPtr<IDirectoryObject, &IID_IDirectoryObject>
pDirectoryObj;
CComQIPtr<IADsObjectOptions, &IID_IADsObjectOptions>
pADsObjectOptions;
CComVariant
vSecurityOptions;
ADSVALUE
AdsValue[1];
ADS_ATTR_INFO
attrInfo[] = { { L"ntSecurityDescriptor", ADS_ATTR_UPDATE, ADSTYPE_NT_SECURITY_DESCRIPTOR, &AdsValue[0], 1} };
CNtSecurityDescriptor
cSD;
DWORD
dwModified;
ADS_OBJECT_INFO
*pADsInfo = NULL;
if(NULL == pIADsContainer_In.p) return WBEM_E_FAILED;
// **** get/create object
hres = pIADsContainer_In->GetObject(L"Container", bstrObjName, &pDisp);
if(FAILED(hres) || (NULL == pDisp.p))
{
CComQIPtr<IADs, &IID_IADs>
pIADs;
hres = pIADsContainer_In->Create(L"Container", bstrObjName, &pDisp);
if(FAILED(hres) || (NULL == pDisp.p))
{
ERRORTRACE((LOG_ESS, "POLICMAN: (Container Creation) Could create container %S : 0x%x\n", (BSTR)bstrObjName, hres));
return hres;
}
// **** write object to AD
pIADs = pDisp;
hres = pIADs->SetInfo();
if(FAILED(hres))
{
ERRORTRACE((LOG_ESS, "POLICMAN: (Container Creation) Could write container %S to DS : 0x%x\n", (BSTR)bstrObjName, hres));
return hres;
}
}
// **** set object security option
pADsObjectOptions = pDisp;
vSecurityOptions = (ADS_SECURITY_INFO_OWNER | ADS_SECURITY_INFO_DACL);
hres = pADsObjectOptions->SetOption(ADS_OPTION_SECURITY_MASK, vSecurityOptions);
if(FAILED(hres))
{
ERRORTRACE((LOG_ESS, "POLICMAN: (Container Creation) Could set security options on object : 0x%x\n", hres));
return hres;
}
// **** create security descriptor
hres = CreateDefaultSecurityDescriptor(cSD);
if(FAILED(hres))
{
ERRORTRACE((LOG_ESS, "POLICMAN: (Container Creation) Could create security descriptor : 0x%x\n", hres));
return hres;
}
// **** set object security descriptor
AdsValue[0].dwType = ADSTYPE_NT_SECURITY_DESCRIPTOR;
AdsValue[0].SecurityDescriptor.dwLength = cSD.GetSize();
AdsValue[0].SecurityDescriptor.lpValue = (LPBYTE)cSD.GetPtr();
pDirectoryObj = pDisp;
hres = pDirectoryObj->SetObjectAttributes(attrInfo, 1, &dwModified);
if(FAILED(hres))
{
ERRORTRACE((LOG_ESS, "POLICMAN: (Container Creation) Could set security on object : 0x%x\n", hres));
return hres;
}
pIADsContainer_Out = pDirectoryObj;
return WBEM_S_NO_ERROR;
}
#define SYSTEM_PATH L"LDAP://CN=System,"
#define WMIPOLICY_PATH L"CN=WMIPolicy"
#define TEMPLATE_PATH L"CN=PolicyTemplate"
#define TYPE_PATH L"CN=PolicyType"
#define GPO_PATH L"CN=WMIGPO"
#define SOM_PATH L"CN=SOM"
HRESULT InScopeOfCOM_CreateADContainers(void)
{
HRESULT
hres = WBEM_E_FAILED;
PDSROLE_PRIMARY_DOMAIN_INFO_BASIC
pBasic;
CComPtr<IADs>
pRootDSE;
CComQIPtr<IADs, &IID_IADs>
pObj;
CComQIPtr<IADsContainer, &IID_IADsContainer>
pWMIPolicyObj,
pSystemObj,
pADsContainer;
CComVariant
vDomainName;
CComBSTR
bstrSystemPath(SYSTEM_PATH),
bstrWMIPolicy(WMIPOLICY_PATH),
bstrTemplate(TEMPLATE_PATH),
bstrType(TYPE_PATH),
bstrSom(SOM_PATH),
bstrGPO(GPO_PATH);
// **** delay until AD is up and running
DWORD
dwResult = DsRoleGetPrimaryDomainInformation(NULL, DsRolePrimaryDomainInfoBasic,
(PBYTE *)&pBasic);
if(dwResult == ERROR_SUCCESS)
{
// **** Check if this is a DC
if((pBasic->MachineRole == DsRole_RoleBackupDomainController) ||
(pBasic->MachineRole == DsRole_RolePrimaryDomainController))
{
HANDLE
hEvent;
hEvent = OpenEvent(EVENT_ALL_ACCESS, FALSE, TEXT("NtdsDelayedStartupCompletedEvent") );
if(hEvent) {
WaitForSingleObject(hEvent, 50000);
CloseHandle (hEvent);
}
}
}
// **** get LDAP name of domain controller
hres = ADsGetObject(L"LDAP://rootDSE", IID_IADs, (void**)&pRootDSE);
if(FAILED(hres))
{
ERRORTRACE((LOG_ESS, "POLICMAN: (Container Creation) Could not get pointer to LDAP://rootDSE : 0x%x\n", hres));
return hres;
}
else
{
hres = pRootDSE->Get(L"defaultNamingContext", &vDomainName);
if(FAILED(hres) || (V_VT(&vDomainName) != VT_BSTR) || (V_BSTR(&vDomainName) == NULL))
{
ERRORTRACE((LOG_ESS, "POLICMAN: (Container Creation) could not get defaultNamingContext : 0x%x\n", hres));
return hres;
}
bstrSystemPath.Append(vDomainName.bstrVal);
}
// **** get system path
hres = ADsGetObject(bstrSystemPath, IID_IADsContainer, (void **)&pSystemObj);
if (FAILED(hres))
{
ERRORTRACE((LOG_ESS, "POLICMAN: (Container Creation) Could not get pointer to %S : 0x%x\n", (BSTR)bstrSystemPath, hres));
return hres;
}
// **** get/create WMIPolicy containers
hres = GetOrCreateObj(pSystemObj, bstrWMIPolicy, pWMIPolicyObj);
if(FAILED(hres))
{
ERRORTRACE((LOG_ESS, "POLICMAN: (Container Creation) Could not create/get pointer to %S : 0x%x\n", (BSTR)bstrWMIPolicy, hres));
return hres;
}
else
{
hres = GetOrCreateObj(pWMIPolicyObj, bstrTemplate, pADsContainer);
if(FAILED(hres))
{
ERRORTRACE((LOG_ESS, "POLICMAN: (Container Creation) Could not create/get pointer to %S : 0x%x\n", (BSTR)bstrTemplate, hres));
return hres;
}
hres = GetOrCreateObj(pWMIPolicyObj, bstrType, pADsContainer);
if(FAILED(hres))
{
ERRORTRACE((LOG_ESS, "POLICMAN: (Container Creation) Could not create/get pointer to %S : 0x%x\n", (BSTR)bstrType, hres));
return hres;
}
hres = GetOrCreateObj(pWMIPolicyObj, bstrSom, pADsContainer);
if(FAILED(hres))
{
ERRORTRACE((LOG_ESS, "POLICMAN: (Container Creation) Could not create/get pointer to %S : 0x%x\n", (BSTR)bstrSom, hres));
return hres;
}
hres = GetOrCreateObj(pWMIPolicyObj, bstrGPO, pADsContainer);
if(FAILED(hres))
{
ERRORTRACE((LOG_ESS, "POLICMAN: (Container Creation) Could not create/get pointer to %S : 0x%x\n", (BSTR)bstrGPO, hres));
return hres;
}
}
return S_OK;
}
extern "C" STDAPI CreateADContainers(void)
{
HRESULT
hres = WBEM_E_FAILED;
// **** init process context
CoInitialize(NULL);
CoInitializeSecurity (NULL, -1, NULL, NULL,
RPC_C_AUTHN_LEVEL_NONE, RPC_C_IMP_LEVEL_IMPERSONATE, NULL,
EOAC_NONE, NULL);
try
{
hres = InScopeOfCOM_CreateADContainers();
}
catch(...)
{
// **** error
return WBEM_E_FAILED;
}
// **** if we returned successfully, then remove the run key
if(SUCCEEDED(hres))
{
wchar_t
swKeyValue[] = L"RUNDLL32.EXE %systemroot%\\system32\\wbem\\policman.dll,CreateADContainers",
swExpandedKeyValue[512],
swRunOnceKey[] = REG_RUN_KEY ;
HKEY
hkRunOnce;
LONG
lReturnCode;
lReturnCode = RegOpenKeyEx(HKEY_LOCAL_MACHINE, swRunOnceKey, 0, KEY_SET_VALUE, &hkRunOnce);
if(ERROR_SUCCESS != lReturnCode)
{
// error
}
lReturnCode = RegDeleteValue(hkRunOnce, L"PolicMan");
if(ERROR_SUCCESS != lReturnCode)
{
// error
}
}
// **** cleanup and shutdown
CoUninitialize();
return S_OK;
}